xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //=== lib/CodeGen/GlobalISel/MipsPreLegalizerCombiner.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 // before the legalizer.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MipsLegalizerInfo.h"
15 #include "MipsTargetMachine.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/GISelValueTracking.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/TargetPassConfig.h"
22 
23 #define DEBUG_TYPE "mips-prelegalizer-combiner"
24 
25 using namespace llvm;
26 
27 namespace {
28 struct MipsPreLegalizerCombinerInfo : public CombinerInfo {
29 public:
MipsPreLegalizerCombinerInfo__anonb65b3b5c0111::MipsPreLegalizerCombinerInfo30   MipsPreLegalizerCombinerInfo()
31       : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
32                      /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
33                      /*EnableOptSize*/ false, /*EnableMinSize*/ false) {}
34 };
35 
36 class MipsPreLegalizerCombinerImpl : public Combiner {
37 protected:
38   const MipsSubtarget &STI;
39   const CombinerHelper Helper;
40 
41 public:
MipsPreLegalizerCombinerImpl(MachineFunction & MF,CombinerInfo & CInfo,const TargetPassConfig * TPC,GISelValueTracking & VT,GISelCSEInfo * CSEInfo,const MipsSubtarget & STI,MachineDominatorTree * MDT,const LegalizerInfo * LI)42   MipsPreLegalizerCombinerImpl(MachineFunction &MF, CombinerInfo &CInfo,
43                                const TargetPassConfig *TPC,
44                                GISelValueTracking &VT, GISelCSEInfo *CSEInfo,
45                                const MipsSubtarget &STI,
46                                MachineDominatorTree *MDT,
47                                const LegalizerInfo *LI)
48       : Combiner(MF, CInfo, TPC, &VT, CSEInfo), STI(STI),
49         Helper(Observer, B, /*IsPreLegalize*/ true, &VT, MDT, LI) {}
50 
getName()51   static const char *getName() { return "MipsPreLegalizerCombiner"; }
52 
setupGeneratedPerFunctionState(MachineFunction & MF)53   void setupGeneratedPerFunctionState(MachineFunction &MF) override {
54     // TODO: TableGen-erate this class' impl.
55   }
56 
tryCombineAll(MachineInstr & MI) const57   bool tryCombineAll(MachineInstr &MI) const override {
58     switch (MI.getOpcode()) {
59     default:
60       return false;
61     case TargetOpcode::G_MEMCPY_INLINE:
62       return Helper.tryEmitMemcpyInline(MI);
63     case TargetOpcode::G_LOAD:
64     case TargetOpcode::G_SEXTLOAD:
65     case TargetOpcode::G_ZEXTLOAD: {
66       // Don't attempt to combine non power of 2 loads or unaligned loads when
67       // subtarget doesn't support them.
68       auto MMO = *MI.memoperands_begin();
69       const MipsSubtarget &STI = MI.getMF()->getSubtarget<MipsSubtarget>();
70       if (!MMO->getSize().hasValue() ||
71           !isPowerOf2_64(MMO->getSize().getValue()))
72         return false;
73       bool isUnaligned = MMO->getAlign() < MMO->getSize().getValue();
74       if (!STI.systemSupportsUnalignedAccess() && isUnaligned)
75         return false;
76 
77       return Helper.tryCombineExtendingLoads(MI);
78     }
79     }
80 
81     return false;
82   }
83 };
84 
85 // Pass boilerplate
86 // ================
87 
88 class MipsPreLegalizerCombiner : public MachineFunctionPass {
89 public:
90   static char ID;
91 
92   MipsPreLegalizerCombiner();
93 
getPassName() const94   StringRef getPassName() const override { return "MipsPreLegalizerCombiner"; }
95 
96   bool runOnMachineFunction(MachineFunction &MF) override;
97 
98   void getAnalysisUsage(AnalysisUsage &AU) const override;
99 };
100 } // end anonymous namespace
101 
getAnalysisUsage(AnalysisUsage & AU) const102 void MipsPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
103   AU.addRequired<TargetPassConfig>();
104   AU.addRequired<GISelValueTrackingAnalysisLegacy>();
105   AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
106   AU.setPreservesCFG();
107   getSelectionDAGFallbackAnalysisUsage(AU);
108   MachineFunctionPass::getAnalysisUsage(AU);
109 }
110 
MipsPreLegalizerCombiner()111 MipsPreLegalizerCombiner::MipsPreLegalizerCombiner()
112     : MachineFunctionPass(ID) {}
113 
runOnMachineFunction(MachineFunction & MF)114 bool MipsPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
115   if (MF.getProperties().hasFailedISel())
116     return false;
117 
118   auto *TPC = &getAnalysis<TargetPassConfig>();
119   const MipsSubtarget &ST = MF.getSubtarget<MipsSubtarget>();
120   const MipsLegalizerInfo *LI =
121       static_cast<const MipsLegalizerInfo *>(ST.getLegalizerInfo());
122 
123   GISelValueTracking *VT =
124       &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
125   MipsPreLegalizerCombinerInfo PCInfo;
126   MipsPreLegalizerCombinerImpl Impl(MF, PCInfo, TPC, *VT, /*CSEInfo*/ nullptr,
127                                     ST, /*MDT*/ nullptr, LI);
128   return Impl.combineMachineInstrs();
129 }
130 
131 char MipsPreLegalizerCombiner::ID = 0;
132 INITIALIZE_PASS_BEGIN(MipsPreLegalizerCombiner, DEBUG_TYPE,
133                       "Combine Mips machine instrs before legalization", false,
134                       false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)135 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
136 INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
137 INITIALIZE_PASS_END(MipsPreLegalizerCombiner, DEBUG_TYPE,
138                     "Combine Mips machine instrs before legalization", false,
139                     false)
140 
141 FunctionPass *llvm::createMipsPreLegalizeCombiner() {
142   return new MipsPreLegalizerCombiner();
143 }
144