Misha Brukman wrote:> >>1. Opcodes and intrinsics >> > That's not really correct. The intrinsics such as llvm.frameaddress and > llvm.returnaddress have no equivalents in LLVM opcodes -- the meaning of > the intrinsics is specifically machine-dependent, and LLVM (and its > opcodes) are machine-independent, so there is no valid interchange of > these intrinsics with any combination of LLVM opcodes. >Yes, I understand that those intrinsics are mapped differently on different machines, but isn't 'add' mapped differently too? It seems to me that those intrinsics are there to support the GNU C extensions, making them a 'language feature' of sorts. That's why they are intrinsics and not opcodes.>>3. Control transfer >> > LLVM has the 'call' instruction that abstracts the target machine's > calling convention. See http://llvm.cs.uiuc.edu/docs/LangRef.html#i_call > for more information. >Yes, it abstracts the target's C calling convention. But I'm trying to see if other types of languages can be implemented using LLVM.> What is that you are looking to express that isn't captured by the > `call' instruction? >Tail calls, closures, continuations, lazy allocation... Basically I'm trying to see how am I going to implement high-level functions on LLVM.> Hope that helps,Certainly, thanks! Marc Ordinas i Llopis | Tragnarion Studios
On Mon, 25 Oct 2004, Marc Ordinas i Llopis wrote:> Misha Brukman wrote: > >>1. Opcodes and intrinsics > >> > > That's not really correct. The intrinsics such as llvm.frameaddress and > > llvm.returnaddress have no equivalents in LLVM opcodes -- the meaning of > > the intrinsics is specifically machine-dependent, and LLVM (and its > > opcodes) are machine-independent, so there is no valid interchange of > > these intrinsics with any combination of LLVM opcodes. > > > > Yes, I understand that those intrinsics are mapped differently on > different machines, but isn't 'add' mapped differently too? > > It seems to me that those intrinsics are there to support the GNU C > extensions, making them a 'language feature' of sorts. That's why they > are intrinsics and not opcodes.Yes, that is accurate. In fact, these intrinsics COULD be made into opcodes, but it would add little value to do so.> >>3. Control transfer > >> > > LLVM has the 'call' instruction that abstracts the target machine's > > calling convention. See http://llvm.cs.uiuc.edu/docs/LangRef.html#i_call > > for more information. > > > > Yes, it abstracts the target's C calling convention. But I'm trying to > see if other types of languages can be implemented using LLVM.Sure they can. :)> > What is that you are looking to express that isn't captured by the > > `call' instruction? > > > > Tail calls, closures, continuations, lazy allocation... Basically I'm > trying to see how am I going to implement high-level functions on LLVM.As for tail calls, my plans are here: http://nondot.org/sabre/LLVMNotes/GuaranteedEfficientTailCalls.txt Note that LLVM already has a pretty aggressive tail-call elimination pass, so this is really more for completeness than anything else. Closures and continuations should not be a problem. Closures are represented as a pair, where the first element is a pointer to a struct (containing any environment needed by the closure) and a function pointer. To invoke the closure, just call the function pointer, passing the pointer to struct. I'm not sure what support you would need in LLVM for lazy allocation. -Chris -- http://llvm.org/ http://nondot.org/sabre/
I agree with Chris's points below, but I would add a couple of caveats: On Oct 26, 2004, at 2:04 PM, Chris Lattner wrote:>>> What is that you are looking to express that isn't captured by the >>> `call' instruction? >>> >> >> Tail calls, closures, continuations, lazy allocation... Basically I'm >> trying to see how am I going to implement high-level functions on >> LLVM. > > As for tail calls, my plans are here: > http://nondot.org/sabre/LLVMNotes/GuaranteedEfficientTailCalls.txt > Note that LLVM already has a pretty aggressive tail-call elimination > pass, > so this is really more for completeness than anything else.Actually, although we can optimize a tail call of a procedure calling itself, we cannot express an optimized tail call from one procedure to another. We don't have a cross-procedure branch in LLVM. Of course, a cross-procedure tail call could be optimized to a branch within a native back-end but that's not really what you want.> > Closures and continuations should not be a problem. Closures are > represented as a pair, where the first element is a pointer to a struct > (containing any environment needed by the closure) and a function > pointer. > To invoke the closure, just call the function pointer, passing the > pointer > to struct.I agree that closures should not be a problem. In the case of closures for polymorphic functions, though, the type information for the function pointer in the closure will be imprecise and casts will probably be needed to use the function pointer. The loss of type information is really due to lack of polymorphism at the LLVM level, not due to closures per se. I'm not sure how well continuations will work. As Chris implied, they can be expressed as closures, but "rediscovering" the continuations for any CPS-based analysis or optimizations could be inconvenient.> > I'm not sure what support you would need in LLVM for lazy allocation.Me neither. You should be able to *implement* it, but I don' t know what should be expressed in LLVM directly.> > -Chris >--Vikram http://www.cs.uiuc.edu/~vadve http://llvm.cs.uiuc.edu/