LLVM insert pass into PassManager - c++

I'm writing a module level pass and inside the runOnModule function I have the following bit of code:
for (Module::iterator F = M.begin(), FEND = M.end(); F != FEND; ++F){
if (!(*F).isDeclaration()){
LoopInfo* LI = new LoopInfo();
LI->runOnFunction(*F);
lis.push_back(LI);
for(LoopInfo::iterator L = LI->begin(), LEND = LI->end(); L != LEND; ++L){
// add all functions
loops.push_back(*L);
}
}
}
This all compiles but when I run it I get the following error:
opt: /include/llvm/PassAnalysisSupport.h:200: AnalysisType
&llvm::Pass::getAnalysis() const [AnalysisType = llvm::DominatorTreeWrapperPass]:
Assertion `Resolver && "Pass has not been inserted into a PassManager object!"' failed.
I tried putting the below code in ``lib/Transforms/IPO/PassManagerBuilder.cppin thepopulateModulePassManager` method but nothing happened.
if (EnableMergeFunctions) {
MPM.add(createMergeFunctionsPass());
MPM.add(createJumpThreadingPass()); // Merge consecutive conditionals
MPM.add(createInstructionCombiningPass());
MPM.add(createCFGSimplificationPass());
}
Any help would be great thanks.

Related

How to use F.getValueSymbolTable()

I wanna get all the local variables in a function.
void getLocalVariables(Function &F) {
ValueSymbolTable *vst = F.getValueSymbolTable();
for (auto vs : vst) { // here it says: This scope-based "for" statement required the appropriate "begin" function, but was not found
auto s = vs.getKey();
auto v = vs.getValue();
}
}
The error is that: This scope-based "for" statement required the appropriate "begin" function, but was not found. So how can I correct my code? Tks.
I check the documentation for ValueSymbolTable, and finally find how to use it. But actually, as arnt said, they are not local variables in source code. They are temporary variables generated by IR.
void getLocalVariables(Function &F) {
// not test yet
ValueSymbolTable *vst = F.getValueSymbolTable();
errs() << (*vst).size() << "\n.";
for (ValueSymbolTable::iterator VI = vst->begin(), VE = vst->end(); VI != VE; ++VI) {
Value *V = VI->getValue();
if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) {
if (!V->getName().startswith("llvm.dbg"))
// Set name to "", removing from symbol table!
V->setName("");
}
}
}

Iterating over the BasicBlocks of loops of function in LLVM IR in module pass

