2012-05-12 50 views
3

我需要在運行時使用LLVM內聯幾個函數。複雜的是,這些功能是在不同的位碼文件中定義的。來自LLVM中不同文件的內聯代碼

在運行時,我需要的功能,如

void snippet1();   //declaring that snippet1 and 2 are defined in snippet1.c and snippet2.c 
void snippet2(); 

void combo12(){ 
    snippet1(); 
    snippet1(); 
    snippet2(); 
    snippet2(); 
} 

從從combo12.c,snippet1.c和snippet2.c編譯獨立LLVM位碼文件生成代碼。事情是,我需要在combo12中將所有調用內聯到snippet1和snippet2。我試圖做到這一點使用下面的代碼(main.cpp中):

OwningPtr<MemoryBuffer> MB, MB2, MB3; 
Module *M1, *M2, *MC12, *MOUT; 
LLVMContext Context; 
std::string ErrorStr; 

MemoryBuffer::getFile("snippet1.bc", MB); 
M1 = ParseBitcodeFile(MB.get(), Context); 

MemoryBuffer::getFile("snippet2.bc", MB2); 
M2 = ParseBitcodeFile(MB2.get(), Context);  

MemoryBuffer::getFile("combo12.bc", MB3); 
MC12 = ParseBitcodeFile(MB3.get(), Context);  

Linker* L; 

L = new Linker("testprog", M1, 0); 

L->setFlags(llvm::Linker::Verbose); 

if (!(L->LinkInModule(M2, &ErrorStr))) 
    std::cout << ErrorStr; 

if (!(L->LinkInModule(MC12, &ErrorStr))) 
    std::cout << ErrorStr; 

MOUT = L->getModule(); 

MOUT->dump(); 

PassManager *PM; 

PM = new PassManager(); 

PM->add(createInternalizePass(true)); 

PM->add(createAlwaysInlinerPass()); 

if (PM->run(*MOUT)){ 
    std::cout << "\n\n\nCode was altered!\n\n\n" << std::endl; 
    MOUT->dump(); 
    std::cout << "\n\n ALTERED BEAST \n\n" << std::endl; 
} 

snippet1.c:

//What this function does is irrelevant 
#include "post_opt.h"  //contains the struct exstr declaration 
extern struct exstr a; 
inline void snippet1() __attribute((always_inline)); 
void snippet1(){ 
    int x, y; 
    a.b = 10; 
    x = 2; 
    if(x < a.a){ 
     y = x + 1; 
    } 
} 

我編譯snippet1.c,snippet2.c和combo12.c使用

clang -c -emit-llvm snippet1.c -o snippet1.bc -O0 
clang -c -emit-llvm snippet2.c -o snippet2.bc -O0 
clang -c -emit-llvm combo12.c -o combo12.bc -O0 

而且main.cpp中與

clang++ -g main.cpp `llvm-config --cppflags --ldflags --libs --cppflags --ldflags --libs core jit native linker transformutils ipo bitreader` -O0 -o main 

當我運行./main,它沒有內聯代碼片段,儘管我明確地標記了帶有always_inline屬性的函數,並使用了AlwaysInline傳遞。它從不在屏幕上打印ALTERED BEAST。

爲什麼會發生這種情況?我認爲,通過將所有模塊連接在一起並應用首次公開發行(AlwaysInline),這可以解決問題。

感謝您的任何見解!

+0

你有沒有想過?我有同樣的問題,我有包裝llvm.uadd.with.overflow。*但我希望他們內聯。 – stribika

+0

您是否注意到http://llvm.org/docs/LinkTimeOptimization.html? –

回答

2

內聯發生在編譯期間,而不是鏈接和內聯僅在編譯時與完全定義的函數一起使用。因此,從其他文件內聯函數是不可能的(因爲編譯文件時會忽略其他文件)。唯一的解決方案是在每個需要內聯函數的文件中定義函數。