@@ -202,7 +202,8 @@ namespace {
202202 bool isMoveImmediate (MachineInstr &MI, SmallSet<Register, 4 > &ImmDefRegs,
203203 DenseMap<Register, MachineInstr *> &ImmDefMIs);
204204 bool foldImmediate (MachineInstr &MI, SmallSet<Register, 4 > &ImmDefRegs,
205- DenseMap<Register, MachineInstr *> &ImmDefMIs);
205+ DenseMap<Register, MachineInstr *> &ImmDefMIs,
206+ bool &Deleted);
206207
207208 // / Finds recurrence cycles, but only ones that formulated around
208209 // / a def operand and a use operand that are tied. If there is a use
@@ -217,8 +218,11 @@ namespace {
217218 // / set \p CopyMIs. If this virtual register was previously seen as a
218219 // / copy, replace the uses of this copy with the previously seen copy's
219220 // / destination register.
221+ // / \p LocalMIs contains all previous seen instructions. An optimized away
222+ // / instruction should be deleted from LocalMIs.
220223 bool foldRedundantCopy (MachineInstr &MI,
221- DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs);
224+ DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs,
225+ SmallPtrSetImpl<MachineInstr *> &LocalMIs);
222226
223227 // / Is the register \p Reg a non-allocatable physical register?
224228 bool isNAPhysCopy (Register Reg);
@@ -1351,26 +1355,28 @@ bool PeepholeOptimizer::isMoveImmediate(
13511355 MachineInstr &MI, SmallSet<Register, 4 > &ImmDefRegs,
13521356 DenseMap<Register, MachineInstr *> &ImmDefMIs) {
13531357 const MCInstrDesc &MCID = MI.getDesc ();
1354- if (!MI.isMoveImmediate ())
1355- return false ;
1356- if (MCID.getNumDefs () != 1 )
1358+ if (MCID.getNumDefs () != 1 || !MI.getOperand (0 ).isReg ())
13571359 return false ;
13581360 Register Reg = MI.getOperand (0 ).getReg ();
1359- if (Reg.isVirtual ()) {
1360- ImmDefMIs.insert (std::make_pair (Reg, &MI));
1361- ImmDefRegs.insert (Reg);
1362- return true ;
1363- }
1361+ if (!Reg.isVirtual ())
1362+ return false ;
13641363
1365- return false ;
1364+ int64_t ImmVal;
1365+ if (!MI.isMoveImmediate () && !TII->getConstValDefinedInReg (MI, Reg, ImmVal))
1366+ return false ;
1367+
1368+ ImmDefMIs.insert (std::make_pair (Reg, &MI));
1369+ ImmDefRegs.insert (Reg);
1370+ return true ;
13661371}
13671372
13681373// / Try folding register operands that are defined by move immediate
13691374// / instructions, i.e. a trivial constant folding optimization, if
13701375// / and only if the def and use are in the same BB.
13711376bool PeepholeOptimizer::foldImmediate (
13721377 MachineInstr &MI, SmallSet<Register, 4 > &ImmDefRegs,
1373- DenseMap<Register, MachineInstr *> &ImmDefMIs) {
1378+ DenseMap<Register, MachineInstr *> &ImmDefMIs, bool &Deleted) {
1379+ Deleted = false ;
13741380 for (unsigned i = 0 , e = MI.getDesc ().getNumOperands (); i != e; ++i) {
13751381 MachineOperand &MO = MI.getOperand (i);
13761382 if (!MO.isReg () || MO.isDef ())
@@ -1384,6 +1390,19 @@ bool PeepholeOptimizer::foldImmediate(
13841390 assert (II != ImmDefMIs.end () && " couldn't find immediate definition" );
13851391 if (TII->FoldImmediate (MI, *II->second , Reg, MRI)) {
13861392 ++NumImmFold;
1393+ // FoldImmediate can delete ImmDefMI if MI was its only user. If ImmDefMI
1394+ // is not deleted, and we happened to get a same MI, we can delete MI and
1395+ // replace its users.
1396+ if (MRI->getVRegDef (Reg) &&
1397+ MI.isIdenticalTo (*II->second , MachineInstr::IgnoreVRegDefs)) {
1398+ Register DstReg = MI.getOperand (0 ).getReg ();
1399+ if (DstReg.isVirtual () &&
1400+ MRI->getRegClass (DstReg) == MRI->getRegClass (Reg)) {
1401+ MRI->replaceRegWith (DstReg, Reg);
1402+ MI.eraseFromParent ();
1403+ Deleted = true ;
1404+ }
1405+ }
13871406 return true ;
13881407 }
13891408 }
@@ -1405,7 +1424,8 @@ bool PeepholeOptimizer::foldImmediate(
14051424//
14061425// Should replace %2 uses with %1:sub1
14071426bool PeepholeOptimizer::foldRedundantCopy (
1408- MachineInstr &MI, DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs) {
1427+ MachineInstr &MI, DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs,
1428+ SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
14091429 assert (MI.isCopy () && " expected a COPY machine instruction" );
14101430
14111431 Register SrcReg = MI.getOperand (1 ).getReg ();
@@ -1425,6 +1445,8 @@ bool PeepholeOptimizer::foldRedundantCopy(
14251445 }
14261446
14271447 MachineInstr *PrevCopy = CopyMIs.find (SrcPair)->second ;
1448+ if (!LocalMIs.count (PrevCopy))
1449+ return false ;
14281450
14291451 assert (SrcSubReg == PrevCopy->getOperand (1 ).getSubReg () &&
14301452 " Unexpected mismatching subreg!" );
@@ -1732,7 +1754,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
17321754 continue ;
17331755 }
17341756
1735- if (MI->isCopy () && (foldRedundantCopy (*MI, CopySrcMIs) ||
1757+ if (MI->isCopy () && (foldRedundantCopy (*MI, CopySrcMIs, LocalMIs ) ||
17361758 foldRedundantNAPhysCopy (*MI, NAPhysToVirtMIs))) {
17371759 LocalMIs.erase (MI);
17381760 LLVM_DEBUG (dbgs () << " Deleting redundant copy: " << *MI << " \n " );
@@ -1750,8 +1772,14 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
17501772 // next iteration sees the new instructions.
17511773 MII = MI;
17521774 ++MII;
1753- if (SeenMoveImm)
1754- Changed |= foldImmediate (*MI, ImmDefRegs, ImmDefMIs);
1775+ if (SeenMoveImm) {
1776+ bool Deleted;
1777+ Changed |= foldImmediate (*MI, ImmDefRegs, ImmDefMIs, Deleted);
1778+ if (Deleted) {
1779+ LocalMIs.erase (MI);
1780+ continue ;
1781+ }
1782+ }
17551783 }
17561784
17571785 // Check whether MI is a load candidate for folding into a later
0 commit comments