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