40
40
41
41
#include " CodeGenTarget.h"
42
42
#include " PredicateExpander.h"
43
- #include " llvm/ADT/SmallVector.h"
44
43
#include " llvm/Support/Debug.h"
45
44
#include " llvm/TableGen/Error.h"
46
45
#include " llvm/TableGen/Record.h"
47
46
#include " llvm/TableGen/TableGenBackend.h"
48
- #include < set>
49
47
#include < vector>
50
48
51
49
using namespace llvm ;
@@ -61,14 +59,14 @@ class MacroFusionPredicatorEmitter {
61
59
raw_ostream &OS);
62
60
void emitMacroFusionImpl (std::vector<Record *> Fusions, PredicateExpander &PE,
63
61
raw_ostream &OS);
64
- void emitPredicates (std::vector<Record *> &FirstPredicate,
62
+ void emitPredicates (std::vector<Record *> &FirstPredicate, bool IsCommutable,
65
63
PredicateExpander &PE, raw_ostream &OS);
66
- void emitFirstPredicate (Record *SecondPredicate, PredicateExpander &PE ,
67
- raw_ostream &OS);
68
- void emitSecondPredicate (Record *SecondPredicate, PredicateExpander &PE ,
69
- raw_ostream &OS);
70
- void emitBothPredicate (Record *Predicates, PredicateExpander &PE ,
71
- raw_ostream &OS);
64
+ void emitFirstPredicate (Record *SecondPredicate, bool IsCommutable ,
65
+ PredicateExpander &PE, raw_ostream &OS);
66
+ void emitSecondPredicate (Record *SecondPredicate, bool IsCommutable ,
67
+ PredicateExpander &PE, raw_ostream &OS);
68
+ void emitBothPredicate (Record *Predicates, bool IsCommutable ,
69
+ PredicateExpander &PE, raw_ostream &OS);
72
70
73
71
public:
74
72
MacroFusionPredicatorEmitter (RecordKeeper &R) : Records(R), Target(R) {}
@@ -103,6 +101,7 @@ void MacroFusionPredicatorEmitter::emitMacroFusionImpl(
103
101
for (Record *Fusion : Fusions) {
104
102
std::vector<Record *> Predicates =
105
103
Fusion->getValueAsListOfDefs (" Predicates" );
104
+ bool IsCommutable = Fusion->getValueAsBit (" IsCommutable" );
106
105
107
106
OS << " bool is" << Fusion->getName () << " (\n " ;
108
107
OS.indent (4 ) << " const TargetInstrInfo &TII,\n " ;
@@ -111,7 +110,7 @@ void MacroFusionPredicatorEmitter::emitMacroFusionImpl(
111
110
OS.indent (4 ) << " const MachineInstr &SecondMI) {\n " ;
112
111
OS.indent (2 ) << " auto &MRI = SecondMI.getMF()->getRegInfo();\n " ;
113
112
114
- emitPredicates (Predicates, PE, OS);
113
+ emitPredicates (Predicates, IsCommutable, PE, OS);
115
114
116
115
OS.indent (2 ) << " return true;\n " ;
117
116
OS << " }\n " ;
@@ -122,22 +121,24 @@ void MacroFusionPredicatorEmitter::emitMacroFusionImpl(
122
121
}
123
122
124
123
void MacroFusionPredicatorEmitter::emitPredicates (
125
- std::vector<Record *> &Predicates, PredicateExpander &PE, raw_ostream &OS) {
124
+ std::vector<Record *> &Predicates, bool IsCommutable, PredicateExpander &PE,
125
+ raw_ostream &OS) {
126
126
for (Record *Predicate : Predicates) {
127
127
Record *Target = Predicate->getValueAsDef (" Target" );
128
128
if (Target->getName () == " first_fusion_target" )
129
- emitFirstPredicate (Predicate, PE, OS);
129
+ emitFirstPredicate (Predicate, IsCommutable, PE, OS);
130
130
else if (Target->getName () == " second_fusion_target" )
131
- emitSecondPredicate (Predicate, PE, OS);
131
+ emitSecondPredicate (Predicate, IsCommutable, PE, OS);
132
132
else if (Target->getName () == " both_fusion_target" )
133
- emitBothPredicate (Predicate, PE, OS);
133
+ emitBothPredicate (Predicate, IsCommutable, PE, OS);
134
134
else
135
135
PrintFatalError (Target->getLoc (),
136
136
" Unsupported 'FusionTarget': " + Target->getName ());
137
137
}
138
138
}
139
139
140
140
void MacroFusionPredicatorEmitter::emitFirstPredicate (Record *Predicate,
141
+ bool IsCommutable,
141
142
PredicateExpander &PE,
142
143
raw_ostream &OS) {
143
144
if (Predicate->isSubClassOf (" WildcardPred" )) {
@@ -170,6 +171,7 @@ void MacroFusionPredicatorEmitter::emitFirstPredicate(Record *Predicate,
170
171
}
171
172
172
173
void MacroFusionPredicatorEmitter::emitSecondPredicate (Record *Predicate,
174
+ bool IsCommutable,
173
175
PredicateExpander &PE,
174
176
raw_ostream &OS) {
175
177
if (Predicate->isSubClassOf (" FusionPredicateWithMCInstPredicate" )) {
@@ -182,6 +184,36 @@ void MacroFusionPredicatorEmitter::emitSecondPredicate(Record *Predicate,
182
184
OS << " )\n " ;
183
185
OS.indent (4 ) << " return false;\n " ;
184
186
OS.indent (2 ) << " }\n " ;
187
+ } else if (Predicate->isSubClassOf (" SameReg" )) {
188
+ int FirstOpIdx = Predicate->getValueAsInt (" FirstOpIdx" );
189
+ int SecondOpIdx = Predicate->getValueAsInt (" SecondOpIdx" );
190
+
191
+ OS.indent (2 ) << " if (!SecondMI.getOperand(" << FirstOpIdx
192
+ << " ).getReg().isVirtual()) {\n " ;
193
+ OS.indent (4 ) << " if (SecondMI.getOperand(" << FirstOpIdx
194
+ << " ).getReg() != SecondMI.getOperand(" << SecondOpIdx
195
+ << " ).getReg())" ;
196
+
197
+ if (IsCommutable) {
198
+ OS << " {\n " ;
199
+ OS.indent (6 ) << " if (!SecondMI.getDesc().isCommutable())\n " ;
200
+ OS.indent (6 ) << " return false;\n " ;
201
+
202
+ OS.indent (6 )
203
+ << " unsigned SrcOpIdx1 = " << SecondOpIdx
204
+ << " , SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;\n " ;
205
+ OS.indent (6 )
206
+ << " if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))\n " ;
207
+ OS.indent (6 )
208
+ << " if (SecondMI.getOperand(" << FirstOpIdx
209
+ << " ).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())\n " ;
210
+ OS.indent (6 ) << " return false;\n " ;
211
+ OS.indent (4 ) << " }\n " ;
212
+ } else {
213
+ OS << " \n " ;
214
+ OS.indent (4 ) << " return false;\n " ;
215
+ }
216
+ OS.indent (2 ) << " }\n " ;
185
217
} else {
186
218
PrintFatalError (Predicate->getLoc (),
187
219
" Unsupported predicate for second instruction: " +
@@ -190,13 +222,14 @@ void MacroFusionPredicatorEmitter::emitSecondPredicate(Record *Predicate,
190
222
}
191
223
192
224
void MacroFusionPredicatorEmitter::emitBothPredicate (Record *Predicate,
225
+ bool IsCommutable,
193
226
PredicateExpander &PE,
194
227
raw_ostream &OS) {
195
228
if (Predicate->isSubClassOf (" FusionPredicateWithCode" ))
196
229
OS << Predicate->getValueAsString (" Predicate" );
197
230
else if (Predicate->isSubClassOf (" BothFusionPredicateWithMCInstPredicate" )) {
198
- emitFirstPredicate (Predicate, PE, OS);
199
- emitSecondPredicate (Predicate, PE, OS);
231
+ emitFirstPredicate (Predicate, IsCommutable, PE, OS);
232
+ emitSecondPredicate (Predicate, IsCommutable, PE, OS);
200
233
} else if (Predicate->isSubClassOf (" TieReg" )) {
201
234
int FirstOpIdx = Predicate->getValueAsInt (" FirstOpIdx" );
202
235
int SecondOpIdx = Predicate->getValueAsInt (" SecondOpIdx" );
@@ -206,8 +239,28 @@ void MacroFusionPredicatorEmitter::emitBothPredicate(Record *Predicate,
206
239
<< " ).isReg() &&\n " ;
207
240
OS.indent (2 ) << " FirstMI->getOperand(" << FirstOpIdx
208
241
<< " ).getReg() == SecondMI.getOperand(" << SecondOpIdx
209
- << " ).getReg()))\n " ;
210
- OS.indent (2 ) << " return false;\n " ;
242
+ << " ).getReg()))" ;
243
+
244
+ if (IsCommutable) {
245
+ OS << " {\n " ;
246
+ OS.indent (4 ) << " if (!SecondMI.getDesc().isCommutable())\n " ;
247
+ OS.indent (4 ) << " return false;\n " ;
248
+
249
+ OS.indent (4 )
250
+ << " unsigned SrcOpIdx1 = " << SecondOpIdx
251
+ << " , SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;\n " ;
252
+ OS.indent (4 )
253
+ << " if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))\n " ;
254
+ OS.indent (4 )
255
+ << " if (FirstMI->getOperand(" << FirstOpIdx
256
+ << " ).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())\n " ;
257
+ OS.indent (4 ) << " return false;\n " ;
258
+ OS.indent (2 ) << " }" ;
259
+ } else {
260
+ OS << " \n " ;
261
+ OS.indent (2 ) << " return false;" ;
262
+ }
263
+ OS << " \n " ;
211
264
} else
212
265
PrintFatalError (Predicate->getLoc (),
213
266
" Unsupported predicate for both instruction: " +
0 commit comments