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