[英]clang: export symbols of implicitly instantiated functions with 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)。
使用clang++ -O0 -I/usr/local/opt/llvm/include -L/usr/local/opt/llvm/lib/ jit.cpp -lLLVM
(OS X 上的 clang 版本 6.0.0),輸出符合預期:
10
15
address of twice: 4350763184
address of thrice: 4350762224
如果啟用優化,則不會再導出twice
符號,如nm a.out | grep twice
nm a.out | grep twice
:
00000001000010b0 T __Z5twiceIiEiRKT_ (with -O0)
00000001000009c0 t __Z5twiceIiEiRKT_ (with -O3)
結果,libLLVM 不再找到該函數:
10
15
address of twice: 0
address of thrice: 4315621072
使用 gcc,符號被導出。
如果我明確實例化它,我可以讓 clang 導出符號:
template int twice<int>(const int& t);
然而,這並不是一個真正的選擇,因為我們不知道 JIT 引擎將調用哪些實例化。
我知道這篇文章,但它只涉及顯式實例化。
添加屬性used
,如下所示:
template <typename T>
__attribute__((used))
int twice(const T& t) {
return t * 2;
}
這將強制 Clang 導出符號。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.