/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/AMDGPU/SIDebuggerInsertNops.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- SIDebuggerInsertNops.cpp - Inserts nops for debugger usage -------===// |
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 | | /// Inserts one nop instruction for each high level source statement for |
11 | | /// debugger usage. |
12 | | /// |
13 | | /// Tools, such as a debugger, need to pause execution based on user input (i.e. |
14 | | /// breakpoint). In order to do this, one nop instruction is inserted before the |
15 | | /// first isa instruction of each high level source statement. Further, the |
16 | | /// debugger may replace nop instructions with trap instructions based on user |
17 | | /// input. |
18 | | // |
19 | | //===----------------------------------------------------------------------===// |
20 | | |
21 | | #include "AMDGPUSubtarget.h" |
22 | | #include "SIInstrInfo.h" |
23 | | #include "MCTargetDesc/AMDGPUMCTargetDesc.h" |
24 | | #include "llvm/ADT/DenseSet.h" |
25 | | #include "llvm/CodeGen/MachineFunction.h" |
26 | | #include "llvm/CodeGen/MachineFunctionPass.h" |
27 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
28 | | #include "llvm/CodeGen/MachineModuleInfo.h" |
29 | | using namespace llvm; |
30 | | |
31 | | #define DEBUG_TYPE "si-debugger-insert-nops" |
32 | 2.10k | #define PASS_NAME "SI Debugger Insert Nops" |
33 | | |
34 | | namespace { |
35 | | |
36 | | class SIDebuggerInsertNops : public MachineFunctionPass { |
37 | | public: |
38 | | static char ID; |
39 | | |
40 | 2.11k | SIDebuggerInsertNops() : MachineFunctionPass(ID) { } |
41 | 2.10k | StringRef getPassName() const override { return PASS_NAME; } |
42 | | |
43 | 2.10k | void getAnalysisUsage(AnalysisUsage &AU) const override { |
44 | 2.10k | AU.setPreservesCFG(); |
45 | 2.10k | MachineFunctionPass::getAnalysisUsage(AU); |
46 | 2.10k | } |
47 | | |
48 | | bool runOnMachineFunction(MachineFunction &MF) override; |
49 | | }; |
50 | | |
51 | | } // anonymous namespace |
52 | | |
53 | | INITIALIZE_PASS(SIDebuggerInsertNops, DEBUG_TYPE, PASS_NAME, false, false) |
54 | | |
55 | | char SIDebuggerInsertNops::ID = 0; |
56 | | char &llvm::SIDebuggerInsertNopsID = SIDebuggerInsertNops::ID; |
57 | | |
58 | 2.11k | FunctionPass *llvm::createSIDebuggerInsertNopsPass() { |
59 | 2.11k | return new SIDebuggerInsertNops(); |
60 | 2.11k | } |
61 | | |
62 | 21.2k | bool SIDebuggerInsertNops::runOnMachineFunction(MachineFunction &MF) { |
63 | 21.2k | // Skip this pass if "amdgpu-debugger-insert-nops" attribute was not |
64 | 21.2k | // specified. |
65 | 21.2k | const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); |
66 | 21.2k | if (!ST.debuggerInsertNops()) |
67 | 21.2k | return false; |
68 | 5 | |
69 | 5 | // Skip machine functions without debug info. |
70 | 5 | if (!MF.getMMI().hasDebugInfo()) |
71 | 0 | return false; |
72 | 5 | |
73 | 5 | // Target instruction info. |
74 | 5 | const SIInstrInfo *TII = ST.getInstrInfo(); |
75 | 5 | |
76 | 5 | // Set containing line numbers that have nop inserted. |
77 | 5 | DenseSet<unsigned> NopInserted; |
78 | 5 | |
79 | 5 | for (auto &MBB : MF) { |
80 | 237 | for (auto MI = MBB.begin(); MI != MBB.end(); ++MI232 ) { |
81 | 232 | // Skip debug instructions and instructions without location. |
82 | 232 | if (MI->isDebugInstr() || !MI->getDebugLoc()226 ) |
83 | 120 | continue; |
84 | 112 | |
85 | 112 | // Insert nop instruction if line number does not have nop inserted. |
86 | 112 | auto DL = MI->getDebugLoc(); |
87 | 112 | if (NopInserted.find(DL.getLine()) == NopInserted.end()) { |
88 | 20 | BuildMI(MBB, *MI, DL, TII->get(AMDGPU::S_NOP)) |
89 | 20 | .addImm(0); |
90 | 20 | NopInserted.insert(DL.getLine()); |
91 | 20 | } |
92 | 112 | } |
93 | 5 | } |
94 | 5 | |
95 | 5 | return true; |
96 | 5 | } |