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