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.addPreserved<MachineDominatorTreeWrapperPass>();
132 AU.addRequired<GISelCSEAnalysisWrapperPass>();
133 AU.addPreserved<GISelCSEAnalysisWrapperPass>();
134 MachineFunctionPass::getAnalysisUsage(AU);
135}
136
137X86PreLegalizerCombinerLegacy::X86PreLegalizerCombinerLegacy()
138 : MachineFunctionPass(ID) {
139 if (!RuleConfig.parseCommandLineOption())
140 report_fatal_error(reason: "Invalid rule identifier");
141}
142
143bool X86PreLegalizerCombinerLegacy::runOnMachineFunction(MachineFunction &MF) {
144 if (MF.getProperties().hasFailedISel())
145 return false;
146 auto &TPC = getAnalysis<TargetPassConfig>();
147
148 // Enable CSE.
149 GISelCSEAnalysisWrapper &Wrapper =
150 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
151 auto *CSEInfo = &Wrapper.get(CSEOpt: TPC.getCSEConfig());
152 const Function &F = MF.getFunction();
153 bool EnableOpt =
154 MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
155 GISelValueTracking *VT =
156 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
157 MachineDominatorTree *MDT =
158 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
159 CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
160 X86PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, MDT);
161 return Impl.combineMachineInstrs();
162}
163
164char X86PreLegalizerCombinerLegacy::ID = 0;
165INITIALIZE_PASS_BEGIN(X86PreLegalizerCombinerLegacy, DEBUG_TYPE,
166 "Combine X86 machine instrs before legalization", false,
167 false)
168INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
169INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
170INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
171INITIALIZE_PASS_END(X86PreLegalizerCombinerLegacy, DEBUG_TYPE,
172 "Combine X86 machine instrs before legalization", false,
173 false)
174
175namespace llvm {
176
177PreservedAnalyses
178X86PreLegalizerCombinerPass::run(MachineFunction &MF,
179 MachineFunctionAnalysisManager &MFAM) {
180 if (MF.getProperties().hasFailedISel())
181 return PreservedAnalyses::all();
182
183 X86PreLegalizerCombinerImplRuleConfig RuleConfig;
184 if (!RuleConfig.parseCommandLineOption())
185 report_fatal_error(reason: "Invalid rule identifier");
186
187 auto &CSEInfo = MFAM.getResult<GISelCSEAnalysis>(IR&: MF);
188 const Function &F = MF.getFunction();
189 bool EnableOpt = MF.getTarget().getOptLevel() != CodeGenOptLevel::None;
190 GISelValueTracking &VT = MFAM.getResult<GISelValueTrackingAnalysis>(IR&: MF);
191 MachineDominatorTree &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(IR&: MF);
192 CombinerInfo CInfo = createCombinerInfo(EnableOpt, F);
193 X86PreLegalizerCombinerImpl Impl(MF, CInfo, VT, CSEInfo.get(), RuleConfig,
194 &MDT);
195 Impl.combineMachineInstrs();
196
197 PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
198 PA.preserveSet<CFGAnalyses>();
199 PA.preserve<GISelCSEAnalysis>();
200 PA.preserve<GISelValueTrackingAnalysis>();
201 return PA;
202}
203
204FunctionPass *createX86PreLegalizerCombinerLegacy() {
205 return new X86PreLegalizerCombinerLegacy();
206}
207} // end namespace llvm
208