1

我有一个遗留的 C++ 应用程序,它构造了一个 C++ 对象树。我想使用 LLVM 调用类构造函数来创建所述树。生成的 LLVM 代码相当简单,看起来像以下重复序列:

; ...
%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“thunk”,例如:

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使用中ExecutionEngine::addGlobalMapping()

当这段代码是 JIT'd 时,JIT'ing 本身的性能很差。我已经使用. kcachegrind我不明白所有的数字(而且这个 PDF 似乎没有在它应该包含逗号的地方包含逗号),但是如果你看一下左叉,底部的两个椭圆,Schedule...被称为 16K 次,setHeightToAtLeas...被称为 37K 次。在右分叉上,RAGreed...被调用了 35K 次。

对于大多数简单的LLVM 指令序列来说,这些调用太多了。call似乎有些不对劲。

关于如何提高 JIT'ing 性能的任何想法?

4

1 回答 1

0

如果不改变 JIT 的工作方式或查看您尝试 JIT 的特定调用,则不太可能发生另一个数量级。您可以在 llc -O0 上启用 -fast-isel-verbose(例如 llc -O0 -fast-isel-verbose mymodule.[ll,bc])并让它告诉您它是否回退到用于指令生成的选择 dag。您可能想再次分析并查看当前热点是什么。

于 2012-11-14T01:08:53.380 回答