1*6d45558cSMatt Arsenault //=== lib/CodeGen/GlobalISel/MipsPostLegalizerCombiner.cpp ----------------===//
2*6d45558cSMatt Arsenault //
3*6d45558cSMatt Arsenault // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*6d45558cSMatt Arsenault // See https://llvm.org/LICENSE.txt for license information.
5*6d45558cSMatt Arsenault // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*6d45558cSMatt Arsenault //
7*6d45558cSMatt Arsenault //===----------------------------------------------------------------------===//
8*6d45558cSMatt Arsenault //
9*6d45558cSMatt Arsenault // This pass does combining of machine instructions at the generic MI level,
10*6d45558cSMatt Arsenault // after the legalizer.
11*6d45558cSMatt Arsenault //
12*6d45558cSMatt Arsenault //===----------------------------------------------------------------------===//
13*6d45558cSMatt Arsenault 
14*6d45558cSMatt Arsenault #include "MCTargetDesc/MipsMCTargetDesc.h"
15*6d45558cSMatt Arsenault #include "Mips.h"
16*6d45558cSMatt Arsenault #include "MipsLegalizerInfo.h"
17*6d45558cSMatt Arsenault #include "MipsSubtarget.h"
18*6d45558cSMatt Arsenault #include "llvm/CodeGen/GlobalISel/Combiner.h"
19*6d45558cSMatt Arsenault #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
20*6d45558cSMatt Arsenault #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
21*6d45558cSMatt Arsenault #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
22*6d45558cSMatt Arsenault #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
23*6d45558cSMatt Arsenault #include "llvm/CodeGen/MachineDominators.h"
24*6d45558cSMatt Arsenault #include "llvm/CodeGen/TargetPassConfig.h"
25*6d45558cSMatt Arsenault #include "llvm/Target/TargetMachine.h"
26*6d45558cSMatt Arsenault 
27*6d45558cSMatt Arsenault #define DEBUG_TYPE "mips-postlegalizer-combiner"
28*6d45558cSMatt Arsenault 
29*6d45558cSMatt Arsenault using namespace llvm;
30*6d45558cSMatt Arsenault using namespace MIPatternMatch;
31*6d45558cSMatt Arsenault 
32*6d45558cSMatt Arsenault #define MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS
33*6d45558cSMatt Arsenault #include "MipsGenPostLegalizeGICombiner.inc"
34*6d45558cSMatt Arsenault #undef MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS
35*6d45558cSMatt Arsenault 
36*6d45558cSMatt Arsenault namespace {
37*6d45558cSMatt Arsenault #define MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H
38*6d45558cSMatt Arsenault #include "MipsGenPostLegalizeGICombiner.inc"
39*6d45558cSMatt Arsenault #undef MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H
40*6d45558cSMatt Arsenault 
41*6d45558cSMatt Arsenault class MipsPostLegalizerCombinerInfo final : public CombinerInfo {
42*6d45558cSMatt Arsenault   GISelKnownBits *KB;
43*6d45558cSMatt Arsenault 
44*6d45558cSMatt Arsenault public:
45*6d45558cSMatt Arsenault   MipsGenPostLegalizerCombinerHelperRuleConfig GeneratedRuleCfg;
46*6d45558cSMatt Arsenault 
MipsPostLegalizerCombinerInfo(bool EnableOpt,bool OptSize,bool MinSize,GISelKnownBits * KB,const MipsLegalizerInfo * LI)47*6d45558cSMatt Arsenault   MipsPostLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize,
48*6d45558cSMatt Arsenault                                 GISelKnownBits *KB, const MipsLegalizerInfo *LI)
49*6d45558cSMatt Arsenault       : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true,
50*6d45558cSMatt Arsenault                      /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize),
51*6d45558cSMatt Arsenault         KB(KB) {
52*6d45558cSMatt Arsenault     if (!GeneratedRuleCfg.parseCommandLineOption())
53*6d45558cSMatt Arsenault       report_fatal_error("Invalid rule identifier");
54*6d45558cSMatt Arsenault   }
55*6d45558cSMatt Arsenault 
56*6d45558cSMatt Arsenault   bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
57*6d45558cSMatt Arsenault                MachineIRBuilder &B) const override;
58*6d45558cSMatt Arsenault };
59*6d45558cSMatt Arsenault 
combine(GISelChangeObserver & Observer,MachineInstr & MI,MachineIRBuilder & B) const60*6d45558cSMatt Arsenault bool MipsPostLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
61*6d45558cSMatt Arsenault                                             MachineInstr &MI,
62*6d45558cSMatt Arsenault                                             MachineIRBuilder &B) const {
63*6d45558cSMatt Arsenault 
64*6d45558cSMatt Arsenault   CombinerHelper Helper(Observer, B, KB,
65*6d45558cSMatt Arsenault                         /*DominatorTree*/ nullptr, LInfo);
66*6d45558cSMatt Arsenault   MipsGenPostLegalizerCombinerHelper Generated(GeneratedRuleCfg, Helper);
67*6d45558cSMatt Arsenault   return Generated.tryCombineAll(Observer, MI, B, Helper);
68*6d45558cSMatt Arsenault }
69*6d45558cSMatt Arsenault 
70*6d45558cSMatt Arsenault #define MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP
71*6d45558cSMatt Arsenault #include "MipsGenPostLegalizeGICombiner.inc"
72*6d45558cSMatt Arsenault #undef MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP
73*6d45558cSMatt Arsenault 
74*6d45558cSMatt Arsenault // Pass boilerplate
75*6d45558cSMatt Arsenault // ================
76*6d45558cSMatt Arsenault 
77*6d45558cSMatt Arsenault class MipsPostLegalizerCombiner : public MachineFunctionPass {
78*6d45558cSMatt Arsenault public:
79*6d45558cSMatt Arsenault   static char ID;
80*6d45558cSMatt Arsenault 
81*6d45558cSMatt Arsenault   MipsPostLegalizerCombiner(bool IsOptNone = false);
82*6d45558cSMatt Arsenault 
getPassName() const83*6d45558cSMatt Arsenault   StringRef getPassName() const override {
84*6d45558cSMatt Arsenault     return "MipsPostLegalizerCombiner";
85*6d45558cSMatt Arsenault   }
86*6d45558cSMatt Arsenault 
87*6d45558cSMatt Arsenault   bool runOnMachineFunction(MachineFunction &MF) override;
88*6d45558cSMatt Arsenault 
89*6d45558cSMatt Arsenault   void getAnalysisUsage(AnalysisUsage &AU) const override;
90*6d45558cSMatt Arsenault 
91*6d45558cSMatt Arsenault private:
92*6d45558cSMatt Arsenault   bool IsOptNone;
93*6d45558cSMatt Arsenault };
94*6d45558cSMatt Arsenault } // end anonymous namespace
95*6d45558cSMatt Arsenault 
getAnalysisUsage(AnalysisUsage & AU) const96*6d45558cSMatt Arsenault void MipsPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
97*6d45558cSMatt Arsenault   AU.addRequired<TargetPassConfig>();
98*6d45558cSMatt Arsenault   AU.setPreservesCFG();
99*6d45558cSMatt Arsenault   getSelectionDAGFallbackAnalysisUsage(AU);
100*6d45558cSMatt Arsenault   AU.addRequired<GISelKnownBitsAnalysis>();
101*6d45558cSMatt Arsenault   AU.addPreserved<GISelKnownBitsAnalysis>();
102*6d45558cSMatt Arsenault   if (!IsOptNone) {
103*6d45558cSMatt Arsenault     AU.addRequired<MachineDominatorTree>();
104*6d45558cSMatt Arsenault     AU.addPreserved<MachineDominatorTree>();
105*6d45558cSMatt Arsenault   }
106*6d45558cSMatt Arsenault   MachineFunctionPass::getAnalysisUsage(AU);
107*6d45558cSMatt Arsenault }
108*6d45558cSMatt Arsenault 
MipsPostLegalizerCombiner(bool IsOptNone)109*6d45558cSMatt Arsenault MipsPostLegalizerCombiner::MipsPostLegalizerCombiner(bool IsOptNone)
110*6d45558cSMatt Arsenault     : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
111*6d45558cSMatt Arsenault   initializeMipsPostLegalizerCombinerPass(*PassRegistry::getPassRegistry());
112*6d45558cSMatt Arsenault }
113*6d45558cSMatt Arsenault 
runOnMachineFunction(MachineFunction & MF)114*6d45558cSMatt Arsenault bool MipsPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
115*6d45558cSMatt Arsenault   if (MF.getProperties().hasProperty(
116*6d45558cSMatt Arsenault           MachineFunctionProperties::Property::FailedISel))
117*6d45558cSMatt Arsenault     return false;
118*6d45558cSMatt Arsenault   auto *TPC = &getAnalysis<TargetPassConfig>();
119*6d45558cSMatt Arsenault   const Function &F = MF.getFunction();
120*6d45558cSMatt Arsenault   bool EnableOpt =
121*6d45558cSMatt Arsenault       MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
122*6d45558cSMatt Arsenault 
123*6d45558cSMatt Arsenault   const MipsSubtarget &ST = MF.getSubtarget<MipsSubtarget>();
124*6d45558cSMatt Arsenault   const MipsLegalizerInfo *LI =
125*6d45558cSMatt Arsenault       static_cast<const MipsLegalizerInfo *>(ST.getLegalizerInfo());
126*6d45558cSMatt Arsenault 
127*6d45558cSMatt Arsenault   GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
128*6d45558cSMatt Arsenault   MipsPostLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
129*6d45558cSMatt Arsenault                                        F.hasMinSize(), KB, LI);
130*6d45558cSMatt Arsenault   Combiner C(PCInfo, TPC);
131*6d45558cSMatt Arsenault   return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
132*6d45558cSMatt Arsenault }
133*6d45558cSMatt Arsenault 
134*6d45558cSMatt Arsenault char MipsPostLegalizerCombiner::ID = 0;
135*6d45558cSMatt Arsenault INITIALIZE_PASS_BEGIN(MipsPostLegalizerCombiner, DEBUG_TYPE,
136*6d45558cSMatt Arsenault                       "Combine Mips machine instrs after legalization", false,
137*6d45558cSMatt Arsenault                       false)
138*6d45558cSMatt Arsenault INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
139*6d45558cSMatt Arsenault INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
140*6d45558cSMatt Arsenault INITIALIZE_PASS_END(MipsPostLegalizerCombiner, DEBUG_TYPE,
141*6d45558cSMatt Arsenault                     "Combine Mips machine instrs after legalization", false,
142*6d45558cSMatt Arsenault                     false)
143*6d45558cSMatt Arsenault 
144*6d45558cSMatt Arsenault namespace llvm {
createMipsPostLegalizeCombiner(bool IsOptNone)145*6d45558cSMatt Arsenault FunctionPass *createMipsPostLegalizeCombiner(bool IsOptNone) {
146*6d45558cSMatt Arsenault   return new MipsPostLegalizerCombiner(IsOptNone);
147*6d45558cSMatt Arsenault }
148*6d45558cSMatt Arsenault } // end namespace llvm
149