Skip to content

Commit 8a038f5

Browse files
committed
[MacroFusion] Add IsPostRA to MacroFusionPredTy
This can save some time to know whether MacroFusion mutation is running in post-ra scheduler. And this can be used in llvm#77461.
1 parent 8f78dd4 commit 8a038f5

File tree

12 files changed

+78
-66
lines changed

12 files changed

+78
-66
lines changed

llvm/include/llvm/CodeGen/MacroFusion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class SUnit;
3232
using MacroFusionPredTy = bool (*)(const TargetInstrInfo &TII,
3333
const TargetSubtargetInfo &STI,
3434
const MachineInstr *FirstMI,
35-
const MachineInstr &SecondMI);
35+
const MachineInstr &SecondMI, bool IsPostRA);
3636

3737
/// Checks if the number of cluster edges between SU and its predecessors is
3838
/// less than FuseLimit

llvm/include/llvm/Target/TargetSchedule.td

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ def both_fusion_target : FusionTarget;
597597
// * const MachineRegisterInfo &MRI
598598
// * const MachineInstr *FirstMI
599599
// * const MachineInstr &SecondMI
600+
// * bool IsPostRA
600601
class FusionPredicate<FusionTarget target> {
601602
FusionTarget Target = target;
602603
}
@@ -642,10 +643,16 @@ def WildcardFalse : WildcardPred<0>;
642643
def WildcardTrue : WildcardPred<1>;
643644

644645
// Indicates that the destination register of `FirstMI` should have one use if
645-
// it is a virtual register.
646+
// it is a virtual register (fusion is done in pre-ra scheduler).
646647
class OneUsePred : FirstFusionPredicate;
647648
def OneUse : OneUsePred;
648649

650+
// Indicates that the first register of `SecondMI` should be the same as the
651+
// second register if it is a physical register (fusion is done in post-ra
652+
// scheduler).
653+
class SameRegisterPred : SecondFusionPredicate;
654+
def SameRegister : SameRegisterPred;
655+
649656
// Handled by MacroFusionPredicatorEmitter backend.
650657
// The generated predicator will be like:
651658
// ```
@@ -688,11 +695,7 @@ class SimpleFusion<MCInstPredicate firstPred, MCInstPredicate secondPred,
688695
SecondFusionPredicateWithMCInstPredicate<secondPred>,
689696
WildcardTrue,
690697
FirstFusionPredicateWithMCInstPredicate<firstPred>,
691-
SecondFusionPredicateWithMCInstPredicate<
692-
CheckAny<[
693-
CheckIsVRegOperand<0>,
694-
CheckSameRegOperand<0, 1>
695-
]>>,
698+
SameRegister,
696699
OneUse,
697700
TieReg<0, 1>,
698701
],

llvm/lib/CodeGen/MacroFusion.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,18 @@ class MacroFusion : public ScheduleDAGMutation {
151151
bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
152152
const TargetSubtargetInfo &STI,
153153
const MachineInstr *FirstMI,
154-
const MachineInstr &SecondMI);
154+
const MachineInstr &SecondMI, bool IsPostRA);
155155
};
156156

157157
} // end anonymous namespace
158158

159159
bool MacroFusion::shouldScheduleAdjacent(const TargetInstrInfo &TII,
160160
const TargetSubtargetInfo &STI,
161161
const MachineInstr *FirstMI,
162-
const MachineInstr &SecondMI) {
162+
const MachineInstr &SecondMI,
163+
bool IsPostRA) {
163164
return llvm::any_of(Predicates, [&](MacroFusionPredTy Predicate) {
164-
return Predicate(TII, STI, FirstMI, SecondMI);
165+
return Predicate(TII, STI, FirstMI, SecondMI, IsPostRA);
165166
});
166167
}
167168

@@ -183,9 +184,11 @@ bool MacroFusion::scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU)
183184
const MachineInstr &AnchorMI = *AnchorSU.getInstr();
184185
const TargetInstrInfo &TII = *DAG.TII;
185186
const TargetSubtargetInfo &ST = DAG.MF.getSubtarget();
187+
bool IsPostRA = DAG.MF.getProperties().hasProperty(
188+
MachineFunctionProperties::Property::NoVRegs);
186189

