[llvm-commits] [llvm] r157006 - in /llvm/trunk/lib/CodeGen: MachineScheduler.cpp RegisterPressure.cpp RegisterPressure.h

Sergei Larin slarin at codeaurora.org
Wed Aug 15 10:07:10 PDT 2012


Andy,

  Are there any examples/documentation on implementing the reg pressure
hooks for a back end?

Thanks.

Sergei

--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum.


> -----Original Message-----
> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
> bounces at cs.uiuc.edu] On Behalf Of Andrew Trick
> Sent: Thursday, May 17, 2012 1:35 PM
> To: llvm-commits at cs.uiuc.edu
> Subject: [llvm-commits] [llvm] r157006 - in /llvm/trunk/lib/CodeGen:
> MachineScheduler.cpp RegisterPressure.cpp RegisterPressure.h
> 
> Author: atrick
> Date: Thu May 17 13:35:10 2012
> New Revision: 157006
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=157006&view=rev
> Log:
> misched: Added 3-level regpressure back-off.
> 
> Introduce the basic strategy for register pressure scheduling.
> 
> 1) Respect target limits at all times.
> 
> 2) Indentify critical register classes (pressure sets).
>    Track pressure within the scheduled region.
>    Avoid increasing scheduled pressure for critical registers.
> 
> 3) Avoid exceeding the max pressure of the region prior to scheduling.
> 
> Added logic for picking between the top and bottom ready Q's based on
> regpressure heuristics.
> 
> Status: functional but needs to be asjusted to achieve good results.
> 
> Modified:
>     llvm/trunk/lib/CodeGen/MachineScheduler.cpp
>     llvm/trunk/lib/CodeGen/RegisterPressure.cpp
>     llvm/trunk/lib/CodeGen/RegisterPressure.h
> 
> Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/CodeGen/MachineScheduler.cpp?rev=157006&r1=15700
> 5&r2=157006&view=diff
> =======================================================================
> =======
> --- llvm/trunk/lib/CodeGen/MachineScheduler.cpp (original)
> +++ llvm/trunk/lib/CodeGen/MachineScheduler.cpp Thu May 17 13:35:10
> 2012
> @@ -1,4 +1,4 @@
> -//===- MachineScheduler.cpp - Machine Instruction Scheduler ----------
> -----===//
> +//===- MachineScheduler.cpp - Machine Instruction Scheduler
> +---------------===//excess
>  //
>  //                     The LLVM Compiler Infrastructure
>  //
> @@ -326,10 +326,15 @@
> 
>    MachineBasicBlock::iterator LiveRegionEnd;
> 
> -  // Register pressure in this region computed by buildSchedGraph.
> +  /// Register pressure in this region computed by buildSchedGraph.
>    IntervalPressure RegPressure;
>    RegPressureTracker RPTracker;
> 
> +  /// List of pressure sets that exceed the target's pressure limit
> + before  /// scheduling, listed in increasing set ID order. Each
> + pressure set is paired  /// with its max pressure in the currently
> scheduled regions.
> +  std::vector<PressureElement> RegionCriticalPSets;
> +
>    /// The top of the unscheduled zone.
>    MachineBasicBlock::iterator CurrentTop;
>    IntervalPressure TopPressure;
> @@ -380,8 +385,13 @@
>    /// Get register pressure for the entire scheduling region before
> scheduling.
>    const IntervalPressure &getRegPressure() const { return RegPressure;
> }
> 
> +  const std::vector<PressureElement> &getRegionCriticalPSets() const {
> +    return RegionCriticalPSets;
> +  }
> +
>  protected:
>    void initRegPressure();
> +  void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
> 
>    void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator
> InsertPos);
>    bool checkSchedLimit();
> @@ -515,6 +525,33 @@
>      BotRPTracker.recede();
> 
>    assert(BotRPTracker.getPos() == RegionEnd && "Can't find the region
> bottom");
> +
> +  // Cache the list of excess pressure sets in this region. This will
> +also track
> +  // the max pressure in the scheduled code for these sets.
> +  RegionCriticalPSets.clear();
> +  std::vector<unsigned> RegionPressure =
> +RPTracker.getPressure().MaxSetPressure;
> +  for (unsigned i = 0, e = RegionPressure.size(); i < e; ++i) {
> +    unsigned Limit = TRI->getRegPressureSetLimit(i);
> +    if (RegionPressure[i] > Limit)
> +      RegionCriticalPSets.push_back(PressureElement(i, 0));
> +  }
> +  DEBUG(dbgs() << "Excess PSets: ";
> +        for (unsigned i = 0, e = RegionCriticalPSets.size(); i != e;
> ++i)
> +          dbgs() << TRI->getRegPressureSetName(
> +            RegionCriticalPSets[i].PSetID) << " ";
> +        dbgs() << "\n");
> +}
> +
> +// FIXME: When the pressure tracker deals in pressure differences then
> +we won't // iterate over all RegionCriticalPSets[i].
> +void ScheduleDAGMI::
> +updateScheduledPressure(std::vector<unsigned> NewMaxPressure) {
> +  for (unsigned i = 0, e = RegionCriticalPSets.size(); i < e; ++i) {
> +    unsigned ID = RegionCriticalPSets[i].PSetID;
> +    int &MaxUnits = RegionCriticalPSets[i].UnitIncrease;
> +    if ((int)NewMaxPressure[ID] > MaxUnits)
> +      MaxUnits = NewMaxPressure[ID];
> +  }
>  }
> 
>  /// schedule - Called back from MachineScheduler::runOnMachineFunction
> @@ -581,6 +618,7 @@
>        // Update top scheduled pressure.
>        TopRPTracker.advance();
>        assert(TopRPTracker.getPos() == CurrentTop && "out of sync");
> +
> + updateScheduledPressure(TopRPTracker.getPressure().MaxSetPressure);
> 
>        // Release dependent instructions for scheduling.
>        releaseSuccessors(SU);
> @@ -602,6 +640,7 @@
>        // Update bottom scheduled pressure.
>        BotRPTracker.recede();
>        assert(BotRPTracker.getPos() == CurrentBottom && "out of sync");
> +
> + updateScheduledPressure(BotRPTracker.getPressure().MaxSetPressure);
> 
>        // Release dependent instructions for scheduling.
>        releasePredecessors(SU);
> @@ -654,6 +693,8 @@
> 
>    bool empty() const { return Queue.empty(); }
> 
> +  unsigned size() const { return Queue.size(); }
> +
>    iterator begin() { return Queue.begin(); }
> 
>    iterator end() { return Queue.end(); } @@ -689,6 +730,9 @@
> 
>      SchedCandidate(): SU(NULL) {}
>    };
> +  /// Represent the type of SchedCandidate found within a single
> queue.
> +  enum CandResult {
> +    NoCand, NodeOrder, SingleExcess, SingleCritical, SingleMax,
> + MultiPressure };
> 
>    ScheduleDAGMI *DAG;
>    const TargetRegisterInfo *TRI;
> @@ -732,88 +776,197 @@
>        BotQueue.push(SU);
>    }
>  protected:
> +  SUnit *pickNodeBidrectional(bool &IsTopNode);
> +
> +  CandResult pickNodeFromQueue(ReadyQ &Q, const RegPressureTracker
> &RPTracker,
> +                               SchedCandidate &Candidate);
>  #ifndef NDEBUG
>    void traceCandidate(const char *Label, unsigned QID, SUnit *SU,
> -                      int RPDiff, unsigned PSetID);
> +                      PressureElement P = PressureElement());
>  #endif
> -  bool pickNodeFromQueue(ReadyQ &Q, const RegPressureTracker
> &RPTracker,
> -                         SchedCandidate &Candidate);
>  };
>  } // namespace
> 
>  #ifndef NDEBUG
>  void ConvergingScheduler::
>  traceCandidate(const char *Label, unsigned QID, SUnit *SU,
> -               int RPDiff, unsigned PSetID) {
> +               PressureElement P) {
>    dbgs() << Label << getQName(QID) << " ";
> -  if (RPDiff)
> -    dbgs() << TRI->getRegPressureSetName(PSetID) << ":" << RPDiff << "
> ";
> +  if (P.isValid())
> +    dbgs() << TRI->getRegPressureSetName(P.PSetID) << ":" <<
> P.UnitIncrease
> +           << " ";
>    else
>      dbgs() << "     ";
>    SU->dump(DAG);
>  }
>  #endif
> 
> +/// Return true if the LHS reg pressure effect is better than RHS.
> +static bool compareRPDelta(const RegPressureDelta &LHS,
> +                           const RegPressureDelta &RHS) {
> +  // Compare each component of pressure in decreasing order of
> +importance
> +  // without checking if any are valid. Invalid PressureElements are
> +assumed to
> +  // have UnitIncrease==0, so are neutral.
> +  if (LHS.Excess.UnitIncrease != RHS.Excess.UnitIncrease)
> +    return LHS.Excess.UnitIncrease < RHS.Excess.UnitIncrease;
> +
> +  if (LHS.CriticalMax.UnitIncrease != RHS.CriticalMax.UnitIncrease)
> +    return LHS.CriticalMax.UnitIncrease <
> RHS.CriticalMax.UnitIncrease;
> +
> +  if (LHS.CurrentMax.UnitIncrease != RHS.CurrentMax.UnitIncrease)
> +    return LHS.CurrentMax.UnitIncrease < RHS.CurrentMax.UnitIncrease;
> +
> +  return false;
> +}
> +
> +
>  /// Pick the best candidate from the top queue.
>  ///
>  /// TODO: getMaxPressureDelta results can be mostly cached for each
> SUnit during  /// DAG building. To adjust for the current scheduling
> location we need to  /// maintain the number of vreg uses remaining to
> be top-scheduled.
> -bool ConvergingScheduler::pickNodeFromQueue(ReadyQ &Q,
> -                                            const RegPressureTracker
> &RPTracker,
> -                                            SchedCandidate &Candidate)
> {
> +ConvergingScheduler::CandResult ConvergingScheduler::
> +pickNodeFromQueue(ReadyQ &Q, const RegPressureTracker &RPTracker,
> +                  SchedCandidate &Candidate) {
> +
>    // getMaxPressureDelta temporarily modifies the tracker.
>    RegPressureTracker &TempTracker =
> const_cast<RegPressureTracker&>(RPTracker);
> 
>    // BestSU remains NULL if no top candidates beat the best existing
> candidate.
> -  bool FoundCandidate = false;
> +  CandResult FoundCandidate = NoCand;
>    for (ReadyQ::iterator I = Q.begin(), E = Q.end(); I != E; ++I) {
> 
>      RegPressureDelta RPDelta;
> -    TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta);
> +    TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta,
> +                                    DAG->getRegionCriticalPSets(),
> +
> + DAG->getRegPressure().MaxSetPressure);
> 
> +    // Initialize the candidate if needed.
> +    if (!Candidate.SU) {
> +      Candidate.SU = *I;
> +      Candidate.RPDelta = RPDelta;
> +      FoundCandidate = NodeOrder;
> +      continue;
> +    }
>      // Avoid exceeding the target's limit.
> -    if (!Candidate.SU || RPDelta.ExcessUnits <
> Candidate.RPDelta.ExcessUnits) {
> -      DEBUG(traceCandidate(Candidate.SU ? "PCAND" : "ACAND", Q.ID, *I,
> -                           RPDelta.ExcessUnits, RPDelta.ExcessSetID));
> +    if (RPDelta.Excess.UnitIncrease <
> Candidate.RPDelta.Excess.UnitIncrease) {
> +      DEBUG(traceCandidate("ECAND", Q.ID, *I, RPDelta.Excess));
>        Candidate.SU = *I;
>        Candidate.RPDelta = RPDelta;
> -      FoundCandidate = true;
> +      FoundCandidate = SingleExcess;
>        continue;
>      }
> -    if (RPDelta.ExcessUnits > Candidate.RPDelta.ExcessUnits)
> +    if (RPDelta.Excess.UnitIncrease >
> + Candidate.RPDelta.Excess.UnitIncrease)
>        continue;
> +    if (FoundCandidate == SingleExcess)
> +      FoundCandidate = MultiPressure;
> 
> -    // Avoid increasing the max pressure.
> -    if (RPDelta.MaxUnitIncrease < Candidate.RPDelta.MaxUnitIncrease) {
> -      DEBUG(traceCandidate("MCAND", Q.ID, *I,
> -                           RPDelta.ExcessUnits, RPDelta.ExcessSetID));
> +    // Avoid increasing the max critical pressure in the scheduled
> region.
> +    if (RPDelta.CriticalMax.UnitIncrease
> +        < Candidate.RPDelta.CriticalMax.UnitIncrease) {
> +      DEBUG(traceCandidate("PCAND", Q.ID, *I, RPDelta.CriticalMax));
>        Candidate.SU = *I;
>        Candidate.RPDelta = RPDelta;
> -      FoundCandidate = true;
> +      FoundCandidate = SingleCritical;
>        continue;
>      }
> -    if (RPDelta.MaxUnitIncrease > Candidate.RPDelta.MaxUnitIncrease)
> +    if (RPDelta.CriticalMax.UnitIncrease
> +        > Candidate.RPDelta.CriticalMax.UnitIncrease)
>        continue;
> +    if (FoundCandidate == SingleCritical)
> +      FoundCandidate = MultiPressure;
> +
> +    // Avoid increasing the max pressure of the entire region.
> +    if (RPDelta.CurrentMax.UnitIncrease
> +        < Candidate.RPDelta.CurrentMax.UnitIncrease) {
> +      DEBUG(traceCandidate("MCAND", Q.ID, *I, RPDelta.CurrentMax));
> +      Candidate.SU = *I;
> +      Candidate.RPDelta = RPDelta;
> +      FoundCandidate = SingleMax;
> +      continue;
> +    }
> +    if (RPDelta.CurrentMax.UnitIncrease
> +        > Candidate.RPDelta.CurrentMax.UnitIncrease)
> +      continue;
> +    if (FoundCandidate == SingleMax)
> +      FoundCandidate = MultiPressure;
> 
>      // Fall through to original instruction order.
> -    // Only consider node order if BestSU was chosen from this Q.
> -    if (!FoundCandidate)
> +    // Only consider node order if Candidate was chosen from this Q.
> +    if (FoundCandidate == NoCand)
>        continue;
> 
>      if ((Q.ID == TopQID && (*I)->NodeNum < Candidate.SU->NodeNum)
>          || (Q.ID == BotQID && (*I)->NodeNum > Candidate.SU->NodeNum))
> {
> -      DEBUG(traceCandidate("NCAND", Q.ID, *I, 0, 0));
> +      DEBUG(traceCandidate("NCAND", Q.ID, *I));
>        Candidate.SU = *I;
>        Candidate.RPDelta = RPDelta;
> -      FoundCandidate = true;
> +      FoundCandidate = NodeOrder;
>      }
>    }
>    return FoundCandidate;
>  }
> 
> -/// Pick the best node from either the top or bottom queue to balance
> the -/// schedule.
> +/// Pick the best candidate node from either the top or bottom queue.
> +SUnit *ConvergingScheduler::pickNodeBidrectional(bool &IsTopNode) {
> +  // Schedule as far as possible in the direction of no choice. This
> is
> +most
> +  // efficient, but also provides the best heuristics for
> CriticalPSets.
> +  if (BotQueue.size() == 1) {
> +    IsTopNode = false;
> +    return *BotQueue.begin();
> +  }
> +  if (TopQueue.size() == 1) {
> +    IsTopNode = true;
> +    return *TopQueue.begin();
> +  }
> +  SchedCandidate BotCandidate;
> +  // Prefer bottom scheduling when heuristics are silent.
> +  CandResult BotResult =
> +    pickNodeFromQueue(BotQueue, DAG->getBotRPTracker(), BotCandidate);
> +  assert(BotResult != NoCand && "failed to find the first candidate");
> +
> +  // If either Q has a single candidate that provides the least
> + increase in  // Excess pressure, we can immediately schedule from
> that Q.
> +  //
> +  // RegionCriticalPSets summarizes the pressure within the scheduled
> + region and  // affects picking from either Q. If scheduling in one
> + direction must  // increase pressure for one of the excess PSets,
> then
> + schedule in that  // direction first to provide more freedom in the
> other direction.
> +  if (BotResult == SingleExcess || BotResult == SingleCritical) {
> +    IsTopNode = false;
> +    return BotCandidate.SU;
> +  }
> +  // Check if the top Q has a better candidate.
> +  SchedCandidate TopCandidate;
> +  CandResult TopResult =
> +    pickNodeFromQueue(TopQueue, DAG->getTopRPTracker(), TopCandidate);
> + assert(TopResult != NoCand && "failed to find the first candidate");
> +
> +  if (TopResult == SingleExcess || TopResult == SingleCritical) {
> +    IsTopNode = true;
> +    return TopCandidate.SU;
> +  }
> +  // If either Q has a single candidate that minimizes pressure above
> +the
> +  // original region's pressure pick it.
> +  if (BotResult == SingleMax) {
> +    IsTopNode = false;
> +    return BotCandidate.SU;
> +  }
> +  if (TopResult == SingleMax) {
> +    IsTopNode = true;
> +    return TopCandidate.SU;
> +  }
> +  // Check for a salient pressure difference and pick the best from
> either side.
> +  if (compareRPDelta(TopCandidate.RPDelta, BotCandidate.RPDelta)) {
> +    IsTopNode = true;
> +    return TopCandidate.SU;
> +  }
> +  // Otherwise prefer the bottom candidate in node order.
> +  IsTopNode = false;
> +  return BotCandidate.SU;
> +}
> +
> +/// Pick the best node to balance the schedule. Implements
> MachineSchedStrategy.
>  SUnit *ConvergingScheduler::pickNode(bool &IsTopNode) {
>    if (DAG->top() == DAG->bottom()) {
>      assert(TopQueue.empty() && BotQueue.empty() && "ReadyQ garbage");
> @@ -829,12 +982,7 @@
>      IsTopNode = false;
>    }
>    else {
> -    SchedCandidate Candidate;
> -    // Prefer picking from the bottom.
> -    pickNodeFromQueue(BotQueue, DAG->getBotRPTracker(), Candidate);
> -    IsTopNode =
> -      pickNodeFromQueue(TopQueue, DAG->getTopRPTracker(), Candidate);
> -    SU = Candidate.SU;
> +    SU = pickNodeBidrectional(IsTopNode);
>    }
>    if (SU->isTopReady()) {
>      assert(!TopQueue.empty() && "bad ready count");
> 
> Modified: llvm/trunk/lib/CodeGen/RegisterPressure.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/CodeGen/RegisterPressure.cpp?rev=157006&r1=15700
> 5&r2=157006&view=diff
> =======================================================================
> =======
> --- llvm/trunk/lib/CodeGen/RegisterPressure.cpp (original)
> +++ llvm/trunk/lib/CodeGen/RegisterPressure.cpp Thu May 17 13:35:10
> 2012
> @@ -562,12 +562,13 @@
>    return true;
>  }
> 
> -// Find the max change in excess pressure across all sets.
> -static int computeMaxPressureDelta(ArrayRef<unsigned> OldPressureVec,
> -                                   ArrayRef<unsigned> NewPressureVec,
> -                                   unsigned &PSetID,
> -                                   const TargetRegisterInfo *TRI) {
> +/// Find the max change in excess pressure across all sets.
> +static void computeExcessPressureDelta(ArrayRef<unsigned>
> OldPressureVec,
> +                                       ArrayRef<unsigned>
> NewPressureVec,
> +                                       RegPressureDelta &Delta,
> +                                       const TargetRegisterInfo *TRI)
> {
>    int ExcessUnits = 0;
> +  unsigned PSetID = ~0U;
>    for (unsigned i = 0, e = OldPressureVec.size(); i < e; ++i) {
>      unsigned POld = OldPressureVec[i];
>      unsigned PNew = NewPressureVec[i];
> @@ -590,7 +591,50 @@
>        PSetID = i;
>      }
>    }
> -  return ExcessUnits;
> +  Delta.Excess.PSetID = PSetID;
> +  Delta.Excess.UnitIncrease = ExcessUnits; }
> +
> +/// Find the max change in max pressure that either surpasses a
> +critical PSet /// limit or exceeds the current MaxPressureLimit.
> +///
> +/// FIXME: comparing each element of the old and new MaxPressure
> +vectors here is /// silly. It's done now to demonstrate the concept
> but
> +will go away with a /// RegPressureTracker API change to work with
> pressure differences.
> +static void computeMaxPressureDelta(ArrayRef<unsigned>
> OldMaxPressureVec,
> +                                    ArrayRef<unsigned>
> NewMaxPressureVec,
> +                                    ArrayRef<PressureElement>
> CriticalPSets,
> +                                    ArrayRef<unsigned>
> MaxPressureLimit,
> +                                    RegPressureDelta &Delta) {
> +  Delta.CriticalMax = PressureElement();
> +  Delta.CurrentMax = PressureElement();
> +
> +  unsigned CritIdx = 0, CritEnd = CriticalPSets.size();  for (unsigned
> + i = 0, e = OldMaxPressureVec.size(); i < e; ++i) {
> +    unsigned POld = OldMaxPressureVec[i];
> +    unsigned PNew = NewMaxPressureVec[i];
> +    if (PNew == POld) // No change in this set in the common case.
> +      continue;
> +
> +    while (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID < i)
> +      ++CritIdx;
> +
> +    if (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID == i) {
> +      int PDiff = (int)PNew -
> (int)CriticalPSets[CritIdx].UnitIncrease;
> +      if (PDiff > Delta.CriticalMax.UnitIncrease) {
> +        Delta.CriticalMax.PSetID = i;
> +        Delta.CriticalMax.UnitIncrease = PDiff;
> +      }
> +    }
> +
> +    // Find the greatest increase above MaxPressureLimit.
> +    // (Ignores negative MDiff).
> +    int MDiff = (int)PNew - (int)MaxPressureLimit[i];
> +    if (MDiff > Delta.CurrentMax.UnitIncrease) {
> +      Delta.CurrentMax.PSetID = i;
> +      Delta.CurrentMax.UnitIncrease = PNew;
> +    }
> +  }
>  }
> 
>  /// Consider the pressure increase caused by traversing this
> instruction @@ -605,13 +649,17 @@  /// result per-SUnit with enough
> information to adjust for the current  /// scheduling position. But
> this works as a proof of concept.
>  void RegPressureTracker::
> -getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta
> &Delta) {
> +getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta
> &Delta,
> +                          ArrayRef<PressureElement> CriticalPSets,
> +                          ArrayRef<unsigned> MaxPressureLimit) {
>    // Account for register pressure similar to
> RegPressureTracker::recede().
>    PhysRegOperands PhysRegOpers;
>    VirtRegOperands VirtRegOpers;
>    collectOperands(MI, PhysRegOpers, VirtRegOpers, TRI, RCI);
> 
>    // Snapshot Pressure.
> +  // FIXME: The snapshot heap space should persist. But I'm planning
> to
> + // summarize the pressure effect so we don't need to snapshot at all.
>    std::vector<unsigned> SavedPressure = CurrSetPressure;
>    std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
> 
> @@ -643,13 +691,11 @@
>        increaseVirtRegPressure(Reg);
>      }
>    }
> -  Delta.ExcessUnits =
> -    computeMaxPressureDelta(SavedPressure, CurrSetPressure,
> -                            Delta.ExcessSetID, TRI);
> -  Delta.MaxUnitIncrease =
> -    computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure,
> -                            Delta.MaxSetID, TRI);
> -  assert(Delta.MaxUnitIncrease >= 0 && "cannot increase max
> pressure");
> +  computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta,
> + TRI);  computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure,
> CriticalPSets,
> +                          MaxPressureLimit, Delta);
> + assert(Delta.CriticalMax.UnitIncrease >= 0 &&
> +         Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max
> + pressure");
> 
>    // Restore the tracker's state.
>    P.MaxSetPressure.swap(SavedMaxPressure);
> @@ -679,7 +725,9 @@
>  ///
>  /// This assumes that the current LiveIn set is sufficient.
>  void RegPressureTracker::
> -getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta
> &Delta) {
> +getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta
> &Delta,
> +                            ArrayRef<PressureElement> CriticalPSets,
> +                            ArrayRef<unsigned> MaxPressureLimit) {
>    // Account for register pressure similar to
> RegPressureTracker::recede().
>    PhysRegOperands PhysRegOpers;
>    VirtRegOperands VirtRegOpers;
> @@ -717,12 +765,11 @@
>    decreasePhysRegPressure(PhysRegOpers.DeadDefs);
>    decreaseVirtRegPressure(VirtRegOpers.DeadDefs);
> 
> -  Delta.ExcessUnits =
> -    computeMaxPressureDelta(SavedPressure, CurrSetPressure,
> -                            Delta.ExcessSetID, TRI);
> -  Delta.MaxUnitIncrease =
> -    computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure,
> -                            Delta.MaxSetID, TRI);
> +  computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta,
> + TRI);  computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure,
> CriticalPSets,
> +                          MaxPressureLimit, Delta);
> + assert(Delta.CriticalMax.UnitIncrease >= 0 &&
> +         Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max
> + pressure");
> 
>    // Restore the tracker's state.
>    P.MaxSetPressure.swap(SavedMaxPressure);
> 
> Modified: llvm/trunk/lib/CodeGen/RegisterPressure.h
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/CodeGen/RegisterPressure.h?rev=157006&r1=157005&
> r2=157006&view=diff
> =======================================================================
> =======
> --- llvm/trunk/lib/CodeGen/RegisterPressure.h (original)
> +++ llvm/trunk/lib/CodeGen/RegisterPressure.h Thu May 17 13:35:10 2012
> @@ -80,28 +80,38 @@
>    void openBottom(MachineBasicBlock::const_iterator PrevBottom);  };
> 
> -/// Store the results of a change in pressure.
> +/// An element of pressure difference that identifies the pressure set
> +and /// amount of increase or decrease in units of pressure.
> +struct PressureElement {
> +  unsigned PSetID;
> +  int UnitIncrease;
> +
> +  PressureElement(): PSetID(~0U), UnitIncrease(0) {}
> + PressureElement(unsigned id, int inc): PSetID(id), UnitIncrease(inc)
> + {}
> +
> +  bool isValid() const { return PSetID != ~0U; } };
> +
> +/// Store the effects of a change in pressure on things that MI
> +scheduler cares /// about.
>  ///
> -/// ExcessUnits is the value of the largest difference in register
> units beyond
> +/// Excess records the value of the largest difference in register
> +units beyond
>  /// the target's pressure limits across the affected pressure sets,
> where  /// largest is defined as the absolute value of the difference.
> Negative  /// ExcessUnits indicates a reduction in pressure that had
> already exceeded the  /// target's limits.
>  ///
> -/// MaxUnitIncrease is the largest increase in register units required
> across -/// the scheduled region across the affected pressure sets,
> regardless of the -/// target's pressure limits.
> +/// CriticalMax records the largest increase in the tracker's max
> +pressure that /// exceeds the critical limit for some pressure set
> determined by the client.
>  ///
> -/// If ExcessUnits == 0, then ExcessSetID is invalid.
> -/// If MaxUnitIncrease == 0, then MaxSetID is invalid.
> +/// CurrentMax records the largest increase in the tracker's max
> +pressure that /// exceeds the current limit for some pressure set
> determined by the client.
>  struct RegPressureDelta {
> -  int ExcessUnits;
> -  unsigned ExcessSetID;
> -  int MaxUnitIncrease;
> -  unsigned MaxSetID;
> +  PressureElement Excess;
> +  PressureElement CriticalMax;
> +  PressureElement CurrentMax;
> 
> -  RegPressureDelta():
> -    ExcessUnits(0), ExcessSetID(~0U), MaxUnitIncrease(0),
> MaxSetID(~0U) {}
> +  RegPressureDelta() {}
>  };
> 
>  /// Track the current register pressure at some position in the
> instruction @@ -203,24 +213,32 @@
>    /// limit based on the tracker's current pressure, and record the
> number of
>    /// excess register units of that pressure set introduced by this
> instruction.
>    void getMaxUpwardPressureDelta(const MachineInstr *MI,
> -                                 RegPressureDelta &Delta);
> +                                 RegPressureDelta &Delta,
> +                                 ArrayRef<PressureElement>
> CriticalPSets,
> +                                 ArrayRef<unsigned> MaxPressureLimit);
> 
>    /// Consider the pressure increase caused by traversing this
> instruction
>    /// top-down. Find the pressure set with the most change beyond its
> pressure
>    /// limit based on the tracker's current pressure, and record the
> number of
>    /// excess register units of that pressure set introduced by this
> instruction.
>    void getMaxDownwardPressureDelta(const MachineInstr *MI,
> -                                   RegPressureDelta &Delta);
> +                                   RegPressureDelta &Delta,
> +                                   ArrayRef<PressureElement>
> CriticalPSets,
> +                                   ArrayRef<unsigned>
> + MaxPressureLimit);
> 
>    /// Find the pressure set with the most change beyond its pressure
> limit after
>    /// traversing this instruction either upward or downward depending
> on the
>    /// closed end of the current region.
> -  void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta
> &Delta) {
> +  void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta
> &Delta,
> +                           ArrayRef<PressureElement> CriticalPSets,
> +                           ArrayRef<unsigned> MaxPressureLimit) {
>      if (isTopClosed())
> -      return getMaxDownwardPressureDelta(MI, Delta);
> +      return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets,
> +                                         MaxPressureLimit);
> 
>      assert(isBottomClosed() && "Uninitialized pressure tracker");
> -    return getMaxUpwardPressureDelta(MI, Delta);
> +    return getMaxUpwardPressureDelta(MI, Delta, CriticalPSets,
> +                                     MaxPressureLimit);
>    }
> 
>  protected:
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list