llvm:如何获得基本块的标签
我已经编写了一个过程来检测并打印函数中基本块的标签,因为我想进一步使用llvm:如何获得基本块的标签,llvm,llvm-c++-api,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";
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;
}
; <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
这些“未命名”的基本块有什么问题?我该怎么办?LLVM IR中的值不需要有名称;事实上,这些基本块没有名称,这就是为什么从
currb->getName()
得到一个空字符串的原因
它们在LLVM IR打印输出中具有名称的原因是,当您打印到LLVM IR的文本格式(如.ll文件中所示)时,您必须为它们指定名称以使其可引用,因此打印机会为基本块(和其他值)指定顺序数字名称。但是,这些数字名称仅由打印机创建,实际上并不存在于模块中。虽然基本锁可能没有名称(如
hasName()
方法所示),但可以使用currBB->printAsOperand(errs(),false)
打印唯一的基本锁标识符,而不是流式输入errs()
currBB->getName()的值。对于未命名的基本块,这将提供数字基本块表示,例如%68
我认为LLVM现在的行为有所不同。
我使用类似的代码行,可以在LLVM-4.0上获取标签的名称
for (auto &funct : m) {
for (auto &basic_block : funct) {
StringRef bbName(basic_block.getName());
errs() << "BasicBlock: " << bbName << "\n";
}
}
for(自动和功能:m){
用于(自动和基本功能块:funct){
StringRef bbName(basic_block.getName());
errs()正如Elazar所说,currBB->printAsOperand(errs(),false)
将在错误流中打印这样的ID,但如果您的逻辑更感兴趣,也可以将其存储在字符串中
在LLVM CFG生成过程-dot CFG
中,它们总是使用BB的名称(如果有)或其表示形式作为字符串来命名基本块。此逻辑出现在CFGPrinter.h
头()中:
您可以使用此逻辑始终返回基本块的有效名称。使用clang将源代码编译为位代码时,请使用下面的标志
-fno-discard-value-names
您将以唯一字符串的形式获得基本块的名称Um…如何拆分这些基本块中的一个?@winter333如果您有其他问题,请单独提问。
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();
}
-fno-discard-value-names