[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGList.cpp ScheduleDAGRRList.cpp
Evan Cheng
evan.cheng at apple.com
Sat Nov 4 01:44:45 PST 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
ScheduleDAG.cpp updated: 1.105 -> 1.106
ScheduleDAGList.cpp updated: 1.67 -> 1.68
ScheduleDAGRRList.cpp updated: 1.19 -> 1.20
---
Log message:
Changes to use operand constraints to process two-address instructions.
---
Diffs of the changes: (+140 -50)
ScheduleDAG.cpp | 13 ++-
ScheduleDAGList.cpp | 5 -
ScheduleDAGRRList.cpp | 172 +++++++++++++++++++++++++++++++++++++-------------
3 files changed, 140 insertions(+), 50 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.105 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.106
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.105 Tue Oct 31 14:01:56 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sat Nov 4 03:44:31 2006
@@ -126,8 +126,13 @@
if (MainNode->isTargetOpcode()) {
unsigned Opc = MainNode->getTargetOpcode();
- if (TII->isTwoAddrInstr(Opc))
- SU->isTwoAddress = true;
+ for (unsigned i = 0, ee = TII->getNumOperands(Opc); i != ee; ++i) {
+ if (TII->getOperandConstraint(Opc, i,
+ TargetInstrInfo::TIED_TO) != -1) {
+ SU->isTwoAddress = true;
+ break;
+ }
+ }
if (TII->isCommutableInstr(Opc))
SU->isCommutable = true;
}
@@ -210,7 +215,7 @@
/// CountResults - The results of target nodes have register or immediate
/// operands first, then an optional chain, and optional flag operands (which do
/// not go into the machine instrs.)
-static unsigned CountResults(SDNode *Node) {
+unsigned ScheduleDAG::CountResults(SDNode *Node) {
unsigned N = Node->getNumValues();
while (N && Node->getValueType(N - 1) == MVT::Flag)
--N;
@@ -222,7 +227,7 @@
/// CountOperands The inputs to target nodes have any actual inputs first,
/// followed by an optional chain operand, then flag operands. Compute the
/// number of actual operands that will go into the machine instr.
-static unsigned CountOperands(SDNode *Node) {
+unsigned ScheduleDAG::CountOperands(SDNode *Node) {
unsigned N = Node->getNumOperands();
while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
--N;
Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.67 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.68
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.67 Sun Aug 27 07:54:01 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Sat Nov 4 03:44:31 2006
@@ -98,7 +98,7 @@
// Build scheduling units.
BuildSchedUnits();
- AvailableQueue->initNodes(SUnits);
+ AvailableQueue->initNodes(SUnitMap, SUnits);
ListScheduleTopDown();
@@ -331,7 +331,8 @@
LatencyPriorityQueue() : Queue(latency_sort(this)) {
}
- void initNodes(std::vector<SUnit> &sunits) {
+ void initNodes(std::map<SDNode*, SUnit*> &sumap,
+ std::vector<SUnit> &sunits) {
SUnits = &sunits;
// Calculate node priorities.
CalculatePriorities();
Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.19 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.20
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.19 Thu Nov 2 19:28:29 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Sat Nov 4 03:44:31 2006
@@ -95,7 +95,7 @@
CalculateDepths();
CalculateHeights();
- AvailableQueue->initNodes(SUnits);
+ AvailableQueue->initNodes(SUnitMap, SUnits);
// Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate.
if (isBottomUp)
@@ -115,7 +115,7 @@
EmitSchedule();
}
-/// CommuteNodesToReducePressure - Is a node is two-address and commutable, and
+/// CommuteNodesToReducePressure - If a node is two-address and commutable, and
/// it is not the last use of its first operand, add it to the CommuteSet if
/// possible. It will be commuted when it is translated to a MI.
void ScheduleDAGRRList::CommuteNodesToReducePressure() {
@@ -123,23 +123,38 @@
for (unsigned i = Sequence.size()-1; i != 0; --i) { // Ignore first node.
SUnit *SU = Sequence[i];
if (!SU) continue;
- if (SU->isTwoAddress && SU->isCommutable) {
- SDNode *OpN = SU->Node->getOperand(0).Val;
- SUnit *OpSU = SUnitMap[OpN];
- if (OpSU && OperandSeen.count(OpSU) == 1) {
- // Ok, so SU is not the last use of OpSU, but SU is two-address so
- // it will clobber OpSU. Try to commute it if possible.
- bool DoCommute = true;
- for (unsigned j = 1, e = SU->Node->getNumOperands(); j != e; ++j) {
- OpN = SU->Node->getOperand(j).Val;
- OpSU = SUnitMap[OpN];
- if (OpSU && OperandSeen.count(OpSU) == 1) {
- DoCommute = false;
- break;
+ if (SU->isCommutable) {
+ unsigned Opc = SU->Node->getTargetOpcode();
+ unsigned NumRes = CountResults(SU->Node);
+ unsigned NumOps = CountOperands(SU->Node);
+ for (unsigned j = 0; j != NumOps; ++j) {
+ if (TII->getOperandConstraint(Opc, j+NumRes,
+ TargetInstrInfo::TIED_TO) == -1)
+ continue;
+
+ SDNode *OpN = SU->Node->getOperand(j).Val;
+ SUnit *OpSU = SUnitMap[OpN];
+ if (OpSU && OperandSeen.count(OpSU) == 1) {
+ // Ok, so SU is not the last use of OpSU, but SU is two-address so
+ // it will clobber OpSU. Try to commute SU if no other source operands
+ // are live below.
+ bool DoCommute = true;
+ for (unsigned k = 0; k < NumOps; ++k) {
+ if (k != j) {
+ OpN = SU->Node->getOperand(k).Val;
+ OpSU = SUnitMap[OpN];
+ if (OpSU && OperandSeen.count(OpSU) == 1) {
+ DoCommute = false;
+ break;
+ }
+ }
}
+ if (DoCommute)
+ CommuteSet.insert(SU->Node);
}
- if (DoCommute)
- CommuteSet.insert(SU->Node);
+
+ // Only look at the first use&def node for now.
+ break;
}
}
@@ -411,7 +426,8 @@
RegReductionPriorityQueue() :
Queue(SF(this)) {}
- virtual void initNodes(std::vector<SUnit> &sunits) {}
+ virtual void initNodes(std::map<SDNode*, SUnit*> &sumap,
+ std::vector<SUnit> &sunits) {}
virtual void releaseState() {}
virtual int getSethiUllmanNumber(unsigned NodeNum) const {
@@ -434,21 +450,32 @@
Queue.pop();
return V;
}
+
+ virtual bool isDUOperand(const SUnit *SU1, const SUnit *SU2) {
+ return false;
+ }
};
template<class SF>
class VISIBILITY_HIDDEN BURegReductionPriorityQueue
: public RegReductionPriorityQueue<SF> {
+ // SUnitMap SDNode to SUnit mapping (n -> 1).
+ std::map<SDNode*, SUnit*> *SUnitMap;
+
// SUnits - The SUnits for the current graph.
const std::vector<SUnit> *SUnits;
// SethiUllmanNumbers - The SethiUllman number for each node.
std::vector<int> SethiUllmanNumbers;
+ const TargetInstrInfo *TII;
public:
- BURegReductionPriorityQueue() {}
+ BURegReductionPriorityQueue(const TargetInstrInfo *tii)
+ : TII(tii) {}
- void initNodes(std::vector<SUnit> &sunits) {
+ void initNodes(std::map<SDNode*, SUnit*> &sumap,
+ std::vector<SUnit> &sunits) {
+ SUnitMap = &sumap;
SUnits = &sunits;
// Add pseudo dependency edges for two-address nodes.
AddPseudoTwoAddrDeps();
@@ -466,7 +493,21 @@
return SethiUllmanNumbers[NodeNum];
}
+ bool isDUOperand(const SUnit *SU1, const SUnit *SU2) {
+ unsigned Opc = SU1->Node->getTargetOpcode();
+ unsigned NumRes = ScheduleDAG::CountResults(SU1->Node);
+ unsigned NumOps = ScheduleDAG::CountOperands(SU1->Node);
+ for (unsigned i = 0; i != NumOps; ++i) {
+ if (TII->getOperandConstraint(Opc, i+NumRes,
+ TargetInstrInfo::TIED_TO) == -1)
+ continue;
+ if (SU1->Node->getOperand(i).isOperand(SU2->Node))
+ return true;
+ }
+ return false;
+ }
private:
+ bool canClobber(SUnit *SU, SUnit *Op);
void AddPseudoTwoAddrDeps();
void CalculatePriorities();
int CalcNodePriority(const SUnit *SU);
@@ -475,6 +516,9 @@
template<class SF>
class TDRegReductionPriorityQueue : public RegReductionPriorityQueue<SF> {
+ // SUnitMap SDNode to SUnit mapping (n -> 1).
+ std::map<SDNode*, SUnit*> *SUnitMap;
+
// SUnits - The SUnits for the current graph.
const std::vector<SUnit> *SUnits;
@@ -484,7 +528,9 @@
public:
TDRegReductionPriorityQueue() {}
- void initNodes(std::vector<SUnit> &sunits) {
+ void initNodes(std::map<SDNode*, SUnit*> &sumap,
+ std::vector<SUnit> &sunits) {
+ SUnitMap = &sumap;
SUnits = &sunits;
// Calculate node priorities.
CalculatePriorities();
@@ -563,13 +609,11 @@
// as a def&use operand is preferred.
if (LIsTarget && RIsTarget) {
if (left->isTwoAddress && !right->isTwoAddress) {
- SDNode *DUNode = left->Node->getOperand(0).Val;
- if (DUNode->isOperand(right->Node))
+ if (SPQ->isDUOperand(left, right))
LBonus += 2;
}
if (!left->isTwoAddress && right->isTwoAddress) {
- SDNode *DUNode = right->Node->getOperand(0).Val;
- if (DUNode->isOperand(left->Node))
+ if (SPQ->isDUOperand(right, left))
RBonus += 2;
}
}
@@ -616,32 +660,70 @@
return Reached;
}
-static SUnit *getDefUsePredecessor(SUnit *SU) {
- SDNode *DU = SU->Node->getOperand(0).Val;
- for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
- I != E; ++I) {
- if (I->second) continue; // ignore chain preds
- SUnit *PredSU = I->first;
- if (PredSU->Node == DU)
- return PredSU;
+template<class SF>
+bool BURegReductionPriorityQueue<SF>::canClobber(SUnit *SU, SUnit *Op) {
+ if (SU->isTwoAddress) {
+ unsigned Opc = SU->Node->getTargetOpcode();
+ unsigned NumRes = ScheduleDAG::CountResults(SU->Node);
+ unsigned NumOps = ScheduleDAG::CountOperands(SU->Node);
+ for (unsigned i = 0; i != NumOps; ++i) {
+ if (TII->getOperandConstraint(Opc, i+NumRes,
+ TargetInstrInfo::TIED_TO) != -1) {
+ SDNode *DU = SU->Node->getOperand(i).Val;
+ if (Op == (*SUnitMap)[DU])
+ return true;
+ }
+ }
}
-
- // Must be flagged.
- return NULL;
-}
-
-static bool canClobber(SUnit *SU, SUnit *Op) {
- if (SU->isTwoAddress)
- return Op == getDefUsePredecessor(SU);
return false;
}
+
/// AddPseudoTwoAddrDeps - If two nodes share an operand and one of them uses
/// it as a def&use operand. Add a pseudo control edge from it to the other
/// node (if it won't create a cycle) so the two-address one will be scheduled
/// first (lower in the schedule).
template<class SF>
void BURegReductionPriorityQueue<SF>::AddPseudoTwoAddrDeps() {
+#if 1
+ for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
+ SUnit *SU = (SUnit *)&((*SUnits)[i]);
+ if (!SU->isTwoAddress)
+ continue;
+
+ SDNode *Node = SU->Node;
+ if (!Node->isTargetOpcode())
+ continue;
+
+ unsigned Opc = Node->getTargetOpcode();
+ unsigned NumRes = ScheduleDAG::CountResults(Node);
+ unsigned NumOps = ScheduleDAG::CountOperands(Node);
+ for (unsigned j = 0; j != NumOps; ++j) {
+ if (TII->getOperandConstraint(Opc, j+NumRes,
+ TargetInstrInfo::TIED_TO) != -1) {
+ SDNode *DU = SU->Node->getOperand(j).Val;
+ SUnit *DUSU = (*SUnitMap)[DU];
+ for (SUnit::succ_iterator I = DUSU->Succs.begin(),E = DUSU->Succs.end();
+ I != E; ++I) {
+ if (I->second) continue;
+ SUnit *SuccSU = I->first;
+ if (SuccSU != SU &&
+ (!canClobber(SuccSU, DUSU) ||
+ (!SU->isCommutable && SuccSU->isCommutable))){
+ if (SuccSU->Depth == SU->Depth && !isReachable(SuccSU, SU)) {
+ DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum
+ << " to SU #" << SuccSU->NodeNum << "\n");
+ if (SU->addPred(SuccSU, true))
+ SU->NumChainPredsLeft++;
+ if (SuccSU->addSucc(SU, true))
+ SuccSU->NumChainSuccsLeft++;
+ }
+ }
+ }
+ }
+ }
+ }
+#else
for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
SUnit *SU = (SUnit *)&((*SUnits)[i]);
SDNode *Node = SU->Node;
@@ -649,7 +731,7 @@
continue;
if (SU->isTwoAddress) {
- SUnit *DUSU = getDefUsePredecessor(SU);
+ SUnit *DUSU = getDefUsePredecessor(SU, TII);
if (!DUSU) continue;
for (SUnit::succ_iterator I = DUSU->Succs.begin(), E = DUSU->Succs.end();
@@ -657,7 +739,7 @@
if (I->second) continue;
SUnit *SuccSU = I->first;
if (SuccSU != SU &&
- (!canClobber(SuccSU, DUSU) ||
+ (!canClobber(SuccSU, DUSU, TII) ||
(!SU->isCommutable && SuccSU->isCommutable))){
if (SuccSU->Depth == SU->Depth && !isReachable(SuccSU, SU)) {
DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum
@@ -671,6 +753,7 @@
}
}
}
+#endif
}
/// CalcNodePriority - Priority is the Sethi Ullman number.
@@ -858,8 +941,9 @@
llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG,
MachineBasicBlock *BB) {
+ const TargetInstrInfo *TII = DAG->getTarget().getInstrInfo();
return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), true,
- new BURegReductionPriorityQueue<bu_ls_rr_sort>());
+ new BURegReductionPriorityQueue<bu_ls_rr_sort>(TII));
}
llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS,
More information about the llvm-commits
mailing list