Question

I am writing an LLVM FunctionPass that transforms certain functions fairly aggressively. It ultimately ends up deleting the old set of blocks and replacing them with totally different ones. However, the loop unroller (LoopUnrollPass), which runs after, fails to find loops in the transformed function. (The transformed version should have natural loops.)

Is there anything I have to poke after recreating a function? How do I trigger the loop detector to run again? Finally, are there other analyses that I have to also update when I transform functions?

Was it helpful?

Solution

First, just in case you skipped it, it's important to read an understand the Writing and LLVM Pass documentation page.

When your pass runs, it says whether the function/module was modified. The pass manager is supposed to take that as a clue to re-run all analyses needed for the next passes, unless your pass declares it preserves them (with addPreserved). You can see the list of analyses required by LoopUnroll in its getAnalysisUsage method:

/// This transformation requires natural loop information & requires that
/// loop preheaders be inserted into the CFG...
///
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<LoopInfo>();
  AU.addPreserved<LoopInfo>();
  AU.addRequiredID(LoopSimplifyID);
  AU.addPreservedID(LoopSimplifyID);
  AU.addRequiredID(LCSSAID);
  AU.addPreservedID(LCSSAID);
  AU.addRequired<ScalarEvolution>();
  AU.addPreserved<ScalarEvolution>();
  AU.addRequired<TargetTransformInfo>();
  // FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
  // If loop unroll does not preserve dom info then LCSSA pass on next
  // loop will receive invalid dom info.
  // For now, recreate dom info, if loop is unrolled.
  AU.addPreserved<DominatorTree>();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top