4 ms·
> platform specific stuff Yes. If I were to write IR for a real project, I'd probably keep a few pretty large functions to avoid overhead caused by calling con
by majke 13y ago
> platform specific stuff
Yes. If I were to write IR for a real project, I'd probably keep a few pretty large functions to avoid overhead caused by calling conventions.
Very interesting link. Thank you! Though I find the arguments unconvincing. More data needed...
> typed assembly
Yes. But now _every_ mac user and plenty of other people have a typed assembly compiler on their machines! IR is reasonably popular and quite well documented. I'm not saying it's new, I'm saying it's cool :)
- azakai 13y agoIt's not just calling conventions. LLVM IR also bakes in various assumptions about the target platform, from endianness to structure alignment to miscellaneous facts like whether char is signed or unsigned. In many of those there is no going back to the original representation, they are one-way. If you have IR that you can compile to various archs and have it work there, that is a lucky thing in that particular case. But it is not what LLVM IR was designed for nor should that work in general.
- phaemon 13y agoI don't understand what this means. Could you please give an example of some code that loses information in this way when compiled with LLVM?
- azakai 13y agoSay you have a struct type X with properties int, double, int. The offset of the last property depends on how alignment works on the target platform - it could be 12 or 16 on some common ones. LLVM IR can contain a read from offset 12, hardcoded. Whereas the C code contains X.propertyThree, which is more portable.
- phaemon 13y agoAh, I think I see....you mean I could write non-portable IR code by doing that, although LLVM would never produce code like that? I guess there must always be IR that the frontend will never produce then?
- KenoFischer 13y agoNo, every LLVM frontend (e.g. Clang) has to do so all the time for things to work.
- phaemon 13y agoThat makes no sense at all. You've just said that every LLVM frontend has to produce code that every LLVM frontend won't produce! If you mean something different, then could you please be clearer, as I really don't understand what you're talking about. [EDIT: caf's post made it clearer. I know what you meant now]
- caf 13y agoNo, the implication is that the LLVM IR that the frontend produces changes depending on the ultimate target that the LLVM IR will be compiled to. In other words, the frontends aren't backend-agnostic.
- phaemon 13y agoOh, right! That makes more sense. So you have to specify the backend when you start the process? I didn't know LLVM did that.
- azakai 13y agoYes, the frontend very much knows what target you are aiming for. It greatly affects the IR that is generated. And once you generate that IR, you can't just built it to an arbitrary target, it must be the one it was generated for.
- nostrademons 13y agoBut that's not how LLVM works, at least when I worked with it a couple years ago. You would define a struct type in terms of primitive types (int64, ptr, etc), and then use getelementptr with the offset of the field path you wanted. Yes, it's a numeric offset, but it's a field offset within the struct, not a byte offset. LLVM handles packing, alignment, and pointer size issues for you automatically.
- vidarh 13y agoOnce you have defined a struct in terms of primitive types, it is platform dependent. Consider C: A C int can be 16 bits. Or 32. Or 64. Etc. As long constraints of the relation to the other types is met. The moment the frontend specifies a primitive type for a field in the struct, that code is incompatible with a whole lot of platforms.
- eropple 13y agoYour primitive types aren't LLVM's though, are they? I mean, I haven't looked at LLVM thoroughly (just enough to be familiar with it, a friend is writing a language he wanted some input on), but I would be surprised and disappointed if they had a C "int" type as opposed to "signed 32-bit integer" or whatever. At which point it's compatible with whatever else is throwing around a signed 32-bit integer.
- vidarh 13y agoBut that is exactly the point - that LLVM IR is not platform independent. The fronted must choose which specific integer type that "int" in C maps to. At that point, the IR is no longer machine independent - if you pick 32 bit signed ints to represent C "int", your program will not match the C ABI on any platform using 16 bit unsigned int as C "int" and you won't be able to directly make calls to libraries on that platform, for example.
- eropple 13y agoSo use uint32_t?
- bodyfour 13y agoint a() { return sizeof(void *); } Obviously a trivial example, but it's illustrative: the front-end compiler knows a bunch of things about your target and bakes that information into the IL. If you took IL generated by the compiler with "-arch i386" and then compiled the IL using "-arch x86_64" it's quite possible to get a non-working executable. It's possible to carefully write IL that will work on multiple platforms as done in this blog post, but I'm not sure how useful that really is. You're still giving up the exact control that assembly gives you, so I don't know how much better you'd get than clang-produced IR. In other words, if you want "portable assembly language" use C. Still, its an interesting blog post. It's good to show people how the compiler works behind the curtain.
- gngeal 13y agoYes. But now _every_ mac user and plenty of other people have a typed assembly compiler on their machines! Really? Where? Which one? The last time I looked, TAL was only a proposal.
- pyre 13y agoI think the parent is referring to the IR being like having a typed assembly language. IIRC, Apple uses LLVM.
- thinkmoore 13y agoLLVM IR is not strongly-typed in the way TAL proposes. Plenty can still go wrong.