我已经编写了一个传递来检测和打印函数中基本块的标签,因为我想进一步使用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:
这些“无名”基本块有什么问题?我该怎么办?
答案 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
您将获得基本块的名称作为唯一字符串