brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · b8c0dd6 Raw
148 lines · cpp
1///===- DroppedVariableStats.cpp ----------------------------------------===//2///3/// Part of the LLVM Project, under the Apache License v2.0 with LLVM4/// Exceptions. See https://llvm.org/LICENSE.txt for license information.5/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6///7///===---------------------------------------------------------------------===//8/// \file9/// Dropped Variable Statistics for Debug Information. Reports any number10/// of #dbg_value that get dropped due to an optimization pass.11///12///===---------------------------------------------------------------------===//13 14#include "llvm/IR/DroppedVariableStats.h"15#include "llvm/IR/DebugInfoMetadata.h"16#include "llvm/IR/DiagnosticInfo.h"17#include "llvm/IR/Function.h"18 19using namespace llvm;20 21DroppedVariableStats::DroppedVariableStats(bool DroppedVarStatsEnabled)22    : DroppedVariableStatsEnabled(DroppedVarStatsEnabled) {23  if (DroppedVarStatsEnabled)24    llvm::outs() << "Pass Level, Pass Name, Num of Dropped Variables, Func or "25                    "Module Name\n";26}27 28void DroppedVariableStats::setup() {29  DebugVariablesStack.push_back({DenseMap<const Function *, DebugVariables>()});30  InlinedAts.push_back({DenseMap<StringRef, DenseMap<VarID, DILocation *>>()});31}32 33void DroppedVariableStats::cleanup() {34  assert(!DebugVariablesStack.empty() &&35         "DebugVariablesStack shouldn't be empty!");36  assert(!InlinedAts.empty() && "InlinedAts shouldn't be empty!");37  DebugVariablesStack.pop_back();38  InlinedAts.pop_back();39}40 41void DroppedVariableStats::calculateDroppedStatsAndPrint(42    DebugVariables &DbgVariables, StringRef FuncName, StringRef PassID,43    StringRef FuncOrModName, StringRef PassLevel, const Function *Func) {44  unsigned DroppedCount = 0;45  DenseSet<VarID> &DebugVariablesBeforeSet = DbgVariables.DebugVariablesBefore;46  DenseSet<VarID> &DebugVariablesAfterSet = DbgVariables.DebugVariablesAfter;47  auto It = InlinedAts.back().find(FuncName);48  if (It == InlinedAts.back().end())49    return;50  DenseMap<VarID, DILocation *> &InlinedAtsMap = It->second;51  // Find an Instruction that shares the same scope as the dropped #dbg_value52  // or has a scope that is the child of the scope of the #dbg_value, and has53  // an inlinedAt equal to the inlinedAt of the #dbg_value or it's inlinedAt54  // chain contains the inlinedAt of the #dbg_value, if such an Instruction is55  // found, debug information is dropped.56  for (VarID Var : DebugVariablesBeforeSet) {57    if (DebugVariablesAfterSet.contains(Var))58      continue;59    visitEveryInstruction(DroppedCount, InlinedAtsMap, Var);60    removeVarFromAllSets(Var, Func);61  }62  if (DroppedCount > 0) {63    llvm::outs() << PassLevel << ", " << PassID << ", " << DroppedCount << ", "64                 << FuncOrModName << "\n";65    PassDroppedVariables = true;66  } else67    PassDroppedVariables = false;68}69 70bool DroppedVariableStats::updateDroppedCount(71    DILocation *DbgLoc, const DIScope *Scope, const DIScope *DbgValScope,72    DenseMap<VarID, DILocation *> &InlinedAtsMap, VarID Var,73    unsigned &DroppedCount) {74  // If the Scope is a child of, or equal to the DbgValScope and is inlined at75  // the Var's InlinedAt location, return true to signify that the Var has76  // been dropped.77  if (isScopeChildOfOrEqualTo(Scope, DbgValScope))78    if (isInlinedAtChildOfOrEqualTo(DbgLoc->getInlinedAt(),79                                    InlinedAtsMap[Var])) {80      // Found another instruction in the variable's scope, so there exists a81      // break point at which the variable could be observed. Count it as82      // dropped.83      DroppedCount++;84      return true;85    }86  return false;87}88 89void DroppedVariableStats::run(DebugVariables &DbgVariables, StringRef FuncName,90                               bool Before) {91  auto &VarIDSet = (Before ? DbgVariables.DebugVariablesBefore92                           : DbgVariables.DebugVariablesAfter);93  auto &InlinedAtsMap = InlinedAts.back();94  if (Before)95    InlinedAtsMap.try_emplace(FuncName, DenseMap<VarID, DILocation *>());96  VarIDSet = DenseSet<VarID>();97  visitEveryDebugRecord(VarIDSet, InlinedAtsMap, FuncName, Before);98}99 100void DroppedVariableStats::populateVarIDSetAndInlinedMap(101    const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,102    DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,103    StringRef FuncName, bool Before) {104  VarID Key{DbgVar->getScope(), DbgLoc->getInlinedAtScope(), DbgVar};105  VarIDSet.insert(Key);106  if (Before)107    InlinedAtsMap[FuncName].try_emplace(Key, DbgLoc.getInlinedAt());108}109 110void DroppedVariableStats::removeVarFromAllSets(VarID Var, const Function *F) {111  // Do not remove Var from the last element, it will be popped from the112  // stack.113  for (auto &DebugVariablesMap : llvm::drop_end(DebugVariablesStack))114    DebugVariablesMap[F].DebugVariablesBefore.erase(Var);115}116 117bool DroppedVariableStats::isScopeChildOfOrEqualTo(const DIScope *Scope,118                                                   const DIScope *DbgValScope) {119  while (Scope != nullptr) {120    if (VisitedScope.insert(Scope).second) {121      if (Scope == DbgValScope) {122        VisitedScope.clear();123        return true;124      }125      Scope = Scope->getScope();126    } else {127      VisitedScope.clear();128      return false;129    }130  }131  return false;132}133 134bool DroppedVariableStats::isInlinedAtChildOfOrEqualTo(135    const DILocation *InlinedAt, const DILocation *DbgValInlinedAt) {136  if (DbgValInlinedAt == InlinedAt)137    return true;138  if (!DbgValInlinedAt)139    return false;140  auto *IA = InlinedAt;141  while (IA) {142    if (IA == DbgValInlinedAt)143      return true;144    IA = IA->getInlinedAt();145  }146  return false;147}148