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