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