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
MipsPostLegalizerCombinerInfo(bool EnableOpt,bool OptSize,bool MinSize,GISelKnownBits * KB,const MipsLegalizerInfo * LI)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
combine(GISelChangeObserver & Observer,MachineInstr & MI,MachineIRBuilder & B) const60 bool MipsPostLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
61 MachineInstr &MI,
62 MachineIRBuilder &B) const {
63
64 CombinerHelper Helper(Observer, B, /* IsPreLegalize*/ false, 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
getPassName() const83 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
getAnalysisUsage(AnalysisUsage & AU) const96 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
MipsPostLegalizerCombiner(bool IsOptNone)109 MipsPostLegalizerCombiner::MipsPostLegalizerCombiner(bool IsOptNone)
110 : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
111 initializeMipsPostLegalizerCombinerPass(*PassRegistry::getPassRegistry());
112 }
113
runOnMachineFunction(MachineFunction & MF)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 {
createMipsPostLegalizeCombiner(bool IsOptNone)145 FunctionPass *createMipsPostLegalizeCombiner(bool IsOptNone) {
146 return new MipsPostLegalizerCombiner(IsOptNone);
147 }
148 } // end namespace llvm
149