The problem I'm experiencing with Stacker has to do with linkage types (again!). What I'm trying to do is create a "global appending" array. In compilation units that don't include "main", I generate it with: TheStack = new GlobalVariable( /*type=*/ stack_type, /*isConstant=*/ false, /*Linkage=*/ GlobalValue::AppendingLinkage, /*initializer=*/ 0, /*name=*/ "_stack_", /*parent=*/ TheModule ); Note that lack of an initializer. I think this makes it external. When a main program is found, I take that same variable (TheStack) and add an initializer: TheStack->setInitializer( Constant::getNullValue(stack_type) ); This should make it global but not external. This used to work before some recent changes to LLVM. But, after the changes, I now get: Global is external, but doesn't have external linkage! [1024 x int]* %_stack_ from the verifier. I tried changing the initial definition of TheStack to include an initializer with no modifications to it when there's a main. The produces the (somewhat expected): stkrc -e -f -o testing.bc /proj/work/llvm/projects/Stacker/test/testing.st llc -f -o testing.s testing.bc gcc -ggdb -L/proj/work/llvmobj/lib/Debug testing.s -lstkr_runtime -o eq eq.s /tmp/ccYV2ZHL.o(.bss+0x0):/proj/work/llvmobj/projects/Stacker/test/eq.s:10: multiple definition of `_stack_' /tmp/ccClZ4Vr.o(.bss+0x0):/proj/work/llvmobj/projects/Stacker/test/testing.s:10: first defined here collect2: ld returned 1 exit status I looked at GlobalValue::LinkageTypes hoping that the enumeration was a set of bitfields that I could OR together to produce: ExternalLinkage|AppendingLinkage but, alas, the enumeration values are sequential. So, how is this supposed to work? Do I have to reset the linkage type after giving it an initializer? Why? Reid. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20031123/bad00451/attachment.sig>
I'm guessing here, but I think what you want to do is have _stack_ be "appending global <stack_type>" in the compilation units where you have main, and "external global <stack_type>" in the compilation units where you do not. I don't quite understand why you need an appending global to do this, if you can only have one main. I would just set it to the correct initializer in the module that has main, and leave it external everywhere else.> What I'm trying to do is create a "global appending" array. In > compilation units that don't include "main", I generate it with: [...]-- gaeke at uiuc.edu
> That's essentially what I did to get it to work but instead of > appending, I just opted for LinkOnce.Sounds ok.> > I don't quite understand why you need an appending global to do this, if you > > can only have one main. I would just set it to the correct initializer in the > > module that has main, and leave it external everywhere else. > > Its essentially a hack. What I was trying to do was have the size of > the global stack array increase depending on the number of compilation > units that are linked together. The idea was that a given compilation > unit would know its stack requirements but not that of other compilation > units. Using appending linkage allows the sum total of the stack > requirements to be handled without foreknowledge of the total size > needed. > > This actually doesn't work because you can't (yet) specify the stack > size to the compiler! I'm debating the pros and cons of doing this.This sounds like something you could do much more cleanly with some sort of interprocedural analysis. You could stick that in your link-time Stacker optimizer. :-) For example: stkrc -c 1.st -o 1.o stkrc -c 2.st -o 2.o ... stkrc -c n.st -o n.o stkrld -o program 1.o 2.o ... n.o (links bytecode files, and does all the inter-procedural analysis and optimizations you need) We do stuff like this with gccld, for C/C++ programs. Hope this helps, -Brian -- gaeke at uiuc.edu
On Sun, 23 Nov 2003, Brian R. Gaeke wrote:> > That's essentially what I did to get it to work but instead of > > appending, I just opted for LinkOnce. > > Sounds ok.Note that appending linkage will do what you want, but the deal is that you have to specify values to append together. In the main translation unit, instead of making it a strong symbol, make it either an appending or external symbol. The assertion you are now getting is correct: if you don't specify an initializer, it must have external (only) linkage. When that xlation unit gets merged with an xlation unit that has appending, linkonce, or strong linkage, it will keep the non-external linkage type.> > > I don't quite understand why you need an appending global to do this, if you > > > can only have one main. I would just set it to the correct initializer in the > > > module that has main, and leave it external everywhere else. > > > > Its essentially a hack. What I was trying to do was have the size of > > the global stack array increase depending on the number of compilation > > units that are linked together. The idea was that a given compilation > > unit would know its stack requirements but not that of other compilation > > units. Using appending linkage allows the sum total of the stack > > requirements to be handled without foreknowledge of the total size > > needed.This should be implementable. :)> We do stuff like this with gccld, for C/C++ programs.Also, on another note, it might be nice if the stacker "compiler driver" took -O -O2, -O3, etc options. There is no reason in particular for you to use gccas/gccld: those tools are specific to the gcc frontend. It's possible that a different set of optimizations makes sense for stacker than for C, for example. *shrug*, anyway, it is _really_ cool that Stacker is in CVS. :) -Chris -- http://llvm.cs.uiuc.edu/ http://www.nondot.org/~sabre/Projects/