clang:使用O3导出隐式实例化函数的符号 [英] clang: export symbols of implicitly instantiated functions with O3

查看:365
本文介绍了clang:使用O3导出隐式实例化函数的符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL,DR:即使-O3处于活动状态,如何强制clang导出隐式实例化函数的符号?

让我们采用以下代码:

#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;
}

有两个函数,两次和三次.第一个是模板化的,第二个不是模板化的.我先定期给他们打电话,然后尝试使用libLLVM获取他们的地址.可以将它视为超级简化的JIT编译器的一部分(该编译器带有随名称而来的mangler).

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).

使用clang++ -O0 -I/usr/local/opt/llvm/include -L/usr/local/opt/llvm/lib/ jit.cpp -lLLVM(在OS X上为clang版本6.0.0),输出符合预期:

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

如果启用优化,则twice的符号将不再导出,如nm a.out | grep twice所示:

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)

结果是,libLLVM不再找到该功能:

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

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

使用gcc可以导出符号.

With gcc, the symbols get exported.

如果我显式实例化它,我可以用clang导出该符号:

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

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

但是,这并不是真正的选择,因为我们不知道JIT引擎将调用哪些实例化.

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.

推荐答案

添加属性used,如下所示:

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

这将迫使Clang导出符号.

That will force Clang to export the symbol.

这篇关于clang:使用O3导出隐式实例化函数的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