1*5f7ddb14SDimitry Andric //=== WebAssemblyNullifyDebugValueLists.cpp - Nullify DBG_VALUE_LISTs   ---===//
2*5f7ddb14SDimitry Andric //
3*5f7ddb14SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5f7ddb14SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5f7ddb14SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5f7ddb14SDimitry Andric //
7*5f7ddb14SDimitry Andric //===----------------------------------------------------------------------===//
8*5f7ddb14SDimitry Andric ///
9*5f7ddb14SDimitry Andric /// \file
10*5f7ddb14SDimitry Andric /// Nullify DBG_VALUE_LISTs instructions as a temporary measure before we
11*5f7ddb14SDimitry Andric /// implement DBG_VALUE_LIST handling in WebAssemblyDebugValueManager.
12*5f7ddb14SDimitry Andric /// See https://bugs.llvm.org/show_bug.cgi?id=50361.
13*5f7ddb14SDimitry Andric /// TODO Correctly handle DBG_VALUE_LISTs
14*5f7ddb14SDimitry Andric ///
15*5f7ddb14SDimitry Andric //===----------------------------------------------------------------------===//
16*5f7ddb14SDimitry Andric 
17*5f7ddb14SDimitry Andric #include "WebAssembly.h"
18*5f7ddb14SDimitry Andric #include "WebAssemblySubtarget.h"
19*5f7ddb14SDimitry Andric using namespace llvm;
20*5f7ddb14SDimitry Andric 
21*5f7ddb14SDimitry Andric #define DEBUG_TYPE "wasm-nullify-dbg-value-lists"
22*5f7ddb14SDimitry Andric 
23*5f7ddb14SDimitry Andric namespace {
24*5f7ddb14SDimitry Andric class WebAssemblyNullifyDebugValueLists final : public MachineFunctionPass {
getPassName() const25*5f7ddb14SDimitry Andric   StringRef getPassName() const override {
26*5f7ddb14SDimitry Andric     return "WebAssembly Nullify DBG_VALUE_LISTs";
27*5f7ddb14SDimitry Andric   }
28*5f7ddb14SDimitry Andric 
29*5f7ddb14SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
30*5f7ddb14SDimitry Andric 
31*5f7ddb14SDimitry Andric public:
32*5f7ddb14SDimitry Andric   static char ID; // Pass identification, replacement for typeid
WebAssemblyNullifyDebugValueLists()33*5f7ddb14SDimitry Andric   WebAssemblyNullifyDebugValueLists() : MachineFunctionPass(ID) {}
34*5f7ddb14SDimitry Andric };
35*5f7ddb14SDimitry Andric } // end anonymous namespace
36*5f7ddb14SDimitry Andric 
37*5f7ddb14SDimitry Andric char WebAssemblyNullifyDebugValueLists::ID = 0;
38*5f7ddb14SDimitry Andric INITIALIZE_PASS(WebAssemblyNullifyDebugValueLists, DEBUG_TYPE,
39*5f7ddb14SDimitry Andric                 "WebAssembly Nullify DBG_VALUE_LISTs", false, false)
40*5f7ddb14SDimitry Andric 
createWebAssemblyNullifyDebugValueLists()41*5f7ddb14SDimitry Andric FunctionPass *llvm::createWebAssemblyNullifyDebugValueLists() {
42*5f7ddb14SDimitry Andric   return new WebAssemblyNullifyDebugValueLists();
43*5f7ddb14SDimitry Andric }
44*5f7ddb14SDimitry Andric 
runOnMachineFunction(MachineFunction & MF)45*5f7ddb14SDimitry Andric bool WebAssemblyNullifyDebugValueLists::runOnMachineFunction(
46*5f7ddb14SDimitry Andric     MachineFunction &MF) {
47*5f7ddb14SDimitry Andric   LLVM_DEBUG(dbgs() << "********** Nullify DBG_VALUE_LISTs **********\n"
48*5f7ddb14SDimitry Andric                        "********** Function: "
49*5f7ddb14SDimitry Andric                     << MF.getName() << '\n');
50*5f7ddb14SDimitry Andric   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
51*5f7ddb14SDimitry Andric   SmallVector<MachineInstr *, 2> DbgValueLists;
52*5f7ddb14SDimitry Andric   for (auto &MBB : MF)
53*5f7ddb14SDimitry Andric     for (auto &MI : MBB)
54*5f7ddb14SDimitry Andric       if (MI.getOpcode() == TargetOpcode::DBG_VALUE_LIST)
55*5f7ddb14SDimitry Andric         DbgValueLists.push_back(&MI);
56*5f7ddb14SDimitry Andric 
57*5f7ddb14SDimitry Andric   // Our backend, including WebAssemblyDebugValueManager, currently cannot
58*5f7ddb14SDimitry Andric   // handle DBG_VALUE_LISTs correctly. So this converts DBG_VALUE_LISTs to
59*5f7ddb14SDimitry Andric   // "DBG_VALUE $noreg", which will appear as "optimized out".
60*5f7ddb14SDimitry Andric   for (auto *DVL : DbgValueLists) {
61*5f7ddb14SDimitry Andric     BuildMI(*DVL->getParent(), DVL, DVL->getDebugLoc(),
62*5f7ddb14SDimitry Andric             TII.get(TargetOpcode::DBG_VALUE), false, Register(),
63*5f7ddb14SDimitry Andric             DVL->getOperand(0).getMetadata(), DVL->getOperand(1).getMetadata());
64*5f7ddb14SDimitry Andric     DVL->eraseFromParent();
65*5f7ddb14SDimitry Andric   }
66*5f7ddb14SDimitry Andric 
67*5f7ddb14SDimitry Andric   return !DbgValueLists.empty();
68*5f7ddb14SDimitry Andric }
69