diff options
52 files changed, 502 insertions, 271 deletions
diff --git a/Makefile.rules b/Makefile.rules index 98c72c0d05..2acadd8400 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -1725,15 +1725,20 @@ $(ObjDir)/%GenRegisterNames.inc.tmp : %.td $(ObjDir)/.dir $(Echo) "Building $(<F) register names with tblgen" $(Verb) $(TableGen) -gen-register-enums -o $(call SYSPATH, $@) $< +$(TARGET:%=$(ObjDir)/%GenRegisterDesc.inc.tmp): \ +$(ObjDir)/%GenRegisterDesc.inc.tmp : %.td $(ObjDir)/.dir + $(Echo) "Building $(<F) register descriptions with tblgen" + $(Verb) $(TableGen) -gen-register-desc -o $(call SYSPATH, $@) $< + $(TARGET:%=$(ObjDir)/%GenRegisterInfo.h.inc.tmp): \ $(ObjDir)/%GenRegisterInfo.h.inc.tmp : %.td $(ObjDir)/.dir $(Echo) "Building $(<F) register information header with tblgen" - $(Verb) $(TableGen) -gen-register-desc-header -o $(call SYSPATH, $@) $< + $(Verb) $(TableGen) -gen-register-info-header -o $(call SYSPATH, $@) $< $(TARGET:%=$(ObjDir)/%GenRegisterInfo.inc.tmp): \ $(ObjDir)/%GenRegisterInfo.inc.tmp : %.td $(ObjDir)/.dir $(Echo) "Building $(<F) register info implementation with tblgen" - $(Verb) $(TableGen) -gen-register-desc -o $(call SYSPATH, $@) $< + $(Verb) $(TableGen) -gen-register-info -o $(call SYSPATH, $@) $< $(TARGET:%=$(ObjDir)/%GenInstrNames.inc.tmp): \ $(ObjDir)/%GenInstrNames.inc.tmp : %.td $(ObjDir)/.dir diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h new file mode 100644 index 0000000000..30db84b762 --- /dev/null +++ b/include/llvm/MC/MCRegisterInfo.h @@ -0,0 +1,123 @@ +//=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes an abstract interface used to get information about a +// target machines register file. This information is used for a variety of +// purposed, especially register allocation. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCREGISTERINFO_H +#define LLVM_MC_MCREGISTERINFO_H + +#include <cassert> + +namespace llvm { + +/// TargetRegisterDesc - This record contains all of the information known about +/// a particular register. The Overlaps field contains a pointer to a zero +/// terminated array of registers that this register aliases, starting with +/// itself. This is needed for architectures like X86 which have AL alias AX +/// alias EAX. The SubRegs field is a zero terminated array of registers that +/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of +/// AX. The SuperRegs field is a zero terminated array of registers that are +/// super-registers of the specific register, e.g. RAX, EAX, are super-registers +/// of AX. +/// +struct TargetRegisterDesc { + const char *Name; // Printable name for the reg (for debugging) + const unsigned *Overlaps; // Overlapping registers, described above + const unsigned *SubRegs; // Sub-register set, described above + const unsigned *SuperRegs; // Super-register set, described above +}; + +/// MCRegisterInfo base class - We assume that the target defines a static +/// array of TargetRegisterDesc objects that represent all of the machine +/// registers that the target has. As such, we simply have to track a pointer +/// to this array so that we can turn register number into a register +/// descriptor. +/// +class MCRegisterInfo { +private: + const TargetRegisterDesc *Desc; // Pointer to the descriptor array + unsigned NumRegs; // Number of entries in the array + +public: + /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen + /// auto-generated routines. *DO NOT USE*. + void InitMCRegisterInfo(const TargetRegisterDesc *D, unsigned NR) { + Desc = D; + NumRegs = NR; + } + + const TargetRegisterDesc &operator[](unsigned RegNo) const { + assert(RegNo < NumRegs && + "Attempting to access record for invalid register number!"); + return Desc[RegNo]; + } + + /// Provide a get method, equivalent to [], but more useful if we have a + /// pointer to this object. + /// + const TargetRegisterDesc &get(unsigned RegNo) const { + return operator[](RegNo); + } + + /// getAliasSet - Return the set of registers aliased by the specified + /// register, or a null list of there are none. The list returned is zero + /// terminated. + /// + const unsigned *getAliasSet(unsigned RegNo) const { + // The Overlaps set always begins with Reg itself. + return get(RegNo).Overlaps + 1; + } + + /// getOverlaps - Return a list of registers that overlap Reg, including + /// itself. This is the same as the alias set except Reg is included in the + /// list. + /// These are exactly the registers in { x | regsOverlap(x, Reg) }. + /// + const unsigned *getOverlaps(unsigned RegNo) const { + return get(RegNo).Overlaps; + } + + /// getSubRegisters - Return the list of registers that are sub-registers of + /// the specified register, or a null list of there are none. The list + /// returned is zero terminated and sorted according to super-sub register + /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH. + /// + const unsigned *getSubRegisters(unsigned RegNo) const { + return get(RegNo).SubRegs; + } + + /// getSuperRegisters - Return the list of registers that are super-registers + /// of the specified register, or a null list of there are none. The list + /// returned is zero terminated and sorted according to super-sub register + /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX. + /// + const unsigned *getSuperRegisters(unsigned RegNo) const { + return get(RegNo).SuperRegs; + } + + /// getName - Return the human-readable symbolic target-specific name for the + /// specified physical register. + const char *getName(unsigned RegNo) const { + return get(RegNo).Name; + } + + /// getNumRegs - Return the number of registers this target has (useful for + /// sizing arrays holding per register information) + unsigned getNumRegs() const { + return NumRegs; + } +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 840b048704..d50bfe7eec 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -16,6 +16,7 @@ #ifndef LLVM_TARGET_TARGETREGISTERINFO_H #define LLVM_TARGET_TARGETREGISTERINFO_H +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/ADT/ArrayRef.h" @@ -32,25 +33,6 @@ class RegScavenger; template<class T> class SmallVectorImpl; class raw_ostream; -/// TargetRegisterDesc - This record contains all of the information known about -/// a particular register. The Overlaps field contains a pointer to a zero -/// terminated array of registers that this register aliases, starting with -/// itself. This is needed for architectures like X86 which have AL alias AX -/// alias EAX. The SubRegs field is a zero terminated array of registers that -/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of -/// AX. The SuperRegs field is a zero terminated array of registers that are -/// super-registers of the specific register, e.g. RAX, EAX, are super-registers -/// of AX. -/// -struct TargetRegisterDesc { - const char *Name; // Printable name for the reg (for debugging) - const unsigned *Overlaps; // Overlapping registers, described above - const unsigned *SubRegs; // Sub-register set, described above - const unsigned *SuperRegs; // Super-register set, described above - unsigned CostPerUse; // Extra cost of instructions using register. - bool inAllocatableClass; // Register belongs to an allocatable regclass. -}; - class TargetRegisterClass { public: typedef const unsigned* iterator; @@ -274,6 +256,12 @@ public: bool isAllocatable() const { return Allocatable; } }; +/// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about +/// registers. These are used by codegen, not by MC. +struct TargetRegisterInfoDesc { + unsigned CostPerUse; // Extra cost of instructions using register. + bool inAllocatableClass; // Register belongs to an allocatable regclass. +}; /// TargetRegisterInfo base class - We assume that the target defines a static /// array of TargetRegisterDesc objects that represent all of the machine @@ -281,20 +269,17 @@ public: /// to this array so that we can turn register number into a register /// descriptor. /// -class TargetRegisterInfo { +class TargetRegisterInfo : public MCRegisterInfo { public: typedef const TargetRegisterClass * const * regclass_iterator; private: - const TargetRegisterDesc *Desc; // Pointer to the descriptor array + const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen const char *const *SubRegIndexNames; // Names of subreg indexes. - unsigned NumRegs; // Number of entries in the array - regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses - int CallFrameSetupOpcode, CallFrameDestroyOpcode; protected: - TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR, + TargetRegisterInfo(const TargetRegisterInfoDesc *ID, regclass_iterator RegClassBegin, regclass_iterator RegClassEnd, const char *const *subregindexnames, @@ -379,71 +364,16 @@ public: BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC = NULL) const; - const TargetRegisterDesc &operator[](unsigned RegNo) const { - assert(RegNo < NumRegs && - "Attempting to access record for invalid register number!"); - return Desc[RegNo]; - } - - /// Provide a get method, equivalent to [], but more useful if we have a - /// pointer to this object. - /// - const TargetRegisterDesc &get(unsigned RegNo) const { - return operator[](RegNo); - } - - /// getAliasSet - Return the set of registers aliased by the specified - /// register, or a null list of there are none. The list returned is zero - /// terminated. - /// - const unsigned *getAliasSet(unsigned RegNo) const { - // The Overlaps set always begins with Reg itself. - return get(RegNo).Overlaps + 1; - } - - /// getOverlaps - Return a list of registers that overlap Reg, including - /// itself. This is the same as the alias set except Reg is included in the - /// list. - /// These are exactly the registers in { x | regsOverlap(x, Reg) }. - /// - const unsigned *getOverlaps(unsigned RegNo) const { - return get(RegNo).Overlaps; - } - - /// getSubRegisters - Return the list of registers that are sub-registers of - /// the specified register, or a null list of there are none. The list - /// returned is zero terminated and sorted according to super-sub register - /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH. - /// - const unsigned *getSubRegisters(unsigned RegNo) const { - return get(RegNo).SubRegs; - } - - /// getSuperRegisters - Return the list of registers that are super-registers - /// of the specified register, or a null list of there are none. The list - /// returned is zero terminated and sorted according to super-sub register - /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX. - /// - const unsigned *getSuperRegisters(unsigned RegNo) const { - return get(RegNo).SuperRegs; - } - - /// getName - Return the human-readable symbolic target-specific name for the - /// specified physical register. - const char *getName(unsigned RegNo) const { - return get(RegNo).Name; - } - /// getCostPerUse - Return the additional cost of using this register instead /// of other registers in its class. unsigned getCostPerUse(unsigned RegNo) const { - return get(RegNo).CostPerUse; + return InfoDesc[RegNo].CostPerUse; } - /// getNumRegs - Return the number of registers this target has (useful for - /// sizing arrays holding per register information) - unsigned getNumRegs() const { - return NumRegs; + /// isInAllocatableClass - Return true if the register is in the allocation + /// of any register class. + bool isInAllocatableClass(unsigned RegNo) const { + return InfoDesc[RegNo].inAllocatableClass; } /// getSubRegIndexName - Return the human-readable symbolic target-specific diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index a464822893..2e219011ab 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -33,6 +33,7 @@ namespace llvm { class MCContext; class MCDisassembler; class MCInstPrinter; + class MCRegisterInfo; class MCStreamer; class TargetAsmBackend; class TargetAsmLexer; @@ -64,7 +65,9 @@ namespace llvm { typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); typedef MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T, - StringRef TT); + StringRef TT); + typedef MCRegisterInfo *(*RegInfoCtorFnTy)(const Target &T, + StringRef TT); typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T, const std::string &TT, const std::string &Features); @@ -120,8 +123,14 @@ namespace llvm { /// HasJIT - Whether this target supports the JIT. bool HasJIT; + /// AsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if + /// registered. AsmInfoCtorFnTy AsmInfoCtorFn; + /// RegInfoCtorFn - Constructor function for this target's MCRegisterInfo, + /// if registered. + RegInfoCtorFnTy RegInfoCtorFn; + /// TargetMachineCtorFn - Construction function for this target's /// TargetMachine, if registered. TargetMachineCtorTy TargetMachineCtorFn; @@ -231,6 +240,19 @@ namespace llvm { return AsmInfoCtorFn(*this, Triple); } + /// createRegInfo - Create a MCRegisterInfo implementation for the specified + /// target triple. + /// + /// \arg Triple - This argument is used to determine the target machine + /// feature set; it should always be provided. Generally this should be + /// either the target triple from the module, or the target triple of the + /// host if that does not exist. + MCRegisterInfo *createRegInfo(StringRef Triple) const { + if (!RegInfoCtorFn) + return 0; + return RegInfoCtorFn(*this, Triple); + } + /// createTargetMachine - Create a target specific machine implementation /// for the specified \arg Triple. /// @@ -444,6 +466,21 @@ namespace llvm { T.AsmInfoCtorFn = Fn; } + /// RegisterRegInfo - Register a MCRegisterInfo implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCRegisterInfo for the target. + static void RegisterRegInfo(Target &T, Target::RegInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.RegInfoCtorFn) + T.RegInfoCtorFn = Fn; + } + /// RegisterTargetMachine - Register a TargetMachine implementation for the /// given target. /// diff --git a/lib/CodeGen/RegisterClassInfo.h b/lib/CodeGen/RegisterClassInfo.h index 6f7d9c9496..d21fd67efe 100644 --- a/lib/CodeGen/RegisterClassInfo.h +++ b/lib/CodeGen/RegisterClassInfo.h @@ -112,7 +112,7 @@ public: /// register, so a register allocator needs to track its liveness and /// availability. bool isAllocatable(unsigned PhysReg) const { - return TRI->get(PhysReg).inAllocatableClass && !isReserved(PhysReg); + return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg); } }; } // end namespace llvm diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 9dc51b810e..0e74ac0cf1 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -39,6 +39,8 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CommandLine.h" +#include "ARMGenRegisterDesc.inc" +#include "ARMGenRegisterInfo.inc" using namespace llvm; @@ -54,7 +56,8 @@ EnableBasePointer("arm-use-base-pointer", cl::Hidden, cl::init(true), ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii, const ARMSubtarget &sti) - : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP), + : ARMGenRegisterInfo(ARMRegDesc, ARMRegInfoDesc, + ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP), TII(tii), STI(sti), FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11), BasePtr(ARM::R6) { @@ -1287,5 +1290,3 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.setDesc(TII.get(ARM::t2SUBri)); } } - -#include "ARMGenRegisterInfo.inc" diff --git a/lib/Target/ARM/CMakeLists.txt b/lib/Target/ARM/CMakeLists.txt index edc0054468..6cb9689515 100644 --- a/lib/Target/ARM/CMakeLists.txt +++ b/lib/Target/ARM/CMakeLists.txt @@ -1,8 +1,9 @@ set(LLVM_TARGET_DEFINITIONS ARM.td) -tablegen(ARMGenRegisterInfo.h.inc -gen-register-desc-header) tablegen(ARMGenRegisterNames.inc -gen-register-enums) -tablegen(ARMGenRegisterInfo.inc -gen-register-desc) +tablegen(ARMGenRegisterDesc.inc -gen-register-desc) +tablegen(ARMGenRegisterInfo.h.inc -gen-register-info-header) +tablegen(ARMGenRegisterInfo.inc -gen-register-info) tablegen(ARMGenInstrNames.inc -gen-instr-enums) tablegen(ARMGenInstrInfo.inc -gen-instr-desc) tablegen(ARMGenCodeEmitter.inc -gen-emitter) diff --git a/lib/Target/ARM/Makefile b/lib/Target/ARM/Makefile index 65a6494986..0a425143dc 100644 --- a/lib/Target/ARM/Makefile +++ b/lib/Target/ARM/Makefile @@ -12,9 +12,10 @@ LIBRARYNAME = LLVMARMCodeGen TARGET = ARM # Make sure that tblgen is run, first thing. -BUILT_SOURCES = ARMGenRegisterInfo.h.inc ARMGenRegisterNames.inc \ - ARMGenRegisterInfo.inc ARMGenInstrNames.inc \ - ARMGenInstrInfo.inc ARMGenAsmWriter.inc ARMGenAsmMatcher.inc \ +BUILT_SOURCES = ARMGenRegisterNames.inc ARMGenRegisterDesc.inc \ + ARMGenRegisterInfo.h.inc ARMGenRegisterInfo.inc \ + ARMGenInstrNames.inc ARMGenInstrInfo.inc \ + ARMGenAsmWriter.inc ARMGenAsmMatcher.inc \ ARMGenDAGISel.inc ARMGenSubtarget.inc \ ARMGenCodeEmitter.inc ARMGenCallingConv.inc \ ARMGenDecoderTables.inc ARMGenEDInfo.inc \ diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp index d6c3809960..5ff846eca7 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.cpp +++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp @@ -33,10 +33,13 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include <cstdlib> +#include "AlphaGenRegisterDesc.inc" +#include "AlphaGenRegisterInfo.inc" using namespace llvm; AlphaRegisterInfo::AlphaRegisterInfo(const TargetInstrInfo &tii) - : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP), + : AlphaGenRegisterInfo(AlphaRegDesc, AlphaRegInfoDesc, + Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP), TII(tii) { } @@ -204,10 +207,8 @@ int AlphaRegisterInfo::getLLVMRegNum(unsigned DwarfRegNum, bool isEH) const { return -1; } -#include "AlphaGenRegisterInfo.inc" - std::string AlphaRegisterInfo::getPrettyName(unsigned reg) { - std::string s(RegisterDescriptors[reg].Name); + std::string s(AlphaRegDesc[reg].Name); return s; } diff --git a/lib/Target/Alpha/CMakeLists.txt b/lib/Target/Alpha/CMakeLists.txt index 454262ad63..1834b06653 100644 --- a/lib/Target/Alpha/CMakeLists.txt +++ b/lib/Target/Alpha/CMakeLists.txt @@ -1,8 +1,9 @@ set(LLVM_TARGET_DEFINITIONS Alpha.td) -tablegen(AlphaGenRegisterInfo.h.inc -gen-register-desc-header) tablegen(AlphaGenRegisterNames.inc -gen-register-enums) -tablegen(AlphaGenRegisterInfo.inc -gen-register-desc) +tablegen(AlphaGenRegisterDesc.inc -gen-register-desc) +tablegen(AlphaGenRegisterInfo.h.inc -gen-register-info-header) +tablegen(AlphaGenRegisterInfo.inc -gen-register-info) tablegen(AlphaGenInstrNames.inc -gen-instr-enums) tablegen(AlphaGenInstrInfo.inc -gen-instr-desc) tablegen(AlphaGenAsmWriter.inc -gen-asm-writer) diff --git a/lib/Target/Alpha/Makefile b/lib/Target/Alpha/Makefile index 9564be680e..f029793d08 100644 --- a/lib/Target/Alpha/Makefile +++ b/lib/Target/Alpha/Makefile @@ -12,9 +12,9 @@ LIBRARYNAME = LLVMAlphaCodeGen TARGET = Alpha # Make sure that tblgen is run, first thing. -BUILT_SOURCES = AlphaGenRegisterInfo.h.inc AlphaGenRegisterNames.inc \ - AlphaGenRegisterInfo.inc AlphaGenInstrNames.inc \ - AlphaGenInstrInfo.inc \ +BUILT_SOURCES = AlphaGenRegisterNames.inc AlphaGenRegisterDesc.inc \ + AlphaGenRegisterInfo.h.inc AlphaGenRegisterInfo.inc \ + AlphaGenInstrNames.inc AlphaGenInstrInfo.inc \ AlphaGenAsmWriter.inc AlphaGenDAGISel.inc \ AlphaGenCallingConv.inc AlphaGenSubtarget.inc diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp index 6ca460ef80..6377d8e403 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp @@ -29,11 +29,14 @@ #include "llvm/Type.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" +#include "BlackfinGenRegisterDesc.inc" +#include "BlackfinGenRegisterInfo.inc" using namespace llvm; BlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st, const TargetInstrInfo &tii) - : BlackfinGenRegisterInfo(BF::ADJCALLSTACKDOWN, BF::ADJCALLSTACKUP), + : BlackfinGenRegisterInfo(BlackfinRegDesc, BlackfinRegInfoDesc, + BF::ADJCALLSTACKDOWN, BF::ADJCALLSTACKUP), Subtarget(st), TII(tii) {} @@ -356,6 +359,3 @@ int BlackfinRegisterInfo::getLLVMRegNum(unsigned DwarfRegNum, llvm_unreachable("What is the dwarf register number"); return -1; } - -#include "Blackf |