Do not use computationally expensive scheduling heuristics with -fast.

llvm-svn: 52971
This commit is contained in:
Evan Cheng 2008-07-01 18:05:03 +00:00
parent fb2573554c
commit 2c9773155a
8 changed files with 77 additions and 67 deletions

View File

@ -39,10 +39,10 @@ namespace {
(void) llvm::createOcamlCollector(); (void) llvm::createOcamlCollector();
(void) llvm::createShadowStackCollector(); (void) llvm::createShadowStackCollector();
(void) llvm::createBURRListDAGScheduler(NULL, NULL, NULL); (void) llvm::createBURRListDAGScheduler(NULL, NULL, NULL, false);
(void) llvm::createTDRRListDAGScheduler(NULL, NULL, NULL); (void) llvm::createTDRRListDAGScheduler(NULL, NULL, NULL, false);
(void) llvm::createTDListDAGScheduler(NULL, NULL, NULL); (void) llvm::createTDListDAGScheduler(NULL, NULL, NULL, false);
(void) llvm::createDefaultScheduler(NULL, NULL, NULL); (void) llvm::createDefaultScheduler(NULL, NULL, NULL, false);
} }
} ForceCodegenLinking; // Force link by creating a global definition. } ForceCodegenLinking; // Force link by creating a global definition.

View File

@ -396,25 +396,29 @@ namespace llvm {
/// reduction list scheduler. /// reduction list scheduler.
ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS, ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG, SelectionDAG *DAG,
MachineBasicBlock *BB); MachineBasicBlock *BB,
bool Fast);
/// createTDRRListDAGScheduler - This creates a top down register usage /// createTDRRListDAGScheduler - This creates a top down register usage
/// reduction list scheduler. /// reduction list scheduler.
ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS, ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG, SelectionDAG *DAG,
MachineBasicBlock *BB); MachineBasicBlock *BB,
bool Fast);
/// createTDListDAGScheduler - This creates a top-down list scheduler with /// createTDListDAGScheduler - This creates a top-down list scheduler with
/// a hazard recognizer. /// a hazard recognizer.
ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS, ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG, SelectionDAG *DAG,
MachineBasicBlock *BB); MachineBasicBlock *BB,
bool Fast);
/// createDefaultScheduler - This creates an instruction scheduler appropriate /// createDefaultScheduler - This creates an instruction scheduler appropriate
/// for the target. /// for the target.
ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS, ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG, SelectionDAG *DAG,
MachineBasicBlock *BB); MachineBasicBlock *BB,
bool Fast);
class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> { class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
SUnit *Node; SUnit *Node;

View File

@ -35,7 +35,7 @@ class RegisterScheduler : public MachinePassRegistryNode {
public: public:
typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAGISel*, SelectionDAG*, typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAGISel*, SelectionDAG*,
MachineBasicBlock*); MachineBasicBlock*, bool);
static MachinePassRegistry Registry; static MachinePassRegistry Registry;

View File

@ -44,10 +44,11 @@ public:
std::vector<SDNode*> TopOrder; std::vector<SDNode*> TopOrder;
unsigned DAGSize; unsigned DAGSize;
CollectorMetadata *GCI; CollectorMetadata *GCI;
bool FastISel;
static char ID; static char ID;
explicit SelectionDAGISel(TargetLowering &tli) : explicit SelectionDAGISel(TargetLowering &tli, bool fast = false) :
FunctionPass((intptr_t)&ID), TLI(tli), DAGSize(0), GCI(0) {} FunctionPass((intptr_t)&ID), TLI(tli), DAGSize(0), GCI(0), FastISel(fast) {}
TargetLowering &getTargetLowering() { return TLI; } TargetLowering &getTargetLowering() { return TLI; }

View File

