xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/GISel/RISCVO0PreLegalizerCombiner.cpp (revision aa1a8ff2d6dbc51ef058f46f3db5a8bb77967145)
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/MachineRegisterInfo.h"
25 #include "llvm/CodeGen/TargetPassConfig.h"
26 
27 #define GET_GICOMBINER_DEPS
28 #include "RISCVGenO0PreLegalizeGICombiner.inc"
29 #undef GET_GICOMBINER_DEPS
30 
31 #define DEBUG_TYPE "riscv-O0-prelegalizer-combiner"
32 
33 using namespace llvm;
34 
35 namespace {
36 #define GET_GICOMBINER_TYPES
37 #include "RISCVGenO0PreLegalizeGICombiner.inc"
38 #undef GET_GICOMBINER_TYPES
39 
40 class RISCVO0PreLegalizerCombinerImpl : public Combiner {
41 protected:
42   // TODO: Make CombinerHelper methods const.
43   mutable CombinerHelper Helper;
44   const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig;
45   const RISCVSubtarget &STI;
46 
47 public:
48   RISCVO0PreLegalizerCombinerImpl(
49       MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
50       GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
51       const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig,
52       const RISCVSubtarget &STI);
53 
54   static const char *getName() { return "RISCVO0PreLegalizerCombiner"; }
55 
56   bool tryCombineAll(MachineInstr &I) const override;
57 
58 private:
59 #define GET_GICOMBINER_CLASS_MEMBERS
60 #include "RISCVGenO0PreLegalizeGICombiner.inc"
61 #undef GET_GICOMBINER_CLASS_MEMBERS
62 };
63 
64 #define GET_GICOMBINER_IMPL
65 #include "RISCVGenO0PreLegalizeGICombiner.inc"
66 #undef GET_GICOMBINER_IMPL
67 
68 RISCVO0PreLegalizerCombinerImpl::RISCVO0PreLegalizerCombinerImpl(
69     MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
70     GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
71     const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig,
72     const RISCVSubtarget &STI)
73     : Combiner(MF, CInfo, TPC, &KB, CSEInfo),
74       Helper(Observer, B, /*IsPreLegalize*/ true, &KB), RuleConfig(RuleConfig),
75       STI(STI),
76 #define GET_GICOMBINER_CONSTRUCTOR_INITS
77 #include "RISCVGenO0PreLegalizeGICombiner.inc"
78 #undef GET_GICOMBINER_CONSTRUCTOR_INITS
79 {
80 }
81 
82 // Pass boilerplate
83 // ================
84 
85 class RISCVO0PreLegalizerCombiner : public MachineFunctionPass {
86 public:
87   static char ID;
88 
89   RISCVO0PreLegalizerCombiner();
90 
91   StringRef getPassName() const override {
92     return "RISCVO0PreLegalizerCombiner";
93   }
94 
95   bool runOnMachineFunction(MachineFunction &MF) override;
96 
97   void getAnalysisUsage(AnalysisUsage &AU) const override;
98 
99 private:
100   RISCVO0PreLegalizerCombinerImplRuleConfig RuleConfig;
101 };
102 } // end anonymous namespace
103 
104 void RISCVO0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
105   AU.addRequired<TargetPassConfig>();
106   AU.setPreservesCFG();
107   getSelectionDAGFallbackAnalysisUsage(AU);
108   AU.addRequired<GISelKnownBitsAnalysis>();
109   AU.addPreserved<GISelKnownBitsAnalysis>();
110   MachineFunctionPass::getAnalysisUsage(AU);
111 }
112 
113 RISCVO0PreLegalizerCombiner::RISCVO0PreLegalizerCombiner()
114     : MachineFunctionPass(ID) {
115   initializeRISCVO0PreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
116 
117   if (!RuleConfig.parseCommandLineOption())
118     report_fatal_error("Invalid rule identifier");
119 }
120 
121 bool RISCVO0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
122   if (MF.getProperties().hasProperty(
123           MachineFunctionProperties::Property::FailedISel))
124     return false;
125   auto &TPC = getAnalysis<TargetPassConfig>();
126 
127   const Function &F = MF.getFunction();
128   GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
129 
130   const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
131 
132   CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
133                      /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
134                      F.hasOptSize(), F.hasMinSize());
135   RISCVO0PreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *KB,
136                                        /*CSEInfo*/ nullptr, RuleConfig, ST);
137   return Impl.combineMachineInstrs();
138 }
139 
140 char RISCVO0PreLegalizerCombiner::ID = 0;
141 INITIALIZE_PASS_BEGIN(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
142                       "Combine RISC-V machine instrs before legalization", false,
143                       false)
144 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
145 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
146 INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
147 INITIALIZE_PASS_END(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
148                     "Combine RISC-V machine instrs before legalization", false,
149                     false)
150 
151 namespace llvm {
152 FunctionPass *createRISCVO0PreLegalizerCombiner() {
153   return new RISCVO0PreLegalizerCombiner();
154 }
155 } // end namespace llvm
156