std::vector<unsigned> LiveRegCycles;
public:
- ScheduleDAGFast(SelectionDAG &dag, MachineBasicBlock *bb,
+ ScheduleDAGFast(SelectionDAG *dag, MachineBasicBlock *bb,
const TargetMachine &tm)
: ScheduleDAG(dag, bb, tm) {}
bool RemovePred(SUnit *M, SUnit *N, bool isCtrl, bool isSpecial);
private:
- void ReleasePred(SUnit*, bool, unsigned);
+ void ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain);
void ScheduleNodeBottomUp(SUnit*, unsigned);
SUnit *CopyAndMoveSuccessors(SUnit*);
void InsertCCCopiesAndMoveSuccs(SUnit*, unsigned,
BuildSchedUnits();
DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
- SUnits[su].dumpAll(&DAG));
+ SUnits[su].dumpAll(this));
// Execute the actual scheduling loop.
ListScheduleBottomUp();
/// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
/// the AvailableQueue if the count reaches zero. Also update its cycle bound.
-void ScheduleDAGFast::ReleasePred(SUnit *PredSU, bool isChain,
- unsigned CurCycle) {
- // FIXME: the distance between two nodes is not always == the predecessor's
- // latency. For example, the reader can very well read the register written
- // by the predecessor later than the issue cycle. It also depends on the
- // interrupt model (drain vs. freeze).
- PredSU->CycleBound = std::max(PredSU->CycleBound, CurCycle + PredSU->Latency);
-
+void ScheduleDAGFast::ReleasePred(SUnit *SU, SUnit *PredSU, bool isChain) {
--PredSU->NumSuccsLeft;
#ifndef NDEBUG
if (PredSU->NumSuccsLeft < 0) {
- cerr << "*** List scheduling failed! ***\n";
- PredSU->dump(&DAG);
+ cerr << "*** Scheduling failed! ***\n";
+ PredSU->dump(this);
cerr << " has been released too many times!\n";
assert(0);
}
/// the Available queue.
void ScheduleDAGFast::ScheduleNodeBottomUp(SUnit *SU, unsigned CurCycle) {
DOUT << "*** Scheduling [" << CurCycle << "]: ";
- DEBUG(SU->dump(&DAG));
+ DEBUG(SU->dump(this));
SU->Cycle = CurCycle;
// Bottom up: release predecessors
for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
I != E; ++I) {
- ReleasePred(I->Dep, I->isCtrl, CurCycle);
+ ReleasePred(SU, I->Dep, I->isCtrl);
if (I->Cost < 0) {
// This is a physical register dependency and it's impossible or
// expensive to copy the register. Make sure nothing that can
/// CopyAndMoveSuccessors - Clone the specified node and move its scheduled
/// successors to the newly created node.
SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) {
- if (SU->FlaggedNodes.size())
+ if (SU->getNode()->getFlaggedNode())
return NULL;
- SDNode *N = SU->Node;
+ SDNode *N = SU->getNode();
if (!N)
return NULL;
if (TryUnfold) {
SmallVector<SDNode*, 2> NewNodes;
- if (!TII->unfoldMemoryOperand(DAG, N, NewNodes))
+ if (!TII->unfoldMemoryOperand(*DAG, N, NewNodes))
return NULL;
DOUT << "Unfolding SU # " << SU->NodeNum << "\n";
N = NewNodes[1];
SDNode *LoadNode = NewNodes[0];
unsigned NumVals = N->getNumValues();
- unsigned OldNumVals = SU->Node->getNumValues();
+ unsigned OldNumVals = SU->getNode()->getNumValues();
for (unsigned i = 0; i != NumVals; ++i)
- DAG.ReplaceAllUsesOfValueWith(SDValue(SU->Node, i), SDValue(N, i));
- DAG.ReplaceAllUsesOfValueWith(SDValue(SU->Node, OldNumVals-1),
- SDValue(LoadNode, 1));
+ DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), i), SDValue(N, i));
+ DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), OldNumVals-1),
+ SDValue(LoadNode, 1));
SUnit *NewSU = CreateNewSUnit(N);
assert(N->getNodeId() == -1 && "Node already inserted!");
// FIXME: Calculate height / depth and propagate the changes?
NewSU->Depth = SU->Depth;
NewSU->Height = SU->Height;
- ComputeLatency(NewSU);
// LoadNode may already exist. This can happen when there is another
// load from the same location and producing the same type of value
LoadSU->Depth = SU->Depth;
LoadSU->Height = SU->Height;
- ComputeLatency(LoadSU);
}
SUnit *ChainPred = NULL;
I != E; ++I) {
if (I->isCtrl)
ChainPred = I->Dep;
- else if (I->Dep->Node && I->Dep->Node->isOperandOf(LoadNode))
+ else if (I->Dep->getNode() && I->Dep->getNode()->isOperandOf(LoadNode))
LoadPreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false));
else
NodePreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false));
}
}
- for (unsigned i = 0, e = SU->FlaggedNodes.size()+1; i != e; ++i) {
- SDNode *Node = (i == 0) ? SU->Node : SU->FlaggedNodes[i-1];
- if (!Node || !Node->isMachineOpcode())
+ for (SDNode *Node = SU->getNode(); Node; Node = Node->getFlaggedNode()) {
+ if (!Node->isMachineOpcode())
continue;
const TargetInstrDesc &TID = TII->get(Node->getMachineOpcode());
if (!TID.ImplicitDefs)
unsigned CurCycle = 0;
// Add root to Available queue.
if (!SUnits.empty()) {
- SUnit *RootSU = &SUnits[DAG.getRoot().getNode()->getNodeId()];
+ SUnit *RootSU = &SUnits[DAG->getRoot().getNode()->getNodeId()];
assert(RootSU->Succs.empty() && "Graph root shouldn't have successors!");
RootSU->isAvailable = true;
AvailableQueue.push(RootSU);
LRegsMap.clear();
SUnit *CurSU = AvailableQueue.pop();
while (CurSU) {
- if (CurSU->CycleBound <= CurCycle) {
- SmallVector<unsigned, 4> LRegs;
- if (!DelayForLiveRegsBottomUp(CurSU, LRegs))
- break;
- Delayed = true;
- LRegsMap.insert(std::make_pair(CurSU, LRegs));
- }
+ SmallVector<unsigned, 4> LRegs;
+ if (!DelayForLiveRegsBottomUp(CurSU, LRegs))
+ break;
+ Delayed = true;
+ LRegsMap.insert(std::make_pair(CurSU, LRegs));
CurSU->isPending = true; // This SU is not in AvailableQueue right now.
NotReady.push_back(CurSU);
SUnit *NewDef = CopyAndMoveSuccessors(LRDef);
if (!NewDef) {
// Issue expensive cross register class copies.
- MVT VT = getPhysicalRegisterVT(LRDef->Node, Reg, TII);
+ MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII);
const TargetRegisterClass *RC =
TRI->getPhysicalRegisterRegClass(Reg, VT);
const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC);
}
if (!AnyNotSched)
cerr << "*** List scheduling failed! ***\n";
- SUnits[i].dump(&DAG);
+ SUnits[i].dump(this);
cerr << "has not been scheduled!\n";
AnyNotSched = true;
}
if (SUnits[i].NumSuccsLeft != 0) {
if (!AnyNotSched)
cerr << "*** List scheduling failed! ***\n";
- SUnits[i].dump(&DAG);
+ SUnits[i].dump(this);
cerr << "has successors left!\n";
AnyNotSched = true;
}
llvm::ScheduleDAG* llvm::createFastDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG,
+ const TargetMachine *TM,
MachineBasicBlock *BB, bool) {
- return new ScheduleDAGFast(*DAG, BB, DAG->getTarget());
+ return new ScheduleDAGFast(DAG, BB, *TM);
}