I have an optimization pass (FunctionPass) where I need to add global constructors. For cleaness sake I decided to add these in my own module. My module is created in my FunctionPass constructor: MyPass() : FunctionPass(ID), myModule("my_module", getGlobalContext()) {} I generate an llvm.global_ctor global variable in my module, and I add my global constructors there. This appears to be correct. Here is a dump of the module after the pass: ; ModuleID = 'my_module' @my_literal = internal constant [6 x i8] c"Hello\00" @llvm.global_ctors = appending global [1 x { i32, void ()* }] [void () { i32 65535, void ()* @my_global_constructor }] define void @my_global_constructor() { %puts = call i32 @puts(i8* getelementptr inbounds ([6 x i8]* @my_literal, i32 0, i32 0)) } declare i32 @puts(i8* nocapture) nounwind My problem is that this module is not linked into the executable. Do I need to insert the module somewhere?
The my_global_function I included in my previous mail was missing a terminating "ret void" instruction. This has been added, and verifyFunction() is now happy with my function. The problem with my module not being linked remains though.
On 8/9/11 6:49 AM, Bjorn Reese wrote:> I have an optimization pass (FunctionPass) where I need to add global > constructors. > > For cleaness sake I decided to add these in my own module. My module > is created in my FunctionPass constructor:This is not how I would do it. A FunctionPass has doInitialization() and doFinalization() methods that you can implement thatcan operate on the whole module. They are designed for exactly the situation you describe: your pass does some sort of local transform, but there's some global modifications it needs to do (add global constructors, add function prototypes, etc). -- John T.> > MyPass() > : FunctionPass(ID), > myModule("my_module", getGlobalContext()) > {} > > I generate an llvm.global_ctor global variable in my module, and I add > my global constructors there. This appears to be correct. Here is a > dump of the module after the pass: > > ; ModuleID = 'my_module' > > @my_literal = internal constant [6 x i8] c"Hello\00" > @llvm.global_ctors = appending global [1 x { i32, void ()* }] [void > () { i32 65535, void ()* @my_global_constructor }] > > define void @my_global_constructor() { > %puts = call i32 @puts(i8* getelementptr inbounds ([6 x i8]* > @my_literal, i32 0, i32 0)) > } > > declare i32 @puts(i8* nocapture) nounwind > > My problem is that this module is not linked into the executable. > > Do I need to insert the module somewhere? > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On 2011-08-09 16:48, John Criswell wrote:> On 8/9/11 6:49 AM, Bjorn Reese wrote: >> I have an optimization pass (FunctionPass) where I need to add global >> constructors. >> >> For cleaness sake I decided to add these in my own module. My module >> is created in my FunctionPass constructor: > > This is not how I would do it. A FunctionPass has doInitialization() > and doFinalization() methods that you can implement thatcan operate on > the whole module. They are designed for exactly the situation you > describe: your pass does some sort of local transform, but there's some > global modifications it needs to do (add global constructors, add > function prototypes, etc).Doesn't doIntialization() run once for each translation unit (module)? I only want to generate my global constructors once for the whole program. They are generated from a scripting language, which is parsed in the optimization pass.