| //===-- 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 |
| |