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