LLVM Assertion error when using module pass inside loop pass - llvm

I'm writing several LLVM passes. One of them is a ModulePass that performs some analyzations but does not change anything (no functions, no metadata, no variables,...). It only looks at some metadata nodes and thats it.
MyModuleChecker.cpp:
INITIALIZE_PASS_BEGIN(MyModuleChecker, "mmc", "Check module", false, true)
INITIALIZE_PASS_END(MyModuleChecker, "mmc", "Check module", false, true)
char MyModuleChecker::ID = 0;
namespace llvm {
Pass* createMyModuleCheckerPass() {
return new MyModuleChecker();
}
}
MyModuleChecker::MyModuleChecker(void) : ModulePass(ID) {
initializeMyModuleCheckerPass(*PassRegistry::getPassRegistry());
}
void MyModuleChecker::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
bool MyModuleChecker::runOnModule(Module &M) {
// ...
return false; // <-- Under all circumstances
}
And then there is a second pass. That pass is a LoopPass and basiclly performs some loop unrolling tasks depending on some criteria. For computing the unroll count the pass needs the results of the MyModuleChecker pass. So I put it in the dependencies.
MyLoopUnroll.cpp:
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)
char MyLoopUnroll::ID = 0;
namespace llvm {
Pass* createMyLoopUnrollPass() {
return new MyLoopUnroll();
}
}
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>(); // <-- Seems not to work
DL = &getAnalysis<DataLayoutPass>().getDataLayout();
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*L->getHeader()->getParent());
if ((LI == nullptr) || (SE == nullptr) || (DL == nullptr) || (MDK == nullptr) || (AC == nullptr)) {
return false;
}
bool Changed = handleLoop(L, LPM);
return Changed;
}
The loop unrolling itself was not implemented by myself but instead I am using the already existing functions that LLVM provides and that are also used by the loop unrolling that LLVM provides.
Currently those passes are part of the Scalar-library so I adopted the corresponding files (include /llvm/Transforms/Scalar.h, LinkAllPasses.h, ...) accordingly. So my passes are not linked dynamicly to opt.
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
I now 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 ()
#9 0x16857f0 MyModuleChecker& llvm::Pass::getAnalysis<MyModuleChecker>() const ()
#10 0x16853cd MyLoopUnroll::runOnLoop(llvm::Loop*, llvm::LPPassManager&) ()
#11 0xd34aaa llvm::LPPassManager::runOnFunction(llvm::Function&) ()
// ...
And I don't know where that error comes and why it occures (any 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>; analysis results.
If I ommit the -simplifycfg and do not run the simplifycfg pass after my own loopunrolling pass everything works fine on the sameprogram and there is no assertion error. Afterwards the loop is unrolled.
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?

Related

llvm pass to flatten (some) nested loops

I want to automatically rewrite simple nested loops as non nested ones.
For example, I have the following code:
if (y >= 0)
{
while (x>y)
{
x -= y+1;
for (z=y; z>0; z--) /* nothing */;
}
}
And I would like some llvm magic to happen so that it becomes:
if (y >= 0)
{
bool outer = true;
while (x>y)
{
if (outer) { z = y; }
if (z > 0) { z--; outer = false; }
else { x-= y+1; outer = true; }
}
}
Am I being over optimistic thinking such a pass exists?
I tried writing opt --help > /tmp/passes.txt && grep "loop" /tmp/passes.txt
but there are so many loop passes I don't know where to start.
This optimization is called loop fusion. I haven't tried your code but Polly should be able to fuse such loops. Polly is the polyhedral compiler framework that ships with LLVM but it should build with LLVM by default. If it does not then you'd need to pass -DLLVM_POLLY_BUILD:BOOL=ON to cmake to build polly with llvm.
Here's the documentation on how to invoke polly optimizations with clang/llvm.
https://polly.llvm.org/docs/UsingPollyWithClang.html#optimizing-with-polly

Getting available ports into a vector for use in a For loop

EDIT: thanks to Scheff and everyone else who commented
I am currently attempting to communicate with a serial device and have to change a foreach loop into a range based for loop. In order to do this I have written the following code:
std::vector<QSerialPortInfo> serialList;
for (QSerialPortInfo const &serialPortInfo : serialList)
{
qDebug() << "check/n";
if (serialPortInfo.hasVendorIdentifier () && serialPortInfo.hasProductIdentifier ())
{
if (serialPortInfo.vendorIdentifier () == trackerVendorID &&
serialPortInfo.productIdentifier () == trackerProductID)
{
trackerPortName = serialPortInfo.portName ();
trackerIsAvailable = true;
}
}
}
The problem is that this just generates an empty vector so the for loop is never used and the qDebug "check" is never called. I know I need to put something in with QSerialPortInfo::availablePorts() but I can't for the life of me work out how.
You write:
std::vector<QSerialPortInfo> serialList;
But QSerialPortInfo::availablePorts() does not return a std::vector, it returns a QList<QSerialPortInfo>, which you can use as is in the for loop:
QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo& serialPortInfo : serialList)
{
...

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;

How to delay a function call until a global variable gets set

I'm trying to execute a function, only after my global bool flag gets set to true. I'm currently parsing a file with instructions. Two of the commands are attack and testIsZOmbie.
void NAttack::CodeGen(CodeContext& context)
{
if(flag == true)
{
context.m_Ops.push_back("attack ");
}
}
The problem is that the flag only gets set after my NisZombie::CodeGen function, which always gets called after NAttack....Is there any way to delay NAttack being called until NisZOmbie?
void NisZombie::CodeGen(CodeContext& context)
{
if (m_Dir->m_value == 1)
{
context.m_Ops.push_back("test_zombie,1");
//std::cout<<"HERE";
context.m_Ops.push_back("je, ");
flag = true;
}
}

Windbg Set Conditional Breakpoints that depends on Call Stack

The problem: I need to make a script or an expression that that doesn't break if somewhere on callstack is a function with a specific name.
Specific question: How can I get functions on callstack to a list of strings ?
Example:
Module!MyFunctionWithConditionalBreakpoint
Module!Function1
Module!Function2
Module!Function3
Module!MyFunctionWithConditionalBreakpoint
Module!Function1
Module!ClassA:MemberFunction
Module!Function3
I want Module!MyFunctionWithConditionalBreakpoint to break only if the call cames from Module!ClassA:MemberFunction
I need this in unmanaged code. Managed solution is something like
System.Diagnostics.StackTrace().ToString().Contains("YourMethodName")
In WinDbg you may set a conditional breakpoint using special $spat function:
bp Module!MyFunctionWithConditionalBreakpoint "r $t0 = 0;.foreach (v { k }) { .if ($spat(\"v\", \"*Module!ClassA:MemberFunction*\")) { r $t0 = 1;.break } }; .if($t0 = 0) { gc }"
In pseudo-code it will be something like:
t0 = 0
foreach (token in k-command result) {
if (token.contains("Module!ClassA:MemberFunction")) {
t0 = 1
break
}
}
if (t0 == 0) {
// continue execution
} else {
// break into the debugger
}
Why not set a breakpoint on entering Module!ClassA:MemberFunction to enable a breakpoint for Module!MyFunctionWithConditionalBreakpoint and upon leaving Module!ClassA:MemberFunction disabling it?