簡體   English   中英

clang:使用 O3 導出隱式實例化函數的符號

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM