1 | //===-- LiveRangeEdit.cpp - Basic tools for editing a register live range -===// |
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 | // The LiveRangeEdit class represents changes done to a virtual register when it |
10 | // is spilled or split. |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/CodeGen/LiveRangeEdit.h" |
14 | #include "llvm/ADT/Statistic.h" |
15 | #include "llvm/CodeGen/CalcSpillWeights.h" |
16 | #include "llvm/CodeGen/LiveIntervals.h" |
17 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
18 | #include "llvm/CodeGen/TargetInstrInfo.h" |
19 | #include "llvm/CodeGen/VirtRegMap.h" |
20 | #include "llvm/Support/Debug.h" |
21 | #include "llvm/Support/raw_ostream.h" |
22 | |
23 | using namespace llvm; |
24 | |
25 | #define DEBUG_TYPE "regalloc" |
26 | |
27 | STATISTIC(NumDCEDeleted, "Number of instructions deleted by DCE" ); |
28 | STATISTIC(NumDCEFoldedLoads, "Number of single use loads folded after DCE" ); |
29 | STATISTIC(NumFracRanges, "Number of live ranges fractured by DCE" ); |
30 | STATISTIC(NumReMaterialization, "Number of instructions rematerialized" ); |
31 | |
32 | void LiveRangeEdit::Delegate::anchor() { } |
33 | |
34 | LiveInterval &LiveRangeEdit::createEmptyIntervalFrom(Register OldReg, |
35 | bool createSubRanges) { |
36 | Register VReg = MRI.cloneVirtualRegister(VReg: OldReg); |
37 | if (VRM) |
38 | VRM->setIsSplitFromReg(virtReg: VReg, SReg: VRM->getOriginal(VirtReg: OldReg)); |
39 | |
40 | LiveInterval &LI = LIS.createEmptyInterval(Reg: VReg); |
41 | if (Parent && !Parent->isSpillable()) |
42 | LI.markNotSpillable(); |
43 | if (createSubRanges) { |
44 | // Create empty subranges if the OldReg's interval has them. Do not create |
45 | // the main range here---it will be constructed later after the subranges |
46 | // have been finalized. |
47 | LiveInterval &OldLI = LIS.getInterval(Reg: OldReg); |
48 | VNInfo::Allocator &Alloc = LIS.getVNInfoAllocator(); |
49 | for (LiveInterval::SubRange &S : OldLI.subranges()) |
50 | LI.createSubRange(Allocator&: Alloc, LaneMask: S.LaneMask); |
51 | } |
52 | return LI; |
53 | } |
54 | |
55 | Register LiveRangeEdit::createFrom(Register OldReg) { |
56 | Register VReg = MRI.cloneVirtualRegister(VReg: OldReg); |
57 | if (VRM) { |
58 | VRM->setIsSplitFromReg(virtReg: VReg, SReg: VRM->getOriginal(VirtReg: OldReg)); |
59 | } |
60 | // FIXME: Getting the interval here actually computes it. |
61 | // In theory, this may not be what we want, but in practice |
62 | // the createEmptyIntervalFrom API is used when this is not |
63 | // the case. Generally speaking we just want to annotate the |
64 | // LiveInterval when it gets created but we cannot do that at |
65 | // the moment. |
66 | if (Parent && !Parent->isSpillable()) |
67 | LIS.getInterval(Reg: VReg).markNotSpillable(); |
68 | return VReg; |
69 | } |
70 | |
71 | bool LiveRangeEdit::checkRematerializable(VNInfo *VNI, |
72 | const MachineInstr *DefMI) { |
73 | assert(DefMI && "Missing instruction" ); |
74 | ScannedRemattable = true; |
75 | if (!TII.isTriviallyReMaterializable(MI: *DefMI)) |
76 | return false; |
77 | Remattable.insert(Ptr: VNI); |
78 | return true; |
79 | } |
80 | |
81 | void LiveRangeEdit::scanRemattable() { |
82 | for (VNInfo *VNI : getParent().valnos) { |
83 | if (VNI->isUnused()) |
84 | continue; |
85 | Register Original = VRM->getOriginal(VirtReg: getReg()); |
86 | LiveInterval &OrigLI = LIS.getInterval(Reg: Original); |
87 | VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx: VNI->def); |
88 | if (!OrigVNI) |
89 | continue; |
90 | MachineInstr *DefMI = LIS.getInstructionFromIndex(index: OrigVNI->def); |
91 | if (!DefMI) |
92 | continue; |
93 | checkRematerializable(VNI: OrigVNI, DefMI); |
94 | } |
95 | ScannedRemattable = true; |
96 | } |
97 | |
98 | bool LiveRangeEdit::anyRematerializable() { |
99 | if (!ScannedRemattable) |
100 | scanRemattable(); |
101 | return !Remattable.empty(); |
102 | } |
103 | |
104 | /// allUsesAvailableAt - Return true if all registers used by OrigMI at |
105 | /// OrigIdx are also available with the same value at UseIdx. |
106 | bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr *OrigMI, |
107 | SlotIndex OrigIdx, |
108 | SlotIndex UseIdx) const { |
109 | OrigIdx = OrigIdx.getRegSlot(EC: true); |
110 | UseIdx = std::max(a: UseIdx, b: UseIdx.getRegSlot(EC: true)); |
111 | for (const MachineOperand &MO : OrigMI->operands()) { |
112 | if (!MO.isReg() || !MO.getReg() || !MO.readsReg()) |
113 | continue; |
114 | |
115 | // We can't remat physreg uses, unless it is a constant or target wants |
116 | // to ignore this use. |
117 | if (MO.getReg().isPhysical()) { |
118 | if (MRI.isConstantPhysReg(PhysReg: MO.getReg()) || TII.isIgnorableUse(MO)) |
119 | continue; |
120 | return false; |
121 | } |
122 | |
123 | LiveInterval &li = LIS.getInterval(Reg: MO.getReg()); |
124 | const VNInfo *OVNI = li.getVNInfoAt(Idx: OrigIdx); |
125 | if (!OVNI) |
126 | continue; |
127 | |
128 | // Don't allow rematerialization immediately after the original def. |
129 | // It would be incorrect if OrigMI redefines the register. |
130 | // See PR14098. |
131 | if (SlotIndex::isSameInstr(A: OrigIdx, B: UseIdx)) |
132 | return false; |
133 | |
134 | if (OVNI != li.getVNInfoAt(Idx: UseIdx)) |
135 | return false; |
136 | |
137 | // Check that subrange is live at UseIdx. |
138 | if (li.hasSubRanges()) { |
139 | const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); |
140 | unsigned SubReg = MO.getSubReg(); |
141 | LaneBitmask LM = SubReg ? TRI->getSubRegIndexLaneMask(SubIdx: SubReg) |
142 | : MRI.getMaxLaneMaskForVReg(Reg: MO.getReg()); |
143 | for (LiveInterval::SubRange &SR : li.subranges()) { |
144 | if ((SR.LaneMask & LM).none()) |
145 | continue; |
146 | if (!SR.liveAt(index: UseIdx)) |
147 | return false; |
148 | // Early exit if all used lanes are checked. No need to continue. |
149 | LM &= ~SR.LaneMask; |
150 | if (LM.none()) |
151 | break; |
152 | } |
153 | } |
154 | } |
155 | return true; |
156 | } |
157 | |
158 | bool LiveRangeEdit::canRematerializeAt(Remat &RM, VNInfo *OrigVNI, |
159 | SlotIndex UseIdx) { |
160 | assert(ScannedRemattable && "Call anyRematerializable first" ); |
161 | |
162 | // Use scanRemattable info. |
163 | if (!Remattable.count(Ptr: OrigVNI)) |
164 | return false; |
165 | |
166 | // No defining instruction provided. |
167 | SlotIndex DefIdx; |
168 | assert(RM.OrigMI && "No defining instruction for remattable value" ); |
169 | DefIdx = LIS.getInstructionIndex(Instr: *RM.OrigMI); |
170 | |
171 | // Verify that all used registers are available with the same values. |
172 | if (!allUsesAvailableAt(OrigMI: RM.OrigMI, OrigIdx: DefIdx, UseIdx)) |
173 | return false; |
174 | |
175 | return true; |
176 | } |
177 | |
178 | SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB, |
179 | MachineBasicBlock::iterator MI, |
180 | Register DestReg, const Remat &RM, |
181 | const TargetRegisterInfo &tri, |
182 | bool Late, unsigned SubIdx, |
183 | MachineInstr *ReplaceIndexMI) { |
184 | assert(RM.OrigMI && "Invalid remat" ); |
185 | TII.reMaterialize(MBB, MI, DestReg, SubIdx, Orig: *RM.OrigMI, TRI: tri); |
186 | // DestReg of the cloned instruction cannot be Dead. Set isDead of DestReg |
187 | // to false anyway in case the isDead flag of RM.OrigMI's dest register |
188 | // is true. |
189 | (*--MI).clearRegisterDeads(Reg: DestReg); |
190 | Rematted.insert(Ptr: RM.ParentVNI); |
191 | ++NumReMaterialization; |
192 | |
193 | if (ReplaceIndexMI) |
194 | return LIS.ReplaceMachineInstrInMaps(MI&: *ReplaceIndexMI, NewMI&: *MI).getRegSlot(); |
195 | return LIS.getSlotIndexes()->insertMachineInstrInMaps(MI&: *MI, Late).getRegSlot(); |
196 | } |
197 | |
198 | void LiveRangeEdit::eraseVirtReg(Register Reg) { |
199 | if (TheDelegate && TheDelegate->LRE_CanEraseVirtReg(Reg)) |
200 | LIS.removeInterval(Reg); |
201 | } |
202 | |
203 | bool LiveRangeEdit::foldAsLoad(LiveInterval *LI, |
204 | SmallVectorImpl<MachineInstr*> &Dead) { |
205 | MachineInstr *DefMI = nullptr, *UseMI = nullptr; |
206 | |
207 | // Check that there is a single def and a single use. |
208 | for (MachineOperand &MO : MRI.reg_nodbg_operands(Reg: LI->reg())) { |
209 | MachineInstr *MI = MO.getParent(); |
210 | if (MO.isDef()) { |
211 | if (DefMI && DefMI != MI) |
212 | return false; |
213 | if (!MI->canFoldAsLoad()) |
214 | return false; |
215 | DefMI = MI; |
216 | } else if (!MO.isUndef()) { |
217 | if (UseMI && UseMI != MI) |
218 | return false; |
219 | // FIXME: Targets don't know how to fold subreg uses. |
220 | if (MO.getSubReg()) |
221 | return false; |
222 | UseMI = MI; |
223 | } |
224 | } |
225 | if (!DefMI || !UseMI) |
226 | return false; |
227 | |
228 | // Since we're moving the DefMI load, make sure we're not extending any live |
229 | // ranges. |
230 | if (!allUsesAvailableAt(OrigMI: DefMI, OrigIdx: LIS.getInstructionIndex(Instr: *DefMI), |
231 | UseIdx: LIS.getInstructionIndex(Instr: *UseMI))) |
232 | return false; |
233 | |
234 | // We also need to make sure it is safe to move the load. |
235 | // Assume there are stores between DefMI and UseMI. |
236 | bool SawStore = true; |
237 | if (!DefMI->isSafeToMove(SawStore)) |
238 | return false; |
239 | |
240 | LLVM_DEBUG(dbgs() << "Try to fold single def: " << *DefMI |
241 | << " into single use: " << *UseMI); |
242 | |
243 | SmallVector<unsigned, 8> Ops; |
244 | if (UseMI->readsWritesVirtualRegister(Reg: LI->reg(), Ops: &Ops).second) |
245 | return false; |
246 | |
247 | MachineInstr *FoldMI = TII.foldMemoryOperand(MI&: *UseMI, Ops, LoadMI&: *DefMI, LIS: &LIS); |
248 | if (!FoldMI) |
249 | return false; |
250 | LLVM_DEBUG(dbgs() << " folded: " << *FoldMI); |
251 | LIS.ReplaceMachineInstrInMaps(MI&: *UseMI, NewMI&: *FoldMI); |
252 | // Update the call info. |
253 | if (UseMI->shouldUpdateAdditionalCallInfo()) |
254 | UseMI->getMF()->moveAdditionalCallInfo(Old: UseMI, New: FoldMI); |
255 | UseMI->eraseFromParent(); |
256 | DefMI->addRegisterDead(Reg: LI->reg(), RegInfo: nullptr); |
257 | Dead.push_back(Elt: DefMI); |
258 | ++NumDCEFoldedLoads; |
259 | return true; |
260 | } |
261 | |
262 | bool LiveRangeEdit::useIsKill(const LiveInterval &LI, |
263 | const MachineOperand &MO) const { |
264 | const MachineInstr &MI = *MO.getParent(); |
265 | SlotIndex Idx = LIS.getInstructionIndex(Instr: MI).getRegSlot(); |
266 | if (LI.Query(Idx).isKill()) |
267 | return true; |
268 | const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); |
269 | unsigned SubReg = MO.getSubReg(); |
270 | LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubIdx: SubReg); |
271 | for (const LiveInterval::SubRange &S : LI.subranges()) { |
272 | if ((S.LaneMask & LaneMask).any() && S.Query(Idx).isKill()) |
273 | return true; |
274 | } |
275 | return false; |
276 | } |
277 | |
278 | /// Find all live intervals that need to shrink, then remove the instruction. |
279 | void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) { |
280 | assert(MI->allDefsAreDead() && "Def isn't really dead" ); |
281 | SlotIndex Idx = LIS.getInstructionIndex(Instr: *MI).getRegSlot(); |
282 | |
283 | // Never delete a bundled instruction. |
284 | if (MI->isBundled()) { |
285 | // TODO: Handle deleting copy bundles |
286 | LLVM_DEBUG(dbgs() << "Won't delete dead bundled inst: " << Idx << '\t' |
287 | << *MI); |
288 | return; |
289 | } |
290 | |
291 | // Never delete inline asm. |
292 | if (MI->isInlineAsm()) { |
293 | LLVM_DEBUG(dbgs() << "Won't delete: " << Idx << '\t' << *MI); |
294 | return; |
295 | } |
296 | |
297 | // Use the same criteria as DeadMachineInstructionElim. |
298 | bool SawStore = false; |
299 | if (!MI->isSafeToMove(SawStore)) { |
300 | LLVM_DEBUG(dbgs() << "Can't delete: " << Idx << '\t' << *MI); |
301 | return; |
302 | } |
303 | |
304 | LLVM_DEBUG(dbgs() << "Deleting dead def " << Idx << '\t' << *MI); |
305 | |
306 | // Collect virtual registers to be erased after MI is gone. |
307 | SmallVector<Register, 8> RegsToErase; |
308 | bool ReadsPhysRegs = false; |
309 | bool isOrigDef = false; |
310 | Register Dest; |
311 | unsigned DestSubReg; |
312 | // Only optimize rematerialize case when the instruction has one def, since |
313 | // otherwise we could leave some dead defs in the code. This case is |
314 | // extremely rare. |
315 | if (VRM && MI->getOperand(i: 0).isReg() && MI->getOperand(i: 0).isDef() && |
316 | MI->getDesc().getNumDefs() == 1) { |
317 | Dest = MI->getOperand(i: 0).getReg(); |
318 | DestSubReg = MI->getOperand(i: 0).getSubReg(); |
319 | Register Original = VRM->getOriginal(VirtReg: Dest); |
320 | LiveInterval &OrigLI = LIS.getInterval(Reg: Original); |
321 | VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx); |
322 | // The original live-range may have been shrunk to |
323 | // an empty live-range. It happens when it is dead, but |
324 | // we still keep it around to be able to rematerialize |
325 | // other values that depend on it. |
326 | if (OrigVNI) |
327 | isOrigDef = SlotIndex::isSameInstr(A: OrigVNI->def, B: Idx); |
328 | } |
329 | |
330 | bool HasLiveVRegUses = false; |
331 | |
332 | // Check for live intervals that may shrink |
333 | for (const MachineOperand &MO : MI->operands()) { |
334 | if (!MO.isReg()) |
335 | continue; |
336 | Register Reg = MO.getReg(); |
337 | if (!Reg.isVirtual()) { |
338 | // Check if MI reads any unreserved physregs. |
339 | if (Reg && MO.readsReg() && !MRI.isReserved(PhysReg: Reg)) |
340 | ReadsPhysRegs = true; |
341 | else if (MO.isDef()) |
342 | LIS.removePhysRegDefAt(Reg: Reg.asMCReg(), Pos: Idx); |
343 | continue; |
344 | } |
345 | LiveInterval &LI = LIS.getInterval(Reg); |
346 | |
347 | // Shrink read registers, unless it is likely to be expensive and |
348 | // unlikely to change anything. We typically don't want to shrink the |
349 | // PIC base register that has lots of uses everywhere. |
350 | // Always shrink COPY uses that probably come from live range splitting. |
351 | if ((MI->readsVirtualRegister(Reg) && |
352 | (MO.isDef() || TII.isCopyInstr(MI: *MI))) || |
353 | (MO.readsReg() && (MRI.hasOneNonDBGUse(RegNo: Reg) || useIsKill(LI, MO)))) |
354 | ToShrink.insert(X: &LI); |
355 | else if (MO.readsReg()) |
356 | HasLiveVRegUses = true; |
357 | |
358 | // Remove defined value. |
359 | if (MO.isDef()) { |
360 | if (TheDelegate && LI.getVNInfoAt(Idx) != nullptr) |
361 | TheDelegate->LRE_WillShrinkVirtReg(LI.reg()); |
362 | LIS.removeVRegDefAt(LI, Pos: Idx); |
363 | if (LI.empty()) |
364 | RegsToErase.push_back(Elt: Reg); |
365 | } |
366 | } |
367 | |
368 | // Currently, we don't support DCE of physreg live ranges. If MI reads |
369 | // any unreserved physregs, don't erase the instruction, but turn it into |
370 | // a KILL instead. This way, the physreg live ranges don't end up |
371 | // dangling. |
372 | // FIXME: It would be better to have something like shrinkToUses() for |
373 | // physregs. That could potentially enable more DCE and it would free up |
374 | // the physreg. It would not happen often, though. |
375 | if (ReadsPhysRegs) { |
376 | MI->setDesc(TII.get(Opcode: TargetOpcode::KILL)); |
377 | // Remove all operands that aren't physregs. |
378 | for (unsigned i = MI->getNumOperands(); i; --i) { |
379 | const MachineOperand &MO = MI->getOperand(i: i-1); |
380 | if (MO.isReg() && MO.getReg().isPhysical()) |
381 | continue; |
382 | MI->removeOperand(OpNo: i-1); |
383 | } |
384 | MI->dropMemRefs(MF&: *MI->getMF()); |
385 | LLVM_DEBUG(dbgs() << "Converted physregs to:\t" << *MI); |
386 | } else { |
387 | // If the dest of MI is an original reg and MI is reMaterializable, |
388 | // don't delete the inst. Replace the dest with a new reg, and keep |
389 | // the inst for remat of other siblings. The inst is saved in |
390 | // LiveRangeEdit::DeadRemats and will be deleted after all the |
391 | // allocations of the func are done. |
392 | // However, immediately delete instructions which have unshrunk virtual |
393 | // register uses. That may provoke RA to split an interval at the KILL |
394 | // and later result in an invalid live segment end. |
395 | if (isOrigDef && DeadRemats && !HasLiveVRegUses && |
396 | TII.isTriviallyReMaterializable(MI: *MI)) { |
397 | LiveInterval &NewLI = createEmptyIntervalFrom(OldReg: Dest, createSubRanges: false); |
398 | VNInfo::Allocator &Alloc = LIS.getVNInfoAllocator(); |
399 | VNInfo *VNI = NewLI.getNextValue(Def: Idx, VNInfoAllocator&: Alloc); |
400 | NewLI.addSegment(S: LiveInterval::Segment(Idx, Idx.getDeadSlot(), VNI)); |
401 | |
402 | if (DestSubReg) { |
403 | const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); |
404 | auto *SR = NewLI.createSubRange( |
405 | Allocator&: Alloc, LaneMask: TRI->getSubRegIndexLaneMask(SubIdx: DestSubReg)); |
406 | SR->addSegment(S: LiveInterval::Segment(Idx, Idx.getDeadSlot(), |
407 | SR->getNextValue(Def: Idx, VNInfoAllocator&: Alloc))); |
408 | } |
409 | |
410 | pop_back(); |
411 | DeadRemats->insert(Ptr: MI); |
412 | const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); |
413 | MI->substituteRegister(FromReg: Dest, ToReg: NewLI.reg(), SubIdx: 0, RegInfo: TRI); |
414 | assert(MI->registerDefIsDead(NewLI.reg(), &TRI)); |
415 | } else { |
416 | if (TheDelegate) |
417 | TheDelegate->LRE_WillEraseInstruction(MI); |
418 | LIS.RemoveMachineInstrFromMaps(MI&: *MI); |
419 | MI->eraseFromParent(); |
420 | ++NumDCEDeleted; |
421 | } |
422 | } |
423 | |
424 | // Erase any virtregs that are now empty and unused. There may be <undef> |
425 | // uses around. Keep the empty live range in that case. |
426 | for (Register Reg : RegsToErase) { |
427 | if (LIS.hasInterval(Reg) && MRI.reg_nodbg_empty(RegNo: Reg)) { |
428 | ToShrink.remove(X: &LIS.getInterval(Reg)); |
429 | eraseVirtReg(Reg); |
430 | } |
431 | } |
432 | } |
433 | |
434 | void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead, |
435 | ArrayRef<Register> RegsBeingSpilled) { |
436 | ToShrinkSet ToShrink; |
437 | |
438 | for (;;) { |
439 | // Erase all dead defs. |
440 | while (!Dead.empty()) |
441 | eliminateDeadDef(MI: Dead.pop_back_val(), ToShrink); |
442 | |
443 | if (ToShrink.empty()) |
444 | break; |
445 | |
446 | // Shrink just one live interval. Then delete new dead defs. |
447 | LiveInterval *LI = ToShrink.pop_back_val(); |
448 | if (foldAsLoad(LI, Dead)) |
449 | continue; |
450 | Register VReg = LI->reg(); |
451 | if (TheDelegate) |
452 | TheDelegate->LRE_WillShrinkVirtReg(VReg); |
453 | if (!LIS.shrinkToUses(li: LI, dead: &Dead)) |
454 | continue; |
455 | |
456 | // Don't create new intervals for a register being spilled. |
457 | // The new intervals would have to be spilled anyway so its not worth it. |
458 | // Also they currently aren't spilled so creating them and not spilling |
459 | // them results in incorrect code. |
460 | if (llvm::is_contained(Range&: RegsBeingSpilled, Element: VReg)) |
461 | continue; |
462 | |
463 | // LI may have been separated, create new intervals. |
464 | LI->RenumberValues(); |
465 | SmallVector<LiveInterval*, 8> SplitLIs; |
466 | LIS.splitSeparateComponents(LI&: *LI, SplitLIs); |
467 | if (!SplitLIs.empty()) |
468 | ++NumFracRanges; |
469 | |
470 | Register Original = VRM ? VRM->getOriginal(VirtReg: VReg) : Register(); |
471 | for (const LiveInterval *SplitLI : SplitLIs) { |
472 | // If LI is an original interval that hasn't been split yet, make the new |
473 | // intervals their own originals instead of referring to LI. The original |
474 | // interval must contain all the split products, and LI doesn't. |
475 | if (Original != VReg && Original != 0) |
476 | VRM->setIsSplitFromReg(virtReg: SplitLI->reg(), SReg: Original); |
477 | if (TheDelegate) |
478 | TheDelegate->LRE_DidCloneVirtReg(New: SplitLI->reg(), Old: VReg); |
479 | } |
480 | } |
481 | } |
482 | |
483 | // Keep track of new virtual registers created via |
484 | // MachineRegisterInfo::createVirtualRegister. |
485 | void |
486 | LiveRangeEdit::MRI_NoteNewVirtualRegister(Register VReg) { |
487 | if (VRM) |
488 | VRM->grow(); |
489 | |
490 | NewRegs.push_back(Elt: VReg); |
491 | } |
492 | |
493 | void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF, |
494 | VirtRegAuxInfo &VRAI) { |
495 | for (unsigned I = 0, Size = size(); I < Size; ++I) { |
496 | LiveInterval &LI = LIS.getInterval(Reg: get(idx: I)); |
497 | if (MRI.recomputeRegClass(Reg: LI.reg())) |
498 | LLVM_DEBUG({ |
499 | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); |
500 | dbgs() << "Inflated " << printReg(LI.reg()) << " to " |
501 | << TRI->getRegClassName(MRI.getRegClass(LI.reg())) << '\n'; |
502 | }); |
503 | VRAI.calculateSpillWeightAndHint(LI); |
504 | } |
505 | } |
506 | |