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