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/GISelValueTracking.h"
26#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
27#include "llvm/CodeGen/MachineDominators.h"
28#include "llvm/CodeGen/MachineFunctionPass.h"
29#include "llvm/CodeGen/TargetPassConfig.h"
30
31#define GET_GICOMBINER_DEPS
32#include "RISCVGenPostLegalizeGICombiner.inc"
33#undef GET_GICOMBINER_DEPS
34
35#define DEBUG_TYPE "riscv-postlegalizer-combiner"
36
37using namespace llvm;
38
39namespace {
40
41#define GET_GICOMBINER_TYPES
42#include "RISCVGenPostLegalizeGICombiner.inc"
43#undef GET_GICOMBINER_TYPES
44
45class RISCVPostLegalizerCombinerImpl : public Combiner {
46protected:
47 const CombinerHelper Helper;
48 const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig;
49 const RISCVSubtarget &STI;
50
51public:
52 RISCVPostLegalizerCombinerImpl(
53 MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
54 GISelValueTracking &VT, GISelCSEInfo *CSEInfo,
55 const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
56 const RISCVSubtarget &STI, MachineDominatorTree *MDT,
57 const LegalizerInfo *LI);
58
59 static const char *getName() { return "RISCVPostLegalizerCombiner"; }
60
61 bool tryCombineAll(MachineInstr &I) const override;
62
63private:
64#define GET_GICOMBINER_CLASS_MEMBERS
65#include "RISCVGenPostLegalizeGICombiner.inc"
66#undef GET_GICOMBINER_CLASS_MEMBERS
67};
68
69#define GET_GICOMBINER_IMPL
70#include "RISCVGenPostLegalizeGICombiner.inc"
71#undef GET_GICOMBINER_IMPL
72
73RISCVPostLegalizerCombinerImpl::RISCVPostLegalizerCombinerImpl(
74 MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
75 GISelValueTracking &VT, GISelCSEInfo *CSEInfo,
76 const RISCVPostLegalizerCombinerImplRuleConfig &RuleConfig,
77 const RISCVSubtarget &STI, MachineDominatorTree *MDT,
78 const LegalizerInfo *LI)
79 : Combiner(MF, CInfo, TPC, &VT, CSEInfo),
80 Helper(Observer, B, /*IsPreLegalize*/ false, &VT, MDT, LI),
81 RuleConfig(RuleConfig), STI(STI),
82#define GET_GICOMBINER_CONSTRUCTOR_INITS
83#include "RISCVGenPostLegalizeGICombiner.inc"
84#undef GET_GICOMBINER_CONSTRUCTOR_INITS
85{
86}
87
88class RISCVPostLegalizerCombiner : public MachineFunctionPass {
89public:
90 static char ID;
91
92 RISCVPostLegalizerCombiner();
93
94 StringRef getPassName() const override {
95 return "RISCVPostLegalizerCombiner";
96 }
97
98 bool runOnMachineFunction(MachineFunction &MF) override;
99 void getAnalysisUsage(AnalysisUsage &AU) const override;
100
101private:
102 RISCVPostLegalizerCombinerImplRuleConfig RuleConfig;
103};
104} // end anonymous namespace
105
106void RISCVPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
107 AU.addRequired<TargetPassConfig>();
108 AU.setPreservesCFG();
109 getSelectionDAGFallbackAnalysisUsage(AU);
110 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
111 AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
112 AU.addRequired<MachineDominatorTreeWrapperPass>();
113 AU.addPreserved<MachineDominatorTreeWrapperPass>();
114 AU.addRequired<GISelCSEAnalysisWrapperPass>();
115 AU.addPreserved<GISelCSEAnalysisWrapperPass>();
116 MachineFunctionPass::getAnalysisUsage(AU);
117}
118
119RISCVPostLegalizerCombiner::RISCVPostLegalizerCombiner()
120 : MachineFunctionPass(ID) {
121 if (!RuleConfig.parseCommandLineOption())
122 report_fatal_error(reason: "Invalid rule identifier");
123}
124
125bool RISCVPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
126 if (MF.getProperties().hasFailedISel())
127 return false;
128 assert(MF.getProperties().hasLegalized() && "Expected a legalized function?");
129 auto *TPC = &getAnalysis<TargetPassConfig>();
130 const Function &F = MF.getFunction();
131 bool EnableOpt =
132 MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
133
134 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
135 const auto *LI = ST.getLegalizerInfo();
136
137 GISelValueTracking *VT =
138 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
139 MachineDominatorTree *MDT =
140 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
141 GISelCSEAnalysisWrapper &Wrapper =
142 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
143 auto *CSEInfo = &Wrapper.get(CSEOpt: TPC->getCSEConfig());
144
145 CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
146 /*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
147 F.hasMinSize());
148 RISCVPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *VT, CSEInfo, RuleConfig,
149 ST, MDT, LI);
150 return Impl.combineMachineInstrs();
151}
152
153char RISCVPostLegalizerCombiner::ID = 0;
154INITIALIZE_PASS_BEGIN(RISCVPostLegalizerCombiner, DEBUG_TYPE,
155 "Combine RISC-V MachineInstrs after legalization", false,
156 false)
157INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
158INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
159INITIALIZE_PASS_END(RISCVPostLegalizerCombiner, DEBUG_TYPE,
160 "Combine RISC-V MachineInstrs after legalization", false,
161 false)
162
163FunctionPass *llvm::createRISCVPostLegalizerCombiner() {
164 return new RISCVPostLegalizerCombiner();
165}
166