compiler-construction - 如何避免 LLVM 的代码生成器执行不需要的常量折叠?

标签 compiler-construction garbage-collection llvm relocation llc

我试图实现的是避免一些常量(代表我代码中的地址)的常量折叠,例如 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 代码常量(例如,调用您知道的特定地址),那么您所做的就很好。

关于compiler-construction - 如何避免 LLVM 的代码生成器执行不需要的常量折叠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31793180/

相关文章:

compiler-construction - 编译 Debug模式时出错 : C++/CLI - error LNK2022

scala - 未推断多参数闭包参数类型

Java:关于调用 Runtime.freeMemory()、Runtime.totalMemory() 和 Runtime.maxMemory() 的成本

java - 在一次采访中有人问我如何检测 Java 中的内存泄漏?

c# - 如何在C#中实现泛型(可能与C++和Java有关)?

java - Java中的内存使用

iphone - NSAssert undeclared first use 为什么?

objective-c - self.iVar 是否需要 ARC 的强大属性?

objective-c - LLVM 3.0 上 switch 语句的意外行为

c++ - 如何将头文件放入 Bison 中的 .tab.h?