当我使用opt
运行下面的LLVM传递时,收到以下错误消息:
While deleting: i32 %
Use still stuck around after Def is destroyed: %indexLoc = alloca i32
opt: /home/nlykkei/llvm/src/lib/IR/Value.cpp:85: virtual llvm::Value::~Value(): Assertion `use_empty() && "Uses remain when a value is destroyed!"' failed.
我将opt
调用为:opt -load build/flatten/libFlattenPass.so -opCounter loop.rll
。
我按照示例将指令插入到http://llvm.org/docs/ProgrammersManual.html#creating-and-inserting-new-instructions中的BB中。
我真的没有看到我的代码有什么问题?我应该明确删除AllocaInst
指针还是?
程序:
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <string>
using namespace llvm;
namespace {
struct CountOp : public FunctionPass {
std::map<std::string, int> opCounter;
std::map<std::string, int> bbNameToId;
static char ID;
LLVMContext ctx;
CountOp() : FunctionPass(ID) {}
virtual bool runOnFunction(Function &F) {
std::string bbName("bb");
int bbId = 0;
errs() << "Function " << F.getName() << '\n';
for (Function::iterator bb = F.begin(), e = F.end(); bb != e; ++bb) {
// assign integer ids to BasicBlock's
if (bb->hasName()) {
bbNameToId[bb->getName()] = bbId++;
} else {
bb->setName(Twine(bbName + std::to_string(bbId)));
bbNameToId[bb->getName()] = bbId++;
}
for (BasicBlock::iterator i = bb->begin(), e = bb->end(); i != e; ++i) {
if(opCounter.find(i->getOpcodeName()) == opCounter.end()) {
opCounter[i->getOpcodeName()] = 1;
} else {
opCounter[i->getOpcodeName()] += 1;
}
}
}
AllocaInst* pa = new AllocaInst(Type::getInt32Ty(ctx), 0, "indexLoc");
BasicBlock& firstBB = F.getBasicBlockList().front();
Instruction& firstInst = firstBB.front();
pa->insertBefore(&firstInst);
std::map <std::string, int>::iterator i = opCounter.begin();
std::map <std::string, int>::iterator e = opCounter.end();
while (i != e) {
errs() << i->first << ": " << i->second << "\n";
i++;
}
i = bbNameToId.begin();
e = bbNameToId.end();
while (i != e) {
errs() << i->first << ": " << i->second << "\n";
i++;
}
errs() << "\n";
opCounter.clear();
return false;
}
};
}
char CountOp::ID = 0;
static RegisterPass<CountOp> X("opCounter", "Counts opcodes per functions");