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