Skip to content

Commit c649fd3

Browse files
[MachineSink][AArch64] Sink instruction copies when they can replace copy into hard register or folded into addressing mode
This patch adds a new code transformation to the `MachineSink` pass, that tries to sink copies of an instruction, when the copies can be folded into the addressing modes of load/store instructions, or replace another instruction (currently, copies into a hard register). The criteria for performing the transformation is that: * the register pressure at the sink destination block must not exceed the register pressure limits * the latency and throughput of the load/store or the copy must not deteriorate * the original instruction must be deleted Reviewed By: dmgreen Differential Revision: https://reviews.llvm.org/D152828
1 parent 0bfaed8 commit c649fd3

30 files changed

+1259
-265
lines changed

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,21 @@ struct RegImmPair {
8585

8686
/// Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
8787
/// It holds the register values, the scale value and the displacement.
88+
/// It also holds a descriptor for the expression used to calculate the address
89+
/// from the operands.
8890
struct ExtAddrMode {
91+
enum class Formula {
92+
Basic = 0, // BaseReg + ScaledReg * Scale + Displacement
93+
SExtScaledReg = 1, // BaseReg + sext(ScaledReg) * Scale + Displacement
94+
ZExtScaledReg = 2 // BaseReg + zext(ScaledReg) * Scale + Displacement
95+
};
96+
8997
Register BaseReg;
9098
Register ScaledReg;
91-
int64_t Scale;
92-
int64_t Displacement;
99+
int64_t Scale = 0;
100+
int64_t Displacement = 0;
101+
Formula Form = Formula::Basic;
102+
ExtAddrMode() = default;
93103
};
94104

95105
//---------------------------------------------------------------------------
@@ -1436,6 +1446,26 @@ class TargetInstrInfo : public MCInstrInfo {
14361446
return std::nullopt;
14371447
}
14381448

1449+
/// Check if it's possible and beneficial to fold the addressing computation
1450+
/// `AddrI` into the addressing mode of the load/store instruction `MemI`. The
1451+
/// memory instruction is a user of the virtual register `Reg`, which in turn
1452+
/// is the ultimate destination of zero or more COPY instructions from the
1453+
/// output register of `AddrI`.
1454+
/// Return the adddressing mode after folding in `AM`.
1455+
virtual bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg,
1456+
const MachineInstr &AddrI,
1457+
ExtAddrMode &AM) const {
1458+
return false;
1459+
}
1460+
1461+
/// Emit a load/store instruction with the same value register as `MemI`, but
1462+
/// using the address from `AM`. The addressing mode must have been obtained
1463+
/// from `canFoldIntoAddr` for the same memory instruction.
1464+
virtual MachineInstr *emitLdStWithAddr(MachineInstr &MemI,
1465+
const ExtAddrMode &AM) const {
1466+
llvm_unreachable("target did not implement emitLdStWithAddr()");
1467+
}
1468+
14391469
/// Returns true if MI's Def is NullValueReg, and the MI
14401470
/// does not change the Zero value. i.e. cases such as rax = shr rax, X where
14411471
/// NullValueReg = rax. Note that if the NullValueReg is non-zero, this

llvm/include/llvm/CodeGen/TargetPassConfig.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ class TargetPassConfig : public ImmutablePass {
130130
/// Default setting for -enable-tail-merge on this target.
131131
bool EnableTailMerge = true;
132132

133+
/// Enable sinking of instructions in MachineSink where a computation can be
134+
/// folded into the addressing mode of a memory load/store instruction or
135+
/// replace a copy.
136+
bool EnableSinkAndFold = false;
137+
133138
/// Require processing of functions such that callees are generated before
134139
/// callers.
135140
bool RequireCodeGenSCCOrder = false;
@@ -176,6 +181,9 @@ class TargetPassConfig : public ImmutablePass {
176181
bool getEnableTailMerge() const { return EnableTailMerge; }
177182
void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); }
178183

184+
bool getEnableSinkAndFold() const { return EnableSinkAndFold; }
185+
void setEnableSinkAndFold(bool Enable) { setOpt(EnableSinkAndFold, Enable); }
186+
179187
bool requiresCodeGenSCCOrder() const { return RequireCodeGenSCCOrder; }
180188
void setRequiresCodeGenSCCOrder(bool Enable = true) {
181189
setOpt(RequireCodeGenSCCOrder, Enable);

llvm/lib/CodeGen/ImplicitNullChecks.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ ImplicitNullChecks::isSuitableMemoryOp(const MachineInstr &MI,
372372
if (!MI.mayLoadOrStore() || MI.isPredicable())
373373
return SR_Unsuitable;
374374
auto AM = TII->getAddrModeFromMemoryOp(MI, TRI);
375-
if (!AM)
375+
if (!AM || AM->Form != ExtAddrMode::Formula::Basic)
376376
return SR_Unsuitable;
377377
auto AddrMode = *AM;
378378
const Register BaseReg = AddrMode.BaseReg, ScaledReg = AddrMode.ScaledReg;

0 commit comments

Comments
 (0)