what is the right abstraction for compilation unit in LLVM?
Asked Answered
L

2

6

in LLVM we have the LLVMContext, which is the unit of storage, and we have the llvm::Module, which is where new symbols (functions and types) are built.

my question is; what is the right llvm abstraction to use for compilation units? is the Module? or is this actually meant for a bigger scope, i.e: a shared library target

It seems to me that a compilation unit must satisfy an all-or-nothing result; either it compiles all its content without errors, or either there are errors and it needs to be fixed and built again before any symbols in the CU are usable. In my head, this is the definition of what a compilation unit should represent

if module is the right abstraction for the CU, how do i present the symbols in other (correctly compiled) Module objects to a new module about to be built, in order that it is able to find those? do i need to add declarations or is there some other expedite way for this?

a point to a relevant line in clang would be of great help

Lifeline answered 23/3, 2012 at 16:47 Comment(5)
You're describing a linker problem, not a compiler problem. There's nothing in clang itself that would have anything to do with that. You need to look at the linking bits in LLVM.Brevet
not all symbol resolution can be delayed to the linking phase, specially in the case of types. In any case i'm concerned with llvm - i only mention clang because its the canonical client exampleLifeline
Ideally, you would just never, ever do compilation units as part of any compiler. As such, I would argue that there is no right abstraction for them.Holden
@DeadMG, can you elaborate your assertion? what you mean 'CU should not be part of any compiler'?Lifeline
i've added more context in another question: https://mcmap.net/q/321387/-design-suggestion-llvm-multiple-runtime-contexts/170521Lifeline
T
5

The Module is the correct abstraction for a compile unit. You can link together modules to do whole program analysis from there.

Theran answered 24/3, 2012 at 19:24 Comment(0)
L
4

this is an on-progress attempt to answer my own question:

The class llvm::Linker has the ability to take multiple Modules and return a single, composite Module back containing all the symbols in the existing modules. After the linking is done and the composite module is created, i'm still not clear what is the rules regarding ownership of the input modules.

In any case, the class should allow you to take an incremental path to growing a module. Say you are trying to implement a REPL, which means that you add new symbols to the global namespace:

The Outline of the REPL would work like:

  • write some function in REPL
  • compile the function as a single module, call it "base"
  • write some more functions in REPL
  • compile the new functions in a new module
  • if the new functions module compiles successfully, link "base" and the new module in a new module, call it "base.2"
  • rinse and repeat

    If you replace a symbol or function by name, you want that older symbols see the overriden version of your symbol. So when you are defining a new function, you need to make sure your getOrInsertFunction is called in the existing "base" module as well as the new one.

Lifeline answered 1/4, 2012 at 15:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.