Adding a module in a pass

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.

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.

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.

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)?

It is run once per LLVM module. An LLVM module can either be a single translation unit or multiple translation units linked together (i.e., LLVM can link multiple LLVM modules together into one large 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.

I'm not familiar with how your languages organizes compilation units, but from the sounds of it, it seems like you're saying that you want to add the global ctor once after the compilation units are linked into a single LLVM bitcode file.

In that case, you either delay running your FunctionPass until you have the whole bitcode file, or you create a ModulePass that is only executed once the whole-program bitcode is generated.

-- John T.

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.

I'm not familiar with how your languages organizes compilation units,
but from the sounds of it, it seems like you're saying that you want to
add the global ctor once after the compilation units are linked into a
single LLVM bitcode file.

I guess that what I am after is the ability to add a translation unit
during the optimization phase. This translation unit does not itself
have to be optimized.

I am using the optimization pass to instrument another C/C++ program
with debugging code (think "DTrace for programs", except that the
instrumentation is static, not dynamic.) The instrumentation is
controlled by a script. For example:

   @begin
   {
     print("This is executed before main()");
   }

   @enter:Foo
   {
     print("This is executed when entering Foo()");
   }

The @enter code is injected at the beginning of Foo(), so this code is
put into the current module. My own module contains the @begin code,
along with all global functions, global variables, and build-in
functions that are generated from the script.

In that case, you either delay running your FunctionPass until you have
the whole bitcode file, or you create a ModulePass that is only executed
once the whole-program bitcode is generated.

I have considered adding a ModulePass but got confused by the
description of analysis groups (which I assume I need to use in order
to make sure that my ModulePass and FunctionPass are run together.)

I am currently generating my code in the FunctionPass constructor, which
works just fine, except I do not know how to get my module passed on to
the linker.