Introducing plugable register allocators and instruction schedulers.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29434 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 870d48a..1146c32 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -221,29 +221,35 @@
                     std::map<SDNode*, unsigned> &VRBaseMap);
   };
 
-  ScheduleDAG *createBFS_DAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB);
+  /// createBFS_DAGScheduler - This creates a simple breadth first instruction
+  /// scheduler.
+  ScheduleDAG *createBFS_DAGScheduler(SelectionDAG *DAG, MachineBasicBlock *BB);
   
   /// createSimpleDAGScheduler - This creates a simple two pass instruction
-  /// scheduler.
-  ScheduleDAG* createSimpleDAGScheduler(bool NoItins, SelectionDAG &DAG,
+  /// scheduler using instruction itinerary.
+  ScheduleDAG* createSimpleDAGScheduler(SelectionDAG *DAG,
                                         MachineBasicBlock *BB);
 
+  /// createNoItinsDAGScheduler - This creates a simple two pass instruction
+  /// scheduler without using instruction itinerary.
+  ScheduleDAG* createNoItinsDAGScheduler(SelectionDAG *DAG,
+                                         MachineBasicBlock *BB);
+
   /// createBURRListDAGScheduler - This creates a bottom up register usage
   /// reduction list scheduler.
-  ScheduleDAG* createBURRListDAGScheduler(SelectionDAG &DAG,
+  ScheduleDAG* createBURRListDAGScheduler(SelectionDAG *DAG,
                                           MachineBasicBlock *BB);
   
   /// createTDRRListDAGScheduler - This creates a top down register usage
   /// reduction list scheduler.
-  ScheduleDAG* createTDRRListDAGScheduler(SelectionDAG &DAG,
+  ScheduleDAG* createTDRRListDAGScheduler(SelectionDAG *DAG,
                                           MachineBasicBlock *BB);
   
   /// createTDListDAGScheduler - This creates a top-down list scheduler with
-  /// the specified hazard recognizer.  This takes ownership of the hazard
-  /// recognizer and deletes it when done.
-  ScheduleDAG* createTDListDAGScheduler(SelectionDAG &DAG,
-                                        MachineBasicBlock *BB,
-                                        HazardRecognizer *HR);
+  /// a hazard recognizer.
+  ScheduleDAG* createTDListDAGScheduler(SelectionDAG *DAG,
+                                        MachineBasicBlock *BB);
+                                        
 }
 
 #endif
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 78179c9..cd8e5f4 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -67,10 +67,6 @@
   /// folded during instruction selection?
   virtual bool CanBeFoldedBy(SDNode *N, SDNode *U) { return true; }
   
-  /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
-  /// to use for this target when scheduling the DAG.
-  virtual HazardRecognizer *CreateTargetHazardRecognizer();
-  
   /// CaseBlock - This structure is used to communicate between SDLowering and
   /// SDISel for the code generation of additional basic blocks needed by multi-
   /// case switch statements.
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
index a33b166..c802fe2 100644
--- a/include/llvm/PassSupport.h
+++ b/include/llvm/PassSupport.h
@@ -369,75 +369,6 @@
 };
 
 
-//===---------------------------------------------------------------------===//
-///
-/// RegisterRegAlloc class - Track the registration of register allocators.
-///
-class RegisterRegAlloc {
-
-public:
-
-  typedef FunctionPass *(*FunctionPassCtor)();
-
-private:
-
-  static RegisterRegAlloc *List;        // Linked list of register allocators.
-  
-  RegisterRegAlloc *Next;               // Next allocation scheme in list.
-  const char *Name;                     // Name of register allocator.
-  const char *Description;              // Description string.
-  FunctionPassCtor Ctor;                // Function to construct register
-                                        // allocator pass.
-public:
-
-  RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
-  : Name(N)
-  , Description(D)
-  , Ctor(C) {
-    Add();
-  }
-  
-  ~RegisterRegAlloc() {
-    Remove();
-  }
-  
-  
-  // Accessors
-  const char *getName()        const { return Name; }
-  const char *getDescription() const { return Description; }
-  FunctionPassCtor getCtor()   const { return Ctor; }
-  
-  
-  /// Add - Adds a register allocator to the registration list.
-  ///
-  void Add() {
-    Next = List;
-    List = this;
-  }
-  
-
-  /// Remove - Removes a register allocator from the registration list.
-  ///
-  void Remove() {
-    for (RegisterRegAlloc **RA = &List; *RA; RA = &(*RA)->Next) {
-      if (*RA == this) {
-        *RA = Next;
-        break;
-      }
-    }
-  }
-  
-  
-  /// Find - Finds a register allocator in registration list.
-  ///
-  static FunctionPassCtor Find(const char *N);
-
-#ifndef NDEBUG  
-  static void print();
-#endif
-};
-
-
 } // End llvm namespace
 
 #endif
diff --git a/include/llvm/Transforms/LinkAllPasses.h b/include/llvm/Transforms/LinkAllPasses.h
index cb83dad..3a9c504 100644
--- a/include/llvm/Transforms/LinkAllPasses.h
+++ b/include/llvm/Transforms/LinkAllPasses.h
@@ -110,7 +110,7 @@
       (void) llvm::createRSProfilingPass();
       (void) llvm::createIndMemRemPass();
     }
-  } ForcePassLinking;
+  } ForcePassLinking; // Force link by creating a global definition.
 }
 
 #endif
diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp
index 12b021c..04f390a 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));
+  cl::opt<const char *, false, RegisterPassParser<RegisterRegAlloc> >
+  RegAlloc("regalloc",
+           cl::init("linearscan"),
+           cl::desc("Register allocator to use: (default = 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";
-  }
-}
-#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();
   
-  RegisterRegAlloc::FunctionPassCtor Ctor =
-                    RegisterRegAlloc::Find(Names[RegAlloc]);
-  if (!Ctor) Ctor = RegisterRegAlloc::Find(DefltName);
-
+  if (!Ctor) {
+    Ctor = RegisterRegAlloc::FindCtor(RegAlloc);
+    assert(Ctor && "No register allocator found");
+    if (!Ctor) Ctor = RegisterRegAlloc::FirstCtor();
+    RegisterRegAlloc::setCache(Ctor);
+  }
+  
   assert(Ctor && "No register allocator found");
   
   return Ctor();
 }
-
-
diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp
index 550d2a4..5463e4e 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 @@
   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 763221f..69b944c 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 @@
   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 c6faead..bd20cd0 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 @@
   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 ee01370..3d24973 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 @@
   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 @@
 //                         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 3718e64..d0e9afc 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 @@
 //                         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 cc98eab..88587ce 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 @@
 
 
 /// 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 4327e47..dd3959b 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 @@
 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 @@
   }
 }
 
+
 //===----------------------------------------------------------------------===//
 /// 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.
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index f57f3e1..19b2df6 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -14,6 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Bytecode/Reader.h"
+#include "llvm/Codegen/LinkAllCodegenComponents.h"
 #include "llvm/Target/SubtargetFeature.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index 283bd48..49fb852 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -17,6 +17,7 @@
 #include "llvm/ModuleProvider.h"
 #include "llvm/Type.h"
 #include "llvm/Bytecode/Reader.h"
+#include "llvm/Codegen/LinkAllCodegenComponents.h"
 #include "llvm/ExecutionEngine/JIT.h"
 #include "llvm/ExecutionEngine/Interpreter.h"
 #include "llvm/ExecutionEngine/GenericValue.h"