1 //===--------------------- 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"
15 #include "CodeGenSchedule.h" // Definition of STIPredicateFunction.
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   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
25      << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
26 }
27 
28 void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
29                                               StringRef ImmVal) {
30   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
31      << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
32 }
33 
34 void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
35                                               const Record *Reg) {
36   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 
46 void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
47                                                      int OpIndex) {
48   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
49      << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
50 }
51 
52 void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
53                                                   int Second) {
54   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
55      << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
56      << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
57 }
58 
59 void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
60   OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
61      << (shouldNegate() ? "!= " : "== ") << NumOps;
62 }
63 
64 void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
65   OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
66      << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
67      << "::" << Inst->getName();
68 }
69 
70 void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
71                                           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';
86     OS.indent(getIndentLevel() * 2);
87     if (!First)
88       OS << (shouldNegate() ? "&& " : "|| ");
89 
90     expandCheckOpcode(OS, Rec);
91     First = false;
92   }
93 
94   OS << '\n';
95   decreaseIndentLevel();
96   OS.indent(getIndentLevel() * 2);
97   OS << ')';
98 }
99 
100 void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
101                                           const RecVec &Opcodes) {
102   if (shouldExpandForMC())
103     expandFalse(OS);
104   else
105     expandCheckOpcode(OS, Opcodes);
106 }
107 
108 void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
109                                                 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';
124     OS.indent(getIndentLevel() * 2);
125     if (!First)
126       OS << (IsCheckAll ? "&& " : "|| ");
127     expandPredicate(OS, Rec);
128     First = false;
129   }
130   OS << '\n';
131   decreaseIndentLevel();
132   OS.indent(getIndentLevel() * 2);
133   OS << ')';
134   setNegatePredicate(OldValue);
135 }
136 
137 void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
138                                               StringRef MethodName) {
139   OS << (shouldNegate() ? "!" : "");
140   OS << TargetName << (shouldExpandForMC() ? "_MC::" : "GenInstrInfo::");
141   OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
142 }
143 
144 void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
145   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
146      << "getOperand(" << OpIndex << ").isReg() ";
147 }
148 
149 void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
150   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
151      << "getOperand(" << OpIndex << ").isImm() ";
152 }
153 
154 void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
155                                                      StringRef MCInstFn,
156                                                      StringRef MachineInstrFn) {
157   OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
158      << (isByRef() ? "(MI)" : "(*MI)");
159 }
160 
161 void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
162                                                StringRef Code) {
163   if (shouldExpandForMC())
164     return expandFalse(OS);
165 
166   OS << '(' << Code << ')';
167 }
168 
169 void PredicateExpander::expandReturnStatement(raw_ostream &OS,
170                                               const Record *Rec) {
171   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;
179 }
180 
181 void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
182                                                const Record *Rec) {
183   const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
184   for (const Record *Opcode : Opcodes) {
185     OS.indent(getIndentLevel() * 2);
186     OS << "case " << Opcode->getValueAsString("Namespace")
187        << "::" << Opcode->getName() << " :\n";
188   }
189 
190   increaseIndentLevel();
191   OS.indent(getIndentLevel() * 2);
192   expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
193   decreaseIndentLevel();
194 }
195 
196 void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
197                                                     const RecVec &Cases,
198                                                     const Record *Default) {
199   std::string Buffer;
200   raw_string_ostream SS(Buffer);
201 
202   SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
203   for (const Record *Rec : Cases) {
204     expandOpcodeSwitchCase(SS, Rec);
205     SS << '\n';
206   }
207 
208   // Expand the default case.
209   SS.indent(getIndentLevel() * 2);
210   SS << "default :\n";
211 
212   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;
222 }
223 
224 void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
225   // Assume that padding has been added by the caller.
226   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 
240 void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
241   // Assume that padding has been added by the caller.
242   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 
271   if (Rec->isSubClassOf("CheckInvalidRegOperand"))
272     return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
273 
274   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"))
312     return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
313 
314   llvm_unreachable("No known rules to expand this MCInstPredicate");
315 }
316 
317 void 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 
344 void 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 
371 void 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 
410 void 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 
443 void 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 
457 void 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 
471 } // namespace llvm
472