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);
 | 
						|
}
 |