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