1 //===--------------------- PredicateExpander.cpp --------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 /// Functionalities used by the Tablegen backends to expand machine predicates.
11 //===----------------------------------------------------------------------===//
13 #include "PredicateExpander.h"
14 #include "CodeGenSchedule.h" // Definition of STIPredicateFunction.
15 #include "llvm/TableGen/Record.h"
19 void PredicateExpander::expandTrue(raw_ostream
&OS
) { OS
<< "true"; }
20 void PredicateExpander::expandFalse(raw_ostream
&OS
) { OS
<< "false"; }
22 void PredicateExpander::expandCheckImmOperand(raw_ostream
&OS
, int OpIndex
,
24 StringRef FunctionMapper
) {
25 if (!FunctionMapper
.empty())
26 OS
<< FunctionMapper
<< "(";
27 OS
<< "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
29 if (!FunctionMapper
.empty())
31 OS
<< (shouldNegate() ? " != " : " == ") << ImmVal
;
34 void PredicateExpander::expandCheckImmOperand(raw_ostream
&OS
, int OpIndex
,
36 StringRef FunctionMapper
) {
38 expandCheckImmOperandSimple(OS
, OpIndex
, FunctionMapper
);
40 if (!FunctionMapper
.empty())
41 OS
<< FunctionMapper
<< "(";
42 OS
<< "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
44 if (!FunctionMapper
.empty())
46 OS
<< (shouldNegate() ? " != " : " == ") << ImmVal
;
49 void PredicateExpander::expandCheckImmOperandSimple(raw_ostream
&OS
,
51 StringRef FunctionMapper
) {
54 if (!FunctionMapper
.empty())
55 OS
<< FunctionMapper
<< "(";
56 OS
<< "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
58 if (!FunctionMapper
.empty())
62 void PredicateExpander::expandCheckImmOperandLT(raw_ostream
&OS
, int OpIndex
,
64 StringRef FunctionMapper
) {
65 if (!FunctionMapper
.empty())
66 OS
<< FunctionMapper
<< "(";
67 OS
<< "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
69 if (!FunctionMapper
.empty())
71 OS
<< (shouldNegate() ? " >= " : " < ") << ImmVal
;
74 void PredicateExpander::expandCheckImmOperandGT(raw_ostream
&OS
, int OpIndex
,
76 StringRef FunctionMapper
) {
77 if (!FunctionMapper
.empty())
78 OS
<< FunctionMapper
<< "(";
79 OS
<< "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
81 if (!FunctionMapper
.empty())
83 OS
<< (shouldNegate() ? " <= " : " > ") << ImmVal
;
86 void PredicateExpander::expandCheckRegOperand(raw_ostream
&OS
, int OpIndex
,
88 StringRef FunctionMapper
) {
89 assert(Reg
->isSubClassOf("Register") && "Expected a register Record!");
91 if (!FunctionMapper
.empty())
92 OS
<< FunctionMapper
<< "(";
93 OS
<< "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
95 if (!FunctionMapper
.empty())
97 OS
<< (shouldNegate() ? " != " : " == ");
98 const StringRef Str
= Reg
->getValueAsString("Namespace");
101 OS
<< Reg
->getName();
104 void PredicateExpander::expandCheckRegOperandSimple(raw_ostream
&OS
,
106 StringRef FunctionMapper
) {
109 if (!FunctionMapper
.empty())
110 OS
<< FunctionMapper
<< "(";
111 OS
<< "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
113 if (!FunctionMapper
.empty())
117 void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream
&OS
,
121 OS
<< "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
122 << ").getReg().isValid()";
125 void PredicateExpander::expandCheckSameRegOperand(raw_ostream
&OS
, int First
,
127 OS
<< "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
128 << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
129 << (isByRef() ? "." : "->") << "getOperand(" << Second
<< ").getReg()";
132 void PredicateExpander::expandCheckNumOperands(raw_ostream
&OS
, int NumOps
) {
133 OS
<< "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
134 << (shouldNegate() ? "!= " : "== ") << NumOps
;
137 void PredicateExpander::expandCheckOpcode(raw_ostream
&OS
, const Record
*Inst
) {
138 OS
<< "MI" << (isByRef() ? "." : "->") << "getOpcode() "
139 << (shouldNegate() ? "!= " : "== ") << Inst
->getValueAsString("Namespace")
140 << "::" << Inst
->getName();
143 void PredicateExpander::expandCheckOpcode(raw_ostream
&OS
,
144 ArrayRef
<const Record
*> Opcodes
) {
145 assert(!Opcodes
.empty() && "Expected at least one opcode to check!");
148 if (Opcodes
.size() == 1) {
150 expandCheckOpcode(OS
, Opcodes
[0]);
157 for (const Record
*Rec
: Opcodes
) {
158 OS
<< '\n' << Indent
;
160 OS
<< (shouldNegate() ? "&& " : "|| ");
162 expandCheckOpcode(OS
, Rec
);
167 OS
<< '\n' << Indent
<< ')';
170 void PredicateExpander::expandCheckPseudo(raw_ostream
&OS
,
171 ArrayRef
<const Record
*> Opcodes
) {
172 if (shouldExpandForMC())
175 expandCheckOpcode(OS
, Opcodes
);
178 void PredicateExpander::expandPredicateSequence(
179 raw_ostream
&OS
, ArrayRef
<const Record
*> Sequence
, bool IsCheckAll
) {
180 assert(!Sequence
.empty() && "Found an invalid empty predicate set!");
181 if (Sequence
.size() == 1)
182 return expandPredicate(OS
, Sequence
[0]);
184 // Okay, there is more than one predicate in the set.
186 OS
<< (shouldNegate() ? "!(" : "(");
189 bool OldValue
= shouldNegate();
190 setNegatePredicate(false);
191 for (const Record
*Rec
: Sequence
) {
192 OS
<< '\n' << Indent
;
194 OS
<< (IsCheckAll
? "&& " : "|| ");
195 expandPredicate(OS
, Rec
);
199 OS
<< '\n' << Indent
<< ')';
200 setNegatePredicate(OldValue
);
203 void PredicateExpander::expandTIIFunctionCall(raw_ostream
&OS
,
204 StringRef MethodName
) {
205 OS
<< (shouldNegate() ? "!" : "");
206 OS
<< TargetName
<< (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
207 OS
<< MethodName
<< (isByRef() ? "(MI)" : "(*MI)");
210 void PredicateExpander::expandCheckIsRegOperand(raw_ostream
&OS
, int OpIndex
) {
211 OS
<< (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
212 << "getOperand(" << OpIndex
<< ").isReg() ";
215 void PredicateExpander::expandCheckIsVRegOperand(raw_ostream
&OS
, int OpIndex
) {
216 OS
<< (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
217 << "getOperand(" << OpIndex
<< ").getReg().isVirtual()";
220 void PredicateExpander::expandCheckIsImmOperand(raw_ostream
&OS
, int OpIndex
) {
221 OS
<< (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
222 << "getOperand(" << OpIndex
<< ").isImm() ";
225 void PredicateExpander::expandCheckFunctionPredicateWithTII(
226 raw_ostream
&OS
, StringRef MCInstFn
, StringRef MachineInstrFn
,
228 if (!shouldExpandForMC()) {
229 OS
<< (TIIPtr
.empty() ? "TII" : TIIPtr
) << "->" << MachineInstrFn
;
230 OS
<< (isByRef() ? "(MI)" : "(*MI)");
234 OS
<< MCInstFn
<< (isByRef() ? "(MI" : "(*MI") << ", MCII)";
237 void PredicateExpander::expandCheckFunctionPredicate(raw_ostream
&OS
,
239 StringRef MachineInstrFn
) {
240 OS
<< (shouldExpandForMC() ? MCInstFn
: MachineInstrFn
)
241 << (isByRef() ? "(MI)" : "(*MI)");
244 void PredicateExpander::expandCheckNonPortable(raw_ostream
&OS
,
246 if (shouldExpandForMC())
247 return expandFalse(OS
);
249 OS
<< '(' << Code
<< ')';
252 void PredicateExpander::expandReturnStatement(raw_ostream
&OS
,
255 raw_string_ostream
SS(Buffer
);
258 expandPredicate(SS
, Rec
);
263 void PredicateExpander::expandOpcodeSwitchCase(raw_ostream
&OS
,
265 for (const Record
*Opcode
: Rec
->getValueAsListOfDefs("Opcodes")) {
266 OS
<< Indent
<< "case " << Opcode
->getValueAsString("Namespace")
267 << "::" << Opcode
->getName() << ":\n";
272 expandStatement(OS
, Rec
->getValueAsDef("CaseStmt"));
276 void PredicateExpander::expandOpcodeSwitchStatement(
277 raw_ostream
&OS
, ArrayRef
<const Record
*> Cases
, const Record
*Default
) {
279 raw_string_ostream
SS(Buffer
);
281 SS
<< "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
282 for (const Record
*Rec
: Cases
) {
283 expandOpcodeSwitchCase(SS
, Rec
);
287 // Expand the default case.
288 SS
<< Indent
<< "default:\n";
292 expandStatement(SS
, Default
);
293 SS
<< '\n' << Indent
<< "} // end of switch-stmt";
297 void PredicateExpander::expandStatement(raw_ostream
&OS
, const Record
*Rec
) {
298 // Assume that padding has been added by the caller.
299 if (Rec
->isSubClassOf("MCOpcodeSwitchStatement")) {
300 expandOpcodeSwitchStatement(OS
, Rec
->getValueAsListOfDefs("Cases"),
301 Rec
->getValueAsDef("DefaultCase"));
305 if (Rec
->isSubClassOf("MCReturnStatement")) {
306 expandReturnStatement(OS
, Rec
->getValueAsDef("Pred"));
310 llvm_unreachable("No known rules to expand this MCStatement");
313 void PredicateExpander::expandPredicate(raw_ostream
&OS
, const Record
*Rec
) {
314 // Assume that padding has been added by the caller.
315 if (Rec
->isSubClassOf("MCTrue")) {
317 return expandFalse(OS
);
318 return expandTrue(OS
);
321 if (Rec
->isSubClassOf("MCFalse")) {
323 return expandTrue(OS
);
324 return expandFalse(OS
);
327 if (Rec
->isSubClassOf("CheckNot")) {
328 flipNegatePredicate();
329 expandPredicate(OS
, Rec
->getValueAsDef("Pred"));
330 flipNegatePredicate();
334 if (Rec
->isSubClassOf("CheckIsRegOperand"))
335 return expandCheckIsRegOperand(OS
, Rec
->getValueAsInt("OpIndex"));
337 if (Rec
->isSubClassOf("CheckIsVRegOperand"))
338 return expandCheckIsVRegOperand(OS
, Rec
->getValueAsInt("OpIndex"));
340 if (Rec
->isSubClassOf("CheckIsImmOperand"))
341 return expandCheckIsImmOperand(OS
, Rec
->getValueAsInt("OpIndex"));
343 if (Rec
->isSubClassOf("CheckRegOperand"))
344 return expandCheckRegOperand(OS
, Rec
->getValueAsInt("OpIndex"),
345 Rec
->getValueAsDef("Reg"),
346 Rec
->getValueAsString("FunctionMapper"));
348 if (Rec
->isSubClassOf("CheckRegOperandSimple"))
349 return expandCheckRegOperandSimple(OS
, Rec
->getValueAsInt("OpIndex"),
350 Rec
->getValueAsString("FunctionMapper"));
352 if (Rec
->isSubClassOf("CheckInvalidRegOperand"))
353 return expandCheckInvalidRegOperand(OS
, Rec
->getValueAsInt("OpIndex"));
355 if (Rec
->isSubClassOf("CheckImmOperand"))
356 return expandCheckImmOperand(OS
, Rec
->getValueAsInt("OpIndex"),
357 Rec
->getValueAsInt("ImmVal"),
358 Rec
->getValueAsString("FunctionMapper"));
360 if (Rec
->isSubClassOf("CheckImmOperand_s"))
361 return expandCheckImmOperand(OS
, Rec
->getValueAsInt("OpIndex"),
362 Rec
->getValueAsString("ImmVal"),
363 Rec
->getValueAsString("FunctionMapper"));
365 if (Rec
->isSubClassOf("CheckImmOperandLT"))
366 return expandCheckImmOperandLT(OS
, Rec
->getValueAsInt("OpIndex"),
367 Rec
->getValueAsInt("ImmVal"),
368 Rec
->getValueAsString("FunctionMapper"));
370 if (Rec
->isSubClassOf("CheckImmOperandGT"))
371 return expandCheckImmOperandGT(OS
, Rec
->getValueAsInt("OpIndex"),
372 Rec
->getValueAsInt("ImmVal"),
373 Rec
->getValueAsString("FunctionMapper"));
375 if (Rec
->isSubClassOf("CheckImmOperandSimple"))
376 return expandCheckImmOperandSimple(OS
, Rec
->getValueAsInt("OpIndex"),
377 Rec
->getValueAsString("FunctionMapper"));
379 if (Rec
->isSubClassOf("CheckSameRegOperand"))
380 return expandCheckSameRegOperand(OS
, Rec
->getValueAsInt("FirstIndex"),
381 Rec
->getValueAsInt("SecondIndex"));
383 if (Rec
->isSubClassOf("CheckNumOperands"))
384 return expandCheckNumOperands(OS
, Rec
->getValueAsInt("NumOps"));
386 if (Rec
->isSubClassOf("CheckPseudo"))
387 return expandCheckPseudo(OS
, Rec
->getValueAsListOfDefs("ValidOpcodes"));
389 if (Rec
->isSubClassOf("CheckOpcode"))
390 return expandCheckOpcode(OS
, Rec
->getValueAsListOfDefs("ValidOpcodes"));
392 if (Rec
->isSubClassOf("CheckAll"))
393 return expandPredicateSequence(OS
, Rec
->getValueAsListOfDefs("Predicates"),
396 if (Rec
->isSubClassOf("CheckAny"))
397 return expandPredicateSequence(OS
, Rec
->getValueAsListOfDefs("Predicates"),
400 if (Rec
->isSubClassOf("CheckFunctionPredicate")) {
401 return expandCheckFunctionPredicate(
402 OS
, Rec
->getValueAsString("MCInstFnName"),
403 Rec
->getValueAsString("MachineInstrFnName"));
406 if (Rec
->isSubClassOf("CheckFunctionPredicateWithTII")) {
407 return expandCheckFunctionPredicateWithTII(
408 OS
, Rec
->getValueAsString("MCInstFnName"),
409 Rec
->getValueAsString("MachineInstrFnName"),
410 Rec
->getValueAsString("TIIPtrName"));
413 if (Rec
->isSubClassOf("CheckNonPortable"))
414 return expandCheckNonPortable(OS
, Rec
->getValueAsString("CodeBlock"));
416 if (Rec
->isSubClassOf("TIIPredicate"))
417 return expandTIIFunctionCall(OS
, Rec
->getValueAsString("FunctionName"));
419 llvm_unreachable("No known rules to expand this MCInstPredicate");
422 void STIPredicateExpander::expandHeader(raw_ostream
&OS
,
423 const STIPredicateFunction
&Fn
) {
424 const Record
*Rec
= Fn
.getDeclaration();
425 StringRef FunctionName
= Rec
->getValueAsString("Name");
427 OS
<< Indent
<< "bool ";
428 if (shouldExpandDefinition())
429 OS
<< getClassPrefix() << "::";
430 OS
<< FunctionName
<< "(";
431 if (shouldExpandForMC())
432 OS
<< "const MCInst " << (isByRef() ? "&" : "*") << "MI";
434 OS
<< "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
435 if (Rec
->getValueAsBit("UpdatesOpcodeMask"))
436 OS
<< ", APInt &Mask";
437 OS
<< (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
438 if (shouldExpandDefinition()) {
443 if (Rec
->getValueAsBit("OverridesBaseClassMember"))
448 void STIPredicateExpander::expandPrologue(raw_ostream
&OS
,
449 const STIPredicateFunction
&Fn
) {
450 bool UpdatesOpcodeMask
=
451 Fn
.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
454 for (const Record
*Delegate
:
455 Fn
.getDeclaration()->getValueAsListOfDefs("Delegates")) {
456 OS
<< Indent
<< "if (" << Delegate
->getValueAsString("Name") << "(MI";
457 if (UpdatesOpcodeMask
)
459 if (shouldExpandForMC())
460 OS
<< ", ProcessorID";
462 OS
<< Indent
+ 1 << "return true;\n\n";
465 if (shouldExpandForMC())
468 OS
<< Indent
<< "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
471 void STIPredicateExpander::expandOpcodeGroup(raw_ostream
&OS
,
472 const OpcodeGroup
&Group
,
473 bool ShouldUpdateOpcodeMask
) {
474 const OpcodeInfo
&OI
= Group
.getOpcodeInfo();
475 for (const PredicateInfo
&PI
: OI
.getPredicates()) {
476 const APInt
&ProcModelMask
= PI
.ProcModelMask
;
477 bool FirstProcID
= true;
478 for (unsigned I
= 0, E
= ProcModelMask
.getActiveBits(); I
< E
; ++I
) {
479 if (!ProcModelMask
[I
])
483 OS
<< Indent
<< "if (ProcessorID == " << I
;
485 OS
<< " || ProcessorID == " << I
;
494 if (ShouldUpdateOpcodeMask
) {
495 if (PI
.OperandMask
.isZero())
496 OS
<< "Mask.clearAllBits();\n";
498 OS
<< "Mask = " << PI
.OperandMask
<< ";\n";
502 expandPredicate(OS
, PI
.Predicate
);
505 OS
<< Indent
<< "}\n";
509 void STIPredicateExpander::expandBody(raw_ostream
&OS
,
510 const STIPredicateFunction
&Fn
) {
511 bool UpdatesOpcodeMask
=
512 Fn
.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
514 OS
<< Indent
<< "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
515 OS
<< Indent
<< "default:\n";
516 OS
<< Indent
<< " break;";
518 for (const OpcodeGroup
&Group
: Fn
.getGroups()) {
519 for (const Record
*Opcode
: Group
.getOpcodes()) {
521 << Indent
<< "case " << getTargetName() << "::" << Opcode
->getName()
527 expandOpcodeGroup(OS
, Group
, UpdatesOpcodeMask
);
529 OS
<< Indent
<< "break;\n";
533 OS
<< Indent
<< "}\n";
536 void STIPredicateExpander::expandEpilogue(raw_ostream
&OS
,
537 const STIPredicateFunction
&Fn
) {
538 OS
<< '\n' << Indent
;
540 expandPredicate(OS
, Fn
.getDefaultReturnPredicate());
544 StringRef FunctionName
= Fn
.getDeclaration()->getValueAsString("Name");
545 OS
<< Indent
<< "} // " << ClassPrefix
<< "::" << FunctionName
<< "\n\n";
548 void STIPredicateExpander::expandSTIPredicate(raw_ostream
&OS
,
549 const STIPredicateFunction
&Fn
) {
550 const Record
*Rec
= Fn
.getDeclaration();
551 if (shouldExpandForMC() && !Rec
->getValueAsBit("ExpandForMC"))
554 expandHeader(OS
, Fn
);
555 if (shouldExpandDefinition()) {
556 expandPrologue(OS
, Fn
);
558 expandEpilogue(OS
, Fn
);