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