Reputation: 1293
I'm using the LLVM C++ API to write a compiler front-end for a subset of the C language. I've noticed the generated IR always has the constant folding optimization applied. But I want to disable this and get a faithful, unoptimized IR. Is there any way to do this?
Following is the code I'm using to generate IR from my module.
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();
Seems like the version of LLVM I'm using is LLVM 10.
sumit@HAL9001:~$ llvm-config --version
10.0.0
For example, when I run my compiler on the following C function
int arith() {
return (10 - 10/3) << 3 | (23+8*12) & 1024;
}
It gets compiled to
define i32 @arith() {
entry:
ret i32 56
}
The binary operations on constants are evaluated by the compiler itself, i.e. constant folding; it doesn't get translated to appropriate IR code.
Upvotes: 2
Views: 1147
Reputation: 41
In LLVM 11 you can use
IRBuilder<llvm::NoFolder>
instead of IRBuilder<>
I'm pretty sure it works for LLVM 10 too (although I haven't verified that).
Don't forget to #include <llvm/IR/NoFolder.h>
:)
Upvotes: 4
Reputation: 57
Quoting from this link:
The way that the front-end lowers code to IR causes this sort of constant folding to happen even before any LLVM IR is generated. Essentially, when you do the AST traversal, you’re going to essentially see the following code get run:
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.
This constant folding cannot be turned off. (I’m also assuming there’s no other constant folding going on at the Clang AST level).
Upvotes: 1