/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ |* *| |* Global Combiner *| |* *| |* Automatically generated file, do not edit! *| |* *| \*===----------------------------------------------------------------------===*/ #ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS #include "llvm/ADT/SparseBitVector.h" namespace llvm { extern cl::OptionCategory GICombinerOptionCategory; } // end namespace llvm #endif // ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_DEPS #ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_H class AArch64GenPostLegalizerLoweringHelperRuleConfig { SparseBitVector<> DisabledRules; public: bool parseCommandLineOption(); bool isRuleDisabled(unsigned ID) const; bool setRuleEnabled(StringRef RuleIdentifier); bool setRuleDisabled(StringRef RuleIdentifier); }; class AArch64GenPostLegalizerLoweringHelper { const AArch64GenPostLegalizerLoweringHelperRuleConfig *RuleConfig; public: template AArch64GenPostLegalizerLoweringHelper(const AArch64GenPostLegalizerLoweringHelperRuleConfig &RuleConfig, Args &&... args) : RuleConfig(&RuleConfig) {} bool tryCombineAll( GISelChangeObserver &Observer, MachineInstr &MI, MachineIRBuilder &B, CombinerHelper & Helper) const; }; static std::optional getRuleIdxForIdentifier(StringRef RuleIdentifier) { uint64_t I; // getAtInteger(...) returns false on success bool Parsed = !RuleIdentifier.getAsInteger(0, I); if (Parsed) return I; #ifndef NDEBUG switch (RuleIdentifier.size()) { default: break; case 3: // 6 strings to match. switch (RuleIdentifier[0]) { default: break; case 'd': // 1 string to match. if (memcmp(RuleIdentifier.data()+1, "up", 2) != 0) break; return 0; // "dup" case 'e': // 1 string to match. if (memcmp(RuleIdentifier.data()+1, "xt", 2) != 0) break; return 2; // "ext" case 'r': // 1 string to match. if (memcmp(RuleIdentifier.data()+1, "ev", 2) != 0) break; return 1; // "rev" case 't': // 1 string to match. if (memcmp(RuleIdentifier.data()+1, "rn", 2) != 0) break; return 5; // "trn" case 'u': // 1 string to match. if (memcmp(RuleIdentifier.data()+1, "zp", 2) != 0) break; return 4; // "uzp" case 'z': // 1 string to match. if (memcmp(RuleIdentifier.data()+1, "ip", 2) != 0) break; return 3; // "zip" } break; case 11: // 1 string to match. if (memcmp(RuleIdentifier.data()+0, "shuf_to_ins", 11) != 0) break; return 7; // "shuf_to_ins" case 12: // 1 string to match. if (memcmp(RuleIdentifier.data()+0, "form_duplane", 12) != 0) break; return 6; // "form_duplane" case 15: // 3 strings to match. switch (RuleIdentifier[0]) { default: break; case 'a': // 1 string to match. if (memcmp(RuleIdentifier.data()+1, "djust_icmp_imm", 14) != 0) break; return 9; // "adjust_icmp_imm" case 'f': // 1 string to match. if (memcmp(RuleIdentifier.data()+1, "orm_truncstore", 14) != 0) break; return 13; // "form_truncstore" case 'v': // 1 string to match. if (memcmp(RuleIdentifier.data()+1, "ashr_vlshr_imm", 14) != 0) break; return 8; // "vashr_vlshr_imm" } break; case 17: // 1 string to match. if (memcmp(RuleIdentifier.data()+0, "lower_vector_fcmp", 17) != 0) break; return 12; // "lower_vector_fcmp" case 18: // 1 string to match. if (memcmp(RuleIdentifier.data()+0, "swap_icmp_operands", 18) != 0) break; return 10; // "swap_icmp_operands" case 19: // 1 string to match. if (memcmp(RuleIdentifier.data()+0, "build_vector_to_dup", 19) != 0) break; return 11; // "build_vector_to_dup" case 26: // 1 string to match. if (memcmp(RuleIdentifier.data()+0, "vector_sext_inreg_to_shift", 26) != 0) break; return 14; // "vector_sext_inreg_to_shift" } #endif // ifndef NDEBUG return std::nullopt; } static std::optional> getRuleRangeForIdentifier(StringRef RuleIdentifier) { std::pair RangePair = RuleIdentifier.split('-'); if (!RangePair.second.empty()) { const auto First = getRuleIdxForIdentifier(RangePair.first); const auto Last = getRuleIdxForIdentifier(RangePair.second); if (!First || !Last) return std::nullopt; if (First >= Last) report_fatal_error("Beginning of range should be before end of range"); return {{*First, *Last + 1}}; } if (RangePair.first == "*") { return {{0, 15}}; } const auto I = getRuleIdxForIdentifier(RangePair.first); if (!I) return std::nullopt; return {{*I, *I + 1}}; } bool AArch64GenPostLegalizerLoweringHelperRuleConfig::setRuleEnabled(StringRef RuleIdentifier) { auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier); if (!MaybeRange) return false; for (auto I = MaybeRange->first; I < MaybeRange->second; ++I) DisabledRules.reset(I); return true; } bool AArch64GenPostLegalizerLoweringHelperRuleConfig::setRuleDisabled(StringRef RuleIdentifier) { auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier); if (!MaybeRange) return false; for (auto I = MaybeRange->first; I < MaybeRange->second; ++I) DisabledRules.set(I); return true; } bool AArch64GenPostLegalizerLoweringHelperRuleConfig::isRuleDisabled(unsigned RuleID) const { return DisabledRules.test(RuleID); } #endif // ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_H #ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_CPP std::vector AArch64PostLegalizerLoweringHelperOption; cl::list AArch64PostLegalizerLoweringHelperDisableOption( "aarch64postlegalizerloweringhelper-disable-rule", cl::desc("Disable one or more combiner rules temporarily in the AArch64PostLegalizerLoweringHelper pass"), cl::CommaSeparated, cl::Hidden, cl::cat(GICombinerOptionCategory), cl::callback([](const std::string &Str) { AArch64PostLegalizerLoweringHelperOption.push_back(Str); })); cl::list AArch64PostLegalizerLoweringHelperOnlyEnableOption( "aarch64postlegalizerloweringhelper-only-enable-rule", cl::desc("Disable all rules in the AArch64PostLegalizerLoweringHelper pass then re-enable the specified ones"), cl::Hidden, cl::cat(GICombinerOptionCategory), cl::callback([](const std::string &CommaSeparatedArg) { StringRef Str = CommaSeparatedArg; AArch64PostLegalizerLoweringHelperOption.push_back("*"); do { auto X = Str.split(","); AArch64PostLegalizerLoweringHelperOption.push_back(("!" + X.first).str()); Str = X.second; } while (!Str.empty()); })); bool AArch64GenPostLegalizerLoweringHelperRuleConfig::parseCommandLineOption() { for (StringRef Identifier : AArch64PostLegalizerLoweringHelperOption) { bool Enabled = Identifier.consume_front("!"); if (Enabled && !setRuleEnabled(Identifier)) return false; if (!Enabled && !setRuleDisabled(Identifier)) return false; } return true; } bool AArch64GenPostLegalizerLoweringHelper::tryCombineAll( GISelChangeObserver &Observer, MachineInstr &MI, MachineIRBuilder &B, CombinerHelper & Helper) const { MachineBasicBlock *MBB = MI.getParent(); MachineFunction *MF = MBB->getParent(); MachineRegisterInfo &MRI = MF->getRegInfo(); SmallVector MIs = {&MI}; (void)MBB; (void)MF; (void)MRI; (void)RuleConfig; // Match data ShuffleVectorPseudo MatchData0; ShuffleVectorPseudo MatchData1; ShuffleVectorPseudo MatchData2; ShuffleVectorPseudo MatchData3; ShuffleVectorPseudo MatchData4; ShuffleVectorPseudo MatchData5; std::pair MatchData6; std::tuple MatchData7; int64_t MatchData8; std::pair MatchData9; Register MatchData13; int Partition = -1; Partition = -1; switch (MIs[0]->getOpcode()) { case TargetOpcode::G_SHUFFLE_VECTOR: Partition = 0; break; case TargetOpcode::G_ASHR: Partition = 1; break; case TargetOpcode::G_LSHR: Partition = 2; break; case TargetOpcode::G_ICMP: Partition = 3; break; case TargetOpcode::G_BUILD_VECTOR: Partition = 4; break; case TargetOpcode::G_FCMP: Partition = 5; break; case TargetOpcode::G_STORE: Partition = 6; break; case TargetOpcode::G_SEXT_INREG: Partition = 7; break; } // Default case but without conflicting with potential default case in selection. if (Partition == -1) return false; if (Partition == 0 /* TargetOpcode::G_SHUFFLE_VECTOR */) { // Leaf name: dup // Rule: dup if (!RuleConfig->isRuleDisabled(0)) { if (1 && [&]() { return matchDup(*MIs[0], MRI, MatchData0); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'dup'\n"); applyShuffleVectorPseudo(*MIs[0], MatchData0); return true; } } // Leaf name: rev // Rule: rev if (!RuleConfig->isRuleDisabled(1)) { if (1 && [&]() { return matchREV(*MIs[0], MRI, MatchData1); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'rev'\n"); applyShuffleVectorPseudo(*MIs[0], MatchData1); return true; } } // Leaf name: ext // Rule: ext if (!RuleConfig->isRuleDisabled(2)) { if (1 && [&]() { return matchEXT(*MIs[0], MRI, MatchData2); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'ext'\n"); applyEXT(*MIs[0], MatchData2); return true; } } // Leaf name: zip // Rule: zip if (!RuleConfig->isRuleDisabled(3)) { if (1 && [&]() { return matchZip(*MIs[0], MRI, MatchData3); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'zip'\n"); applyShuffleVectorPseudo(*MIs[0], MatchData3); return true; } } // Leaf name: uzp // Rule: uzp if (!RuleConfig->isRuleDisabled(4)) { if (1 && [&]() { return matchUZP(*MIs[0], MRI, MatchData4); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'uzp'\n"); applyShuffleVectorPseudo(*MIs[0], MatchData4); return true; } } // Leaf name: trn // Rule: trn if (!RuleConfig->isRuleDisabled(5)) { if (1 && [&]() { return matchTRN(*MIs[0], MRI, MatchData5); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'trn'\n"); applyShuffleVectorPseudo(*MIs[0], MatchData5); return true; } } // Leaf name: form_duplane // Rule: form_duplane if (!RuleConfig->isRuleDisabled(6)) { if (1 && [&]() { return matchDupLane(*MIs[0], MRI, MatchData6); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'form_duplane'\n"); applyDupLane(*MIs[0], MRI, B, MatchData6); return true; } } // Leaf name: shuf_to_ins // Rule: shuf_to_ins if (!RuleConfig->isRuleDisabled(7)) { if (1 && [&]() { return matchINS(*MIs[0], MRI, MatchData7); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'shuf_to_ins'\n"); return applyINS(*MIs[0], MRI, B, MatchData7); return true; } } return false; } if (Partition == 1 /* TargetOpcode::G_ASHR */) { // Leaf name: vashr_vlshr_imm // Rule: vashr_vlshr_imm if (!RuleConfig->isRuleDisabled(8)) { if (1 && [&]() { return matchVAshrLshrImm(*MIs[0], MRI, MatchData8); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'vashr_vlshr_imm'\n"); applyVAshrLshrImm(*MIs[0], MRI, MatchData8); return true; } } return false; } if (Partition == 2 /* TargetOpcode::G_LSHR */) { // Leaf name: vashr_vlshr_imm // Rule: vashr_vlshr_imm if (!RuleConfig->isRuleDisabled(8)) { if (1 && [&]() { return matchVAshrLshrImm(*MIs[0], MRI, MatchData8); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'vashr_vlshr_imm'\n"); applyVAshrLshrImm(*MIs[0], MRI, MatchData8); return true; } } return false; } if (Partition == 3 /* TargetOpcode::G_ICMP */) { // Leaf name: adjust_icmp_imm // Rule: adjust_icmp_imm if (!RuleConfig->isRuleDisabled(9)) { if (1 && [&]() { return matchAdjustICmpImmAndPred(*MIs[0], MRI, MatchData9); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'adjust_icmp_imm'\n"); applyAdjustICmpImmAndPred(*MIs[0], MatchData9, B, Observer); return true; } } // Leaf name: swap_icmp_operands // Rule: swap_icmp_operands if (!RuleConfig->isRuleDisabled(10)) { if (1 && [&]() { return trySwapICmpOperands(*MIs[0], MRI); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'swap_icmp_operands'\n"); applySwapICmpOperands(*MIs[0], Observer); return true; } } return false; } if (Partition == 4 /* TargetOpcode::G_BUILD_VECTOR */) { // Leaf name: build_vector_to_dup // Rule: build_vector_to_dup if (!RuleConfig->isRuleDisabled(11)) { if (1 && [&]() { return matchBuildVectorToDup(*MIs[0], MRI); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'build_vector_to_dup'\n"); return applyBuildVectorToDup(*MIs[0], MRI, B); return true; } } return false; } if (Partition == 5 /* TargetOpcode::G_FCMP */) { // Leaf name: lower_vector_fcmp // Rule: lower_vector_fcmp if (!RuleConfig->isRuleDisabled(12)) { if (1 && [&]() { return lowerVectorFCMP(*MIs[0], MRI, B); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'lower_vector_fcmp'\n"); return true; } } return false; } if (Partition == 6 /* TargetOpcode::G_STORE */) { // Leaf name: form_truncstore // Rule: form_truncstore if (!RuleConfig->isRuleDisabled(13)) { if (1 && [&]() { return matchFormTruncstore(*MIs[0], MRI, MatchData13); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'form_truncstore'\n"); applyFormTruncstore(*MIs[0], MRI, B, Observer, MatchData13); return true; } } return false; } if (Partition == 7 /* TargetOpcode::G_SEXT_INREG */) { // Leaf name: vector_sext_inreg_to_shift // Rule: vector_sext_inreg_to_shift if (!RuleConfig->isRuleDisabled(14)) { if (1 && [&]() { return matchVectorSextInReg(*MIs[0], MRI); return true; }() ) { LLVM_DEBUG(dbgs() << "Applying rule 'vector_sext_inreg_to_shift'\n"); applyVectorSextInReg(*MIs[0], MRI, B, Observer); return true; } } return false; } return false; } #endif // ifdef AARCH64POSTLEGALIZERLOWERINGHELPER_GENCOMBINERHELPER_CPP