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