[llvm-commits] llvm-gcc4: nested function support (w/o trampolines)

Duncan Sands baldrick at free.fr
Mon Feb 5 13:17:13 PST 2007


This patch adds support for nested subroutines, but not for
trampolines (used for taking pointers to nested subroutines;
implementing support for trampolines is more tricky since it
needs help from the code generators).  There are no changes
to LLVM itself.

The patch is quite simple because gcc already does the heavy
lifting - all that's needed is to emit the static chains when
converting to LLVM.  The static chain is passed in a register
as an additional parameter.  For example, consider

int nest(int n)
{
  int a;
  void z(void) { a = 1; }
  z();
  return a;
}

gcc turns z into

void z(struct frame* chain) { chain->a = 1; }

and nest into

int nest(int n)
{
  struct frame FRAME;
  int a;
  z(&FRAME);
  return FRAME.a;
}

where struct frame is a record with one integer field called "a".
gcc introduces struct frame to hold all the local variables
in the parent "nest" that are accessed by the child "z".  It
rewrites all references to these variables to refer to the
corresponding FRAME fields instead, in both the parent and child.
It leaves the old variable declarations on the stack (which is why
"int a;" is still present), but since they are no longer used, the
optimizers will remove them.

This patch only touches emission of nested function bodies and calls
to nested functions.  It emits z as

define internal void @z(%struct.frame* inreg %chain) {...}

and the call becomes

call void @z( %struct.frame* %FRAME inreg )

It doesn't try to teach ConvertType to correctly emit local function
types, since gcc doesn't put enough information in the function type
to do this, and it's not needed anyway since llvm-convert has enough
"fix up dud prototypes" code to handle this situation too.

There are a bunch of gcc testcases for nested functions.  They all
worked as expected [1], except for those involving variable sized objects
(which blew up LLVM), and some twisted examples which blew up the gcc
nested function code (i.e. long before reaching llvm-convert and this
patch).  The variable sized object problems don't seem to have anything
to do with nested functions.

Enjoy!

Duncan.

[1] For example, the tests using trampolines and/or non-local gotos
failed: they are not yet supported.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nested.diff
Type: text/x-diff
Size: 9559 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20070205/4781dc54/attachment.diff>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: testcase.diff
Type: text/x-diff
Size: 826 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20070205/4781dc54/attachment-0001.diff>


More information about the llvm-commits mailing list