• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 namespace llvm {
17 
expandTrue(formatted_raw_ostream & OS)18 void PredicateExpander::expandTrue(formatted_raw_ostream &OS) { OS << "true"; }
expandFalse(formatted_raw_ostream & OS)19 void PredicateExpander::expandFalse(formatted_raw_ostream &OS) {
20   OS << "false";
21 }
22 
expandCheckImmOperand(formatted_raw_ostream & OS,int OpIndex,int ImmVal)23 void PredicateExpander::expandCheckImmOperand(formatted_raw_ostream &OS,
24                                               int OpIndex, int ImmVal) {
25   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
26      << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
27 }
28 
expandCheckImmOperand(formatted_raw_ostream & OS,int OpIndex,StringRef ImmVal)29 void PredicateExpander::expandCheckImmOperand(formatted_raw_ostream &OS,
30                                               int OpIndex, StringRef ImmVal) {
31   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
32      << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
33 }
34 
expandCheckRegOperand(formatted_raw_ostream & OS,int OpIndex,const Record * Reg)35 void PredicateExpander::expandCheckRegOperand(formatted_raw_ostream &OS,
36                                               int OpIndex, const Record *Reg) {
37   assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
38 
39   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
40      << ").getReg() " << (shouldNegate() ? "!= " : "== ");
41   const StringRef Str = Reg->getValueAsString("Namespace");
42   if (!Str.empty())
43     OS << Str << "::";
44   OS << Reg->getName();
45 }
46 
expandCheckInvalidRegOperand(formatted_raw_ostream & OS,int OpIndex)47 void PredicateExpander::expandCheckInvalidRegOperand(formatted_raw_ostream &OS,
48                                                      int OpIndex) {
49   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
50      << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
51 }
52 
expandCheckSameRegOperand(formatted_raw_ostream & OS,int First,int Second)53 void PredicateExpander::expandCheckSameRegOperand(formatted_raw_ostream &OS,
54                                                   int First, int Second) {
55   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
56      << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
57      << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
58 }
59 
expandCheckNumOperands(formatted_raw_ostream & OS,int NumOps)60 void PredicateExpander::expandCheckNumOperands(formatted_raw_ostream &OS,
61                                                int NumOps) {
62   OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
63      << (shouldNegate() ? "!= " : "== ") << NumOps;
64 }
65 
expandCheckOpcode(formatted_raw_ostream & OS,const Record * Inst)66 void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
67                                           const Record *Inst) {
68   OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
69      << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
70      << "::" << Inst->getName();
71 }
72 
expandCheckOpcode(formatted_raw_ostream & OS,const RecVec & Opcodes)73 void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
74                                           const RecVec &Opcodes) {
75   assert(!Opcodes.empty() && "Expected at least one opcode to check!");
76   bool First = true;
77 
78   if (Opcodes.size() == 1) {
79     OS << "( ";
80     expandCheckOpcode(OS, Opcodes[0]);
81     OS << " )";
82     return;
83   }
84 
85   OS << '(';
86   increaseIndentLevel();
87   for (const Record *Rec : Opcodes) {
88     OS << '\n';
89     OS.PadToColumn(getIndentLevel() * 2);
90     if (!First)
91       OS << (shouldNegate() ? "&& " : "|| ");
92 
93     expandCheckOpcode(OS, Rec);
94     First = false;
95   }
96 
97   OS << '\n';
98   decreaseIndentLevel();
99   OS.PadToColumn(getIndentLevel() * 2);
100   OS << ')';
101 }
102 
expandCheckPseudo(formatted_raw_ostream & OS,const RecVec & Opcodes)103 void PredicateExpander::expandCheckPseudo(formatted_raw_ostream &OS,
104                                           const RecVec &Opcodes) {
105   if (shouldExpandForMC())
106     expandFalse(OS);
107   else
108     expandCheckOpcode(OS, Opcodes);
109 }
110 
expandPredicateSequence(formatted_raw_ostream & OS,const RecVec & Sequence,bool IsCheckAll)111 void PredicateExpander::expandPredicateSequence(formatted_raw_ostream &OS,
112                                                 const RecVec &Sequence,
113                                                 bool IsCheckAll) {
114   assert(!Sequence.empty() && "Found an invalid empty predicate set!");
115   if (Sequence.size() == 1)
116     return expandPredicate(OS, Sequence[0]);
117 
118   // Okay, there is more than one predicate in the set.
119   bool First = true;
120   OS << (shouldNegate() ? "!(" : "(");
121   increaseIndentLevel();
122 
123   bool OldValue = shouldNegate();
124   setNegatePredicate(false);
125   for (const Record *Rec : Sequence) {
126     OS << '\n';
127     OS.PadToColumn(getIndentLevel() * 2);
128     if (!First)
129       OS << (IsCheckAll ? "&& " : "|| ");
130     expandPredicate(OS, Rec);
131     First = false;
132   }
133   OS << '\n';
134   decreaseIndentLevel();
135   OS.PadToColumn(getIndentLevel() * 2);
136   OS << ')';
137   setNegatePredicate(OldValue);
138 }
139 
expandTIIFunctionCall(formatted_raw_ostream & OS,StringRef TargetName,StringRef MethodName)140 void PredicateExpander::expandTIIFunctionCall(formatted_raw_ostream &OS,
141                                               StringRef TargetName,
142                                               StringRef MethodName) {
143   OS << (shouldNegate() ? "!" : "");
144   if (shouldExpandForMC())
145     OS << TargetName << "_MC::";
146   else
147     OS << TargetName << "Gen"
148        << "InstrInfo::";
149   OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
150 }
151 
expandCheckIsRegOperand(formatted_raw_ostream & OS,int OpIndex)152 void PredicateExpander::expandCheckIsRegOperand(formatted_raw_ostream &OS,
153                                                 int OpIndex) {
154   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
155      << "getOperand(" << OpIndex << ").isReg() ";
156 }
157 
expandCheckIsImmOperand(formatted_raw_ostream & OS,int OpIndex)158 void PredicateExpander::expandCheckIsImmOperand(formatted_raw_ostream &OS,
159                                                 int OpIndex) {
160   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
161      << "getOperand(" << OpIndex << ").isImm() ";
162 }
163 
expandCheckFunctionPredicate(formatted_raw_ostream & OS,StringRef MCInstFn,StringRef MachineInstrFn)164 void PredicateExpander::expandCheckFunctionPredicate(formatted_raw_ostream &OS,
165                                                      StringRef MCInstFn,
166                                                      StringRef MachineInstrFn) {
167   OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
168      << (isByRef() ? "(MI)" : "(*MI)");
169 }
170 
expandCheckNonPortable(formatted_raw_ostream & OS,StringRef Code)171 void PredicateExpander::expandCheckNonPortable(formatted_raw_ostream &OS,
172                                                StringRef Code) {
173   if (shouldExpandForMC())
174     return expandFalse(OS);
175 
176   OS << '(' << Code << ')';
177 }
178 
expandPredicate(formatted_raw_ostream & OS,const Record * Rec)179 void PredicateExpander::expandPredicate(formatted_raw_ostream &OS,
180                                         const Record *Rec) {
181   OS.flush();
182   unsigned ColNum = getIndentLevel() * 2;
183   if (OS.getColumn() < ColNum)
184     OS.PadToColumn(ColNum);
185 
186   if (Rec->isSubClassOf("MCTrue")) {
187     if (shouldNegate())
188       return expandFalse(OS);
189     return expandTrue(OS);
190   }
191 
192   if (Rec->isSubClassOf("MCFalse")) {
193     if (shouldNegate())
194       return expandTrue(OS);
195     return expandFalse(OS);
196   }
197 
198   if (Rec->isSubClassOf("CheckNot")) {
199     flipNegatePredicate();
200     expandPredicate(OS, Rec->getValueAsDef("Pred"));
201     flipNegatePredicate();
202     return;
203   }
204 
205   if (Rec->isSubClassOf("CheckIsRegOperand"))
206     return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
207 
208   if (Rec->isSubClassOf("CheckIsImmOperand"))
209     return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
210 
211   if (Rec->isSubClassOf("CheckRegOperand"))
212     return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
213                                  Rec->getValueAsDef("Reg"));
214 
215   if (Rec->isSubClassOf("CheckInvalidRegOperand"))
216     return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
217 
218   if (Rec->isSubClassOf("CheckImmOperand"))
219     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
220                                  Rec->getValueAsInt("ImmVal"));
221 
222   if (Rec->isSubClassOf("CheckImmOperand_s"))
223     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
224                                  Rec->getValueAsString("ImmVal"));
225 
226   if (Rec->isSubClassOf("CheckSameRegOperand"))
227     return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
228                                      Rec->getValueAsInt("SecondIndex"));
229 
230   if (Rec->isSubClassOf("CheckNumOperands"))
231     return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
232 
233   if (Rec->isSubClassOf("CheckPseudo"))
234     return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
235 
236   if (Rec->isSubClassOf("CheckOpcode"))
237     return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
238 
239   if (Rec->isSubClassOf("CheckAll"))
240     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
241                                    /* AllOf */ true);
242 
243   if (Rec->isSubClassOf("CheckAny"))
244     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
245                                    /* AllOf */ false);
246 
247   if (Rec->isSubClassOf("CheckFunctionPredicate"))
248     return expandCheckFunctionPredicate(
249         OS, Rec->getValueAsString("MCInstFnName"),
250         Rec->getValueAsString("MachineInstrFnName"));
251 
252   if (Rec->isSubClassOf("CheckNonPortable"))
253     return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
254 
255   if (Rec->isSubClassOf("TIIPredicate"))
256     return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"),
257                                  Rec->getValueAsString("FunctionName"));
258 
259   llvm_unreachable("No known rules to expand this MCInstPredicate");
260 }
261 
262 } // namespace llvm
263