FunctionPass 中的 LLVM LoopInfo 无法编译
LLVM LoopInfo in FunctionPass doesn't compile
我开始学习 llvm api 并且我写了我的第一遍。
我的目标是打印函数如何相互调用。
最近我想在显示中添加一些循环信息,以查看一个函数是否可以多次调用。但是当我尝试使用 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.
这是我的代码:
#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);
我在任何地方都找不到任何对 "no member named 'ID' in 'llvm::LoopInfo'" 错误的引用,有人知道这里出了什么问题吗?
为什么你的代码无法编译
AU.addRequired<typename passclass>()
需要一个LLMV::Pass
的类型,然而你传入的是LoopInfo
,这只是一个LLVM内部class用于循环信息维护。它没有字段 ID
。
LoopInfoWrapperPass
应该改用
如果要获取循环信息。尝试将其更改为 AU.addRequired<LoopInfoWrapperPass>
,如 LLVM Write a new Pass document 所示。 LoopInfoWrapperPass
用于生成LoopInfo
.
LoopInfo
应该从 pass
得到
你的代码中还有一个关于如何获取LoopInfo
的问题,你试图使用new
创建一个LoopInfo
,你得到的将是一个空的LoopInfo
.
您问题的 "should work" 代码
以下是您的代码的修改版本,可以打印出预期的信息。
#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);
将以下代码馈送到 LLVM opt
:
#include <stdio.h>
#define ARRAY_SIZE 100
int foo(int* a , int n) {
int i;
int sum = 0;
for (; i < n; i++) {
sum += a[i];
}
return sum;
}
int main() {
int a[ARRAY_SIZE] = {1};
int sum = foo(a, ARRAY_SIZE);
printf("sum:0x%x\n", sum);
return 0;
}
输出将是:
foo :
BB :
BB : loop{}
BB : loop{}
BB : loop{}
BB :
main :
BB : llvm.memset.p0i8.i64 foo printf
我开始学习 llvm api 并且我写了我的第一遍。 我的目标是打印函数如何相互调用。
最近我想在显示中添加一些循环信息,以查看一个函数是否可以多次调用。但是当我尝试使用 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.
这是我的代码:
#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);
我在任何地方都找不到任何对 "no member named 'ID' in 'llvm::LoopInfo'" 错误的引用,有人知道这里出了什么问题吗?
为什么你的代码无法编译
AU.addRequired<typename passclass>()
需要一个LLMV::Pass
的类型,然而你传入的是LoopInfo
,这只是一个LLVM内部class用于循环信息维护。它没有字段 ID
。
LoopInfoWrapperPass
应该改用
如果要获取循环信息。尝试将其更改为 AU.addRequired<LoopInfoWrapperPass>
,如 LLVM Write a new Pass document 所示。 LoopInfoWrapperPass
用于生成LoopInfo
.
LoopInfo
应该从 pass
得到
你的代码中还有一个关于如何获取LoopInfo
的问题,你试图使用new
创建一个LoopInfo
,你得到的将是一个空的LoopInfo
.
您问题的 "should work" 代码
以下是您的代码的修改版本,可以打印出预期的信息。
#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);
将以下代码馈送到 LLVM opt
:
#include <stdio.h>
#define ARRAY_SIZE 100
int foo(int* a , int n) {
int i;
int sum = 0;
for (; i < n; i++) {
sum += a[i];
}
return sum;
}
int main() {
int a[ARRAY_SIZE] = {1};
int sum = foo(a, ARRAY_SIZE);
printf("sum:0x%x\n", sum);
return 0;
}
输出将是:
foo :
BB :
BB : loop{}
BB : loop{}
BB : loop{}
BB :
main :
BB : llvm.memset.p0i8.i64 foo printf