Пример #1
0
void SplitAnalysis::getCriticalPreds(const SplitAnalysis::LoopBlocks &Blocks,
                                     BlockPtrSet &CriticalPreds) {
  CriticalPreds.clear();

  // A critical predecessor block has curli live-out, and has a successor that
  // has curli live-in and is not in the loop nor a loop exit block. For such a
  // predecessor block, we must carry the value in both the 'inside' and
  // 'outside' registers.
  for (BlockPtrSet::iterator I = Blocks.Preds.begin(), E = Blocks.Preds.end();
       I != E; ++I) {
    const MachineBasicBlock *Pred = *I;
    // Definitely not a critical edge.
    if (Pred->succ_size() == 1)
      continue;
    // This block may not have curli live out at all if there is a PHI.
    if (!lis_.isLiveOutOfMBB(*curli_, Pred))
      continue;
    // Does this block have a successor outside the loop?
    for (MachineBasicBlock::const_pred_iterator SI = Pred->succ_begin(),
         SE = Pred->succ_end(); SI != SE; ++SI) {
      const MachineBasicBlock *Succ = *SI;
      if (Blocks.Loop.count(Succ) || Blocks.Exits.count(Succ))
        continue;
      if (!lis_.isLiveInToMBB(*curli_, Succ))
        continue;
      // This is a critical predecessor block.
      CriticalPreds.insert(Pred);
      break;
    }
  }
}
Пример #2
0
/// canSplitCriticalExits - Return true if it is possible to insert new exit
/// blocks before the blocks in CriticalExits.
bool
SplitAnalysis::canSplitCriticalExits(const SplitAnalysis::LoopBlocks &Blocks,
                                     BlockPtrSet &CriticalExits) {
  // If we don't allow critical edge splitting, require no critical exits.
  if (!AllowSplit)
    return CriticalExits.empty();

  for (BlockPtrSet::iterator I = CriticalExits.begin(), E = CriticalExits.end();
       I != E; ++I) {
    const MachineBasicBlock *Succ = *I;
    // We want to insert a new pre-exit MBB before Succ, and change all the
    // in-loop blocks to branch to the pre-exit instead of Succ.
    // Check that all the in-loop predecessors can be changed.
    for (MachineBasicBlock::const_pred_iterator PI = Succ->pred_begin(),
         PE = Succ->pred_end(); PI != PE; ++PI) {
      const MachineBasicBlock *Pred = *PI;
      // The external predecessors won't be altered.
      if (!Blocks.Loop.count(Pred) && !Blocks.Preds.count(Pred))
        continue;
      if (!canAnalyzeBranch(Pred))
        return false;
    }

    // If Succ's layout predecessor falls through, that too must be analyzable.
    // We need to insert the pre-exit block in the gap.
    MachineFunction::const_iterator MFI = Succ;
    if (MFI == mf_.begin())
      continue;
    if (!canAnalyzeBranch(--MFI))
      return false;
  }
  // No problems found.
  return true;
}
Пример #3
0
/// getCriticalExits - It may be necessary to partially break critical edges
/// leaving the loop if an exit block has predecessors from outside the loop
/// periphery.
void SplitAnalysis::getCriticalExits(const SplitAnalysis::LoopBlocks &Blocks,
                                     BlockPtrSet &CriticalExits) {
  CriticalExits.clear();

  // A critical exit block has curli live-in, and has a predecessor that is not
  // in the loop nor a loop predecessor. For such an exit block, the edges
  // carrying the new variable must be moved to a new pre-exit block.
  for (BlockPtrSet::iterator I = Blocks.Exits.begin(), E = Blocks.Exits.end();
       I != E; ++I) {
    const MachineBasicBlock *Exit = *I;
    // A single-predecessor exit block is definitely not a critical edge.
    if (Exit->pred_size() == 1)
      continue;
    // This exit may not have curli live in at all. No need to split.
    if (!lis_.isLiveInToMBB(*curli_, Exit))
      continue;
    // Does this exit block have a predecessor that is not a loop block or loop
    // predecessor?
    for (MachineBasicBlock::const_pred_iterator PI = Exit->pred_begin(),
         PE = Exit->pred_end(); PI != PE; ++PI) {
      const MachineBasicBlock *Pred = *PI;
      if (Blocks.Loop.count(Pred) || Blocks.Preds.count(Pred))
        continue;
      // This is a critical exit block, and we need to split the exit edge.
      CriticalExits.insert(Exit);
      break;
    }
  }
}
Пример #4
0
/// getCriticalExits - It may be necessary to partially break critical edges
/// leaving the loop if an exit block has phi uses of curli. Collect the exit
/// blocks that need special treatment into CriticalExits.
void SplitAnalysis::getCriticalExits(const SplitAnalysis::LoopBlocks &Blocks,
                                     BlockPtrSet &CriticalExits) {
  CriticalExits.clear();

  // A critical exit block contains a phi def of curli, and has a predecessor
  // that is not in the loop nor a loop predecessor.
  // For such an exit block, the edges carrying the new variable must be moved
  // to a new pre-exit block.
  for (BlockPtrSet::iterator I = Blocks.Exits.begin(), E = Blocks.Exits.end();
       I != E; ++I) {
    const MachineBasicBlock *Succ = *I;
    SlotIndex SuccIdx = lis_.getMBBStartIdx(Succ);
    VNInfo *SuccVNI = curli_->getVNInfoAt(SuccIdx);
    // This exit may not have curli live in at all. No need to split.
    if (!SuccVNI)
      continue;
    // If this is not a PHI def, it is either using a value from before the
    // loop, or a value defined inside the loop. Both are safe.
    if (!SuccVNI->isPHIDef() || SuccVNI->def.getBaseIndex() != SuccIdx)
      continue;
    // This exit block does have a PHI. Does it also have a predecessor that is
    // not a loop block or loop predecessor?
    for (MachineBasicBlock::const_pred_iterator PI = Succ->pred_begin(),
         PE = Succ->pred_end(); PI != PE; ++PI) {
      const MachineBasicBlock *Pred = *PI;
      if (Blocks.Loop.count(Pred) || Blocks.Preds.count(Pred))
        continue;
      // This is a critical exit block, and we need to split the exit edge.
      CriticalExits.insert(Succ);
      break;
    }
  }
}
Пример #5
0
/// getMultiUseBlocks - if curli has more than one use in a basic block, it
/// may be an advantage to split curli for the duration of the block.
bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) {
  // If curli is local to one block, there is no point to splitting it.
  if (usingBlocks_.size() <= 1)
    return false;
  // Add blocks with multiple uses.
  for (BlockCountMap::iterator I = usingBlocks_.begin(), E = usingBlocks_.end();
       I != E; ++I)
    switch (I->second) {
    case 0:
    case 1:
      continue;
    case 2: {
      // It doesn't pay to split a 2-instr block if it redefines curli.
      VNInfo *VN1 = curli_->getVNInfoAt(lis_.getMBBStartIdx(I->first));
      VNInfo *VN2 =
        curli_->getVNInfoAt(lis_.getMBBEndIdx(I->first).getPrevIndex());
      // live-in and live-out with a different value.
      if (VN1 && VN2 && VN1 != VN2)
        continue;
    } // Fall through.
    default:
      Blocks.insert(I->first);
    }
  return !Blocks.empty();
}
Пример #6
0
void SplitAnalysis::print(const BlockPtrSet &B, raw_ostream &OS) const {
  for (BlockPtrSet::const_iterator I = B.begin(), E = B.end(); I != E; ++I) {
    unsigned count = usingBlocks_.lookup(*I);
    OS << " BB#" << (*I)->getNumber();
    if (count)
      OS << '(' << count << ')';
  }
}
Пример #7
0
const MachineLoop *SplitAnalysis::getBestSplitLoop() {
  assert(curli_ && "Call analyze() before getBestSplitLoop");
  if (usingLoops_.empty())
    return 0;

  LoopPtrSet Loops;
  LoopBlocks Blocks;
  BlockPtrSet CriticalExits;

  // We split around loops where curli is used outside the periphery.
  for (LoopCountMap::const_iterator I = usingLoops_.begin(),
       E = usingLoops_.end(); I != E; ++I) {
    const MachineLoop *Loop = I->first;
    getLoopBlocks(Loop, Blocks);
    DEBUG({ dbgs() << "  "; print(Blocks, dbgs()); });

    switch(analyzeLoopPeripheralUse(Blocks)) {
    case OutsideLoop:
      break;
    case MultiPeripheral:
      // FIXME: We could split a live range with multiple uses in a peripheral
      // block and still make progress. However, it is possible that splitting
      // another live range will insert copies into a peripheral block, and
      // there is a small chance we can enter an infinity loop, inserting copies
      // forever.
      // For safety, stick to splitting live ranges with uses outside the
      // periphery.
      DEBUG(dbgs() << ": multiple peripheral uses\n");
      break;
    case ContainedInLoop:
      DEBUG(dbgs() << ": fully contained\n");
      continue;
    case SinglePeripheral:
      DEBUG(dbgs() << ": single peripheral use\n");
      continue;
    }
    // Will it be possible to split around this loop?
    getCriticalExits(Blocks, CriticalExits);
    DEBUG(dbgs() << ": " << CriticalExits.size() << " critical exits\n");
    if (!canSplitCriticalExits(Blocks, CriticalExits))
      continue;
    // This is a possible split.
    Loops.insert(Loop);
  }
Пример #8
0
void BlockMap::Segment(Block& seed, BlockPtrSet& segment) {
  std::stack<Block*> blockStack;
  blockStack.push(&seed);
  while (!blockStack.empty()) {
    Block& currBlock = *(blockStack.top());
    blockStack.pop();

    currBlock.visited = true;
    segment.insert(&currBlock);
    for (const auto& neighborCoord : currBlock.GetNeighborCoords()) {
      Block& neighbor = GetBlock(neighborCoord);
      if (!neighbor.visited) {
        blockStack.push(&neighbor);
      }
    }
  }
}
Пример #9
0
const MachineLoop *SplitAnalysis::getBestSplitLoop() {
  assert(curli_ && "Call analyze() before getBestSplitLoop");
  if (usingLoops_.empty())
    return 0;

  LoopPtrSet Loops, SecondLoops;
  LoopBlocks Blocks;
  BlockPtrSet CriticalExits;

  // Find first-class and second class candidate loops.
  // We prefer to split around loops where curli is used outside the periphery.
  for (LoopPtrSet::const_iterator I = usingLoops_.begin(),
       E = usingLoops_.end(); I != E; ++I) {
    getLoopBlocks(*I, Blocks);
    LoopPtrSet *LPS = 0;
    switch(analyzeLoopPeripheralUse(Blocks)) {
    case OutsideLoop:
      LPS = &Loops;
      break;
    case MultiPeripheral:
      LPS = &SecondLoops;
      break;
    case ContainedInLoop:
      DEBUG(dbgs() << "ContainedInLoop: " << **I);
      continue;
    case SinglePeripheral:
      DEBUG(dbgs() << "SinglePeripheral: " << **I);
      continue;
    }
    // Will it be possible to split around this loop?
    getCriticalExits(Blocks, CriticalExits);
    DEBUG(dbgs() << CriticalExits.size() << " critical exits: " << **I);
    if (!canSplitCriticalExits(Blocks, CriticalExits))
      continue;
    // This is a possible split.
    assert(LPS);
    LPS->insert(*I);
  }

  DEBUG(dbgs() << "Got " << Loops.size() << " + " << SecondLoops.size()
               << " candidate loops\n");

  // If there are no first class loops available, look at second class loops.
  if (Loops.empty())
    Loops = SecondLoops;

  if (Loops.empty())
    return 0;

  // Pick the earliest loop.
  // FIXME: Are there other heuristics to consider?
  const MachineLoop *Best = 0;
  SlotIndex BestIdx;
  for (LoopPtrSet::const_iterator I = Loops.begin(), E = Loops.end(); I != E;
       ++I) {
    SlotIndex Idx = lis_.getMBBStartIdx((*I)->getHeader());
    if (!Best || Idx < BestIdx)
      Best = *I, BestIdx = Idx;
  }
  DEBUG(dbgs() << "Best: " << *Best);
  return Best;
}