clang: export symbols of implicitly instantiated functions with O3

假装没事ソ 提交于 2020-02-06 05:08:05

问题


TL,DR: How can I force clang to export the symbols of implicitly instantiated functions even when -O3 is active?

Let's take the following code:

#include <iostream>
#include <llvm/Support/DynamicLibrary.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/RTDyldMemoryManager.h>

template <typename T>
__attribute__((noinline))
int twice(const T& t) {
    return t * 2;
}

int thrice(const int& t) {
    return t * 3;
}

int main() {
    std::cout << twice(5) << std::endl;
    std::cout << thrice(5) << std::endl;

    llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);  // Make symbols from current process visible
    std::cout << "address of twice: " << llvm::RTDyldMemoryManager::getSymbolAddressInProcess("__Z5twiceIiEiRKT_") << std::endl;
    std::cout << "address of thrice: " << llvm::RTDyldMemoryManager::getSymbolAddressInProcess("__Z6thriceRKi") << std::endl;
}

There are two functions, twice and thrice. The first is templated, the second is not. I first call them regularly, then I try to get their address using libLLVM. Think of it as part of a super simplified JIT compiler (that has a mangler that comes up with the name).

With clang++ -O0 -I/usr/local/opt/llvm/include -L/usr/local/opt/llvm/lib/ jit.cpp -lLLVM (clang version 6.0.0 on OS X), the output is as expected:

10
15
address of twice: 4350763184
address of thrice: 4350762224

If I enable optimization, the symbol for twice does not get exported anymore, as seen in nm a.out | grep twice:

00000001000010b0 T __Z5twiceIiEiRKT_ (with -O0)
00000001000009c0 t __Z5twiceIiEiRKT_ (with -O3)

As a result, libLLVM does not find the function anymore:

10
15
address of twice: 0
address of thrice: 4315621072

With gcc, the symbols get exported.

I can get clang to export the symbol if I explicitly instantiate it:

template int twice<int>(const int& t);

That, however, is not really an option, as we don't know which instantiations will be called by the JIT engine.

I am aware of this post, but it only deals with explicit instantiations.


回答1:


Add attribute used, like this:

template <typename T>
__attribute__((used))
int twice(const T& t) {
    return t * 2;
}

That will force Clang to export the symbol.



来源:https://stackoverflow.com/questions/52211379/clang-export-symbols-of-implicitly-instantiated-functions-with-o3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!