如何避免 LLVM 的代码生成器执行不希望的常量折叠?
How to avoid undesired constant folding performed by LLVM's code generator?
我想要实现的是避免对某些常量(在我的代码中表示地址)进行常量折叠,例如下面的 100000000
常量。我需要这个,因为稍后可能会修补 JIT 编译的代码,这会因对象重定位而更改常量。
下面的代码是我为避免常量折叠所做的最大努力(不惜一切代价)。它不起作用。我最终在指令流中得到常量 100011111
。
llc -O0 code.ll -print-after-all
显示折叠发生在 Expand ISel Pseudo-instructions
关卡。
; ModuleID = '0'
target triple = "x86_64-unknown-linux-gnu"
define i64 @"0"() {
BlockEntry0:
%cell = alloca i64, align 8
store volatile i64 0, i64* %cell, align 8
%volatile_zero3 = load volatile i64, i64* %cell, align 8
%base = add i64 %volatile_zero3, 100000000
%volatile_zero4 = load volatile i64, i64* %cell, align 8
%opaque_offset = add i64 %volatile_zero4, 11111
%casted_base = inttoptr i64 %base to i8*
%gep = getelementptr i8, i8* %casted_base, i64 %opaque_offset
%as_ptr = bitcast i8* %gep to i64*
%loaded = load i64, i64* %as_ptr, align 4
%as_function = inttoptr i64 %loaded to i64 (i64)*
%ret_val = tail call i64 %as_function(i64 0)
ret i64 %ret_val
}
attributes #0 = { nounwind }
我意识到我的问题可以通过添加一些内在代码来解决,这些内在代码在代码生成级别会展开为简单 movabs reg, imm64
。但我想暂时有一个临时解决方案。
问题:是否可以在 llvm 中创建一个不常量折叠的不透明常量?
我的llvm版本是3.7.0svn。
不,这不可能。最好的办法是使用评论中提到的外部全局变量。事实上,出于您的目的,它可能正是您想要做的,因为那时您的 jittable 代码将根据您实际想要的进行重定位,并在执行时由 rtdyld 进行相应的修补。
如果你想要一个实际的常量用于 jitted 代码(例如调用你知道的特定地址)那么你正在做的就很好。
我想要实现的是避免对某些常量(在我的代码中表示地址)进行常量折叠,例如下面的 100000000
常量。我需要这个,因为稍后可能会修补 JIT 编译的代码,这会因对象重定位而更改常量。
下面的代码是我为避免常量折叠所做的最大努力(不惜一切代价)。它不起作用。我最终在指令流中得到常量 100011111
。
llc -O0 code.ll -print-after-all
显示折叠发生在 Expand ISel Pseudo-instructions
关卡。
; ModuleID = '0'
target triple = "x86_64-unknown-linux-gnu"
define i64 @"0"() {
BlockEntry0:
%cell = alloca i64, align 8
store volatile i64 0, i64* %cell, align 8
%volatile_zero3 = load volatile i64, i64* %cell, align 8
%base = add i64 %volatile_zero3, 100000000
%volatile_zero4 = load volatile i64, i64* %cell, align 8
%opaque_offset = add i64 %volatile_zero4, 11111
%casted_base = inttoptr i64 %base to i8*
%gep = getelementptr i8, i8* %casted_base, i64 %opaque_offset
%as_ptr = bitcast i8* %gep to i64*
%loaded = load i64, i64* %as_ptr, align 4
%as_function = inttoptr i64 %loaded to i64 (i64)*
%ret_val = tail call i64 %as_function(i64 0)
ret i64 %ret_val
}
attributes #0 = { nounwind }
我意识到我的问题可以通过添加一些内在代码来解决,这些内在代码在代码生成级别会展开为简单 movabs reg, imm64
。但我想暂时有一个临时解决方案。
问题:是否可以在 llvm 中创建一个不常量折叠的不透明常量?
我的llvm版本是3.7.0svn。
不,这不可能。最好的办法是使用评论中提到的外部全局变量。事实上,出于您的目的,它可能正是您想要做的,因为那时您的 jittable 代码将根据您实际想要的进行重定位,并在执行时由 rtdyld 进行相应的修补。
如果你想要一个实际的常量用于 jitted 代码(例如调用你知道的特定地址)那么你正在做的就很好。