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
/// 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.
};
-//===---------------------------------------------------------------------===//
-///
-/// 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
(void) llvm::createRSProfilingPass();
(void) llvm::createIndMemRemPass();
}
- } ForcePassLinking;
+ } ForcePassLinking; // Force link by creating a global definition.
}
#endif
//
//===---------------------------------------------------------------------===//
+#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();
}
-
-
#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"
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;
#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"
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;
#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"
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;
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "sched"
+#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/MRegisterInfo.h"
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
// 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());
}
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "sched"
+#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/MRegisterInfo.h"
#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
// 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>());
}
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "sched"
+#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Target/TargetData.h"
#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;
/// 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());
}
#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"
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 {
}
}
+
//===----------------------------------------------------------------------===//
/// 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.
//===----------------------------------------------------------------------===//
#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"
#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"