[Frontend] Remove unused includes (NFC) (#116927)
[llvm-project.git] / llvm / utils / TableGen / Common / PredicateExpander.cpp
blobe54df89937c4a0c332c5eb72594a62a6c8a32b16
1 //===--------------------- PredicateExpander.cpp --------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
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"
17 namespace llvm {
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,
23 int ImmVal,
24 StringRef FunctionMapper) {
25 if (!FunctionMapper.empty())
26 OS << FunctionMapper << "(";
27 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
28 << ").getImm()";
29 if (!FunctionMapper.empty())
30 OS << ")";
31 OS << (shouldNegate() ? " != " : " == ") << ImmVal;
34 void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
35 StringRef ImmVal,
36 StringRef FunctionMapper) {
37 if (ImmVal.empty())
38 expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper);
40 if (!FunctionMapper.empty())
41 OS << FunctionMapper << "(";
42 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
43 << ").getImm()";
44 if (!FunctionMapper.empty())
45 OS << ")";
46 OS << (shouldNegate() ? " != " : " == ") << ImmVal;
49 void PredicateExpander::expandCheckImmOperandSimple(raw_ostream &OS,
50 int OpIndex,
51 StringRef FunctionMapper) {
52 if (shouldNegate())
53 OS << "!";
54 if (!FunctionMapper.empty())
55 OS << FunctionMapper << "(";
56 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
57 << ").getImm()";
58 if (!FunctionMapper.empty())
59 OS << ")";
62 void PredicateExpander::expandCheckImmOperandLT(raw_ostream &OS, int OpIndex,
63 int ImmVal,
64 StringRef FunctionMapper) {
65 if (!FunctionMapper.empty())
66 OS << FunctionMapper << "(";
67 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
68 << ").getImm()";
69 if (!FunctionMapper.empty())
70 OS << ")";
71 OS << (shouldNegate() ? " >= " : " < ") << ImmVal;
74 void PredicateExpander::expandCheckImmOperandGT(raw_ostream &OS, int OpIndex,
75 int ImmVal,
76 StringRef FunctionMapper) {
77 if (!FunctionMapper.empty())
78 OS << FunctionMapper << "(";
79 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
80 << ").getImm()";
81 if (!FunctionMapper.empty())
82 OS << ")";
83 OS << (shouldNegate() ? " <= " : " > ") << ImmVal;
86 void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
87 const Record *Reg,
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
94 << ").getReg()";
95 if (!FunctionMapper.empty())
96 OS << ")";
97 OS << (shouldNegate() ? " != " : " == ");
98 const StringRef Str = Reg->getValueAsString("Namespace");
99 if (!Str.empty())
100 OS << Str << "::";
101 OS << Reg->getName();
104 void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS,
105 int OpIndex,
106 StringRef FunctionMapper) {
107 if (shouldNegate())
108 OS << "!";
109 if (!FunctionMapper.empty())
110 OS << FunctionMapper << "(";
111 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
112 << ").getReg()";
113 if (!FunctionMapper.empty())
114 OS << ")";
117 void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
118 int OpIndex) {
119 if (!shouldNegate())
120 OS << "!";
121 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
122 << ").getReg().isValid()";
125 void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
126 int Second) {
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!");
146 bool First = true;
148 if (Opcodes.size() == 1) {
149 OS << "( ";
150 expandCheckOpcode(OS, Opcodes[0]);
151 OS << " )";
152 return;
155 OS << '(';
156 ++Indent;
157 for (const Record *Rec : Opcodes) {
158 OS << '\n' << Indent;
159 if (!First)
160 OS << (shouldNegate() ? "&& " : "|| ");
162 expandCheckOpcode(OS, Rec);
163 First = false;
166 --Indent;
167 OS << '\n' << Indent << ')';
170 void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
171 ArrayRef<const Record *> Opcodes) {
172 if (shouldExpandForMC())
173 expandFalse(OS);
174 else
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.
185 bool First = true;
186 OS << (shouldNegate() ? "!(" : "(");
187 ++Indent;
189 bool OldValue = shouldNegate();
190 setNegatePredicate(false);
191 for (const Record *Rec : Sequence) {
192 OS << '\n' << Indent;
193 if (!First)
194 OS << (IsCheckAll ? "&& " : "|| ");
195 expandPredicate(OS, Rec);
196 First = false;
198 --Indent;
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,
227 StringRef TIIPtr) {
228 if (!shouldExpandForMC()) {
229 OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn;
230 OS << (isByRef() ? "(MI)" : "(*MI)");
231 return;
234 OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)";
237 void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
238 StringRef MCInstFn,
239 StringRef MachineInstrFn) {
240 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
241 << (isByRef() ? "(MI)" : "(*MI)");
244 void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
245 StringRef Code) {
246 if (shouldExpandForMC())
247 return expandFalse(OS);
249 OS << '(' << Code << ')';
252 void PredicateExpander::expandReturnStatement(raw_ostream &OS,
253 const Record *Rec) {
254 std::string Buffer;
255 raw_string_ostream SS(Buffer);
257 SS << "return ";
258 expandPredicate(SS, Rec);
259 SS << ";";
260 OS << Buffer;
263 void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
264 const Record *Rec) {
265 for (const Record *Opcode : Rec->getValueAsListOfDefs("Opcodes")) {
266 OS << Indent << "case " << Opcode->getValueAsString("Namespace")
267 << "::" << Opcode->getName() << ":\n";
270 ++Indent;
271 OS << Indent;
272 expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
273 --Indent;
276 void PredicateExpander::expandOpcodeSwitchStatement(
277 raw_ostream &OS, ArrayRef<const Record *> Cases, const Record *Default) {
278 std::string Buffer;
279 raw_string_ostream SS(Buffer);
281 SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
282 for (const Record *Rec : Cases) {
283 expandOpcodeSwitchCase(SS, Rec);
284 SS << '\n';
287 // Expand the default case.
288 SS << Indent << "default:\n";
290 ++Indent;
291 SS << Indent;
292 expandStatement(SS, Default);
293 SS << '\n' << Indent << "} // end of switch-stmt";
294 OS << Buffer;
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"));
302 return;
305 if (Rec->isSubClassOf("MCReturnStatement")) {
306 expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
307 return;
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")) {
316 if (shouldNegate())
317 return expandFalse(OS);
318 return expandTrue(OS);
321 if (Rec->isSubClassOf("MCFalse")) {
322 if (shouldNegate())
323 return expandTrue(OS);
324 return expandFalse(OS);
327 if (Rec->isSubClassOf("CheckNot")) {
328 flipNegatePredicate();
329 expandPredicate(OS, Rec->getValueAsDef("Pred"));
330 flipNegatePredicate();
331 return;
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"),
394 /* AllOf */ true);
396 if (Rec->isSubClassOf("CheckAny"))
397 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
398 /* AllOf */ false);
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";
433 else
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()) {
439 OS << "{\n";
440 return;
443 if (Rec->getValueAsBit("OverridesBaseClassMember"))
444 OS << "override";
445 OS << ";\n";
448 void STIPredicateExpander::expandPrologue(raw_ostream &OS,
449 const STIPredicateFunction &Fn) {
450 bool UpdatesOpcodeMask =
451 Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
453 ++Indent;
454 for (const Record *Delegate :
455 Fn.getDeclaration()->getValueAsListOfDefs("Delegates")) {
456 OS << Indent << "if (" << Delegate->getValueAsString("Name") << "(MI";
457 if (UpdatesOpcodeMask)
458 OS << ", Mask";
459 if (shouldExpandForMC())
460 OS << ", ProcessorID";
461 OS << "))\n";
462 OS << Indent + 1 << "return true;\n\n";
465 if (shouldExpandForMC())
466 return;
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])
480 continue;
482 if (FirstProcID) {
483 OS << Indent << "if (ProcessorID == " << I;
484 } else {
485 OS << " || ProcessorID == " << I;
487 FirstProcID = false;
490 OS << ") {\n";
492 ++Indent;
493 OS << Indent;
494 if (ShouldUpdateOpcodeMask) {
495 if (PI.OperandMask.isZero())
496 OS << "Mask.clearAllBits();\n";
497 else
498 OS << "Mask = " << PI.OperandMask << ";\n";
499 OS << Indent;
501 OS << "return ";
502 expandPredicate(OS, PI.Predicate);
503 OS << ";\n";
504 --Indent;
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()) {
520 OS << '\n'
521 << Indent << "case " << getTargetName() << "::" << Opcode->getName()
522 << ":";
525 OS << '\n';
526 ++Indent;
527 expandOpcodeGroup(OS, Group, UpdatesOpcodeMask);
529 OS << Indent << "break;\n";
530 --Indent;
533 OS << Indent << "}\n";
536 void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
537 const STIPredicateFunction &Fn) {
538 OS << '\n' << Indent;
539 OS << "return ";
540 expandPredicate(OS, Fn.getDefaultReturnPredicate());
541 OS << ";\n";
543 --Indent;
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"))
552 return;
554 expandHeader(OS, Fn);
555 if (shouldExpandDefinition()) {
556 expandPrologue(OS, Fn);
557 expandBody(OS, Fn);
558 expandEpilogue(OS, Fn);
562 } // namespace llvm