xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp (revision e25152834cdf3b353892835a4f3b157e066a8ed4)
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 Andric void 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 Andric void 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 Andric void LostDebugLocObserver::createdInstr(MachineInstr &MI) {
78*5ffd83dbSDimitry Andric   PotentialMIsForDebugLocs.insert(&MI);
79*5ffd83dbSDimitry Andric }
80*5ffd83dbSDimitry Andric 
irTranslatorNeverAddsLocations(unsigned Opcode)81*5ffd83dbSDimitry Andric static 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 Andric void 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 Andric void 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 Andric void LostDebugLocObserver::changedInstr(MachineInstr &MI) {
112*5ffd83dbSDimitry Andric   PotentialMIsForDebugLocs.insert(&MI);
113*5ffd83dbSDimitry Andric }
114