void RegPressureTracker::advance() {
  const MachineInstr &MI = *CurrPos;
  RegisterOperands RegOpers;
  RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, false);
  if (TrackLaneMasks) {
    SlotIndex SlotIdx = getCurrSlot();
    RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
  }
  advance(RegOpers);
}
void RegPressureTracker::recede(SmallVectorImpl<RegisterMaskPair> *LiveUses) {
  recedeSkipDebugValues();

  const MachineInstr &MI = *CurrPos;
  RegisterOperands RegOpers;
  RegOpers.collect(MI, *TRI, *MRI, TrackLaneMasks, false);
  if (TrackLaneMasks) {
    SlotIndex SlotIdx = LIS->getInstructionIndex(*CurrPos).getRegSlot();
    RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
  } else if (RequireIntervals) {
    RegOpers.detectDeadDefs(MI, *LIS);
  }

  recede(RegOpers, LiveUses);
}
/// Record the downward impact of a single instruction on current register
/// pressure. Unlike the advance/recede pressure tracking interface, this does
/// not discover live in/outs.
///
/// This is intended for speculative queries. It leaves pressure inconsistent
/// with the current position, so must be restored by the caller.
void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
  assert(!MI->isDebugValue() && "Expect a nondebug instruction.");

  SlotIndex SlotIdx;
  if (RequireIntervals)
    SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();

  // Account for register pressure similar to RegPressureTracker::recede().
  RegisterOperands RegOpers;
  RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, false);
  if (TrackLaneMasks)
    RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);

  for (const RegisterMaskPair &Use : RegOpers.Uses) {
    unsigned Reg = Use.RegUnit;
    LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
    if (LastUseMask == 0)
      continue;
    if (RequireIntervals) {
      // The LastUseMask is queried from the liveness information of instruction
      // which may be further down the schedule. Some lanes may actually not be
      // last uses for the current position.
      // FIXME: allow the caller to pass in the list of vreg uses that remain
      // to be bottom-scheduled to avoid searching uses at each query.
      SlotIndex CurrIdx = getCurrSlot();
      LastUseMask
        = findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, LIS);
      if (LastUseMask == 0)
        continue;
    }

    LaneBitmask LiveMask = LiveRegs.contains(Reg);
    LaneBitmask NewMask = LiveMask & ~LastUseMask;
    decreaseRegPressure(Reg, LiveMask, NewMask);
  }

  // Generate liveness for defs.
  for (const RegisterMaskPair &Def : RegOpers.Defs) {
    unsigned Reg = Def.RegUnit;
    LaneBitmask LiveMask = LiveRegs.contains(Reg);
    LaneBitmask NewMask = LiveMask | Def.LaneMask;
    increaseRegPressure(Reg, LiveMask, NewMask);
  }

  // Boost pressure for all dead defs together.
  bumpDeadDefs(RegOpers.DeadDefs);
}
Exemple #4
0
/// Collect physical and virtual register operands.
static void collectOperands(const MachineInstr *MI,
                            RegisterOperands &RegOpers) {
  for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI)
    RegOpers.collect(*OperI);

  // Remove redundant physreg dead defs.
  SmallVectorImpl<unsigned>::iterator I =
    std::remove_if(RegOpers.DeadDefs.begin(), RegOpers.DeadDefs.end(),
                   std::bind1st(std::ptr_fun(containsReg), RegOpers.Defs));
  RegOpers.DeadDefs.erase(I, RegOpers.DeadDefs.end());
}
/// Record the upward impact of a single instruction on current register
/// pressure. Unlike the advance/recede pressure tracking interface, this does
/// not discover live in/outs.
///
/// This is intended for speculative queries. It leaves pressure inconsistent
/// with the current position, so must be restored by the caller.
void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
  assert(!MI->isDebugValue() && "Expect a nondebug instruction.");

  SlotIndex SlotIdx;
  if (RequireIntervals)
    SlotIdx = LIS->getInstructionIndex(*MI).getRegSlot();

  // Account for register pressure similar to RegPressureTracker::recede().
  RegisterOperands RegOpers;
  RegOpers.collect(*MI, *TRI, *MRI, TrackLaneMasks, /*IgnoreDead=*/true);
  assert(RegOpers.DeadDefs.size() == 0);
  if (TrackLaneMasks)
    RegOpers.adjustLaneLiveness(*LIS, *MRI, SlotIdx);
  else if (RequireIntervals)
    RegOpers.detectDeadDefs(*MI, *LIS);

  // Boost max pressure for all dead defs together.
  // Since CurrSetPressure and MaxSetPressure
  bumpDeadDefs(RegOpers.DeadDefs);

  // Kill liveness at live defs.
  for (const RegisterMaskPair &P : RegOpers.Defs) {
    unsigned Reg = P.RegUnit;
    LaneBitmask LiveLanes = LiveRegs.contains(Reg);
    LaneBitmask UseLanes = getRegLanes(RegOpers.Uses, Reg);
    LaneBitmask DefLanes = P.LaneMask;
    LaneBitmask LiveAfter = (LiveLanes & ~DefLanes) | UseLanes;
    decreaseRegPressure(Reg, LiveLanes, LiveAfter);
  }
  // Generate liveness for uses.
  for (const RegisterMaskPair &P : RegOpers.Uses) {
    unsigned Reg = P.RegUnit;
    LaneBitmask LiveLanes = LiveRegs.contains(Reg);
    LaneBitmask LiveAfter = LiveLanes | P.LaneMask;
    increaseRegPressure(Reg, LiveLanes, LiveAfter);
  }
}