Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/AMDGPU/R600ClauseMergePass.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- R600ClauseMergePass - Merge consecutive CF_ALU -------------------===//
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
/// \file
10
/// R600EmitClauseMarker pass emits CFAlu instruction in a conservative maneer.
11
/// This pass is merging consecutive CFAlus where applicable.
12
/// It needs to be called after IfCvt for best results.
13
//===----------------------------------------------------------------------===//
14
15
#include "AMDGPU.h"
16
#include "AMDGPUSubtarget.h"
17
#include "R600Defines.h"
18
#include "R600InstrInfo.h"
19
#include "R600MachineFunctionInfo.h"
20
#include "R600RegisterInfo.h"
21
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
22
#include "llvm/CodeGen/MachineFunctionPass.h"
23
#include "llvm/CodeGen/MachineInstrBuilder.h"
24
#include "llvm/CodeGen/MachineRegisterInfo.h"
25
#include "llvm/Support/Debug.h"
26
#include "llvm/Support/raw_ostream.h"
27
28
using namespace llvm;
29
30
#define DEBUG_TYPE "r600mergeclause"
31
32
namespace {
33
34
131k
static bool isCFAlu(const MachineInstr &MI) {
35
131k
  switch (MI.getOpcode()) {
36
131k
  case R600::CF_ALU:
37
9.47k
  case R600::CF_ALU_PUSH_BEFORE:
38
9.47k
    return true;
39
121k
  default:
40
121k
    return false;
41
131k
  }
42
131k
}
43
44
class R600ClauseMergePass : public MachineFunctionPass {
45
46
private:
47
  const R600InstrInfo *TII;
48
49
  unsigned getCFAluSize(const MachineInstr &MI) const;
50
  bool isCFAluEnabled(const MachineInstr &MI) const;
51
52
  /// IfCvt pass can generate "disabled" ALU clause marker that need to be
53
  /// removed and their content affected to the previous alu clause.
54
  /// This function parse instructions after CFAlu until it find a disabled
55
  /// CFAlu and merge the content, or an enabled CFAlu.
56
  void cleanPotentialDisabledCFAlu(MachineInstr &CFAlu) const;
57
58
  /// Check whether LatrCFAlu can be merged into RootCFAlu and do it if
59
  /// it is the case.
60
  bool mergeIfPossible(MachineInstr &RootCFAlu,
61
                       const MachineInstr &LatrCFAlu) const;
62
63
public:
64
  static char ID;
65
66
280
  R600ClauseMergePass() : MachineFunctionPass(ID) { }
67
68
  bool runOnMachineFunction(MachineFunction &MF) override;
69
70
  StringRef getPassName() const override;
71
};
72
73
} // end anonymous namespace
74
75
101k
INITIALIZE_PASS_BEGIN(R600ClauseMergePass, DEBUG_TYPE,
76
101k
                      "R600 Clause Merge", false, false)
77
101k
INITIALIZE_PASS_END(R600ClauseMergePass, DEBUG_TYPE,
78
                    "R600 Clause Merge", false, false)
79
80
char R600ClauseMergePass::ID = 0;
81
82
char &llvm::R600ClauseMergePassID = R600ClauseMergePass::ID;
83
84
708
unsigned R600ClauseMergePass::getCFAluSize(const MachineInstr &MI) const {
85
708
  assert(isCFAlu(MI));
86
708
  return MI
87
708
      .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::COUNT))
88
708
      .getImm();
89
708
}
90
91
1.63k
bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr &MI) const {
92
1.63k
  assert(isCFAlu(MI));
93
1.63k
  return MI
94
1.63k
      .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::Enabled))
95
1.63k
      .getImm();
96
1.63k
}
97
98
void R600ClauseMergePass::cleanPotentialDisabledCFAlu(
99
3.92k
    MachineInstr &CFAlu) const {
100
3.92k
  int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
101
3.92k
  MachineBasicBlock::iterator I = CFAlu, E = CFAlu.getParent()->end();
102
3.92k
  I++;
103
3.94k
  do {
104
60.7k
    while (I != E && 
!isCFAlu(*I)58.4k
)
105
56.8k
      I++;
106
3.94k
    if (I == E)
107
2.31k
      return;
108
1.63k
    MachineInstr &MI = *I++;
109
1.63k
    if (isCFAluEnabled(MI))
110
1.61k
      break;
111
26
    CFAlu.getOperand(CntIdx).setImm(getCFAluSize(CFAlu) + getCFAluSize(MI));
112
26
    MI.eraseFromParent();
113
26
  } while (I != E);
114
3.92k
}
115
116
bool R600ClauseMergePass::mergeIfPossible(MachineInstr &RootCFAlu,
117
328
                                          const MachineInstr &LatrCFAlu) const {
118
328
  assert(isCFAlu(RootCFAlu) && isCFAlu(LatrCFAlu));
119
328
  int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
120
328
  unsigned RootInstCount = getCFAluSize(RootCFAlu),
121
328
      LaterInstCount = getCFAluSize(LatrCFAlu);
122
328
  unsigned CumuledInsts = RootInstCount + LaterInstCount;
123
328
  if (CumuledInsts >= TII->getMaxAlusPerClause()) {
124
232
    LLVM_DEBUG(dbgs() << "Excess inst counts\n");
125
232
    return false;
126
232
  }
127
96
  if (RootCFAlu.getOpcode() == R600::CF_ALU_PUSH_BEFORE)
128
0
    return false;
129
96
  // Is KCache Bank 0 compatible ?
130
96
  int Mode0Idx =
131
96
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE0);
132
96
  int KBank0Idx =
