How would following Pascal code be translated to LLVM? procedure outer(a: integer): integer; procedure inner(b: integer): integer; begin return a + b end; begin return inner(a) end; If outer(10) is called, it returns 20. The problem here is that inner has access to the locals and formal arguments of outer. I do not see any direct support for this. It could be handled by creating a struct for outer that contains everything used by inner procedures and explicitly passing its address to the inner procedures as an extra parameter. Am I missing something? If not, are there any plans to directly support this?
----- Original Message ----- From: "Jeff Cohen" <jeffc at jolt-lang.org> To: <LLVMdev at cs.uiuc.edu> Sent: Saturday, August 21, 2004 7:35 PM Subject: [LLVMdev] How to handle nested procedures?> How would following Pascal code be translated to LLVM? > > procedure outer(a: integer): integer; > procedure inner(b: integer): integer; > begin > return a + b > end; > begin > return inner(a) > end; > > If outer(10) is called, it returns 20. > > The problem here is that inner has access to the locals and formal > arguments of outer. I do not see any direct support for this. It could > be handled by creating a struct for outer that contains everything used > by inner procedures and explicitly passing its address to the inner > procedures as an extra parameter.There is no need for support of this, keep in mind that normal Pascal compilers translate to local assembly code which also does not support inner functions. The struct idea is probably a good LLVM way to do it. In a normal compiler you would use displays or access links, which basically consist of having some way to refer to the stack frame of a parent function. The struct would be acheiving the same thing.> Am I missing something? If not, are there any plans to directly support > this? > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
On Sat, 21 Aug 2004 20:35:35 -0500 "Patrick Meredith" <pmeredit at uiuc.edu> wrote:> > ----- Original Message ----- > From: "Jeff Cohen" <jeffc at jolt-lang.org> > To: <LLVMdev at cs.uiuc.edu> > Sent: Saturday, August 21, 2004 7:35 PM > Subject: [LLVMdev] How to handle nested procedures? > > > > How would following Pascal code be translated to LLVM? > > > > procedure outer(a: integer): integer; > > procedure inner(b: integer): integer; > > begin > > return a + b > > end; > > begin > > return inner(a) > > end; > > > > If outer(10) is called, it returns 20. > > > > The problem here is that inner has access to the locals and formal > > arguments of outer. I do not see any direct support for this. It could > > be handled by creating a struct for outer that contains everything used > > by inner procedures and explicitly passing its address to the inner > > procedures as an extra parameter. > > There is no need for support of this, keep in mind that normal Pascal > compilers translate to local assembly code which also does not support inner > functions. The struct idea is probably a good LLVM way to do it. In a > normal compiler you would use displays or access links, which basically > consist of having some way to refer to the stack frame of a parent function. > The struct would be acheiving the same thing.I was concerned that if the optimizer inlined inner, it would not be able to eliminate all the overhead introduced by this scheme. So I ran a test. I simulated the above with the following C code: struct FRAME { int a; }; static int inner(struct FRAME* frame, int b) { return frame->a + b; } int outer(int a) { struct FRAME frame; frame.a = a; return inner(&frame, a); } This produces: int %outer(int %a) { entry: %tmp.4.i = shl int %a, ubyte 1 ; <int> [#uses=1] ret int %tmp.4.i } Function inner isn't even emitted (no doubt a consequence of being static, as an inner method shouldn't have external visibility). I can't complain :-)