Remove the FlaggedNodes member from SUnit. Instead of requiring each SUnit

to carry a SmallVector of flagged nodes, just calculate the flagged nodes
dynamically when they are needed.

The local-liveness change is due to a trivial scheduling change where
the scheduler arbitrary decision differently.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59273 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2008-11-13 23:24:17 +00:00
parent e4f309e582
commit d23e0f81bc
9 changed files with 59 additions and 61 deletions

View File

@ -95,7 +95,6 @@ namespace llvm {
private: private:
SDNode *Node; // Representative node. SDNode *Node; // Representative node.
public: public:
SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
SUnit *OrigNode; // If not this, the node from which SUnit *OrigNode; // If not this, the node from which
// this node was cloned. // this node was cloned.

View File

@ -1308,6 +1308,15 @@ public:
SDVTList X = { ValueList, NumValues }; SDVTList X = { ValueList, NumValues };
return X; return X;
}; };
/// getFlaggedNode - If this node has a flag operand, return the node
/// to which the flag operand points. Otherwise return NULL.
SDNode *getFlaggedNode() const {
if (getNumOperands() != 0 &&
getOperand(getNumOperands()-1).getValueType() == MVT::Flag)
return getOperand(getNumOperands()-1).getNode();
return 0;
}
/// getNumValues - Return the number of values defined/returned by this /// getNumValues - Return the number of values defined/returned by this
/// operator. /// operator.

View File

