Пример #1
0
/// \brief Clones the body of the loop L, putting it between \p InsertTop and \p
/// InsertBot.
/// \param IterNumber The serial number of the iteration currently being
/// peeled off.
/// \param Exit The exit block of the original loop.
/// \param[out] NewBlocks A list of the the blocks in the newly created clone
/// \param[out] VMap The value map between the loop and the new clone.
/// \param LoopBlocks A helper for DFS-traversal of the loop.
/// \param LVMap A value-map that maps instructions from the original loop to
/// instructions in the last peeled-off iteration.
static void cloneLoopBlocks(Loop *L, unsigned IterNumber, BasicBlock *InsertTop,
                            BasicBlock *InsertBot, BasicBlock *Exit,
                            SmallVectorImpl<BasicBlock *> &NewBlocks,
                            LoopBlocksDFS &LoopBlocks, ValueToValueMapTy &VMap,
                            ValueToValueMapTy &LVMap, LoopInfo *LI) {

  BasicBlock *Header = L->getHeader();
  BasicBlock *Latch = L->getLoopLatch();
  BasicBlock *PreHeader = L->getLoopPreheader();

  Function *F = Header->getParent();
  LoopBlocksDFS::RPOIterator BlockBegin = LoopBlocks.beginRPO();
  LoopBlocksDFS::RPOIterator BlockEnd = LoopBlocks.endRPO();
  Loop *ParentLoop = L->getParentLoop();

  // For each block in the original loop, create a new copy,
  // and update the value map with the newly created values.
  for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) {
    BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, ".peel", F);
    NewBlocks.push_back(NewBB);

    if (ParentLoop)
      ParentLoop->addBasicBlockToLoop(NewBB, *LI);

    VMap[*BB] = NewBB;
  }

  // Hook-up the control flow for the newly inserted blocks.
  // The new header is hooked up directly to the "top", which is either
  // the original loop preheader (for the first iteration) or the previous
  // iteration's exiting block (for every other iteration)
  InsertTop->getTerminator()->setSuccessor(0, cast<BasicBlock>(VMap[Header]));

  // Similarly, for the latch:
  // The original exiting edge is still hooked up to the loop exit.
  // The backedge now goes to the "bottom", which is either the loop's real
  // header (for the last peeled iteration) or the copied header of the next
  // iteration (for every other iteration)
  BranchInst *LatchBR =
      cast<BranchInst>(cast<BasicBlock>(VMap[Latch])->getTerminator());
  unsigned HeaderIdx = (LatchBR->getSuccessor(0) == Header ? 0 : 1);
  LatchBR->setSuccessor(HeaderIdx, InsertBot);
  LatchBR->setSuccessor(1 - HeaderIdx, Exit);

  // The new copy of the loop body starts with a bunch of PHI nodes
  // that pick an incoming value from either the preheader, or the previous
  // loop iteration. Since this copy is no longer part of the loop, we
  // resolve this statically:
  // For the first iteration, we use the value from the preheader directly.
  // For any other iteration, we replace the phi with the value generated by
  // the immediately preceding clone of the loop body (which represents
  // the previous iteration).
  for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
    PHINode *NewPHI = cast<PHINode>(VMap[&*I]);
    if (IterNumber == 0) {
      VMap[&*I] = NewPHI->getIncomingValueForBlock(PreHeader);
    } else {
      Value *LatchVal = NewPHI->getIncomingValueForBlock(Latch);
      Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
      if (LatchInst && L->contains(LatchInst))
        VMap[&*I] = LVMap[LatchInst];
      else
        VMap[&*I] = LatchVal;
    }
    cast<BasicBlock>(VMap[Header])->getInstList().erase(NewPHI);
  }

  // Fix up the outgoing values - we need to add a value for the iteration
  // we've just created. Note that this must happen *after* the incoming
  // values are adjusted, since the value going out of the latch may also be
  // a value coming into the header.
  for (BasicBlock::iterator I = Exit->begin(); isa<PHINode>(I); ++I) {
    PHINode *PHI = cast<PHINode>(I);
    Value *LatchVal = PHI->getIncomingValueForBlock(Latch);
    Instruction *LatchInst = dyn_cast<Instruction>(LatchVal);
    if (LatchInst && L->contains(LatchInst))
      LatchVal = VMap[LatchVal];
    PHI->addIncoming(LatchVal, cast<BasicBlock>(VMap[Latch]));
  }

  // LastValueMap is updated with the values for the current loop
  // which are used the next time this function is called.
  for (const auto &KV : VMap)
    LVMap[KV.first] = KV.second;
}
Пример #2
0
/// Create a clone of the blocks in a loop and connect them together.
/// This function doesn't create a clone of the loop structure.
///
/// There are two value maps that are defined and used.  VMap is
/// for the values in the current loop instance.  LVMap contains
/// the values from the last loop instance.  We need the LVMap values
/// to update the initial values for the current loop instance.
///
static void CloneLoopBlocks(Loop *L,
                            bool FirstCopy,
                            BasicBlock *InsertTop,
                            BasicBlock *InsertBot,
                            std::vector<BasicBlock *> &NewBlocks,
                            LoopBlocksDFS &LoopBlocks,
                            ValueToValueMapTy &VMap,
                            ValueToValueMapTy &LVMap,
                            LoopInfo *LI) {

  BasicBlock *Preheader = L->getLoopPreheader();
  BasicBlock *Header = L->getHeader();
  BasicBlock *Latch = L->getLoopLatch();
  Function *F = Header->getParent();
  LoopBlocksDFS::RPOIterator BlockBegin = LoopBlocks.beginRPO();
  LoopBlocksDFS::RPOIterator BlockEnd = LoopBlocks.endRPO();
  // For each block in the original loop, create a new copy,
  // and update the value map with the newly created values.
  for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) {
    BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, ".unr", F);
    NewBlocks.push_back(NewBB);

    if (Loop *ParentLoop = L->getParentLoop())
      ParentLoop->addBasicBlockToLoop(NewBB, LI->getBase());

    VMap[*BB] = NewBB;
    if (Header == *BB) {
      // For the first block, add a CFG connection to this newly
      // created block
      InsertTop->getTerminator()->setSuccessor(0, NewBB);

      // Change the incoming values to the ones defined in the
      // previously cloned loop.
      for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
        PHINode *NewPHI = cast<PHINode>(VMap[I]);
        if (FirstCopy) {
          // We replace the first phi node with the value from the preheader
          VMap[I] = NewPHI->getIncomingValueForBlock(Preheader);
          NewBB->getInstList().erase(NewPHI);
        } else {
          // Update VMap with values from the previous block
          unsigned idx = NewPHI->getBasicBlockIndex(Latch);
          Value *InVal = NewPHI->getIncomingValue(idx);
          if (Instruction *I = dyn_cast<Instruction>(InVal))
            if (L->contains(I))
              InVal = LVMap[InVal];
          NewPHI->setIncomingValue(idx, InVal);
          NewPHI->setIncomingBlock(idx, InsertTop);
        }
      }
    }

    if (Latch == *BB) {
      VMap.erase((*BB)->getTerminator());
      NewBB->getTerminator()->eraseFromParent();
      BranchInst::Create(InsertBot, NewBB);
    }
  }
  // LastValueMap is updated with the values for the current loop
  // which are used the next time this function is called.
  for (ValueToValueMapTy::iterator VI = VMap.begin(), VE = VMap.end();
       VI != VE; ++VI) {
    LVMap[VI->first] = VI->second;
  }
}
Пример #3
0
/// Create a clone of the blocks in a loop and connect them together.
/// If UnrollProlog is true, loop structure will not be cloned, otherwise a new
/// loop will be created including all cloned blocks, and the iterator of it
/// switches to count NewIter down to 0.
///
static void CloneLoopBlocks(Loop *L, Value *NewIter, const bool UnrollProlog,
                            BasicBlock *InsertTop, BasicBlock *InsertBot,
                            std::vector<BasicBlock *> &NewBlocks,
                            LoopBlocksDFS &LoopBlocks, ValueToValueMapTy &VMap,
                            LoopInfo *LI) {
    BasicBlock *Preheader = L->getLoopPreheader();
    BasicBlock *Header = L->getHeader();
    BasicBlock *Latch = L->getLoopLatch();
    Function *F = Header->getParent();
    LoopBlocksDFS::RPOIterator BlockBegin = LoopBlocks.beginRPO();
    LoopBlocksDFS::RPOIterator BlockEnd = LoopBlocks.endRPO();
    Loop *NewLoop = 0;
    Loop *ParentLoop = L->getParentLoop();
    if (!UnrollProlog) {
        NewLoop = new Loop();
        if (ParentLoop)
            ParentLoop->addChildLoop(NewLoop);
        else
            LI->addTopLevelLoop(NewLoop);
    }

    // For each block in the original loop, create a new copy,
    // and update the value map with the newly created values.
    for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) {
        BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, ".prol", F);
        NewBlocks.push_back(NewBB);

        if (NewLoop)
            NewLoop->addBasicBlockToLoop(NewBB, *LI);
        else if (ParentLoop)
            ParentLoop->addBasicBlockToLoop(NewBB, *LI);

        VMap[*BB] = NewBB;
        if (Header == *BB) {
            // For the first block, add a CFG connection to this newly
            // created block.
            InsertTop->getTerminator()->setSuccessor(0, NewBB);

        }
        if (Latch == *BB) {
            // For the last block, if UnrollProlog is true, create a direct jump to
            // InsertBot. If not, create a loop back to cloned head.
            VMap.erase((*BB)->getTerminator());
            BasicBlock *FirstLoopBB = cast<BasicBlock>(VMap[Header]);
            BranchInst *LatchBR = cast<BranchInst>(NewBB->getTerminator());
            IRBuilder<> Builder(LatchBR);
            if (UnrollProlog) {
                Builder.CreateBr(InsertBot);
            } else {
                PHINode *NewIdx = PHINode::Create(NewIter->getType(), 2, "prol.iter",
                                                  FirstLoopBB->getFirstNonPHI());
                Value *IdxSub =
                    Builder.CreateSub(NewIdx, ConstantInt::get(NewIdx->getType(), 1),
                                      NewIdx->getName() + ".sub");
                Value *IdxCmp =
                    Builder.CreateIsNotNull(IdxSub, NewIdx->getName() + ".cmp");
                Builder.CreateCondBr(IdxCmp, FirstLoopBB, InsertBot);
                NewIdx->addIncoming(NewIter, InsertTop);
                NewIdx->addIncoming(IdxSub, NewBB);
            }
            LatchBR->eraseFromParent();
        }
    }

    // Change the incoming values to the ones defined in the preheader or
    // cloned loop.
    for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
        PHINode *NewPHI = cast<PHINode>(VMap[I]);
        if (UnrollProlog) {
            VMap[I] = NewPHI->getIncomingValueForBlock(Preheader);
            cast<BasicBlock>(VMap[Header])->getInstList().erase(NewPHI);
        } else {
            unsigned idx = NewPHI->getBasicBlockIndex(Preheader);
            NewPHI->setIncomingBlock(idx, InsertTop);
            BasicBlock *NewLatch = cast<BasicBlock>(VMap[Latch]);
            idx = NewPHI->getBasicBlockIndex(Latch);
            Value *InVal = NewPHI->getIncomingValue(idx);
            NewPHI->setIncomingBlock(idx, NewLatch);
            if (VMap[InVal])
                NewPHI->setIncomingValue(idx, VMap[InVal]);
        }
    }
    if (NewLoop) {
        // Add unroll disable metadata to disable future unrolling for this loop.
        SmallVector<Metadata *, 4> MDs;
        // Reserve first location for self reference to the LoopID metadata node.
        MDs.push_back(nullptr);
        MDNode *LoopID = NewLoop->getLoopID();
        if (LoopID) {
            // First remove any existing loop unrolling metadata.
            for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i) {
                bool IsUnrollMetadata = false;
                MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(i));
                if (MD) {
                    const MDString *S = dyn_cast<MDString>(MD->getOperand(0));
                    IsUnrollMetadata = S && S->getString().startswith("llvm.loop.unroll.");
                }
                if (!IsUnrollMetadata)
                    MDs.push_back(LoopID->getOperand(i));
            }
        }

        LLVMContext &Context = NewLoop->getHeader()->getContext();
        SmallVector<Metadata *, 1> DisableOperands;
        DisableOperands.push_back(MDString::get(Context, "llvm.loop.unroll.disable"));
        MDNode *DisableNode = MDNode::get(Context, DisableOperands);
        MDs.push_back(DisableNode);

        MDNode *NewLoopID = MDNode::get(Context, MDs);
        // Set operand 0 to refer to the loop id itself.
        NewLoopID->replaceOperandWith(0, NewLoopID);
        NewLoop->setLoopID(NewLoopID);
    }
}