@@ -274,14 +274,45 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
274274 }
275275 }
276276
277+ // If the dest of MI is an original reg and MI is reMaterializable,
278+ // don't delete the inst. Replace the dest with a new reg, and keep
279+ // the inst for remat of other siblings. The inst is saved in
280+ // LiveRangeEdit::DeadRemats and will be deleted after all the
281+ // allocations of the func are done. Note that if we keep the
282+ // instruction with the original operands, that handles the physreg
283+ // operand case (described just below) as well.
284+ // However, immediately delete instructions which have unshrunk virtual
285+ // register uses. That may provoke RA to split an interval at the KILL
286+ // and later result in an invalid live segment end.
287+ if (isOrigDef && DeadRemats && !HasLiveVRegUses &&
288+ TII.isReMaterializable (*MI)) {
289+ LiveInterval &NewLI = createEmptyIntervalFrom (Dest, false );
290+ VNInfo::Allocator &Alloc = LIS.getVNInfoAllocator ();
291+ VNInfo *VNI = NewLI.getNextValue (Idx, Alloc);
292+ NewLI.addSegment (LiveInterval::Segment (Idx, Idx.getDeadSlot (), VNI));
293+
294+ if (DestSubReg) {
295+ const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo ();
296+ auto *SR =
297+ NewLI.createSubRange (Alloc, TRI->getSubRegIndexLaneMask (DestSubReg));
298+ SR->addSegment (LiveInterval::Segment (Idx, Idx.getDeadSlot (),
299+ SR->getNextValue (Idx, Alloc)));
300+ }
301+
302+ pop_back ();
303+ DeadRemats->insert (MI);
304+ const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo ();
305+ MI->substituteRegister (Dest, NewLI.reg (), 0 , TRI);
306+ assert (MI->registerDefIsDead (NewLI.reg (), &TRI));
307+ }
277308 // Currently, we don't support DCE of physreg live ranges. If MI reads
278309 // any unreserved physregs, don't erase the instruction, but turn it into
279310 // a KILL instead. This way, the physreg live ranges don't end up
280311 // dangling.
281312 // FIXME: It would be better to have something like shrinkToUses() for
282313 // physregs. That could potentially enable more DCE and it would free up
283314 // the physreg. It would not happen often, though.
284- if (ReadsPhysRegs) {
315+ else if (ReadsPhysRegs) {
285316 MI->setDesc (TII.get (TargetOpcode::KILL));
286317 // Remove all operands that aren't physregs.
287318 for (unsigned i = MI->getNumOperands (); i; --i) {
@@ -293,41 +324,11 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
293324 MI->dropMemRefs (*MI->getMF ());
294325 LLVM_DEBUG (dbgs () << " Converted physregs to:\t " << *MI);
295326 } else {
296- // If the dest of MI is an original reg and MI is reMaterializable,
297- // don't delete the inst. Replace the dest with a new reg, and keep
298- // the inst for remat of other siblings. The inst is saved in
299- // LiveRangeEdit::DeadRemats and will be deleted after all the
300- // allocations of the func are done.
301- // However, immediately delete instructions which have unshrunk virtual
302- // register uses. That may provoke RA to split an interval at the KILL
303- // and later result in an invalid live segment end.
304- if (isOrigDef && DeadRemats && !HasLiveVRegUses &&
305- TII.isReMaterializable (*MI)) {
306- LiveInterval &NewLI = createEmptyIntervalFrom (Dest, false );
307- VNInfo::Allocator &Alloc = LIS.getVNInfoAllocator ();
308- VNInfo *VNI = NewLI.getNextValue (Idx, Alloc);
309- NewLI.addSegment (LiveInterval::Segment (Idx, Idx.getDeadSlot (), VNI));
310-
311- if (DestSubReg) {
312- const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo ();
313- auto *SR = NewLI.createSubRange (
314- Alloc, TRI->getSubRegIndexLaneMask (DestSubReg));
315- SR->addSegment (LiveInterval::Segment (Idx, Idx.getDeadSlot (),
316- SR->getNextValue (Idx, Alloc)));
317- }
318-
319- pop_back ();
320- DeadRemats->insert (MI);
321- const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo ();
322- MI->substituteRegister (Dest, NewLI.reg (), 0 , TRI);
323- assert (MI->registerDefIsDead (NewLI.reg (), &TRI));
324- } else {
325- if (TheDelegate)
326- TheDelegate->LRE_WillEraseInstruction (MI);
327- LIS.RemoveMachineInstrFromMaps (*MI);
328- MI->eraseFromParent ();
329- ++NumDCEDeleted;
330- }
327+ if (TheDelegate)
328+ TheDelegate->LRE_WillEraseInstruction (MI);
329+ LIS.RemoveMachineInstrFromMaps (*MI);
330+ MI->eraseFromParent ();
331+ ++NumDCEDeleted;
331332 }
332333
333334 // Erase any virtregs that are now empty and unused. There may be <undef>
0 commit comments