Path: blob/main/contrib/llvm-project/llvm/lib/IR/DroppedVariableStats.cpp
213766 views
///===- DroppedVariableStats.cpp ----------------------------------------===//1///2/// Part of the LLVM Project, under the Apache License v2.0 with LLVM3/// Exceptions. See https://llvm.org/LICENSE.txt for license information.4/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5///6///===---------------------------------------------------------------------===//7/// \file8/// Dropped Variable Statistics for Debug Information. Reports any number9/// of #dbg_value that get dropped due to an optimization pass.10///11///===---------------------------------------------------------------------===//1213#include "llvm/IR/DroppedVariableStats.h"14#include "llvm/IR/DebugInfoMetadata.h"15#include "llvm/IR/DiagnosticInfo.h"16#include "llvm/IR/Function.h"1718using namespace llvm;1920DroppedVariableStats::DroppedVariableStats(bool DroppedVarStatsEnabled)21: DroppedVariableStatsEnabled(DroppedVarStatsEnabled) {22if (DroppedVarStatsEnabled)23llvm::outs() << "Pass Level, Pass Name, Num of Dropped Variables, Func or "24"Module Name\n";25}2627void DroppedVariableStats::setup() {28DebugVariablesStack.push_back({DenseMap<const Function *, DebugVariables>()});29InlinedAts.push_back({DenseMap<StringRef, DenseMap<VarID, DILocation *>>()});30}3132void DroppedVariableStats::cleanup() {33assert(!DebugVariablesStack.empty() &&34"DebugVariablesStack shouldn't be empty!");35assert(!InlinedAts.empty() && "InlinedAts shouldn't be empty!");36DebugVariablesStack.pop_back();37InlinedAts.pop_back();38}3940void DroppedVariableStats::calculateDroppedStatsAndPrint(41DebugVariables &DbgVariables, StringRef FuncName, StringRef PassID,42StringRef FuncOrModName, StringRef PassLevel, const Function *Func) {43unsigned DroppedCount = 0;44DenseSet<VarID> &DebugVariablesBeforeSet = DbgVariables.DebugVariablesBefore;45DenseSet<VarID> &DebugVariablesAfterSet = DbgVariables.DebugVariablesAfter;46auto It = InlinedAts.back().find(FuncName);47if (It == InlinedAts.back().end())48return;49DenseMap<VarID, DILocation *> &InlinedAtsMap = It->second;50// Find an Instruction that shares the same scope as the dropped #dbg_value51// or has a scope that is the child of the scope of the #dbg_value, and has52// an inlinedAt equal to the inlinedAt of the #dbg_value or it's inlinedAt53// chain contains the inlinedAt of the #dbg_value, if such an Instruction is54// found, debug information is dropped.55for (VarID Var : DebugVariablesBeforeSet) {56if (DebugVariablesAfterSet.contains(Var))57continue;58visitEveryInstruction(DroppedCount, InlinedAtsMap, Var);59removeVarFromAllSets(Var, Func);60}61if (DroppedCount > 0) {62llvm::outs() << PassLevel << ", " << PassID << ", " << DroppedCount << ", "63<< FuncOrModName << "\n";64PassDroppedVariables = true;65} else66PassDroppedVariables = false;67}6869bool DroppedVariableStats::updateDroppedCount(70DILocation *DbgLoc, const DIScope *Scope, const DIScope *DbgValScope,71DenseMap<VarID, DILocation *> &InlinedAtsMap, VarID Var,72unsigned &DroppedCount) {73// If the Scope is a child of, or equal to the DbgValScope and is inlined at74// the Var's InlinedAt location, return true to signify that the Var has75// been dropped.76if (isScopeChildOfOrEqualTo(Scope, DbgValScope))77if (isInlinedAtChildOfOrEqualTo(DbgLoc->getInlinedAt(),78InlinedAtsMap[Var])) {79// Found another instruction in the variable's scope, so there exists a80// break point at which the variable could be observed. Count it as81// dropped.82DroppedCount++;83return true;84}85return false;86}8788void DroppedVariableStats::run(DebugVariables &DbgVariables, StringRef FuncName,89bool Before) {90auto &VarIDSet = (Before ? DbgVariables.DebugVariablesBefore91: DbgVariables.DebugVariablesAfter);92auto &InlinedAtsMap = InlinedAts.back();93if (Before)94InlinedAtsMap.try_emplace(FuncName, DenseMap<VarID, DILocation *>());95VarIDSet = DenseSet<VarID>();96visitEveryDebugRecord(VarIDSet, InlinedAtsMap, FuncName, Before);97}9899void DroppedVariableStats::populateVarIDSetAndInlinedMap(100const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,101DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,102StringRef FuncName, bool Before) {103VarID Key{DbgVar->getScope(), DbgLoc->getInlinedAtScope(), DbgVar};104VarIDSet.insert(Key);105if (Before)106InlinedAtsMap[FuncName].try_emplace(Key, DbgLoc.getInlinedAt());107}108109void DroppedVariableStats::removeVarFromAllSets(VarID Var, const Function *F) {110// Do not remove Var from the last element, it will be popped from the111// stack.112for (auto &DebugVariablesMap : llvm::drop_end(DebugVariablesStack))113DebugVariablesMap[F].DebugVariablesBefore.erase(Var);114}115116bool DroppedVariableStats::isScopeChildOfOrEqualTo(const DIScope *Scope,117const DIScope *DbgValScope) {118while (Scope != nullptr) {119if (VisitedScope.insert(Scope).second) {120if (Scope == DbgValScope) {121VisitedScope.clear();122return true;123}124Scope = Scope->getScope();125} else {126VisitedScope.clear();127return false;128}129}130return false;131}132133bool DroppedVariableStats::isInlinedAtChildOfOrEqualTo(134const DILocation *InlinedAt, const DILocation *DbgValInlinedAt) {135if (DbgValInlinedAt == InlinedAt)136return true;137if (!DbgValInlinedAt)138return false;139auto *IA = InlinedAt;140while (IA) {141if (IA == DbgValInlinedAt)142return true;143IA = IA->getInlinedAt();144}145return false;146}147148149