为LLVM 10 C++ API禁用常量折叠

wfypjpf4  于 2023-04-29  发布在  其他
关注(0)|答案(2)|浏览(128)

我正在使用LLVM C++ API为C语言的一个子集编写编译器前端。我注意到生成的IR总是应用了恒定的折叠优化。但我想禁用它,并获得一个忠实的,未优化的IR。有什么办法可以做到这一点吗?
下面是我用来从模块中生成IR的代码。

llvm::verifyModule(kit.module, &llvm::outs());
    kit.module.print(llvm::outs(), nullptr);
    auto tirFile = "output.ir";
    error_code ec;
    llvm::raw_fd_ostream tirFileStream(tirFile, ec, llvm::sys::fs::F_None);
    kit.module.print(tirFileStream, nullptr);
    tirFileStream.flush();

我使用的LLVM版本是LLVM 10。

sumit@HAL9001:~$ llvm-config --version
10.0.0

例如,当我在下面的C函数上运行编译器时

int arith() {
  return (10 - 10/3) << 3 | (23+8*12) & 1024;
}

它被编译成

define i32 @arith() {
entry:
  ret i32 56
}

对常量的二进制操作由编译器本身进行评估,即。e.恒定折叠;它不会被转换成合适的红外线代码

tsm1rwdh

tsm1rwdh1#

引用自this link
前端将代码降低到IR的方式导致这种常量折叠甚至在生成任何LLVM IR之前发生。本质上,当你进行AST遍历时,你会看到下面的代码运行:

IRBuilder<> Builder; Value *LHS = Builder.getInt32(2); 
Value *RHS = Builder.getInt32(4); // LHS and RHS are ConstantInt values because they’re constant expressions.
Value *Res = Builder.CreateMul(LHS,RHS); // Because LHS and RHS are constant values, the IRBuilder folds this to a constant expression.

无法关闭此恒定折叠。(我还假设在Clang AST级别没有其他恒定的折叠)。

nr9pn0ug

nr9pn0ug2#

在LLVM 11中,您可以使用IRBuilder<llvm::NoFolder>而不是IRBuilder<>
我很确定它也适用于LLVM 10(尽管我还没有验证)。
别忘了#include <llvm/IR/NoFolder.h>:)

相关问题