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/GISelValueTracking.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
25#define GET_GICOMBINER_DEPS
26#include "RISCVGenO0PreLegalizeGICombiner.inc"
27#undef GET_GICOMBINER_DEPS
28
29#define DEBUG_TYPE "riscv-O0-prelegalizer-combiner"
30
31using namespace llvm;
32
33namespace {
34#define GET_GICOMBINER_TYPES
35#include "RISCVGenO0PreLegalizeGICombiner.inc"
36#undef GET_GICOMBINER_TYPES
37
38class RISCVO0PreLegalizerCombinerImpl : public Combiner {
39protected:
40 const CombinerHelper Helper;
41 const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig;
42 const RISCVSubtarget &STI;
43
44public:
45 RISCVO0PreLegalizerCombinerImpl(
46 MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
47 GISelCSEInfo *CSEInfo,
48 const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig,
49 const RISCVSubtarget &STI);
50
51 static const char *getName() { return "RISCVO0PreLegalizerCombiner"; }
52
53 bool tryCombineAll(MachineInstr &I) const override;
54
55private:
56#define GET_GICOMBINER_CLASS_MEMBERS
57#include "RISCVGenO0PreLegalizeGICombiner.inc"
58#undef GET_GICOMBINER_CLASS_MEMBERS
59};
60
61#define GET_GICOMBINER_IMPL
62#include "RISCVGenO0PreLegalizeGICombiner.inc"
63#undef GET_GICOMBINER_IMPL
64
65RISCVO0PreLegalizerCombinerImpl::RISCVO0PreLegalizerCombinerImpl(
66 MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
67 GISelCSEInfo *CSEInfo,
68 const RISCVO0PreLegalizerCombinerImplRuleConfig &RuleConfig,
69 const RISCVSubtarget &STI)
70 : Combiner(MF, CInfo, &VT, CSEInfo),
71 Helper(Observer, B, /*IsPreLegalize*/ true, &VT), RuleConfig(RuleConfig),
72 STI(STI),
73#define GET_GICOMBINER_CONSTRUCTOR_INITS
74#include "RISCVGenO0PreLegalizeGICombiner.inc"
75#undef GET_GICOMBINER_CONSTRUCTOR_INITS
76{
77}
78
79// Pass boilerplate
80// ================
81
82class RISCVO0PreLegalizerCombiner : public MachineFunctionPass {
83public:
84 static char ID;
85
86 RISCVO0PreLegalizerCombiner();
87
88 StringRef getPassName() const override {
89 return "RISCVO0PreLegalizerCombiner";
90 }
91
92 bool runOnMachineFunction(MachineFunction &MF) override;
93
94 void getAnalysisUsage(AnalysisUsage &AU) const override;
95
96private:
97 RISCVO0PreLegalizerCombinerImplRuleConfig RuleConfig;
98};
99} // end anonymous namespace
100
101void RISCVO0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
102 AU.setPreservesCFG();
103 getSelectionDAGFallbackAnalysisUsage(AU);
104 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
105 AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
106 MachineFunctionPass::getAnalysisUsage(AU);
107}
108
109RISCVO0PreLegalizerCombiner::RISCVO0PreLegalizerCombiner()
110 : MachineFunctionPass(ID) {
111 if (!RuleConfig.parseCommandLineOption())
112 report_fatal_error(reason: "Invalid rule identifier");
113}
114
115bool RISCVO0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
116 if (MF.getProperties().hasFailedISel())
117 return false;
118
119 const Function &F = MF.getFunction();
120 GISelValueTracking *VT =
121 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
122
123 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
124
125 CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
126 /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
127 F.hasOptSize(), F.hasMinSize());
128 // Disable fixed-point iteration in the Combiner. This improves compile-time
129 // at the cost of possibly missing optimizations. See PR#94291 for details.
130 CInfo.MaxIterations = 1;
131
132 RISCVO0PreLegalizerCombinerImpl Impl(MF, CInfo, *VT,
133 /*CSEInfo*/ nullptr, RuleConfig, ST);
134 return Impl.combineMachineInstrs();
135}
136
137char RISCVO0PreLegalizerCombiner::ID = 0;
138INITIALIZE_PASS_BEGIN(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
139 "Combine RISC-V machine instrs before legalization",
140 false, false)
141INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
142INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
143INITIALIZE_PASS_END(RISCVO0PreLegalizerCombiner, DEBUG_TYPE,
144 "Combine RISC-V machine instrs before legalization", false,
145 false)
146
147FunctionPass *llvm::createRISCVO0PreLegalizerCombiner() {
148 return new RISCVO0PreLegalizerCombiner();
149}
150