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
43#define GET_GICOMBINER_TYPES
44#include "X86GenPreLegalizeGICombiner.inc"
45#undef GET_GICOMBINER_TYPES
46
47class X86PreLegalizerCombinerImpl : public Combiner {
48protected:
49 const CombinerHelper Helper;
50 const X86PreLegalizerCombinerImplRuleConfig &RuleConfig;
51 const X86Subtarget &STI;
52
53public:
54 X86PreLegalizerCombinerImpl(
55 MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
56 GISelValueTracking &VT, GISelCSEInfo *CSEInfo,
57 const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
58 const X86Subtarget &STI, MachineDominatorTree *MDT,
59 const LegalizerInfo *LI);
60
61 static const char *getName() { return "X86PreLegalizerCombiner"; }
62
63 bool tryCombineAll(MachineInstr &I) const override;
64
65 bool tryCombineAllImpl(MachineInstr &I) const;
66
67private:
68#define GET_GICOMBINER_CLASS_MEMBERS
69#include "X86GenPreLegalizeGICombiner.inc"
70#undef GET_GICOMBINER_CLASS_MEMBERS
71};
72
73#define GET_GICOMBINER_IMPL
74#include "X86GenPreLegalizeGICombiner.inc"
75#undef GET_GICOMBINER_IMPL
76
77X86PreLegalizerCombinerImpl::X86PreLegalizerCombinerImpl(
78 MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
79 GISelValueTracking &VT, GISelCSEInfo *CSEInfo,
80 const X86PreLegalizerCombinerImplRuleConfig &RuleConfig,
81 const X86Subtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI)
82 : Combiner(MF, CInfo, TPC, &VT, CSEInfo),
83 Helper(Observer, B, /*IsPreLegalize=*/true, &VT, MDT, LI),
84 RuleConfig(RuleConfig), STI(STI),
85#define GET_GICOMBINER_CONSTRUCTOR_INITS
86#include "X86GenPreLegalizeGICombiner.inc"
87#undef GET_GICOMBINER_CONSTRUCTOR_INITS
88{
89}
90
91bool X86PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
92 return tryCombineAllImpl(I&: MI);
93}
94
95class X86PreLegalizerCombiner : public MachineFunctionPass {
96public:
97 static char ID;
98
99 X86PreLegalizerCombiner();
100
101 StringRef getPassName() const override { return "X86PreLegalizerCombiner"; }
102
103 bool runOnMachineFunction(MachineFunction &MF) override;
104
105 void getAnalysisUsage(AnalysisUsage &AU) const override;
106
107private:
108 X86PreLegalizerCombinerImplRuleConfig RuleConfig;
109};
110} // end anonymous namespace
111
112void X86PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
113 AU.addRequired<TargetPassConfig>();
114 AU.setPreservesCFG();
115 getSelectionDAGFallbackAnalysisUsage(AU);
116 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
117 AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
118 AU.addRequired<MachineDominatorTreeWrapperPass>();
119 AU.addPreserved<MachineDominatorTreeWrapperPass>();
120 AU.addRequired<GISelCSEAnalysisWrapperPass>();
121 AU.addPreserved<GISelCSEAnalysisWrapperPass>();
122 MachineFunctionPass::getAnalysisUsage(AU);
123}
124
125X86PreLegalizerCombiner::X86PreLegalizerCombiner() : MachineFunctionPass(ID) {
126 if (!RuleConfig.parseCommandLineOption())
127 report_fatal_error(reason: "Invalid rule identifier");
128}
129
130bool X86PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
131 if (MF.getProperties().hasFailedISel())
132 return false;
133 auto &TPC = getAnalysis<TargetPassConfig>();
134
135 // Enable CSE.
136 GISelCSEAnalysisWrapper &Wrapper =
137 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
138 auto *CSEInfo = &Wrapper.get(CSEOpt: TPC.getCSEConfig());
139
140 const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
141 const LegalizerInfo *LI = ST.getLegalizerInfo();
142
143 const Function &F = MF.getFunction();
144 bool EnableOpt =
145 MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
146 GISelValueTracking *VT =
147 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
148 MachineDominatorTree *MDT =
149 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
150 CombinerInfo CInfo(/*AllowIllegalOps=*/true, /*ShouldLegalizeIllegal=*/false,
151 /*LegalizerInfo=*/LI, EnableOpt, F.hasOptSize(),
152 F.hasMinSize());
153
154 // This is the first Combiner, so the input IR might contain dead
155 // instructions.
156 CInfo.EnableFullDCE = true;
157 X86PreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *VT, CSEInfo, RuleConfig,
158 ST, MDT, LI);
159 return Impl.combineMachineInstrs();
160}
161
162char X86PreLegalizerCombiner::ID = 0;
163INITIALIZE_PASS_BEGIN(X86PreLegalizerCombiner, DEBUG_TYPE,
164 "Combine X86 machine instrs before legalization", false,
165 false)
166INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
167INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
168INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
169INITIALIZE_PASS_END(X86PreLegalizerCombiner, DEBUG_TYPE,
170 "Combine X86 machine instrs before legalization", false,
171 false)
172
173namespace llvm {
174FunctionPass *createX86PreLegalizerCombiner() {
175 return new X86PreLegalizerCombiner();
176}
177} // end namespace llvm
178