1 //===- llvm/CodeGen/LiveRegUnits.h - Register Unit Set ----------*- 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 /// \file 10 /// A set of register units. It is intended for register liveness tracking. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CODEGEN_LIVEREGUNITS_H 15 #define LLVM_CODEGEN_LIVEREGUNITS_H 16 17 #include "llvm/ADT/BitVector.h" 18 #include "llvm/CodeGen/MachineInstrBundle.h" 19 #include "llvm/CodeGen/TargetRegisterInfo.h" 20 #include "llvm/MC/LaneBitmask.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include <cstdint> 23 24 namespace llvm { 25 26 class MachineInstr; 27 class MachineBasicBlock; 28 29 /// A set of register units used to track register liveness. 30 class LiveRegUnits { 31 const TargetRegisterInfo *TRI = nullptr; 32 BitVector Units; 33 34 public: 35 /// Constructs a new empty LiveRegUnits set. 36 LiveRegUnits() = default; 37 38 /// Constructs and initialize an empty LiveRegUnits set. 39 LiveRegUnits(const TargetRegisterInfo &TRI) { 40 init(TRI); 41 } 42 43 /// For a machine instruction \p MI, adds all register units used in 44 /// \p UsedRegUnits and defined or clobbered in \p ModifiedRegUnits. This is 45 /// useful when walking over a range of instructions to track registers 46 /// used or defined seperately. 47 static void accumulateUsedDefed(const MachineInstr &MI, 48 LiveRegUnits &ModifiedRegUnits, 49 LiveRegUnits &UsedRegUnits, 50 const TargetRegisterInfo *TRI) { 51 for (ConstMIBundleOperands O(MI); O.isValid(); ++O) { 52 if (O->isRegMask()) 53 ModifiedRegUnits.addRegsInMask(O->getRegMask()); 54 if (!O->isReg()) 55 continue; 56 Register Reg = O->getReg(); 57 if (!Reg.isPhysical()) 58 continue; 59 if (O->isDef()) { 60 // Some architectures (e.g. AArch64 XZR/WZR) have registers that are 61 // constant and may be used as destinations to indicate the generated 62 // value is discarded. No need to track such case as a def. 63 if (!TRI->isConstantPhysReg(Reg)) 64 ModifiedRegUnits.addReg(Reg); 65 } else { 66 assert(O->isUse() && "Reg operand not a def and not a use"); 67 UsedRegUnits.addReg(Reg); 68 } 69 } 70 } 71 72 /// Initialize and clear the set. 73 void init(const TargetRegisterInfo &TRI) { 74 this->TRI = &TRI; 75 Units.reset(); 76 Units.resize(TRI.getNumRegUnits()); 77 } 78 79 /// Clears the set. 80 void clear() { Units.reset(); } 81 82 /// Returns true if the set is empty. 83 bool empty() const { return Units.none(); } 84 85 /// Adds register units covered by physical register \p Reg. 86 void addReg(MCPhysReg Reg) { 87 for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) 88 Units.set(*Unit); 89 } 90 91 /// Adds register units covered by physical register \p Reg that are 92 /// part of the lanemask \p Mask. 93 void addRegMasked(MCPhysReg Reg, LaneBitmask Mask) { 94 for (MCRegUnitMaskIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) { 95 LaneBitmask UnitMask = (*Unit).second; 96 if (UnitMask.none() || (UnitMask & Mask).any()) 97 Units.set((*Unit).first); 98 } 99 } 100 101 /// Removes all register units covered by physical register \p Reg. 102 void removeReg(MCPhysReg Reg) { 103 for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) 104 Units.reset(*Unit); 105 } 106 107 /// Removes register units not preserved by the regmask \p RegMask. 108 /// The regmask has the same format as the one in the RegMask machine operand. 109 void removeRegsNotPreserved(const uint32_t *RegMask); 110 111 /// Adds register units not preserved by the regmask \p RegMask. 112 /// The regmask has the same format as the one in the RegMask machine operand. 113 void addRegsInMask(const uint32_t *RegMask); 114 115 /// Returns true if no part of physical register \p Reg is live. 116 bool available(MCPhysReg Reg) const { 117 for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) { 118 if (Units.test(*Unit)) 119 return false; 120 } 121 return true; 122 } 123 124 /// Updates liveness when stepping backwards over the instruction \p MI. 125 /// This removes all register units defined or clobbered in \p MI and then 126 /// adds the units used (as in use operands) in \p MI. 127 void stepBackward(const MachineInstr &MI); 128 129 /// Adds all register units used, defined or clobbered in \p MI. 130 /// This is useful when walking over a range of instruction to find registers 131 /// unused over the whole range. 132 void accumulate(const MachineInstr &MI); 133 134 /// Adds registers living out of block \p MBB. 135 /// Live out registers are the union of the live-in registers of the successor 136 /// blocks and pristine registers. Live out registers of the end block are the 137 /// callee saved registers. 138 void addLiveOuts(const MachineBasicBlock &MBB); 139 140 /// Adds registers living into block \p MBB. 141 void addLiveIns(const MachineBasicBlock &MBB); 142 143 /// Adds all register units marked in the bitvector \p RegUnits. 144 void addUnits(const BitVector &RegUnits) { 145 Units |= RegUnits; 146 } 147 /// Removes all register units marked in the bitvector \p RegUnits. 148 void removeUnits(const BitVector &RegUnits) { 149 Units.reset(RegUnits); 150 } 151 /// Return the internal bitvector representation of the set. 152 const BitVector &getBitVector() const { 153 return Units; 154 } 155 156 private: 157 /// Adds pristine registers. Pristine registers are callee saved registers 158 /// that are unused in the function. 159 void addPristines(const MachineFunction &MF); 160 }; 161 162 /// Returns an iterator range over all physical register and mask operands for 163 /// \p MI and bundled instructions. This also skips any debug operands. 164 inline iterator_range<filter_iterator< 165 ConstMIBundleOperands, std::function<bool(const MachineOperand &)>>> 166 phys_regs_and_masks(const MachineInstr &MI) { 167 std::function<bool(const MachineOperand &)> Pred = 168 [](const MachineOperand &MOP) { 169 return MOP.isRegMask() || (MOP.isReg() && !MOP.isDebug() && 170 Register::isPhysicalRegister(MOP.getReg())); 171 }; 172 return make_filter_range(const_mi_bundle_ops(MI), Pred); 173 } 174 175 } // end namespace llvm 176 177 #endif // LLVM_CODEGEN_LIVEREGUNITS_H 178