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