1 //===-- WebAssemblyDebugValueManager.cpp - WebAssembly DebugValue Manager -===//
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 /// This file implements the manager for MachineInstr DebugValues.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "WebAssemblyDebugValueManager.h"
15 #include "WebAssembly.h"
16 #include "WebAssemblyMachineFunctionInfo.h"
17 #include "llvm/CodeGen/MachineInstr.h"
18
19 using namespace llvm;
20
WebAssemblyDebugValueManager(MachineInstr * Instr)21 WebAssemblyDebugValueManager::WebAssemblyDebugValueManager(
22 MachineInstr *Instr) {
23 const auto *MF = Instr->getParent()->getParent();
24 const auto *TII = MF->getSubtarget<WebAssemblySubtarget>().getInstrInfo();
25
26 // This code differs from MachineInstr::collectDebugValues in that it scans
27 // the whole BB, not just contiguous DBG_VALUEs.
28 if (!Instr->getOperand(0).isReg())
29 return;
30 CurrentReg = Instr->getOperand(0).getReg();
31
32 SmallVector<MachineInstr *, 2> DbgValueLists;
33 MachineBasicBlock::iterator DI = *Instr;
34 ++DI;
35 for (MachineBasicBlock::iterator DE = Instr->getParent()->end(); DI != DE;
36 ++DI) {
37 if (DI->isDebugValue() &&
38 DI->hasDebugOperandForReg(Instr->getOperand(0).getReg()))
39 DI->getOpcode() == TargetOpcode::DBG_VALUE
40 ? DbgValues.push_back(&*DI)
41 : DbgValueLists.push_back(&*DI);
42 }
43
44 // This class currently cannot handle DBG_VALUE_LISTs correctly. So this
45 // converts DBG_VALUE_LISTs to "DBG_VALUE $noreg", which will appear as
46 // "optimized out". This can invalidate existing iterators pointing to
47 // instructions within this BB from the caller.
48 // See https://bugs.llvm.org/show_bug.cgi?id=50361
49 // TODO Correctly handle DBG_VALUE_LISTs
50 for (auto *DVL : DbgValueLists) {
51 BuildMI(*DVL->getParent(), DVL, DVL->getDebugLoc(),
52 TII->get(TargetOpcode::DBG_VALUE), false, Register(),
53 DVL->getOperand(0).getMetadata(), DVL->getOperand(1).getMetadata());
54 DVL->eraseFromParent();
55 }
56 }
57
move(MachineInstr * Insert)58 void WebAssemblyDebugValueManager::move(MachineInstr *Insert) {
59 MachineBasicBlock *MBB = Insert->getParent();
60 for (MachineInstr *DBI : reverse(DbgValues))
61 MBB->splice(Insert, DBI->getParent(), DBI);
62 }
63
updateReg(unsigned Reg)64 void WebAssemblyDebugValueManager::updateReg(unsigned Reg) {
65 for (auto *DBI : DbgValues)
66 for (auto &MO : DBI->getDebugOperandsForReg(CurrentReg))
67 MO.setReg(Reg);
68 CurrentReg = Reg;
69 }
70
clone(MachineInstr * Insert,unsigned NewReg)71 void WebAssemblyDebugValueManager::clone(MachineInstr *Insert,
72 unsigned NewReg) {
73 MachineBasicBlock *MBB = Insert->getParent();
74 MachineFunction *MF = MBB->getParent();
75 for (MachineInstr *DBI : reverse(DbgValues)) {
76 MachineInstr *Clone = MF->CloneMachineInstr(DBI);
77 for (auto &MO : Clone->getDebugOperandsForReg(CurrentReg))
78 MO.setReg(NewReg);
79 MBB->insert(Insert, Clone);
80 }
81 }
82
replaceWithLocal(unsigned LocalId)83 void WebAssemblyDebugValueManager::replaceWithLocal(unsigned LocalId) {
84 for (auto *DBI : DbgValues) {
85 auto IndexType = DBI->isIndirectDebugValue()
86 ? llvm::WebAssembly::TI_LOCAL_INDIRECT
87 : llvm::WebAssembly::TI_LOCAL;
88 for (auto &MO : DBI->getDebugOperandsForReg(CurrentReg))
89 MO.ChangeToTargetIndex(IndexType, LocalId);
90 }
91 }
92