[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / lib / Target / Mips / MipsPreLegalizerCombiner.cpp
blob0765233bfc3157b54d90172b88849d0aaca3c1ca
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.
12 //===----------------------------------------------------------------------===//
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/GISelKnownBits.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/TargetPassConfig.h"
22 #include "llvm/InitializePasses.h"
24 #define DEBUG_TYPE "mips-prelegalizer-combiner"
26 using namespace llvm;
28 namespace {
29 struct MipsPreLegalizerCombinerInfo : public CombinerInfo {
30 public:
31 MipsPreLegalizerCombinerInfo()
32 : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
33 /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
34 /*EnableOptSize*/ false, /*EnableMinSize*/ false) {}
37 class MipsPreLegalizerCombinerImpl : public Combiner {
38 protected:
39 const MipsSubtarget &STI;
40 // TODO: Make CombinerHelper methods const.
41 mutable CombinerHelper Helper;
43 public:
44 MipsPreLegalizerCombinerImpl(MachineFunction &MF, CombinerInfo &CInfo,
45 const TargetPassConfig *TPC, GISelKnownBits &KB,
46 GISelCSEInfo *CSEInfo, const MipsSubtarget &STI,
47 MachineDominatorTree *MDT,
48 const LegalizerInfo *LI)
49 : Combiner(MF, CInfo, TPC, &KB, CSEInfo), STI(STI),
50 Helper(Observer, B, /*IsPreLegalize*/ true, &KB, MDT, LI) {}
52 static const char *getName() { return "MipsPreLegalizerCombiner"; }
54 void setupGeneratedPerFunctionState(MachineFunction &MF) override {
55 // TODO: TableGen-erate this class' impl.
58 bool tryCombineAll(MachineInstr &MI) const override {
60 switch (MI.getOpcode()) {
61 default:
62 return false;
63 case TargetOpcode::G_MEMCPY_INLINE:
64 return Helper.tryEmitMemcpyInline(MI);
65 case TargetOpcode::G_LOAD:
66 case TargetOpcode::G_SEXTLOAD:
67 case TargetOpcode::G_ZEXTLOAD: {
68 // Don't attempt to combine non power of 2 loads or unaligned loads when
69 // subtarget doesn't support them.
70 auto MMO = *MI.memoperands_begin();
71 const MipsSubtarget &STI = MI.getMF()->getSubtarget<MipsSubtarget>();
72 if (!MMO->getSize().hasValue() ||
73 !isPowerOf2_64(MMO->getSize().getValue()))
74 return false;
75 bool isUnaligned = MMO->getAlign() < MMO->getSize().getValue();
76 if (!STI.systemSupportsUnalignedAccess() && isUnaligned)
77 return false;
79 return Helper.tryCombineExtendingLoads(MI);
83 return false;
87 // Pass boilerplate
88 // ================
90 class MipsPreLegalizerCombiner : public MachineFunctionPass {
91 public:
92 static char ID;
94 MipsPreLegalizerCombiner();
96 StringRef getPassName() const override { return "MipsPreLegalizerCombiner"; }
98 bool runOnMachineFunction(MachineFunction &MF) override;
100 void getAnalysisUsage(AnalysisUsage &AU) const override;
102 } // end anonymous namespace
104 void MipsPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
105 AU.addRequired<TargetPassConfig>();
106 AU.addRequired<GISelKnownBitsAnalysis>();
107 AU.addPreserved<GISelKnownBitsAnalysis>();
108 AU.setPreservesCFG();
109 getSelectionDAGFallbackAnalysisUsage(AU);
110 MachineFunctionPass::getAnalysisUsage(AU);
113 MipsPreLegalizerCombiner::MipsPreLegalizerCombiner() : MachineFunctionPass(ID) {
114 initializeMipsPreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
117 bool MipsPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
118 if (MF.getProperties().hasProperty(
119 MachineFunctionProperties::Property::FailedISel))
120 return false;
122 auto *TPC = &getAnalysis<TargetPassConfig>();
123 const MipsSubtarget &ST = MF.getSubtarget<MipsSubtarget>();
124 const MipsLegalizerInfo *LI =
125 static_cast<const MipsLegalizerInfo *>(ST.getLegalizerInfo());
127 GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
128 MipsPreLegalizerCombinerInfo PCInfo;
129 MipsPreLegalizerCombinerImpl Impl(MF, PCInfo, TPC, *KB, /*CSEInfo*/ nullptr,
130 ST, /*MDT*/ nullptr, LI);
131 return Impl.combineMachineInstrs();
134 char MipsPreLegalizerCombiner::ID = 0;
135 INITIALIZE_PASS_BEGIN(MipsPreLegalizerCombiner, DEBUG_TYPE,
136 "Combine Mips machine instrs before legalization", false,
137 false)
138 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
139 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
140 INITIALIZE_PASS_END(MipsPreLegalizerCombiner, DEBUG_TYPE,
141 "Combine Mips machine instrs before legalization", false,
142 false)
144 namespace llvm {
145 FunctionPass *createMipsPreLegalizeCombiner() {
146 return new MipsPreLegalizerCombiner();
148 } // end namespace llvm