Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/NVPTX/NVPTXProxyRegErasure.cpp
Line
Count
Source
1
//===- NVPTXProxyRegErasure.cpp - NVPTX Proxy Register Instruction Erasure -==//
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
// The pass is needed to remove ProxyReg instructions and restore related
10
// registers. The instructions were needed at instruction selection stage to
11
// make sure that callseq_end nodes won't be removed as "dead nodes". This can
12
// happen when we expand instructions into libcalls and the call site doesn't
13
// care about the libcall chain. Call site cares about data flow only, and the
14
// latest data flow node happens to be before callseq_end. Therefore the node
15
// becomes dangling and "dead". The ProxyReg acts like an additional data flow
16
// node *after* the callseq_end in the chain and ensures that everything will be
17
// preserved.
18
//
19
//===----------------------------------------------------------------------===//
20
21
#include "NVPTX.h"
22
#include "llvm/CodeGen/MachineFunctionPass.h"
23
#include "llvm/CodeGen/MachineInstrBuilder.h"
24
#include "llvm/CodeGen/MachineRegisterInfo.h"
25
#include "llvm/CodeGen/TargetInstrInfo.h"
26
#include "llvm/CodeGen/TargetRegisterInfo.h"
27
28
using namespace llvm;
29
30
namespace llvm {
31
void initializeNVPTXProxyRegErasurePass(PassRegistry &);
32
}
33
34
namespace {
35
36
struct NVPTXProxyRegErasure : public MachineFunctionPass {
37
public:
38
  static char ID;
39
263
  NVPTXProxyRegErasure() : MachineFunctionPass(ID) {
40
263
    initializeNVPTXProxyRegErasurePass(*PassRegistry::getPassRegistry());
41
263
  }
42
43
  bool runOnMachineFunction(MachineFunction &MF) override;
44
45
1.93k
  StringRef getPassName() const override {
46
1.93k
    return "NVPTX Proxy Register Instruction Erasure";
47
1.93k
  }
48
49
259
  void getAnalysisUsage(AnalysisUsage &AU) const override {
50
259
    MachineFunctionPass::getAnalysisUsage(AU);
51
259
  }
52
53
private:
54
  void replaceMachineInstructionUsage(MachineFunction &MF, MachineInstr &MI);
55
56
  void replaceRegisterUsage(MachineInstr &Instr, MachineOperand &From,
57
                            MachineOperand &To);
58
};
59
60
} // namespace
61
62
char NVPTXProxyRegErasure::ID = 0;
63
64
INITIALIZE_PASS(NVPTXProxyRegErasure, "nvptx-proxyreg-erasure", "NVPTX ProxyReg Erasure", false, false)
65
66
1.67k
bool NVPTXProxyRegErasure::runOnMachineFunction(MachineFunction &MF) {
67
1.67k
  SmallVector<MachineInstr *, 16> RemoveList;
68
1.67k
69
1.83k
  for (auto &BB : MF) {
70
13.5k
    for (auto &MI : BB) {
71
13.5k
      switch (MI.getOpcode()) {
72
13.5k
      case NVPTX::ProxyRegI1:
73
219
      case NVPTX::ProxyRegI16:
74
219
      case NVPTX::ProxyRegI32:
75
219
      case NVPTX::ProxyRegI64:
76
219
      case NVPTX::ProxyRegF16:
77
219
      case NVPTX::ProxyRegF16x2:
78
219
      case NVPTX::ProxyRegF32:
79
219
      case NVPTX::ProxyRegF64:
80
219
        replaceMachineInstructionUsage(MF, MI);
81
219
        RemoveList.push_back(&MI);
82
219
        break;
83
13.5k
      }
84
13.5k
    }
85
1.83k
  }
86
1.67k
87
1.67k
  for (auto *MI : RemoveList) {
88
219
    MI->eraseFromParent();
89
219
  }
90
1.67k
91
1.67k
  return !RemoveList.empty();
92
1.67k
}
93
94
void NVPTXProxyRegErasure::replaceMachineInstructionUsage(MachineFunction &MF,
95
219
                                                          MachineInstr &MI) {
96
219
  auto &InOp = *MI.uses().begin();
97
219
  auto &OutOp = *MI.defs().begin();
98
219
99
219
  assert(InOp.isReg() && "ProxyReg input operand should be a register.");
100
219
  assert(OutOp.isReg() && "ProxyReg output operand should be a register.");
101
219
102
263
  for (auto &BB : MF) {
103
6.19k
    for (auto &I : BB) {
104
6.19k
      replaceRegisterUsage(I, OutOp, InOp);
105
6.19k
    }
106
263
  }
107
219
}
108
109
void NVPTXProxyRegErasure::replaceRegisterUsage(MachineInstr &Instr,
110
                                                MachineOperand &From,
111
6.19k
                                                MachineOperand &To) {
112
13.2k
  for (auto &Op : Instr.uses()) {
113
13.2k
    if (Op.isReg() && 
Op.getReg() == From.getReg()3.59k
) {
114
214
      Op.setReg(To.getReg());
115
214
    }
116
13.2k
  }
117
6.19k
}
118
119
263
MachineFunctionPass *llvm::createNVPTXProxyRegErasurePass() {
120
263
  return new NVPTXProxyRegErasure();
121
263
}