[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGSimple.cpp SelectionDAGISel.cpp
Evan Cheng
evan.cheng at apple.com
Sun Jan 22 23:01:20 PST 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
ScheduleDAG.cpp updated: 1.56 -> 1.57
ScheduleDAGSimple.cpp updated: 1.1 -> 1.2
SelectionDAGISel.cpp updated: 1.132 -> 1.133
---
Log message:
Factor out more instruction scheduler code to the base class.
---
Diffs of the changes: (+306 -333)
ScheduleDAG.cpp | 240 +++++++++++++++++++++++++++++++-
ScheduleDAGSimple.cpp | 369 +++++---------------------------------------------
SelectionDAGISel.cpp | 30 +++-
3 files changed, 306 insertions(+), 333 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.56 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.57
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.56 Fri Jan 20 20:32:06 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Jan 23 01:01:07 2006
@@ -51,11 +51,51 @@
return N;
}
-/// CreateVirtualRegisters - Add result register values for things that are
-/// defined by this instruction.
-unsigned ScheduleDAG::CreateVirtualRegisters(MachineInstr *MI,
- unsigned NumResults,
- const TargetInstrDescriptor &II) {
+/// PrepareNodeInfo - Set up the basic minimum node info for scheduling.
+///
+void ScheduleDAG::PrepareNodeInfo() {
+ // Allocate node information
+ Info = new NodeInfo[NodeCount];
+
+ unsigned i = 0;
+ for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
+ E = DAG.allnodes_end(); I != E; ++I, ++i) {
+ // Fast reference to node schedule info
+ NodeInfo* NI = &Info[i];
+ // Set up map
+ Map[I] = NI;
+ // Set node
+ NI->Node = I;
+ // Set pending visit count
+ NI->setPending(I->use_size());
+ }
+}
+
+/// IdentifyGroups - Put flagged nodes into groups.
+///
+void ScheduleDAG::IdentifyGroups() {
+ for (unsigned i = 0, N = NodeCount; i < N; i++) {
+ NodeInfo* NI = &Info[i];
+ SDNode *Node = NI->Node;
+
+ // For each operand (in reverse to only look at flags)
+ for (unsigned N = Node->getNumOperands(); 0 < N--;) {
+ // Get operand
+ SDOperand Op = Node->getOperand(N);
+ // No more flags to walk
+ if (Op.getValueType() != MVT::Flag) break;
+ // Add to node group
+ NodeGroup::Add(getNI(Op.Val), NI);
+ // Let evryone else know
+ HasGroups = true;
+ }
+ }
+}
+
+static unsigned CreateVirtualRegisters(MachineInstr *MI,
+ unsigned NumResults,
+ SSARegMap *RegMap,
+ const TargetInstrDescriptor &II) {
// Create the result registers for this node and add the result regs to
// the machine instruction.
const TargetOperandInfo *OpInfo = II.OpInfo;
@@ -114,7 +154,7 @@
// Otherwise, create new virtual registers.
if (NumResults && VRBase == 0)
- VRBase = CreateVirtualRegisters(MI, NumResults, II);
+ VRBase = CreateVirtualRegisters(MI, NumResults, RegMap, II);
// Emit all of the actual operands of this instruction, adding them to the
// instruction as appropriate.
@@ -250,6 +290,112 @@
NI->VRBase = VRBase;
}
+/// EmitAll - Emit all nodes in schedule sorted order.
+///
+void ScheduleDAG::EmitAll() {
+ // For each node in the ordering
+ for (unsigned i = 0, N = Ordering.size(); i < N; i++) {
+ // Get the scheduling info
+ NodeInfo *NI = Ordering[i];
+ if (NI->isInGroup()) {
+ NodeGroupIterator NGI(Ordering[i]);
+ while (NodeInfo *NI = NGI.next()) EmitNode(NI);
+ } else {
+ EmitNode(NI);
+ }
+ }
+}
+
+/// isFlagDefiner - Returns true if the node defines a flag result.
+static bool isFlagDefiner(SDNode *A) {
+ unsigned N = A->getNumValues();
+ return N && A->getValueType(N - 1) == MVT::Flag;
+}
+
+/// isFlagUser - Returns true if the node uses a flag result.
+///
+static bool isFlagUser(SDNode *A) {
+ unsigned N = A->getNumOperands();
+ return N && A->getOperand(N - 1).getValueType() == MVT::Flag;
+}
+
+/// printNI - Print node info.
+///
+void ScheduleDAG::printNI(std::ostream &O, NodeInfo *NI) const {
+#ifndef NDEBUG
+ SDNode *Node = NI->Node;
+ O << " "
+ << std::hex << Node << std::dec
+ << ", Lat=" << NI->Latency
+ << ", Slot=" << NI->Slot
+ << ", ARITY=(" << Node->getNumOperands() << ","
+ << Node->getNumValues() << ")"
+ << " " << Node->getOperationName(&DAG);
+ if (isFlagDefiner(Node)) O << "<#";
+ if (isFlagUser(Node)) O << ">#";
+#endif
+}
+
+/// printChanges - Hilight changes in order caused by scheduling.
+///
+void ScheduleDAG::printChanges(unsigned Index) const {
+#ifndef NDEBUG
+ // Get the ordered node count
+ unsigned N = Ordering.size();
+ // Determine if any changes
+ unsigned i = 0;
+ for (; i < N; i++) {
+ NodeInfo *NI = Ordering[i];
+ if (NI->Preorder != i) break;
+ }
+
+ if (i < N) {
+ std::cerr << Index << ". New Ordering\n";
+
+ for (i = 0; i < N; i++) {
+ NodeInfo *NI = Ordering[i];
+ std::cerr << " " << NI->Preorder << ". ";
+ printNI(std::cerr, NI);
+ std::cerr << "\n";
+ if (NI->isGroupDominator()) {
+ NodeGroup *Group = NI->Group;
+ for (NIIterator NII = Group->group_begin(), E = Group->group_end();
+ NII != E; NII++) {
+ std::cerr << " ";
+ printNI(std::cerr, *NII);
+ std::cerr << "\n";
+ }
+ }
+ }
+ } else {
+ std::cerr << Index << ". No Changes\n";
+ }
+#endif
+}
+
+/// print - Print ordering to specified output stream.
+///
+void ScheduleDAG::print(std::ostream &O) const {
+#ifndef NDEBUG
+ using namespace std;
+ O << "Ordering\n";
+ for (unsigned i = 0, N = Ordering.size(); i < N; i++) {
+ NodeInfo *NI = Ordering[i];
+ printNI(O, NI);
+ O << "\n";
+ if (NI->isGroupDominator()) {
+ NodeGroup *Group = NI->Group;
+ for (NIIterator NII = Group->group_begin(), E = Group->group_end();
+ NII != E; NII++) {
+ O << " ";
+ printNI(O, *NII);
+ O << "\n";
+ }
+ }
+ }
+#endif
+}
+
void ScheduleDAG::dump(const char *tag) const {
std::cerr << tag; dump();
}
@@ -265,6 +411,88 @@
MRI = TM.getRegisterInfo();
RegMap = BB->getParent()->getSSARegMap();
ConstPool = BB->getParent()->getConstantPool();
+
+ // Number the nodes
+ NodeCount = std::distance(DAG.allnodes_begin(), DAG.allnodes_end());
+ // Set up minimum info for scheduling
+ PrepareNodeInfo();
+ // Construct node groups for flagged nodes
+ IdentifyGroups();
+
Schedule();
return BB;
}
+
+
+/// CountInternalUses - Returns the number of edges between the two nodes.
+///
+static unsigned CountInternalUses(NodeInfo *D, NodeInfo *U) {
+ unsigned N = 0;
+ for (unsigned M = U->Node->getNumOperands(); 0 < M--;) {
+ SDOperand Op = U->Node->getOperand(M);
+ if (Op.Val == D->Node) N++;
+ }
+
+ return N;
+}
+
+//===----------------------------------------------------------------------===//
+/// Add - Adds a definer and user pair to a node group.
+///
+void NodeGroup::Add(NodeInfo *D, NodeInfo *U) {
+ // Get current groups
+ NodeGroup *DGroup = D->Group;
+ NodeGroup *UGroup = U->Group;
+ // If both are members of groups
+ if (DGroup && UGroup) {
+ // There may have been another edge connecting
+ if (DGroup == UGroup) return;
+ // Add the pending users count
+ DGroup->addPending(UGroup->getPending());
+ // For each member of the users group
+ NodeGroupIterator UNGI(U);
+ while (NodeInfo *UNI = UNGI.next() ) {
+ // Change the group
+ UNI->Group = DGroup;
+ // For each member of the definers group
+ NodeGroupIterator DNGI(D);
+ while (NodeInfo *DNI = DNGI.next() ) {
+ // Remove internal edges
+ DGroup->addPending(-CountInternalUses(DNI, UNI));
+ }
+ }
+ // Merge the two lists
+ DGroup->group_insert(DGroup->group_end(),
+ UGroup->group_begin(), UGroup->group_end());
+ } else if (DGroup) {
+ // Make user member of definers group
+ U->Group = DGroup;
+ // Add users uses to definers group pending
+ DGroup->addPending(U->Node->use_size());
+ // For each member of the definers group
+ NodeGroupIterator DNGI(D);
+ while (NodeInfo *DNI = DNGI.next() ) {
+ // Remove internal edges
+ DGroup->addPending(-CountInternalUses(DNI, U));
+ }
+ DGroup->group_push_back(U);
+ } else if (UGroup) {
+ // Make definer member of users group
+ D->Group = UGroup;
+ // Add definers uses to users group pending
+ UGroup->addPending(D->Node->use_size());
+ // For each member of the users group
+ NodeGroupIterator UNGI(U);
+ while (NodeInfo *UNI = UNGI.next() ) {
+ // Remove internal edges
+ UGroup->addPending(-CountInternalUses(D, UNI));
+ }
+ UGroup->group_insert(UGroup->group_begin(), D);
+ } else {
+ D->Group = U->Group = DGroup = new NodeGroup();
+ DGroup->addPending(D->Node->use_size() + U->Node->use_size() -
+ CountInternalUses(D, U));
+ DGroup->group_push_back(D);
+ DGroup->group_push_back(U);
+ }
+}
Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.1 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.2
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp:1.1 Fri Jan 20 20:32:06 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp Mon Jan 23 01:01:07 2006
@@ -21,33 +21,9 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include <iostream>
-#include <ios>
-#include <algorithm>
using namespace llvm;
namespace {
- // Style of scheduling to use.
- enum ScheduleChoices {
- noScheduling,
- simpleScheduling,
- simpleNoItinScheduling
- };
-} // namespace
-
-cl::opt<ScheduleChoices> ScheduleStyle("sched",
- cl::desc("Choose scheduling style"),
- cl::init(noScheduling),
- cl::values(
- clEnumValN(noScheduling, "none",
- "Trivial emission with no analysis"),
- clEnumValN(simpleScheduling, "simple",
- "Minimize critical path and maximize processor utilization"),
- clEnumValN(simpleNoItinScheduling, "simple-noitin",
- "Same as simple except using generic latency"),
- clEnumValEnd));
-
-
-namespace {
//===----------------------------------------------------------------------===//
///
/// BitsIterator - Provides iteration through individual bits in a bit vector.
@@ -212,10 +188,6 @@
///
class ScheduleDAGSimple : public ScheduleDAG {
private:
- unsigned NodeCount; // Number of nodes in DAG
- bool HasGroups; // True if there are any groups
- NodeInfo *Info; // Info for nodes being scheduled
- NIVector Ordering; // Emit ordering of nodes
ResourceTally<unsigned> Tally; // Resource usage tally
unsigned NSlots; // Total latency
static const unsigned NotFound = ~0U; // Search marker
@@ -223,10 +195,9 @@
public:
// Ctor.
- ScheduleDAGSimple(SelectionDAG &dag, MachineBasicBlock *bb,
- const TargetMachine &tm)
- : ScheduleDAG(dag, bb, tm),
- NodeCount(0), HasGroups(false), Info(NULL), Tally(), NSlots(0) {
+ ScheduleDAGSimple(SchedHeuristics hstc, SelectionDAG &dag,
+ MachineBasicBlock *bb, const TargetMachine &tm)
+ : ScheduleDAG(hstc, dag, bb, tm), Tally(), NSlots(0) {
assert(&TII && "Target doesn't provide instr info?");
assert(&MRI && "Target doesn't provide register info?");
}
@@ -234,29 +205,18 @@
virtual ~ScheduleDAGSimple() {};
private:
- static bool isFlagDefiner(SDNode *A);
- static bool isFlagUser(SDNode *A);
static bool isDefiner(NodeInfo *A, NodeInfo *B);
- static bool isPassiveNode(SDNode *Node);
void IncludeNode(NodeInfo *NI);
void VisitAll();
void Schedule();
- void IdentifyGroups();
void GatherSchedulingInfo();
void FakeGroupDominators();
- void PrepareNodeInfo();
bool isStrongDependency(NodeInfo *A, NodeInfo *B);
bool isWeakDependency(NodeInfo *A, NodeInfo *B);
void ScheduleBackward();
void ScheduleForward();
- void EmitAll();
-
- void printChanges(unsigned Index);
- void printSI(std::ostream &O, NodeInfo *NI) const;
- void print(std::ostream &O) const;
};
-
//===----------------------------------------------------------------------===//
/// Special case itineraries.
///
@@ -275,103 +235,12 @@
static InstrStage FloatStage = { 3, RSFloat };
//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-
} // namespace
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
-/// Add - Adds a definer and user pair to a node group.
-///
-void NodeGroup::Add(NodeInfo *D, NodeInfo *U) {
- // Get current groups
- NodeGroup *DGroup = D->Group;
- NodeGroup *UGroup = U->Group;
- // If both are members of groups
- if (DGroup && UGroup) {
- // There may have been another edge connecting
- if (DGroup == UGroup) return;
- // Add the pending users count
- DGroup->addPending(UGroup->getPending());
- // For each member of the users group
- NodeGroupIterator UNGI(U);
- while (NodeInfo *UNI = UNGI.next() ) {
- // Change the group
- UNI->Group = DGroup;
- // For each member of the definers group
- NodeGroupIterator DNGI(D);
- while (NodeInfo *DNI = DNGI.next() ) {
- // Remove internal edges
- DGroup->addPending(-CountInternalUses(DNI, UNI));
- }
- }
- // Merge the two lists
- DGroup->group_insert(DGroup->group_end(),
- UGroup->group_begin(), UGroup->group_end());
- } else if (DGroup) {
- // Make user member of definers group
- U->Group = DGroup;
- // Add users uses to definers group pending
- DGroup->addPending(U->Node->use_size());
- // For each member of the definers group
- NodeGroupIterator DNGI(D);
- while (NodeInfo *DNI = DNGI.next() ) {
- // Remove internal edges
- DGroup->addPending(-CountInternalUses(DNI, U));
- }
- DGroup->group_push_back(U);
- } else if (UGroup) {
- // Make definer member of users group
- D->Group = UGroup;
- // Add definers uses to users group pending
- UGroup->addPending(D->Node->use_size());
- // For each member of the users group
- NodeGroupIterator UNGI(U);
- while (NodeInfo *UNI = UNGI.next() ) {
- // Remove internal edges
- UGroup->addPending(-CountInternalUses(D, UNI));
- }
- UGroup->group_insert(UGroup->group_begin(), D);
- } else {
- D->Group = U->Group = DGroup = new NodeGroup();
- DGroup->addPending(D->Node->use_size() + U->Node->use_size() -
- CountInternalUses(D, U));
- DGroup->group_push_back(D);
- DGroup->group_push_back(U);
- }
-}
-
-/// CountInternalUses - Returns the number of edges between the two nodes.
-///
-unsigned NodeGroup::CountInternalUses(NodeInfo *D, NodeInfo *U) {
- unsigned N = 0;
- for (unsigned M = U->Node->getNumOperands(); 0 < M--;) {
- SDOperand Op = U->Node->getOperand(M);
- if (Op.Val == D->Node) N++;
- }
-
- return N;
-}
-//===----------------------------------------------------------------------===//
-
-
-//===----------------------------------------------------------------------===//
-/// isFlagDefiner - Returns true if the node defines a flag result.
-bool ScheduleDAGSimple::isFlagDefiner(SDNode *A) {
- unsigned N = A->getNumValues();
- return N && A->getValueType(N - 1) == MVT::Flag;
-}
-
-/// isFlagUser - Returns true if the node uses a flag result.
-///
-bool ScheduleDAGSimple::isFlagUser(SDNode *A) {
- unsigned N = A->getNumOperands();
- return N && A->getOperand(N - 1).getValueType() == MVT::Flag;
-}
-
/// isDefiner - Return true if node A is a definer for B.
///
bool ScheduleDAGSimple::isDefiner(NodeInfo *A, NodeInfo *B) {
@@ -391,19 +260,6 @@
return false;
}
-/// isPassiveNode - Return true if the node is a non-scheduled leaf.
-///
-bool ScheduleDAGSimple::isPassiveNode(SDNode *Node) {
- if (isa<ConstantSDNode>(Node)) return true;
- if (isa<RegisterSDNode>(Node)) return true;
- if (isa<GlobalAddressSDNode>(Node)) return true;
- if (isa<BasicBlockSDNode>(Node)) return true;
- if (isa<FrameIndexSDNode>(Node)) return true;
- if (isa<ConstantPoolSDNode>(Node)) return true;
- if (isa<ExternalSymbolSDNode>(Node)) return true;
- return false;
-}
-
/// IncludeNode - Add node to NodeInfo vector.
///
void ScheduleDAGSimple::IncludeNode(NodeInfo *NI) {
@@ -432,62 +288,6 @@
NI->setPending(Count);
}
-/// VisitAll - Visit each node breadth-wise to produce an initial ordering.
-/// Note that the ordering in the Nodes vector is reversed.
-void ScheduleDAGSimple::VisitAll() {
- // Add first element to list
- NodeInfo *NI = getNI(DAG.getRoot().Val);
- if (NI->isInGroup()) {
- Ordering.push_back(NI->Group->getDominator());
- } else {
- Ordering.push_back(NI);
- }
-
- // Iterate through all nodes that have been added
- for (unsigned i = 0; i < Ordering.size(); i++) { // note: size() varies
- // Visit all operands
- NodeGroupOpIterator NGI(Ordering[i]);
- while (!NGI.isEnd()) {
- // Get next operand
- SDOperand Op = NGI.next();
- // Get node
- SDNode *Node = Op.Val;
- // Ignore passive nodes
- if (isPassiveNode(Node)) continue;
- // Check out node
- IncludeNode(getNI(Node));
- }
- }
-
- // Add entry node last (IncludeNode filters entry nodes)
- if (DAG.getEntryNode().Val != DAG.getRoot().Val)
- Ordering.push_back(getNI(DAG.getEntryNode().Val));
-
- // Reverse the order
- std::reverse(Ordering.begin(), Ordering.end());
-}
-
-/// IdentifyGroups - Put flagged nodes into groups.
-///
-void ScheduleDAGSimple::IdentifyGroups() {
- for (unsigned i = 0, N = NodeCount; i < N; i++) {
- NodeInfo* NI = &Info[i];
- SDNode *Node = NI->Node;
-
- // For each operand (in reverse to only look at flags)
- for (unsigned N = Node->getNumOperands(); 0 < N--;) {
- // Get operand
- SDOperand Op = Node->getOperand(N);
- // No more flags to walk
- if (Op.getValueType() != MVT::Flag) break;
- // Add to node group
- NodeGroup::Add(getNI(Op.Val), NI);
- // Let evryone else know
- HasGroups = true;
- }
- }
-}
-
/// GatherSchedulingInfo - Get latency and resource information about each node.
///
void ScheduleDAGSimple::GatherSchedulingInfo() {
@@ -501,7 +301,7 @@
SDNode *Node = NI->Node;
// If there are itineraries and it is a machine instruction
- if (InstrItins.isEmpty() || ScheduleStyle == simpleNoItinScheduling) {
+ if (InstrItins.isEmpty() || Heuristic == simpleNoItinScheduling) {
// If machine opcode
if (Node->isTargetOpcode()) {
// Get return type to guess which processing unit
@@ -572,6 +372,41 @@
}
}
+/// VisitAll - Visit each node breadth-wise to produce an initial ordering.
+/// Note that the ordering in the Nodes vector is reversed.
+void ScheduleDAGSimple::VisitAll() {
+ // Add first element to list
+ NodeInfo *NI = getNI(DAG.getRoot().Val);
+ if (NI->isInGroup()) {
+ Ordering.push_back(NI->Group->getDominator());
+ } else {
+ Ordering.push_back(NI);
+ }
+
+ // Iterate through all nodes that have been added
+ for (unsigned i = 0; i < Ordering.size(); i++) { // note: size() varies
+ // Visit all operands
+ NodeGroupOpIterator NGI(Ordering[i]);
+ while (!NGI.isEnd()) {
+ // Get next operand
+ SDOperand Op = NGI.next();
+ // Get node
+ SDNode *Node = Op.Val;
+ // Ignore passive nodes
+ if (isPassiveNode(Node)) continue;
+ // Check out node
+ IncludeNode(getNI(Node));
+ }
+ }
+
+ // Add entry node last (IncludeNode filters entry nodes)
+ if (DAG.getEntryNode().Val != DAG.getRoot().Val)
+ Ordering.push_back(getNI(DAG.getEntryNode().Val));
+
+ // Reverse the order
+ std::reverse(Ordering.begin(), Ordering.end());
+}
+
/// FakeGroupDominators - Set dominators for non-scheduling.
///
void ScheduleDAGSimple::FakeGroupDominators() {
@@ -588,26 +423,6 @@
}
}
-/// PrepareNodeInfo - Set up the basic minimum node info for scheduling.
-///
-void ScheduleDAGSimple::PrepareNodeInfo() {
- // Allocate node information
- Info = new NodeInfo[NodeCount];
-
- unsigned i = 0;
- for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
- E = DAG.allnodes_end(); I != E; ++I, ++i) {
- // Fast reference to node schedule info
- NodeInfo* NI = &Info[i];
- // Set up map
- Map[I] = NI;
- // Set node
- NI->Node = I;
- // Set pending visit count
- NI->setPending(I->use_size());
- }
-}
-
/// isStrongDependency - Return true if node A has results used by node B.
/// I.E., B must wait for latency of A.
bool ScheduleDAGSimple::isStrongDependency(NodeInfo *A, NodeInfo *B) {
@@ -742,34 +557,11 @@
}
}
-/// EmitAll - Emit all nodes in schedule sorted order.
-///
-void ScheduleDAGSimple::EmitAll() {
- // For each node in the ordering
- for (unsigned i = 0, N = Ordering.size(); i < N; i++) {
- // Get the scheduling info
- NodeInfo *NI = Ordering[i];
- if (NI->isInGroup()) {
- NodeGroupIterator NGI(Ordering[i]);
- while (NodeInfo *NI = NGI.next()) EmitNode(NI);
- } else {
- EmitNode(NI);
- }
- }
-}
-
/// Schedule - Order nodes according to selected style.
///
void ScheduleDAGSimple::Schedule() {
- // Number the nodes
- NodeCount = std::distance(DAG.allnodes_begin(), DAG.allnodes_end());
// Test to see if scheduling should occur
- bool ShouldSchedule = NodeCount > 3 && ScheduleStyle != noScheduling;
- // Set up minimum info for scheduling
- PrepareNodeInfo();
- // Construct node groups for flagged nodes
- IdentifyGroups();
-
+ bool ShouldSchedule = NodeCount > 3 && Heuristic != noScheduling;
// Don't waste time if is only entry and return
if (ShouldSchedule) {
// Get latency and resource requirements
@@ -806,86 +598,11 @@
EmitAll();
}
-/// printChanges - Hilight changes in order caused by scheduling.
-///
-void ScheduleDAGSimple::printChanges(unsigned Index) {
-#ifndef NDEBUG
- // Get the ordered node count
- unsigned N = Ordering.size();
- // Determine if any changes
- unsigned i = 0;
- for (; i < N; i++) {
- NodeInfo *NI = Ordering[i];
- if (NI->Preorder != i) break;
- }
-
- if (i < N) {
- std::cerr << Index << ". New Ordering\n";
-
- for (i = 0; i < N; i++) {
- NodeInfo *NI = Ordering[i];
- std::cerr << " " << NI->Preorder << ". ";
- printSI(std::cerr, NI);
- std::cerr << "\n";
- if (NI->isGroupDominator()) {
- NodeGroup *Group = NI->Group;
- for (NIIterator NII = Group->group_begin(), E = Group->group_end();
- NII != E; NII++) {
- std::cerr << " ";
- printSI(std::cerr, *NII);
- std::cerr << "\n";
- }
- }
- }
- } else {
- std::cerr << Index << ". No Changes\n";
- }
-#endif
-}
-
-/// printSI - Print schedule info.
-///
-void ScheduleDAGSimple::printSI(std::ostream &O, NodeInfo *NI) const {
-#ifndef NDEBUG
- SDNode *Node = NI->Node;
- O << " "
- << std::hex << Node << std::dec
- << ", Lat=" << NI->Latency
- << ", Slot=" << NI->Slot
- << ", ARITY=(" << Node->getNumOperands() << ","
- << Node->getNumValues() << ")"
- << " " << Node->getOperationName(&DAG);
- if (isFlagDefiner(Node)) O << "<#";
- if (isFlagUser(Node)) O << ">#";
-#endif
-}
-
-/// print - Print ordering to specified output stream.
-///
-void ScheduleDAGSimple::print(std::ostream &O) const {
-#ifndef NDEBUG
- using namespace std;
- O << "Ordering\n";
- for (unsigned i = 0, N = Ordering.size(); i < N; i++) {
- NodeInfo *NI = Ordering[i];
- printSI(O, NI);
- O << "\n";
- if (NI->isGroupDominator()) {
- NodeGroup *Group = NI->Group;
- for (NIIterator NII = Group->group_begin(), E = Group->group_end();
- NII != E; NII++) {
- O << " ";
- printSI(O, *NII);
- O << "\n";
- }
- }
- }
-#endif
-}
/// createSimpleDAGScheduler - This creates a simple two pass instruction
/// scheduler.
-llvm::ScheduleDAG* llvm::createSimpleDAGScheduler(SelectionDAG &DAG,
+llvm::ScheduleDAG* llvm::createSimpleDAGScheduler(SchedHeuristics Heuristic,
+ SelectionDAG &DAG,
MachineBasicBlock *BB) {
- return new ScheduleDAGSimple(DAG, BB, DAG.getTarget());
+ return new ScheduleDAGSimple(Heuristic, DAG, BB, DAG.getTarget());
}
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.132 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.133
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.132 Sun Jan 22 23:22:07 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Jan 23 01:01:07 2006
@@ -54,6 +54,25 @@
static const bool ViewSchedDAGs = 0;
#endif
+namespace {
+ cl::opt<SchedHeuristics>
+ ISHeuristic(
+ "sched",
+ cl::desc("Choose scheduling style"),
+ cl::init(noScheduling),
+ cl::values(
+ clEnumValN(noScheduling, "none",
+ "No scheduling: breath first sequencing"),
+ clEnumValN(simpleScheduling, "simple",
+ "Simple two pass scheduling: minimize critical path "
+ "and maximize processor utilization"),
+ clEnumValN(simpleNoItinScheduling, "simple-noitin",
+ "Simple two pass scheduling: Same as simple "
+ "except using generic latency"),
+ clEnumValEnd));
+} // namespace
+
+
namespace llvm {
//===--------------------------------------------------------------------===//
/// FunctionLoweringInfo - This contains information that is global to a
@@ -1747,6 +1766,15 @@
/// target node in the graph.
void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) {
if (ViewSchedDAGs) DAG.viewGraph();
- ScheduleDAG *SL = createSimpleDAGScheduler(DAG, BB);
+ ScheduleDAG *SL = NULL;
+
+ switch (ISHeuristic) {
+ default: assert(0 && "Unrecognized scheduling heuristic");
+ case noScheduling:
+ case simpleScheduling:
+ case simpleNoItinScheduling:
+ SL = createSimpleDAGScheduler(ISHeuristic, DAG, BB);
+ break;
+ }
BB = SL->Run();
}
More information about the llvm-commits
mailing list