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                                               StringRef FunctionMapper) {
25   if (!FunctionMapper.empty())
26     OS << FunctionMapper << "(";
27   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
28      << ").getImm()";
29   OS << (FunctionMapper.empty() ? " " : ") ");
30   OS << (shouldNegate() ? "!= " : "== ") << ImmVal;
31 }
32 
33 void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
34                                               StringRef ImmVal,
35                                               StringRef FunctionMapper) {
36   if (!FunctionMapper.empty())
37     OS << FunctionMapper << "(";
38   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
39      << ").getImm()";
40 
41   OS << (FunctionMapper.empty() ? "" : ")");
42   if (ImmVal.empty())
43     return;
44   OS << (shouldNegate() ? " != " : " == ") << ImmVal;
45 }
46 
47 void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
48                                               const Record *Reg,
49                                               StringRef FunctionMapper) {
50   assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
51 
52   if (!FunctionMapper.empty())
53     OS << FunctionMapper << "(";
54   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
55      << ").getReg()";
56   OS << (FunctionMapper.empty() ? "" : ")");
57   if (!Reg)
58     return;
59   OS << (shouldNegate() ? " != " : " == ");
60   const StringRef Str = Reg->getValueAsString("Namespace");
61   if (!Str.empty())
62     OS << Str << "::";
63   OS << Reg->getName();
64 }
65 
66 void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
67                                                      int OpIndex) {
68   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
69      << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
70 }
71 
72 void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
73                                                   int Second) {
74   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
75      << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
76      << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
77 }
78 
79 void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
80   OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
81      << (shouldNegate() ? "!= " : "== ") << NumOps;
82 }
83 
84 void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
85   OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
86      << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
87      << "::" << Inst->getName();
88 }
89 
90 void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
91                                           const RecVec &Opcodes) {
92   assert(!Opcodes.empty() && "Expected at least one opcode to check!");
93   bool First = true;
94 
95   if (Opcodes.size() == 1) {
96     OS << "( ";
97     expandCheckOpcode(OS, Opcodes[0]);
98     OS << " )";
99     return;
100   }
101 
102   OS << '(';
103   increaseIndentLevel();
104   for (const Record *Rec : Opcodes) {
105     OS << '\n';
106     OS.indent(getIndentLevel() * 2);
107     if (!First)
108       OS << (shouldNegate() ? "&& " : "|| ");
109 
110     expandCheckOpcode(OS, Rec);
111     First = false;
112   }
113 
114   OS << '\n';
115   decreaseIndentLevel();
116   OS.indent(getIndentLevel() * 2);
117   OS << ')';
118 }
119 
120 void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
121                                           const RecVec &Opcodes) {
122   if (shouldExpandForMC())
123     expandFalse(OS);
124   else
125     expandCheckOpcode(OS, Opcodes);
126 }
127 
128 void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
129                                                 const RecVec &Sequence,
130                                                 bool IsCheckAll) {
131   assert(!Sequence.empty() && "Found an invalid empty predicate set!");
132   if (Sequence.size() == 1)
133     return expandPredicate(OS, Sequence[0]);
134 
135   // Okay, there is more than one predicate in the set.
136   bool First = true;
137   OS << (shouldNegate() ? "!(" : "(");
138   increaseIndentLevel();
139 
140   bool OldValue = shouldNegate();
141   setNegatePredicate(false);
142   for (const Record *Rec : Sequence) {
143     OS << '\n';
144     OS.indent(getIndentLevel() * 2);
145     if (!First)
146       OS << (IsCheckAll ? "&& " : "|| ");
147     expandPredicate(OS, Rec);
148     First = false;
149   }
150   OS << '\n';
151   decreaseIndentLevel();
152   OS.indent(getIndentLevel() * 2);
153   OS << ')';
154   setNegatePredicate(OldValue);
155 }
156 
157 void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
158                                               StringRef MethodName) {
159   OS << (shouldNegate() ? "!" : "");
160   OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
161   OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
162 }
163 
164 void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
165   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
166      << "getOperand(" << OpIndex << ").isReg() ";
167 }
168 
169 void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
170   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
171      << "getOperand(" << OpIndex << ").isImm() ";
172 }
173 
174 void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
175                                                      StringRef MCInstFn,
176                                                      StringRef MachineInstrFn) {
177   OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
178      << (isByRef() ? "(MI)" : "(*MI)");
179 }
180 
181 void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
182                                                StringRef Code) {
183   if (shouldExpandForMC())
184     return expandFalse(OS);
185 
186   OS << '(' << Code << ')';
187 }
188 
189 void PredicateExpander::expandReturnStatement(raw_ostream &OS,
190                                               const Record *Rec) {
191   std::string Buffer;
192   raw_string_ostream SS(Buffer);
193 
194   SS << "return ";
195   expandPredicate(SS, Rec);
196   SS << ";";
197   SS.flush();
198   OS << Buffer;
199 }
200 
201 void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
202                                                const Record *Rec) {
203   const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
204   for (const Record *Opcode : Opcodes) {
205     OS.indent(getIndentLevel() * 2);
206     OS << "case " << Opcode->getValueAsString("Namespace")
207        << "::" << Opcode->getName() << " :\n";
208   }
209 
210   increaseIndentLevel();
211   OS.indent(getIndentLevel() * 2);
212   expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
213   decreaseIndentLevel();
214 }
215 
216 void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
217                                                     const RecVec &Cases,
218                                                     const Record *Default) {
219   std::string Buffer;
220   raw_string_ostream SS(Buffer);
221 
222   SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
223   for (const Record *Rec : Cases) {
224     expandOpcodeSwitchCase(SS, Rec);
225     SS << '\n';
226   }
227 
228   // Expand the default case.
229   SS.indent(getIndentLevel() * 2);
230   SS << "default :\n";
231 
232   increaseIndentLevel();
233   SS.indent(getIndentLevel() * 2);
234   expandStatement(SS, Default);
235   decreaseIndentLevel();
236   SS << '\n';
237 
238   SS.indent(getIndentLevel() * 2);
239   SS << "} // end of switch-stmt";
240   SS.flush();
241   OS << Buffer;
242 }
243 
244 void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
245   // Assume that padding has been added by the caller.
246   if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
247     expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
248                                 Rec->getValueAsDef("DefaultCase"));
249     return;
250   }
251 
252   if (Rec->isSubClassOf("MCReturnStatement")) {
253     expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
254     return;
255   }
256 
257   llvm_unreachable("No known rules to expand this MCStatement");
258 }
259 
260 void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
261   // Assume that padding has been added by the caller.
262   if (Rec->isSubClassOf("MCTrue")) {
263     if (shouldNegate())
264       return expandFalse(OS);
265     return expandTrue(OS);
266   }
267 
268   if (Rec->isSubClassOf("MCFalse")) {
269     if (shouldNegate())
270       return expandTrue(OS);
271     return expandFalse(OS);
272   }
273 
274   if (Rec->isSubClassOf("CheckNot")) {
275     flipNegatePredicate();
276     expandPredicate(OS, Rec->getValueAsDef("Pred"));
277     flipNegatePredicate();
278     return;
279   }
280 
281   if (Rec->isSubClassOf("CheckIsRegOperand"))
282     return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
283 
284   if (Rec->isSubClassOf("CheckIsImmOperand"))
285     return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
286 
287   if (Rec->isSubClassOf("CheckRegOperand"))
288     return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
289                                  Rec->getValueAsDef("Reg"),
290                                  Rec->getValueAsString("FunctionMapper"));
291 
292   if (Rec->isSubClassOf("CheckRegOperandSimple"))
293     return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
294                                  nullptr,
295                                  Rec->getValueAsString("FunctionMapper"));
296 
297   if (Rec->isSubClassOf("CheckInvalidRegOperand"))
298     return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
299 
300   if (Rec->isSubClassOf("CheckImmOperand"))
301     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
302                                  Rec->getValueAsInt("ImmVal"),
303                                  Rec->getValueAsString("FunctionMapper"));
304 
305   if (Rec->isSubClassOf("CheckImmOperand_s"))
306     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
307                                  Rec->getValueAsString("ImmVal"),
308                                  Rec->getValueAsString("FunctionMapper"));
309 
310   if (Rec->isSubClassOf("CheckImmOperandSimple"))
311     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), "",
312                                  Rec->getValueAsString("FunctionMapper"));
313 
314   if (Rec->isSubClassOf("CheckSameRegOperand"))
315     return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
316                                      Rec->getValueAsInt("SecondIndex"));
317 
318   if (Rec->isSubClassOf("CheckNumOperands"))
319     return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
320 
321   if (Rec->isSubClassOf("CheckPseudo"))
322     return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
323 
324   if (Rec->isSubClassOf("CheckOpcode"))
325     return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
326 
327   if (Rec->isSubClassOf("CheckAll"))
328     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
329                                    /* AllOf */ true);
330 
331   if (Rec->isSubClassOf("CheckAny"))
332     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
333                                    /* AllOf */ false);
334 
335   if (Rec->isSubClassOf("CheckFunctionPredicate"))
336     return expandCheckFunctionPredicate(
337         OS, Rec->getValueAsString("MCInstFnName"),
338         Rec->getValueAsString("MachineInstrFnName"));
339 
340   if (Rec->isSubClassOf("CheckNonPortable"))
341     return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
342 
343   if (Rec->isSubClassOf("TIIPredicate"))
344     return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
345 
346   llvm_unreachable("No known rules to expand this MCInstPredicate");
347 }
348 
349 void STIPredicateExpander::expandHeader(raw_ostream &OS,
350                                         const STIPredicateFunction &Fn) {
351   const Record *Rec = Fn.getDeclaration();
352   StringRef FunctionName = Rec->getValueAsString("Name");
353 
354   OS.indent(getIndentLevel() * 2);
355   OS << "bool ";
356   if (shouldExpandDefinition())
357     OS << getClassPrefix() << "::";
358   OS << FunctionName << "(";
359   if (shouldExpandForMC())
360     OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
361   else
362     OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
363   if (Rec->getValueAsBit("UpdatesOpcodeMask"))
364     OS << ", APInt &Mask";
365   OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
366   if (shouldExpandDefinition()) {
367     OS << "{\n";
368     return;
369   }
370 
371   if (Rec->getValueAsBit("OverridesBaseClassMember"))
372     OS << "override";
373   OS << ";\n";
374 }
375 
376 void STIPredicateExpander::expandPrologue(raw_ostream &OS,
377                                           const STIPredicateFunction &Fn) {
378   RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates");
379   bool UpdatesOpcodeMask =
380       Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
381 
382   increaseIndentLevel();
383   unsigned IndentLevel = getIndentLevel();
384   for (const Record *Delegate : Delegates) {
385     OS.indent(IndentLevel * 2);
386     OS << "if (" << Delegate->getValueAsString("Name") << "(MI";
387     if (UpdatesOpcodeMask)
388       OS << ", Mask";
389     if (shouldExpandForMC())
390       OS << ", ProcessorID";
391     OS << "))\n";
392     OS.indent((1 + IndentLevel) * 2);
393     OS << "return true;\n\n";
394   }
395 
396   if (shouldExpandForMC())
397     return;
398 
399   OS.indent(IndentLevel * 2);
400   OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
401 }
402 
403 void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
404                                              bool ShouldUpdateOpcodeMask) {
405   const OpcodeInfo &OI = Group.getOpcodeInfo();
406   for (const PredicateInfo &PI : OI.getPredicates()) {
407     const APInt &ProcModelMask = PI.ProcModelMask;
408     bool FirstProcID = true;
409     for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) {
410       if (!ProcModelMask[I])
411         continue;
412 
413       if (FirstProcID) {
414         OS.indent(getIndentLevel() * 2);
415         OS << "if (ProcessorID == " << I;
416       } else {
417         OS << " || ProcessorID == " << I;
418       }
419       FirstProcID = false;
420     }
421 
422     OS << ") {\n";
423 
424     increaseIndentLevel();
425     OS.indent(getIndentLevel() * 2);
426     if (ShouldUpdateOpcodeMask) {
427       if (PI.OperandMask.isNullValue())
428         OS << "Mask.clearAllBits();\n";
429       else
430         OS << "Mask = " << PI.OperandMask << ";\n";
431       OS.indent(getIndentLevel() * 2);
432     }
433     OS << "return ";
434     expandPredicate(OS, PI.Predicate);
435     OS << ";\n";
436     decreaseIndentLevel();
437     OS.indent(getIndentLevel() * 2);
438     OS << "}\n";
439   }
440 }
441 
442 void STIPredicateExpander::expandBody(raw_ostream &OS,
443                                       const STIPredicateFunction &Fn) {
444   bool UpdatesOpcodeMask =
445       Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
446 
447   unsigned IndentLevel = getIndentLevel();
448   OS.indent(IndentLevel * 2);
449   OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
450   OS.indent(IndentLevel * 2);
451   OS << "default:\n";
452   OS.indent(IndentLevel * 2);
453   OS << "  break;";
454 
455   for (const OpcodeGroup &Group : Fn.getGroups()) {
456     for (const Record *Opcode : Group.getOpcodes()) {
457       OS << '\n';
458       OS.indent(IndentLevel * 2);
459       OS << "case " << getTargetName() << "::" << Opcode->getName() << ":";
460     }
461 
462     OS << '\n';
463     increaseIndentLevel();
464     expandOpcodeGroup(OS, Group, UpdatesOpcodeMask);
465 
466     OS.indent(getIndentLevel() * 2);
467     OS << "break;\n";
468     decreaseIndentLevel();
469   }
470 
471   OS.indent(IndentLevel * 2);
472   OS << "}\n";
473 }
474 
475 void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
476                                           const STIPredicateFunction &Fn) {
477   OS << '\n';
478   OS.indent(getIndentLevel() * 2);
479   OS << "return ";
480   expandPredicate(OS, Fn.getDefaultReturnPredicate());
481   OS << ";\n";
482 
483   decreaseIndentLevel();
484   OS.indent(getIndentLevel() * 2);
485   StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name");
486   OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n";
487 }
488 
489 void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS,
490                                               const STIPredicateFunction &Fn) {
491   const Record *Rec = Fn.getDeclaration();
492   if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC"))
493     return;
494 
495   expandHeader(OS, Fn);
496   if (shouldExpandDefinition()) {
497     expandPrologue(OS, Fn);
498     expandBody(OS, Fn);
499     expandEpilogue(OS, Fn);
500   }
501 }
502 
503 } // namespace llvm
504