@ -548,7 +548,7 @@ void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) {
/// recognizer and deletes it when done. /// recognizer and deletes it when done.
ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAGISel *IS, ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG, SelectionDAG *DAG,
MachineBasicBlock *BB) { MachineBasicBlock *BB, bool Fast) {
return new ScheduleDAGList(*DAG, BB, DAG->getTarget(), return new ScheduleDAGList(*DAG, BB, DAG->getTarget(),
new LatencyPriorityQueue(), new LatencyPriorityQueue(),
IS->CreateTargetHazardRecognizer()); IS->CreateTargetHazardRecognizer());

View File

@ -59,6 +59,8 @@ private:
/// it is top-down. /// it is top-down.
bool isBottomUp; bool isBottomUp;
bool Fast;
/// AvailableQueue - The priority queue to use for the available SUnits. /// AvailableQueue - The priority queue to use for the available SUnits.
SchedulingPriorityQueue *AvailableQueue; SchedulingPriorityQueue *AvailableQueue;
@ -71,9 +73,9 @@ private:
public: public:
ScheduleDAGRRList(SelectionDAG &dag, MachineBasicBlock *bb, ScheduleDAGRRList(SelectionDAG &dag, MachineBasicBlock *bb,
const TargetMachine &tm, bool isbottomup, const TargetMachine &tm, bool isbottomup, bool f,
SchedulingPriorityQueue *availqueue) SchedulingPriorityQueue *availqueue)
: ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), : ScheduleDAG(dag, bb, tm), isBottomUp(isbottomup), Fast(f),
AvailableQueue(availqueue) { AvailableQueue(availqueue) {
} }
@ -144,36 +146,6 @@ private:
/// even after dynamic insertions of new edges. /// even after dynamic insertions of new edges.
/// This allows a very fast implementation of IsReachable. /// This allows a very fast implementation of IsReachable.
/**
The idea of the algorithm is taken from
"Online algorithms for managing the topological order of
a directed acyclic graph" by David J. Pearce and Paul H.J. Kelly
This is the MNR algorithm, which was first introduced by
A. Marchetti-Spaccamela, U. Nanni and H. Rohnert in
"Maintaining a topological order under edge insertions".
Short description of the algorithm:
Topological ordering, ord, of a DAG maps each node to a topological
index so that for all edges X->Y it is the case that ord(X) < ord(Y).
This means that if there is a path from the node X to the node Z,
then ord(X) < ord(Z).
This property can be used to check for reachability of nodes:
if Z is reachable from X, then an insertion of the edge Z->X would
create a cycle.
The algorithm first computes a topological ordering for the DAG by initializing
the Index2Node and Node2Index arrays and then tries to keep the ordering
up-to-date after edge insertions by reordering the DAG.
On insertion of the edge X->Y, the algorithm first marks by calling DFS the
nodes reachable from Y, and then shifts them using Shift to lie immediately
after X in Index2Node.
*/
/// InitDAGTopologicalSorting - create the initial topological /// InitDAGTopologicalSorting - create the initial topological
/// ordering from the DAG to be scheduled. /// ordering from the DAG to be scheduled.
void InitDAGTopologicalSorting(); void InitDAGTopologicalSorting();
@ -212,8 +184,10 @@ void ScheduleDAGRRList::Schedule() {
DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su) DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
SUnits[su].dumpAll(&DAG)); SUnits[su].dumpAll(&DAG));
if (!Fast) {
CalculateDepths(); CalculateDepths();
CalculateHeights(); CalculateHeights();
}
InitDAGTopologicalSorting(); InitDAGTopologicalSorting();
AvailableQueue->initNodes(SUnits); AvailableQueue->initNodes(SUnits);
@ -226,6 +200,7 @@ void ScheduleDAGRRList::Schedule() {
AvailableQueue->releaseState(); AvailableQueue->releaseState();
if (!Fast)
CommuteNodesToReducePressure(); CommuteNodesToReducePressure();
DOUT << "*** Final schedule ***\n"; DOUT << "*** Final schedule ***\n";
@ -449,6 +424,33 @@ inline void ScheduleDAGRRList::Allocate(int n, int index) {
/// InitDAGTopologicalSorting - create the initial topological /// InitDAGTopologicalSorting - create the initial topological
/// ordering from the DAG to be scheduled. /// ordering from the DAG to be scheduled.
/// The idea of the algorithm is taken from
/// "Online algorithms for managing the topological order of
/// a directed acyclic graph" by David J. Pearce and Paul H.J. Kelly
/// This is the MNR algorithm, which was first introduced by
/// A. Marchetti-Spaccamela, U. Nanni and H. Rohnert in
/// "Maintaining a topological order under edge insertions".
///
/// Short description of the algorithm:
///
/// Topological ordering, ord, of a DAG maps each node to a topological
/// index so that for all edges X->Y it is the case that ord(X) < ord(Y).
///
/// This means that if there is a path from the node X to the node Z,
/// then ord(X) < ord(Z).
///
/// This property can be used to check for reachability of nodes:
/// if Z is reachable from X, then an insertion of the edge Z->X would
/// create a cycle.
///
/// The algorithm first computes a topological ordering for the DAG by
/// initializing the Index2Node and Node2Index arrays and then tries to keep
/// the ordering up-to-date after edge insertions by reordering the DAG.
///
/// On insertion of the edge X->Y, the algorithm first marks by calling DFS
/// the nodes reachable from Y, and then shifts them using Shift to lie
/// immediately after X in Index2Node.
void ScheduleDAGRRList::InitDAGTopologicalSorting() { void ScheduleDAGRRList::InitDAGTopologicalSorting() {
unsigned DAGSize = SUnits.size(); unsigned DAGSize = SUnits.size();
std::vector<unsigned> InDegree(DAGSize); std::vector<unsigned> InDegree(DAGSize);
@ -1335,14 +1337,18 @@ namespace {
const TargetInstrInfo *TII; const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI; const TargetRegisterInfo *TRI;
ScheduleDAGRRList *scheduleDAG; ScheduleDAGRRList *scheduleDAG;
bool Fast;
public: public:
explicit BURegReductionPriorityQueue(const TargetInstrInfo *tii, explicit BURegReductionPriorityQueue(const TargetInstrInfo *tii,
const TargetRegisterInfo *tri) const TargetRegisterInfo *tri,
: TII(tii), TRI(tri), scheduleDAG(NULL) {} bool f)
: TII(tii), TRI(tri), scheduleDAG(NULL), Fast(f) {}
void initNodes(std::vector<SUnit> &sunits) { void initNodes(std::vector<SUnit> &sunits) {
SUnits = &sunits; SUnits = &sunits;
// Add pseudo dependency edges for two-address nodes. // Add pseudo dependency edges for two-address nodes.
if (!Fast)
AddPseudoTwoAddrDeps(); AddPseudoTwoAddrDeps();
// Calculate node priorities. // Calculate node priorities.
CalculateSethiUllmanNumbers(); CalculateSethiUllmanNumbers();
@ -1821,23 +1827,25 @@ void TDRegReductionPriorityQueue::CalculateSethiUllmanNumbers() {
llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAGISel *IS, llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG, SelectionDAG *DAG,
MachineBasicBlock *BB) { MachineBasicBlock *BB,
bool Fast) {
const TargetInstrInfo *TII = DAG->getTarget().getInstrInfo(); const TargetInstrInfo *TII = DAG->getTarget().getInstrInfo();
const TargetRegisterInfo *TRI = DAG->getTarget().getRegisterInfo(); const TargetRegisterInfo *TRI = DAG->getTarget().getRegisterInfo();
BURegReductionPriorityQueue *priorityQueue = BURegReductionPriorityQueue *priorityQueue =
new BURegReductionPriorityQueue(TII, TRI); new BURegReductionPriorityQueue(TII, TRI, Fast);
ScheduleDAGRRList * scheduleDAG = ScheduleDAGRRList * scheduleDAG =
new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), true, priorityQueue); new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), true, Fast,priorityQueue);
priorityQueue->setScheduleDAG(scheduleDAG); priorityQueue->setScheduleDAG(scheduleDAG);
return scheduleDAG; return scheduleDAG;
} }
llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG, SelectionDAG *DAG,
MachineBasicBlock *BB) { MachineBasicBlock *BB,
return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), false, bool Fast) {
return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), false, Fast,
new TDRegReductionPriorityQueue()); new TDRegReductionPriorityQueue());
} }

