133 lines · cpp
1///===- DroppedVariableStatsIR.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/DroppedVariableStatsIR.h"15#include "llvm/IR/DebugInfoMetadata.h"16#include "llvm/IR/InstIterator.h"17#include "llvm/IR/Module.h"18#include "llvm/IR/PassInstrumentation.h"19 20using namespace llvm;21 22template <typename IRUnitT>23const IRUnitT *DroppedVariableStatsIR::unwrapIR(Any IR) {24 const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);25 return IRPtr ? *IRPtr : nullptr;26}27 28void DroppedVariableStatsIR::runBeforePass(StringRef P, Any IR) {29 setup();30 if (const auto *M = unwrapIR<Module>(IR))31 return this->runOnModule(P, M, true);32 if (const auto *F = unwrapIR<Function>(IR))33 return this->runOnFunction(P, F, true);34}35 36void DroppedVariableStatsIR::runAfterPass(StringRef P, Any IR) {37 if (const auto *M = unwrapIR<Module>(IR))38 runAfterPassModule(P, M);39 else if (const auto *F = unwrapIR<Function>(IR))40 runAfterPassFunction(P, F);41 cleanup();42}43 44void DroppedVariableStatsIR::runAfterPassFunction(StringRef PassID,45 const Function *F) {46 runOnFunction(PassID, F, false);47 calculateDroppedVarStatsOnFunction(F, PassID, F->getName().str(), "Function");48}49 50void DroppedVariableStatsIR::runAfterPassModule(StringRef PassID,51 const Module *M) {52 runOnModule(PassID, M, false);53 calculateDroppedVarStatsOnModule(M, PassID, M->getName().str(), "Module");54}55 56void DroppedVariableStatsIR::runOnFunction(StringRef PassID, const Function *F,57 bool Before) {58 auto &DebugVariables = DebugVariablesStack.back()[F];59 auto FuncName = F->getName();60 Func = F;61 run(DebugVariables, FuncName, Before);62}63 64void DroppedVariableStatsIR::calculateDroppedVarStatsOnFunction(65 const Function *F, StringRef PassID, StringRef FuncOrModName,66 StringRef PassLevel) {67 Func = F;68 StringRef FuncName = F->getName();69 DebugVariables &DbgVariables = DebugVariablesStack.back()[F];70 calculateDroppedStatsAndPrint(DbgVariables, FuncName, PassID, FuncOrModName,71 PassLevel, Func);72}73 74void DroppedVariableStatsIR::runOnModule(StringRef PassID, const Module *M,75 bool Before) {76 for (auto &F : *M) {77 runOnFunction(PassID, &F, Before);78 }79}80 81void DroppedVariableStatsIR::calculateDroppedVarStatsOnModule(82 const Module *M, StringRef PassID, StringRef FuncOrModName,83 StringRef PassLevel) {84 for (auto &F : *M) {85 calculateDroppedVarStatsOnFunction(&F, PassID, FuncOrModName, PassLevel);86 }87}88 89void DroppedVariableStatsIR::registerCallbacks(90 PassInstrumentationCallbacks &PIC) {91 if (!DroppedVariableStatsEnabled)92 return;93 94 PIC.registerBeforeNonSkippedPassCallback(95 [this](StringRef P, Any IR) { return runBeforePass(P, IR); });96 PIC.registerAfterPassCallback(97 [this](StringRef P, Any IR, const PreservedAnalyses &PA) {98 return runAfterPass(P, IR);99 });100 PIC.registerAfterPassInvalidatedCallback(101 [this](StringRef P, const PreservedAnalyses &PA) { return cleanup(); });102}103 104void DroppedVariableStatsIR::visitEveryInstruction(105 unsigned &DroppedCount, DenseMap<VarID, DILocation *> &InlinedAtsMap,106 VarID Var) {107 const DIScope *DbgValScope = std::get<0>(Var);108 for (const auto &I : instructions(Func)) {109 auto *DbgLoc = I.getDebugLoc().get();110 if (!DbgLoc)111 continue;112 if (updateDroppedCount(DbgLoc, DbgLoc->getScope(), DbgValScope,113 InlinedAtsMap, Var, DroppedCount))114 break;115 }116}117 118void DroppedVariableStatsIR::visitEveryDebugRecord(119 DenseSet<VarID> &VarIDSet,120 DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,121 StringRef FuncName, bool Before) {122 for (const auto &I : instructions(Func)) {123 for (DbgRecord &DR : I.getDbgRecordRange()) {124 if (auto *Dbg = dyn_cast<DbgVariableRecord>(&DR)) {125 auto *DbgVar = Dbg->getVariable();126 auto DbgLoc = DR.getDebugLoc();127 populateVarIDSetAndInlinedMap(DbgVar, DbgLoc, VarIDSet, InlinedAtsMap,128 FuncName, Before);129 }130 }131 }132}133