1*5ffd83dbSDimitry Andric //===----- llvm/CodeGen/GlobalISel/LostDebugLocObserver.cpp -----*- C++ -*-===// 2*5ffd83dbSDimitry Andric // 3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5ffd83dbSDimitry Andric // 7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 8*5ffd83dbSDimitry Andric // 9*5ffd83dbSDimitry Andric /// Tracks DebugLocs between checkpoints and verifies that they are transferred. 10*5ffd83dbSDimitry Andric // 11*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 12*5ffd83dbSDimitry Andric 13*5ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h" 14*5ffd83dbSDimitry Andric 15*5ffd83dbSDimitry Andric using namespace llvm; 16*5ffd83dbSDimitry Andric 17*5ffd83dbSDimitry Andric #define LOC_DEBUG(X) DEBUG_WITH_TYPE(DebugType.str().c_str(), X) 18*5ffd83dbSDimitry Andric analyzeDebugLocations()19*5ffd83dbSDimitry Andricvoid LostDebugLocObserver::analyzeDebugLocations() { 20*5ffd83dbSDimitry Andric if (LostDebugLocs.empty()) { 21*5ffd83dbSDimitry Andric LOC_DEBUG(dbgs() << ".. No debug info was present\n"); 22*5ffd83dbSDimitry Andric return; 23*5ffd83dbSDimitry Andric } 24*5ffd83dbSDimitry Andric if (PotentialMIsForDebugLocs.empty()) { 25*5ffd83dbSDimitry Andric LOC_DEBUG( 26*5ffd83dbSDimitry Andric dbgs() << ".. No instructions to carry debug info (dead code?)\n"); 27*5ffd83dbSDimitry Andric return; 28*5ffd83dbSDimitry Andric } 29*5ffd83dbSDimitry Andric 30*5ffd83dbSDimitry Andric LOC_DEBUG(dbgs() << ".. Searching " << PotentialMIsForDebugLocs.size() 31*5ffd83dbSDimitry Andric << " instrs for " << LostDebugLocs.size() << " locations\n"); 32*5ffd83dbSDimitry Andric SmallPtrSet<MachineInstr *, 4> FoundIn; 33*5ffd83dbSDimitry Andric for (MachineInstr *MI : PotentialMIsForDebugLocs) { 34*5ffd83dbSDimitry Andric if (!MI->getDebugLoc()) 35*5ffd83dbSDimitry Andric continue; 36*5ffd83dbSDimitry Andric // Check this first in case there's a matching line-0 location on both input 37*5ffd83dbSDimitry Andric // and output. 38*5ffd83dbSDimitry Andric if (MI->getDebugLoc().getLine() == 0) { 39*5ffd83dbSDimitry Andric LOC_DEBUG( 40*5ffd83dbSDimitry Andric dbgs() << ".. Assuming line-0 location covers remainder (if any)\n"); 41*5ffd83dbSDimitry Andric return; 42*5ffd83dbSDimitry Andric } 43*5ffd83dbSDimitry Andric if (LostDebugLocs.erase(MI->getDebugLoc())) { 44*5ffd83dbSDimitry Andric LOC_DEBUG(dbgs() << ".. .. found " << MI->getDebugLoc() << " in " << *MI); 45*5ffd83dbSDimitry Andric FoundIn.insert(MI); 46*5ffd83dbSDimitry Andric continue; 47*5ffd83dbSDimitry Andric } 48*5ffd83dbSDimitry Andric } 49*5ffd83dbSDimitry Andric if (LostDebugLocs.empty()) 50*5ffd83dbSDimitry Andric return; 51*5ffd83dbSDimitry Andric 52*5ffd83dbSDimitry Andric NumLostDebugLocs += LostDebugLocs.size(); 53*5ffd83dbSDimitry Andric LOC_DEBUG({ 54*5ffd83dbSDimitry Andric dbgs() << ".. Lost locations:\n"; 55*5ffd83dbSDimitry Andric for (const DebugLoc &Loc : LostDebugLocs) { 56*5ffd83dbSDimitry Andric dbgs() << ".. .. "; 57*5ffd83dbSDimitry Andric Loc.print(dbgs()); 58*5ffd83dbSDimitry Andric dbgs() << "\n"; 59*5ffd83dbSDimitry Andric } 60*5ffd83dbSDimitry Andric dbgs() << ".. MIs with matched locations:\n"; 61*5ffd83dbSDimitry Andric for (MachineInstr *MI : FoundIn) 62*5ffd83dbSDimitry Andric if (PotentialMIsForDebugLocs.erase(MI)) 63*5ffd83dbSDimitry Andric dbgs() << ".. .. " << *MI; 64*5ffd83dbSDimitry Andric dbgs() << ".. Remaining MIs with unmatched/no locations:\n"; 65*5ffd83dbSDimitry Andric for (const MachineInstr *MI : PotentialMIsForDebugLocs) 66*5ffd83dbSDimitry Andric dbgs() << ".. .. " << *MI; 67*5ffd83dbSDimitry Andric }); 68*5ffd83dbSDimitry Andric } 69*5ffd83dbSDimitry Andric checkpoint(bool CheckDebugLocs)70*5ffd83dbSDimitry Andricvoid LostDebugLocObserver::checkpoint(bool CheckDebugLocs) { 71*5ffd83dbSDimitry Andric if (CheckDebugLocs) 72*5ffd83dbSDimitry Andric analyzeDebugLocations(); 73*5ffd83dbSDimitry Andric PotentialMIsForDebugLocs.clear(); 74*5ffd83dbSDimitry Andric LostDebugLocs.clear(); 75*5ffd83dbSDimitry Andric } 76*5ffd83dbSDimitry Andric createdInstr(MachineInstr & MI)77*5ffd83dbSDimitry Andricvoid LostDebugLocObserver::createdInstr(MachineInstr &MI) { 78*5ffd83dbSDimitry Andric PotentialMIsForDebugLocs.insert(&MI); 79*5ffd83dbSDimitry Andric } 80*5ffd83dbSDimitry Andric irTranslatorNeverAddsLocations(unsigned Opcode)81*5ffd83dbSDimitry Andricstatic bool irTranslatorNeverAddsLocations(unsigned Opcode) { 82*5ffd83dbSDimitry Andric switch (Opcode) { 83*5ffd83dbSDimitry Andric default: 84*5ffd83dbSDimitry Andric return false; 85*5ffd83dbSDimitry Andric case TargetOpcode::G_CONSTANT: 86*5ffd83dbSDimitry Andric case TargetOpcode::G_FCONSTANT: 87*5ffd83dbSDimitry Andric case TargetOpcode::G_IMPLICIT_DEF: 88*5ffd83dbSDimitry Andric case TargetOpcode::G_GLOBAL_VALUE: 89*5ffd83dbSDimitry Andric return true; 90*5ffd83dbSDimitry Andric } 91*5ffd83dbSDimitry Andric } 92*5ffd83dbSDimitry Andric erasingInstr(MachineInstr & MI)93*5ffd83dbSDimitry Andricvoid LostDebugLocObserver::erasingInstr(MachineInstr &MI) { 94*5ffd83dbSDimitry Andric if (irTranslatorNeverAddsLocations(MI.getOpcode())) 95*5ffd83dbSDimitry Andric return; 96*5ffd83dbSDimitry Andric 97*5ffd83dbSDimitry Andric PotentialMIsForDebugLocs.erase(&MI); 98*5ffd83dbSDimitry Andric if (MI.getDebugLoc()) 99*5ffd83dbSDimitry Andric LostDebugLocs.insert(MI.getDebugLoc()); 100*5ffd83dbSDimitry Andric } 101*5ffd83dbSDimitry Andric changingInstr(MachineInstr & MI)102*5ffd83dbSDimitry Andricvoid LostDebugLocObserver::changingInstr(MachineInstr &MI) { 103*5ffd83dbSDimitry Andric if (irTranslatorNeverAddsLocations(MI.getOpcode())) 104*5ffd83dbSDimitry Andric return; 105*5ffd83dbSDimitry Andric 106*5ffd83dbSDimitry Andric PotentialMIsForDebugLocs.erase(&MI); 107*5ffd83dbSDimitry Andric if (MI.getDebugLoc()) 108*5ffd83dbSDimitry Andric LostDebugLocs.insert(MI.getDebugLoc()); 109*5ffd83dbSDimitry Andric } 110*5ffd83dbSDimitry Andric changedInstr(MachineInstr & MI)111*5ffd83dbSDimitry Andricvoid LostDebugLocObserver::changedInstr(MachineInstr &MI) { 112*5ffd83dbSDimitry Andric PotentialMIsForDebugLocs.insert(&MI); 113*5ffd83dbSDimitry Andric } 114