LLVM 19.0.0git
Classes | Namespaces | Macros | Variables
InstrRefBasedImpl.cpp File Reference

This is a separate implementation of LiveDebugValues, see LiveDebugValues.cpp and VarLocBasedImpl.cpp for more information. More...

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GenericIteratedDominanceFrontier.h"
#include "llvm/Support/TypeSize.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/SSAUpdaterImpl.h"
#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdint>
#include <functional>
#include <queue>
#include <tuple>
#include <utility>
#include <vector>
#include "InstrRefBasedImpl.h"
#include "LiveDebugValues.h"
#include <optional>

Go to the source code of this file.


class  TransferTracker
 Tracker for converting machine value locations and variable values into variable locations (the output of LiveDebugValues), recorded as DBG_VALUEs specifying block live-in locations and transfers within blocks. More...
struct  TransferTracker::Transfer
 Record of all changes in variable locations at a block position. More...
struct  TransferTracker::ResolvedDbgValue
 Stores the resolved operands (machine locations and constants) and qualifying meta-information needed to construct a concrete DBG_VALUE-like instruction. More...
struct  TransferTracker::UseBeforeDef
 Record of a use-before-def: created when a value that's live-in to the current block isn't available in any machine location, but it will be defined in this block. More...
class  TransferTracker::LocationAndQuality
class  llvm::SSAUpdaterTraits< LDVSSAUpdater >
 Template specialization to give SSAUpdater access to CFG and value information. More...
class  llvm::SSAUpdaterTraits< LDVSSAUpdater >::PHI_iterator
 Iterator for PHI operands. More...


namespace  llvm
 This is an optimization pass for GlobalISel generic memory operations.


#define DEBUG_TYPE   "livedebugvalues"


static cl::opt< boolEmulateOldLDV ("emulate-old-livedebugvalues", cl::Hidden, cl::desc("Act like old LiveDebugValues did"), cl::init(false))
static cl::opt< unsignedStackWorkingSetLimit ("livedebugvalues-max-stack-slots", cl::Hidden, cl::desc("livedebugvalues-stack-ws-limit"), cl::init(250))

Detailed Description

This is a separate implementation of LiveDebugValues, see LiveDebugValues.cpp and VarLocBasedImpl.cpp for more information.

This pass propagates variable locations between basic blocks, resolving control flow conflicts between them. The problem is SSA construction, where each debug instruction assigns the value that a variable has, and every instruction where the variable is in scope uses that variable. The resulting map of instruction-to-value is then translated into a register (or spill) location for each variable over each instruction.

The primary difference from normal SSA construction is that we cannot create PHI values that contain variable values. CodeGen has already completed, and we can't alter it just to make debug-info complete. Thus: we can identify function positions where we would like a PHI value for a variable, but must search the MachineFunction to see whether such a PHI is available. If no such PHI exists, the variable location must be dropped.

To achieve this, we perform two kinds of analysis. First, we identify every value defined by every instruction (ignoring those that only move another value), then re-compute an SSA-form representation of the MachineFunction, using value propagation to eliminate any un-necessary PHI values. This gives us a map of every value computed in the function, and its location within the register file / stack.

Secondly, for each variable we perform the same analysis, where each debug instruction is considered a def, and every instruction where the variable is in lexical scope as a use. Value propagation is used again to eliminate any un-necessary PHIs. This gives us a map of each variable to the value it should have in a block.

Once both are complete, we have two maps for each block:

This pass is kept efficient because the size of the first SSA problem is proportional to the working-set size of the function, which the compiler tries to keep small. (It's also proportional to the number of blocks). Additionally, we repeatedly perform the second SSA problem analysis with only the variables and blocks in a single lexical scope, exploiting their locality.


A machine location is a register or spill slot, a value is something that's defined by an instruction or PHI node, while a variable value is the value assigned to a variable. A variable location is a machine location, that must contain the appropriate variable value. A value that is a PHI node is occasionally called an mphi.

The first SSA problem is the "machine value location" problem, because we're determining which machine locations contain which values. The "locations" are constant: what's unknown is what value they contain.

The second SSA problem (the one for variables) is the "variable value problem", because it's determining what values a variable has, rather than what location those values are placed in.

TODO: Overlapping fragments Entry values Add back DEBUG statements for debugging this Collect statistics

Definition in file InstrRefBasedImpl.cpp.

Macro Definition Documentation


#define DEBUG_TYPE   "livedebugvalues"

Definition at line 137 of file InstrRefBasedImpl.cpp.

Variable Documentation

◆ EmulateOldLDV

cl::opt< bool > EmulateOldLDV("emulate-old-livedebugvalues", cl::Hidden, cl::desc("Act like old LiveDebugValues did"), cl::init(false)) ( "emulate-old-livedebugvalues"  ,
cl::Hidden  ,
cl::desc("Act like old LiveDebugValues did")  ,

◆ StackWorkingSetLimit

cl::opt< unsigned > StackWorkingSetLimit("livedebugvalues-max-stack-slots", cl::Hidden, cl::desc("livedebugvalues-stack-ws-limit"), cl::init(250)) ( "livedebugvalues-max-stack-slots"  ,
cl::Hidden  ,
cl::desc("livedebugvalues-stack-ws-limit")  ,