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