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