diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h index 9350e284fcf..a33b166d5ba 100644 --- a/include/llvm/PassSupport.h +++ b/include/llvm/PassSupport.h @@ -368,6 +368,76 @@ struct PassRegistrationListener { virtual void passEnumerate(const PassInfo *P) {} }; + +//===---------------------------------------------------------------------===// +/// +/// 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/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index 435d6b5627f..12b021c3bd5 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -13,6 +13,7 @@ //===---------------------------------------------------------------------===// #include "llvm/CodeGen/Passes.h" +#include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include using namespace llvm; @@ -33,17 +34,52 @@ namespace { cl::init(linearscan)); } -FunctionPass *llvm::createRegisterAllocator() { - switch (RegAlloc) { - default: - std::cerr << "no register allocator selected"; - abort(); - case simple: - return createSimpleRegisterAllocator(); - case local: - return createLocalRegisterAllocator(); - case linearscan: - return createLinearScanRegisterAllocator(); + +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::Find(Names[RegAlloc]); + if (!Ctor) Ctor = RegisterRegAlloc::Find(DefltName); + + assert(Ctor && "No register allocator found"); + + return Ctor(); +} + +