LLVM 18.0.0git
|
#include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
#include "LiveDebugValues/LiveDebugValues.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/UniqueVector.h"
#include "llvm/Analysis/Interval.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PrintPasses.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <assert.h>
#include <cstdint>
#include <optional>
#include <sstream>
#include <unordered_map>
Go to the source code of this file.
Classes | |
struct | llvm::DenseMapInfo< VariableID > |
class | FunctionVarLocsBuilder |
Helper class to build FunctionVarLocs, since that class isn't easy to modify. More... | |
Macros | |
#define | DEBUG_TYPE "debug-ata" |
Typedefs | |
using | DebugAggregate = std::pair< const DILocalVariable *, const DILocation * > |
A whole (unfragmented) source variable. | |
Functions | |
STATISTIC (NumDefsScanned, "Number of dbg locs that get scanned for removal") | |
STATISTIC (NumDefsRemoved, "Number of dbg locs removed") | |
STATISTIC (NumWedgesScanned, "Number of dbg wedges scanned") | |
STATISTIC (NumWedgesChanged, "Number of dbg wedges changed") | |
static std::pair< Value *, DIExpression * > | walkToAllocaAndPrependOffsetDeref (const DataLayout &DL, Value *Start, DIExpression *Expression) |
Walk backwards along constant GEPs and bitcasts to the base storage from Start as far as possible. | |
static std::optional< int64_t > | getDerefOffsetInBytes (const DIExpression *DIExpr) |
Extract the offset used in DIExpr . | |
static DebugAggregate | getAggregate (const DbgVariableIntrinsic *DII) |
static DebugAggregate | getAggregate (const DebugVariable &Var) |
static bool | shouldCoalesceFragments (Function &F) |
static DIAssignID * | getIDFromInst (const Instruction &I) |
static DIAssignID * | getIDFromMarker (const DbgAssignIntrinsic &DAI) |
const char * | locStr (AssignmentTrackingLowering::LocKind Loc) |
static bool | hasZeroSizedFragment (DbgVariableIntrinsic &DVI) |
static bool | fullyContains (DIExpression::FragmentInfo A, DIExpression::FragmentInfo B) |
Return true if A fully contains B. | |
static std::optional< at::AssignmentInfo > | getUntaggedStoreAssignmentInfo (const Instruction &I, const DataLayout &Layout) |
static AssignmentTrackingLowering::OverlapMap | buildOverlapMapAndRecordDeclares (Function &Fn, FunctionVarLocsBuilder *FnVarLocs, const DenseSet< DebugAggregate > &VarsWithStackSlot, AssignmentTrackingLowering::UntaggedStoreAssignmentMap &UntaggedStoreVars, unsigned &TrackedVariablesVectorSize) |
Build a map of {Variable x: Variables y} where all variable fragments contained within the variable fragment x are in set y. | |
static bool | removeRedundantDbgLocsUsingBackwardScan (const BasicBlock *BB, FunctionVarLocsBuilder &FnVarLocs) |
Remove redundant definitions within sequences of consecutive location defs. | |
static bool | removeRedundantDbgLocsUsingForwardScan (const BasicBlock *BB, FunctionVarLocsBuilder &FnVarLocs) |
Remove redundant location defs using a forward scan. | |
static bool | removeUndefDbgLocsFromEntryBlock (const BasicBlock *BB, FunctionVarLocsBuilder &FnVarLocs) |
static bool | removeRedundantDbgLocs (const BasicBlock *BB, FunctionVarLocsBuilder &FnVarLocs) |
static DenseSet< DebugAggregate > | findVarsWithStackSlot (Function &Fn) |
static void | analyzeFunction (Function &Fn, const DataLayout &Layout, FunctionVarLocsBuilder *FnVarLocs) |
Variables | |
static cl::opt< unsigned > | MaxNumBlocks ("debug-ata-max-blocks", cl::init(10000), cl::desc("Maximum num basic blocks before debug info dropped"), cl::Hidden) |
static cl::opt< bool > | EnableMemLocFragFill ("mem-loc-frag-fill", cl::init(true), cl::Hidden) |
Option for debugging the pass, determines if the memory location fragment filling happens after generating the variable locations. | |
static cl::opt< bool > | PrintResults ("print-debug-ata", cl::init(false), cl::Hidden) |
Print the results of the analysis. Respects -filter-print-funcs. | |
static cl::opt< cl::boolOrDefault > | CoalesceAdjacentFragmentsOpt ("debug-ata-coalesce-frags", cl::Hidden) |
Coalesce adjacent dbg locs describing memory locations that have contiguous fragments. | |
#define DEBUG_TYPE "debug-ata" |
Definition at line 33 of file AssignmentTrackingAnalysis.cpp.
using DebugAggregate = std::pair<const DILocalVariable *, const DILocation *> |
A whole (unfragmented) source variable.
Definition at line 289 of file AssignmentTrackingAnalysis.cpp.
|
static |
Definition at line 2519 of file AssignmentTrackingAnalysis.cpp.
References findVarsWithStackSlot(), removeRedundantDbgLocs(), and shouldCoalesceFragments().
Referenced by llvm::AssignmentTrackingAnalysis::runOnFunction().
|
static |
Build a map of {Variable x: Variables y} where all variable fragments contained within the variable fragment x are in set y.
This means that y does not contain all overlaps because partial overlaps are excluded.
While we're iterating over the function, add single location defs for dbg.declares to FnVarLocs
.
Variables that are interesting to this pass in are added to FnVarLocs->Variables first. TrackedVariablesVectorSize is set to the ID of the last interesting variable plus 1, meaning variables with ID 1 (inclusive) to TrackedVariablesVectorSize (exclusive) are interesting. The subsequent variables are either stack homed or fully promoted.
Finally, populate UntaggedStoreVars with a mapping of untagged stores to the stored-to variable fragments.
These tasks are bundled together to reduce the number of times we need to iterate over the function as they can be achieved together in one pass.
Definition at line 1951 of file AssignmentTrackingAnalysis.cpp.
References FunctionVarLocsBuilder::addSingleLocVar(), assert(), llvm::SmallVectorTemplateCommon< T, typename >::begin(), llvm::at::calculateFragmentIntersect(), llvm::detail::DenseSetImpl< ValueT, MapTy, ValueInfoT >::contains(), llvm::SmallVectorTemplateCommon< T, typename >::end(), fullyContains(), llvm::at::getAssignmentMarkers(), llvm::Module::getDataLayout(), llvm::Instruction::getDebugLoc(), llvm::DbgVariableIntrinsic::getExpression(), llvm::DIExpression::getFragmentInfo(), llvm::DebugVariable::getInlinedAt(), llvm::DebugLoc::getInlinedAt(), FunctionVarLocsBuilder::getNumVariables(), llvm::GlobalValue::getParent(), getUntaggedStoreAssignmentInfo(), llvm::DebugVariable::getVariable(), llvm::DbgVariableIntrinsic::getVariable(), I, Info, llvm::detail::DenseSetImpl< ValueT, MapTy, ValueInfoT >::insert(), FunctionVarLocsBuilder::insertVariable(), and llvm::SmallVectorTemplateBase< T, bool >::push_back().
|
static |
Definition at line 2502 of file AssignmentTrackingAnalysis.cpp.
References llvm::at::getAssignmentMarkers(), llvm::Instruction::getDebugLoc(), llvm::DebugLoc::getInlinedAt(), llvm::DbgVariableIntrinsic::getVariable(), and I.
Referenced by analyzeFunction().
|
static |
Return true if A fully contains B.
Definition at line 1906 of file AssignmentTrackingAnalysis.cpp.
Referenced by buildOverlapMapAndRecordDeclares().
|
static |
Definition at line 290 of file AssignmentTrackingAnalysis.cpp.
References llvm::Instruction::getDebugLoc(), llvm::DebugLoc::getInlinedAt(), and llvm::DbgVariableIntrinsic::getVariable().
Referenced by removeRedundantDbgLocsUsingBackwardScan().
|
static |
Definition at line 293 of file AssignmentTrackingAnalysis.cpp.
References llvm::DebugVariable::getInlinedAt(), and llvm::DebugVariable::getVariable().
|
static |
Extract the offset used in DIExpr
.
Returns std::nullopt if the expression doesn't explicitly describe a memory location with DW_OP_deref or if the expression is too complex to interpret.
Definition at line 247 of file AssignmentTrackingAnalysis.cpp.
References llvm::dwarf::DW_OP_LLVM_fragment, llvm::DIExpression::getElements(), llvm::DIExpression::getNumElements(), and llvm::Offset.
|
static |
Definition at line 1375 of file AssignmentTrackingAnalysis.cpp.
References I.
|
static |
Definition at line 1379 of file AssignmentTrackingAnalysis.cpp.
References llvm::DbgAssignIntrinsic::getAssignID().
|
static |
Definition at line 1921 of file AssignmentTrackingAnalysis.cpp.
References llvm::at::getAssignmentInfo(), I, and MI.
Referenced by buildOverlapMapAndRecordDeclares().
|
static |
Definition at line 1705 of file AssignmentTrackingAnalysis.cpp.
References F, llvm::DbgVariableIntrinsic::getExpression(), and llvm::DIExpression::getFragmentInfo().
Definition at line 1399 of file AssignmentTrackingAnalysis.cpp.
References llvm_unreachable.
|
static |
Definition at line 2488 of file AssignmentTrackingAnalysis.cpp.
References llvm::dbgs(), llvm::Value::getName(), llvm::BasicBlock::isEntryBlock(), LLVM_DEBUG, removeRedundantDbgLocsUsingBackwardScan(), removeRedundantDbgLocsUsingForwardScan(), and removeUndefDbgLocsFromEntryBlock().
Referenced by analyzeFunction().
|
static |
Remove redundant definitions within sequences of consecutive location defs.
This is done using a backward scan to keep the last def describing a specific variable/fragment.
This implements removeRedundantDbgInstrsUsingBackwardScan from lib/Transforms/Utils/BasicBlockUtils.cpp for locations described with FunctionVarLocsBuilder instead of with intrinsics.
Definition at line 2269 of file AssignmentTrackingAnalysis.cpp.
References llvm::SmallVectorTemplateCommon< T, typename >::begin(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::clear(), llvm::SmallVectorTemplateCommon< T, typename >::end(), llvm::DIExpression::FragmentInfo::endInBits(), llvm::BitVector::find_first_unset_in(), getAggregate(), FunctionVarLocsBuilder::getVariable(), FunctionVarLocsBuilder::getWedge(), I, llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::reverse(), llvm::BitVector::set(), FunctionVarLocsBuilder::setWedge(), llvm::DIExpression::FragmentInfo::startInBits(), and llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::try_emplace().
Referenced by removeRedundantDbgLocs().
|
static |
Remove redundant location defs using a forward scan.
This can remove a location definition that is redundant due to indicating that a variable has the same value as is already being indicated by an earlier def.
This implements removeRedundantDbgInstrsUsingForwardScan from lib/Transforms/Utils/BasicBlockUtils.cpp for locations described with FunctionVarLocsBuilder instead of with intrinsics
Definition at line 2355 of file AssignmentTrackingAnalysis.cpp.
References llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::end(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::find(), llvm::DebugVariable::getVariable(), FunctionVarLocsBuilder::getVariable(), FunctionVarLocsBuilder::getWedge(), I, llvm::SmallVectorTemplateBase< T, bool >::push_back(), and FunctionVarLocsBuilder::setWedge().
Referenced by removeRedundantDbgLocs().
|
static |
Definition at line 2408 of file AssignmentTrackingAnalysis.cpp.
References A, llvm::any_of(), assert(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::end(), llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::find(), llvm::DebugVariable::getVariable(), FunctionVarLocsBuilder::getVariable(), FunctionVarLocsBuilder::getWedge(), I, llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::insert(), llvm::BasicBlock::isEntryBlock(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), and FunctionVarLocsBuilder::setWedge().
Referenced by removeRedundantDbgLocs().
Definition at line 297 of file AssignmentTrackingAnalysis.cpp.
References llvm::cl::BOU_FALSE, llvm::cl::BOU_TRUE, llvm::cl::BOU_UNSET, CoalesceAdjacentFragmentsOpt, llvm::debuginfoShouldUseDebugInstrRef(), F, and llvm_unreachable.
Referenced by analyzeFunction().
STATISTIC | ( | NumDefsRemoved | , |
"Number of dbg locs removed" | |||
) |
STATISTIC | ( | NumDefsScanned | , |
"Number of dbg locs that get scanned for removal" | |||
) |
STATISTIC | ( | NumWedgesChanged | , |
"Number of dbg wedges changed" | |||
) |
STATISTIC | ( | NumWedgesScanned | , |
"Number of dbg wedges scanned" | |||
) |
|
static |
Walk backwards along constant GEPs and bitcasts to the base storage from Start
as far as possible.
Prepend \Expression with the offset and append it with a DW_OP_deref that haes been implicit until now. Returns the walked-to value and modified expression.
Definition at line 228 of file AssignmentTrackingAnalysis.cpp.
References llvm::DIExpression::append(), DL, End, llvm::APInt::getBoolValue(), llvm::APInt::getZExtValue(), and llvm::DIExpression::prependOpcodes().
|
static |
Coalesce adjacent dbg locs describing memory locations that have contiguous fragments.
This reduces the cost of LiveDebugValues which does SSA construction for each explicitly stated variable fragment.
Referenced by shouldCoalesceFragments().
|
static |
Option for debugging the pass, determines if the memory location fragment filling happens after generating the variable locations.
|
static |
|
static |
Print the results of the analysis. Respects -filter-print-funcs.
Referenced by llvm::AssignmentTrackingAnalysis::runOnFunction().