1//=== RISCVPostLegalizerCombiner.cpp --------------------------*- C++ -*-===//
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/// \file
10/// Post-legalization combines on generic MachineInstrs.
11///
12/// The combines here must preserve instruction legality.
13///
14/// Combines which don't rely on instruction legality should go in the
15/// RISCVPreLegalizerCombiner.
16///
17//===----------------------------------------------------------------------===//
18
19#include "RISCVTargetMachine.h"
20#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
21#include "llvm/CodeGen/GlobalISel/Combiner.h"
22#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
23#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
24#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
25#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
26#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
27#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
28#include "llvm/CodeGen/MachineDominators.h"
29#include "llvm/CodeGen/MachineFunctionPass.h"
30#include "llvm/CodeGen/MachineRegisterInfo.h"
31#include "llvm/CodeGen/TargetPassConfig.h"
32
33#define GET_GICOMBINER_DEPS
34#include "RISCVGenPostLegalizeGICombiner.inc"
35#undef GET_GICOMBINER_DEPS
36
37#define DEBUG_TYPE "riscv-postlegalizer-combiner"
38
39using namespace llvm;
40
41namespace {
42
43#define GET_GICOMBINER_TYPES
44#include "RISCVGenPostLegalizeGICombiner.inc"
45#undef GET_GICOMBINER_TYPES
46
47class RISCVPostLegalizerCombinerImpl : public Combiner {
48protected:
49 // TODO: Make CombinerHelper methods const.
50 mutable CombinerHelper Helper;
51 const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig;
52 const RISCVSubtarget &STI;
53
54public:
55 RISCVPostLegalizerCombinerImpl(
56 MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
57 GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
58 const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
59 const RISCVSubtarget &STI, MachineDominatorTree *MDT,
60 const LegalizerInfo *LI);
61
62 static const char *getName() { return "RISCVPostLegalizerCombiner"; }
63
64 bool tryCombineAll(MachineInstr &I) const override;
65
66private:
67#define GET_GICOMBINER_CLASS_MEMBERS
68#include "RISCVGenPostLegalizeGICombiner.inc"
69#undef GET_GICOMBINER_CLASS_MEMBERS
70};
71
72#define GET_GICOMBINER_IMPL
73#include "RISCVGenPostLegalizeGICombiner.inc"
74#undef GET_GICOMBINER_IMPL
75
76RISCVPostLegalizerCombinerImpl::RISCVPostLegalizerCombinerImpl(
77 MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
78 GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
79 const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
80 const RISCVSubtarget &STI, MachineDominatorTree *MDT,
81 const LegalizerInfo *LI)
82 : Combiner(MF, CInfo, TPC, &KB, CSEInfo),
83 Helper(Observer, B, /*IsPreLegalize*/ false, &KB, MDT, LI),
84 RuleConfig(RuleConfig), STI(STI),
85#define GET_GICOMBINER_CONSTRUCTOR_INITS
86#include "RISCVGenPostLegalizeGICombiner.inc"
87#undef GET_GICOMBINER_CONSTRUCTOR_INITS
88{
89}
90
91class RISCVPostLegalizerCombiner : public MachineFunctionPass {
92public:
93 static char ID;
94
95 RISCVPostLegalizerCombiner();
96
97 StringRef getPassName() const override {
98 return "RISCVPostLegalizerCombiner";
99 }
100
101 bool runOnMachineFunction(MachineFunction &MF) override;
102 void getAnalysisUsage(AnalysisUsage &AU) const override;
103
104private:
105 RISCVPostLegalizerCombinerImplRuleConfig RuleConfig;
106};
107} // end anonymous namespace
108
109void RISCVPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
110 AU.addRequired<TargetPassConfig>();
111 AU.setPreservesCFG();
112 getSelectionDAGFallbackAnalysisUsage(AU);
113 AU.addRequired<GISelKnownBitsAnalysis>();
114 AU.addPreserved<GISelKnownBitsAnalysis>();
115 AU.addRequired<MachineDominatorTreeWrapperPass>();
116 AU.addPreserved<MachineDominatorTreeWrapperPass>();
117 AU.addRequired<GISelCSEAnalysisWrapperPass>();
118 AU.addPreserved<GISelCSEAnalysisWrapperPass>();
119 MachineFunctionPass::getAnalysisUsage(AU);
120}
121
122RISCVPostLegalizerCombiner::RISCVPostLegalizerCombiner()
123 : MachineFunctionPass(ID) {
124 initializeRISCVPostLegalizerCombinerPass(*PassRegistry::getPassRegistry());
125
126 if (!RuleConfig.parseCommandLineOption())
127 report_fatal_error(reason: "Invalid rule identifier");
128}
129
130bool RISCVPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
131 if (MF.getProperties().hasProperty(
132 P: MachineFunctionProperties::Property::FailedISel))
133 return false;
134 assert(MF.getProperties().hasProperty(
135 MachineFunctionProperties::Property::Legalized) &&
136 "Expected a legalized function?");
137 auto *TPC = &getAnalysis<TargetPassConfig>();
138 const Function &F = MF.getFunction();
139 bool EnableOpt =
140 MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
141
142 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
143 const auto *LI = ST.getLegalizerInfo();
144
145 GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
146 MachineDominatorTree *MDT =
147 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
148 GISelCSEAnalysisWrapper &Wrapper =
149 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
150 auto *CSEInfo = &Wrapper.get(CSEOpt: TPC->getCSEConfig());
151
152 CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
153 /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
154 F.hasMinSize());
155 RISCVPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *KB, CSEInfo,
156 RuleConfig, ST, MDT, LI);
157 return Impl.combineMachineInstrs();
158}
159
160char RISCVPostLegalizerCombiner::ID = 0;
161INITIALIZE_PASS_BEGIN(RISCVPostLegalizerCombiner, DEBUG_TYPE,
162 "Combine RISC-V MachineInstrs after legalization", false,
163 false)
164INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
165INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
166INITIALIZE_PASS_END(RISCVPostLegalizerCombiner, DEBUG_TYPE,
167 "Combine RISC-V MachineInstrs after legalization", false,
168 false)
169
170namespace llvm {
171FunctionPass *createRISCVPostLegalizerCombiner() {
172 return new RISCVPostLegalizerCombiner();
173}
174} // end namespace llvm
175