View File

@ -266,15 +266,16 @@ namespace llvm {
/// for the target. /// for the target.
ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS, ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG, SelectionDAG *DAG,
MachineBasicBlock *BB) { MachineBasicBlock *BB,
bool Fast) {
TargetLowering &TLI = IS->getTargetLowering(); TargetLowering &TLI = IS->getTargetLowering();
if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) { if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) {
return createTDListDAGScheduler(IS, DAG, BB); return createTDListDAGScheduler(IS, DAG, BB, Fast);
} else { } else {
assert(TLI.getSchedulingPreference() == assert(TLI.getSchedulingPreference() ==
TargetLowering::SchedulingForRegPressure && "Unknown sched type!"); TargetLowering::SchedulingForRegPressure && "Unknown sched type!");
return createBURRListDAGScheduler(IS, DAG, BB); return createBURRListDAGScheduler(IS, DAG, BB, Fast);
} }
} }
@ -5611,7 +5612,7 @@ void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) {
RegisterScheduler::setDefault(Ctor); RegisterScheduler::setDefault(Ctor);
} }
ScheduleDAG *SL = Ctor(this, &DAG, BB); ScheduleDAG *SL = Ctor(this, &DAG, BB, FastISel);
BB = SL->Run(); BB = SL->Run();
if (ViewSUnitDAGs) SL->viewGraph(); if (ViewSUnitDAGs) SL->viewGraph();

View File

@ -90,10 +90,6 @@ namespace {
/// register should set this to true. /// register should set this to true.
bool ContainsFPCode; bool ContainsFPCode;
/// FastISel - Enable fast(er) instruction selection.
///
bool FastISel;
/// TM - Keep a reference to X86TargetMachine. /// TM - Keep a reference to X86TargetMachine.
/// ///
X86TargetMachine &TM; X86TargetMachine &TM;
@ -116,8 +112,8 @@ namespace {
public: public:
X86DAGToDAGISel(X86TargetMachine &tm, bool fast) X86DAGToDAGISel(X86TargetMachine &tm, bool fast)
: SelectionDAGISel(X86Lowering), : SelectionDAGISel(X86Lowering, fast),
ContainsFPCode(false), FastISel(fast), TM(tm), ContainsFPCode(false), TM(tm),
X86Lowering(*TM.getTargetLowering()), X86Lowering(*TM.getTargetLowering()),
Subtarget(&TM.getSubtarget<X86Subtarget>()) {} Subtarget(&TM.getSubtarget<X86Subtarget>()) {}