[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
Evan Cheng
evan.cheng at apple.com
Mon Jan 8 15:50:53 PST 2007
Changes in directory llvm/lib/CodeGen/SelectionDAG:
ScheduleDAGRRList.cpp updated: 1.23 -> 1.24
---
Log message:
Fix for PR1075: http://llvm.org/PR1075 : bottom-up register-reduction scheduling actually increases register pressure.
- Fixed bugs in sethi-ullman number computation and priority queue comparison
functions.
- Separate code that handles priority computation special cases from SU number computation.
---
Diffs of the changes: (+72 -120)
ScheduleDAGRRList.cpp | 192 ++++++++++++++++++--------------------------------
1 files changed, 72 insertions(+), 120 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.23 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.24
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.23 Thu Dec 7 14:04:42 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Jan 8 17:50:38 2007
@@ -414,6 +414,12 @@
};
} // end anonymous namespace
+static inline bool isCopyFromLiveIn(const SUnit *SU) {
+ SDNode *N = SU->Node;
+ return N->getOpcode() == ISD::CopyFromReg &&
+ N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag;
+}
+
namespace {
template<class SF>
class VISIBILITY_HIDDEN RegReductionPriorityQueue
@@ -428,7 +434,7 @@
std::vector<SUnit> &sunits) {}
virtual void releaseState() {}
- virtual int getSethiUllmanNumber(unsigned NodeNum) const {
+ virtual unsigned getSethiUllmanNumber(const SUnit *SU) const {
return 0;
}
@@ -464,7 +470,7 @@
const std::vector<SUnit> *SUnits;
// SethiUllmanNumbers - The SethiUllman number for each node.
- std::vector<int> SethiUllmanNumbers;
+ std::vector<unsigned> SethiUllmanNumbers;
const TargetInstrInfo *TII;
public:
@@ -486,9 +492,30 @@
SethiUllmanNumbers.clear();
}
- int getSethiUllmanNumber(unsigned NodeNum) const {
- assert(NodeNum < SethiUllmanNumbers.size());
- return SethiUllmanNumbers[NodeNum];
+ unsigned getSethiUllmanNumber(const SUnit *SU) const {
+ assert(SU->NodeNum < SethiUllmanNumbers.size());
+ unsigned Opc = SU->Node->getOpcode();
+ if (Opc == ISD::CopyFromReg && !isCopyFromLiveIn(SU))
+ // CopyFromReg should be close to its def because it restricts
+ // allocation choices. But if it is a livein then perhaps we want it
+ // closer to its uses so it can be coalesced.
+ return 0xffff;
+ else if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg)
+ // CopyToReg should be close to its uses to facilitate coalescing and
+ // avoid spilling.
+ return 0;
+ else if (SU->NumSuccs == 0)
+ // If SU does not have a use, i.e. it doesn't produce a value that would
+ // be consumed (e.g. store), then it terminates a chain of computation.
+ // Give it a large SethiUllman number so it will be scheduled right
+ // before its predecessors that it doesn't lengthen their live ranges.
+ return 0xffff;
+ else if (SU->NumPreds == 0)
+ // If SU does not have a def, schedule it close to its uses because it
+ // does not lengthen any live ranges.
+ return 0;
+ else
+ return SethiUllmanNumbers[SU->NodeNum];
}
bool isDUOperand(const SUnit *SU1, const SUnit *SU2) {
@@ -507,7 +534,7 @@
bool canClobber(SUnit *SU, SUnit *Op);
void AddPseudoTwoAddrDeps();
void CalculatePriorities();
- int CalcNodePriority(const SUnit *SU);
+ unsigned CalcNodePriority(const SUnit *SU);
};
@@ -520,7 +547,7 @@
const std::vector<SUnit> *SUnits;
// SethiUllmanNumbers - The SethiUllman number for each node.
- std::vector<int> SethiUllmanNumbers;
+ std::vector<unsigned> SethiUllmanNumbers;
public:
TDRegReductionPriorityQueue() {}
@@ -538,86 +565,38 @@
SethiUllmanNumbers.clear();
}
- int getSethiUllmanNumber(unsigned NodeNum) const {
- assert(NodeNum < SethiUllmanNumbers.size());
- return SethiUllmanNumbers[NodeNum];
+ unsigned getSethiUllmanNumber(const SUnit *SU) const {
+ assert(SU->NodeNum < SethiUllmanNumbers.size());
+ return SethiUllmanNumbers[SU->NodeNum];
}
private:
void CalculatePriorities();
- int CalcNodePriority(const SUnit *SU);
+ unsigned CalcNodePriority(const SUnit *SU);
};
}
-static bool isFloater(const SUnit *SU) {
- if (SU->Node->isTargetOpcode()) {
- if (SU->NumPreds == 0)
- return true;
- if (SU->NumPreds == 1) {
- for (SUnit::const_pred_iterator I = SU->Preds.begin(),E = SU->Preds.end();
- I != E; ++I) {
- if (I->second) continue;
-
- SUnit *PredSU = I->first;
- unsigned Opc = PredSU->Node->getOpcode();
- if (Opc != ISD::EntryToken && Opc != ISD::TokenFactor &&
- Opc != ISD::CopyToReg)
- return false;
- }
- return true;
- }
- }
- return false;
-}
-
-static bool isSimpleFloaterUse(const SUnit *SU) {
- unsigned NumOps = 0;
- for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
- I != E; ++I) {
- if (I->second) continue;
- if (++NumOps > 1)
- return false;
- if (!isFloater(I->first))
- return false;
- }
- return true;
-}
-
// Bottom up
bool bu_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
- unsigned LeftNum = left->NodeNum;
- unsigned RightNum = right->NodeNum;
bool LIsTarget = left->Node->isTargetOpcode();
bool RIsTarget = right->Node->isTargetOpcode();
- int LPriority = SPQ->getSethiUllmanNumber(LeftNum);
- int RPriority = SPQ->getSethiUllmanNumber(RightNum);
- int LBonus = 0;
- int RBonus = 0;
-
- // Schedule floaters (e.g. load from some constant address) and those nodes
- // with a single predecessor each first. They maintain / reduce register
- // pressure.
- if (isFloater(left) || isSimpleFloaterUse(left))
- LBonus += 2;
- if (isFloater(right) || isSimpleFloaterUse(right))
- RBonus += 2;
+ unsigned LPriority = SPQ->getSethiUllmanNumber(left);
+ unsigned RPriority = SPQ->getSethiUllmanNumber(right);
// Special tie breaker: if two nodes share a operand, the one that use it
// as a def&use operand is preferred.
if (LIsTarget && RIsTarget) {
- if (left->isTwoAddress && !right->isTwoAddress) {
+ if (left->isTwoAddress && !right->isTwoAddress)
if (SPQ->isDUOperand(left, right))
- LBonus += 2;
- }
- if (!left->isTwoAddress && right->isTwoAddress) {
+ return false;
+ if (!left->isTwoAddress && right->isTwoAddress)
if (SPQ->isDUOperand(right, left))
- RBonus += 2;
- }
+ return true;
}
- if (LPriority+LBonus < RPriority+RBonus)
+ if (LPriority > RPriority)
return true;
- else if (LPriority+LBonus == RPriority+RBonus)
+ else if (LPriority == RPriority)
if (left->Height > right->Height)
return true;
else if (left->Height == right->Height)
@@ -629,12 +608,6 @@
return false;
}
-static inline bool isCopyFromLiveIn(const SUnit *SU) {
- SDNode *N = SU->Node;
- return N->getOpcode() == ISD::CopyFromReg &&
- N->getOperand(N->getNumOperands()-1).getValueType() != MVT::Flag;
-}
-
// FIXME: This is probably too slow!
static void isReachable(SUnit *SU, SUnit *TargetSU,
std::set<SUnit *> &Visited, bool &Reached) {
@@ -723,47 +696,28 @@
/// CalcNodePriority - Priority is the Sethi Ullman number.
/// Smaller number is the higher priority.
template<class SF>
-int BURegReductionPriorityQueue<SF>::CalcNodePriority(const SUnit *SU) {
- int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
+unsigned BURegReductionPriorityQueue<SF>::CalcNodePriority(const SUnit *SU) {
+ unsigned &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
if (SethiUllmanNumber != 0)
return SethiUllmanNumber;
- unsigned Opc = SU->Node->getOpcode();
- if (Opc == ISD::CopyFromReg && !isCopyFromLiveIn(SU))
- // CopyFromReg should be close to its def because it restricts allocation
- // choices. But if it is a livein then perhaps we want it closer to the
- // uses so it can be coalesced.
- SethiUllmanNumber = INT_MIN + 10;
- else if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg)
- // CopyToReg should be close to its uses to facilitate coalescing and avoid
- // spilling.
- SethiUllmanNumber = INT_MAX - 10;
- else if (SU->NumSuccsLeft == 0)
- // If SU does not have a use, i.e. it doesn't produce a value that would
- // be consumed (e.g. store), then it terminates a chain of computation.
- // Give it a small SethiUllman number so it will be scheduled right before its
- // predecessors that it doesn't lengthen their live ranges.
- SethiUllmanNumber = INT_MIN + 10;
- else if (SU->NumPredsLeft == 0)
- // If SU does not have a def, schedule it close to its uses because it does
- // not lengthen any live ranges.
- SethiUllmanNumber = INT_MAX - 10;
- else {
- int Extra = 0;
- for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
- I != E; ++I) {
- if (I->second) continue; // ignore chain preds
- SUnit *PredSU = I->first;
- int PredSethiUllman = CalcNodePriority(PredSU);
- if (PredSethiUllman > SethiUllmanNumber) {
- SethiUllmanNumber = PredSethiUllman;
- Extra = 0;
- } else if (PredSethiUllman == SethiUllmanNumber && !I->second)
- Extra++;
- }
-
- SethiUllmanNumber += Extra;
+ unsigned Extra = 0;
+ for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
+ I != E; ++I) {
+ if (I->second) continue; // ignore chain preds
+ SUnit *PredSU = I->first;
+ unsigned PredSethiUllman = CalcNodePriority(PredSU);
+ if (PredSethiUllman > SethiUllmanNumber) {
+ SethiUllmanNumber = PredSethiUllman;
+ Extra = 0;
+ } else if (PredSethiUllman == SethiUllmanNumber && !I->second)
+ Extra++;
}
+
+ SethiUllmanNumber += Extra;
+
+ if (SethiUllmanNumber == 0)
+ SethiUllmanNumber = 1;
return SethiUllmanNumber;
}
@@ -796,10 +750,8 @@
// Top down
bool td_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
- unsigned LeftNum = left->NodeNum;
- unsigned RightNum = right->NodeNum;
- int LPriority = SPQ->getSethiUllmanNumber(LeftNum);
- int RPriority = SPQ->getSethiUllmanNumber(RightNum);
+ unsigned LPriority = SPQ->getSethiUllmanNumber(left);
+ unsigned RPriority = SPQ->getSethiUllmanNumber(right);
bool LIsTarget = left->Node->isTargetOpcode();
bool RIsTarget = right->Node->isTargetOpcode();
bool LIsFloater = LIsTarget && left->NumPreds == 0;
@@ -852,30 +804,30 @@
/// CalcNodePriority - Priority is the Sethi Ullman number.
/// Smaller number is the higher priority.
template<class SF>
-int TDRegReductionPriorityQueue<SF>::CalcNodePriority(const SUnit *SU) {
- int &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
+unsigned TDRegReductionPriorityQueue<SF>::CalcNodePriority(const SUnit *SU) {
+ unsigned &SethiUllmanNumber = SethiUllmanNumbers[SU->NodeNum];
if (SethiUllmanNumber != 0)
return SethiUllmanNumber;
unsigned Opc = SU->Node->getOpcode();
if (Opc == ISD::TokenFactor || Opc == ISD::CopyToReg)
- SethiUllmanNumber = INT_MAX - 10;
+ SethiUllmanNumber = 0xffff;
else if (SU->NumSuccsLeft == 0)
// If SU does not have a use, i.e. it doesn't produce a value that would
// be consumed (e.g. store), then it terminates a chain of computation.
// Give it a small SethiUllman number so it will be scheduled right before its
// predecessors that it doesn't lengthen their live ranges.
- SethiUllmanNumber = INT_MIN + 10;
+ SethiUllmanNumber = 0;
else if (SU->NumPredsLeft == 0 &&
(Opc != ISD::CopyFromReg || isCopyFromLiveIn(SU)))
- SethiUllmanNumber = 1;
+ SethiUllmanNumber = 0xffff;
else {
int Extra = 0;
for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
I != E; ++I) {
if (I->second) continue; // ignore chain preds
SUnit *PredSU = I->first;
- int PredSethiUllman = CalcNodePriority(PredSU);
+ unsigned PredSethiUllman = CalcNodePriority(PredSU);
if (PredSethiUllman > SethiUllmanNumber) {
SethiUllmanNumber = PredSethiUllman;
Extra = 0;
More information about the llvm-commits
mailing list