Esempio n. 1
0
/// leaveIntvAfter - Leave openli after the instruction at Idx.
void SplitEditor::leaveIntvAfter(SlotIndex Idx) {
  assert(openli_ && "openIntv not called before leaveIntvAfter");

  const LiveRange *CurLR = curli_->getLiveRangeContaining(Idx.getDefIndex());
  if (!CurLR || CurLR->end <= Idx.getBoundaryIndex()) {
    DEBUG(dbgs() << "    leaveIntvAfter " << Idx << ": not live\n");
    return;
  }

  // Was this value of curli live through openli?
  if (!openli_->liveAt(CurLR->valno->def)) {
    DEBUG(dbgs() << "    leaveIntvAfter " << Idx << ": using external value\n");
    liveThrough_ = true;
    return;
  }

  // We are going to insert a back copy, so we must have a dupli_.
  LiveRange *DupLR = getDupLI()->getLiveRangeContaining(Idx.getDefIndex());
  assert(DupLR && "dupli not live into black, but curli is?");

  // Insert the COPY instruction.
  MachineBasicBlock::iterator I = lis_.getInstructionFromIndex(Idx);
  MachineInstr *MI = BuildMI(*I->getParent(), llvm::next(I), I->getDebugLoc(),
                             tii_.get(TargetOpcode::COPY), dupli_->reg)
                       .addReg(openli_->reg);
  SlotIndex CopyIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
  openli_->addRange(LiveRange(Idx.getDefIndex(), CopyIdx,
                    mapValue(CurLR->valno)));
  DupLR->valno->def = CopyIdx;
  DEBUG(dbgs() << "    leaveIntvAfter " << Idx << ": " << *openli_ << '\n');
}
Esempio n. 2
0
SlotIndex SplitEditor::enterIntvAfter(SlotIndex Idx) {
  assert(OpenIdx && "openIntv not called before enterIntvAfter");
  DEBUG(dbgs() << "    enterIntvAfter " << Idx);
  Idx = Idx.getBoundaryIndex();
  VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx);
  if (!ParentVNI) {
    DEBUG(dbgs() << ": not live\n");
    return Idx;
  }
  DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n');
  MachineInstr *MI = LIS.getInstructionFromIndex(Idx);
  assert(MI && "enterIntvAfter called with invalid index");

  VNInfo *VNI = defFromParent(OpenIdx, ParentVNI, Idx, *MI->getParent(),
                              llvm::next(MachineBasicBlock::iterator(MI)));
  return VNI->def;
}
Esempio n. 3
0
SlotIndex SplitEditor::leaveIntvAfter(SlotIndex Idx) {
  assert(OpenIdx && "openIntv not called before leaveIntvAfter");
  DEBUG(dbgs() << "    leaveIntvAfter " << Idx);

  // The interval must be live beyond the instruction at Idx.
  Idx = Idx.getBoundaryIndex();
  VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx);
  if (!ParentVNI) {
    DEBUG(dbgs() << ": not live\n");
    return Idx.getNextSlot();
  }
  DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n');

  MachineInstr *MI = LIS.getInstructionFromIndex(Idx);
  assert(MI && "No instruction at index");
  VNInfo *VNI = defFromParent(0, ParentVNI, Idx, *MI->getParent(),
                              llvm::next(MachineBasicBlock::iterator(MI)));
  return VNI->def;
}
Esempio n. 4
0
/// Check whether (part of) \p SuperPhysReg is live through \p MI.
/// \pre \p MI defines a subregister of a virtual register that
/// has been assigned to \p SuperPhysReg.
bool VirtRegRewriter::subRegLiveThrough(const MachineInstr &MI,
                                        unsigned SuperPhysReg) const {
  SlotIndex MIIndex = LIS->getInstructionIndex(MI);
  SlotIndex BeforeMIUses = MIIndex.getBaseIndex();
  SlotIndex AfterMIDefs = MIIndex.getBoundaryIndex();
  for (MCRegUnitIterator Unit(SuperPhysReg, TRI); Unit.isValid(); ++Unit) {
    const LiveRange &UnitRange = LIS->getRegUnit(*Unit);
    // If the regunit is live both before and after MI,
    // we assume it is live through.
    // Generally speaking, this is not true, because something like
    // "RU = op RU" would match that description.
    // However, we know that we are trying to assess whether
    // a def of a virtual reg, vreg, is live at the same time of RU.
    // If we are in the "RU = op RU" situation, that means that vreg
    // is defined at the same time as RU (i.e., "vreg, RU = op RU").
    // Thus, vreg and RU interferes and vreg cannot be assigned to
    // SuperPhysReg. Therefore, this situation cannot happen.
    if (UnitRange.liveAt(AfterMIDefs) && UnitRange.liveAt(BeforeMIUses))
      return true;
  }
  return false;
}
Esempio n. 5
0
void SplitEditor::splitLiveThroughBlock(unsigned MBBNum,
                                        unsigned IntvIn, SlotIndex LeaveBefore,
                                        unsigned IntvOut, SlotIndex EnterAfter){
  SlotIndex Start, Stop;
  tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(MBBNum);

  DEBUG(dbgs() << "BB#" << MBBNum << " [" << Start << ';' << Stop
               << ") intf " << LeaveBefore << '-' << EnterAfter
               << ", live-through " << IntvIn << " -> " << IntvOut);

  assert((IntvIn || IntvOut) && "Use splitSingleBlock for isolated blocks");

  assert((!LeaveBefore || LeaveBefore < Stop) && "Interference after block");
  assert((!IntvIn || !LeaveBefore || LeaveBefore > Start) && "Impossible intf");
  assert((!EnterAfter || EnterAfter >= Start) && "Interference before block");

  MachineBasicBlock *MBB = VRM.getMachineFunction().getBlockNumbered(MBBNum);

  if (!IntvOut) {
    DEBUG(dbgs() << ", spill on entry.\n");
    //
    //        <<<<<<<<<    Possible LeaveBefore interference.
    //    |-----------|    Live through.
    //    -____________    Spill on entry.
    //
    selectIntv(IntvIn);
    SlotIndex Idx = leaveIntvAtTop(*MBB);
    assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference");
    (void)Idx;
    return;
  }

  if (!IntvIn) {
    DEBUG(dbgs() << ", reload on exit.\n");
    //
    //    >>>>>>>          Possible EnterAfter interference.
    //    |-----------|    Live through.
    //    ___________--    Reload on exit.
    //
    selectIntv(IntvOut);
    SlotIndex Idx = enterIntvAtEnd(*MBB);
    assert((!EnterAfter || Idx >= EnterAfter) && "Interference");
    (void)Idx;
    return;
  }

  if (IntvIn == IntvOut && !LeaveBefore && !EnterAfter) {
    DEBUG(dbgs() << ", straight through.\n");
    //
    //    |-----------|    Live through.
    //    -------------    Straight through, same intv, no interference.
    //
    selectIntv(IntvOut);
    useIntv(Start, Stop);
    return;
  }

  // We cannot legally insert splits after LSP.
  SlotIndex LSP = SA.getLastSplitPoint(MBBNum);
  assert((!IntvOut || !EnterAfter || EnterAfter < LSP) && "Impossible intf");

  if (IntvIn != IntvOut && (!LeaveBefore || !EnterAfter ||
                  LeaveBefore.getBaseIndex() > EnterAfter.getBoundaryIndex())) {
    DEBUG(dbgs() << ", switch avoiding interference.\n");
    //
    //    >>>>     <<<<    Non-overlapping EnterAfter/LeaveBefore interference.
    //    |-----------|    Live through.
    //    ------=======    Switch intervals between interference.
    //
    selectIntv(IntvOut);
    SlotIndex Idx;
    if (LeaveBefore && LeaveBefore < LSP) {
      Idx = enterIntvBefore(LeaveBefore);
      useIntv(Idx, Stop);
    } else {
      Idx = enterIntvAtEnd(*MBB);
    }
    selectIntv(IntvIn);
    useIntv(Start, Idx);
    assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference");
    assert((!EnterAfter || Idx >= EnterAfter) && "Interference");
    return;
  }

  DEBUG(dbgs() << ", create local intv for interference.\n");
  //
  //    >>><><><><<<<    Overlapping EnterAfter/LeaveBefore interference.
  //    |-----------|    Live through.
  //    ==---------==    Switch intervals before/after interference.
  //
  assert(LeaveBefore <= EnterAfter && "Missed case");

  selectIntv(IntvOut);
  SlotIndex Idx = enterIntvAfter(EnterAfter);
  useIntv(Idx, Stop);
  assert((!EnterAfter || Idx >= EnterAfter) && "Interference");

  selectIntv(IntvIn);
  Idx = leaveIntvBefore(LeaveBefore);
  useIntv(Start, Idx);
  assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference");
}