Skip to content

Commit 9a091de

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 c18e78c commit 9a091de

27 files changed

+3030
-2211
lines changed

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,11 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
463463
virtual void MF_HandleInsertion(MachineInstr &MI) = 0;
464464
/// Callback before a removal. This should not modify the MI directly.
465465
virtual void MF_HandleRemoval(MachineInstr &MI) = 0;
466+
/// Callback before changing MCInstrDesc. This should not modify the MI
467+
/// directly.
468+
virtual void MF_HandleChangeDesc(MachineInstr &MI, const MCInstrDesc &TID) {
469+
return;
470+
}
466471
};
467472

468473
/// Structure used to represent pair of argument number after call lowering
@@ -498,6 +503,9 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
498503
friend struct ilist_traits<MachineInstr>;
499504

500505
public:
506+
// Need to be accessed from MachineInstr::setDesc.
507+
void handleChangeDesc(MachineInstr &MI, const MCInstrDesc &TID);
508+
501509
using VariableDbgInfoMapTy = SmallVector<VariableDbgInfo, 4>;
502510
VariableDbgInfoMapTy VariableDbgInfos;
503511

llvm/include/llvm/CodeGen/MachineInstr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1814,7 +1814,7 @@ class MachineInstr
18141814

18151815
/// Replace the instruction descriptor (thus opcode) of
18161816
/// the current instruction with a new one.
1817-
void setDesc(const MCInstrDesc &TID) { MCID = &TID; }
1817+
void setDesc(const MCInstrDesc &TID);
18181818

18191819
/// Replace current source information with new such.
18201820
/// Avoid using this, the constructor argument is preferable.

llvm/lib/CodeGen/MachineFunction.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,12 @@ void MachineFunction::handleRemoval(MachineInstr &MI) {
178178
TheDelegate->MF_HandleRemoval(MI);
179179
}
180180

181+
void MachineFunction::handleChangeDesc(MachineInstr &MI,
182+
const MCInstrDesc &TID) {
183+
if (TheDelegate)
184+
TheDelegate->MF_HandleChangeDesc(MI, TID);
185+
}
186+
181187
void MachineFunction::init() {
182188
// Assume the function starts in SSA form with correct liveness.
183189
Properties.set(MachineFunctionProperties::Property::IsSSA);

llvm/lib/CodeGen/MachineInstr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
138138
setFlags(MI.Flags);
139139
}
140140

141+
void MachineInstr::setDesc(const MCInstrDesc &TID) {
142+
if (getParent())
143+
getMF()->handleChangeDesc(*this, TID);
144+
MCID = &TID;
145+
}
146+
141147
void MachineInstr::moveBefore(MachineInstr *MovePos) {
142148
MovePos->getParent()->splice(MovePos, getParent(), getIterator());
143149
}

llvm/lib/CodeGen/PeepholeOptimizer.cpp

