blob: 83f67c023e51d00c8acb53bc86dd821b4d5ca42a [file] [log] [blame]
Andrea Di Biagio95140022018-05-25 15:55:37 +00001//===--------------------- PredicateExpander.cpp --------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// Functionalities used by the Tablegen backends to expand machine predicates.
11//
12//===----------------------------------------------------------------------===//
13
14#include "PredicateExpander.h"
Andrea Di Biagio8b6c3142018-09-19 15:57:45 +000015#include "CodeGenSchedule.h" // Definition of STIPredicateFunction.
Andrea Di Biagio95140022018-05-25 15:55:37 +000016
17namespace llvm {
18
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000019void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
20void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
Andrea Di Biagio95140022018-05-25 15:55:37 +000021
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000022void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
23 int ImmVal) {
Andrea Di Biagioad0293c2018-07-17 16:11:37 +000024 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
25 << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
Andrea Di Biagio95140022018-05-25 15:55:37 +000026}
27
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000028void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
29 StringRef ImmVal) {
Andrea Di Biagioad0293c2018-07-17 16:11:37 +000030 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
31 << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
Andrea Di Biagio95140022018-05-25 15:55:37 +000032}
33
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000034void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
35 const Record *Reg) {
Andrea Di Biagio95140022018-05-25 15:55:37 +000036 assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
37
38 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
39 << ").getReg() " << (shouldNegate() ? "!= " : "== ");
40 const StringRef Str = Reg->getValueAsString("Namespace");
41 if (!Str.empty())
42 OS << Str << "::";
43 OS << Reg->getName();
44}
45
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000046void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
Andrea Di Biagio9a2e9db2018-07-18 11:03:22 +000047 int OpIndex) {
48 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
49 << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
50}
51
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000052void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
53 int Second) {
Andrea Di Biagio95140022018-05-25 15:55:37 +000054 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
55 << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
56 << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
57}
58
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000059void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
Andrea Di Biagio95140022018-05-25 15:55:37 +000060 OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
61 << (shouldNegate() ? "!= " : "== ") << NumOps;
62}
63
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000064void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
Andrea Di Biagio95140022018-05-25 15:55:37 +000065 OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
66 << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
67 << "::" << Inst->getName();
68}
69
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000070void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +000071 const RecVec &Opcodes) {
72 assert(!Opcodes.empty() && "Expected at least one opcode to check!");
73 bool First = true;
74
75 if (Opcodes.size() == 1) {
76 OS << "( ";
77 expandCheckOpcode(OS, Opcodes[0]);
78 OS << " )";
79 return;
80 }
81
82 OS << '(';
83 increaseIndentLevel();
84 for (const Record *Rec : Opcodes) {
85 OS << '\n';
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000086 OS.indent(getIndentLevel() * 2);
Andrea Di Biagio95140022018-05-25 15:55:37 +000087 if (!First)
88 OS << (shouldNegate() ? "&& " : "|| ");
89
90 expandCheckOpcode(OS, Rec);
91 First = false;
92 }
93
94 OS << '\n';
95 decreaseIndentLevel();
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000096 OS.indent(getIndentLevel() * 2);
Andrea Di Biagio95140022018-05-25 15:55:37 +000097 OS << ')';
98}
99
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000100void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000101 const RecVec &Opcodes) {
102 if (shouldExpandForMC())
103 expandFalse(OS);
104 else
105 expandCheckOpcode(OS, Opcodes);
106}
107
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000108void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000109 const RecVec &Sequence,
110 bool IsCheckAll) {
111 assert(!Sequence.empty() && "Found an invalid empty predicate set!");
112 if (Sequence.size() == 1)
113 return expandPredicate(OS, Sequence[0]);
114
115 // Okay, there is more than one predicate in the set.
116 bool First = true;
117 OS << (shouldNegate() ? "!(" : "(");
118 increaseIndentLevel();
119
120 bool OldValue = shouldNegate();
121 setNegatePredicate(false);
122 for (const Record *Rec : Sequence) {
123 OS << '\n';
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000124 OS.indent(getIndentLevel() * 2);
Andrea Di Biagio95140022018-05-25 15:55:37 +0000125 if (!First)
126 OS << (IsCheckAll ? "&& " : "|| ");
127 expandPredicate(OS, Rec);
128 First = false;
129 }
130 OS << '\n';
131 decreaseIndentLevel();
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000132 OS.indent(getIndentLevel() * 2);
Andrea Di Biagio95140022018-05-25 15:55:37 +0000133 OS << ')';
134 setNegatePredicate(OldValue);
135}
136
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000137void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000138 StringRef MethodName) {
139 OS << (shouldNegate() ? "!" : "");
Andrea Di Biagio9eaf5aa2018-08-14 18:36:54 +0000140 OS << TargetName << (shouldExpandForMC() ? "_MC::" : "GenInstrInfo::");
Andrea Di Biagio95140022018-05-25 15:55:37 +0000141 OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
142}
143
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000144void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
Andrea Di Biagio95140022018-05-25 15:55:37 +0000145 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
146 << "getOperand(" << OpIndex << ").isReg() ";
147}
148
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000149void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
Andrea Di Biagio95140022018-05-25 15:55:37 +0000150 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
151 << "getOperand(" << OpIndex << ").isImm() ";
152}
153
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000154void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000155 StringRef MCInstFn,
156 StringRef MachineInstrFn) {
157 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
158 << (isByRef() ? "(MI)" : "(*MI)");
159}
160
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000161void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000162 StringRef Code) {
163 if (shouldExpandForMC())
164 return expandFalse(OS);
165
166 OS << '(' << Code << ')';
167}
168
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000169void PredicateExpander::expandReturnStatement(raw_ostream &OS,
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000170 const Record *Rec) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000171 std::string Buffer;
172 raw_string_ostream SS(Buffer);
173
174 SS << "return ";
175 expandPredicate(SS, Rec);
176 SS << ";";
177 SS.flush();
178 OS << Buffer;
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000179}
180
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000181void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000182 const Record *Rec) {
183 const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
184 for (const Record *Opcode : Opcodes) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000185 OS.indent(getIndentLevel() * 2);
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000186 OS << "case " << Opcode->getValueAsString("Namespace")
187 << "::" << Opcode->getName() << " :\n";
188 }
189
190 increaseIndentLevel();
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000191 OS.indent(getIndentLevel() * 2);
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000192 expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
193 decreaseIndentLevel();
194}
195
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000196void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000197 const RecVec &Cases,
198 const Record *Default) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000199 std::string Buffer;
200 raw_string_ostream SS(Buffer);
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000201
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000202 SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000203 for (const Record *Rec : Cases) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000204 expandOpcodeSwitchCase(SS, Rec);
205 SS << '\n';
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000206 }
207
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000208 // Expand the default case.
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000209 SS.indent(getIndentLevel() * 2);
210 SS << "default :\n";
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000211
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000212 increaseIndentLevel();
213 SS.indent(getIndentLevel() * 2);
214 expandStatement(SS, Default);
215 decreaseIndentLevel();
216 SS << '\n';
217
218 SS.indent(getIndentLevel() * 2);
219 SS << "} // end of switch-stmt";
220 SS.flush();
221 OS << Buffer;
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000222}
223
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000224void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
225 // Assume that padding has been added by the caller.
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000226 if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
227 expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
228 Rec->getValueAsDef("DefaultCase"));
229 return;
230 }
231
232 if (Rec->isSubClassOf("MCReturnStatement")) {
233 expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
234 return;
235 }
236
237 llvm_unreachable("No known rules to expand this MCStatement");
238}
239
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000240void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
241 // Assume that padding has been added by the caller.
Andrea Di Biagio95140022018-05-25 15:55:37 +0000242 if (Rec->isSubClassOf("MCTrue")) {
243 if (shouldNegate())
244 return expandFalse(OS);
245 return expandTrue(OS);
246 }
247
248 if (Rec->isSubClassOf("MCFalse")) {
249 if (shouldNegate())
250 return expandTrue(OS);
251 return expandFalse(OS);
252 }
253
254 if (Rec->isSubClassOf("CheckNot")) {
255 flipNegatePredicate();
256 expandPredicate(OS, Rec->getValueAsDef("Pred"));
257 flipNegatePredicate();
258 return;
259 }
260
261 if (Rec->isSubClassOf("CheckIsRegOperand"))
262 return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
263
264 if (Rec->isSubClassOf("CheckIsImmOperand"))
265 return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
266
267 if (Rec->isSubClassOf("CheckRegOperand"))
268 return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
269 Rec->getValueAsDef("Reg"));
270
Andrea Di Biagio9a2e9db2018-07-18 11:03:22 +0000271 if (Rec->isSubClassOf("CheckInvalidRegOperand"))
272 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
273
Andrea Di Biagio95140022018-05-25 15:55:37 +0000274 if (Rec->isSubClassOf("CheckImmOperand"))
275 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
276 Rec->getValueAsInt("ImmVal"));
277
278 if (Rec->isSubClassOf("CheckImmOperand_s"))
279 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
280 Rec->getValueAsString("ImmVal"));
281
282 if (Rec->isSubClassOf("CheckSameRegOperand"))
283 return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
284 Rec->getValueAsInt("SecondIndex"));
285
286 if (Rec->isSubClassOf("CheckNumOperands"))
287 return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
288
289 if (Rec->isSubClassOf("CheckPseudo"))
290 return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
291
292 if (Rec->isSubClassOf("CheckOpcode"))
293 return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
294
295 if (Rec->isSubClassOf("CheckAll"))
296 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
297 /* AllOf */ true);
298
299 if (Rec->isSubClassOf("CheckAny"))
300 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
301 /* AllOf */ false);
302
303 if (Rec->isSubClassOf("CheckFunctionPredicate"))
304 return expandCheckFunctionPredicate(
305 OS, Rec->getValueAsString("MCInstFnName"),
306 Rec->getValueAsString("MachineInstrFnName"));
307
308 if (Rec->isSubClassOf("CheckNonPortable"))
309 return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
310
311 if (Rec->isSubClassOf("TIIPredicate"))
Andrea Di Biagio9eaf5aa2018-08-14 18:36:54 +0000312 return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
Andrea Di Biagio95140022018-05-25 15:55:37 +0000313
314 llvm_unreachable("No known rules to expand this MCInstPredicate");
315}
316
Andrea Di Biagio8b6c3142018-09-19 15:57:45 +0000317void STIPredicateExpander::expandHeader(raw_ostream &OS,
318 const STIPredicateFunction &Fn) {
319 const Record *Rec = Fn.getDeclaration();
320 StringRef FunctionName = Rec->getValueAsString("Name");
321
322 OS.indent(getIndentLevel() * 2);
323 OS << "bool ";
324 if (shouldExpandDefinition())
325 OS << getClassPrefix() << "::";
326 OS << FunctionName << "(";
327 if (shouldExpandForMC())
328 OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
329 else
330 OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
331 if (Rec->getValueAsBit("UpdatesOpcodeMask"))
332 OS << ", APInt &Mask";
333 OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
334 if (shouldExpandDefinition()) {
335 OS << "{\n";
336 return;
337 }
338
339 if (Rec->getValueAsBit("OverridesBaseClassMember"))
340 OS << "override";
341 OS << ";\n";
342}
343
344void STIPredicateExpander::expandPrologue(raw_ostream &OS,
345 const STIPredicateFunction &Fn) {
346 RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates");
347 bool UpdatesOpcodeMask =
348 Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
349
350 increaseIndentLevel();
351 unsigned IndentLevel = getIndentLevel();
352 for (const Record *Delegate : Delegates) {
353 OS.indent(IndentLevel * 2);
354 OS << "if (" << Delegate->getValueAsString("Name") << "(MI";
355 if (UpdatesOpcodeMask)
356 OS << ", Mask";
357 if (shouldExpandForMC())
358 OS << ", ProcessorID";
359 OS << "))\n";
360 OS.indent((1 + IndentLevel) * 2);
361 OS << "return true;\n\n";
362 }
363
364 if (shouldExpandForMC())
365 return;
366
367 OS.indent(IndentLevel * 2);
368 OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
369}
370
371void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
372 bool ShouldUpdateOpcodeMask) {
373 const OpcodeInfo &OI = Group.getOpcodeInfo();
374 for (const PredicateInfo &PI : OI.getPredicates()) {
375 const APInt &ProcModelMask = PI.ProcModelMask;
376 bool FirstProcID = true;
377 for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) {
378 if (!ProcModelMask[I])
379 continue;
380
381 if (FirstProcID) {
382 OS.indent(getIndentLevel() * 2);
383 OS << "if (ProcessorID == " << I;
384 } else {
385 OS << " || ProcessorID == " << I;
386 }
387 FirstProcID = false;
388 }
389
390 OS << ") {\n";
391
392 increaseIndentLevel();
393 OS.indent(getIndentLevel() * 2);
394 if (ShouldUpdateOpcodeMask) {
395 if (PI.OperandMask.isNullValue())
396 OS << "Mask.clearAllBits();\n";
397 else
398 OS << "Mask = " << PI.OperandMask << ";\n";
399 OS.indent(getIndentLevel() * 2);
400 }
401 OS << "return ";
402 expandPredicate(OS, PI.Predicate);
403 OS << ";\n";
404 decreaseIndentLevel();
405 OS.indent(getIndentLevel() * 2);
406 OS << "}\n";
407 }
408}
409
410void STIPredicateExpander::expandBody(raw_ostream &OS,
411 const STIPredicateFunction &Fn) {
412 bool UpdatesOpcodeMask =
413 Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
414
415 unsigned IndentLevel = getIndentLevel();
416 OS.indent(IndentLevel * 2);
417 OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
418 OS.indent(IndentLevel * 2);
419 OS << "default:\n";
420 OS.indent(IndentLevel * 2);
421 OS << " break;";
422
423 for (const OpcodeGroup &Group : Fn.getGroups()) {
424 for (const Record *Opcode : Group.getOpcodes()) {
425 OS << '\n';
426 OS.indent(IndentLevel * 2);
427 OS << "case " << getTargetName() << "::" << Opcode->getName() << ":";
428 }
429
430 OS << '\n';
431 increaseIndentLevel();
432 expandOpcodeGroup(OS, Group, UpdatesOpcodeMask);
433
434 OS.indent(getIndentLevel() * 2);
435 OS << "break;\n";
436 decreaseIndentLevel();
437 }
438
439 OS.indent(IndentLevel * 2);
440 OS << "}\n";
441}
442
443void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
444 const STIPredicateFunction &Fn) {
445 OS << '\n';
446 OS.indent(getIndentLevel() * 2);
447 OS << "return ";
448 expandPredicate(OS, Fn.getDefaultReturnPredicate());
449 OS << ";\n";
450
451 decreaseIndentLevel();
452 OS.indent(getIndentLevel() * 2);
453 StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name");
454 OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n";
455}
456
457void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS,
458 const STIPredicateFunction &Fn) {
459 const Record *Rec = Fn.getDeclaration();
460 if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC"))
461 return;
462
463 expandHeader(OS, Fn);
464 if (shouldExpandDefinition()) {
465 expandPrologue(OS, Fn);
466 expandBody(OS, Fn);
467 expandEpilogue(OS, Fn);
468 }
469}
470
Andrea Di Biagio95140022018-05-25 15:55:37 +0000471} // namespace llvm