[llvm-dev] Understanding on-the-fly passes (Take 2)

125 views
Skip to first unread message

David Greene via llvm-dev

unread,
Mar 26, 2019, 4:48:51 PM3/26/19
to llvm...@lists.llvm.org
Apologies for the earlier aborted e-mail. I hit a keyboard shortcut by
mistake. :)

I'm seeing some odd behavior with a ModulePass I'm developing. In order
for it to work with both the legacy and new pass managers, I've
abstracted away the code to get the passes it depends on:

// Legacy pass.
bool MyPass::runOnModule(Module &M) override {
auto DominatorGetter = [this] (Function &F) -> DominatorTree & {
return this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
};

auto PostDominatorGetter = [this] (Function &F) -> PostDominatorTree & {
return this->
getAnalysis<PostDominatorTreeWrapperPass>(F).getPostDomTree();
};

auto LoopInfoGetter = [this] (Function &F) -> LoopInfo & {
return this->getAnalysis<LoopInfoWrapperPass>(F).getLoopInfo();
};

auto SCEVGetter = [this] (Function &F) -> ScalarEvolution & {
return this->getAnalysis<ScalarEvolutionWrapperPass>(F).getSE();
};

auto AssumptionCacheGetter = [this] (Function &F) ->
AssumptionCache & {
return
this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
};

auto OREGetter = [this] (Function &F) -> OptimizationRemarkEmitter & {
return this->
getAnalysis<OptimizationRemarkEmitterWrapperPass>(F).getORE();
};

doTheWork(M,
DominatorGetter,
PostDominatorGetter,
LoopInfoGetter,
SCEVGetter,
AssumptionCacheGetter,
OREGetter);

return false;
}

// New pass.
PreservedAnalyses
MyPass::run(Module &M, ModuleAnalysisManager &AM) {
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();

auto DominatorGetter = [&FAM] (Function &F) -> DominatorTree & {
return FAM.getResult<DominatorTreeAnalysis>(F);
};

auto PostDominatorGetter = [&FAM] (Function &F) -> PostDominatorTree & {
return FAM.getResult<PostDominatorTreeAnalysis>(F);
};

auto LoopInfoGetter = [&FAM] (Function &F) -> LoopInfo & {
return FAM.getResult<LoopAnalysis>(F);
};

auto SCEVGetter = [&FAM] (Function &F) -> ScalarEvolution & {
return FAM.getResult<ScalarEvolutionAnalysis>(F);
};

auto AssumptionCacheGetter = [&FAM] (Function &F) -> AssumptionCache & {
return FAM.getResult<AssumptionAnalysis>(F);
};

auto OREGetter = [&FAM] (Function &F) -> OptimizationRemarkEmitter & {
return FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
};

doTheWork(M,
DominatorGetter,
PostDominatorGetter,
LoopInfoGetter,
SCEVGetter,
AssumptionCacheGetter,
OREGetter);

return PreservedAnalyses::all();
}

template<typename D,
typename P,
typename L,
typename S,
typename A,
typename O>
bool doTheWork(Module &M,
D &DominatorGetter,
P &PostDominatorGetter,
L &LoopInfoGetter,
S &SCEVGetter,
A &AssumptionCacheGetter,
O &OREGetter) {
auto &FirstORE = OREGetter(getFirstDefinedFunction(M));

// Do some checking to see if doing the work makes sense and emit
// messages with FirstORE.

// Ok, everything ok, actually do the work.
for (auto &F : M) {
if (!F.isDeclaration()) {
auto &DT = DominatorGetter(F);
auto &PDT = PostDominatorGetter(F);
auto &LI = LoopInfoGetter(F);
auto &SE = SCEVGetter(F);
auto &AC = AssumptionCacheGetter(F);
auto &ORE = OREGetter(F); // BAM! SE is deleted here!
reallyDoTheWork(M,
F,
API,
DT,
PDT,
LI,
SE,
AC,
ORE);
}
}
}

When I use the legacy pass manager, the SE object retrieved by
SCEVGetter is deleted when the OREGetter gets the
OptimizationRemarkEmitter. Bad things ensue. Tracing through with a
debugger shows that on-the-fly passes are created and deleted a bunch of
times, including ScalarEvolution. This is because on-the-fly pass
managers are created and deleted a bunch of times, essentially each time
a *Getter is invoked.

I'm curious why the deletion happens when OREGetter is invoked. Is it
because I called OREGetter once at the top of doTheWork with the same
Function?

Is there something special about ScalarEvolution? I see that no IPO
passes use it. SCCP does the same kind of abstracting for getting pass
dependencies so I don't think the abstraction is causing the issue.

What is the proper way to run function analysis passes from a
ModulePass?

Thanks for any help!

-David
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Reply all
Reply to author
Forward
0 new messages