llvm: How to get the label of Basic Blocks

拈花ヽ惹草 提交于 2020-07-05 01:16:48

问题


I have written a pass to detect and print the label of basicblocks in a function, for I want to use splitBasicBlock() further. I wrote that like this:

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 file looks like this:

; <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

However, I got nothing about the label:

Function:main
BasicBlock:
BasicBlock:
BasicBlock:

What's wrong with these "unnamed" basic block? What should I do?


回答1:


Values in LLVM IR are not required to have a name; and indeed, those basic blocks don't have names, which is why you get an empty string from currBB->getName().

The reason that they have names in the LLVM IR printout is because when you print to the textual format of LLVM IR (as it appears in .ll files), you have to assign a name to them to make them referable, so the printer assigns sequential numeric names to basic blocks (and other values). Those numeric names are only created by the printer, though, and don't actually exist in the module.




回答2:


While BasicBlocks may be with no name (as indicated by hasName() method) one may print unique BasicBlock identifier by using currBB->printAsOperand(errs(), false) instead of streaming into errs() the value of currBB->getName(). For unnamed BasicBlock this would provide the numerical basic block representation, such as %68 .




回答3:


I think the behavior of LLVM now is different. I use similar lines of code and can get the label's name on LLVM-4.0

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



回答4:


As ElazarR said, currBB->printAsOperand(errs(), false) will print such ID in the error stream, but it is possible to store it in a string as well if this is more interesting to your logic.

In the LLVM CFG generation pass -dot-cfg, they always name the basic block using the BB's name (if any) or its representation as a string. This logic is present in the CFGPrinter.h header (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();
}

You can use this logic to always return a valid name for the basic block.



来源:https://stackoverflow.com/questions/26281823/llvm-how-to-get-the-label-of-basic-blocks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!