diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 9dfb502fa3b..125f8eaa8ce 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -94,6 +94,7 @@ namespace llvm { struct SUnit { private: SDNode *Node; // Representative node. + MachineInstr *Instr; // Alternatively, a MachineInstr. public: SUnit *OrigNode; // If not this, the node from which // this node was cloned. @@ -128,19 +129,53 @@ namespace llvm { const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null. const TargetRegisterClass *CopySrcRC; + /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent + /// an SDNode and any nodes flagged to it. SUnit(SDNode *node, unsigned nodenum) - : Node(node), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), Latency(0), - NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), + : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), + Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), + isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), + isPending(false), isAvailable(false), isScheduled(false), + CycleBound(0), Cycle(0), Depth(0), Height(0), + CopyDstRC(NULL), CopySrcRC(NULL) {} + + /// SUnit - Construct an SUnit for post-regalloc scheduling to represent + /// a MachineInstr. + SUnit(MachineInstr *instr, unsigned nodenum) + : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), + Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false), isPending(false), isAvailable(false), isScheduled(false), CycleBound(0), Cycle(0), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} /// setNode - Assign the representative SDNode for this SUnit. - void setNode(SDNode *N) { Node = N; } + /// This may be used during pre-regalloc scheduling. + void setNode(SDNode *N) { + assert(!Instr && "Setting SDNode of SUnit with MachineInstr!"); + Node = N; + } /// getNode - Return the representative SDNode for this SUnit. - SDNode *getNode() const { return Node; } + /// This may be used during pre-regalloc scheduling. + SDNode *getNode() const { + assert(!Instr && "Reading SDNode of SUnit with MachineInstr!"); + return Node; + } + + /// setInstr - Assign the instruction for the SUnit. + /// This may be used during post-regalloc scheduling. + void setInstr(MachineInstr *MI) { + assert(!Node && "Setting MachineInstr of SUnit with SDNode!"); + Instr = MI; + } + + /// getInstr - Return the representative MachineInstr for this SUnit. + /// This may be used during post-regalloc scheduling. + MachineInstr *getInstr() const { + assert(!Node && "Reading MachineInstr of SUnit with SDNode!"); + return Instr; + } /// addPred - This adds the specified node as a pred of the current node if /// not already. This returns true if this is a new pred. diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp index 2c40d97a7ea..d60dd493576 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp @@ -684,6 +684,16 @@ MachineBasicBlock *ScheduleDAG::EmitSchedule() { EmitNoop(); continue; } + + // For post-regalloc scheduling, we already have the instruction; + // just append it to the block. + if (!DAG) { + BB->push_back(SU->getInstr()); + continue; + } + + // For pre-regalloc scheduling, create instructions corresponding to the + // SDNode and any flagged SDNodes and append them to the block. SmallVector FlaggedNodes; for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode()) FlaggedNodes.push_back(N); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp index 27746333e44..8ff50c1a3ad 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp @@ -420,11 +420,24 @@ namespace llvm { static void addCustomGraphFeatures(ScheduleDAG *G, GraphWriter &GW) { + // Draw a special "GraphRoot" node to indicate the root of the graph. GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); - const SDNode *N = G->DAG->getRoot().getNode(); - if (N && N->getNodeId() != -1) - GW.emitEdge(0, -1, &G->SUnits[N->getNodeId()], -1, - "color=blue,style=dashed"); + if (G->DAG) { + // For an SDNode-based ScheduleDAG, point to the root of the ScheduleDAG. + const SDNode *N = G->DAG->getRoot().getNode(); + if (N && N->getNodeId() != -1) + GW.emitEdge(0, -1, &G->SUnits[N->getNodeId()], -1, + "color=blue,style=dashed"); + } else { + // For a MachineInstr-based ScheduleDAG, find a root to point to. + for (unsigned i = 0, e = G->SUnits.size(); i != e; ++i) { + if (G->SUnits[i].Succs.empty()) { + GW.emitEdge(0, -1, &G->SUnits[i], -1, + "color=blue,style=dashed"); + break; + } + } + } } }; }