1//===---------------- X86PreLegalizerCombiner.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/// \file
9/// This pass does combining of machine instructions at the generic MI level,
10/// before the legalizer.
11///
12//===----------------------------------------------------------------------===//
13#include "X86.h"
14#include "X86TargetMachine.h"
15#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
16#include "llvm/CodeGen/GlobalISel/Combiner.h"
17#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
18#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
19#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
20#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
21#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
22#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
23#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
24#include "llvm/CodeGen/GlobalISel/Utils.h"
25#include "llvm/CodeGen/MachineDominators.h"
26#include "llvm/CodeGen/MachineFunction.h"
27#include "llvm/CodeGen/MachineFunctionPass.h"
28#include "llvm/CodeGen/MachineRegisterInfo.h"
29#include "llvm/CodeGen/TargetPassConfig.h"
30#include "llvm/IR/Instructions.h"
31
32#define GET_GICOMBINER_DEPS
33#include "X86GenPreLegalizeGICombiner.inc"
34#undef GET_GICOMBINER_DEPS
35
36#define DEBUG_TYPE "x86-prelegalizer-combiner"
37
38using namespace llvm;
39using namespace MIPatternMatch;
40
41namespace {
42
43CombinerInfo createCombinerInfo(bool EnableOpt, const Function &F) {
44 CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
45 nullptr, EnableOpt, F.hasOptSize(), F.hasMinSize());
46
47 // This is the first Combiner, so the input IR might contain dead
48 // instructions.
49 CInfo.EnableFullDCE = true;
50 return CInfo;
51}
52
53#define GET_GICOMBINER_TYPES
54#include "X86GenPreLegalizeGICombiner.inc"
55#undef GET_GICOMBINER_TYPES
56
57class X86PreLegalizerCombinerImpl : public Combiner {
58protected:
59 const CombinerHelper Helper;
60 const X86PreLegalizerCombinerImplRuleConfig &RuleConfig;
61 const X86Subtarget &STI;
62
63public:
64 X86PreLegalizerCombinerImpl(
65 MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
66 GISelCSEInfo *CSEInfo,
67 const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
68 MachineDominatorTree *MDT);
69
70 static const char *getName() { return "X86PreLegalizerCombiner"; }
71
72 bool tryCombineAll(MachineInstr &I) const override;
73
74 bool tryCombineAllImpl(MachineInstr &I) const;
75
76private:
77#define GET_GICOMBINER_CLASS_MEMBERS
78#include "X86GenPreLegalizeGICombiner.inc"
79#undef GET_GICOMBINER_CLASS_MEMBERS
80};
81
82#define GET_GICOMBINER_IMPL
83#include "X86GenPreLegalizeGICombiner.inc"
84#undef GET_GICOMBINER_IMPL
85
86X86PreLegalizerCombinerImpl::X86PreLegalizerCombinerImpl(
87 MachineFunction &MF, CombinerInfo &CInfo, GISelValueTracking &VT,
88 GISelCSEInfo *CSEInfo,
89 const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
90 MachineDominatorTree *MDT)
91 : Combiner(MF, CInfo, &VT, CSEInfo),
92 Helper(Observer, B, /*IsPreLegalize=*/true, &VT, MDT,
93 MF.getSubtarget<X86Subtarget>().getLegalizerInfo()),
94 RuleConfig(RuleConfig), STI(MF.getSubtarget<X86Subtarget>()),
95#define GET_GICOMBINER_CONSTRUCTOR_INITS
96#include "X86GenPreLegalizeGICombiner.inc"
97#undef GET_GICOMBINER_CONSTRUCTOR_INITS
98{
99}
100
101bool X86PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
102 return tryCombineAllImpl(I&: MI);
103}
104
105class X86PreLegalizerCombinerLegacy : public MachineFunctionPass {
106public:
107 static char ID;
108
109 X86PreLegalizerCombinerLegacy();
110
111 StringRef getPassName() const override {
112 return "X86PreLegalizerCombinerLegacy";
113 }
114
115 bool runOnMachineFunction(MachineFunction &MF) override;
116
117 void getAnalysisUsage(AnalysisUsage &AU) const override;
118
119private:
120 X86PreLegalizerCombinerImplRuleConfig RuleConfig;
121};
122} // end anonymous namespace
123
124void X86PreLegalizerCombinerLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
125 AU.addRequired<TargetPassConfig>();
126 AU.setPreservesCFG();
127 getSelectionDAGFallbackAnalysisUsage(AU);
128 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
129 AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
130 AU.addRequired<MachineDominatorTreeWrapperPass>();
131 AU.addRequired<GISelCSEAnalysisWrapperPass>();
132 AU.addPreserved<GISelCSEAnalysisWrapperPass>();
133 MachineFunctionPass::getAnalysisUsage(AU);
134}
135
136X86PreLegalizerCombinerLegacy::X86PreLegalizerCombinerLegacy()
137 : MachineFunctionPass(ID) {
138 if (!RuleConfig.parseCommandLineOption())
139 report_fatal_error(reason: "Invalid rule identifier");
140}
141
142bool X86PreLegalizerCombinerLegacy::runOnMachineFunction(MachineFunction &MF) {
143 if (MF.getProperties().hasFailedISel())
144 return false;
145 auto &TPC = getAnalysis<TargetPassConfig>();
146
147 // Enable CSE.
148 GISelCSEAnalysisWrapper &Wrapper =
149 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
150 auto *CSEInfo = &Wrapper.get(CSEOpt: TPC.getCSEConfig());
151 const Function &F = MF.getFunction();
152 bool EnableOpt =
153 MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
154 GISelValueTracking *VT =
155 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
156 MachineDominatorTree *MDT =
157 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
158 CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
159 X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT);
160 return Impl.combineMachineInstrs();
161}
162
163char X86PreLegalizerCombinerLegacy::ID = 0;
164INITIALIZE_PASS_BEGIN(X86PreLegalizerCombinerLegacy, DEBUG_TYPE,
165 "Combine X86 machine instrs before legalization", false,
166 false)
167INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
168INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
169INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
170INITIALIZE_PASS_END(X86PreLegalizerCombinerLegacy, DEBUG_TYPE,
171 "Combine X86 machine instrs before legalization", false,
172 false)
173
174namespace llvm {
175
176PreservedAnalyses
177X86PreLegalizerCombinerPass::run(MachineFunction &MF,
178 MachineFunctionAnalysisManager &MFAM) {
179 if (MF.getProperties().hasFailedISel())
180 return PreservedAnalyses::all();
181
182 X86PreLegalizerCombinerImplRuleConfig RuleConfig;
183 if (!RuleConfig.parseCommandLineOption())
184 report_fatal_error(reason: "Invalid rule identifier");
185
186 auto &CSEInfo = MFAM.getResult<GISelCSEAnalysis>(IR&: MF);
187 const Function &F = MF.getFunction();
188 bool EnableOpt = MF.getTarget().getOptLevel() != CodeGenOptLevel::None;
189 GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(IR&: MF);
190 MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(IR&: MF);
191 CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
192 X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(), RuleConfig,
193 &MDT);
194 Impl.combineMachineInstrs();
195
196 PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
197 PA.preserveSet<CFGAnalyses>();
198 PA.preserve<GISelCSEAnalysis>();
199 PA.preserve<GISelValueTrackingAnalysis>();
200 return PA;
201}
202
203FunctionPass *createX86PreLegalizerCombinerLegacy() {
204 return new X86PreLegalizerCombinerLegacy();
205}
206} // end namespace llvm
207