使用 C++ API 打印 LLVM IR 以调试 IR 生成
Printing LLVM IR with c++ API for debugging IR generation
我目前正在使用 LLVM 12 C++ API 将自定义设计特定语言转换为 LLVM IR 代码。但是,我正在 运行 处理生成的 IR 代码中的一些错误。
你能给我指出正确的方向吗,看看我如何打印出我的 llvm::Module.
中包含的生成的 IR 代码
我尝试使用这个最小的示例代码
#include <iostream>
#include "llvm/ADT/APFloat.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/IRPrintingPasses.h"
int main(){
// initialize the context, builder and module
llvm::LLVMContext TheContext;
llvm::IRBuilder<> Builder(TheContext);
std::unique_ptr<llvm::Module> TheModule;
TheModule = std::make_unique<llvm::Module>("my jit module", TheContext);
// generate an example IR code
/* (in reality this will be complex code running through the
language AST and making appropriate calls to the Builder
to add the IR instructions) */
auto L = llvm::ConstantFP::get(TheContext, llvm::APFloat(5.0));
auto R = llvm::ConstantFP::get(TheContext, llvm::APFloat(7.0));
auto IR = Builder.CreateFAdd(L, R, "addtmp");
IR->print(llvm::errs()); // method 0 for printing IR
fprintf(stderr,"\n");
// outputs: "double 1.200000e+01"
// method 0 is unacceptable, as I would have to manually manage the
// printing calls and their printing order after each call to generate an IR instruction
// this manual way of managing can easily lead to
// out of order printing or omissions in printing, leading to further confusion in the debug process
// now the IR generation is completed
// print out the IR code contained in TheModule
TheModule->print(llvm::errs(),nullptr,false,true); // method 1
// and
TheModule->dump(); // method 2
// and
llvm::errs()<< *TheModule; // method 3
// and
std::unique_ptr<llvm::legacy::PassManager> TheMPM;
TheMPM = std::make_unique<llvm::legacy::PassManager>();
TheMPM->add(llvm::createPrintModulePass(llvm::errs()));
TheMPM->run(*TheModule); // method 4
// Perform JIT compilation of the IR code
// (this works fine but am getting incorrect results
// and hence want to print out the IR code to see if
// I am getting what I assume I should be getting)
return 0;
}
但是所有四种方法都只给我一个看起来像
的标准输出
; ModuleID = 'my jit module'
source_filename = "my jit module"
并且没有显示红外代码。我知道模块有 IR 代码,因为我可以成功地 JIT 编译模块和 运行 代码。
你能告诉我打印模块中包含的 LLVM IR 的正确方法吗?
(首先,请原谅我的愚蠢评论。我正在排队消磨时间,显然我的思绪并没有真正投入。现在回到我的办公桌。)
您的代码创建了一个模块、两个常数和一个加法。但是,加法可以是常量或指令。如果是后者,则指令需要在基本块中,块在函数中,函数在模块中。 LLVM 不提供在模块中但在所有函数之外的指令。
由于您没有函数(和基本块),因此您的添加必然是 a constant。
我建议你创建两个函数,a(float) 和 b(),让 b() 调用 a(7.0),将加法放在 a 的入口块中,并使其将 5.0 添加到 a 的参数而不是 5.0 +7.0。这样你就可以确保创建的加法不会是常量。
我目前正在使用 LLVM 12 C++ API 将自定义设计特定语言转换为 LLVM IR 代码。但是,我正在 运行 处理生成的 IR 代码中的一些错误。
你能给我指出正确的方向吗,看看我如何打印出我的 llvm::Module.
中包含的生成的 IR 代码我尝试使用这个最小的示例代码
#include <iostream>
#include "llvm/ADT/APFloat.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/IRPrintingPasses.h"
int main(){
// initialize the context, builder and module
llvm::LLVMContext TheContext;
llvm::IRBuilder<> Builder(TheContext);
std::unique_ptr<llvm::Module> TheModule;
TheModule = std::make_unique<llvm::Module>("my jit module", TheContext);
// generate an example IR code
/* (in reality this will be complex code running through the
language AST and making appropriate calls to the Builder
to add the IR instructions) */
auto L = llvm::ConstantFP::get(TheContext, llvm::APFloat(5.0));
auto R = llvm::ConstantFP::get(TheContext, llvm::APFloat(7.0));
auto IR = Builder.CreateFAdd(L, R, "addtmp");
IR->print(llvm::errs()); // method 0 for printing IR
fprintf(stderr,"\n");
// outputs: "double 1.200000e+01"
// method 0 is unacceptable, as I would have to manually manage the
// printing calls and their printing order after each call to generate an IR instruction
// this manual way of managing can easily lead to
// out of order printing or omissions in printing, leading to further confusion in the debug process
// now the IR generation is completed
// print out the IR code contained in TheModule
TheModule->print(llvm::errs(),nullptr,false,true); // method 1
// and
TheModule->dump(); // method 2
// and
llvm::errs()<< *TheModule; // method 3
// and
std::unique_ptr<llvm::legacy::PassManager> TheMPM;
TheMPM = std::make_unique<llvm::legacy::PassManager>();
TheMPM->add(llvm::createPrintModulePass(llvm::errs()));
TheMPM->run(*TheModule); // method 4
// Perform JIT compilation of the IR code
// (this works fine but am getting incorrect results
// and hence want to print out the IR code to see if
// I am getting what I assume I should be getting)
return 0;
}
但是所有四种方法都只给我一个看起来像
的标准输出; ModuleID = 'my jit module'
source_filename = "my jit module"
并且没有显示红外代码。我知道模块有 IR 代码,因为我可以成功地 JIT 编译模块和 运行 代码。
你能告诉我打印模块中包含的 LLVM IR 的正确方法吗?
(首先,请原谅我的愚蠢评论。我正在排队消磨时间,显然我的思绪并没有真正投入。现在回到我的办公桌。)
您的代码创建了一个模块、两个常数和一个加法。但是,加法可以是常量或指令。如果是后者,则指令需要在基本块中,块在函数中,函数在模块中。 LLVM 不提供在模块中但在所有函数之外的指令。
由于您没有函数(和基本块),因此您的添加必然是 a constant。
我建议你创建两个函数,a(float) 和 b(),让 b() 调用 a(7.0),将加法放在 a 的入口块中,并使其将 5.0 添加到 a 的参数而不是 5.0 +7.0。这样你就可以确保创建的加法不会是常量。