Skip to content

Commit 760e7d0

Browse files
committed
[X86, Peephole] Enable FoldImmediate for X86
Enable FoldImmediate for X86 by implementing X86InstrInfo::FoldImmediate. Also enhanced peephole by deleting identical instructions after FoldImmediate. Differential Revision: https://reviews.llvm.org/D151848
1 parent 08d6b87 commit 760e7d0

20 files changed

+2874
-2210
lines changed

llvm/lib/CodeGen/PeepholeOptimizer.cpp

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
13711376
bool 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
14071426
bool 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

Comments
 (0)