[LLVMdev] Generating PIC object files from the LLVM API

Tim Northover t.p.northover at gmail.com
Wed Jan 8 11:29:38 PST 2014


On 8 January 2014 16:55, Josh Klontz <josh.klontz at gmail.com> wrote:
> Thanks for the quick response. I was able fix the problem by generating the
> target machine like llc does with:
>
>     TargetRegistry::lookupTarget(<...>)->createTargetMachine(<...>)
>
> Working backwards from there, it became apparent that the cause of the issue
> was EngineBuilder's default code model was CodeModel::JITDefault but what I
> needed for static code generation was CodeModel::Default.

Interesting. Glad you sorted it, anyway!

> Is there any documentation on CodeModel? I couldn't find any in the usual
> places.

Well, it maps to the GCC option "-mcmodel" with common values "tiny",
"small", "medium", "large" & "kernel". Unfortunately what each of
those means (and even whether it's a valid option) is completely
target specific.

The outline is that by specifying one you're promising the compiler
that all your code and statically allocated data will be within
certain bounds, size-wise (& location). With that promise in hand, it
can use more efficient code sequences. For example on x86_64 it can
reference global variables using something like ("small" model == all
code and static data are in low 2GB of memory):

    movl var(%rip), %eax

rather than ("large" model == code and static data can be anywhere in
64-bit address space):

   movabsq $var, %ebx
   movl (%rbx), %eax

Of course, just where the boundaries between these models should be
placed depends on what instructions your CPU has. And so CPU designers
specify just what each mode means on their target.

I *think* this affected you because LLVM defaults to "large" for JIT,
which doesn't have good support for PIC. For static codegen it
defaults to "small", which is where most C & C++ code is compiled so
obviously supports PIC rather well.

Cheers.

Tim.



More information about the llvm-dev mailing list