• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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