diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/Passes.cpp | 71 | ||||
-rw-r--r-- | lib/CodeGen/RegAllocLinearScan.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/RegAllocLocal.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/RegAllocSimple.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp | 37 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 97 |
8 files changed, 119 insertions, 140 deletions
diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index 12b021c3bd..04f390a2f8 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -12,74 +12,31 @@ // //===---------------------------------------------------------------------===// +#include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include <iostream> + using namespace llvm; namespace { - enum RegAllocName { simple, local, linearscan }; - - static cl::opt<RegAllocName> - RegAlloc( - "regalloc", - cl::desc("Register allocator to use: (default = linearscan)"), - cl::Prefix, - cl::values( - clEnumVal(simple, " simple register allocator"), - clEnumVal(local, " local register allocator"), - clEnumVal(linearscan, " linear scan register allocator"), - clEnumValEnd), - cl::init(linearscan)); -} - - -RegisterRegAlloc *RegisterRegAlloc::List = NULL; - -/// Find - Finds a register allocator in registration list. -/// -RegisterRegAlloc::FunctionPassCtor RegisterRegAlloc::Find(const char *N) { - for (RegisterRegAlloc *RA = List; RA; RA = RA->Next) { - if (strcmp(N, RA->Name) == 0) return RA->Ctor; - } - return NULL; -} - - -#ifndef NDEBUG -void RegisterRegAlloc::print() { - for (RegisterRegAlloc *RA = List; RA; RA = RA->Next) { - std::cerr << "RegAlloc:" << RA->Name << "\n"; - } + cl::opt<const char *, false, RegisterPassParser<RegisterRegAlloc> > + RegAlloc("regalloc", + cl::init("linearscan"), + cl::desc("Register allocator to use: (default = linearscan)")); } -#endif - - -static RegisterRegAlloc - simpleRegAlloc("simple", " simple register allocator", - createSimpleRegisterAllocator); - -static RegisterRegAlloc - localRegAlloc("local", " local register allocator", - createLocalRegisterAllocator); - -static RegisterRegAlloc - linearscanRegAlloc("linearscan", "linear scan register allocator", - createLinearScanRegisterAllocator); - FunctionPass *llvm::createRegisterAllocator() { - const char *Names[] = {"simple", "local", "linearscan"}; - const char *DefltName = "linearscan"; + RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getCache(); + + if (!Ctor) { + Ctor = RegisterRegAlloc::FindCtor(RegAlloc); + assert(Ctor && "No register allocator found"); + if (!Ctor) Ctor = RegisterRegAlloc::FirstCtor(); + RegisterRegAlloc::setCache(Ctor); + } - RegisterRegAlloc::FunctionPassCtor Ctor = - RegisterRegAlloc::Find(Names[RegAlloc]); - if (!Ctor) Ctor = RegisterRegAlloc::Find(DefltName); - assert(Ctor && "No register allocator found"); return Ctor(); } - - diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index 550d2a4e0c..5463e4e4b6 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -18,6 +18,7 @@ #include "llvm/Function.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/MRegisterInfo.h" @@ -42,6 +43,10 @@ namespace { static Statistic<> NumBacktracks ("regalloc", "Number of times we had to backtrack"); + static RegisterRegAlloc + linearscanRegAlloc("linearscan", " linear scan register allocator", + createLinearScanRegisterAllocator); + static unsigned numIterations = 0; static unsigned numIntervals = 0; diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp index 763221ffbf..69b944c709 100644 --- a/lib/CodeGen/RegAllocLocal.cpp +++ b/lib/CodeGen/RegAllocLocal.cpp @@ -18,6 +18,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/LiveVariables.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -35,6 +36,12 @@ namespace { static Statistic<> NumLoads ("ra-local", "Number of loads added"); static Statistic<> NumFolded("ra-local", "Number of loads/stores folded " "into instructions"); + + static RegisterRegAlloc + localRegAlloc("local", " local register allocator", + createLocalRegisterAllocator); + + class VISIBILITY_HIDDEN RA : public MachineFunctionPass { const TargetMachine *TM; MachineFunction *MF; diff --git a/lib/CodeGen/RegAllocSimple.cpp b/lib/CodeGen/RegAllocSimple.cpp index c6faead658..bd20cd04c5 100644 --- a/lib/CodeGen/RegAllocSimple.cpp +++ b/lib/CodeGen/RegAllocSimple.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Debug.h" @@ -33,6 +34,10 @@ namespace { static Statistic<> NumStores("ra-simple", "Number of stores added"); static Statistic<> NumLoads ("ra-simple", "Number of loads added"); + static RegisterRegAlloc + simpleRegAlloc("simple", " simple register allocator", + createSimpleRegisterAllocator); + class VISIBILITY_HIDDEN RegAllocSimple : public MachineFunctionPass { MachineFunction *MF; const TargetMachine *TM; diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp index ee01370d59..3d249733c6 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp @@ -19,6 +19,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sched" +#include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/MRegisterInfo.h" @@ -38,6 +39,10 @@ namespace { static Statistic<> NumStalls("scheduler", "Number of pipeline stalls"); } +static RegisterScheduler + tdListDAGScheduler("list-td", " Top-down list scheduler", + createTDListDAGScheduler); + namespace { //===----------------------------------------------------------------------===// /// ScheduleDAGList - The actual list scheduler implementation. This supports @@ -511,12 +516,12 @@ void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) { // Public Constructor Functions //===----------------------------------------------------------------------===// -/// createTDListDAGScheduler - This creates a top-down list scheduler with the -/// specified hazard recognizer. -ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG &DAG, - MachineBasicBlock *BB, - HazardRecognizer *HR) { - return new ScheduleDAGList(DAG, BB, DAG.getTarget(), +/// createTDListDAGScheduler - This creates a top-down list scheduler with a +/// new hazard recognizer. This scheduler takes ownership of the hazard +/// recognizer and deletes it when done. +ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAG *DAG, + MachineBasicBlock *BB) { + return new ScheduleDAGList(*DAG, BB, DAG->getTarget(), new LatencyPriorityQueue(), - HR); + new HazardRecognizer()); } diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index 3718e64d9c..d0e9afc3a3 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -16,6 +16,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sched" +#include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/MRegisterInfo.h" @@ -31,6 +32,15 @@ #include "llvm/Support/CommandLine.h" using namespace llvm; +static RegisterScheduler + burrListDAGScheduler("list-burr", + " Bottom-up register reduction list scheduling", + createBURRListDAGScheduler); +static RegisterScheduler + tdrListrDAGScheduler("list-tdrr", + " Top-down register reduction list scheduling", + createTDRRListDAGScheduler); + namespace { //===----------------------------------------------------------------------===// /// ScheduleDAGRRList - The actual register reduction list scheduler @@ -876,15 +886,15 @@ void TDRegReductionPriorityQueue<SF>::CalculatePriorities() { // Public Constructor Functions //===----------------------------------------------------------------------===// -llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG &DAG, +llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG *DAG, MachineBasicBlock *BB) { - return new ScheduleDAGRRList(DAG, BB, DAG.getTarget(), true, + return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), true, new BURegReductionPriorityQueue<bu_ls_rr_sort>()); } -llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAG &DAG, +llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAG *DAG, MachineBasicBlock *BB) { - return new ScheduleDAGRRList(DAG, BB, DAG.getTarget(), false, + return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), false, new TDRegReductionPriorityQueue<td_ls_rr_sort>()); } diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp index cc98eab378..88587ce5d7 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sched" +#include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/Target/TargetData.h" @@ -25,7 +26,23 @@ #include <iostream> using namespace llvm; + namespace { + +static RegisterScheduler + bfsDAGScheduler("none", " No scheduling: breadth first sequencing", + createBFS_DAGScheduler); +static RegisterScheduler + simpleDAGScheduler("simple", + " Simple two pass scheduling: minimize critical path " + "and maximize processor utilization", + createSimpleDAGScheduler); +static RegisterScheduler + noitinDAGScheduler("simple-noitin", + " Simple two pass scheduling: Same as simple " + "except using generic latency", + createNoItinsDAGScheduler); + class NodeInfo; typedef NodeInfo *NodeInfoPtr; typedef std::vector<NodeInfoPtr> NIVector; @@ -1102,14 +1119,22 @@ void ScheduleDAGSimple::Schedule() { /// createSimpleDAGScheduler - This creates a simple two pass instruction -/// scheduler. -llvm::ScheduleDAG* llvm::createSimpleDAGScheduler(bool NoItins, - SelectionDAG &DAG, +/// scheduler using instruction itinerary. +llvm::ScheduleDAG* llvm::createSimpleDAGScheduler(SelectionDAG *DAG, MachineBasicBlock *BB) { - return new ScheduleDAGSimple(false, NoItins, DAG, BB, DAG.getTarget()); + return new ScheduleDAGSimple(false, false, *DAG, BB, DAG->getTarget()); } -llvm::ScheduleDAG* llvm::createBFS_DAGScheduler(SelectionDAG &DAG, +/// createNoItinsDAGScheduler - This creates a simple two pass instruction +/// scheduler without using instruction itinerary. +llvm::ScheduleDAG* llvm::createNoItinsDAGScheduler(SelectionDAG *DAG, + MachineBasicBlock *BB) { + return new ScheduleDAGSimple(false, true, *DAG, BB, DAG->getTarget()); +} + +/// createBFS_DAGScheduler - This creates a simple breadth first instruction +/// scheduler. +llvm::ScheduleDAG* llvm::createBFS_DAGScheduler(SelectionDAG *DAG, MachineBasicBlock *BB) { - return new ScheduleDAGSimple(true, false, DAG, BB, DAG.getTarget()); + return new ScheduleDAGSimple(true, false, *DAG, BB, DAG->getTarget()); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 4327e4744a..dd3959b224 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -29,6 +29,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/MRegisterInfo.h" @@ -60,41 +61,14 @@ ViewSchedDAGs("view-sched-dags", cl::Hidden, static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0; #endif -// Scheduling heuristics -enum SchedHeuristics { - defaultScheduling, // Let the target specify its preference. - noScheduling, // No scheduling, emit breadth first sequence. - simpleScheduling, // Two pass, min. critical path, max. utilization. - simpleNoItinScheduling, // Same as above exact using generic latency. - listSchedulingBURR, // Bottom-up reg reduction list scheduling. - listSchedulingTDRR, // Top-down reg reduction list scheduling. - listSchedulingTD // Top-down list scheduler. -}; - namespace { - cl::opt<SchedHeuristics> - ISHeuristic( - "sched", - cl::desc("Choose scheduling style"), - cl::init(defaultScheduling), - cl::values( - clEnumValN(defaultScheduling, "default", - "Target preferred scheduling style"), - clEnumValN(noScheduling, "none", - "No scheduling: breadth 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"), - clEnumValN(listSchedulingBURR, "list-burr", - "Bottom-up register reduction list scheduling"), - clEnumValN(listSchedulingTDRR, "list-tdrr", - "Top-down register reduction list scheduling"), - clEnumValN(listSchedulingTD, "list-td", - "Top-down list scheduler"), - clEnumValEnd)); + cl::opt<const char *, false, RegisterPassParser<RegisterScheduler> > + ISHeuristic("sched", + cl::init("default"), + cl::desc("Instruction schedulers available:")); + + RegisterScheduler + defaultListDAGScheduler("default", " Best scheduler for the target", NULL); } // namespace namespace { @@ -3629,50 +3603,41 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, } } + //===----------------------------------------------------------------------===// /// ScheduleAndEmitDAG - Pick a safe ordering and emit instructions for each /// target node in the graph. void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) { if (ViewSchedDAGs) DAG.viewGraph(); - ScheduleDAG *SL = NULL; - - switch (ISHeuristic) { - default: assert(0 && "Unrecognized scheduling heuristic"); - case defaultScheduling: - if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) - SL = createTDListDAGScheduler(DAG, BB, CreateTargetHazardRecognizer()); - else { - assert(TLI.getSchedulingPreference() == + + static RegisterScheduler::FunctionPassCtor Ctor = + RegisterScheduler::getCache(); + + if (!Ctor) { + if (std::string("default") == std::string(ISHeuristic)) { + if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency) + Ctor = RegisterScheduler::FindCtor("list-td"); + else { + assert(TLI.getSchedulingPreference() == TargetLowering::SchedulingForRegPressure && "Unknown sched type!"); - SL = createBURRListDAGScheduler(DAG, BB); + Ctor = RegisterScheduler::FindCtor("list-burr"); + } + + assert(Ctor && "Default instruction scheduler not present"); + if (!Ctor) Ctor = RegisterScheduler::FindCtor("none"); + } else { + Ctor = RegisterScheduler::FindCtor(ISHeuristic); } - break; - case noScheduling: - SL = createBFS_DAGScheduler(DAG, BB); - break; - case simpleScheduling: - SL = createSimpleDAGScheduler(false, DAG, BB); - break; - case simpleNoItinScheduling: - SL = createSimpleDAGScheduler(true, DAG, BB); - break; - case listSchedulingBURR: - SL = createBURRListDAGScheduler(DAG, BB); - break; - case listSchedulingTDRR: - SL = createTDRRListDAGScheduler(DAG, BB); - break; - case listSchedulingTD: - SL = createTDListDAGScheduler(DAG, BB, CreateTargetHazardRecognizer()); - break; + + RegisterScheduler::setCache(Ctor); } + + assert(Ctor && "No instruction scheduler found"); + ScheduleDAG *SL = Ctor(&DAG, BB); BB = SL->Run(); delete SL; } -HazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() { - return new HazardRecognizer(); -} /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated /// by tblgen. Others should not call it. |