Lines changed: 92 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ namespace {
149149
class ValueTrackerResult;
150150
class RecurrenceInstr;
151151

152-
class PeepholeOptimizer : public MachineFunctionPass {
152+
class PeepholeOptimizer : public MachineFunctionPass,
153+
private MachineFunction::Delegate {
153154
const TargetInstrInfo *TII = nullptr;
154155
const TargetRegisterInfo *TRI = nullptr;
155156
MachineRegisterInfo *MRI = nullptr;
@@ -202,7 +203,8 @@ namespace {
202203
bool isMoveImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
203204
DenseMap<Register, MachineInstr *> &ImmDefMIs);
204205
bool foldImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
205-
DenseMap<Register, MachineInstr *> &ImmDefMIs);
206+
DenseMap<Register, MachineInstr *> &ImmDefMIs,
207+
bool &Deleted);
206208

207209
/// Finds recurrence cycles, but only ones that formulated around
208210
/// a def operand and a use operand that are tied. If there is a use
@@ -214,11 +216,10 @@ namespace {
214216

215217
/// If copy instruction \p MI is a virtual register copy or a copy of a
216218
/// constant physical register to a virtual register, track it in the
217-
/// set \p CopyMIs. If this virtual register was previously seen as a
219+
/// set CopySrcMIs. If this virtual register was previously seen as a
218220
/// copy, replace the uses of this copy with the previously seen copy's
219221
/// destination register.
220-
bool foldRedundantCopy(MachineInstr &MI,
221-
DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs);
222+
bool foldRedundantCopy(MachineInstr &MI);
222223

223224
/// Is the register \p Reg a non-allocatable physical register?
224225
bool isNAPhysCopy(Register Reg);
@@ -255,6 +256,49 @@ namespace {
255256

256257
MachineInstr &rewriteSource(MachineInstr &CopyLike,
257258
RegSubRegPair Def, RewriteMapTy &RewriteMap);
259+
260+
// Set of copies to virtual registers keyed by source register. Never
261+
// holds any physreg which requires def tracking.
262+
DenseMap<RegSubRegPair, MachineInstr *> CopySrcMIs;
263+
264+
// MachineFunction::Delegate implementation. Used to maintain CopySrcMIs.
265+
void MF_HandleInsertion(MachineInstr &MI) override {
266+
return;
267+
}
268+
269+
bool getCopySrc(MachineInstr &MI, RegSubRegPair &SrcPair) {
270+
if (!MI.isCopy())
271+
return false;
272+
273+
Register SrcReg = MI.getOperand(1).getReg();
274+
unsigned SrcSubReg = MI.getOperand(1).getSubReg();
275+
if (!SrcReg.isVirtual() && !MRI->isConstantPhysReg(SrcReg))
276+
return false;
277+
278+
SrcPair = RegSubRegPair(SrcReg, SrcSubReg);
279+
return true;
280+
}
281+
282+
// If a COPY instruction is to be deleted or changed, we should also remove
283+
// it from CopySrcMIs.
284+
void deleteChangedCopy(MachineInstr &MI) {
285+
RegSubRegPair SrcPair;
286+
if (!getCopySrc(MI, SrcPair))
287+
return;
288+
289+
auto It = CopySrcMIs.find(SrcPair);
290+
if (It != CopySrcMIs.end() && It->second == &MI)
291+
CopySrcMIs.erase(It);
292+
}
293+
294+
void MF_HandleRemoval(MachineInstr &MI) override {
295+
deleteChangedCopy(MI);
296+
}
297+
298+
void MF_HandleChangeDesc(MachineInstr &MI, const MCInstrDesc &TID) override
299+
{
300+
deleteChangedCopy(MI);
301+
}
258302
};
259303

260304
/// Helper class to hold instructions that are inside recurrence cycles.
@@ -1351,26 +1395,28 @@ bool PeepholeOptimizer::isMoveImmediate(
13511395
MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
13521396
DenseMap<Register, MachineInstr *> &ImmDefMIs) {
13531397
const MCInstrDesc &MCID = MI.getDesc();
1354-
if (!MI.isMoveImmediate())
1355-
return false;
1356-
if (MCID.getNumDefs() != 1)
1398+
if (MCID.getNumDefs() != 1 || !MI.getOperand(0).isReg())
13571399
return false;
13581400
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-
}
1401+
if (!Reg.isVirtual())
1402+
return false;
13641403

1365-
return false;
1404+
int64_t ImmVal;
1405+
if (!MI.isMoveImmediate() && !TII->getConstValDefinedInReg(MI, Reg, ImmVal))
1406+
return false;
1407+
1408+
ImmDefMIs.insert(std::make_pair(Reg, &MI));
1409+
ImmDefRegs.insert(Reg);
1410+
return true;
13661411
}
13671412

13681413
/// Try folding register operands that are defined by move immediate
13691414
/// instructions, i.e. a trivial constant folding optimization, if
13701415
/// and only if the def and use are in the same BB.
13711416
bool PeepholeOptimizer::foldImmediate(
13721417
MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
1373-
DenseMap<Register, MachineInstr *> &ImmDefMIs) {
1418+
DenseMap<Register, MachineInstr *> &ImmDefMIs, bool &Deleted) {
1419+
Deleted = false;
13741420
for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) {
13751421
MachineOperand &MO = MI.getOperand(i);
13761422
if (!MO.isReg() || MO.isDef())
@@ -1384,6 +1430,19 @@ bool PeepholeOptimizer::foldImmediate(
13841430
assert(II != ImmDefMIs.end() && "couldn't find immediate definition");
13851431
if (TII->FoldImmediate(MI, *II->second, Reg, MRI)) {
13861432
++NumImmFold;
1433+
// FoldImmediate can delete ImmDefMI if MI was its only user. If ImmDefMI
1434+
// is not deleted, and we happened to get a same MI, we can delete MI and
1435+
// replace its users.
1436+
if (MRI->getVRegDef(Reg) &&
1437+
MI.isIdenticalTo(*II->second, MachineInstr::IgnoreVRegDefs)) {
1438+
Register DstReg = MI.getOperand(0).getReg();
1439+
if (DstReg.isVirtual() &&
1440+
MRI->getRegClass(DstReg) == MRI->getRegClass(Reg)) {
1441+
MRI->replaceRegWith(DstReg, Reg);
1442+
MI.eraseFromParent();
1443+
Deleted = true;
1444+
}
1445+
}
13871446
return true;
13881447
}
13891448
}
@@ -1404,29 +1463,25 @@ bool PeepholeOptimizer::foldImmediate(
14041463
// %2 = COPY %0:sub1
14051464
//
14061465
// Should replace %2 uses with %1:sub1
1407-
bool PeepholeOptimizer::foldRedundantCopy(
1408-
MachineInstr &MI, DenseMap<RegSubRegPair, MachineInstr *> &CopyMIs) {
1466+
bool PeepholeOptimizer::foldRedundantCopy(MachineInstr &MI) {
14091467
assert(MI.isCopy() && "expected a COPY machine instruction");
14101468

1411-
Register SrcReg = MI.getOperand(1).getReg();
1412-
unsigned SrcSubReg = MI.getOperand(1).getSubReg();
1413-
if (!SrcReg.isVirtual() && !MRI->isConstantPhysReg(SrcReg))
1469+
RegSubRegPair SrcPair;
1470+
if (!getCopySrc(MI, SrcPair))
14141471
return false;
14151472

14161473
Register DstReg = MI.getOperand(0).getReg();
14171474
if (!DstReg.isVirtual())
14181475
return false;
14191476

1420-
RegSubRegPair SrcPair(SrcReg, SrcSubReg);
1421-
1422-
if (CopyMIs.insert(std::make_pair(SrcPair, &MI)).second) {
1477+
if (CopySrcMIs.insert(std::make_pair(SrcPair, &MI)).second) {
14231478
// First copy of this reg seen.
14241479
return false;
14251480
}
14261481

1427-
MachineInstr *PrevCopy = CopyMIs.find(SrcPair)->second;
1482+
MachineInstr *PrevCopy = CopySrcMIs.find(SrcPair)->second;
14281483

1429-
assert(SrcSubReg == PrevCopy->getOperand(1).getSubReg() &&
1484+
assert(SrcPair.SubReg == PrevCopy->getOperand(1).getSubReg() &&
14301485
"Unexpected mismatching subreg!");
14311486

14321487
Register PrevDstReg = PrevCopy->getOperand(0).getReg();
@@ -1617,6 +1672,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
16171672
MRI = &MF.getRegInfo();
16181673
DT = Aggressive ? &getAnalysis<MachineDominatorTree>() : nullptr;
16191674
MLI = &getAnalysis<MachineLoopInfo>();
1675+
MF.setDelegate(this);
16201676

16211677
bool Changed = false;
16221678

@@ -1641,9 +1697,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
16411697
// without any intervening re-definition of $physreg.
16421698
DenseMap<Register, MachineInstr *> NAPhysToVirtMIs;
16431699

1644-
// Set of copies to virtual registers keyed by source register. Never
1645-
// holds any physreg which requires def tracking.
1646-
DenseMap<RegSubRegPair, MachineInstr *> CopySrcMIs;
1700+
CopySrcMIs.clear();
16471701

16481702
bool IsLoopHeader = MLI->isLoopHeader(&MBB);
16491703

@@ -1732,7 +1786,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
17321786
continue;
17331787
}
17341788

1735-
if (MI->isCopy() && (foldRedundantCopy(*MI, CopySrcMIs) ||
1789+
if (MI->isCopy() && (foldRedundantCopy(*MI) ||
17361790
foldRedundantNAPhysCopy(*MI, NAPhysToVirtMIs))) {
17371791
LocalMIs.erase(MI);
17381792
LLVM_DEBUG(dbgs() << "Deleting redundant copy: " << *MI << "\n");
@@ -1750,8 +1804,14 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
17501804
// next iteration sees the new instructions.
17511805
MII = MI;
17521806
++MII;
1753-
if (SeenMoveImm)
1754-
Changed |= foldImmediate(*MI, ImmDefRegs, ImmDefMIs);
1807+
if (SeenMoveImm) {
1808+
bool Deleted;
1809+
Changed |= foldImmediate(*MI, ImmDefRegs, ImmDefMIs, Deleted);
1810+
if (Deleted) {
1811+
LocalMIs.erase(MI);
1812+
continue;
1813+
}
1814+
}
17551815
}
17561816

17571817
// Check whether MI is a load candidate for folding into a later
@@ -1815,6 +1875,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
18151875
}
18161876
}
18171877

1878+
MF.resetDelegate(this);
18181879
return Changed;
18191880
}
18201881

0 commit comments

Comments
 (0)