does anybody know how to iterate over the basic of Loops of functions in module pass.I was trying :
bool runOnModule(Module &M) override
{
for(Module::iterator f = M.begin(), fend = M.end(); f != fend; ++f)
{
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
for(Loop *L : LI)
{
for(BasicBlock *BB : L->getBlocks())
{
dbgs() << "basicb name: "<< BB->getName() <<"\n";
}
}
}
return true;
}
and it always gives the error
opt: /home/anurag/polly/llvm/include/llvm/PassAnalysisSupport.h:235: AnalysisType& llvm::Pass::getAnalysisID(llvm::AnalysisID) const [with AnalysisType = llvm::LoopInfoWrapperPass; llvm::AnalysisID = const void*]: Assertion `ResultPass && "getAnalysis*() called on an analysis that was not " "'required' by pass!"' failed.
There are two updates needed for this code. The first was also noted in this question, that when requesting the loop info from a module pass, you need to specify the function (adding the iterator access):
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>(*f).getLoopInfo();
The second issue is that some functions in the module are "empty", declarations without definitions. Adding a check for the size should skip those and avoiding any issues with trying to find loops in empty functions.
if ((*f).size() == 0) continue;

C++11/ Auto assign me a bool?

TGuildMemberContainer::iterator it;
if ((it = m_member.find (p->dwPID)) == m_member.end())
{
m_member.insert (std::make_pair (p->dwPID, TGuildMember (p->dwPID, p->bGrade, p->isGeneral, p->bJob, p->bLevel, p->dwOffer, p->szName)));
}
else
{
TGuildMember& r_gm = it->second;
r_gm.pid = p->dwPID;
r_gm.grade = p->bGrade;
r_gm.job = p->bJob;
r_gm.offer_exp = p->dwOffer;
r_gm.is_general = p->isGeneral;
}
Hi, i want to apply auto transform intro my codes, but i'm stuck.
If i add auto
if (auto it = m_member.find (p->dwPID) == m_member.end())
The auto assign a bool
if ( bool it = m_member.find (p->dwPID) == m_member.end())
This say Visual Studio intelisense.
My question, why auto assign me a bool and not the corect iteration range ?
Because the compiler is parsing it as:
if (auto it = (m_member.find (p->dwPID) == m_member.end()))
which is a boolean expression. You can't write it as:
if ((auto it = m_member.find (p->dwPID)) == m_member.end())
because putting the variable declaration inside brackets like that is not allowed.
I find creating variables in if hard to read. Just use:
const auto it = m_member.find(p->dwPID);
if (it == m_member.end())
...
In C++17, this can be done as
if (auto it = m_member.find (p->dwPID); it == m_member.end())
which avoids the scope problem mentioned in the other answer.

List Iterator not Dereferenceable Run time

portalManager::portalManager(SDL_Renderer* argRenderer)
{
mLootManager = new lootManager();
mLootManager->initialize();
lootPortal* newPortal;
newPortal = new lootPortal(128, 128, Portal::eForest, Tile::eForest);
mPortalList.push_back(newPortal);
newPortal = new lootPortal(256, 256, Portal::eForest, Tile::eForest);
mPortalList.push_back(newPortal);
mPortalSheet = new spriteSheet(192, 192, 0);
mPortalSheet->loadTexture("Images/Portals.png", argRenderer);
mRenderQuad.w = Tile::cTileSize;
mRenderQuad.h = Tile::cTileSize;
mTextureQuad.w = Tile::cTileSize;
mTextureQuad.h = Tile::cTileSize;
}
void portalManager::render(int argX, int argY, int argW, int argH, SDL_Renderer* argRenderer)
{
std::list<lootPortal*>::const_iterator itr = mPortalList.begin();
for (itr = mPortalList.begin(); itr != mPortalList.end(); itr++);
{
std::cout<<(*itr)->getX()<<std::endl;
mRenderQuad.x = (*itr)->getX();
mRenderQuad.y = (*itr)->getY();
if ((mRenderQuad.x >= argX && mRenderQuad.x <= argX+argW) && (mRenderQuad.y >= argY && mRenderQuad.y <= argY + argH))
{
mTextureQuad.x = 0;
mTextureQuad.y = 0;
}
}
};
The problem happens in the for loop of render when I try to dereference the iterator.
I have checked that the list is not empty I can access the first and last element of the list but for some reason the for loop always throws a list Iterator not dereferenceable.
The problem is in this line:
for (itr = mPortalList.begin(); itr != mPortalList.end(); itr++);
^
You have a spurious semi-colon at the end of the for clause. Easy fix - get rid of it.
If you're curious as to why this causes a problem - what this means is that the entire loop will complete before it proceeds to execute the code in the body of the loop (because that code isn't actually in the body of the loop after all). And once it gets to that code, itr equals mPortalList.end().

LLVM storing Loop* in std::vector

I've stumbled into something very peculiar - I'm writing an LLVM module Pass. I iterate over all functions of the module and then all loops of every non-declaration function and I store pointers to loops in a std::vector. Here's the source:
virtual bool runOnModule(Module& Mod){
std::vector<Loop*> loops;
// first gather all loop info
for(Module::iterator f = Mod.begin(), fend = Mod.end(); f != fend; ++f){
if (!(*f).isDeclaration()){
LoopInfo& LI = getAnalysis<LoopInfo>(*f);
for(LoopInfo::iterator l = LI.begin(), lend = LI.end(); l != lend; ++l){
loops.push_back(*l);
}
}
}
for (auto& l: loops) errs () << *l << " ";
}
Now if I run this I get a runtime error - it can't print the loops, somehow I'm doing a null pointer dereference or sth. Any ideas?
You have to make sure that the LoopInfo pass actually runs before your pass. Here is a complete example - stanalone from opt:
class AnalyzeLoops : public FunctionPass {
public:
AnalyzeLoops()
: FunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();
}
virtual bool runOnFunction(Function &F) {
LoopInfo &LI = getAnalysis<LoopInfo>();
for (LoopInfo::iterator L = LI.begin(), LE = LI.end(); L != LE; ++L) {
(*L)->dump();
}
return false;
}
static char ID;
};
In addition, when creating the passes, do:
PassManager PM;
PM.add(new LoopInfo());
PM.add(new AnalyzeLoops());
PM.run(*Mod);
I suspect that to make opt actually run LoopInfo before your pass, you should pass -loops too.
Also, note that I define getAnalysisUsage - this will make LLVM complain if LoopInfo didn't run before this pass, making the problem more obvious.
Note that LoopInfo is specifically a FunctionPass, and as an analysis it has to be used from another FunctionPass. The LoopInfo data structure doesn't really survive between different functions, and since it owns its data (those Loop* objects) they will be destroyed as well.
One thing you could do if you really need a ModulePass is just invoke LoopInfo manually and not as an analysis. When you iterate the functions in the module, for each function create a new LoopInfo object and use its runOnFunction method. Though even in this case, you have to make sure the LoopInfo that owns a given Loop* survives if you want to use the latter.
First of all LoopInfo should run just once before the for loop.
Secondly LoopInfo::iterator just includes top level loops of the Function. in order to visit all loops you also need to iterate over subloops of every loop. it can be implemented either as recursive function or by WorkList, like this`
virtual bool runOnFunction(Function &F) {
LoopInfo *loopinfo;
loopinfo = &getAnalysis<LoopInfo>();
std::vector<Loop*> allLoops;
for (LoopInfo::iterator Li = loopinfo->begin(), Le = loopinfo->end();
Li != Le; Li++) {
Loop *L = *Li;
allLoops.push_back(L);
dfsOnLoops(L, loopinfo, allLoops);
}
}
void dfsOnLoops(Loop *L, LoopInfo *loopinfo, std::vector<Loop*> LoopS) {
std::vector<Loop *> subloops = L->getSubLoops();
if (subloops.size()) {
// recursive on subloops
for (std::vector<Loop *>::iterator Li = subloops.begin();Li != subloops.end(); Li++){
LoopS.push_back(*Li);
dfsOnLoops(*Li, loopinfo, LoopS);
}
}
}
`
None of the answers really helped but I managed to solve the problem myself. Basically, each llvm pass can define a releaseMemory() method, read more here. The LoopInfo class had that method implemented and thus the analysis information would be lost every time we get out of scope from the call to getAnalysis. I simply removed the releaseMemory() method in Loopinfo.h and the memory was no longer released. Note that this triggered a big change in the codebase and even opt had to be rebuilt so doing this in general is probably a bad idea and this would definitely not be easily accepted as a change to llvm (I speculate, not sure).
I think the best way to solve this is to explicitly create LoopInfo objects and save them. Here is the Code for LLVM 3.5
using LoopInfoType=llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>;
std::vector<llvm::Loop*> loopVec;
std::vector<LoopInfoType*> loopInfoVec;
for(llvm::Module::iterator F = M.begin(); F!= M.end(); F++){
//skip declrations
if(F->isDeclaration()){
continue;
}
//TODO that scope problem
llvm::DominatorTree DT = llvm::DominatorTree();
DT.recalculate(*F);
LoopInfoType *loopInfo = new LoopInfoType();
loopInfo->releaseMemory();
loopInfo->Analyze(DT);
loopInfoVec.push_back(loopInfo);
for(llvm::LoopInfo::iterator lit = loopInfo->begin(); lit != loopInfo->end(); lit++){
Loop * L = * lit;
loopVec.push_back(L);
//L->dump();
}
}//for all functions
cin.get();
for(auto loop : loopVec){
std::cout << "loop\n";
loop->dump();
for(llvm::Loop::block_iterator bit = loop->block_begin(); bit != loop->block_end(); bit++){
llvm::BasicBlock * B = * bit;
B->dump();
std::cout << "\n\n";
}
}