llvm:如何获取Basic Blocks的标签

时间:2014-10-09 15:05:22

标签: llvm llvm-c++-api

我已经编写了一个传递来检测和打印函数中基本块的标签,因为我想进一步使用splitBasicBlock()。我这样写的是:

virtual bool runOnModule(Module &M)
{
    for(Module::iterator F = M.begin(), E = M.end(); F!= E; ++F)
    {
        errs()<<"Function:"<<F->getName()<<"\n";
        //for(Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
        for (iplist<BasicBlock>::iterator iter = F->getBasicBlockList().begin();
                    iter != F->getBasicBlockList().end();
                    iter++)
        {
          BasicBlock* currBB = iter;
          errs() << "BasicBlock: "  << currBB->getName() << "\n";   
        }
    }
    return true;
}

IR文件如下所示:

; <label>:63                                      ; preds = %43
  %64 = load i32* %j, align 4
  %65 = sext i32 %64 to i64
  %66 = load i8** %tempdst, align 8
  %67 = getelementptr inbounds i8* %66, i64 %65
  store i8 -1, i8* %67, align 1
  br label %73

; <label>:68                                      ; preds = %43
  %69 = load i32* %j, align 4
  %70 = sext i32 %69 to i64
  %71 = load i8** %tempdst, align 8
  %72 = getelementptr inbounds i8* %71, i64 %70
  store i8 0, i8* %72, align 1
  br label %73

; <label>:73                                      ; preds = %68, %63
  br label %74

然而,我对标签一无所知:

Function:main
BasicBlock:
BasicBlock:
BasicBlock:

这些“无名”基本块有什么问题?我该怎么办?

5 个答案:

答案 0 :(得分:9)

LLVM IR中的值不需要具有名称;事实上,那些基本块没有名称,这就是你从currBB->getName()得到一个空字符串的原因。

它们在LLVM IR打印输出中具有名称的原因是因为当您打印到LLVM IR的文本格式(因为它出现在.ll文件中)时,您必须为它们指定一个名称以使它们具有可参考性,因此打印机将顺序数字名称分配给基本块(和其他值)。但是,这些数字名称仅由打印机创建,并且实际上并不存在于模块中。

答案 1 :(得分:8)

虽然BasicBlocks可能没有名称(由hasName()方法指示),但可以使用currBB->printAsOperand(errs(), false)打印唯一的BasicBlock标识符,而不是errs() currBB->getName()的值%68 }。对于未命名的BasicBlock,这将提供数字基本块表示,例如WANTED

答案 2 :(得分:0)

我认为现在LLVM的行为是不同的。 我使用类似的代码行,可以在LLVM-4.0上获得标签的名称

for (auto &funct : m) {
            for (auto &basic_block : funct) {
            StringRef bbName(basic_block.getName());
                errs() << "BasicBlock: "  << bbName << "\n";
            }
}

答案 3 :(得分:0)

正如ElazarR所说,currBB->printAsOperand(errs(), false)会在错误流中打印出这样的ID,但如果这对你的逻辑更有意义,也可以将它存储在一个字符串中。

在LLVM CFG生成传递-dot-cfg中,它们始终使用BB的名称(如果有)或其表示形式为字符串命名基本块。此逻辑存在于CFGPrinter.h标题(http://llvm.org/doxygen/CFGPrinter_8h_source.html#l00063)中:

static std::string getSimpleNodeLabel(const BasicBlock *Node,
                                      const Function *) {
    if (!Node->getName().empty())
        return Node->getName().str();

    std::string Str;
    raw_string_ostream OS(Str);

    Node->printAsOperand(OS, false);
    return OS.str();
}

您可以使用此逻辑始终返回基本块的有效名称。

答案 4 :(得分:0)

使用clang将源代码编译为位代码时,请使用以下标志

-fno-discard-value-names

您将获得基本块的名称作为唯一字符串