1 //===- RegisterClassInfo.h - Dynamic Register Class Info --------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the RegisterClassInfo class which provides dynamic 10 // information about target register classes. Callee saved and reserved 11 // registers depends on calling conventions and other dynamic information, so 12 // some things cannot be determined statically. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_CODEGEN_REGISTERCLASSINFO_H 17 #define LLVM_CODEGEN_REGISTERCLASSINFO_H 18 19 #include "llvm/ADT/ArrayRef.h" 20 #include "llvm/ADT/BitVector.h" 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/CodeGen/TargetRegisterInfo.h" 23 #include "llvm/MC/MCRegisterInfo.h" 24 #include <cassert> 25 #include <cstdint> 26 #include <memory> 27 28 namespace llvm { 29 30 class RegisterClassInfo { 31 struct RCInfo { 32 unsigned Tag = 0; 33 unsigned NumRegs = 0; 34 bool ProperSubClass = false; 35 uint8_t MinCost = 0; 36 uint16_t LastCostChange = 0; 37 std::unique_ptr<MCPhysReg[]> Order; 38 39 RCInfo() = default; 40 41 operator ArrayRef<MCPhysReg>() const { 42 return makeArrayRef(Order.get(), NumRegs); 43 } 44 }; 45 46 // Brief cached information for each register class. 47 std::unique_ptr<RCInfo[]> RegClass; 48 49 // Tag changes whenever cached information needs to be recomputed. An RCInfo 50 // entry is valid when its tag matches. 51 unsigned Tag = 0; 52 53 const MachineFunction *MF = nullptr; 54 const TargetRegisterInfo *TRI = nullptr; 55 56 // Callee saved registers of last MF. Assumed to be valid until the next 57 // runOnFunction() call. 58 // Used only to determine if an update was made to CalleeSavedAliases. 59 const MCPhysReg *CalleeSavedRegs = nullptr; 60 61 // Map register alias to the callee saved Register. 62 SmallVector<MCPhysReg, 4> CalleeSavedAliases; 63 64 // Reserved registers in the current MF. 65 BitVector Reserved; 66 67 std::unique_ptr<unsigned[]> PSetLimits; 68 69 // Compute all information about RC. 70 void compute(const TargetRegisterClass *RC) const; 71 72 // Return an up-to-date RCInfo for RC. get(const TargetRegisterClass * RC)73 const RCInfo &get(const TargetRegisterClass *RC) const { 74 const RCInfo &RCI = RegClass[RC->getID()]; 75 if (Tag != RCI.Tag) 76 compute(RC); 77 return RCI; 78 } 79 80 public: 81 RegisterClassInfo(); 82 83 /// runOnFunction - Prepare to answer questions about MF. This must be called 84 /// before any other methods are used. 85 void runOnMachineFunction(const MachineFunction &MF); 86 87 /// getNumAllocatableRegs - Returns the number of actually allocatable 88 /// registers in RC in the current function. getNumAllocatableRegs(const TargetRegisterClass * RC)89 unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const { 90 return get(RC).NumRegs; 91 } 92 93 /// getOrder - Returns the preferred allocation order for RC. The order 94 /// contains no reserved registers, and registers that alias callee saved 95 /// registers come last. getOrder(const TargetRegisterClass * RC)96 ArrayRef<MCPhysReg> getOrder(const TargetRegisterClass *RC) const { 97 return get(RC); 98 } 99 100 /// isProperSubClass - Returns true if RC has a legal super-class with more 101 /// allocatable registers. 102 /// 103 /// Register classes like GR32_NOSP are not proper sub-classes because %esp 104 /// is not allocatable. Similarly, tGPR is not a proper sub-class in Thumb 105 /// mode because the GPR super-class is not legal. isProperSubClass(const TargetRegisterClass * RC)106 bool isProperSubClass(const TargetRegisterClass *RC) const { 107 return get(RC).ProperSubClass; 108 } 109 110 /// getLastCalleeSavedAlias - Returns the last callee saved register that 111 /// overlaps PhysReg, or 0 if Reg doesn't overlap a CalleeSavedAliases. getLastCalleeSavedAlias(unsigned PhysReg)112 unsigned getLastCalleeSavedAlias(unsigned PhysReg) const { 113 assert(Register::isPhysicalRegister(PhysReg)); 114 if (PhysReg < CalleeSavedAliases.size()) 115 return CalleeSavedAliases[PhysReg]; 116 return 0; 117 } 118 119 /// Get the minimum register cost in RC's allocation order. 120 /// This is the smallest value returned by TRI->getCostPerUse(Reg) for all 121 /// the registers in getOrder(RC). getMinCost(const TargetRegisterClass * RC)122 unsigned getMinCost(const TargetRegisterClass *RC) { 123 return get(RC).MinCost; 124 } 125 126 /// Get the position of the last cost change in getOrder(RC). 127 /// 128 /// All registers in getOrder(RC).slice(getLastCostChange(RC)) will have the 129 /// same cost according to TRI->getCostPerUse(). getLastCostChange(const TargetRegisterClass * RC)130 unsigned getLastCostChange(const TargetRegisterClass *RC) { 131 return get(RC).LastCostChange; 132 } 133 134 /// Get the register unit limit for the given pressure set index. 135 /// 136 /// RegisterClassInfo adjusts this limit for reserved registers. getRegPressureSetLimit(unsigned Idx)137 unsigned getRegPressureSetLimit(unsigned Idx) const { 138 if (!PSetLimits[Idx]) 139 PSetLimits[Idx] = computePSetLimit(Idx); 140 return PSetLimits[Idx]; 141 } 142 143 protected: 144 unsigned computePSetLimit(unsigned Idx) const; 145 }; 146 147 } // end namespace llvm 148 149 #endif // LLVM_CODEGEN_REGISTERCLASSINFO_H 150