133
96
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK0);
134
96
  int KBank0LineIdx =
135
96
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR0);
136
96
  if (LatrCFAlu.getOperand(Mode0Idx).getImm() &&
137
96
      
RootCFAlu.getOperand(Mode0Idx).getImm()2
&&
138
96
      
(0
LatrCFAlu.getOperand(KBank0Idx).getImm() !=
139
0
           RootCFAlu.getOperand(KBank0Idx).getImm() ||
140
0
       LatrCFAlu.getOperand(KBank0LineIdx).getImm() !=
141
0
           RootCFAlu.getOperand(KBank0LineIdx).getImm())) {
142
0
    LLVM_DEBUG(dbgs() << "Wrong KC0\n");
143
0
    return false;
144
0
  }
145
96
  // Is KCache Bank 1 compatible ?
146
96
  int Mode1Idx =
147
96
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE1);
148
96
  int KBank1Idx =
149
96
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK1);
150
96
  int KBank1LineIdx =
151
96
      TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR1);
152
96
  if (LatrCFAlu.getOperand(Mode1Idx).getImm() &&
153
96
      
RootCFAlu.getOperand(Mode1Idx).getImm()0
&&
154
96
      
(0
LatrCFAlu.getOperand(KBank1Idx).getImm() !=
155
0
           RootCFAlu.getOperand(KBank1Idx).getImm() ||
156
0
       LatrCFAlu.getOperand(KBank1LineIdx).getImm() !=
157
0
           RootCFAlu.getOperand(KBank1LineIdx).getImm())) {
158
0
    LLVM_DEBUG(dbgs() << "Wrong KC0\n");
159
0
    return false;
160
0
  }
161
96
  if (LatrCFAlu.getOperand(Mode0Idx).getImm()) {
162
2
    RootCFAlu.getOperand(Mode0Idx).setImm(
163
2
        LatrCFAlu.getOperand(Mode0Idx).getImm());
164
2
    RootCFAlu.getOperand(KBank0Idx).setImm(
165
2
        LatrCFAlu.getOperand(KBank0Idx).getImm());
166
2
    RootCFAlu.getOperand(KBank0LineIdx)
167
2
        .setImm(LatrCFAlu.getOperand(KBank0LineIdx).getImm());
168
2
  }
169
96
  if (LatrCFAlu.getOperand(Mode1Idx).getImm()) {
170
0
    RootCFAlu.getOperand(Mode1Idx).setImm(
171
0
        LatrCFAlu.getOperand(Mode1Idx).getImm());
172
0
    RootCFAlu.getOperand(KBank1Idx).setImm(
173
0
        LatrCFAlu.getOperand(KBank1Idx).getImm());
174
0
    RootCFAlu.getOperand(KBank1LineIdx)
175
0
        .setImm(LatrCFAlu.getOperand(KBank1LineIdx).getImm());
176
0
  }
177
96
  RootCFAlu.getOperand(CntIdx).setImm(CumuledInsts);
178
96
  RootCFAlu.setDesc(TII->get(LatrCFAlu.getOpcode()));
179
96
  return true;
180
96
}
181
182
2.29k
bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
183
2.29k
  if (skipFunction(MF.getFunction()))
184
0
    return false;
185
2.29k
186
2.29k
  const R600Subtarget &ST = MF.getSubtarget<R600Subtarget>();
187
2.29k
  TII = ST.getInstrInfo();
188
2.29k
189
2.29k
  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
190
4.71k
                                                  BB != BB_E; 
++BB2.42k
) {
191
2.42k
    MachineBasicBlock &MBB = *BB;
192
2.42k
    MachineBasicBlock::iterator I = MBB.begin(),  E = MBB.end();
193
2.42k
    MachineBasicBlock::iterator LatestCFAlu = E;
194
63.3k
    while (I != E) {
195
60.8k
      MachineInstr &MI = *I++;
196
60.8k
      if ((!TII->canBeConsideredALU(MI) && 
!isCFAlu(MI)11.6k
) ||
197
60.8k
          
TII->mustBeLastInClause(MI.getOpcode())53.1k
)
198
7.72k
        LatestCFAlu = E;
199
60.8k
      if (!isCFAlu(MI))
200
56.9k
        continue;
201
3.92k
      cleanPotentialDisabledCFAlu(MI);
202
3.92k
203
3.92k
      if (LatestCFAlu != E && 
mergeIfPossible(*LatestCFAlu, MI)328
) {
204
96
        MI.eraseFromParent();
205
3.82k
      } else {
206
3.82k
        assert(MI.getOperand(8).getImm() && "CF ALU instruction disabled");
207
3.82k
        LatestCFAlu = MI;
208
3.82k
      }
209
3.92k
    }
210
2.42k
  }
211
2.29k
  return false;
212
2.29k
}
213
214
2.57k
StringRef R600ClauseMergePass::getPassName() const {
215
2.57k
  return "R600 Merge Clause Markers Pass";
216
2.57k
}
217
218
280
llvm::FunctionPass *llvm::createR600ClauseMergePass() {
219
280
  return new R600ClauseMergePass();
220
280
}