FunctionPass中的LLVM LoopInfo不';不编译

FunctionPass中的LLVM LoopInfo不';不编译,llvm,llvm-clang,Llvm,Llvm Clang,我开始学习LLVMAPI,我写了第一篇文章。 我的目标是打印函数如何相互调用 最近我想在显示器上添加一些循环信息,看看一个函数是否可以多次调用。但当我尝试使用LoopInfo时,我得到了以下编译错误: llvm[0]: Compiling cfg.cpp for Debug+Asserts build (PIC) In file included from cfg.cpp:19: In file included from /home/llvm-lab/llvm/include/llvm/Pas

我开始学习LLVMAPI,我写了第一篇文章。 我的目标是打印函数如何相互调用

最近我想在显示器上添加一些循环信息,看看一个函数是否可以多次调用。但当我尝试使用LoopInfo时,我得到了以下编译错误:

llvm[0]: Compiling cfg.cpp for Debug+Asserts build (PIC)
In file included from cfg.cpp:19:
In file included from /home/llvm-lab/llvm/include/llvm/Pass.h:378:
  /home/llvm-lab/llvm/include/llvm/PassAnalysisSupport.h:56:37: error:
        no member named 'ID' in 'llvm::LoopInfo'
      return addRequiredID(PassClass::ID);
                                  ^
cfg.cpp:33:10: note: in instantiation of function template
      specialization 'llvm::AnalysisUsage::addRequired<llvm::LoopInfo>'
      requested here
      AU.addRequired<LoopInfo>();
         ^
1 error generated.
llvm[0]:编译cfg.cpp用于调试+断言生成(PIC)
在cfg.cpp:19中包含的文件中:
在/home/llvm lab/llvm/include/llvm/Pass.h中包含的文件中:378:
/home/llvm lab/llvm/include/llvm/passanalysisssupport.h:56:37:错误:
“llvm::LoopInfo”中没有名为“ID”的成员
返回addRequiredID(PassClass::ID);
^
cfg.cpp:33:10:注:在函数模板实例化中
专门化“llvm::AnalysisUsage::addRequired”
在此请求
AU.addRequired();
^
生成1个错误。
这是我的密码:

#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "iostream"
#include "llvm/Pass.h"
#include "llvm/IR/InstIterator.h"
#include <llvm/IR/Instructions.h>
#include <llvm/Analysis/LoopInfo.h>

using namespace llvm;


namespace {
  struct CFG : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    CFG() : FunctionPass(ID) {}

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.addRequired<LoopInfo>();
    }

    bool runOnFunction(Function &F) override {
      errs().write_escaped(F.getName());

      errs() << " : ";

      for( Function::iterator b = F.begin() , be = F.end(); b != be; ++b){
        errs() << "\n\t BB : ";
        LoopInfo *loop = new LoopInfo();
        bool isLoop = loop->getLoopFor(b);
        if(isLoop){
          errs() << "loop{";
        }
        for(BasicBlock::iterator i = b->begin() , ie = b->end(); i!=ie; ++i){
          if( isa<CallInst>(&(*i)) || isa<InvokeInst>(&(*i))){
            errs() << cast<CallInst>(&(*i))->getCalledFunction()->getName() << "\t";
          }
        }
        if(isLoop){
          errs() << "}";
        }
     }

     errs() << '\n';
     return false;
   }



  };
}

char CFG::ID = 0;
static RegisterPass<CFG> X("CFG", "Gen CFG",true ,true);
#包括“llvm/ADT/Statistic.h”
#包括“llvm/IR/Function.h”
#包括“llvm/Support/raw_ostream.h”
#包括“iostream”
#包括“llvm/Pass.h”
#包括“llvm/IR/InstIterator.h”
#包括
#包括
使用名称空间llvm;
名称空间{
结构CFG:公共函数传递{
静态字符ID;//传递标识,替换typeid
CFG():FunctionPass(ID){}
无效getAnalysisUsage(AnalysisUsage&AU)常量重写{
AU.addRequired();
}
bool runOnFunction(功能和F)覆盖{
errs().write_转义(F.getName());
errs()end();i!=ie;++i){
如果(isa(&(*i))| isa(&(*i))){
errs()getCalledFunction()->getName()无法生成代码的原因
AU.addRequired()
需要一个类型为
LLMV::Pass
,但是传入的是
LoopInfo
,它只是一个用于循环信息维护的LLVM内部类。它没有字段
ID

应改用
LoopInfoWrapperPass
如果要获取循环信息,请尝试将其更改为
AU.addRequired
,如中所示。
LoopInfoWrapperPass
用于生成
LoopInfo

LoopInfo
应该从pass中获取 您的代码中还有一个关于如何获取
LoopInfo
的问题,您正在尝试使用
new
创建
LoopInfo
,您将获得一个空的
LoopInfo

您的问题的“应该有效”代码 下面是代码的修改版本,可以打印出预期的信息

#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "iostream"
#include "llvm/Pass.h"
#include "llvm/IR/InstIterator.h"
#include <llvm/IR/Instructions.h>
#include <llvm/Analysis/LoopInfo.h>


using namespace llvm;


namespace {
  struct CFG : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    CFG() : FunctionPass(ID) {}

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.setPreservesCFG();
      AU.addRequired<LoopInfoWrapperPass>();
    }
    bool runOnFunction(Function &F) override {
      LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
      errs().write_escaped(F.getName());
      errs() << " : ";
      for( Function::iterator b = F.begin() , be = F.end(); b != be; ++b){
        errs() << "\n\t BB : ";
        bool isLoop = LI.getLoopFor(b);
        if(isLoop){ 
          errs() << "loop{";
        }
        for(BasicBlock::iterator i = b->begin() , ie = b->end(); i!=ie; ++i){
          if( isa<CallInst>(&(*i)) || isa<InvokeInst>(&(*i))){
            errs() << cast<CallInst>(&(*i))->getCalledFunction()->getName() << "\t";
          }
        }
        if(isLoop){ 
          errs() << "}";
        }
     }
     errs() << '\n';
     return false;
   }
  };
}

char CFG::ID = 0;
static RegisterPass<CFG> X("CFG", "Gen CFG",true ,true);
输出将是:

foo : 
     BB : 
     BB : loop{}
     BB : loop{}
     BB : loop{}
     BB : 
main : 
     BB : llvm.memset.p0i8.i64  foo printf  

非常好,谢谢!现在我觉得有点傻,但真的谢谢你我在这方面被绊倒太久了:)谢谢,节省了我很多时间!。有趣的是,我在将旧版本的LLVM的通行证移植到3.6.2时遇到了同样的问题,似乎旧版本没有包装器也可以。
foo : 
     BB : 
     BB : loop{}
     BB : loop{}
     BB : loop{}
     BB : 
main : 
     BB : llvm.memset.p0i8.i64  foo printf