1/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ 2|* *| 3|* Global Combiner *| 4|* *| 5|* Automatically generated file, do not edit! *| 6|* *| 7\*===----------------------------------------------------------------------===*/ 8 9#ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS 10#include "llvm/ADT/SparseBitVector.h" 11namespace llvm { 12extern cl::OptionCategory GICombinerOptionCategory; 13} // end namespace llvm 14#endif // ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS 15 16#ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_H 17class AArch64GenPostLegalizerLoweringHelperRuleConfig { 18 SparseBitVector<> DisabledRules; 19 20public: 21 bool parseCommandLineOption(); 22 bool isRuleDisabled(unsigned ID) const; 23 bool setRuleEnabled(StringRef RuleIdentifier); 24 bool setRuleDisabled(StringRef RuleIdentifier); 25}; 26 27class AArch64GenPostLegalizerLoweringHelper { 28 const AArch64GenPostLegalizerLoweringHelperRuleConfig *RuleConfig; 29 30public: 31 template <typename... Args>AArch64GenPostLegalizerLoweringHelper(const AArch64GenPostLegalizerLoweringHelperRuleConfig &RuleConfig, Args &&... args) : RuleConfig(&RuleConfig) {} 32 33 bool tryCombineAll( 34 GISelChangeObserver &Observer, 35 MachineInstr &MI, 36 MachineIRBuilder &B, 37 CombinerHelper & Helper) const; 38}; 39 40static std::optional<uint64_t> getRuleIdxForIdentifier(StringRef RuleIdentifier) { 41 uint64_t I; 42 // getAtInteger(...) returns false on success 43 bool Parsed = !RuleIdentifier.getAsInteger(0, I); 44 if (Parsed) 45 return I; 46 47#ifndef NDEBUG 48 switch (RuleIdentifier.size()) { 49 default: break; 50 case 3: // 6 strings to match. 51 switch (RuleIdentifier[0]) { 52 default: break; 53 case 'd': // 1 string to match. 54 if (memcmp(RuleIdentifier.data()+1, "up", 2) != 0) 55 break; 56 return 0; // "dup" 57 case 'e': // 1 string to match. 58 if (memcmp(RuleIdentifier.data()+1, "xt", 2) != 0) 59 break; 60 return 2; // "ext" 61 case 'r': // 1 string to match. 62 if (memcmp(RuleIdentifier.data()+1, "ev", 2) != 0) 63 break; 64 return 1; // "rev" 65 case 't': // 1 string to match. 66 if (memcmp(RuleIdentifier.data()+1, "rn", 2) != 0) 67 break; 68 return 5; // "trn" 69 case 'u': // 1 string to match. 70 if (memcmp(RuleIdentifier.data()+1, "zp", 2) != 0) 71 break; 72 return 4; // "uzp" 73 case 'z': // 1 string to match. 74 if (memcmp(RuleIdentifier.data()+1, "ip", 2) != 0) 75 break; 76 return 3; // "zip" 77 } 78 break; 79 case 11: // 1 string to match. 80 if (memcmp(RuleIdentifier.data()+0, "shuf_to_ins", 11) != 0) 81 break; 82 return 7; // "shuf_to_ins" 83 case 12: // 1 string to match. 84 if (memcmp(RuleIdentifier.data()+0, "form_duplane", 12) != 0) 85 break; 86 return 6; // "form_duplane" 87 case 15: // 3 strings to match. 88 switch (RuleIdentifier[0]) { 89 default: break; 90 case 'a': // 1 string to match. 91 if (memcmp(RuleIdentifier.data()+1, "djust_icmp_imm", 14) != 0) 92 break; 93 return 9; // "adjust_icmp_imm" 94 case 'f': // 1 string to match. 95 if (memcmp(RuleIdentifier.data()+1, "orm_truncstore", 14) != 0) 96 break; 97 return 13; // "form_truncstore" 98 case 'v': // 1 string to match. 99 if (memcmp(RuleIdentifier.data()+1, "ashr_vlshr_imm", 14) != 0) 100 break; 101 return 8; // "vashr_vlshr_imm" 102 } 103 break; 104 case 17: // 1 string to match. 105 if (memcmp(RuleIdentifier.data()+0, "lower_vector_fcmp", 17) != 0) 106 break; 107 return 12; // "lower_vector_fcmp" 108 case 18: // 1 string to match. 109 if (memcmp(RuleIdentifier.data()+0, "swap_icmp_operands", 18) != 0) 110 break; 111 return 10; // "swap_icmp_operands" 112 case 19: // 1 string to match. 113 if (memcmp(RuleIdentifier.data()+0, "build_vector_to_dup", 19) != 0) 114 break; 115 return 11; // "build_vector_to_dup" 116 case 26: // 1 string to match. 117 if (memcmp(RuleIdentifier.data()+0, "vector_sext_inreg_to_shift", 26) != 0) 118 break; 119 return 14; // "vector_sext_inreg_to_shift" 120 } 121#endif // ifndef NDEBUG 122 123 return std::nullopt; 124} 125static std::optional<std::pair<uint64_t, uint64_t>> getRuleRangeForIdentifier(StringRef RuleIdentifier) { 126 std::pair<StringRef, StringRef> RangePair = RuleIdentifier.split('-'); 127 if (!RangePair.second.empty()) { 128 const auto First = getRuleIdxForIdentifier(RangePair.first); 129 const auto Last = getRuleIdxForIdentifier(RangePair.second); 130 if (!First || !Last) 131 return std::nullopt; 132 if (First >= Last) 133 report_fatal_error("Beginning of range should be before end of range"); 134 return {{*First, *Last + 1}}; 135 } 136 if (RangePair.first == "*") { 137 return {{0, 15}}; 138 } 139 const auto I = getRuleIdxForIdentifier(RangePair.first); 140 if (!I) 141 return std::nullopt; 142 return {{*I, *I + 1}}; 143} 144 145bool AArch64GenPostLegalizerLoweringHelperRuleConfig::setRuleEnabled(StringRef RuleIdentifier) { 146 auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier); 147 if (!MaybeRange) 148 return false; 149 for (auto I = MaybeRange->first; I < MaybeRange->second; ++I) 150 DisabledRules.reset(I); 151 return true; 152} 153 154bool AArch64GenPostLegalizerLoweringHelperRuleConfig::setRuleDisabled(StringRef RuleIdentifier) { 155 auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier); 156 if (!MaybeRange) 157 return false; 158 for (auto I = MaybeRange->first; I < MaybeRange->second; ++I) 159 DisabledRules.set(I); 160 return true; 161} 162 163bool AArch64GenPostLegalizerLoweringHelperRuleConfig::isRuleDisabled(unsigned RuleID) const { 164 return DisabledRules.test(RuleID); 165} 166#endif // ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_H 167 168#ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_CPP 169 170std::vector<std::string> AArch64PostLegalizerLoweringHelperOption; 171cl::list<std::string> AArch64PostLegalizerLoweringHelperDisableOption( 172 "aarch64postlegalizerloweringhelper-disable-rule", 173 cl::desc("Disable one or more combiner rules temporarily in the AArch64PostLegalizerLoweringHelper pass"), 174 cl::CommaSeparated, 175 cl::Hidden, 176 cl::cat(GICombinerOptionCategory), 177 cl::callback([](const std::string &Str) { 178 AArch64PostLegalizerLoweringHelperOption.push_back(Str); 179 })); 180cl::list<std::string> AArch64PostLegalizerLoweringHelperOnlyEnableOption( 181 "aarch64postlegalizerloweringhelper-only-enable-rule", 182 cl::desc("Disable all rules in the AArch64PostLegalizerLoweringHelper pass then re-enable the specified ones"), 183 cl::Hidden, 184 cl::cat(GICombinerOptionCategory), 185 cl::callback([](const std::string &CommaSeparatedArg) { 186 StringRef Str = CommaSeparatedArg; 187 AArch64PostLegalizerLoweringHelperOption.push_back("*"); 188 do { 189 auto X = Str.split(","); 190 AArch64PostLegalizerLoweringHelperOption.push_back(("!" + X.first).str()); 191 Str = X.second; 192 } while (!Str.empty()); 193 })); 194 195bool AArch64GenPostLegalizerLoweringHelperRuleConfig::parseCommandLineOption() { 196 for (StringRef Identifier : AArch64PostLegalizerLoweringHelperOption) { 197 bool Enabled = Identifier.consume_front("!"); 198 if (Enabled && !setRuleEnabled(Identifier)) 199 return false; 200 if (!Enabled && !setRuleDisabled(Identifier)) 201 return false; 202 } 203 return true; 204} 205 206bool AArch64GenPostLegalizerLoweringHelper::tryCombineAll( 207 GISelChangeObserver &Observer, 208 MachineInstr &MI, 209 MachineIRBuilder &B, 210 CombinerHelper & Helper) const { 211 MachineBasicBlock *MBB = MI.getParent(); 212 MachineFunction *MF = MBB->getParent(); 213 MachineRegisterInfo &MRI = MF->getRegInfo(); 214 SmallVector<MachineInstr *, 8> MIs = {&MI}; 215 216 (void)MBB; (void)MF; (void)MRI; (void)RuleConfig; 217 218 // Match data 219 ShuffleVectorPseudo MatchData0; 220 ShuffleVectorPseudo MatchData1; 221 ShuffleVectorPseudo MatchData2; 222 ShuffleVectorPseudo MatchData3; 223 ShuffleVectorPseudo MatchData4; 224 ShuffleVectorPseudo MatchData5; 225 std::pair<unsigned, int> MatchData6; 226 std::tuple<Register, int, Register, int> MatchData7; 227 int64_t MatchData8; 228 std::pair<uint64_t, CmpInst::Predicate> MatchData9; 229 Register MatchData13; 230 231 int Partition = -1; 232 Partition = -1; 233 switch (MIs[0]->getOpcode()) { 234 case TargetOpcode::G_SHUFFLE_VECTOR: Partition = 0; break; 235 case TargetOpcode::G_ASHR: Partition = 1; break; 236 case TargetOpcode::G_LSHR: Partition = 2; break; 237 case TargetOpcode::G_ICMP: Partition = 3; break; 238 case TargetOpcode::G_BUILD_VECTOR: Partition = 4; break; 239 case TargetOpcode::G_FCMP: Partition = 5; break; 240 case TargetOpcode::G_STORE: Partition = 6; break; 241 case TargetOpcode::G_SEXT_INREG: Partition = 7; break; 242 } 243 // Default case but without conflicting with potential default case in selection. 244 if (Partition == -1) return false; 245 if (Partition == 0 /* TargetOpcode::G_SHUFFLE_VECTOR */) { 246 // Leaf name: dup 247 // Rule: dup 248 if (!RuleConfig->isRuleDisabled(0)) { 249 if (1 250 && [&]() { 251 return matchDup(*MIs[0], MRI, MatchData0); 252 return true; 253 }() ) { 254 LLVM_DEBUG(dbgs() << "Applying rule 'dup'\n"); 255 applyShuffleVectorPseudo(*MIs[0], MatchData0); 256 return true; 257 } 258 } 259 // Leaf name: rev 260 // Rule: rev 261 if (!RuleConfig->isRuleDisabled(1)) { 262 if (1 263 && [&]() { 264 return matchREV(*MIs[0], MRI, MatchData1); 265 return true; 266 }() ) { 267 LLVM_DEBUG(dbgs() << "Applying rule 'rev'\n"); 268 applyShuffleVectorPseudo(*MIs[0], MatchData1); 269 return true; 270 } 271 } 272 // Leaf name: ext 273 // Rule: ext 274 if (!RuleConfig->isRuleDisabled(2)) { 275 if (1 276 && [&]() { 277 return matchEXT(*MIs[0], MRI, MatchData2); 278 return true; 279 }() ) { 280 LLVM_DEBUG(dbgs() << "Applying rule 'ext'\n"); 281 applyEXT(*MIs[0], MatchData2); 282 return true; 283 } 284 } 285 // Leaf name: zip 286 // Rule: zip 287 if (!RuleConfig->isRuleDisabled(3)) { 288 if (1 289 && [&]() { 290 return matchZip(*MIs[0], MRI, MatchData3); 291 return true; 292 }() ) { 293 LLVM_DEBUG(dbgs() << "Applying rule 'zip'\n"); 294 applyShuffleVectorPseudo(*MIs[0], MatchData3); 295 return true; 296 } 297 } 298 // Leaf name: uzp 299 // Rule: uzp 300 if (!RuleConfig->isRuleDisabled(4)) { 301 if (1 302 && [&]() { 303 return matchUZP(*MIs[0], MRI, MatchData4); 304 return true; 305 }() ) { 306 LLVM_DEBUG(dbgs() << "Applying rule 'uzp'\n"); 307 applyShuffleVectorPseudo(*MIs[0], MatchData4); 308 return true; 309 } 310 } 311 // Leaf name: trn 312 // Rule: trn 313 if (!RuleConfig->isRuleDisabled(5)) { 314 if (1 315 && [&]() { 316 return matchTRN(*MIs[0], MRI, MatchData5); 317 return true; 318 }() ) { 319 LLVM_DEBUG(dbgs() << "Applying rule 'trn'\n"); 320 applyShuffleVectorPseudo(*MIs[0], MatchData5); 321 return true; 322 } 323 } 324 // Leaf name: form_duplane 325 // Rule: form_duplane 326 if (!RuleConfig->isRuleDisabled(6)) { 327 if (1 328 && [&]() { 329 return matchDupLane(*MIs[0], MRI, MatchData6); 330 return true; 331 }() ) { 332 LLVM_DEBUG(dbgs() << "Applying rule 'form_duplane'\n"); 333 applyDupLane(*MIs[0], MRI, B, MatchData6); 334 return true; 335 } 336 } 337 // Leaf name: shuf_to_ins 338 // Rule: shuf_to_ins 339 if (!RuleConfig->isRuleDisabled(7)) { 340 if (1 341 && [&]() { 342 return matchINS(*MIs[0], MRI, MatchData7); 343 return true; 344 }() ) { 345 LLVM_DEBUG(dbgs() << "Applying rule 'shuf_to_ins'\n"); 346 return applyINS(*MIs[0], MRI, B, MatchData7); 347 return true; 348 } 349 } 350 return false; 351 } 352 if (Partition == 1 /* TargetOpcode::G_ASHR */) { 353 // Leaf name: vashr_vlshr_imm 354 // Rule: vashr_vlshr_imm 355 if (!RuleConfig->isRuleDisabled(8)) { 356 if (1 357 && [&]() { 358 return matchVAshrLshrImm(*MIs[0], MRI, MatchData8); 359 return true; 360 }() ) { 361 LLVM_DEBUG(dbgs() << "Applying rule 'vashr_vlshr_imm'\n"); 362 applyVAshrLshrImm(*MIs[0], MRI, MatchData8); 363 return true; 364 } 365 } 366 return false; 367 } 368 if (Partition == 2 /* TargetOpcode::G_LSHR */) { 369 // Leaf name: vashr_vlshr_imm 370 // Rule: vashr_vlshr_imm 371 if (!RuleConfig->isRuleDisabled(8)) { 372 if (1 373 && [&]() { 374 return matchVAshrLshrImm(*MIs[0], MRI, MatchData8); 375 return true; 376 }() ) { 377 LLVM_DEBUG(dbgs() << "Applying rule 'vashr_vlshr_imm'\n"); 378 applyVAshrLshrImm(*MIs[0], MRI, MatchData8); 379 return true; 380 } 381 } 382 return false; 383 } 384 if (Partition == 3 /* TargetOpcode::G_ICMP */) { 385 // Leaf name: adjust_icmp_imm 386 // Rule: adjust_icmp_imm 387 if (!RuleConfig->isRuleDisabled(9)) { 388 if (1 389 && [&]() { 390 return matchAdjustICmpImmAndPred(*MIs[0], MRI, MatchData9); 391 return true; 392 }() ) { 393 LLVM_DEBUG(dbgs() << "Applying rule 'adjust_icmp_imm'\n"); 394 applyAdjustICmpImmAndPred(*MIs[0], MatchData9, B, Observer); 395 return true; 396 } 397 } 398 // Leaf name: swap_icmp_operands 399 // Rule: swap_icmp_operands 400 if (!RuleConfig->isRuleDisabled(10)) { 401 if (1 402 && [&]() { 403 return trySwapICmpOperands(*MIs[0], MRI); 404 return true; 405 }() ) { 406 LLVM_DEBUG(dbgs() << "Applying rule 'swap_icmp_operands'\n"); 407 applySwapICmpOperands(*MIs[0], Observer); 408 return true; 409 } 410 } 411 return false; 412 } 413 if (Partition == 4 /* TargetOpcode::G_BUILD_VECTOR */) { 414 // Leaf name: build_vector_to_dup 415 // Rule: build_vector_to_dup 416 if (!RuleConfig->isRuleDisabled(11)) { 417 if (1 418 && [&]() { 419 return matchBuildVectorToDup(*MIs[0], MRI); 420 return true; 421 }() ) { 422 LLVM_DEBUG(dbgs() << "Applying rule 'build_vector_to_dup'\n"); 423 return applyBuildVectorToDup(*MIs[0], MRI, B); 424 return true; 425 } 426 } 427 return false; 428 } 429 if (Partition == 5 /* TargetOpcode::G_FCMP */) { 430 // Leaf name: lower_vector_fcmp 431 // Rule: lower_vector_fcmp 432 if (!RuleConfig->isRuleDisabled(12)) { 433 if (1 434 && [&]() { 435 return lowerVectorFCMP(*MIs[0], MRI, B); 436 return true; 437 }() ) { 438 LLVM_DEBUG(dbgs() << "Applying rule 'lower_vector_fcmp'\n"); 439 440 return true; 441 } 442 } 443 return false; 444 } 445 if (Partition == 6 /* TargetOpcode::G_STORE */) { 446 // Leaf name: form_truncstore 447 // Rule: form_truncstore 448 if (!RuleConfig->isRuleDisabled(13)) { 449 if (1 450 && [&]() { 451 return matchFormTruncstore(*MIs[0], MRI, MatchData13); 452 return true; 453 }() ) { 454 LLVM_DEBUG(dbgs() << "Applying rule 'form_truncstore'\n"); 455 applyFormTruncstore(*MIs[0], MRI, B, Observer, MatchData13); 456 return true; 457 } 458 } 459 return false; 460 } 461 if (Partition == 7 /* TargetOpcode::G_SEXT_INREG */) { 462 // Leaf name: vector_sext_inreg_to_shift 463 // Rule: vector_sext_inreg_to_shift 464 if (!RuleConfig->isRuleDisabled(14)) { 465 if (1 466 && [&]() { 467 return matchVectorSextInReg(*MIs[0], MRI); 468 return true; 469 }() ) { 470 LLVM_DEBUG(dbgs() << "Applying rule 'vector_sext_inreg_to_shift'\n"); 471 applyVectorSextInReg(*MIs[0], MRI, B, Observer); 472 return true; 473 } 474 } 475 return false; 476 } 477 478 return false; 479} 480#endif // ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_CPP 481