@ -60,7 +60,6 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
SUnit *ScheduleDAG::Clone(SUnit *Old) { SUnit *ScheduleDAG::Clone(SUnit *Old) {
SUnit *SU = NewSUnit(Old->getNode()); SUnit *SU = NewSUnit(Old->getNode());
SU->OrigNode = Old->OrigNode; SU->OrigNode = Old->OrigNode;
SU->FlaggedNodes = Old->FlaggedNodes;
SU->Latency = Old->Latency; SU->Latency = Old->Latency;
SU->isTwoAddress = Old->isTwoAddress; SU->isTwoAddress = Old->isTwoAddress;
SU->isCommutable = Old->isCommutable; SU->isCommutable = Old->isCommutable;
@ -99,23 +98,19 @@ void ScheduleDAG::BuildSchedUnits() {
// nodes. Nodes can have at most one flag input and one flag output. Flags // nodes. Nodes can have at most one flag input and one flag output. Flags
// are required the be the last operand and result of a node. // are required the be the last operand and result of a node.
// Scan up, adding flagged preds to FlaggedNodes. // Scan up to find flagged preds.
SDNode *N = NI; SDNode *N = NI;
if (N->getNumOperands() && if (N->getNumOperands() &&
N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) { N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) {
do { do {
N = N->getOperand(N->getNumOperands()-1).getNode(); N = N->getOperand(N->getNumOperands()-1).getNode();
NodeSUnit->FlaggedNodes.push_back(N);
assert(N->getNodeId() == -1 && "Node already inserted!"); assert(N->getNodeId() == -1 && "Node already inserted!");
N->setNodeId(NodeSUnit->NodeNum); N->setNodeId(NodeSUnit->NodeNum);
} while (N->getNumOperands() && } while (N->getNumOperands() &&
N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag); N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag);
std::reverse(NodeSUnit->FlaggedNodes.begin(),
NodeSUnit->FlaggedNodes.end());
} }
// Scan down, adding this node and any flagged succs to FlaggedNodes if they // Scan down to find any flagged succs.
// have a user of the flag operand.
N = NI; N = NI;
while (N->getValueType(N->getNumValues()-1) == MVT::Flag) { while (N->getValueType(N->getNumValues()-1) == MVT::Flag) {
SDValue FlagVal(N, N->getNumValues()-1); SDValue FlagVal(N, N->getNumValues()-1);
@ -126,7 +121,6 @@ void ScheduleDAG::BuildSchedUnits() {
UI != E; ++UI) UI != E; ++UI)
if (FlagVal.isOperandOf(*UI)) { if (FlagVal.isOperandOf(*UI)) {
HasFlagUse = true; HasFlagUse = true;
NodeSUnit->FlaggedNodes.push_back(N);
assert(N->getNodeId() == -1 && "Node already inserted!"); assert(N->getNodeId() == -1 && "Node already inserted!");
N->setNodeId(NodeSUnit->NodeNum); N->setNodeId(NodeSUnit->NodeNum);
N = *UI; N = *UI;
@ -135,8 +129,9 @@ void ScheduleDAG::BuildSchedUnits() {
if (!HasFlagUse) break; if (!HasFlagUse) break;
} }
// Now all flagged nodes are in FlaggedNodes and N is the bottom-most node. // If there are flag operands involved, N is now the bottom-most node
// Update the SUnit // of the sequence of nodes that are flagged together.
// Update the SUnit.
NodeSUnit->setNode(N); NodeSUnit->setNode(N);
assert(N->getNodeId() == -1 && "Node already inserted!"); assert(N->getNodeId() == -1 && "Node already inserted!");
N->setNodeId(NodeSUnit->NodeNum); N->setNodeId(NodeSUnit->NodeNum);
@ -163,11 +158,7 @@ void ScheduleDAG::BuildSchedUnits() {
} }
// Find all predecessors and successors of the group. // Find all predecessors and successors of the group.
// Temporarily add N to make code simpler. for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
SU->FlaggedNodes.push_back(MainNode);
for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) {
SDNode *N = SU->FlaggedNodes[n];
if (N->isMachineOpcode() && if (N->isMachineOpcode() &&
TII->get(N->getMachineOpcode()).getImplicitDefs() && TII->get(N->getMachineOpcode()).getImplicitDefs() &&
CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs()) CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs())
@ -191,9 +182,6 @@ void ScheduleDAG::BuildSchedUnits() {
SU->addPred(OpSU, isChain, false, PhysReg, Cost); SU->addPred(OpSU, isChain, false, PhysReg, Cost);
} }
} }
// Remove MainNode from FlaggedNodes again.
SU->FlaggedNodes.pop_back();
} }
} }
@ -209,17 +197,9 @@ void ScheduleDAG::ComputeLatency(SUnit *SU) {
} }
SU->Latency = 0; SU->Latency = 0;
if (SU->getNode()->isMachineOpcode()) { for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
unsigned SchedClass = TII->get(SU->getNode()->getMachineOpcode()).getSchedClass(); if (N->isMachineOpcode()) {
const InstrStage *S = InstrItins.begin(SchedClass); unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass();
const InstrStage *E = InstrItins.end(SchedClass);
for (; S != E; ++S)
SU->Latency += S->Cycles;
}
for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) {
SDNode *FNode = SU->FlaggedNodes[i];
if (FNode->isMachineOpcode()) {
unsigned SchedClass = TII->get(FNode->getMachineOpcode()).getSchedClass();
const InstrStage *S = InstrItins.begin(SchedClass); const InstrStage *S = InstrItins.begin(SchedClass);
const InstrStage *E = InstrItins.end(SchedClass); const InstrStage *E = InstrItins.end(SchedClass);
for (; S != E; ++S) for (; S != E; ++S)
@ -397,17 +377,19 @@ void ScheduleDAG::Run() {
/// a group of nodes flagged together. /// a group of nodes flagged together.
void SUnit::dump(const SelectionDAG *G) const { void SUnit::dump(const SelectionDAG *G) const {
cerr << "SU(" << NodeNum << "): "; cerr << "SU(" << NodeNum << "): ";
if (Node) if (getNode())
Node->dump(G); getNode()->dump(G);
else else
cerr << "CROSS RC COPY "; cerr << "CROSS RC COPY ";
cerr << "\n"; cerr << "\n";
if (FlaggedNodes.size() != 0) { SmallVector<SDNode *, 4> FlaggedNodes;
for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) { for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
cerr << " "; FlaggedNodes.push_back(N);
FlaggedNodes[i]->dump(G); while (!FlaggedNodes.empty()) {
cerr << "\n"; cerr << " ";
} FlaggedNodes.back()->dump(G);
cerr << "\n";
FlaggedNodes.pop_back();
} }
} }

View File

@ -684,8 +684,13 @@ MachineBasicBlock *ScheduleDAG::EmitSchedule() {
EmitNoop(); EmitNoop();
continue; continue;
} }
for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; ++j) SmallVector<SDNode *, 4> FlaggedNodes;
EmitNode(SU->FlaggedNodes[j], SU->OrigNode != SU, VRBaseMap); for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
FlaggedNodes.push_back(N);
while (!FlaggedNodes.empty()) {
EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, VRBaseMap);
FlaggedNodes.pop_back();
}
if (!SU->getNode()) if (!SU->getNode())
EmitCrossRCCopy(SU, CopyVRBaseMap); EmitCrossRCCopy(SU, CopyVRBaseMap);
else else

View File

