| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 1 | //===-- RenameIndependentSubregs.cpp - Live Interval Analysis -------------===// | 
|  | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [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 | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 | // | 
|  | 9 | /// Rename independent subregisters looks for virtual registers with | 
|  | 10 | /// independently used subregisters and renames them to new virtual registers. | 
|  | 11 | /// Example: In the following: | 
| Francis Visoiu Mistrih | 93ef145 | 2017-11-30 12:12:19 +0000 | [diff] [blame] | 12 | ///   %0:sub0<read-undef> = ... | 
|  | 13 | ///   %0:sub1 = ... | 
|  | 14 | ///   use %0:sub0 | 
|  | 15 | ///   %0:sub0 = ... | 
|  | 16 | ///   use %0:sub0 | 
|  | 17 | ///   use %0:sub1 | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 18 | /// sub0 and sub1 are never used together, and we have two independent sub0 | 
|  | 19 | /// definitions. This pass will rename to: | 
| Francis Visoiu Mistrih | 93ef145 | 2017-11-30 12:12:19 +0000 | [diff] [blame] | 20 | ///   %0:sub0<read-undef> = ... | 
|  | 21 | ///   %1:sub1<read-undef> = ... | 
|  | 22 | ///   use %1:sub1 | 
|  | 23 | ///   %2:sub1<read-undef> = ... | 
|  | 24 | ///   use %2:sub1 | 
|  | 25 | ///   use %0:sub0 | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 26 | // | 
|  | 27 | //===----------------------------------------------------------------------===// | 
|  | 28 |  | 
|  | 29 | #include "LiveRangeUtils.h" | 
|  | 30 | #include "PHIEliminationUtils.h" | 
|  | 31 | #include "llvm/CodeGen/LiveInterval.h" | 
| Matthias Braun | f842297 | 2017-12-13 02:51:04 +0000 | [diff] [blame] | 32 | #include "llvm/CodeGen/LiveIntervals.h" | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 33 | #include "llvm/CodeGen/MachineFunctionPass.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 34 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 35 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
|  | 36 | #include "llvm/CodeGen/Passes.h" | 
| David Blaikie | 3f833ed | 2017-11-08 01:01:31 +0000 | [diff] [blame] | 37 | #include "llvm/CodeGen/TargetInstrInfo.h" | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 38 |  | 
|  | 39 | using namespace llvm; | 
|  | 40 |  | 
|  | 41 | #define DEBUG_TYPE "rename-independent-subregs" | 
|  | 42 |  | 
|  | 43 | namespace { | 
|  | 44 |  | 
|  | 45 | class RenameIndependentSubregs : public MachineFunctionPass { | 
|  | 46 | public: | 
|  | 47 | static char ID; | 
|  | 48 | RenameIndependentSubregs() : MachineFunctionPass(ID) {} | 
|  | 49 |  | 
| Mehdi Amini | 117296c | 2016-10-01 02:56:57 +0000 | [diff] [blame] | 50 | StringRef getPassName() const override { | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 51 | return "Rename Disconnected Subregister Components"; | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | void getAnalysisUsage(AnalysisUsage &AU) const override { | 
|  | 55 | AU.setPreservesCFG(); | 
|  | 56 | AU.addRequired<LiveIntervals>(); | 
|  | 57 | AU.addPreserved<LiveIntervals>(); | 
|  | 58 | AU.addRequired<SlotIndexes>(); | 
|  | 59 | AU.addPreserved<SlotIndexes>(); | 
|  | 60 | MachineFunctionPass::getAnalysisUsage(AU); | 
|  | 61 | } | 
|  | 62 |  | 
|  | 63 | bool runOnMachineFunction(MachineFunction &MF) override; | 
|  | 64 |  | 
|  | 65 | private: | 
|  | 66 | struct SubRangeInfo { | 
|  | 67 | ConnectedVNInfoEqClasses ConEQ; | 
|  | 68 | LiveInterval::SubRange *SR; | 
|  | 69 | unsigned Index; | 
|  | 70 |  | 
|  | 71 | SubRangeInfo(LiveIntervals &LIS, LiveInterval::SubRange &SR, | 
|  | 72 | unsigned Index) | 
|  | 73 | : ConEQ(LIS), SR(&SR), Index(Index) {} | 
|  | 74 | }; | 
|  | 75 |  | 
|  | 76 | /// Split unrelated subregister components and rename them to new vregs. | 
|  | 77 | bool renameComponents(LiveInterval &LI) const; | 
|  | 78 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 79 | /// Build a vector of SubRange infos and a union find set of | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 80 | /// equivalence classes. | 
|  | 81 | /// Returns true if more than 1 equivalence class was found. | 
|  | 82 | bool findComponents(IntEqClasses &Classes, | 
|  | 83 | SmallVectorImpl<SubRangeInfo> &SubRangeInfos, | 
|  | 84 | LiveInterval &LI) const; | 
|  | 85 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 86 | /// Distribute the LiveInterval segments into the new LiveIntervals | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 87 | /// belonging to their class. | 
|  | 88 | void distribute(const IntEqClasses &Classes, | 
|  | 89 | const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, | 
|  | 90 | const SmallVectorImpl<LiveInterval*> &Intervals) const; | 
|  | 91 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 92 | /// Constructs main liverange and add missing undef+dead flags. | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 93 | void computeMainRangesFixFlags(const IntEqClasses &Classes, | 
|  | 94 | const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, | 
|  | 95 | const SmallVectorImpl<LiveInterval*> &Intervals) const; | 
|  | 96 |  | 
|  | 97 | /// Rewrite Machine Operands to use the new vreg belonging to their class. | 
|  | 98 | void rewriteOperands(const IntEqClasses &Classes, | 
|  | 99 | const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, | 
|  | 100 | const SmallVectorImpl<LiveInterval*> &Intervals) const; | 
|  | 101 |  | 
|  | 102 |  | 
|  | 103 | LiveIntervals *LIS; | 
|  | 104 | MachineRegisterInfo *MRI; | 
|  | 105 | const TargetInstrInfo *TII; | 
|  | 106 | }; | 
|  | 107 |  | 
|  | 108 | } // end anonymous namespace | 
|  | 109 |  | 
|  | 110 | char RenameIndependentSubregs::ID; | 
|  | 111 |  | 
|  | 112 | char &llvm::RenameIndependentSubregsID = RenameIndependentSubregs::ID; | 
|  | 113 |  | 
| Matthias Braun | 1527baa | 2017-05-25 21:26:32 +0000 | [diff] [blame] | 114 | INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, DEBUG_TYPE, | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 115 | "Rename Independent Subregisters", false, false) | 
|  | 116 | INITIALIZE_PASS_DEPENDENCY(SlotIndexes) | 
|  | 117 | INITIALIZE_PASS_DEPENDENCY(LiveIntervals) | 
| Matthias Braun | 1527baa | 2017-05-25 21:26:32 +0000 | [diff] [blame] | 118 | INITIALIZE_PASS_END(RenameIndependentSubregs, DEBUG_TYPE, | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 119 | "Rename Independent Subregisters", false, false) | 
|  | 120 |  | 
|  | 121 | bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const { | 
|  | 122 | // Shortcut: We cannot have split components with a single definition. | 
|  | 123 | if (LI.valnos.size() < 2) | 
|  | 124 | return false; | 
|  | 125 |  | 
|  | 126 | SmallVector<SubRangeInfo, 4> SubRangeInfos; | 
|  | 127 | IntEqClasses Classes; | 
|  | 128 | if (!findComponents(Classes, SubRangeInfos, LI)) | 
|  | 129 | return false; | 
|  | 130 |  | 
|  | 131 | // Create a new VReg for each class. | 
|  | 132 | unsigned Reg = LI.reg; | 
|  | 133 | const TargetRegisterClass *RegClass = MRI->getRegClass(Reg); | 
|  | 134 | SmallVector<LiveInterval*, 4> Intervals; | 
|  | 135 | Intervals.push_back(&LI); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 136 | LLVM_DEBUG(dbgs() << printReg(Reg) << ": Found " << Classes.getNumClasses() | 
|  | 137 | << " equivalence classes.\n"); | 
|  | 138 | LLVM_DEBUG(dbgs() << printReg(Reg) << ": Splitting into newly created:"); | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 139 | for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses; | 
|  | 140 | ++I) { | 
|  | 141 | unsigned NewVReg = MRI->createVirtualRegister(RegClass); | 
|  | 142 | LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg); | 
|  | 143 | Intervals.push_back(&NewLI); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 144 | LLVM_DEBUG(dbgs() << ' ' << printReg(NewVReg)); | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 145 | } | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 146 | LLVM_DEBUG(dbgs() << '\n'); | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 147 |  | 
|  | 148 | rewriteOperands(Classes, SubRangeInfos, Intervals); | 
|  | 149 | distribute(Classes, SubRangeInfos, Intervals); | 
|  | 150 | computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals); | 
|  | 151 | return true; | 
|  | 152 | } | 
|  | 153 |  | 
|  | 154 | bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes, | 
|  | 155 | SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos, | 
|  | 156 | LiveInterval &LI) const { | 
|  | 157 | // First step: Create connected components for the VNInfos inside the | 
|  | 158 | // subranges and count the global number of such components. | 
|  | 159 | unsigned NumComponents = 0; | 
|  | 160 | for (LiveInterval::SubRange &SR : LI.subranges()) { | 
|  | 161 | SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents)); | 
|  | 162 | ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ; | 
|  | 163 |  | 
|  | 164 | unsigned NumSubComponents = ConEQ.Classify(SR); | 
|  | 165 | NumComponents += NumSubComponents; | 
|  | 166 | } | 
|  | 167 | // Shortcut: With only 1 subrange, the normal separate component tests are | 
|  | 168 | // enough and we do not need to perform the union-find on the subregister | 
|  | 169 | // segments. | 
|  | 170 | if (SubRangeInfos.size() < 2) | 
|  | 171 | return false; | 
|  | 172 |  | 
|  | 173 | // Next step: Build union-find structure over all subranges and merge classes | 
|  | 174 | // across subranges when they are affected by the same MachineOperand. | 
|  | 175 | const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); | 
|  | 176 | Classes.grow(NumComponents); | 
|  | 177 | unsigned Reg = LI.reg; | 
|  | 178 | for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) { | 
|  | 179 | if (!MO.isDef() && !MO.readsReg()) | 
|  | 180 | continue; | 
|  | 181 | unsigned SubRegIdx = MO.getSubReg(); | 
|  | 182 | LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx); | 
|  | 183 | unsigned MergedID = ~0u; | 
|  | 184 | for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) { | 
|  | 185 | const LiveInterval::SubRange &SR = *SRInfo.SR; | 
| Krzysztof Parzyszek | 91b5cf8 | 2016-12-15 14:36:06 +0000 | [diff] [blame] | 186 | if ((SR.LaneMask & LaneMask).none()) | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 187 | continue; | 
|  | 188 | SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()); | 
|  | 189 | Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber()) | 
|  | 190 | : Pos.getBaseIndex(); | 
|  | 191 | const VNInfo *VNI = SR.getVNInfoAt(Pos); | 
|  | 192 | if (VNI == nullptr) | 
|  | 193 | continue; | 
|  | 194 |  | 
|  | 195 | // Map to local representant ID. | 
|  | 196 | unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI); | 
|  | 197 | // Global ID | 
|  | 198 | unsigned ID = LocalID + SRInfo.Index; | 
|  | 199 | // Merge other sets | 
|  | 200 | MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID); | 
|  | 201 | } | 
|  | 202 | } | 
|  | 203 |  | 
|  | 204 | // Early exit if we ended up with a single equivalence class. | 
|  | 205 | Classes.compress(); | 
|  | 206 | unsigned NumClasses = Classes.getNumClasses(); | 
|  | 207 | return NumClasses > 1; | 
|  | 208 | } | 
|  | 209 |  | 
|  | 210 | void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes, | 
|  | 211 | const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, | 
|  | 212 | const SmallVectorImpl<LiveInterval*> &Intervals) const { | 
|  | 213 | const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo(); | 
| Matt Arsenault | 540d133 | 2017-06-05 23:01:31 +0000 | [diff] [blame] | 214 | unsigned Reg = Intervals[0]->reg; | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 215 | for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg), | 
|  | 216 | E = MRI->reg_nodbg_end(); I != E; ) { | 
|  | 217 | MachineOperand &MO = *I++; | 
|  | 218 | if (!MO.isDef() && !MO.readsReg()) | 
|  | 219 | continue; | 
|  | 220 |  | 
| Mark Searles | 7139dea | 2018-07-09 20:07:03 +0000 | [diff] [blame] | 221 | auto *MI = MO.getParent(); | 
|  | 222 | SlotIndex Pos = LIS->getInstructionIndex(*MI); | 
| Matthias Braun | 1873998 | 2016-08-03 22:37:47 +0000 | [diff] [blame] | 223 | Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber()) | 
|  | 224 | : Pos.getBaseIndex(); | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 225 | unsigned SubRegIdx = MO.getSubReg(); | 
|  | 226 | LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx); | 
|  | 227 |  | 
|  | 228 | unsigned ID = ~0u; | 
|  | 229 | for (const SubRangeInfo &SRInfo : SubRangeInfos) { | 
|  | 230 | const LiveInterval::SubRange &SR = *SRInfo.SR; | 
| Krzysztof Parzyszek | 91b5cf8 | 2016-12-15 14:36:06 +0000 | [diff] [blame] | 231 | if ((SR.LaneMask & LaneMask).none()) | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 232 | continue; | 
| Matthias Braun | 1873998 | 2016-08-03 22:37:47 +0000 | [diff] [blame] | 233 | const VNInfo *VNI = SR.getVNInfoAt(Pos); | 
|  | 234 | if (VNI == nullptr) | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 235 | continue; | 
|  | 236 |  | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 237 | // Map to local representant ID. | 
| Matthias Braun | 1873998 | 2016-08-03 22:37:47 +0000 | [diff] [blame] | 238 | unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI); | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 239 | // Global ID | 
|  | 240 | ID = Classes[LocalID + SRInfo.Index]; | 
|  | 241 | break; | 
|  | 242 | } | 
|  | 243 |  | 
|  | 244 | unsigned VReg = Intervals[ID]->reg; | 
|  | 245 | MO.setReg(VReg); | 
| Matt Arsenault | 836d786 | 2017-06-27 18:28:10 +0000 | [diff] [blame] | 246 |  | 
|  | 247 | if (MO.isTied() && Reg != VReg) { | 
| Mark Searles | 7139dea | 2018-07-09 20:07:03 +0000 | [diff] [blame] | 248 | /// Undef use operands are not tracked in the equivalence class, | 
|  | 249 | /// but need to be updated if they are tied; take care to only | 
|  | 250 | /// update the tied operand. | 
|  | 251 | unsigned OperandNo = MI->getOperandNo(&MO); | 
|  | 252 | unsigned TiedIdx = MI->findTiedOperandIdx(OperandNo); | 
|  | 253 | MI->getOperand(TiedIdx).setReg(VReg); | 
| Matt Arsenault | 53fae07 | 2017-06-26 21:33:36 +0000 | [diff] [blame] | 254 |  | 
| Mark Searles | 7139dea | 2018-07-09 20:07:03 +0000 | [diff] [blame] | 255 | // above substitution breaks the iterator, so restart. | 
| Matt Arsenault | 53fae07 | 2017-06-26 21:33:36 +0000 | [diff] [blame] | 256 | I = MRI->reg_nodbg_begin(Reg); | 
| Matt Arsenault | 9e5b505 | 2017-06-05 22:58:57 +0000 | [diff] [blame] | 257 | } | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 258 | } | 
|  | 259 | // TODO: We could attempt to recompute new register classes while visiting | 
|  | 260 | // the operands: Some of the split register may be fine with less constraint | 
|  | 261 | // classes than the original vreg. | 
|  | 262 | } | 
|  | 263 |  | 
|  | 264 | void RenameIndependentSubregs::distribute(const IntEqClasses &Classes, | 
|  | 265 | const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, | 
|  | 266 | const SmallVectorImpl<LiveInterval*> &Intervals) const { | 
|  | 267 | unsigned NumClasses = Classes.getNumClasses(); | 
|  | 268 | SmallVector<unsigned, 8> VNIMapping; | 
|  | 269 | SmallVector<LiveInterval::SubRange*, 8> SubRanges; | 
|  | 270 | BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator(); | 
|  | 271 | for (const SubRangeInfo &SRInfo : SubRangeInfos) { | 
|  | 272 | LiveInterval::SubRange &SR = *SRInfo.SR; | 
|  | 273 | unsigned NumValNos = SR.valnos.size(); | 
|  | 274 | VNIMapping.clear(); | 
|  | 275 | VNIMapping.reserve(NumValNos); | 
|  | 276 | SubRanges.clear(); | 
|  | 277 | SubRanges.resize(NumClasses-1, nullptr); | 
|  | 278 | for (unsigned I = 0; I < NumValNos; ++I) { | 
|  | 279 | const VNInfo &VNI = *SR.valnos[I]; | 
|  | 280 | unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI); | 
|  | 281 | unsigned ID = Classes[LocalID + SRInfo.Index]; | 
|  | 282 | VNIMapping.push_back(ID); | 
|  | 283 | if (ID > 0 && SubRanges[ID-1] == nullptr) | 
|  | 284 | SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask); | 
|  | 285 | } | 
|  | 286 | DistributeRange(SR, SubRanges.data(), VNIMapping); | 
|  | 287 | } | 
|  | 288 | } | 
|  | 289 |  | 
|  | 290 | static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) { | 
|  | 291 | for (const LiveInterval::SubRange &SR : LI.subranges()) { | 
|  | 292 | if (SR.liveAt(Pos)) | 
|  | 293 | return true; | 
|  | 294 | } | 
|  | 295 | return false; | 
|  | 296 | } | 
|  | 297 |  | 
|  | 298 | void RenameIndependentSubregs::computeMainRangesFixFlags( | 
|  | 299 | const IntEqClasses &Classes, | 
|  | 300 | const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, | 
|  | 301 | const SmallVectorImpl<LiveInterval*> &Intervals) const { | 
|  | 302 | BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator(); | 
|  | 303 | const SlotIndexes &Indexes = *LIS->getSlotIndexes(); | 
|  | 304 | for (size_t I = 0, E = Intervals.size(); I < E; ++I) { | 
|  | 305 | LiveInterval &LI = *Intervals[I]; | 
|  | 306 | unsigned Reg = LI.reg; | 
|  | 307 |  | 
|  | 308 | LI.removeEmptySubRanges(); | 
|  | 309 |  | 
|  | 310 | // There must be a def (or live-in) before every use. Splitting vregs may | 
|  | 311 | // violate this principle as the splitted vreg may not have a definition on | 
|  | 312 | // every path. Fix this by creating IMPLICIT_DEF instruction as necessary. | 
|  | 313 | for (const LiveInterval::SubRange &SR : LI.subranges()) { | 
|  | 314 | // Search for "PHI" value numbers in the subranges. We must find a live | 
|  | 315 | // value in each predecessor block, add an IMPLICIT_DEF where it is | 
|  | 316 | // missing. | 
|  | 317 | for (unsigned I = 0; I < SR.valnos.size(); ++I) { | 
|  | 318 | const VNInfo &VNI = *SR.valnos[I]; | 
|  | 319 | if (VNI.isUnused() || !VNI.isPHIDef()) | 
|  | 320 | continue; | 
|  | 321 |  | 
|  | 322 | SlotIndex Def = VNI.def; | 
|  | 323 | MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def); | 
|  | 324 | for (MachineBasicBlock *PredMBB : MBB.predecessors()) { | 
|  | 325 | SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB); | 
|  | 326 | if (subRangeLiveAt(LI, PredEnd.getPrevSlot())) | 
|  | 327 | continue; | 
|  | 328 |  | 
|  | 329 | MachineBasicBlock::iterator InsertPos = | 
|  | 330 | llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg); | 
|  | 331 | const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF); | 
|  | 332 | MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos, | 
|  | 333 | DebugLoc(), MCDesc, Reg); | 
|  | 334 | SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef); | 
|  | 335 | SlotIndex RegDefIdx = DefIdx.getRegSlot(); | 
|  | 336 | for (LiveInterval::SubRange &SR : LI.subranges()) { | 
|  | 337 | VNInfo *SRVNI = SR.getNextValue(RegDefIdx, Allocator); | 
|  | 338 | SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI)); | 
|  | 339 | } | 
|  | 340 | } | 
|  | 341 | } | 
|  | 342 | } | 
|  | 343 |  | 
|  | 344 | for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) { | 
|  | 345 | if (!MO.isDef()) | 
|  | 346 | continue; | 
|  | 347 | unsigned SubRegIdx = MO.getSubReg(); | 
|  | 348 | if (SubRegIdx == 0) | 
|  | 349 | continue; | 
|  | 350 | // After assigning the new vreg we may not have any other sublanes living | 
|  | 351 | // in and out of the instruction anymore. We need to add new dead and | 
|  | 352 | // undef flags in these cases. | 
|  | 353 | if (!MO.isUndef()) { | 
|  | 354 | SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()); | 
|  | 355 | if (!subRangeLiveAt(LI, Pos)) | 
|  | 356 | MO.setIsUndef(); | 
|  | 357 | } | 
|  | 358 | if (!MO.isDead()) { | 
|  | 359 | SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()).getDeadSlot(); | 
|  | 360 | if (!subRangeLiveAt(LI, Pos)) | 
|  | 361 | MO.setIsDead(); | 
|  | 362 | } | 
|  | 363 | } | 
|  | 364 |  | 
|  | 365 | if (I == 0) | 
|  | 366 | LI.clear(); | 
|  | 367 | LIS->constructMainRangeFromSubranges(LI); | 
| Krzysztof Parzyszek | a7ed090 | 2016-08-24 13:37:55 +0000 | [diff] [blame] | 368 | // A def of a subregister may be a use of other register lanes. Replacing | 
|  | 369 | // such a def with a def of a different register will eliminate the use, | 
|  | 370 | // and may cause the recorded live range to be larger than the actual | 
|  | 371 | // liveness in the program IR. | 
|  | 372 | LIS->shrinkToUses(&LI); | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 373 | } | 
|  | 374 | } | 
|  | 375 |  | 
|  | 376 | bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) { | 
|  | 377 | // Skip renaming if liveness of subregister is not tracked. | 
| Matthias Braun | f1b20c5 | 2016-08-24 22:17:45 +0000 | [diff] [blame] | 378 | MRI = &MF.getRegInfo(); | 
|  | 379 | if (!MRI->subRegLivenessEnabled()) | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 380 | return false; | 
|  | 381 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 382 | LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in " | 
|  | 383 | << MF.getName() << '\n'); | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 384 |  | 
|  | 385 | LIS = &getAnalysis<LiveIntervals>(); | 
| Matthias Braun | f9acaca | 2016-05-31 22:38:06 +0000 | [diff] [blame] | 386 | TII = MF.getSubtarget().getInstrInfo(); | 
|  | 387 |  | 
|  | 388 | // Iterate over all vregs. Note that we query getNumVirtRegs() the newly | 
|  | 389 | // created vregs end up with higher numbers but do not need to be visited as | 
|  | 390 | // there can't be any further splitting. | 
|  | 391 | bool Changed = false; | 
|  | 392 | for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) { | 
|  | 393 | unsigned Reg = TargetRegisterInfo::index2VirtReg(I); | 
|  | 394 | if (!LIS->hasInterval(Reg)) | 
|  | 395 | continue; | 
|  | 396 | LiveInterval &LI = LIS->getInterval(Reg); | 
|  | 397 | if (!LI.hasSubRanges()) | 
|  | 398 | continue; | 
|  | 399 |  | 
|  | 400 | Changed |= renameComponents(LI); | 
|  | 401 | } | 
|  | 402 |  | 
|  | 403 | return Changed; | 
|  | 404 | } |