forked from OSchip/llvm-project
114 lines
3.4 KiB
C++
114 lines
3.4 KiB
C++
//===----- llvm/CodeGen/GlobalISel/LostDebugLocObserver.cpp -----*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// Tracks DebugLocs between checkpoints and verifies that they are transferred.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
|
|
|
|
using namespace llvm;
|
|
|
|
#define LOC_DEBUG(X) DEBUG_WITH_TYPE(DebugType.str().c_str(), X)
|
|
|
|
void LostDebugLocObserver::analyzeDebugLocations() {
|
|
if (LostDebugLocs.empty()) {
|
|
LOC_DEBUG(dbgs() << ".. No debug info was present\n");
|
|
return;
|
|
}
|
|
if (PotentialMIsForDebugLocs.empty()) {
|
|
LOC_DEBUG(
|
|
dbgs() << ".. No instructions to carry debug info (dead code?)\n");
|
|
return;
|
|
}
|
|
|
|
LOC_DEBUG(dbgs() << ".. Searching " << PotentialMIsForDebugLocs.size()
|
|
<< " instrs for " << LostDebugLocs.size() << " locations\n");
|
|
SmallPtrSet<MachineInstr *, 4> FoundIn;
|
|
for (MachineInstr *MI : PotentialMIsForDebugLocs) {
|
|
if (!MI->getDebugLoc())
|
|
continue;
|
|
// Check this first in case there's a matching line-0 location on both input
|
|
// and output.
|
|
if (MI->getDebugLoc().getLine() == 0) {
|
|
LOC_DEBUG(
|
|
dbgs() << ".. Assuming line-0 location covers remainder (if any)\n");
|
|
return;
|
|
}
|
|
if (LostDebugLocs.erase(MI->getDebugLoc())) {
|
|
LOC_DEBUG(dbgs() << ".. .. found " << MI->getDebugLoc() << " in " << *MI);
|
|
FoundIn.insert(MI);
|
|
continue;
|
|
}
|
|
}
|
|
if (LostDebugLocs.empty())
|
|
return;
|
|
|
|
NumLostDebugLocs += LostDebugLocs.size();
|
|
LOC_DEBUG({
|
|
dbgs() << ".. Lost locations:\n";
|
|
for (const DebugLoc &Loc : LostDebugLocs) {
|
|
dbgs() << ".. .. ";
|
|
Loc.print(dbgs());
|
|
dbgs() << "\n";
|
|
}
|
|
dbgs() << ".. MIs with matched locations:\n";
|
|
for (MachineInstr *MI : FoundIn)
|
|
if (PotentialMIsForDebugLocs.erase(MI))
|
|
dbgs() << ".. .. " << *MI;
|
|
dbgs() << ".. Remaining MIs with unmatched/no locations:\n";
|
|
for (const MachineInstr *MI : PotentialMIsForDebugLocs)
|
|
dbgs() << ".. .. " << *MI;
|
|
});
|
|
}
|
|
|
|
void LostDebugLocObserver::checkpoint(bool CheckDebugLocs) {
|
|
if (CheckDebugLocs)
|
|
analyzeDebugLocations();
|
|
PotentialMIsForDebugLocs.clear();
|
|
LostDebugLocs.clear();
|
|
}
|
|
|
|
void LostDebugLocObserver::createdInstr(MachineInstr &MI) {
|
|
PotentialMIsForDebugLocs.insert(&MI);
|
|
}
|
|
|
|
static bool irTranslatorNeverAddsLocations(unsigned Opcode) {
|
|
switch (Opcode) {
|
|
default:
|
|
return false;
|
|
case TargetOpcode::G_CONSTANT:
|
|
case TargetOpcode::G_FCONSTANT:
|
|
case TargetOpcode::G_IMPLICIT_DEF:
|
|
case TargetOpcode::G_GLOBAL_VALUE:
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void LostDebugLocObserver::erasingInstr(MachineInstr &MI) {
|
|
if (irTranslatorNeverAddsLocations(MI.getOpcode()))
|
|
return;
|
|
|
|
PotentialMIsForDebugLocs.erase(&MI);
|
|
if (MI.getDebugLoc())
|
|
LostDebugLocs.insert(MI.getDebugLoc());
|
|
}
|
|
|
|
void LostDebugLocObserver::changingInstr(MachineInstr &MI) {
|
|
if (irTranslatorNeverAddsLocations(MI.getOpcode()))
|
|
return;
|
|
|
|
PotentialMIsForDebugLocs.erase(&MI);
|
|
if (MI.getDebugLoc())
|
|
LostDebugLocs.insert(MI.getDebugLoc());
|
|
}
|
|
|
|
void LostDebugLocObserver::changedInstr(MachineInstr &MI) {
|
|
PotentialMIsForDebugLocs.insert(&MI);
|
|
}
|