xref: /llvm-project/llvm/lib/Target/RISCV/GISel/RISCVO0PreLegalizerCombiner.cpp (revision ee7ca0dddafb609090ad1789570c099d95c0afb6)
1 //=== RISCVO0PreLegalizerCombiner.cpp -------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass does combining of machine instructions at the generic MI level,
10 // before the legalizer.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "RISCVSubtarget.h"
15 #include "llvm/CodeGen/GlobalISel/Combiner.h"
16 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
17 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
18 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
19 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
20 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
21 #include "llvm/CodeGen/MachineDominators.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/TargetPassConfig.h"
25 
26 #define GET_GICOMBINER_DEPS
27 #include "RISCVGenO0PreLegalizeGICombiner.inc"
28 #undef GET_GICOMBINER_DEPS
29 
30 #define DEBUG_TYPE "riscv-O0-prelegalizer-combiner"
31 
32 using namespace llvm;
33 
34 namespace {
35 #define GET_GICOMBINER_TYPES
36 #include "RISCVGenO0PreLegalizeGICombiner.inc"
37 #undef GET_GICOMBINER_TYPES
38 
39 class RISCVO0PreLegalizerCombinerImpl : public Combiner {
40 protected:
41   const CombinerHelper Helper;
42   const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig;
43   const RISCVSubtarget &STI;
44 
45 public:
46   RISCVO0PreLegalizerCombinerImpl(
47       MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
48       GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
49       const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig,
50       const RISCVSubtarget &STI);
51 
52   static const char *getName() { return "RISCVO0PreLegalizerCombiner"; }
53 
54   bool tryCombineAll(MachineInstr &I) const override;
55 
56 private:
57 #define GET_GICOMBINER_CLASS_MEMBERS
58 #include "RISCVGenO0PreLegalizeGICombiner.inc"
59 #undef GET_GICOMBINER_CLASS_MEMBERS
60 };
61 
62 #define GET_GICOMBINER_IMPL
63 #include "RISCVGenO0PreLegalizeGICombiner.inc"
64 #undef GET_GICOMBINER_IMPL
65 
66 RISCVO0PreLegalizerCombinerImpl::RISCVO0PreLegalizerCombinerImpl(
67     MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
68     GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
69     const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig,
70     const RISCVSubtarget &STI)
71     : Combiner(MF, CInfo, TPC, &KB, CSEInfo),
72       Helper(Observer, B, /*IsPreLegalize*/ true, &KB), RuleConfig(RuleConfig),
73       STI(STI),
74 #define GET_GICOMBINER_CONSTRUCTOR_INITS
75 #include "RISCVGenO0PreLegalizeGICombiner.inc"
76 #undef GET_GICOMBINER_CONSTRUCTOR_INITS
77 {
78 }
79 
80 // Pass boilerplate
81 // ================
82 
83 class RISCVO0PreLegalizerCombiner : public MachineFunctionPass {
84 public:
85   static char ID;
86 
87   RISCVO0PreLegalizerCombiner();
88 
89   StringRef getPassName() const override {
90     return "RISCVO0PreLegalizerCombiner";
91   }
92 
93   bool runOnMachineFunction(MachineFunction &MF) override;
94 
95   void getAnalysisUsage(AnalysisUsage &AU) const override;
96 
97 private:
98   RISCVO0PreLegalizerCombinerImplRuleConfig RuleConfig;
99 };
100 } // end anonymous namespace
101 
102 void RISCVO0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
103   AU.addRequired<TargetPassConfig>();
104   AU.setPreservesCFG();
105   getSelectionDAGFallbackAnalysisUsage(AU);
106   AU.addRequired<GISelKnownBitsAnalysis>();
107   AU.addPreserved<GISelKnownBitsAnalysis>();
108   MachineFunctionPass::getAnalysisUsage(AU);
109 }
110 
111 RISCVO0PreLegalizerCombiner::RISCVO0PreLegalizerCombiner()
112     : MachineFunctionPass(ID) {
113   initializeRISCVO0PreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
114 
115   if (!RuleConfig.parseCommandLineOption())
116     report_fatal_error("Invalid rule identifier");
117 }
118 
119 bool RISCVO0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
120   if (MF.getProperties().hasProperty(
121           MachineFunctionProperties::Property::FailedISel))
122     return false;
123   auto &TPC = getAnalysis<TargetPassConfig>();
124 
125   const Function &F = MF.getFunction();
126   GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
127 
128   const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
129 
130   CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
131                      /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
132                      F.hasOptSize(), F.hasMinSize());
133   // Disable fixed-point iteration in the Combiner. This improves compile-time
134   // at the cost of possibly missing optimizations. See PR#94291 for details.
135   CInfo.MaxIterations = 1;
136 
137   RISCVO0PreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *KB,
138                                        /*CSEInfo*/ nullptr, RuleConfig, ST);
139   return Impl.combineMachineInstrs();
140 }
141 
142 char RISCVO0PreLegalizerCombiner::ID = 0;
143 INITIALIZE_PASS_BEGIN(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
144                       "Combine RISC-V machine instrs before legalization",
145                       false, false)
146 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
147 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
148 INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
149 INITIALIZE_PASS_END(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
150                     "Combine RISC-V machine instrs before legalization", false,
151                     false)
152 
153 namespace llvm {
154 FunctionPass *createRISCVO0PreLegalizerCombiner() {
155   return new RISCVO0PreLegalizerCombiner();
156 }
157 } // end namespace llvm
158