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