我有一個遺留的C++應用程序,它構造了一個C++對象樹。我想使用LLVM調用類構造函數來創建所述樹。生成的LLVM代碼是相當直接的,看起來像的重複序列:LLVM JIT性能差
; ...
%11 = getelementptr [11 x i8*]* %Value_array1, i64 0, i64 1
%12 = call i8* @T_string_M_new_A_2Pv(i8* %heap, i8* getelementptr inbounds ([10 x i8]* @0, i64 0, i64 0))
%13 = call i8* @T_QueryLoc_M_new_A_2Pv4i(i8* %heap, i8* %12, i32 1, i32 1, i32 4, i32 5)
%14 = call i8* @T_GlobalEnvironment_M_getItemFactory_A_Pv(i8* %heap)
%15 = call i8* @T_xs_integer_M_new_A_Pvl(i8* %heap, i64 2)
%16 = call i8* @T_ItemFactory_M_createInteger_A_3Pv(i8* %heap, i8* %14, i8* %15)
%17 = call i8* @T_SingletonIterator_M_new_A_4Pv(i8* %heap, i8* %2, i8* %13, i8* %16)
store i8* %17, i8** %11, align 8
; ...
如果每個T_
函數是C「形實轉換」調用一些C++的構造函數,例如:
void* T_string_M_new_A_2Pv(void *v_value) {
string *const value = static_cast<string*>(v_value);
return new string(value);
}
的的thunk當然是必要的,因爲LLVM對C++一無所知。 T_
功能通過ExecutionEngine::addGlobalMapping()
添加到使用中的ExecutionEngine
。
當這段代碼被JIT調用時,JIT本身的性能非常差。我使用kcachegrind
生成call-graph。我不明白所有的數字(這個PDF似乎不包括逗號),但是如果你看左邊的叉子,底部的兩個橢圓,Schedule...
被稱爲16K倍,而setHeightToAtLeas...
被稱爲37K倍。在右側的叉子上,RAGreed...
被稱爲35K次。
這些太多的電話什麼什麼是call
LLVM指令的簡單序列。有些東西似乎是可怕的錯誤。
關於如何提高JIT'ing性能的任何想法?
這將是一個很好的問題到LLVM郵件列表我已經問LLv郵件列表llvmdev郵件列表 –
。最初只有1個人回覆,但經過繼續討論後,停止了回覆。 –
你有沒有機會用-o3編譯?另外,值得看看生成的代碼。您提到的功能 - 調度和寄存器分配(RAGreed) - 是LLVM IR已經降低並且不再像原始版本很長時間之後的代碼階段的一部分。 – Oak