Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 1 | //===- LiveIntervals.h - Live Interval Analysis -----------------*- C++ -*-===// |
| 2 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 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 |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | /// \file This file implements the LiveInterval analysis pass. Given some |
| 10 | /// numbering of each the machine instructions (in this implemention depth-first |
| 11 | /// order) an interval [i, j) is said to be a live interval for register v if |
| 12 | /// there is no instruction with number j' > j such that v is live at j' and |
| 13 | /// there is no instruction with number i' < i such that v is live at i'. In |
| 14 | /// this implementation intervals can have holes, i.e. an interval might look |
| 15 | /// like [1,20), [50,65), [1000,1001). |
| 16 | // |
| 17 | //===----------------------------------------------------------------------===// |
| 18 | |
| 19 | #ifndef LLVM_CODEGEN_LIVEINTERVALS_H |
| 20 | #define LLVM_CODEGEN_LIVEINTERVALS_H |
| 21 | |
| 22 | #include "llvm/ADT/ArrayRef.h" |
| 23 | #include "llvm/ADT/IndexedMap.h" |
| 24 | #include "llvm/ADT/SmallVector.h" |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 25 | #include "llvm/CodeGen/LiveInterval.h" |
| 26 | #include "llvm/CodeGen/MachineBasicBlock.h" |
| 27 | #include "llvm/CodeGen/MachineFunctionPass.h" |
| 28 | #include "llvm/CodeGen/SlotIndexes.h" |
| 29 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
| 30 | #include "llvm/MC/LaneBitmask.h" |
| 31 | #include "llvm/Support/CommandLine.h" |
| 32 | #include "llvm/Support/Compiler.h" |
| 33 | #include "llvm/Support/ErrorHandling.h" |
| 34 | #include <cassert> |
| 35 | #include <cstdint> |
| 36 | #include <utility> |
| 37 | |
| 38 | namespace llvm { |
| 39 | |
| 40 | extern cl::opt<bool> UseSegmentSetForPhysRegs; |
| 41 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 42 | class AAResults; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 43 | class BitVector; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 44 | class LiveIntervalCalc; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 45 | class MachineBlockFrequencyInfo; |
| 46 | class MachineDominatorTree; |
| 47 | class MachineFunction; |
| 48 | class MachineInstr; |
| 49 | class MachineRegisterInfo; |
| 50 | class raw_ostream; |
| 51 | class TargetInstrInfo; |
| 52 | class VirtRegMap; |
| 53 | |
| 54 | class LiveIntervals : public MachineFunctionPass { |
| 55 | MachineFunction* MF; |
| 56 | MachineRegisterInfo* MRI; |
| 57 | const TargetRegisterInfo* TRI; |
| 58 | const TargetInstrInfo* TII; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 59 | AAResults *AA; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 60 | SlotIndexes* Indexes; |
| 61 | MachineDominatorTree *DomTree = nullptr; |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 62 | LiveIntervalCalc *LICalc = nullptr; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 63 | |
| 64 | /// Special pool allocator for VNInfo's (LiveInterval val#). |
| 65 | VNInfo::Allocator VNInfoAllocator; |
| 66 | |
| 67 | /// Live interval pointers for all the virtual registers. |
| 68 | IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals; |
| 69 | |
| 70 | /// Sorted list of instructions with register mask operands. Always use the |
| 71 | /// 'r' slot, RegMasks are normal clobbers, not early clobbers. |
| 72 | SmallVector<SlotIndex, 8> RegMaskSlots; |
| 73 | |
| 74 | /// This vector is parallel to RegMaskSlots, it holds a pointer to the |
| 75 | /// corresponding register mask. This pointer can be recomputed as: |
| 76 | /// |
| 77 | /// MI = Indexes->getInstructionFromIndex(RegMaskSlot[N]); |
| 78 | /// unsigned OpNum = findRegMaskOperand(MI); |
| 79 | /// RegMaskBits[N] = MI->getOperand(OpNum).getRegMask(); |
| 80 | /// |
| 81 | /// This is kept in a separate vector partly because some standard |
| 82 | /// libraries don't support lower_bound() with mixed objects, partly to |
| 83 | /// improve locality when searching in RegMaskSlots. |
| 84 | /// Also see the comment in LiveInterval::find(). |
| 85 | SmallVector<const uint32_t*, 8> RegMaskBits; |
| 86 | |
| 87 | /// For each basic block number, keep (begin, size) pairs indexing into the |
| 88 | /// RegMaskSlots and RegMaskBits arrays. |
| 89 | /// Note that basic block numbers may not be layout contiguous, that's why |
| 90 | /// we can't just keep track of the first register mask in each basic |
| 91 | /// block. |
| 92 | SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks; |
| 93 | |
| 94 | /// Keeps a live range set for each register unit to track fixed physreg |
| 95 | /// interference. |
| 96 | SmallVector<LiveRange*, 0> RegUnitRanges; |
| 97 | |
| 98 | public: |
| 99 | static char ID; |
| 100 | |
| 101 | LiveIntervals(); |
| 102 | ~LiveIntervals() override; |
| 103 | |
| 104 | /// Calculate the spill weight to assign to a single instruction. |
| 105 | static float getSpillWeight(bool isDef, bool isUse, |
| 106 | const MachineBlockFrequencyInfo *MBFI, |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 107 | const MachineInstr &MI); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 108 | |
| 109 | /// Calculate the spill weight to assign to a single instruction. |
| 110 | static float getSpillWeight(bool isDef, bool isUse, |
| 111 | const MachineBlockFrequencyInfo *MBFI, |
| 112 | const MachineBasicBlock *MBB); |
| 113 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 114 | LiveInterval &getInterval(Register Reg) { |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 115 | if (hasInterval(Reg)) |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 116 | return *VirtRegIntervals[Reg.id()]; |
| 117 | |
| 118 | return createAndComputeVirtRegInterval(Reg); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 119 | } |
| 120 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 121 | const LiveInterval &getInterval(Register Reg) const { |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 122 | return const_cast<LiveIntervals*>(this)->getInterval(Reg); |
| 123 | } |
| 124 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 125 | bool hasInterval(Register Reg) const { |
| 126 | return VirtRegIntervals.inBounds(Reg.id()) && |
| 127 | VirtRegIntervals[Reg.id()]; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | /// Interval creation. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 131 | LiveInterval &createEmptyInterval(Register Reg) { |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 132 | assert(!hasInterval(Reg) && "Interval already exists!"); |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 133 | VirtRegIntervals.grow(Reg.id()); |
| 134 | VirtRegIntervals[Reg.id()] = createInterval(Reg); |
| 135 | return *VirtRegIntervals[Reg.id()]; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 136 | } |
| 137 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 138 | LiveInterval &createAndComputeVirtRegInterval(Register Reg) { |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 139 | LiveInterval &LI = createEmptyInterval(Reg); |
| 140 | computeVirtRegInterval(LI); |
| 141 | return LI; |
| 142 | } |
| 143 | |
| 144 | /// Interval removal. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 145 | void removeInterval(Register Reg) { |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 146 | delete VirtRegIntervals[Reg]; |
| 147 | VirtRegIntervals[Reg] = nullptr; |
| 148 | } |
| 149 | |
| 150 | /// Given a register and an instruction, adds a live segment from that |
| 151 | /// instruction to the end of its MBB. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 152 | LiveInterval::Segment addSegmentToEndOfBlock(Register Reg, |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 153 | MachineInstr &startInst); |
| 154 | |
| 155 | /// After removing some uses of a register, shrink its live range to just |
| 156 | /// the remaining uses. This method does not compute reaching defs for new |
| 157 | /// uses, and it doesn't remove dead defs. |
| 158 | /// Dead PHIDef values are marked as unused. New dead machine instructions |
| 159 | /// are added to the dead vector. Returns true if the interval may have been |
| 160 | /// separated into multiple connected components. |
| 161 | bool shrinkToUses(LiveInterval *li, |
| 162 | SmallVectorImpl<MachineInstr*> *dead = nullptr); |
| 163 | |
| 164 | /// Specialized version of |
| 165 | /// shrinkToUses(LiveInterval *li, SmallVectorImpl<MachineInstr*> *dead) |
| 166 | /// that works on a subregister live range and only looks at uses matching |
| 167 | /// the lane mask of the subregister range. |
| 168 | /// This may leave the subrange empty which needs to be cleaned up with |
| 169 | /// LiveInterval::removeEmptySubranges() afterwards. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 170 | void shrinkToUses(LiveInterval::SubRange &SR, Register Reg); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 171 | |
| 172 | /// Extend the live range \p LR to reach all points in \p Indices. The |
| 173 | /// points in the \p Indices array must be jointly dominated by the union |
| 174 | /// of the existing defs in \p LR and points in \p Undefs. |
| 175 | /// |
| 176 | /// PHI-defs are added as needed to maintain SSA form. |
| 177 | /// |
| 178 | /// If a SlotIndex in \p Indices is the end index of a basic block, \p LR |
| 179 | /// will be extended to be live out of the basic block. |
| 180 | /// If a SlotIndex in \p Indices is jointy dominated only by points in |
| 181 | /// \p Undefs, the live range will not be extended to that point. |
| 182 | /// |
| 183 | /// See also LiveRangeCalc::extend(). |
| 184 | void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices, |
| 185 | ArrayRef<SlotIndex> Undefs); |
| 186 | |
| 187 | void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices) { |
| 188 | extendToIndices(LR, Indices, /*Undefs=*/{}); |
| 189 | } |
| 190 | |
| 191 | /// If \p LR has a live value at \p Kill, prune its live range by removing |
| 192 | /// any liveness reachable from Kill. Add live range end points to |
| 193 | /// EndPoints such that extendToIndices(LI, EndPoints) will reconstruct the |
| 194 | /// value's live range. |
| 195 | /// |
| 196 | /// Calling pruneValue() and extendToIndices() can be used to reconstruct |
| 197 | /// SSA form after adding defs to a virtual register. |
| 198 | void pruneValue(LiveRange &LR, SlotIndex Kill, |
| 199 | SmallVectorImpl<SlotIndex> *EndPoints); |
| 200 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 201 | /// This function should not be used. Its intent is to tell you that you are |
| 202 | /// doing something wrong if you call pruneValue directly on a |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 203 | /// LiveInterval. Indeed, you are supposed to call pruneValue on the main |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 204 | /// LiveRange and all the LiveRanges of the subranges if any. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 205 | LLVM_ATTRIBUTE_UNUSED void pruneValue(LiveInterval &, SlotIndex, |
| 206 | SmallVectorImpl<SlotIndex> *) { |
| 207 | llvm_unreachable( |
| 208 | "Use pruneValue on the main LiveRange and on each subrange"); |
| 209 | } |
| 210 | |
| 211 | SlotIndexes *getSlotIndexes() const { |
| 212 | return Indexes; |
| 213 | } |
| 214 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 215 | AAResults *getAliasAnalysis() const { |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 216 | return AA; |
| 217 | } |
| 218 | |
| 219 | /// Returns true if the specified machine instr has been removed or was |
| 220 | /// never entered in the map. |
| 221 | bool isNotInMIMap(const MachineInstr &Instr) const { |
| 222 | return !Indexes->hasIndex(Instr); |
| 223 | } |
| 224 | |
| 225 | /// Returns the base index of the given instruction. |
| 226 | SlotIndex getInstructionIndex(const MachineInstr &Instr) const { |
| 227 | return Indexes->getInstructionIndex(Instr); |
| 228 | } |
| 229 | |
| 230 | /// Returns the instruction associated with the given index. |
| 231 | MachineInstr* getInstructionFromIndex(SlotIndex index) const { |
| 232 | return Indexes->getInstructionFromIndex(index); |
| 233 | } |
| 234 | |
| 235 | /// Return the first index in the given basic block. |
| 236 | SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const { |
| 237 | return Indexes->getMBBStartIdx(mbb); |
| 238 | } |
| 239 | |
| 240 | /// Return the last index in the given basic block. |
| 241 | SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const { |
| 242 | return Indexes->getMBBEndIdx(mbb); |
| 243 | } |
| 244 | |
| 245 | bool isLiveInToMBB(const LiveRange &LR, |
| 246 | const MachineBasicBlock *mbb) const { |
| 247 | return LR.liveAt(getMBBStartIdx(mbb)); |
| 248 | } |
| 249 | |
| 250 | bool isLiveOutOfMBB(const LiveRange &LR, |
| 251 | const MachineBasicBlock *mbb) const { |
| 252 | return LR.liveAt(getMBBEndIdx(mbb).getPrevSlot()); |
| 253 | } |
| 254 | |
| 255 | MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { |
| 256 | return Indexes->getMBBFromIndex(index); |
| 257 | } |
| 258 | |
| 259 | void insertMBBInMaps(MachineBasicBlock *MBB) { |
| 260 | Indexes->insertMBBInMaps(MBB); |
| 261 | assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() && |
| 262 | "Blocks must be added in order."); |
| 263 | RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0)); |
| 264 | } |
| 265 | |
| 266 | SlotIndex InsertMachineInstrInMaps(MachineInstr &MI) { |
| 267 | return Indexes->insertMachineInstrInMaps(MI); |
| 268 | } |
| 269 | |
| 270 | void InsertMachineInstrRangeInMaps(MachineBasicBlock::iterator B, |
| 271 | MachineBasicBlock::iterator E) { |
| 272 | for (MachineBasicBlock::iterator I = B; I != E; ++I) |
| 273 | Indexes->insertMachineInstrInMaps(*I); |
| 274 | } |
| 275 | |
| 276 | void RemoveMachineInstrFromMaps(MachineInstr &MI) { |
| 277 | Indexes->removeMachineInstrFromMaps(MI); |
| 278 | } |
| 279 | |
| 280 | SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI) { |
| 281 | return Indexes->replaceMachineInstrInMaps(MI, NewMI); |
| 282 | } |
| 283 | |
| 284 | VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; } |
| 285 | |
| 286 | void getAnalysisUsage(AnalysisUsage &AU) const override; |
| 287 | void releaseMemory() override; |
| 288 | |
| 289 | /// Pass entry point; Calculates LiveIntervals. |
| 290 | bool runOnMachineFunction(MachineFunction&) override; |
| 291 | |
| 292 | /// Implement the dump method. |
| 293 | void print(raw_ostream &O, const Module* = nullptr) const override; |
| 294 | |
| 295 | /// If LI is confined to a single basic block, return a pointer to that |
| 296 | /// block. If LI is live in to or out of any block, return NULL. |
| 297 | MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const; |
| 298 | |
| 299 | /// Returns true if VNI is killed by any PHI-def values in LI. |
| 300 | /// This may conservatively return true to avoid expensive computations. |
| 301 | bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const; |
| 302 | |
| 303 | /// Add kill flags to any instruction that kills a virtual register. |
| 304 | void addKillFlags(const VirtRegMap*); |
| 305 | |
| 306 | /// Call this method to notify LiveIntervals that instruction \p MI has been |
| 307 | /// moved within a basic block. This will update the live intervals for all |
| 308 | /// operands of \p MI. Moves between basic blocks are not supported. |
| 309 | /// |
| 310 | /// \param UpdateFlags Update live intervals for nonallocatable physregs. |
| 311 | void handleMove(MachineInstr &MI, bool UpdateFlags = false); |
| 312 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 313 | /// Update intervals of operands of all instructions in the newly |
| 314 | /// created bundle specified by \p BundleStart. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 315 | /// |
| 316 | /// \param UpdateFlags Update live intervals for nonallocatable physregs. |
| 317 | /// |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 318 | /// Assumes existing liveness is accurate. |
| 319 | /// \pre BundleStart should be the first instruction in the Bundle. |
| 320 | /// \pre BundleStart should not have a have SlotIndex as one will be assigned. |
| 321 | void handleMoveIntoNewBundle(MachineInstr &BundleStart, |
| 322 | bool UpdateFlags = false); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 323 | |
| 324 | /// Update live intervals for instructions in a range of iterators. It is |
| 325 | /// intended for use after target hooks that may insert or remove |
| 326 | /// instructions, and is only efficient for a small number of instructions. |
| 327 | /// |
| 328 | /// OrigRegs is a vector of registers that were originally used by the |
| 329 | /// instructions in the range between the two iterators. |
| 330 | /// |
| 331 | /// Currently, the only only changes that are supported are simple removal |
| 332 | /// and addition of uses. |
| 333 | void repairIntervalsInRange(MachineBasicBlock *MBB, |
| 334 | MachineBasicBlock::iterator Begin, |
| 335 | MachineBasicBlock::iterator End, |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 336 | ArrayRef<Register> OrigRegs); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 337 | |
| 338 | // Register mask functions. |
| 339 | // |
| 340 | // Machine instructions may use a register mask operand to indicate that a |
| 341 | // large number of registers are clobbered by the instruction. This is |
| 342 | // typically used for calls. |
| 343 | // |
| 344 | // For compile time performance reasons, these clobbers are not recorded in |
| 345 | // the live intervals for individual physical registers. Instead, |
| 346 | // LiveIntervalAnalysis maintains a sorted list of instructions with |
| 347 | // register mask operands. |
| 348 | |
| 349 | /// Returns a sorted array of slot indices of all instructions with |
| 350 | /// register mask operands. |
| 351 | ArrayRef<SlotIndex> getRegMaskSlots() const { return RegMaskSlots; } |
| 352 | |
| 353 | /// Returns a sorted array of slot indices of all instructions with register |
| 354 | /// mask operands in the basic block numbered \p MBBNum. |
| 355 | ArrayRef<SlotIndex> getRegMaskSlotsInBlock(unsigned MBBNum) const { |
| 356 | std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum]; |
| 357 | return getRegMaskSlots().slice(P.first, P.second); |
| 358 | } |
| 359 | |
| 360 | /// Returns an array of register mask pointers corresponding to |
| 361 | /// getRegMaskSlots(). |
| 362 | ArrayRef<const uint32_t*> getRegMaskBits() const { return RegMaskBits; } |
| 363 | |
| 364 | /// Returns an array of mask pointers corresponding to |
| 365 | /// getRegMaskSlotsInBlock(MBBNum). |
| 366 | ArrayRef<const uint32_t*> getRegMaskBitsInBlock(unsigned MBBNum) const { |
| 367 | std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum]; |
| 368 | return getRegMaskBits().slice(P.first, P.second); |
| 369 | } |
| 370 | |
| 371 | /// Test if \p LI is live across any register mask instructions, and |
| 372 | /// compute a bit mask of physical registers that are not clobbered by any |
| 373 | /// of them. |
| 374 | /// |
| 375 | /// Returns false if \p LI doesn't cross any register mask instructions. In |
| 376 | /// that case, the bit vector is not filled in. |
| 377 | bool checkRegMaskInterference(LiveInterval &LI, |
| 378 | BitVector &UsableRegs); |
| 379 | |
| 380 | // Register unit functions. |
| 381 | // |
| 382 | // Fixed interference occurs when MachineInstrs use physregs directly |
| 383 | // instead of virtual registers. This typically happens when passing |
| 384 | // arguments to a function call, or when instructions require operands in |
| 385 | // fixed registers. |
| 386 | // |
| 387 | // Each physreg has one or more register units, see MCRegisterInfo. We |
| 388 | // track liveness per register unit to handle aliasing registers more |
| 389 | // efficiently. |
| 390 | |
| 391 | /// Return the live range for register unit \p Unit. It will be computed if |
| 392 | /// it doesn't exist. |
| 393 | LiveRange &getRegUnit(unsigned Unit) { |
| 394 | LiveRange *LR = RegUnitRanges[Unit]; |
| 395 | if (!LR) { |
| 396 | // Compute missing ranges on demand. |
| 397 | // Use segment set to speed-up initial computation of the live range. |
| 398 | RegUnitRanges[Unit] = LR = new LiveRange(UseSegmentSetForPhysRegs); |
| 399 | computeRegUnitRange(*LR, Unit); |
| 400 | } |
| 401 | return *LR; |
| 402 | } |
| 403 | |
| 404 | /// Return the live range for register unit \p Unit if it has already been |
| 405 | /// computed, or nullptr if it hasn't been computed yet. |
| 406 | LiveRange *getCachedRegUnit(unsigned Unit) { |
| 407 | return RegUnitRanges[Unit]; |
| 408 | } |
| 409 | |
| 410 | const LiveRange *getCachedRegUnit(unsigned Unit) const { |
| 411 | return RegUnitRanges[Unit]; |
| 412 | } |
| 413 | |
| 414 | /// Remove computed live range for register unit \p Unit. Subsequent uses |
| 415 | /// should rely on on-demand recomputation. |
| 416 | void removeRegUnit(unsigned Unit) { |
| 417 | delete RegUnitRanges[Unit]; |
| 418 | RegUnitRanges[Unit] = nullptr; |
| 419 | } |
| 420 | |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 421 | /// Remove associated live ranges for the register units associated with \p |
| 422 | /// Reg. Subsequent uses should rely on on-demand recomputation. \note This |
| 423 | /// method can result in inconsistent liveness tracking if multiple phyical |
| 424 | /// registers share a regunit, and should be used cautiously. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 425 | void removeAllRegUnitsForPhysReg(MCRegister Reg) { |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 426 | for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) |
| 427 | removeRegUnit(*Units); |
| 428 | } |
| 429 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 430 | /// Remove value numbers and related live segments starting at position |
| 431 | /// \p Pos that are part of any liverange of physical register \p Reg or one |
| 432 | /// of its subregisters. |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 433 | void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 434 | |
| 435 | /// Remove value number and related live segments of \p LI and its subranges |
| 436 | /// that start at position \p Pos. |
| 437 | void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos); |
| 438 | |
| 439 | /// Split separate components in LiveInterval \p LI into separate intervals. |
| 440 | void splitSeparateComponents(LiveInterval &LI, |
| 441 | SmallVectorImpl<LiveInterval*> &SplitLIs); |
| 442 | |
| 443 | /// For live interval \p LI with correct SubRanges construct matching |
| 444 | /// information for the main live range. Expects the main live range to not |
| 445 | /// have any segments or value numbers. |
| 446 | void constructMainRangeFromSubranges(LiveInterval &LI); |
| 447 | |
| 448 | private: |
| 449 | /// Compute live intervals for all virtual registers. |
| 450 | void computeVirtRegs(); |
| 451 | |
| 452 | /// Compute RegMaskSlots and RegMaskBits. |
| 453 | void computeRegMasks(); |
| 454 | |
| 455 | /// Walk the values in \p LI and check for dead values: |
| 456 | /// - Dead PHIDef values are marked as unused. |
| 457 | /// - Dead operands are marked as such. |
| 458 | /// - Completely dead machine instructions are added to the \p dead vector |
| 459 | /// if it is not nullptr. |
| 460 | /// Returns true if any PHI value numbers have been removed which may |
| 461 | /// have separated the interval into multiple connected components. |
| 462 | bool computeDeadValues(LiveInterval &LI, |
| 463 | SmallVectorImpl<MachineInstr*> *dead); |
| 464 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 465 | static LiveInterval *createInterval(Register Reg); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 466 | |
| 467 | void printInstrs(raw_ostream &O) const; |
| 468 | void dumpInstrs() const; |
| 469 | |
| 470 | void computeLiveInRegUnits(); |
| 471 | void computeRegUnitRange(LiveRange&, unsigned Unit); |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 472 | bool computeVirtRegInterval(LiveInterval&); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 473 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 474 | using ShrinkToUsesWorkList = SmallVector<std::pair<SlotIndex, VNInfo*>, 16>; |
| 475 | void extendSegmentsToUses(LiveRange &Segments, |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 476 | ShrinkToUsesWorkList &WorkList, Register Reg, |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 477 | LaneBitmask LaneMask); |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 478 | |
| 479 | /// Helper function for repairIntervalsInRange(), walks backwards and |
| 480 | /// creates/modifies live segments in \p LR to match the operands found. |
| 481 | /// Only full operands or operands with subregisters matching \p LaneMask |
| 482 | /// are considered. |
| 483 | void repairOldRegInRange(MachineBasicBlock::iterator Begin, |
| 484 | MachineBasicBlock::iterator End, |
| 485 | const SlotIndex endIdx, LiveRange &LR, |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame^] | 486 | Register Reg, |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 487 | LaneBitmask LaneMask = LaneBitmask::getAll()); |
| 488 | |
| 489 | class HMEditor; |
| 490 | }; |
| 491 | |
| 492 | } // end namespace llvm |
| 493 | |
| 494 | #endif |