0

I am looking at a llvm ir file converted from a cpp file by clang. But I found there were several functions in llvm ir file only with declaration without definition. And all these functions are not the "build-in" functions like:

declare i32 @puts(i8* nocapture)

It's like:

declare void @_ZNK5Arrow7BaseRow9getColumnINS_11IpGenPrefixEEEvtRT_(%"class.Arrow::BaseRow"*, i16 zeroext, %"class.Arrow::IpGenPrefix"* dereferenceable(24)) #0

It seems like those functions are using some external definition? I am new to LLVM IR. And I was wondering is there a way that LLVM IR can do like cpp library, I can store the functions I will use in some LLVM IR libraries and use them in a .ll file by just do something like include ?

Thanks

He Yucheng
  • 31
  • 3
  • Are you sure you include the file in which `Arrow::BaseRow::getColumn` is defined? – eush77 Jul 27 '16 at 07:27
  • No, there is no include declaration type. It may be achieved, obviously, by some utility that would insert the declarations. – Frank C. Jul 28 '16 at 09:12
  • @eush77 As I mentioned, this llvm ir is converted from a cpp file with clang. The cpp file include the file in which getColumn is defined. But I was wondering when I use MCJIT to execute the function in llvm ir, how would I execute the function only declared in llvm ir without definition. Is there any way the function in llvm ir only declared and defined in other files like(cpp file)? And how can I generate this kind of function? – He Yucheng Aug 01 '16 at 18:41

1 Answers1

1

It seems like those functions are using some external definition?

Exactly. declare keyword indicates a function declaration, as opposed to function definition, and function declarations can only be linked externally:

It is illegal for a function declaration to have any linkage type other than external or extern_weak.

The reason Clang generated declarations instead of definitions is (most likely) that these functions were not defined in the translation unit that was given to it.

The declarations are resolved during linking. To link several LLVM modules together, use llvm-link tool.

For example, suppose lib.cpp defines function foo() which is used in main.cpp.

$ clang++ -c -emit-llvm main.cpp lib.cpp

This command compiles these files to LLVM IR and creates two modules main.bc and lib.bc. main.bc contains just a declaration of foo() because this function is defined in a separate translation unit. The definition of foo() is in lib.bc.

$ llvm-link main.bc lib.bc -o all.bc

This command links main.bc and lib.bc into a single module, which now contains the definition of foo().

eush77
  • 3,870
  • 1
  • 23
  • 30
  • In my case, I have three files: `main.cpp` `lib.cpp` and `func.cpp`: FIRST: `func.cpp` has a function `foo()` which use the function `foo1()` in `lib.cpp`, and `func.cpp` was converted into `func.ll` by clang SECOND: `main.cpp` using `parseIRFile` to extract the function `foo()` in `func.ll` and call it. Q: the function `func.ll` only has the declaration of `foo1()` without definition. While `main.cpp` did not include `lib.h`, without definition in `func.ll`, how to execute `foo1()` without definition in llvm ir. If we could, how can we genrate this kind of function in llvm ir manually. – He Yucheng Aug 01 '16 at 18:54
  • @He Well, does it fail when you compile and call `foo()` this way? Do you link `lib.cpp` into `main.cpp` so that `foo1` is present and externally visible in the object file? LLVM should find `foo1()` by name when there's no definition given. See http://stackoverflow.com/a/6086687/2424184 – eush77 Aug 01 '16 at 21:42
  • Thanks for helping. It did not fail. But I want to generate llvm ir manually, so I was wondering is there anyway I can use cpp functions in llvm ir, and how we can do this. In other words, I want my llvm ir can use the function defined in cpp file. I know I need to declare the function in llvm ir, but how can I link this declaration to the definition in cpp. – He Yucheng Aug 03 '16 at 14:48
  • @He (1) This should happen automatically by function name, regardless of how LLVM IR is generated, whether by Clang or your own code. It might fail though due to name mangling. (2) Then your other option is to get LLVM function from module using `Module::getFunction` and map it manually with `ExecutionEngine::addGlobalMapping` to the address of the target C++ function. – eush77 Aug 03 '16 at 18:57
  • You mean by function name is the name in llvm ir like `_ZNK5Arrow7BaseRow9getColumnINS_11IpGenPrefixEEEvtRT_` or by the function name in cpp `getColumn`. So basically I just declare the external function in llvm ir, and when I use MCJIT, it will resolve the function by itself? Btw, thank you very much for your help. – He Yucheng Aug 03 '16 at 21:45
  • @He Yeah, I mean when function declaration for `@getColumn` gets compiled, it'll try to link to the function named `getColumn` in the object file. It works in C, but I'm not sure if it works with C++ name mangling correctly. In C++ source, you can try to wrap the function in `extern "C"` to disable mangling. – eush77 Aug 03 '16 at 22:45