| //===-- RegisterClassInfo.h - Dynamic Register Class Info -*- C++ -*-------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file implements the RegisterClassInfo class which provides dynamic | |
| // information about target register classes. Callee saved and reserved | |
| // registers depends on calling conventions and other dynamic information, so | |
| // some things cannot be determined statically. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLVM_CODEGEN_REGISTERCLASSINFO_H | |
| #define LLVM_CODEGEN_REGISTERCLASSINFO_H | |
| #include "llvm/ADT/ArrayRef.h" | |
| #include "llvm/ADT/BitVector.h" | |
| #include "llvm/ADT/OwningPtr.h" | |
| #include "llvm/Target/TargetRegisterInfo.h" | |
| namespace llvm { | |
| class RegisterClassInfo { | |
| struct RCInfo { | |
| unsigned Tag; | |
| unsigned NumRegs; | |
| bool ProperSubClass; | |
| OwningArrayPtr<unsigned> Order; | |
| RCInfo() : Tag(0), NumRegs(0), ProperSubClass(false) {} | |
| operator ArrayRef<unsigned>() const { | |
| return makeArrayRef(Order.get(), NumRegs); | |
| } | |
| }; | |
| // Brief cached information for each register class. | |
| OwningArrayPtr<RCInfo> RegClass; | |
| // Tag changes whenever cached information needs to be recomputed. An RCInfo | |
| // entry is valid when its tag matches. | |
| unsigned Tag; | |
| const MachineFunction *MF; | |
| const TargetRegisterInfo *TRI; | |
| // Callee saved registers of last MF. Assumed to be valid until the next | |
| // runOnFunction() call. | |
| const unsigned *CalleeSaved; | |
| // Map register number to CalleeSaved index + 1; | |
| SmallVector<uint8_t, 4> CSRNum; | |
| // Reserved registers in the current MF. | |
| BitVector Reserved; | |
| // Compute all information about RC. | |
| void compute(const TargetRegisterClass *RC) const; | |
| // Return an up-to-date RCInfo for RC. | |
| const RCInfo &get(const TargetRegisterClass *RC) const { | |
| const RCInfo &RCI = RegClass[RC->getID()]; | |
| if (Tag != RCI.Tag) | |
| compute(RC); | |
| return RCI; | |
| } | |
| public: | |
| RegisterClassInfo(); | |
| /// runOnFunction - Prepare to answer questions about MF. This must be called | |
| /// before any other methods are used. | |
| void runOnMachineFunction(const MachineFunction &MF); | |
| /// getNumAllocatableRegs - Returns the number of actually allocatable | |
| /// registers in RC in the current function. | |
| unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const { | |
| return get(RC).NumRegs; | |
| } | |
| /// getOrder - Returns the preferred allocation order for RC. The order | |
| /// contains no reserved registers, and registers that alias callee saved | |
| /// registers come last. | |
| ArrayRef<unsigned> getOrder(const TargetRegisterClass *RC) const { | |
| return get(RC); | |
| } | |
| /// isProperSubClass - Returns true if RC has a legal super-class with more | |
| /// allocatable registers. | |
| /// | |
| /// Register classes like GR32_NOSP are not proper sub-classes because %esp | |
| /// is not allocatable. Similarly, tGPR is not a proper sub-class in Thumb | |
| /// mode because the GPR super-class is not legal. | |
| bool isProperSubClass(const TargetRegisterClass *RC) const { | |
| return get(RC).ProperSubClass; | |
| } | |
| /// getLastCalleeSavedAlias - Returns the last callee saved register that | |
| /// overlaps PhysReg, or 0 if Reg doesn't overlap a CSR. | |
| unsigned getLastCalleeSavedAlias(unsigned PhysReg) const { | |
| assert(TargetRegisterInfo::isPhysicalRegister(PhysReg)); | |
| if (unsigned N = CSRNum[PhysReg]) | |
| return CalleeSaved[N-1]; | |
| return 0; | |
| } | |
| /// isReserved - Returns true when PhysReg is a reserved register. | |
| /// | |
| /// Reserved registers may belong to an allocatable register class, but the | |
| /// target has explicitly requested that they are not used. | |
| /// | |
| bool isReserved(unsigned PhysReg) const { | |
| return Reserved.test(PhysReg); | |
| } | |
| /// isAllocatable - Returns true when PhysReg belongs to an allocatable | |
| /// register class and it hasn't been reserved. | |
| /// | |
| /// Allocatable registers may show up in the allocation order of some virtual | |
| /// register, so a register allocator needs to track its liveness and | |
| /// availability. | |
| bool isAllocatable(unsigned PhysReg) const { | |
| return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg); | |
| } | |
| }; | |
| } // end namespace llvm | |
| #endif | |