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