Mapping High-Level Constructs to LLVM IR
llvm.lyngvig.org
llvm.lyngvig.org
This isn't really accurate. IT's accurate at some level, in that there are not two different types. But that's because it's not necessary, they have nsw/nuw (no signed wrap, no unsigned wrap) flags on the operations.
Why would you want to do this? You are trying to reconstruct high level, language specific info from low level, language independent info. Of course you can't do this.
Your comment comes out to "lowering loses information", which is, of course, true.
So let's try again: What semantic information do you believe is lost here. IE where does it result in an incorrect translation, or the inability to optimize something?
Because that's what "necessary" would come out to.
Because SPIR requires that you can load and enqueue an OpenCL kernel from an IR, without having a source. And you need this type information in order to be able to format your arguments properly.
Please note that I'm not commenting here on the very choice of LLVM IR as a common medium made by SPIR committee.
> Your comment comes out to "lowering loses information", which is, of course, true.
Exactly. But the current common uses of LLVM IR do require some of the information which is lost, and, in case of signedness, it was not even necessary to lower it.
> IE where does it result in an incorrect translation, or the inability to optimize something?
You're limiting IR uses to translation and optimisations. Fine. I would have welcomed this way of thinking. But, unfortunately, this is not the case.
Portability of a high level language is an explicit non-goal of LLVM :)
The fact that someone decided to do it just makes them silly :)
I guess for closures you simply copy all the locals that they capture into a heap allocated structure that also has the pointer to the closure code.
Also, for performance, it may be beneficial to skip the 'put a local on the stack' part and create a to-be-captured object directly on the heap.
I see somebody posted https://news.ycombinator.com/item?id=8580501, which points to the Wikipedia entry on 'spaghetti trees', the conceptual view on the needed data structures (which one may recognize from reading SICP, although I do not remember it using the term)
Many implementations, at runtime, will implement the 'main line' of the tree as a 'real stack', but that can be risky, as you will have to make sure that no closures survive the point where any locals they refer to get removed from the stack (what does C++ here? Declare it undefined behaviour or make it impossible?)
The only potentially funny bit with the closures is construction of a set of potentially mutually recursive closures - in such case you have to defer filling in the corresponding environment fields until all the closure structures are allocated.
If you want to look at something similar, OpenCL has an LLVM IR -based standardized binary IR.
SIL has a very large number of differences from LLVM IR. It's essentially built as an IR that the can do static analysis and high level optimization on.
This means it has a number of higher level constructs that LLVM doesn't, in order to be able to achieve the semantics they want for static analysis, and in order to be able to do things like optimize dispatch.