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 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 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 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 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 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