@ -221,7 +221,7 @@ bool ScheduleDAGFast::RemovePred(SUnit *M, SUnit *N,
/// CopyAndMoveSuccessors - Clone the specified node and move its scheduled /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled
/// successors to the newly created node. /// successors to the newly created node.
SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) { SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) {
if (SU->FlaggedNodes.size()) if (SU->getNode()->getFlaggedNode())
return NULL; return NULL;
SDNode *N = SU->getNode(); SDNode *N = SU->getNode();
@ -485,9 +485,8 @@ bool ScheduleDAGFast::DelayForLiveRegsBottomUp(SUnit *SU,
} }
} }
for (unsigned i = 0, e = SU->FlaggedNodes.size()+1; i != e; ++i) { for (SDNode *Node = SU->getNode(); Node; Node = Node->getFlaggedNode()) {
SDNode *Node = (i == 0) ? SU->getNode() : SU->FlaggedNodes[i-1]; if (!Node->isMachineOpcode())
if (!Node || !Node->isMachineOpcode())
continue; continue;
const TargetInstrDesc &TID = TII->get(Node->getMachineOpcode()); const TargetInstrDesc &TID = TII->get(Node->getMachineOpcode());
if (!TID.ImplicitDefs) if (!TID.ImplicitDefs)

View File

@ -205,9 +205,11 @@ void ScheduleDAGList::ListScheduleTopDown() {
// If this is a pseudo op, like copyfromreg, look to see if there is a // If this is a pseudo op, like copyfromreg, look to see if there is a
// real target node flagged to it. If so, use the target node. // real target node flagged to it. If so, use the target node.
for (unsigned i = 0, e = CurSUnit->FlaggedNodes.size(); while (!FoundNode->isMachineOpcode()) {
!FoundNode->isMachineOpcode() && i != e; ++i) SDNode *N = FoundNode->getFlaggedNode();
FoundNode = CurSUnit->FlaggedNodes[i]; if (!N) break;
FoundNode = N;
}
HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode); HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode);
if (HT == HazardRecognizer::NoHazard) { if (HT == HazardRecognizer::NoHazard) {

View File

@ -626,7 +626,7 @@ void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle,
/// CopyAndMoveSuccessors - Clone the specified node and move its scheduled /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled
/// successors to the newly created node. /// successors to the newly created node.
SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) {
if (SU->FlaggedNodes.size()) if (SU->getNode()->getFlaggedNode())
return NULL; return NULL;
SDNode *N = SU->getNode(); SDNode *N = SU->getNode();
@ -903,9 +903,8 @@ bool ScheduleDAGRRList::DelayForLiveRegsBottomUp(SUnit *SU,
} }
} }
for (unsigned i = 0, e = SU->FlaggedNodes.size()+1; i != e; ++i) { for (SDNode *Node = SU->getNode(); Node; Node = Node->getFlaggedNode()) {
SDNode *Node = (i == 0) ? SU->getNode() : SU->FlaggedNodes[i-1]; if (!Node->isMachineOpcode())
if (!Node || !Node->isMachineOpcode())
continue; continue;
const TargetInstrDesc &TID = TII->get(Node->getMachineOpcode()); const TargetInstrDesc &TID = TII->get(Node->getMachineOpcode());
if (!TID.ImplicitDefs) if (!TID.ImplicitDefs)
@ -1736,7 +1735,7 @@ void BURegReductionPriorityQueue::AddPseudoTwoAddrDeps() {
continue; continue;
SDNode *Node = SU->getNode(); SDNode *Node = SU->getNode();
if (!Node || !Node->isMachineOpcode() || SU->FlaggedNodes.size() > 0) if (!Node || !Node->isMachineOpcode() || SU->getNode()->getFlaggedNode())
continue; continue;
unsigned Opc = Node->getMachineOpcode(); unsigned Opc = Node->getMachineOpcode();

View File

@ -433,16 +433,19 @@ std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
const ScheduleDAG *G) { const ScheduleDAG *G) {
std::string Op; std::string Op;
for (unsigned i = 0; i < SU->FlaggedNodes.size(); ++i) { if (!SU->getNode())
Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(SU->FlaggedNodes[i], Op = "<CROSS RC COPY>";
G->DAG) + "\n"; else {
SmallVector<SDNode *, 4> FlaggedNodes;
for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode())
FlaggedNodes.push_back(N);
while (!FlaggedNodes.empty()) {
Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(FlaggedNodes.back(),
G->DAG) + "\n";
FlaggedNodes.pop_back();
}
} }
if (SU->getNode())
Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(SU->getNode(), G->DAG);
else
Op += "<CROSS RC COPY>";
return Op; return Op;
} }

View File

@ -1,4 +1,4 @@
; RUN: llvm-as < %s | llc -march=x86 -regalloc=local | grep {subl %eax, %esi} ; RUN: llvm-as < %s | llc -march=x86 -regalloc=local | grep {subl %eax, %edx}
; Local regalloc shouldn't assume that both the uses of the ; Local regalloc shouldn't assume that both the uses of the
; sub instruction are kills, because one of them is tied ; sub instruction are kills, because one of them is tied