From 9ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3b Mon Sep 17 00:00:00 2001 From: Jim Laskey Date: Tue, 1 Aug 2006 18:29:48 +0000 Subject: [PATCH] 1. Change use of "Cache" to "Default". 2. Added argument to instruction scheduler creators so the creators can do special things. 3. Repaired target hazard code. 4. Misc. More to follow. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29450 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/CodeGen/LinkAllCodegenComponents.h | 14 +++--- include/llvm/CodeGen/MachinePassRegistry.h | 44 +++++++++++-------- include/llvm/CodeGen/ScheduleDAG.h | 20 ++++++--- include/llvm/CodeGen/SelectionDAGISel.h | 4 ++ lib/CodeGen/MachinePassRegistry.cpp | 8 +++- lib/CodeGen/Passes.cpp | 4 +- lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp | 6 ++- .../SelectionDAG/ScheduleDAGRRList.cpp | 6 ++- .../SelectionDAG/ScheduleDAGSimple.cpp | 9 ++-- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 13 ++++-- 10 files changed, 82 insertions(+), 46 deletions(-) diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h index 82b5da9f0bf..17212c45f76 100644 --- a/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -32,15 +32,15 @@ namespace { (void) llvm::createLocalRegisterAllocator(); (void) llvm::createLinearScanRegisterAllocator(); - (void) llvm::createBFS_DAGScheduler(NULL, NULL); - (void) llvm::createSimpleDAGScheduler(NULL, NULL); - (void) llvm::createNoItinsDAGScheduler(NULL, NULL); - (void) llvm::createBURRListDAGScheduler(NULL, NULL); - (void) llvm::createTDRRListDAGScheduler(NULL, NULL); - (void) llvm::createTDListDAGScheduler(NULL, NULL); + (void) llvm::createBFS_DAGScheduler(NULL, NULL, NULL); + (void) llvm::createSimpleDAGScheduler(NULL, NULL, NULL); + (void) llvm::createNoItinsDAGScheduler(NULL, NULL, NULL); + (void) llvm::createBURRListDAGScheduler(NULL, NULL, NULL); + (void) llvm::createTDRRListDAGScheduler(NULL, NULL, NULL); + (void) llvm::createTDListDAGScheduler(NULL, NULL, NULL); } } ForceCodegenLinking; // Force link by creating a global definition. } -#endif \ No newline at end of file +#endif diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h index e8c385d7e41..97ecaae1842 100644 --- a/include/llvm/CodeGen/MachinePassRegistry.h +++ b/include/llvm/CodeGen/MachinePassRegistry.h @@ -2,10 +2,18 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under +// This file was developed by the James M. Laskey and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// This file contains the mechanics for machine function pass registries. A +// function pass registry (MachinePassRegistry) is auto filled by the static +// constructors of MachinePassRegistryNode. Further there is a command line +// parser (RegisterPassParser) which listens to each registry for additions +// and deletions, so that the appropriate command option is updated. +// +//===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_MACHINEPASSREGISTRY_H #define LLVM_CODEGEN_MACHINEPASSREGISTRY_H @@ -14,8 +22,6 @@ #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/Support/CommandLine.h" -#include - namespace llvm { @@ -83,7 +89,7 @@ private: MachinePassRegistryNode *List; // List of registry nodes. - FunctionPassCtor Cache; // Cached function pass creator. + FunctionPassCtor Default; // Default function pass creator. MachinePassRegistryListener* Listener;// Listener for list adds are removes. public: @@ -94,8 +100,8 @@ public: // Accessors. // MachinePassRegistryNode *getList() { return List; } - FunctionPassCtor getCache() { return Cache; } - void setCache(FunctionPassCtor C) { Cache = C; } + FunctionPassCtor getDefault() { return Default; } + void setDefault(FunctionPassCtor C) { Default = C; } void setListener(MachinePassRegistryListener *L) { Listener = L; } /// Add - Adds a function pass to the registration list. @@ -113,10 +119,8 @@ public: for (MachinePassRegistryNode **I = &List; *I; I = (*I)->getNextAddress()) { if (*I == Node) { -#if 0 // FIXME: Command opt needs to call a termination routine. if (Listener) Listener->NotifyRemove(Node->getName(), Node->getDescription()); -#endif *I = (*I)->getNext(); break; } @@ -166,11 +170,11 @@ public: static RegisterRegAlloc *getList() { return (RegisterRegAlloc *)Registry.getList(); } - static FunctionPassCtor getCache() { - return Registry.getCache(); + static FunctionPassCtor getDefault() { + return Registry.getDefault(); } - static void setCache(FunctionPassCtor C) { - Registry.setCache(C); + static void setDefault(FunctionPassCtor C) { + Registry.setDefault(C); } static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); @@ -200,16 +204,19 @@ public: /// //===----------------------------------------------------------------------===// +class SelectionDAGISel; class ScheduleDAG; class SelectionDAG; class MachineBasicBlock; class RegisterScheduler : public - MachinePassRegistryNode { + MachinePassRegistryNode< + ScheduleDAG *(*)(SelectionDAGISel*, SelectionDAG*, MachineBasicBlock*)> { public: - typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAG*, MachineBasicBlock*); + typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAGISel*, SelectionDAG*, + MachineBasicBlock*); static MachinePassRegistry Registry; @@ -228,11 +235,11 @@ public: static RegisterScheduler *getList() { return (RegisterScheduler *)Registry.getList(); } - static FunctionPassCtor getCache() { - return Registry.getCache(); + static FunctionPassCtor getDefault() { + return Registry.getDefault(); } - static void setCache(FunctionPassCtor C) { - Registry.setCache(C); + static void setDefault(FunctionPassCtor C) { + Registry.setDefault(C); } static void setListener(MachinePassRegistryListener *L) { Registry.setListener(L); @@ -267,6 +274,7 @@ class RegisterPassParser : public MachinePassRegistryListener, public cl::parser { public: RegisterPassParser() {} + ~RegisterPassParser() { RegistryClass::setListener(NULL); } void initialize(cl::Option &O) { cl::parser::initialize(O); diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 1146c327a6c..a1214db8a83 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -26,6 +26,7 @@ namespace llvm { class MachineInstr; class MRegisterInfo; class SelectionDAG; + class SelectionDAGISel; class SSARegMap; class TargetInstrInfo; class TargetInstrDescriptor; @@ -223,31 +224,38 @@ namespace llvm { /// createBFS_DAGScheduler - This creates a simple breadth first instruction /// scheduler. - ScheduleDAG *createBFS_DAGScheduler(SelectionDAG *DAG, MachineBasicBlock *BB); + ScheduleDAG *createBFS_DAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, + MachineBasicBlock *BB); /// createSimpleDAGScheduler - This creates a simple two pass instruction /// scheduler using instruction itinerary. - ScheduleDAG* createSimpleDAGScheduler(SelectionDAG *DAG, + ScheduleDAG* createSimpleDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB); /// createNoItinsDAGScheduler - This creates a simple two pass instruction /// scheduler without using instruction itinerary. - ScheduleDAG* createNoItinsDAGScheduler(SelectionDAG *DAG, + ScheduleDAG* createNoItinsDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB); /// createBURRListDAGScheduler - This creates a bottom up register usage /// reduction list scheduler. - ScheduleDAG* createBURRListDAGScheduler(SelectionDAG *DAG, + ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB); /// createTDRRListDAGScheduler - This creates a top down register usage /// reduction list scheduler. - ScheduleDAG* createTDRRListDAGScheduler(SelectionDAG *DAG, + ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB); /// createTDListDAGScheduler - This creates a top-down list scheduler with /// a hazard recognizer. - ScheduleDAG* createTDListDAGScheduler(SelectionDAG *DAG, + ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB); } diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index cd8e5f4989c..78179c9e2ad 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -67,6 +67,10 @@ public: /// 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/lib/CodeGen/MachinePassRegistry.cpp b/lib/CodeGen/MachinePassRegistry.cpp index a5f4408f7d7..c4409924760 100644 --- a/lib/CodeGen/MachinePassRegistry.cpp +++ b/lib/CodeGen/MachinePassRegistry.cpp @@ -1,4 +1,4 @@ -//===-- MachineInstr.cpp --------------------------------------------------===// +//===-- CodeGen/MachineInstr.cpp ------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -6,9 +6,13 @@ // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// This file contains the machine function pass registry for register allocators +// and instruction schedulers. +// +//===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachinePassRegistry.h" -#include using namespace llvm; diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index 04f390a2f84..a896f83526e 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -27,13 +27,13 @@ namespace { } FunctionPass *llvm::createRegisterAllocator() { - RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getCache(); + RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault(); if (!Ctor) { Ctor = RegisterRegAlloc::FindCtor(RegAlloc); assert(Ctor && "No register allocator found"); if (!Ctor) Ctor = RegisterRegAlloc::FirstCtor(); - RegisterRegAlloc::setCache(Ctor); + RegisterRegAlloc::setDefault(Ctor); } assert(Ctor && "No register allocator found"); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp index 3d249733c63..8b82197b75f 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp @@ -21,6 +21,7 @@ #define DEBUG_TYPE "sched" #include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/ScheduleDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetData.h" @@ -519,9 +520,10 @@ void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) { /// 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, +ScheduleDAG* llvm::createTDListDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB) { return new ScheduleDAGList(*DAG, BB, DAG->getTarget(), new LatencyPriorityQueue(), - new HazardRecognizer()); + IS->CreateTargetHazardRecognizer()); } diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index d0e9afc3a3f..6e7ef2e2511 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -886,13 +886,15 @@ void TDRegReductionPriorityQueue::CalculatePriorities() { // Public Constructor Functions //===----------------------------------------------------------------------===// -llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAG *DAG, +llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB) { return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), true, new BURegReductionPriorityQueue()); } -llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAG *DAG, +llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB) { return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), false, new TDRegReductionPriorityQueue()); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp index 88587ce5d72..2b8a754a061 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSimple.cpp @@ -1120,21 +1120,24 @@ void ScheduleDAGSimple::Schedule() { /// createSimpleDAGScheduler - This creates a simple two pass instruction /// scheduler using instruction itinerary. -llvm::ScheduleDAG* llvm::createSimpleDAGScheduler(SelectionDAG *DAG, +llvm::ScheduleDAG* llvm::createSimpleDAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB) { return new ScheduleDAGSimple(false, false, *DAG, BB, DAG->getTarget()); } /// createNoItinsDAGScheduler - This creates a simple two pass instruction /// scheduler without using instruction itinerary. -llvm::ScheduleDAG* llvm::createNoItinsDAGScheduler(SelectionDAG *DAG, +llvm::ScheduleDAG* llvm::createNoItinsDAGScheduler(SelectionDAGISel *IS, + 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, +llvm::ScheduleDAG* llvm::createBFS_DAGScheduler(SelectionDAGISel *IS, + SelectionDAG *DAG, MachineBasicBlock *BB) { return new ScheduleDAGSimple(true, false, *DAG, BB, DAG->getTarget()); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index dd3959b2241..84daabbd635 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -67,7 +67,7 @@ namespace { cl::init("default"), cl::desc("Instruction schedulers available:")); - RegisterScheduler + static RegisterScheduler defaultListDAGScheduler("default", " Best scheduler for the target", NULL); } // namespace @@ -3611,7 +3611,7 @@ void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) { if (ViewSchedDAGs) DAG.viewGraph(); static RegisterScheduler::FunctionPassCtor Ctor = - RegisterScheduler::getCache(); + RegisterScheduler::getDefault(); if (!Ctor) { if (std::string("default") == std::string(ISHeuristic)) { @@ -3629,16 +3629,21 @@ void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) { Ctor = RegisterScheduler::FindCtor(ISHeuristic); } - RegisterScheduler::setCache(Ctor); + RegisterScheduler::setDefault(Ctor); } assert(Ctor && "No instruction scheduler found"); - ScheduleDAG *SL = Ctor(&DAG, BB); + ScheduleDAG *SL = Ctor(this, &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. void SelectionDAGISel:: -- 2.34.1