[llvm-dev] Cannot access module pass results from inside loop pass
Sebastian Hain via llvm-dev
llvm-dev at lists.llvm.org
Sun Apr 24 09:59:09 PDT 2016
Hello,
I don't know wether this is the right place to ask, but I did not find
any other appropriate place else so just ask:
I'm writing several LLVM passes: the first one is a ModulePass that
performs some analyzations tasks but does not change anything. It
simply looks at some (named) metadata nodes and thats it. It neither
changes them nor does it change anything else. This is the code to
initialize the pass (MyModuleChecker.cpp):
INITIALIZE_PASS_BEGIN(MyModuleChecker, "mmc", "Check module", false, true)
INITIALIZE_PASS_END(MyModuleChecker, "mmc", "Check module", false, true)
MyModuleChecker::MyModuleChecker(void) : ModulePass(ID) {
initializeMyModuleCheckerPass(*PassRegistry::getPassRegistry());
}
void MyModuleChecker::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
bool MyModuleChecker::runOnModule(Module &M) {
// ...
return false;
}
And then there is a second pass. That pass is a LoopPass and basicly
performs some loop unrolling tasks depending on some other criteria.
For computing the unroll count the pass needs the results of the
MyModuleChecker pass. So I put it in the dependencies like this:
INITIALIZE_PASS_BEGIN(MyLoopUnroll, "myloopunroll", "Unroll loops",
false, false)
INITIALIZE_PASS_DEPENDENCY(LoopInfo)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
INITIALIZE_PASS_DEPENDENCY(MyModuleChecker)
INITIALIZE_PASS_DEPENDENCY(DataLayoutPass)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_END(MyLoopUnroll, "myloopunroll", "Unroll loops", false, false)
MyLoopUnroll::MyLoopUnroll()
: LoopPass(ID), MDK(nullptr), LI(nullptr), SE(nullptr), AC(nullptr),
DL(nullptr) {
initializeMyLoopUnrollPass(*PassRegistry::getPassRegistry());
}
void HDLLoopUnroll::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();
AU.addRequired<ScalarEvolution>();
AU.addRequired<MyModuleChecker>();
AU.addPreserved<MyModuleChecker>();
AU.addRequired<DataLayoutPass>();
AU.addPreserved<DataLayoutPass>();
AU.addRequired<AssumptionCacheTracker>();
}
bool MyLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
LI = &getAnalysis<LoopInfo>();
SE = &getAnalysis<ScalarEvolution>();
MDK = &getAnalysis<MyModuleChecker>();
DL = &getAnalysis<DataLayoutPass>().getDataLayout();
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*L->getHeader()->getParent());
bool Changed = handleLoop(L, LPM);
return Changed;
}
The loop unrolling itself is carried out by the functions already
existing in LLVM (and that are used by the LLVM loop unrolling pass).
So my pass "only" computes the loop unroll count.
Currently those passes are part of the Scalar-library so I adopted the
corresponding files (include /llvm/Transforms/Scalar.h,
LinkAllPasses.h, ...) accordingly.
Now I want to run the passes using opt (I'm using LLVM 3.6):
opt -stats -debug -debug-pass=Structure -mem2reg -loop-rotate
-myloopunroll -simplifycfg
And now I get an assertion error:
LoopRotation: rotating Loop at depth 1 containing:
%for.cond<header><exiting>,%for.body,%for.inc<latch>
Inserted PHI: %i.01 = phi i32 [ 0, %entry ], [ %i.0, %for.cond ]
LoopRotation: into Loop at depth 1 containing:
%for.body<header>,%for.inc<latch><exiting>
opt: ~/llvm-clang/source/include/llvm/PassAnalysisSupport.h:214:
AnalysisType& llvm::Pass::getAnalysisID(llvm::AnalysisID) const [with
AnalysisType = MyModuleChecker; llvm::AnalysisID = const void*]:
Assertion `ResultPass && "getAnalysis*() called on an analysis that
was not " "'required' by pass!"' failed.
// ...
#8 0x1685a99 MyModuleChecker&
llvm::Pass::getAnalysisID<MyModuleChecker>(void const*) const
(.../opt+0x1685a99)
#9 0x16857f0 MyModuleChecker&
llvm::Pass::getAnalysis<MyModuleChecker>() const (.../opt+0x16857f0)
#10 0x16853cd MyLoopUnroll::runOnLoop(llvm::Loop*,
llvm::LPPassManager&) (.../opt+0x16853cd)
#11 0xd34aaa llvm::LPPassManager::runOnFunction(llvm::Function&)
(.../opt+0xd34aaa)
#12 0x11c6a34 llvm::FPPassManager::runOnFunction(llvm::Function&)
(.../opt+0x11c6a34)
#13 0x11c6ba4 llvm::FPPassManager::runOnModule(llvm::Module&)
(.../opt+0x11c6ba4)
#14 0x11c6ec2 (anonymous
namespace)::MPPassManager::runOnModule(llvm::Module&)
(.../opt+0x11c6ec2)
#15 0x11c7568 llvm::legacy::PassManagerImpl::run(llvm::Module&)
(.../opt+0x11c7568)
#16 0x11c7787 llvm::legacy::PassManager::run(llvm::Module&) (.../opt+0x11c7787)
// ...
The following passes are run:
Assumption Cache Tracker
ModulePass Manager
FunctionPass Manager
Dominator Tree Construction
Promote Memory to Register
Natural Loop Information
Canonicalize natural loops
Loop-Closed SSA Form Pass
Loop Pass Manager
Rotate Loops
Scalar Evolution Analysis
Check module
FunctionPass Manager
Dominator Tree Construction
Natural Loop Information
Scalar Evolution Analysis
Loop Pass Manager
Unroll loops
Simple constant propagation
Module Verifier
Debug Info Verifier
Bitcode Writer
And then the assertion error occurs and I don't know where that error
comes from and why it occures (and yes, everything compiles without
errors and warnings). It looks like the loop rotation pass is executed
normally and then pass manager gets stuck in the loop unroll pass when
calling the getAnalysis<MyModuleChecker> function in the LoopPass to
get the analysis results.
If I omit the -simplifycfg(when calling opt) and like this do not run
the simplifycfg pass after my own loopunrolling pass, everything works
fine and there is no assertion error. The assertion error also occurs
if I replace the SimplifyCFG pass by - for example - the constprop
pass.
It also seems as if the error does not occur if the ModuleChecker pass
is transformed into a FunctionPass.
Could anyone tell my why this assertion error occures and (perhaps)
how to solve that issue?
Thanks
Sebastian
More information about the llvm-dev
mailing list