使用 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。这样你就可以确保创建的加法不会是常量。