MAJOR API CHANGE: LLVMContext

Notice of a major upcoming API change: The static methods for constructing types and constants will be going away in the future. Instead, the global uniquing tables that lurk behind these APIs will be privatized within LLVMContext instances.

What this means for you: Your client application will need to create an LLVMContext in main(), and pass it into a few APIs (the constructor for Module, for instance). You can, in theory, have more than one LLVMContext as long as you never want Modules created under separate contexts to interact.

In the near term, I will be committing patches to do this conversion for the existing LLVM tools, including Clang and LLVM-GCC, which should provide examples for those following along at home.

--Owen

To ease this transition, I have added a getGlobalContext() API. If you're only ever planning to use LLVM on a single thread, it will be completely safe to simply pass this value to every API that takes an LLVMContext.

--Owen

Hello Owen,

Is this effective immediately for the 2.6 Top of Tree or is it something that will change in the next release (eg. 2.7)?

Thanks,

--Sam

The code freeze for 2.6 is still nearly two months away; it's safe to
assume any API changes are going to apply to current trunk (i.e. 2.6).

-Eli

That's awesome, thanks very much for working on this Owen. So if I understand correctly, there can be as many LLVMContext instances as we want? Or one module only has a single LLVMContext?

A similar question is: can I now delete constants created, after JIT-compiling a function's IR? I know we can already delete the body of the function, but not the constants the body needs. So can we do that now?

Thanks!
Nicolas

Owen Anderson wrote:

That's awesome, thanks very much for working on this Owen. So if I
understand correctly, there can be as many LLVMContext instances as we
want? Or one module only has a single LLVMContext?

You can have as many modules per context as you wish, and as many contexts as you wish.
Modules belonging to different contexts are essentially isolated from each other. You can't,
for now at least, link them together or anything. It might be possible in the future, but it will
be significantly heavier weight than linking two modules in the same context.

A similar question is: can I now delete constants created, after
JIT-compiling a function's IR? I know we can already delete the body of
the function, but not the constants the body needs. So can we do that now?

I'm honestly not sure, and this is not an explicit goal of the LLVMContext work. Patches are welcome, though. :slight_smile:

--Owen

Hi Owen, can you please document this ABI change in
ReleaseNotes-2.6.html.

Thanks,

Duncan.

Owen Anderson wrote:

Notice of a major upcoming API change: The static methods for
constructing types and constants will be going away in the future.
Instead, the global uniquing tables that lurk behind these APIs will
be privatized within LLVMContext instances.

What this means for you: Your client application will need to create
an LLVMContext in main(), and pass it into a few APIs (the constructor
for Module, for instance). You can, in theory, have more than one
LLVMContext as long as you never want Modules created under separate
contexts to interact.

In the near term, I will be committing patches to do this conversion
for the existing LLVM tools, including Clang and LLVM-GCC, which
should provide examples for those following along at home.
  

Can you give a brief example of where to find the LLVMContext within a
ModulePass or FunctionPass? Is this just the context stored within the
Module or Function passed to runOnModule/runOnFunction?

If the above is true, then does the GlobalVariable constructor need to
take a Context argument? It seems it should be able to infer it from
the Module argument.

-- John T.

Owen Anderson wrote:
Can you give a brief example of where to find the LLVMContext within a
ModulePass or FunctionPass? Is this just the context stored within the
Module or Function passed to runOnModule/runOnFunction?

Passes have a protected Context member, which is set for them by the PassManager, if you don’t override doInitialization. If you do, yes, you can fetch it from the Module or the Function.

If the above is true, then does the GlobalVariable constructor need to
take a Context argument? It seems it should be able to infer it from
the Module argument.

The GlobalVariables can be (and are, for the create_sentinel() methods) constructed with null for the Module argument.

–Owen

Chris has proposed, and I am planning to implement, a solution to this whereby there will be two GV constructors: one that takes a mandatory Module, and one that takes a mandatory Context, which should cut down on the redundancy.

--Owen