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.
10//
11//===----------------------------------------------------------------------===//
12
13#include "PredicateExpander.h"
14#include "CodeGenSchedule.h" // Definition of STIPredicateFunction.
15#include "llvm/TableGen/Record.h"
16
17namespace llvm {
18
19void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
20void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
21
22void 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;
32}
33
34void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
35 StringRef ImmVal,
36 StringRef FunctionMapper) {
37 if (ImmVal.empty())
38 expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper);
39
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;
47}
48
49void 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 << ")";
60}
61
62void 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;
72}
73
74void 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;
84}
85
86void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
87 const Record *Reg,
88 StringRef FunctionMapper) {
89 assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
90
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(FieldName: "Namespace");
99 if (!Str.empty())
100 OS << Str << "::";
101 OS << Reg->getName();
102}
103
104void 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 << ")";
115}
116
117void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
118 int OpIndex) {
119 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
120 << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
121}
122
123void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
124 int Second) {
125 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
126 << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
127 << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
128}
129
130void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
131 OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
132 << (shouldNegate() ? "!= " : "== ") << NumOps;
133}
134
135void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
136 OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
137 << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString(FieldName: "Namespace")
138 << "::" << Inst->getName();
139}
140
141void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
142 const RecVec &Opcodes) {
143 assert(!Opcodes.empty() && "Expected at least one opcode to check!");
144 bool First = true;
145
146 if (Opcodes.size() == 1) {
147 OS << "( ";
148 expandCheckOpcode(OS, Inst: Opcodes[0]);
149 OS << " )";
150 return;
151 }
152
153 OS << '(';
154 increaseIndentLevel();
155 for (const Record *Rec : Opcodes) {
156 OS << '\n';
157 OS.indent(NumSpaces: getIndentLevel() * 2);
158 if (!First)
159 OS << (shouldNegate() ? "&& " : "|| ");
160
161 expandCheckOpcode(OS, Inst: Rec);
162 First = false;
163 }
164
165 OS << '\n';
166 decreaseIndentLevel();
167 OS.indent(NumSpaces: getIndentLevel() * 2);
168 OS << ')';
169}
170
171void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
172 const RecVec &Opcodes) {
173 if (shouldExpandForMC())
174 expandFalse(OS);
175 else
176 expandCheckOpcode(OS, Opcodes);
177}
178
179void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
180 const RecVec &Sequence,
181 bool IsCheckAll) {
182 assert(!Sequence.empty() && "Found an invalid empty predicate set!");
183 if (Sequence.size() == 1)
184 return expandPredicate(OS, Rec: Sequence[0]);
185
186 // Okay, there is more than one predicate in the set.
187 bool First = true;
188 OS << (shouldNegate() ? "!(" : "(");
189 increaseIndentLevel();
190
191 bool OldValue = shouldNegate();
192 setNegatePredicate(false);
193 for (const Record *Rec : Sequence) {
194 OS << '\n';
195 OS.indent(NumSpaces: getIndentLevel() * 2);
196 if (!First)
197 OS << (IsCheckAll ? "&& " : "|| ");
198 expandPredicate(OS, Rec);
199 First = false;
200 }
201 OS << '\n';
202 decreaseIndentLevel();
203 OS.indent(NumSpaces: getIndentLevel() * 2);
204 OS << ')';
205 setNegatePredicate(OldValue);
206}
207
208void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
209 StringRef MethodName) {
210 OS << (shouldNegate() ? "!" : "");
211 OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
212 OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
213}
214
215void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
216 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
217 << "getOperand(" << OpIndex << ").isReg() ";
218}
219
220void PredicateExpander::expandCheckIsVRegOperand(raw_ostream &OS, int OpIndex) {
221 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
222 << "getOperand(" << OpIndex << ").getReg().isVirtual()";
223}
224
225void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
226 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
227 << "getOperand(" << OpIndex << ").isImm() ";
228}
229
230void PredicateExpander::expandCheckFunctionPredicateWithTII(
231 raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn,
232 StringRef TIIPtr) {
233 if (!shouldExpandForMC()) {
234 OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn;
235 OS << (isByRef() ? "(MI)" : "(*MI)");
236 return;
237 }
238
239 OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)";
240}
241
242void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
243 StringRef MCInstFn,
244 StringRef MachineInstrFn) {
245 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
246 << (isByRef() ? "(MI)" : "(*MI)");
247}
248
249void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
250 StringRef Code) {
251 if (shouldExpandForMC())
252 return expandFalse(OS);
253
254 OS << '(' << Code << ')';
255}
256
257void PredicateExpander::expandReturnStatement(raw_ostream &OS,
258 const Record *Rec) {
259 std::string Buffer;
260 raw_string_ostream SS(Buffer);
261
262 SS << "return ";
263 expandPredicate(OS&: SS, Rec);
264 SS << ";";
265 OS << Buffer;
266}
267
268void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
269 const Record *Rec) {
270 const RecVec &Opcodes = Rec->getValueAsListOfDefs(FieldName: "Opcodes");
271 for (const Record *Opcode : Opcodes) {
272 OS.indent(NumSpaces: getIndentLevel() * 2);
273 OS << "case " << Opcode->getValueAsString(FieldName: "Namespace")
274 << "::" << Opcode->getName() << ":\n";
275 }
276
277 increaseIndentLevel();
278 OS.indent(NumSpaces: getIndentLevel() * 2);
279 expandStatement(OS, Rec: Rec->getValueAsDef(FieldName: "CaseStmt"));
280 decreaseIndentLevel();
281}
282
283void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
284 const RecVec &Cases,
285 const Record *Default) {
286 std::string Buffer;
287 raw_string_ostream SS(Buffer);
288
289 SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
290 for (const Record *Rec : Cases) {
291 expandOpcodeSwitchCase(OS&: SS, Rec);
292 SS << '\n';
293 }
294
295 // Expand the default case.
296 SS.indent(NumSpaces: getIndentLevel() * 2);
297 SS << "default:\n";
298
299 increaseIndentLevel();
300 SS.indent(NumSpaces: getIndentLevel() * 2);
301 expandStatement(OS&: SS, Rec: Default);
302 decreaseIndentLevel();
303 SS << '\n';
304
305 SS.indent(NumSpaces: getIndentLevel() * 2);
306 SS << "} // end of switch-stmt";
307 OS << Buffer;
308}
309
310void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
311 // Assume that padding has been added by the caller.
312 if (Rec->isSubClassOf(Name: "MCOpcodeSwitchStatement")) {
313 expandOpcodeSwitchStatement(OS, Cases: Rec->getValueAsListOfDefs(FieldName: "Cases"),
314 Default: Rec->getValueAsDef(FieldName: "DefaultCase"));
315 return;
316 }
317
318 if (Rec->isSubClassOf(Name: "MCReturnStatement")) {
319 expandReturnStatement(OS, Rec: Rec->getValueAsDef(FieldName: "Pred"));
320 return;
321 }
322
323 llvm_unreachable("No known rules to expand this MCStatement");
324}
325
326void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
327 // Assume that padding has been added by the caller.
328 if (Rec->isSubClassOf(Name: "MCTrue")) {
329 if (shouldNegate())
330 return expandFalse(OS);
331 return expandTrue(OS);
332 }
333
334 if (Rec->isSubClassOf(Name: "MCFalse")) {
335 if (shouldNegate())
336 return expandTrue(OS);
337 return expandFalse(OS);
338 }
339
340 if (Rec->isSubClassOf(Name: "CheckNot")) {
341 flipNegatePredicate();
342 expandPredicate(OS, Rec: Rec->getValueAsDef(FieldName: "Pred"));
343 flipNegatePredicate();
344 return;
345 }
346
347 if (Rec->isSubClassOf(Name: "CheckIsRegOperand"))
348 return expandCheckIsRegOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"));
349
350 if (Rec->isSubClassOf(Name: "CheckIsVRegOperand"))
351 return expandCheckIsVRegOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"));
352
353 if (Rec->isSubClassOf(Name: "CheckIsImmOperand"))
354 return expandCheckIsImmOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"));
355
356 if (Rec->isSubClassOf(Name: "CheckRegOperand"))
357 return expandCheckRegOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"),
358 Reg: Rec->getValueAsDef(FieldName: "Reg"),
359 FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper"));
360
361 if (Rec->isSubClassOf(Name: "CheckRegOperandSimple"))
362 return expandCheckRegOperandSimple(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"),
363 FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper"));
364
365 if (Rec->isSubClassOf(Name: "CheckInvalidRegOperand"))
366 return expandCheckInvalidRegOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"));
367
368 if (Rec->isSubClassOf(Name: "CheckImmOperand"))
369 return expandCheckImmOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"),
370 ImmVal: Rec->getValueAsInt(FieldName: "ImmVal"),
371 FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper"));
372
373 if (Rec->isSubClassOf(Name: "CheckImmOperand_s"))
374 return expandCheckImmOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"),
375 ImmVal: Rec->getValueAsString(FieldName: "ImmVal"),
376 FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper"));
377
378 if (Rec->isSubClassOf(Name: "CheckImmOperandLT"))
379 return expandCheckImmOperandLT(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"),
380 ImmVal: Rec->getValueAsInt(FieldName: "ImmVal"),
381 FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper"));
382
383 if (Rec->isSubClassOf(Name: "CheckImmOperandGT"))
384 return expandCheckImmOperandGT(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"),
385 ImmVal: Rec->getValueAsInt(FieldName: "ImmVal"),
386 FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper"));
387
388 if (Rec->isSubClassOf(Name: "CheckImmOperandSimple"))
389 return expandCheckImmOperandSimple(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex"),
390 FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper"));
391
392 if (Rec->isSubClassOf(Name: "CheckSameRegOperand"))
393 return expandCheckSameRegOperand(OS, First: Rec->getValueAsInt(FieldName: "FirstIndex"),
394 Second: Rec->getValueAsInt(FieldName: "SecondIndex"));
395
396 if (Rec->isSubClassOf(Name: "CheckNumOperands"))
397 return expandCheckNumOperands(OS, NumOps: Rec->getValueAsInt(FieldName: "NumOps"));
398
399 if (Rec->isSubClassOf(Name: "CheckPseudo"))
400 return expandCheckPseudo(OS, Opcodes: Rec->getValueAsListOfDefs(FieldName: "ValidOpcodes"));
401
402 if (Rec->isSubClassOf(Name: "CheckOpcode"))
403 return expandCheckOpcode(OS, Opcodes: Rec->getValueAsListOfDefs(FieldName: "ValidOpcodes"));
404
405 if (Rec->isSubClassOf(Name: "CheckAll"))
406 return expandPredicateSequence(OS, Sequence: Rec->getValueAsListOfDefs(FieldName: "Predicates"),
407 /* AllOf */ IsCheckAll: true);
408
409 if (Rec->isSubClassOf(Name: "CheckAny"))
410 return expandPredicateSequence(OS, Sequence: Rec->getValueAsListOfDefs(FieldName: "Predicates"),
411 /* AllOf */ IsCheckAll: false);
412
413 if (Rec->isSubClassOf(Name: "CheckFunctionPredicate")) {
414 return expandCheckFunctionPredicate(
415 OS, MCInstFn: Rec->getValueAsString(FieldName: "MCInstFnName"),
416 MachineInstrFn: Rec->getValueAsString(FieldName: "MachineInstrFnName"));
417 }
418
419 if (Rec->isSubClassOf(Name: "CheckFunctionPredicateWithTII")) {
420 return expandCheckFunctionPredicateWithTII(
421 OS, MCInstFn: Rec->getValueAsString(FieldName: "MCInstFnName"),
422 MachineInstrFn: Rec->getValueAsString(FieldName: "MachineInstrFnName"),
423 TIIPtr: Rec->getValueAsString(FieldName: "TIIPtrName"));
424 }
425
426 if (Rec->isSubClassOf(Name: "CheckNonPortable"))
427 return expandCheckNonPortable(OS, Code: Rec->getValueAsString(FieldName: "CodeBlock"));
428
429 if (Rec->isSubClassOf(Name: "TIIPredicate"))
430 return expandTIIFunctionCall(OS, MethodName: Rec->getValueAsString(FieldName: "FunctionName"));
431
432 llvm_unreachable("No known rules to expand this MCInstPredicate");
433}
434
435void STIPredicateExpander::expandHeader(raw_ostream &OS,
436 const STIPredicateFunction &Fn) {
437 const Record *Rec = Fn.getDeclaration();
438 StringRef FunctionName = Rec->getValueAsString(FieldName: "Name");
439
440 OS.indent(NumSpaces: getIndentLevel() * 2);
441 OS << "bool ";
442 if (shouldExpandDefinition())
443 OS << getClassPrefix() << "::";
444 OS << FunctionName << "(";
445 if (shouldExpandForMC())
446 OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
447 else
448 OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
449 if (Rec->getValueAsBit(FieldName: "UpdatesOpcodeMask"))
450 OS << ", APInt &Mask";
451 OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
452 if (shouldExpandDefinition()) {
453 OS << "{\n";
454 return;
455 }
456
457 if (Rec->getValueAsBit(FieldName: "OverridesBaseClassMember"))
458 OS << "override";
459 OS << ";\n";
460}
461
462void STIPredicateExpander::expandPrologue(raw_ostream &OS,
463 const STIPredicateFunction &Fn) {
464 RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs(FieldName: "Delegates");
465 bool UpdatesOpcodeMask =
466 Fn.getDeclaration()->getValueAsBit(FieldName: "UpdatesOpcodeMask");
467
468 increaseIndentLevel();
469 unsigned IndentLevel = getIndentLevel();
470 for (const Record *Delegate : Delegates) {
471 OS.indent(NumSpaces: IndentLevel * 2);
472 OS << "if (" << Delegate->getValueAsString(FieldName: "Name") << "(MI";
473 if (UpdatesOpcodeMask)
474 OS << ", Mask";
475 if (shouldExpandForMC())
476 OS << ", ProcessorID";
477 OS << "))\n";
478 OS.indent(NumSpaces: (1 + IndentLevel) * 2);
479 OS << "return true;\n\n";
480 }
481
482 if (shouldExpandForMC())
483 return;
484
485 OS.indent(NumSpaces: IndentLevel * 2);
486 OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
487}
488
489void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS,
490 const OpcodeGroup &Group,
491 bool ShouldUpdateOpcodeMask) {
492 const OpcodeInfo &OI = Group.getOpcodeInfo();
493 for (const PredicateInfo &PI : OI.getPredicates()) {
494 const APInt &ProcModelMask = PI.ProcModelMask;
495 bool FirstProcID = true;
496 for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) {
497 if (!ProcModelMask[I])
498 continue;
499
500 if (FirstProcID) {
501 OS.indent(NumSpaces: getIndentLevel() * 2);
502 OS << "if (ProcessorID == " << I;
503 } else {
504 OS << " || ProcessorID == " << I;
505 }
506 FirstProcID = false;
507 }
508
509 OS << ") {\n";
510
511 increaseIndentLevel();
512 OS.indent(NumSpaces: getIndentLevel() * 2);
513 if (ShouldUpdateOpcodeMask) {
514 if (PI.OperandMask.isZero())
515 OS << "Mask.clearAllBits();\n";
516 else
517 OS << "Mask = " << PI.OperandMask << ";\n";
518 OS.indent(NumSpaces: getIndentLevel() * 2);
519 }
520 OS << "return ";
521 expandPredicate(OS, Rec: PI.Predicate);
522 OS << ";\n";
523 decreaseIndentLevel();
524 OS.indent(NumSpaces: getIndentLevel() * 2);
525 OS << "}\n";
526 }
527}
528
529void STIPredicateExpander::expandBody(raw_ostream &OS,
530 const STIPredicateFunction &Fn) {
531 bool UpdatesOpcodeMask =
532 Fn.getDeclaration()->getValueAsBit(FieldName: "UpdatesOpcodeMask");
533
534 unsigned IndentLevel = getIndentLevel();
535 OS.indent(NumSpaces: IndentLevel * 2);
536 OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
537 OS.indent(NumSpaces: IndentLevel * 2);
538 OS << "default:\n";
539 OS.indent(NumSpaces: IndentLevel * 2);
540 OS << " break;";
541
542 for (const OpcodeGroup &Group : Fn.getGroups()) {
543 for (const Record *Opcode : Group.getOpcodes()) {
544 OS << '\n';
545 OS.indent(NumSpaces: IndentLevel * 2);
546 OS << "case " << getTargetName() << "::" << Opcode->getName() << ":";
547 }
548
549 OS << '\n';
550 increaseIndentLevel();
551 expandOpcodeGroup(OS, Group, ShouldUpdateOpcodeMask: UpdatesOpcodeMask);
552
553 OS.indent(NumSpaces: getIndentLevel() * 2);
554 OS << "break;\n";
555 decreaseIndentLevel();
556 }
557
558 OS.indent(NumSpaces: IndentLevel * 2);
559 OS << "}\n";
560}
561
562void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
563 const STIPredicateFunction &Fn) {
564 OS << '\n';
565 OS.indent(NumSpaces: getIndentLevel() * 2);
566 OS << "return ";
567 expandPredicate(OS, Rec: Fn.getDefaultReturnPredicate());
568 OS << ";\n";
569
570 decreaseIndentLevel();
571 OS.indent(NumSpaces: getIndentLevel() * 2);
572 StringRef FunctionName = Fn.getDeclaration()->getValueAsString(FieldName: "Name");
573 OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n";
574}
575
576void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS,
577 const STIPredicateFunction &Fn) {
578 const Record *Rec = Fn.getDeclaration();
579 if (shouldExpandForMC() && !Rec->getValueAsBit(FieldName: "ExpandForMC"))
580 return;
581
582 expandHeader(OS, Fn);
583 if (shouldExpandDefinition()) {
584 expandPrologue(OS, Fn);
585 expandBody(OS, Fn);
586 expandEpilogue(OS, Fn);
587 }
588}
589
590} // namespace llvm
591