1 //=== RISCVPreLegalizerCombiner.cpp ---------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This pass does combining of machine instructions at the generic MI level,
10 // before the legalizer.
12 //===----------------------------------------------------------------------===//
14 #include "RISCVSubtarget.h"
15 #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
16 #include "llvm/CodeGen/GlobalISel/Combiner.h"
17 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
18 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
19 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
20 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
21 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
22 #include "llvm/CodeGen/MachineDominators.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/TargetPassConfig.h"
28 #define GET_GICOMBINER_DEPS
29 #include "RISCVGenPreLegalizeGICombiner.inc"
30 #undef GET_GICOMBINER_DEPS
32 #define DEBUG_TYPE "riscv-prelegalizer-combiner"
38 #define GET_GICOMBINER_TYPES
39 #include "RISCVGenPreLegalizeGICombiner.inc"
40 #undef GET_GICOMBINER_TYPES
42 class RISCVPreLegalizerCombinerImpl
: public Combiner
{
44 // TODO: Make CombinerHelper methods const.
45 mutable CombinerHelper Helper
;
46 const RISCVPreLegalizerCombinerImplRuleConfig
&RuleConfig
;
47 const RISCVSubtarget
&STI
;
50 RISCVPreLegalizerCombinerImpl(
51 MachineFunction
&MF
, CombinerInfo
&CInfo
, const TargetPassConfig
*TPC
,
52 GISelKnownBits
&KB
, GISelCSEInfo
*CSEInfo
,
53 const RISCVPreLegalizerCombinerImplRuleConfig
&RuleConfig
,
54 const RISCVSubtarget
&STI
, MachineDominatorTree
*MDT
,
55 const LegalizerInfo
*LI
);
57 static const char *getName() { return "RISCV00PreLegalizerCombiner"; }
59 bool tryCombineAll(MachineInstr
&I
) const override
;
62 #define GET_GICOMBINER_CLASS_MEMBERS
63 #include "RISCVGenPreLegalizeGICombiner.inc"
64 #undef GET_GICOMBINER_CLASS_MEMBERS
67 #define GET_GICOMBINER_IMPL
68 #include "RISCVGenPreLegalizeGICombiner.inc"
69 #undef GET_GICOMBINER_IMPL
71 RISCVPreLegalizerCombinerImpl::RISCVPreLegalizerCombinerImpl(
72 MachineFunction
&MF
, CombinerInfo
&CInfo
, const TargetPassConfig
*TPC
,
73 GISelKnownBits
&KB
, GISelCSEInfo
*CSEInfo
,
74 const RISCVPreLegalizerCombinerImplRuleConfig
&RuleConfig
,
75 const RISCVSubtarget
&STI
, MachineDominatorTree
*MDT
,
76 const LegalizerInfo
*LI
)
77 : Combiner(MF
, CInfo
, TPC
, &KB
, CSEInfo
),
78 Helper(Observer
, B
, /*IsPreLegalize*/ true, &KB
, MDT
, LI
),
79 RuleConfig(RuleConfig
), STI(STI
),
80 #define GET_GICOMBINER_CONSTRUCTOR_INITS
81 #include "RISCVGenPreLegalizeGICombiner.inc"
82 #undef GET_GICOMBINER_CONSTRUCTOR_INITS
89 class RISCVPreLegalizerCombiner
: public MachineFunctionPass
{
93 RISCVPreLegalizerCombiner();
95 StringRef
getPassName() const override
{ return "RISCVPreLegalizerCombiner"; }
97 bool runOnMachineFunction(MachineFunction
&MF
) override
;
99 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
102 RISCVPreLegalizerCombinerImplRuleConfig RuleConfig
;
104 } // end anonymous namespace
106 void RISCVPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage
&AU
) const {
107 AU
.addRequired
<TargetPassConfig
>();
108 AU
.setPreservesCFG();
109 getSelectionDAGFallbackAnalysisUsage(AU
);
110 AU
.addRequired
<GISelKnownBitsAnalysis
>();
111 AU
.addPreserved
<GISelKnownBitsAnalysis
>();
112 AU
.addRequired
<MachineDominatorTree
>();
113 AU
.addPreserved
<MachineDominatorTree
>();
114 AU
.addRequired
<GISelCSEAnalysisWrapperPass
>();
115 AU
.addPreserved
<GISelCSEAnalysisWrapperPass
>();
116 MachineFunctionPass::getAnalysisUsage(AU
);
119 RISCVPreLegalizerCombiner::RISCVPreLegalizerCombiner()
120 : MachineFunctionPass(ID
) {
121 initializeRISCVPreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
123 if (!RuleConfig
.parseCommandLineOption())
124 report_fatal_error("Invalid rule identifier");
127 bool RISCVPreLegalizerCombiner::runOnMachineFunction(MachineFunction
&MF
) {
128 if (MF
.getProperties().hasProperty(
129 MachineFunctionProperties::Property::FailedISel
))
131 auto &TPC
= getAnalysis
<TargetPassConfig
>();
134 GISelCSEAnalysisWrapper
&Wrapper
=
135 getAnalysis
<GISelCSEAnalysisWrapperPass
>().getCSEWrapper();
136 auto *CSEInfo
= &Wrapper
.get(TPC
.getCSEConfig());
138 const RISCVSubtarget
&ST
= MF
.getSubtarget
<RISCVSubtarget
>();
139 const auto *LI
= ST
.getLegalizerInfo();
141 const Function
&F
= MF
.getFunction();
143 MF
.getTarget().getOptLevel() != CodeGenOptLevel::None
&& !skipFunction(F
);
144 GISelKnownBits
*KB
= &getAnalysis
<GISelKnownBitsAnalysis
>().get(MF
);
145 MachineDominatorTree
*MDT
= &getAnalysis
<MachineDominatorTree
>();
146 CombinerInfo
CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
147 /*LegalizerInfo*/ nullptr, EnableOpt
, F
.hasOptSize(),
149 RISCVPreLegalizerCombinerImpl
Impl(MF
, CInfo
, &TPC
, *KB
, CSEInfo
, RuleConfig
,
151 return Impl
.combineMachineInstrs();
154 char RISCVPreLegalizerCombiner::ID
= 0;
155 INITIALIZE_PASS_BEGIN(RISCVPreLegalizerCombiner
, DEBUG_TYPE
,
156 "Combine RISC-V machine instrs before legalization", false,
158 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig
)
159 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis
)
160 INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass
)
161 INITIALIZE_PASS_END(RISCVPreLegalizerCombiner
, DEBUG_TYPE
,
162 "Combine RISC-V machine instrs before legalization", false,
166 FunctionPass
*createRISCVPreLegalizerCombiner() {
167 return new RISCVPreLegalizerCombiner();
169 } // end namespace llvm