Search code examples
optimizationcompiler-constructionllvm

insert a statement before the execution of a loop


In LLVM intermediate representation, how can I insert an instruction for a loop, which will be executed exactly once before the execution of that loop? Inserting the instruction to the preheader does not work, because preheader is NULL for some loops.


Solution

  • If the loop does not have a preheader, you can create new preheader.

    Here is an example http://www.cs.ucla.edu/classes/spring08/cs259/llvm-2.2/lib/Transforms/Utils/LoopSimplify.cpp or http://www.opensource.apple.com/source/clang/clang-23/clang/lib/Transforms/Utils/LoopSimplify.cpp (find function InsertPreheaderForLoop and call to it)

    /// InsertPreheaderForLoop - Once we discover that a loop doesn't have a
    /// preheader, this method is called to insert one.  This method has two phases:
    /// preheader insertion and analysis updating.
    ///
    void LoopSimplify::InsertPreheaderForLoop(Loop *L) {
      BasicBlock *Header = L->getHeader();
    
      // Compute the set of predecessors of the loop that are not in the loop.
      std::vector<BasicBlock*> OutsideBlocks;
      for (pred_iterator PI = pred_begin(Header), PE = pred_end(Header);
           PI != PE; ++PI)
        if (!L->contains(*PI))           // Coming in from outside the loop?
          OutsideBlocks.push_back(*PI);  // Keep track of it...
    
      // Split out the loop pre-header.
      BasicBlock *NewBB =
        SplitBlockPredecessors(Header, ".preheader", OutsideBlocks);
    
    
      //===--------------------------------------------------------------------===//
      //  Update analysis results now that we have performed the transformation
      //
    
      // We know that we have loop information to update... update it now.
      if (Loop *Parent = L->getParentLoop())
        Parent->addBasicBlockToLoop(NewBB, LI->getBase());
    
      DT->splitBlock(NewBB);
      if (DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>())
        DF->splitBlock(NewBB);
    
      // Make sure that NewBB is put someplace intelligent, which doesn't mess up
      // code layout too horribly.
      PlaceSplitBlockCarefully(NewBB, OutsideBlocks, L);
    }