Skip to content

Commit 9570bf9

Browse files
authored
[TableGen][MacroFusion] Predicate if the first inst has the same register (llvm#137778)
We rename `SameReg` to `SecondInstHasSameReg ` and add `FirstInstHasSameReg ` which has the logic but applies to the first instruction. We have some cases that require the first instruction has the same input/output register.
1 parent c14acb7 commit 9570bf9

File tree

3 files changed

+72
-6
lines changed

3 files changed

+72
-6
lines changed

llvm/include/llvm/Target/TargetMacroFusion.td

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,20 @@ class TieReg<int firstOpIdx, int secondOpIdx> : BothFusionPredicate {
5555
int SecondOpIdx = secondOpIdx;
5656
}
5757

58+
// The operand of `FirstMI` at position `firstOpIdx` should be the same as the
59+
// operand at position `secondOpIdx`.
60+
// If the fusion has `IsCommutable` being true and the operand at `secondOpIdx`
61+
// has commutable operand, then the commutable operand will be checked too.
62+
class FirstInstHasSameReg<int firstOpIdx, int secondOpIdx> : FirstFusionPredicate {
63+
int FirstOpIdx = firstOpIdx;
64+
int SecondOpIdx = secondOpIdx;
65+
}
66+
5867
// The operand of `SecondMI` at position `firstOpIdx` should be the same as the
5968
// operand at position `secondOpIdx`.
6069
// If the fusion has `IsCommutable` being true and the operand at `secondOpIdx`
6170
// has commutable operand, then the commutable operand will be checked too.
62-
class SameReg<int firstOpIdx, int secondOpIdx> : SecondFusionPredicate {
71+
class SecondInstHasSameReg<int firstOpIdx, int secondOpIdx> : SecondFusionPredicate {
6372
int FirstOpIdx = firstOpIdx;
6473
int SecondOpIdx = secondOpIdx;
6574
}
@@ -129,7 +138,7 @@ class SimpleFusion<string name, string fieldName, string desc,
129138
SecondFusionPredicateWithMCInstPredicate<secondPred>,
130139
WildcardTrue,
131140
FirstFusionPredicateWithMCInstPredicate<firstPred>,
132-
SameReg<0, 1>,
141+
SecondInstHasSameReg<0, 1>,
133142
OneUse,
134143
TieReg<0, 1>,
135144
],

llvm/test/TableGen/MacroFusion.td

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,19 @@ def TestSingleFusion: SingleFusion<"test-single-fusion", "HasTestSingleFusion",
6262
Inst0, Inst2,
6363
secondInstPred=CheckRegOperand<0, X0>>;
6464

65+
def TestFirstSameRegFusion: Fusion<"test-first-same-reg-fusion", "HasTestFirstSameRegFusion",
66+
"Test FirstSameReg",
67+
[FirstInstHasSameReg<0, 1>]> {
68+
bit IsCommutable = 1;
69+
}
70+
6571
// CHECK-PREDICATOR: #ifdef GET_Test_MACRO_FUSION_PRED_DECL
6672
// CHECK-PREDICATOR-NEXT: #undef GET_Test_MACRO_FUSION_PRED_DECL
6773
// CHECK-PREDICATOR-EMPTY:
6874
// CHECK-PREDICATOR-NEXT: namespace llvm {
6975
// CHECK-PREDICATOR-NEXT: bool isTestBothFusionPredicate(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
70-
// CHECK-PREDICATOR-NEXT: bool isTestCommutableFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
76+
// CHECK-PREDICATOR-NEXT: bool isTestCommutableFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
77+
// CHECK-PREDICATOR-NEXT: bool isTestFirstSameRegFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
7178
// CHECK-PREDICATOR-NEXT: bool isTestFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
7279
// CHECK-PREDICATOR-NEXT: bool isTestSingleFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
7380
// CHECK-PREDICATOR-NEXT: } // end namespace llvm
@@ -144,6 +151,24 @@ def TestSingleFusion: SingleFusion<"test-single-fusion", "HasTestSingleFusion",
144151
// CHECK-PREDICATOR-NEXT: }
145152
// CHECK-PREDICATOR-NEXT: return true;
146153
// CHECK-PREDICATOR-NEXT: }
154+
// CHECK-PREDICATOR-NEXT: bool isTestFirstSameRegFusion(
155+
// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII,
156+
// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI,
157+
// CHECK-PREDICATOR-NEXT: const MachineInstr *FirstMI,
158+
// CHECK-PREDICATOR-NEXT: const MachineInstr &SecondMI) {
159+
// CHECK-PREDICATOR-NEXT: {{[[]}}{{[[]}}maybe_unused{{[]]}}{{[]]}} auto &MRI = SecondMI.getMF()->getRegInfo();
160+
// CHECK-PREDICATOR-NEXT: if (!FirstMI->getOperand(0).getReg().isVirtual()) {
161+
// CHECK-PREDICATOR-NEXT: if (FirstMI->getOperand(0).getReg() != FirstMI->getOperand(1).getReg()) {
162+
// CHECK-PREDICATOR-NEXT: if (!FirstMI->getDesc().isCommutable())
163+
// CHECK-PREDICATOR-NEXT: return false;
164+
// CHECK-PREDICATOR-NEXT: unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
165+
// CHECK-PREDICATOR-NEXT: if (TII.findCommutedOpIndices(FirstMI, SrcOpIdx1, SrcOpIdx2))
166+
// CHECK-PREDICATOR-NEXT: if (FirstMI->getOperand(0).getReg() != FirstMI->getOperand(SrcOpIdx2).getReg())
167+
// CHECK-PREDICATOR-NEXT: return false;
168+
// CHECK-PREDICATOR-NEXT: }
169+
// CHECK-PREDICATOR-NEXT: }
170+
// CHECK-PREDICATOR-NEXT: return true;
171+
// CHECK-PREDICATOR-NEXT: }
147172
// CHECK-PREDICATOR-NEXT: bool isTestFusion(
148173
// CHECK-PREDICATOR-NEXT: const TargetInstrInfo &TII,
149174
// CHECK-PREDICATOR-NEXT: const TargetSubtargetInfo &STI,
@@ -238,6 +263,7 @@ def TestSingleFusion: SingleFusion<"test-single-fusion", "HasTestSingleFusion",
238263
// Check that we have generated target subfeature.
239264
// CHECK-SUBTARGET: { "test-both-fusion-predicate", "Test BothFusionPredicate", Test::TestBothFusionPredicate
240265
// CHECK-SUBTARGET: { "test-commutable-fusion", "Test Commutable Fusion", Test::TestCommutableFusion
266+
// CHECK-SUBTARGET: { "test-first-same-reg-fusion", "Test FirstSameReg", Test::TestFirstSameRegFusion
241267
// CHECK-SUBTARGET: { "test-fusion", "Test Fusion", Test::TestFusion
242268
// CHECK-SUBTARGET: { "test-single-fusion", "Test SingleFusion", Test::TestSingleFusion
243269

@@ -246,8 +272,9 @@ def TestSingleFusion: SingleFusion<"test-single-fusion", "HasTestSingleFusion",
246272

247273
// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> TestGenSubtargetInfo::getMacroFusions() const {
248274
// CHECK-SUBTARGET-NEXT: std::vector<MacroFusionPredTy> Fusions;
249-
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestBothFusionPredicate)) Fusions.push_back(llvm::isTestBothFusionPredicate);
250-
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestCommutableFusion)) Fusions.push_back(llvm::isTestCommutableFusion);
275+
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestBothFusionPredicate)) Fusions.push_back(llvm::isTestBothFusionPredicate);
276+
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestCommutableFusion)) Fusions.push_back(llvm::isTestCommutableFusion);
277+
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFirstSameRegFusion)) Fusions.push_back(llvm::isTestFirstSameRegFusion);
251278
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) Fusions.push_back(llvm::isTestFusion);
252279
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestSingleFusion)) Fusions.push_back(llvm::isTestSingleFusion);
253280
// CHECK-SUBTARGET-NEXT: return Fusions;

