xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
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