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