xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/GISel/RISCVPostLegalizerCombiner.cpp (revision 95eb4b873b6a8b527c5bd78d7191975dfca38998)
1 //=== RISCVPostLegalizerCombiner.cpp --------------------------*- C++ -*-===//
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 /// \file
10 /// Post-legalization combines on generic MachineInstrs.
11 ///
12 /// The combines here must preserve instruction legality.
13 ///
14 /// Combines which don't rely on instruction legality should go in the
15 /// RISCVPreLegalizerCombiner.
16 ///
17 //===----------------------------------------------------------------------===//
18 
19 #include "RISCVTargetMachine.h"
20 #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
21 #include "llvm/CodeGen/GlobalISel/Combiner.h"
22 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
23 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
24 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
25 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
26 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
27 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
28 #include "llvm/CodeGen/MachineDominators.h"
29 #include "llvm/CodeGen/MachineFunctionPass.h"
30 #include "llvm/CodeGen/MachineRegisterInfo.h"
31 #include "llvm/CodeGen/TargetPassConfig.h"
32 
33 #define GET_GICOMBINER_DEPS
34 #include "RISCVGenPostLegalizeGICombiner.inc"
35 #undef GET_GICOMBINER_DEPS
36 
37 #define DEBUG_TYPE "riscv-postlegalizer-combiner"
38 
39 using namespace llvm;
40 
41 namespace {
42 
43 #define GET_GICOMBINER_TYPES
44 #include "RISCVGenPostLegalizeGICombiner.inc"
45 #undef GET_GICOMBINER_TYPES
46 
47 class RISCVPostLegalizerCombinerImpl : public Combiner {
48 protected:
49   // TODO: Make CombinerHelper methods const.
50   mutable CombinerHelper Helper;
51   const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig;
52   const RISCVSubtarget &STI;
53 
54 public:
55   RISCVPostLegalizerCombinerImpl(
56       MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
57       GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
58       const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
59       const RISCVSubtarget &STI, MachineDominatorTree *MDT,
60       const LegalizerInfo *LI);
61 
62   static const char *getName() { return "RISCVPostLegalizerCombiner"; }
63 
64   bool tryCombineAll(MachineInstr &I) const override;
65 
66 private:
67 #define GET_GICOMBINER_CLASS_MEMBERS
68 #include "RISCVGenPostLegalizeGICombiner.inc"
69 #undef GET_GICOMBINER_CLASS_MEMBERS
70 };
71 
72 #define GET_GICOMBINER_IMPL
73 #include "RISCVGenPostLegalizeGICombiner.inc"
74 #undef GET_GICOMBINER_IMPL
75 
76 RISCVPostLegalizerCombinerImpl::RISCVPostLegalizerCombinerImpl(
77     MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
78     GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
79     const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
80     const RISCVSubtarget &STI, MachineDominatorTree *MDT,
81     const LegalizerInfo *LI)
82     : Combiner(MF, CInfo, TPC, &KB, CSEInfo),
83       Helper(Observer, B, /*IsPreLegalize*/ false, &KB, MDT, LI),
84       RuleConfig(RuleConfig), STI(STI),
85 #define GET_GICOMBINER_CONSTRUCTOR_INITS
86 #include "RISCVGenPostLegalizeGICombiner.inc"
87 #undef GET_GICOMBINER_CONSTRUCTOR_INITS
88 {
89 }
90 
91 class RISCVPostLegalizerCombiner : public MachineFunctionPass {
92 public:
93   static char ID;
94 
95   RISCVPostLegalizerCombiner();
96 
97   StringRef getPassName() const override {
98     return "RISCVPostLegalizerCombiner";
99   }
100 
101   bool runOnMachineFunction(MachineFunction &MF) override;
102   void getAnalysisUsage(AnalysisUsage &AU) const override;
103 
104 private:
105   RISCVPostLegalizerCombinerImplRuleConfig RuleConfig;
106 };
107 } // end anonymous namespace
108 
109 void RISCVPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
110   AU.addRequired<TargetPassConfig>();
111   AU.setPreservesCFG();
112   getSelectionDAGFallbackAnalysisUsage(AU);
113   AU.addRequired<GISelKnownBitsAnalysis>();
114   AU.addPreserved<GISelKnownBitsAnalysis>();
115   AU.addRequired<MachineDominatorTree>();
116   AU.addPreserved<MachineDominatorTree>();
117   AU.addRequired<GISelCSEAnalysisWrapperPass>();
118   AU.addPreserved<GISelCSEAnalysisWrapperPass>();
119   MachineFunctionPass::getAnalysisUsage(AU);
120 }
121 
122 RISCVPostLegalizerCombiner::RISCVPostLegalizerCombiner()
123     : MachineFunctionPass(ID) {
124   initializeRISCVPostLegalizerCombinerPass(*PassRegistry::getPassRegistry());
125 
126   if (!RuleConfig.parseCommandLineOption())
127     report_fatal_error("Invalid rule identifier");
128 }
129 
130 bool RISCVPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
131   if (MF.getProperties().hasProperty(
132           MachineFunctionProperties::Property::FailedISel))
133     return false;
134   assert(MF.getProperties().hasProperty(
135              MachineFunctionProperties::Property::Legalized) &&
136          "Expected a legalized function?");
137   auto *TPC = &getAnalysis<TargetPassConfig>();
138   const Function &F = MF.getFunction();
139   bool EnableOpt =
140       MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
141 
142   const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
143   const auto *LI = ST.getLegalizerInfo();
144 
145   GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
146   MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
147   GISelCSEAnalysisWrapper &Wrapper =
148       getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
149   auto *CSEInfo = &Wrapper.get(TPC->getCSEConfig());
150 
151   CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
152                      /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
153                      F.hasMinSize());
154   RISCVPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *KB, CSEInfo,
155                                         RuleConfig, ST, MDT, LI);
156   return Impl.combineMachineInstrs();
157 }
158 
159 char RISCVPostLegalizerCombiner::ID = 0;
160 INITIALIZE_PASS_BEGIN(RISCVPostLegalizerCombiner, DEBUG_TYPE,
161                       "Combine RISC-V MachineInstrs after legalization", false,
162                       false)
163 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
164 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
165 INITIALIZE_PASS_END(RISCVPostLegalizerCombiner, DEBUG_TYPE,
166                     "Combine RISC-V MachineInstrs after legalization", false,
167                     false)
168 
169 namespace llvm {
170 FunctionPass *createRISCVPostLegalizerCombiner() {
171   return new RISCVPostLegalizerCombiner();
172 }
173 } // end namespace llvm
174