llvm/utils/TableGen/MacroFusionPredicatorEmitter.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,36 @@ void MacroFusionPredicatorEmitter::emitFirstPredicate(const Record *Predicate,
155155
<< "if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))\n";
156156
OS.indent(4) << " return false;\n";
157157
OS.indent(2) << "}\n";
158+
} else if (Predicate->isSubClassOf("FirstInstHasSameReg")) {
159+
int FirstOpIdx = Predicate->getValueAsInt("FirstOpIdx");
160+
int SecondOpIdx = Predicate->getValueAsInt("SecondOpIdx");
161+
162+
OS.indent(2) << "if (!FirstMI->getOperand(" << FirstOpIdx
163+
<< ").getReg().isVirtual()) {\n";
164+
OS.indent(4) << "if (FirstMI->getOperand(" << FirstOpIdx
165+
<< ").getReg() != FirstMI->getOperand(" << SecondOpIdx
166+
<< ").getReg())";
167+
168+
if (IsCommutable) {
169+
OS << " {\n";
170+
OS.indent(6) << "if (!FirstMI->getDesc().isCommutable())\n";
171+
OS.indent(6) << " return false;\n";
172+
173+
OS.indent(6)
174+
<< "unsigned SrcOpIdx1 = " << SecondOpIdx
175+
<< ", SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;\n";
176+
OS.indent(6)
177+
<< "if (TII.findCommutedOpIndices(FirstMI, SrcOpIdx1, SrcOpIdx2))\n";
178+
OS.indent(6)
179+
<< " if (FirstMI->getOperand(" << FirstOpIdx
180+
<< ").getReg() != FirstMI->getOperand(SrcOpIdx2).getReg())\n";
181+
OS.indent(6) << " return false;\n";
182+
OS.indent(4) << "}\n";
183+
} else {
184+
OS << "\n";
185+
OS.indent(4) << " return false;\n";
186+
}
187+
OS.indent(2) << "}\n";
158188
} else if (Predicate->isSubClassOf("FusionPredicateWithMCInstPredicate")) {
159189
OS.indent(2) << "{\n";
160190
OS.indent(4) << "const MachineInstr *MI = FirstMI;\n";
@@ -186,7 +216,7 @@ void MacroFusionPredicatorEmitter::emitSecondPredicate(const Record *Predicate,
186216
OS << ")\n";
187217
OS.indent(4) << " return false;\n";
188218
OS.indent(2) << "}\n";
189-
} else if (Predicate->isSubClassOf("SameReg")) {
219+
} else if (Predicate->isSubClassOf("SecondInstHasSameReg")) {
190220
int FirstOpIdx = Predicate->getValueAsInt("FirstOpIdx");
191221
int SecondOpIdx = Predicate->getValueAsInt("SecondOpIdx");
192222

0 commit comments

Comments
 (0)