Coverage Report

Created: 2024-01-17 10:31

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