187190
// Check if the anchor instr may be fused.
188-
if (!shouldScheduleAdjacent(TII, ST, nullptr, AnchorMI))
191+
if (!shouldScheduleAdjacent(TII, ST, nullptr, AnchorMI, IsPostRA))
189192
return false;
190193

191194
// Explorer for fusion candidates among the dependencies of the anchor instr.
@@ -201,7 +204,7 @@ bool MacroFusion::scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU)
201204
// Only chain two instructions together at most.
202205
const MachineInstr *DepMI = DepSU.getInstr();
203206
if (!hasLessThanNumFused(DepSU, 2) ||
204-
!shouldScheduleAdjacent(TII, ST, DepMI, AnchorMI))
207+
!shouldScheduleAdjacent(TII, ST, DepMI, AnchorMI, IsPostRA))
205208
continue;
206209

207210
if (fuseInstructionPair(DAG, DepSU, AnchorSU))

llvm/lib/Target/AArch64/AArch64MacroFusion.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,8 @@ static bool isAddSub2RegAndConstOnePair(const MachineInstr *FirstMI,
443443
static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
444444
const TargetSubtargetInfo &TSI,
445445
const MachineInstr *FirstMI,
446-
const MachineInstr &SecondMI) {
446+
const MachineInstr &SecondMI,
447+
bool IsPostRA) {
447448
const AArch64Subtarget &ST = static_cast<const AArch64Subtarget&>(TSI);
448449

449450
// All checking functions assume that the 1st instr is a wildcard if it is

llvm/lib/Target/AMDGPU/AMDGPUMacroFusion.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ namespace {
2626
static bool shouldScheduleAdjacent(const TargetInstrInfo &TII_,
2727
const TargetSubtargetInfo &TSI,
2828
const MachineInstr *FirstMI,
29-
const MachineInstr &SecondMI) {
29+
const MachineInstr &SecondMI,
30+
bool IsPostRA) {
3031
const SIInstrInfo &TII = static_cast<const SIInstrInfo&>(TII_);
3132

3233
switch (SecondMI.getOpcode()) {

llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ bool llvm::checkVOPDRegConstraints(const SIInstrInfo &TII,
123123
static bool shouldScheduleVOPDAdjacent(const TargetInstrInfo &TII,
124124
const TargetSubtargetInfo &TSI,
125125
const MachineInstr *FirstMI,
126-
const MachineInstr &SecondMI) {
126+
const MachineInstr &SecondMI,
127+
bool IsPostRA) {
127128
const SIInstrInfo &STII = static_cast<const SIInstrInfo &>(TII);
128129
unsigned Opc2 = SecondMI.getOpcode();
129130
auto SecondCanBeVOPD = AMDGPU::getCanBeVOPD(Opc2);
@@ -165,7 +166,7 @@ struct VOPDPairingMutation : ScheduleDAGMutation {
165166
std::vector<SUnit>::iterator ISUI, JSUI;
166167
for (ISUI = DAG->SUnits.begin(); ISUI != DAG->SUnits.end(); ++ISUI) {
167168
const MachineInstr *IMI = ISUI->getInstr();
168-
if (!shouldScheduleAdjacent(TII, ST, nullptr, *IMI))
169+
if (!shouldScheduleAdjacent(TII, ST, nullptr, *IMI, /*IsPostRA=*/true))
169170
continue;
170171
if (!hasLessThanNumFused(*ISUI, 2))
171172
continue;
@@ -175,7 +176,7 @@ struct VOPDPairingMutation : ScheduleDAGMutation {
175176
continue;
176177
const MachineInstr *JMI = JSUI->getInstr();
177178
if (!hasLessThanNumFused(*JSUI, 2) ||
178-
!shouldScheduleAdjacent(TII, ST, IMI, *JMI))
179+
!shouldScheduleAdjacent(TII, ST, IMI, *JMI, /*IsPostRA=*/true))
179180
continue;
180181
if (fuseInstructionPair(*DAG, *ISUI, *JSUI))
181182
break;

llvm/lib/Target/ARM/ARMMacroFusion.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ static bool isLiteralsPair(const MachineInstr *FirstMI,
5151
static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
5252
const TargetSubtargetInfo &TSI,
5353
const MachineInstr *FirstMI,
54-
const MachineInstr &SecondMI) {
54+
const MachineInstr &SecondMI,
55+
bool IsPostRA) {
5556
const ARMSubtarget &ST = static_cast<const ARMSubtarget&>(TSI);
5657

5758
if (ST.hasFuseAES() && isAESPair(FirstMI, SecondMI))

llvm/lib/Target/PowerPC/PPCMacroFusion.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ static bool checkOpConstraints(FusionFeature::FusionKind Kd,
234234
static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
235235
const TargetSubtargetInfo &TSI,
236236
const MachineInstr *FirstMI,
237-
const MachineInstr &SecondMI) {
237+
const MachineInstr &SecondMI,
238+
bool IsPostRA) {
238239
// We use the PPC namespace to avoid the need to prefix opcodes with PPC:: in
239240
// the def file.
240241
using namespace PPC;

llvm/lib/Target/RISCV/RISCVMacroFusion.cpp

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@
1818

1919
using namespace llvm;
2020

21-
static bool checkRegisters(Register FirstDest, const MachineInstr &SecondMI) {
21+
static bool checkRegisters(Register FirstDest, const MachineInstr &SecondMI,
22+
bool IsPostRA) {
2223
if (!SecondMI.getOperand(1).isReg())
2324
return false;
2425

2526
if (SecondMI.getOperand(1).getReg() != FirstDest)
2627
return false;
2728

2829
// If the input is virtual make sure this is the only user.
29-
if (FirstDest.isVirtual()) {
30+
if (!IsPostRA) {
3031
auto &MRI = SecondMI.getMF()->getRegInfo();
3132
return MRI.hasOneNonDBGUse(FirstDest);
3233
}
@@ -37,7 +38,8 @@ static bool checkRegisters(Register FirstDest, const MachineInstr &SecondMI) {
3738
// Fuse load with add:
3839
// add rd, rs1, rs2
3940
// ld rd, 0(rd)
40-
static bool isLDADD(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
41+
static bool isLDADD(const MachineInstr *FirstMI, const MachineInstr &SecondMI,
42+
bool IsPostRA) {
4143
if (SecondMI.getOpcode() != RISCV::LD)
4244
return false;
4345

@@ -55,13 +57,14 @@ static bool isLDADD(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
5557
if (FirstMI->getOpcode() != RISCV::ADD)
5658
return true;
5759

58-
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
60+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI, IsPostRA);
5961
}
6062

6163
// Fuse zero extension of halfword:
6264
// slli rd, rs1, 48
6365
// srli rd, rd, 48
64-
static bool isZExtH(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
66+
static bool isZExtH(const MachineInstr *FirstMI, const MachineInstr &SecondMI,
67+
bool IsPostRA) {
6568
if (SecondMI.getOpcode() != RISCV::SRLI)
6669
return false;
6770

@@ -82,13 +85,14 @@ static bool isZExtH(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
8285
if (FirstMI->getOperand(2).getImm() != 48)
8386
return false;
8487

85-
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
88+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI, IsPostRA);
8689
}
8790

8891
// Fuse zero extension of word:
8992
// slli rd, rs1, 32
9093
// srli rd, rd, 32
91-
static bool isZExtW(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
94+
static bool isZExtW(const MachineInstr *FirstMI, const MachineInstr &SecondMI,
95+
bool IsPostRA) {
9296
if (SecondMI.getOpcode() != RISCV::SRLI)
9397
return false;
9498

@@ -109,15 +113,15 @@ static bool isZExtW(const MachineInstr *FirstMI, const MachineInstr &SecondMI) {
109113
if (FirstMI->getOperand(2).getImm() != 32)
110114
return false;
111115

112-
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
116+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI, IsPostRA);
113117
}
114118

115119
// Fuse shifted zero extension of word:
116120
// slli rd, rs1, 32
117121
// srli rd, rd, x
118122
// where 0 <= x < 32
119123
static bool isShiftedZExtW(const MachineInstr *FirstMI,
120-
const MachineInstr &SecondMI) {
124+
const MachineInstr &SecondMI, bool IsPostRA) {
121125
if (SecondMI.getOpcode() != RISCV::SRLI)
122126
return false;
123127

@@ -139,14 +143,14 @@ static bool isShiftedZExtW(const MachineInstr *FirstMI,
139143
if (FirstMI->getOperand(2).getImm() != 32)
140144
return false;
141145

142-
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
146+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI, IsPostRA);
143147
}
144148

145149
// Fuse AUIPC followed by ADDI
146150
// auipc rd, imm20
147151
// addi rd, rd, imm12
148152
static bool isAUIPCADDI(const MachineInstr *FirstMI,
149-
const MachineInstr &SecondMI) {
153+
const MachineInstr &SecondMI, bool IsPostRA) {
150154
if (SecondMI.getOpcode() != RISCV::ADDI)
151155
return false;
152156
// Assume the 1st instr to be a wildcard if it is unspecified.
@@ -156,15 +160,15 @@ static bool isAUIPCADDI(const MachineInstr *FirstMI,
156160
if (FirstMI->getOpcode() != RISCV::AUIPC)
157161
return false;
158162

159-
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
163+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI, IsPostRA);
160164
}
161165

162166
// Fuse LUI followed by ADDI or ADDIW.
163167
// rd = imm[31:0] which decomposes to
164168
// lui rd, imm[31:12]
165169
// addi(w) rd, rd, imm[11:0]
166-
static bool isLUIADDI(const MachineInstr *FirstMI,
167-
const MachineInstr &SecondMI) {
170+
static bool isLUIADDI(const MachineInstr *FirstMI, const MachineInstr &SecondMI,
171+
bool IsPostRA) {
168172
if (SecondMI.getOpcode() != RISCV::ADDI &&
169173
SecondMI.getOpcode() != RISCV::ADDIW)
170174
return false;
@@ -175,31 +179,32 @@ static bool isLUIADDI(const MachineInstr *FirstMI,
175179
if (FirstMI->getOpcode() != RISCV::LUI)
176180
return false;
177181

178-
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI);
182+
return checkRegisters(FirstMI->getOperand(0).getReg(), SecondMI, IsPostRA);
179183
}
180184

181185
static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
182186
const TargetSubtargetInfo &TSI,
183187
const MachineInstr *FirstMI,
184-
const MachineInstr &SecondMI) {
188+
const MachineInstr &SecondMI,
189+
bool IsPostRA) {
185190
const RISCVSubtarget &ST = static_cast<const RISCVSubtarget &>(TSI);
186191

187-
if (ST.hasLUIADDIFusion() && isLUIADDI(FirstMI, SecondMI))
192+
if (ST.hasLUIADDIFusion() && isLUIADDI(FirstMI, SecondMI, IsPostRA))
188193
return true;
189194

190-
if (ST.hasAUIPCADDIFusion() && isAUIPCADDI(FirstMI, SecondMI))
195+
if (ST.hasAUIPCADDIFusion() && isAUIPCADDI(FirstMI, SecondMI, IsPostRA))
191196
return true;
192197

193-
if (ST.hasZExtHFusion() && isZExtH(FirstMI, SecondMI))
198+
if (ST.hasZExtHFusion() && isZExtH(FirstMI, SecondMI, IsPostRA))
194199
return true;
195200

196-
if (ST.hasZExtWFusion() && isZExtW(FirstMI, SecondMI))
201+
if (ST.hasZExtWFusion() && isZExtW(FirstMI, SecondMI, IsPostRA))
197202
return true;
198203

199-
if (ST.hasShiftedZExtWFusion() && isShiftedZExtW(FirstMI, SecondMI))
204+
if (ST.hasShiftedZExtWFusion() && isShiftedZExtW(FirstMI, SecondMI, IsPostRA))
200205
return true;
201206

202-
if (ST.hasLDADDFusion() && isLDADD(FirstMI, SecondMI))
207+
if (ST.hasLDADDFusion() && isLDADD(FirstMI, SecondMI, IsPostRA))
203208
return true;
204209

205210
return false;

llvm/lib/Target/X86/X86MacroFusion.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ static X86::SecondMacroFusionInstKind classifySecond(const MachineInstr &MI) {
3535
static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
3636
const TargetSubtargetInfo &TSI,
3737
const MachineInstr *FirstMI,
38-
const MachineInstr &SecondMI) {
38+
const MachineInstr &SecondMI,
39+
bool IsPostRA) {
3940
const X86Subtarget &ST = static_cast<const X86Subtarget &>(TSI);
4041

4142
// Check if this processor supports any kind of fusion.

llvm/test/TableGen/MacroFusion.td

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def TestFusion: SimpleFusion<CheckOpcode<[Inst0]>,
4343
// CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_DECL
4444
// CHECK-PREDICATOR-EMPTY:
4545
// CHECK-PREDICATOR-NEXT: namespace llvm {
46-
// CHECK-PREDICATOR-NEXT: bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
46+
// CHECK-PREDICATOR-NEXT: bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, bool);
4747
// CHECK-PREDICATOR-NEXT: } // end namespace llvm
4848
// CHECK-PREDICATOR-EMPTY:
4949
// CHECK-PREDICATOR-NEXT: #endif
@@ -56,7 +56,8 @@ def TestFusion: SimpleFusion<CheckOpcode<[Inst0]>,
5656
// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII,
5757
// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI,
5858
// CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI,
59-
// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) {
59+
// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI,
60+
// CHECK-PREDICATOR-NEXT: bool IsPostRA) {
6061
// CHECK-PREDICATOR-NEXT: auto &MRI = SecondMI.getMF()->getRegInfo();
6162
// CHECK-PREDICATOR-NEXT: {
6263
// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI;
@@ -73,19 +74,10 @@ def TestFusion: SimpleFusion<CheckOpcode<[Inst0]>,
7374
// CHECK-PREDICATOR-NEXT: if (( MI->getOpcode() != Test::Inst0 ))
7475
// CHECK-PREDICATOR-NEXT: return false;
7576
// CHECK-PREDICATOR-NEXT: }
76-
// CHECK-PREDICATOR-NEXT: {
77-
// CHECK-PREDICATOR-NEXT: const MachineInstr *MI = &SecondMI;
78-
// CHECK-PREDICATOR-NEXT: if (!(
79-
// CHECK-PREDICATOR-NEXT: MI->getOperand(0).getReg().isVirtual()
80-
// CHECK-PREDICATOR-NEXT: || MI->getOperand(0).getReg() == MI->getOperand(1).getReg()
81-
// CHECK-PREDICATOR-NEXT: ))
82-
// CHECK-PREDICATOR-NEXT: return false;
83-
// CHECK-PREDICATOR-NEXT: }
84-
// CHECK-PREDICATOR-NEXT: {
85-
// CHECK-PREDICATOR-NEXT: Register FirstDest = FirstMI->getOperand(0).getReg();
86-
// CHECK-PREDICATOR-NEXT: if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
87-
// CHECK-PREDICATOR-NEXT: return false;
88-
// CHECK-PREDICATOR-NEXT: }
77+
// CHECK-PREDICATOR-NEXT: if (IsPostRA && SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
78+
// CHECK-PREDICATOR-NEXT: return false;
79+
// CHECK-PREDICATOR-NEXT: if (!IsPostRA && !MRI.hasOneNonDBGUse(FirstMI->getOperand(0).getReg()))
80+
// CHECK-PREDICATOR-NEXT: return false;
8981
// CHECK-PREDICATOR-NEXT: if (!(FirstMI->getOperand(0).isReg() &&
9082
// CHECK-PREDICATOR-NEXT: SecondMI.getOperand(1).isReg() &&
9183
// CHECK-PREDICATOR-NEXT: FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))

0 commit comments

Comments
 (0)