aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugVariables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/LiveDebugVariables.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/LiveDebugVariables.cpp1971
1 files changed, 1971 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugVariables.cpp b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugVariables.cpp
new file mode 100644
index 000000000000..7cb90af5ff17
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -0,0 +1,1971 @@
+//===- LiveDebugVariables.cpp - Tracking debug info variables -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveDebugVariables analysis.
+//
+// Remove all DBG_VALUE instructions referencing virtual registers and replace
+// them with a data structure tracking where live user variables are kept - in a
+// virtual register or in a stack slot.
+//
+// Allow the data structure to be updated during register allocation when values
+// are moved between registers and stack slots. Finally emit new DBG_VALUE
+// instructions after register allocation is complete.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LiveDebugVariables.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/CodeGen/LexicalScopes.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/LiveIntervals.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/VirtRegMap.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Function.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <map>
+#include <memory>
+#include <optional>
+#include <utility>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "livedebugvars"
+
+static cl::opt<bool>
+EnableLDV("live-debug-variables", cl::init(true),
+ cl::desc("Enable the live debug variables pass"), cl::Hidden);
+
+STATISTIC(NumInsertedDebugValues, "Number of DBG_VALUEs inserted");
+STATISTIC(NumInsertedDebugLabels, "Number of DBG_LABELs inserted");
+
+char LiveDebugVariables::ID = 0;
+
+INITIALIZE_PASS_BEGIN(LiveDebugVariables, DEBUG_TYPE,
+ "Debug Variable Analysis", false, false)
+INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
+INITIALIZE_PASS_END(LiveDebugVariables, DEBUG_TYPE,
+ "Debug Variable Analysis", false, false)
+
+void LiveDebugVariables::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<MachineDominatorTree>();
+ AU.addRequiredTransitive<LiveIntervals>();
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+LiveDebugVariables::LiveDebugVariables() : MachineFunctionPass(ID) {
+ initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry());
+}
+
+enum : unsigned { UndefLocNo = ~0U };
+
+namespace {
+/// Describes a debug variable value by location number and expression along
+/// with some flags about the original usage of the location.
+class DbgVariableValue {
+public:
+ DbgVariableValue(ArrayRef<unsigned> NewLocs, bool WasIndirect, bool WasList,
+ const DIExpression &Expr)
+ : WasIndirect(WasIndirect), WasList(WasList), Expression(&Expr) {
+ assert(!(WasIndirect && WasList) &&
+ "DBG_VALUE_LISTs should not be indirect.");
+ SmallVector<unsigned> LocNoVec;
+ for (unsigned LocNo : NewLocs) {
+ auto It = find(LocNoVec, LocNo);
+ if (It == LocNoVec.end())
+ LocNoVec.push_back(LocNo);
+ else {
+ // Loc duplicates an element in LocNos; replace references to Op
+ // with references to the duplicating element.
+ unsigned OpIdx = LocNoVec.size();
+ unsigned DuplicatingIdx = std::distance(LocNoVec.begin(), It);
+ Expression =
+ DIExpression::replaceArg(Expression, OpIdx, DuplicatingIdx);
+ }
+ }
+ // FIXME: Debug values referencing 64+ unique machine locations are rare and
+ // currently unsupported for performance reasons. If we can verify that
+ // performance is acceptable for such debug values, we can increase the
+ // bit-width of LocNoCount to 14 to enable up to 16384 unique machine
+ // locations. We will also need to verify that this does not cause issues
+ // with LiveDebugVariables' use of IntervalMap.
+ if (LocNoVec.size() < 64) {
+ LocNoCount = LocNoVec.size();
+ if (LocNoCount > 0) {
+ LocNos = std::make_unique<unsigned[]>(LocNoCount);
+ std::copy(LocNoVec.begin(), LocNoVec.end(), loc_nos_begin());
+ }
+ } else {
+ LLVM_DEBUG(dbgs() << "Found debug value with 64+ unique machine "
+ "locations, dropping...\n");
+ LocNoCount = 1;
+ // Turn this into an undef debug value list; right now, the simplest form
+ // of this is an expression with one arg, and an undef debug operand.
+ Expression =
+ DIExpression::get(Expr.getContext(), {dwarf::DW_OP_LLVM_arg, 0});
+ if (auto FragmentInfoOpt = Expr.getFragmentInfo())
+ Expression = *DIExpression::createFragmentExpression(
+ Expression, FragmentInfoOpt->OffsetInBits,
+ FragmentInfoOpt->SizeInBits);
+ LocNos = std::make_unique<unsigned[]>(LocNoCount);
+ LocNos[0] = UndefLocNo;
+ }
+ }
+
+ DbgVariableValue() : LocNoCount(0), WasIndirect(false), WasList(false) {}
+ DbgVariableValue(const DbgVariableValue &Other)
+ : LocNoCount(Other.LocNoCount), WasIndirect(Other.getWasIndirect()),
+ WasList(Other.getWasList()), Expression(Other.getExpression()) {
+ if (Other.getLocNoCount()) {
+ LocNos.reset(new unsigned[Other.getLocNoCount()]);
+ std::copy(Other.loc_nos_begin(), Other.loc_nos_end(), loc_nos_begin());
+ }
+ }
+
+ DbgVariableValue &operator=(const DbgVariableValue &Other) {
+ if (this == &Other)
+ return *this;
+ if (Other.getLocNoCount()) {
+ LocNos.reset(new unsigned[Other.getLocNoCount()]);
+ std::copy(Other.loc_nos_begin(), Other.loc_nos_end(), loc_nos_begin());
+ } else {
+ LocNos.release();
+ }
+ LocNoCount = Other.getLocNoCount();
+ WasIndirect = Other.getWasIndirect();
+ WasList = Other.getWasList();
+ Expression = Other.getExpression();
+ return *this;
+ }
+
+ const DIExpression *getExpression() const { return Expression; }
+ uint8_t getLocNoCount() const { return LocNoCount; }
+ bool containsLocNo(unsigned LocNo) const {
+ return is_contained(loc_nos(), LocNo);
+ }
+ bool getWasIndirect() const { return WasIndirect; }
+ bool getWasList() const { return WasList; }
+ bool isUndef() const { return LocNoCount == 0 || containsLocNo(UndefLocNo); }
+
+ DbgVariableValue decrementLocNosAfterPivot(unsigned Pivot) const {
+ SmallVector<unsigned, 4> NewLocNos;
+ for (unsigned LocNo : loc_nos())
+ NewLocNos.push_back(LocNo != UndefLocNo && LocNo > Pivot ? LocNo - 1
+ : LocNo);
+ return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);
+ }
+
+ DbgVariableValue remapLocNos(ArrayRef<unsigned> LocNoMap) const {
+ SmallVector<unsigned> NewLocNos;
+ for (unsigned LocNo : loc_nos())
+ // Undef values don't exist in locations (and thus not in LocNoMap
+ // either) so skip over them. See getLocationNo().
+ NewLocNos.push_back(LocNo == UndefLocNo ? UndefLocNo : LocNoMap[LocNo]);
+ return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);
+ }
+
+ DbgVariableValue changeLocNo(unsigned OldLocNo, unsigned NewLocNo) const {
+ SmallVector<unsigned> NewLocNos;
+ NewLocNos.assign(loc_nos_begin(), loc_nos_end());
+ auto OldLocIt = find(NewLocNos, OldLocNo);
+ assert(OldLocIt != NewLocNos.end() && "Old location must be present.");
+ *OldLocIt = NewLocNo;
+ return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);
+ }
+
+ bool hasLocNoGreaterThan(unsigned LocNo) const {
+ return any_of(loc_nos(),
+ [LocNo](unsigned ThisLocNo) { return ThisLocNo > LocNo; });
+ }
+
+ void printLocNos(llvm::raw_ostream &OS) const {
+ for (const unsigned &Loc : loc_nos())
+ OS << (&Loc == loc_nos_begin() ? " " : ", ") << Loc;
+ }
+
+ friend inline bool operator==(const DbgVariableValue &LHS,
+ const DbgVariableValue &RHS) {
+ if (std::tie(LHS.LocNoCount, LHS.WasIndirect, LHS.WasList,
+ LHS.Expression) !=
+ std::tie(RHS.LocNoCount, RHS.WasIndirect, RHS.WasList, RHS.Expression))
+ return false;
+ return std::equal(LHS.loc_nos_begin(), LHS.loc_nos_end(),
+ RHS.loc_nos_begin());
+ }
+
+ friend inline bool operator!=(const DbgVariableValue &LHS,
+ const DbgVariableValue &RHS) {
+ return !(LHS == RHS);
+ }
+
+ unsigned *loc_nos_begin() { return LocNos.get(); }
+ const unsigned *loc_nos_begin() const { return LocNos.get(); }
+ unsigned *loc_nos_end() { return LocNos.get() + LocNoCount; }
+ const unsigned *loc_nos_end() const { return LocNos.get() + LocNoCount; }
+ ArrayRef<unsigned> loc_nos() const {
+ return ArrayRef<unsigned>(LocNos.get(), LocNoCount);
+ }
+
+private:
+ // IntervalMap requires the value object to be very small, to the extent
+ // that we do not have enough room for an std::vector. Using a C-style array
+ // (with a unique_ptr wrapper for convenience) allows us to optimize for this
+ // specific case by packing the array size into only 6 bits (it is highly
+ // unlikely that any debug value will need 64+ locations).
+ std::unique_ptr<unsigned[]> LocNos;
+ uint8_t LocNoCount : 6;
+ bool WasIndirect : 1;
+ bool WasList : 1;
+ const DIExpression *Expression = nullptr;
+};
+} // namespace
+
+/// Map of where a user value is live to that value.
+using LocMap = IntervalMap<SlotIndex, DbgVariableValue, 4>;
+
+/// Map of stack slot offsets for spilled locations.
+/// Non-spilled locations are not added to the map.
+using SpillOffsetMap = DenseMap<unsigned, unsigned>;
+
+/// Cache to save the location where it can be used as the starting
+/// position as input for calling MachineBasicBlock::SkipPHIsLabelsAndDebug.
+/// This is to prevent MachineBasicBlock::SkipPHIsLabelsAndDebug from
+/// repeatedly searching the same set of PHIs/Labels/Debug instructions
+/// if it is called many times for the same block.
+using BlockSkipInstsMap =
+ DenseMap<MachineBasicBlock *, MachineBasicBlock::iterator>;
+
+namespace {
+
+class LDVImpl;
+
+/// A user value is a part of a debug info user variable.
+///
+/// A DBG_VALUE instruction notes that (a sub-register of) a virtual register
+/// holds part of a user variable. The part is identified by a byte offset.
+///
+/// UserValues are grouped into equivalence classes for easier searching. Two
+/// user values are related if they are held by the same virtual register. The
+/// equivalence class is the transitive closure of that relation.
+class UserValue {
+ const DILocalVariable *Variable; ///< The debug info variable we are part of.
+ /// The part of the variable we describe.
+ const std::optional<DIExpression::FragmentInfo> Fragment;
+ DebugLoc dl; ///< The debug location for the variable. This is
+ ///< used by dwarf writer to find lexical scope.
+ UserValue *leader; ///< Equivalence class leader.
+ UserValue *next = nullptr; ///< Next value in equivalence class, or null.
+
+ /// Numbered locations referenced by locmap.
+ SmallVector<MachineOperand, 4> locations;
+
+ /// Map of slot indices where this value is live.
+ LocMap locInts;
+
+ /// Set of interval start indexes that have been trimmed to the
+ /// lexical scope.
+ SmallSet<SlotIndex, 2> trimmedDefs;
+
+ /// Insert a DBG_VALUE into MBB at Idx for DbgValue.
+ void insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
+ SlotIndex StopIdx, DbgVariableValue DbgValue,
+ ArrayRef<bool> LocSpills,
+ ArrayRef<unsigned> SpillOffsets, LiveIntervals &LIS,
+ const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ BlockSkipInstsMap &BBSkipInstsMap);
+
+ /// Replace OldLocNo ranges with NewRegs ranges where NewRegs
+ /// is live. Returns true if any changes were made.
+ bool splitLocation(unsigned OldLocNo, ArrayRef<Register> NewRegs,
+ LiveIntervals &LIS);
+
+public:
+ /// Create a new UserValue.
+ UserValue(const DILocalVariable *var,
+ std::optional<DIExpression::FragmentInfo> Fragment, DebugLoc L,
+ LocMap::Allocator &alloc)
+ : Variable(var), Fragment(Fragment), dl(std::move(L)), leader(this),
+ locInts(alloc) {}
+
+ /// Get the leader of this value's equivalence class.
+ UserValue *getLeader() {
+ UserValue *l = leader;
+ while (l != l->leader)
+ l = l->leader;
+ return leader = l;
+ }
+
+ /// Return the next UserValue in the equivalence class.
+ UserValue *getNext() const { return next; }
+
+ /// Merge equivalence classes.
+ static UserValue *merge(UserValue *L1, UserValue *L2) {
+ L2 = L2->getLeader();
+ if (!L1)
+ return L2;
+ L1 = L1->getLeader();
+ if (L1 == L2)
+ return L1;
+ // Splice L2 before L1's members.
+ UserValue *End = L2;
+ while (End->next) {
+ End->leader = L1;
+ End = End->next;
+ }
+ End->leader = L1;
+ End->next = L1->next;
+ L1->next = L2;
+ return L1;
+ }
+
+ /// Return the location number that matches Loc.
+ ///
+ /// For undef values we always return location number UndefLocNo without
+ /// inserting anything in locations. Since locations is a vector and the
+ /// location number is the position in the vector and UndefLocNo is ~0,
+ /// we would need a very big vector to put the value at the right position.
+ unsigned getLocationNo(const MachineOperand &LocMO) {
+ if (LocMO.isReg()) {
+ if (LocMO.getReg() == 0)
+ return UndefLocNo;
+ // For register locations we dont care about use/def and other flags.
+ for (unsigned i = 0, e = locations.size(); i != e; ++i)
+ if (locations[i].isReg() &&
+ locations[i].getReg() == LocMO.getReg() &&
+ locations[i].getSubReg() == LocMO.getSubReg())
+ return i;
+ } else
+ for (unsigned i = 0, e = locations.size(); i != e; ++i)
+ if (LocMO.isIdenticalTo(locations[i]))
+ return i;
+ locations.push_back(LocMO);
+ // We are storing a MachineOperand outside a MachineInstr.
+ locations.back().clearParent();
+ // Don't store def operands.
+ if (locations.back().isReg()) {
+ if (locations.back().isDef())
+ locations.back().setIsDead(false);
+ locations.back().setIsUse();
+ }
+ return locations.size() - 1;
+ }
+
+ /// Remove (recycle) a location number. If \p LocNo still is used by the
+ /// locInts nothing is done.
+ void removeLocationIfUnused(unsigned LocNo) {
+ // Bail out if LocNo still is used.
+ for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) {
+ const DbgVariableValue &DbgValue = I.value();
+ if (DbgValue.containsLocNo(LocNo))
+ return;
+ }
+ // Remove the entry in the locations vector, and adjust all references to
+ // location numbers above the removed entry.
+ locations.erase(locations.begin() + LocNo);
+ for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) {
+ const DbgVariableValue &DbgValue = I.value();
+ if (DbgValue.hasLocNoGreaterThan(LocNo))
+ I.setValueUnchecked(DbgValue.decrementLocNosAfterPivot(LocNo));
+ }
+ }
+
+ /// Ensure that all virtual register locations are mapped.
+ void mapVirtRegs(LDVImpl *LDV);
+
+ /// Add a definition point to this user value.
+ void addDef(SlotIndex Idx, ArrayRef<MachineOperand> LocMOs, bool IsIndirect,
+ bool IsList, const DIExpression &Expr) {
+ SmallVector<unsigned> Locs;
+ for (const MachineOperand &Op : LocMOs)
+ Locs.push_back(getLocationNo(Op));
+ DbgVariableValue DbgValue(Locs, IsIndirect, IsList, Expr);
+ // Add a singular (Idx,Idx) -> value mapping.
+ LocMap::iterator I = locInts.find(Idx);
+ if (!I.valid() || I.start() != Idx)
+ I.insert(Idx, Idx.getNextSlot(), std::move(DbgValue));
+ else
+ // A later DBG_VALUE at the same SlotIndex overrides the old location.
+ I.setValue(std::move(DbgValue));
+ }
+
+ /// Extend the current definition as far as possible down.
+ ///
+ /// Stop when meeting an existing def or when leaving the live
+ /// range of VNI. End points where VNI is no longer live are added to Kills.
+ ///
+ /// We only propagate DBG_VALUES locally here. LiveDebugValues performs a
+ /// data-flow analysis to propagate them beyond basic block boundaries.
+ ///
+ /// \param Idx Starting point for the definition.
+ /// \param DbgValue value to propagate.
+ /// \param LiveIntervalInfo For each location number key in this map,
+ /// restricts liveness to where the LiveRange has the value equal to the\
+ /// VNInfo.
+ /// \param [out] Kills Append end points of VNI's live range to Kills.
+ /// \param LIS Live intervals analysis.
+ void
+ extendDef(SlotIndex Idx, DbgVariableValue DbgValue,
+ SmallDenseMap<unsigned, std::pair<LiveRange *, const VNInfo *>>
+ &LiveIntervalInfo,
+ std::optional<std::pair<SlotIndex, SmallVector<unsigned>>> &Kills,
+ LiveIntervals &LIS);
+
+ /// The value in LI may be copies to other registers. Determine if
+ /// any of the copies are available at the kill points, and add defs if
+ /// possible.
+ ///
+ /// \param DbgValue Location number of LI->reg, and DIExpression.
+ /// \param LocIntervals Scan for copies of the value for each location in the
+ /// corresponding LiveInterval->reg.
+ /// \param KilledAt The point where the range of DbgValue could be extended.
+ /// \param [in,out] NewDefs Append (Idx, DbgValue) of inserted defs here.
+ void addDefsFromCopies(
+ DbgVariableValue DbgValue,
+ SmallVectorImpl<std::pair<unsigned, LiveInterval *>> &LocIntervals,
+ SlotIndex KilledAt,
+ SmallVectorImpl<std::pair<SlotIndex, DbgVariableValue>> &NewDefs,
+ MachineRegisterInfo &MRI, LiveIntervals &LIS);
+
+ /// Compute the live intervals of all locations after collecting all their
+ /// def points.
+ void computeIntervals(MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
+ LiveIntervals &LIS, LexicalScopes &LS);
+
+ /// Replace OldReg ranges with NewRegs ranges where NewRegs is
+ /// live. Returns true if any changes were made.
+ bool splitRegister(Register OldReg, ArrayRef<Register> NewRegs,
+ LiveIntervals &LIS);
+
+ /// Rewrite virtual register locations according to the provided virtual
+ /// register map. Record the stack slot offsets for the locations that
+ /// were spilled.
+ void rewriteLocations(VirtRegMap &VRM, const MachineFunction &MF,
+ const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ SpillOffsetMap &SpillOffsets);
+
+ /// Recreate DBG_VALUE instruction from data structures.
+ void emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
+ const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ const SpillOffsetMap &SpillOffsets,
+ BlockSkipInstsMap &BBSkipInstsMap);
+
+ /// Return DebugLoc of this UserValue.
+ const DebugLoc &getDebugLoc() { return dl; }
+
+ void print(raw_ostream &, const TargetRegisterInfo *);
+};
+
+/// A user label is a part of a debug info user label.
+class UserLabel {
+ const DILabel *Label; ///< The debug info label we are part of.
+ DebugLoc dl; ///< The debug location for the label. This is
+ ///< used by dwarf writer to find lexical scope.
+ SlotIndex loc; ///< Slot used by the debug label.
+
+ /// Insert a DBG_LABEL into MBB at Idx.
+ void insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx,
+ LiveIntervals &LIS, const TargetInstrInfo &TII,
+ BlockSkipInstsMap &BBSkipInstsMap);
+
+public:
+ /// Create a new UserLabel.
+ UserLabel(const DILabel *label, DebugLoc L, SlotIndex Idx)
+ : Label(label), dl(std::move(L)), loc(Idx) {}
+
+ /// Does this UserLabel match the parameters?
+ bool matches(const DILabel *L, const DILocation *IA,
+ const SlotIndex Index) const {
+ return Label == L && dl->getInlinedAt() == IA && loc == Index;
+ }
+
+ /// Recreate DBG_LABEL instruction from data structures.
+ void emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII,
+ BlockSkipInstsMap &BBSkipInstsMap);
+
+ /// Return DebugLoc of this UserLabel.
+ const DebugLoc &getDebugLoc() { return dl; }
+
+ void print(raw_ostream &, const TargetRegisterInfo *);
+};
+
+/// Implementation of the LiveDebugVariables pass.
+class LDVImpl {
+ LiveDebugVariables &pass;
+ LocMap::Allocator allocator;
+ MachineFunction *MF = nullptr;
+ LiveIntervals *LIS;
+ const TargetRegisterInfo *TRI;
+
+ /// Position and VReg of a PHI instruction during register allocation.
+ struct PHIValPos {
+ SlotIndex SI; /// Slot where this PHI occurs.
+ Register Reg; /// VReg this PHI occurs in.
+ unsigned SubReg; /// Qualifiying subregister for Reg.
+ };
+
+ /// Map from debug instruction number to PHI position during allocation.
+ std::map<unsigned, PHIValPos> PHIValToPos;
+ /// Index of, for each VReg, which debug instruction numbers and corresponding
+ /// PHIs are sensitive to splitting. Each VReg may have multiple PHI defs,
+ /// at different positions.
+ DenseMap<Register, std::vector<unsigned>> RegToPHIIdx;
+
+ /// Record for any debug instructions unlinked from their blocks during
+ /// regalloc. Stores the instr and it's location, so that they can be
+ /// re-inserted after regalloc is over.
+ struct InstrPos {
+ MachineInstr *MI; ///< Debug instruction, unlinked from it's block.
+ SlotIndex Idx; ///< Slot position where MI should be re-inserted.
+ MachineBasicBlock *MBB; ///< Block that MI was in.
+ };
+
+ /// Collection of stored debug instructions, preserved until after regalloc.
+ SmallVector<InstrPos, 32> StashedDebugInstrs;
+
+ /// Whether emitDebugValues is called.
+ bool EmitDone = false;
+
+ /// Whether the machine function is modified during the pass.
+ bool ModifiedMF = false;
+
+ /// All allocated UserValue instances.
+ SmallVector<std::unique_ptr<UserValue>, 8> userValues;
+
+ /// All allocated UserLabel instances.
+ SmallVector<std::unique_ptr<UserLabel>, 2> userLabels;
+
+ /// Map virtual register to eq class leader.
+ using VRMap = DenseMap<unsigned, UserValue *>;
+ VRMap virtRegToEqClass;
+
+ /// Map to find existing UserValue instances.
+ using UVMap = DenseMap<DebugVariable, UserValue *>;
+ UVMap userVarMap;
+
+ /// Find or create a UserValue.
+ UserValue *getUserValue(const DILocalVariable *Var,
+ std::optional<DIExpression::FragmentInfo> Fragment,
+ const DebugLoc &DL);
+
+ /// Find the EC leader for VirtReg or null.
+ UserValue *lookupVirtReg(Register VirtReg);
+
+ /// Add DBG_VALUE instruction to our maps.
+ ///
+ /// \param MI DBG_VALUE instruction
+ /// \param Idx Last valid SLotIndex before instruction.
+ ///
+ /// \returns True if the DBG_VALUE instruction should be deleted.
+ bool handleDebugValue(MachineInstr &MI, SlotIndex Idx);
+
+ /// Track variable location debug instructions while using the instruction
+ /// referencing implementation. Such debug instructions do not need to be
+ /// updated during regalloc because they identify instructions rather than
+ /// register locations. However, they needs to be removed from the
+ /// MachineFunction during regalloc, then re-inserted later, to avoid
+ /// disrupting the allocator.
+ ///
+ /// \param MI Any DBG_VALUE / DBG_INSTR_REF / DBG_PHI instruction
+ /// \param Idx Last valid SlotIndex before instruction
+ ///
+ /// \returns Iterator to continue processing from after unlinking.
+ MachineBasicBlock::iterator handleDebugInstr(MachineInstr &MI, SlotIndex Idx);
+
+ /// Add DBG_LABEL instruction to UserLabel.
+ ///
+ /// \param MI DBG_LABEL instruction
+ /// \param Idx Last valid SlotIndex before instruction.
+ ///
+ /// \returns True if the DBG_LABEL instruction should be deleted.
+ bool handleDebugLabel(MachineInstr &MI, SlotIndex Idx);
+
+ /// Collect and erase all DBG_VALUE instructions, adding a UserValue def
+ /// for each instruction.
+ ///
+ /// \param mf MachineFunction to be scanned.
+ /// \param InstrRef Whether to operate in instruction referencing mode. If
+ /// true, most of LiveDebugVariables doesn't run.
+ ///
+ /// \returns True if any debug values were found.
+ bool collectDebugValues(MachineFunction &mf, bool InstrRef);
+
+ /// Compute the live intervals of all user values after collecting all
+ /// their def points.
+ void computeIntervals();
+
+public:
+ LDVImpl(LiveDebugVariables *ps) : pass(*ps) {}
+
+ bool runOnMachineFunction(MachineFunction &mf, bool InstrRef);
+
+ /// Release all memory.
+ void clear() {
+ MF = nullptr;
+ PHIValToPos.clear();
+ RegToPHIIdx.clear();
+ StashedDebugInstrs.clear();
+ userValues.clear();
+ userLabels.clear();
+ virtRegToEqClass.clear();
+ userVarMap.clear();
+ // Make sure we call emitDebugValues if the machine function was modified.
+ assert((!ModifiedMF || EmitDone) &&
+ "Dbg values are not emitted in LDV");
+ EmitDone = false;
+ ModifiedMF = false;
+ }
+
+ /// Map virtual register to an equivalence class.
+ void mapVirtReg(Register VirtReg, UserValue *EC);
+
+ /// Replace any PHI referring to OldReg with its corresponding NewReg, if
+ /// present.
+ void splitPHIRegister(Register OldReg, ArrayRef<Register> NewRegs);
+
+ /// Replace all references to OldReg with NewRegs.
+ void splitRegister(Register OldReg, ArrayRef<Register> NewRegs);
+
+ /// Recreate DBG_VALUE instruction from data structures.
+ void emitDebugValues(VirtRegMap *VRM);
+
+ void print(raw_ostream&);
+};
+
+} // end anonymous namespace
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+static void printDebugLoc(const DebugLoc &DL, raw_ostream &CommentOS,
+ const LLVMContext &Ctx) {
+ if (!DL)
+ return;
+
+ auto *Scope = cast<DIScope>(DL.getScope());
+ // Omit the directory, because it's likely to be long and uninteresting.
+ CommentOS << Scope->getFilename();
+ CommentOS << ':' << DL.getLine();
+ if (DL.getCol() != 0)
+ CommentOS << ':' << DL.getCol();
+
+ DebugLoc InlinedAtDL = DL.getInlinedAt();
+ if (!InlinedAtDL)
+ return;
+
+ CommentOS << " @[ ";
+ printDebugLoc(InlinedAtDL, CommentOS, Ctx);
+ CommentOS << " ]";
+}
+
+static void printExtendedName(raw_ostream &OS, const DINode *Node,
+ const DILocation *DL) {
+ const LLVMContext &Ctx = Node->getContext();
+ StringRef Res;
+ unsigned Line = 0;
+ if (const auto *V = dyn_cast<const DILocalVariable>(Node)) {
+ Res = V->getName();
+ Line = V->getLine();
+ } else if (const auto *L = dyn_cast<const DILabel>(Node)) {
+ Res = L->getName();
+ Line = L->getLine();
+ }
+
+ if (!Res.empty())
+ OS << Res << "," << Line;
+ auto *InlinedAt = DL ? DL->getInlinedAt() : nullptr;
+ if (InlinedAt) {
+ if (DebugLoc InlinedAtDL = InlinedAt) {
+ OS << " @[";
+ printDebugLoc(InlinedAtDL, OS, Ctx);
+ OS << "]";
+ }
+ }
+}
+
+void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) {
+ OS << "!\"";
+ printExtendedName(OS, Variable, dl);
+
+ OS << "\"\t";
+ for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) {
+ OS << " [" << I.start() << ';' << I.stop() << "):";
+ if (I.value().isUndef())
+ OS << " undef";
+ else {
+ I.value().printLocNos(OS);
+ if (I.value().getWasIndirect())
+ OS << " ind";
+ else if (I.value().getWasList())
+ OS << " list";
+ }
+ }
+ for (unsigned i = 0, e = locations.size(); i != e; ++i) {
+ OS << " Loc" << i << '=';
+ locations[i].print(OS, TRI);
+ }
+ OS << '\n';
+}
+
+void UserLabel::print(raw_ostream &OS, const TargetRegisterInfo *TRI) {
+ OS << "!\"";
+ printExtendedName(OS, Label, dl);
+
+ OS << "\"\t";
+ OS << loc;
+ OS << '\n';
+}
+
+void LDVImpl::print(raw_ostream &OS) {
+ OS << "********** DEBUG VARIABLES **********\n";
+ for (auto &userValue : userValues)
+ userValue->print(OS, TRI);
+ OS << "********** DEBUG LABELS **********\n";
+ for (auto &userLabel : userLabels)
+ userLabel->print(OS, TRI);
+}
+#endif
+
+void UserValue::mapVirtRegs(LDVImpl *LDV) {
+ for (unsigned i = 0, e = locations.size(); i != e; ++i)
+ if (locations[i].isReg() && locations[i].getReg().isVirtual())
+ LDV->mapVirtReg(locations[i].getReg(), this);
+}
+
+UserValue *
+LDVImpl::getUserValue(const DILocalVariable *Var,
+ std::optional<DIExpression::FragmentInfo> Fragment,
+ const DebugLoc &DL) {
+ // FIXME: Handle partially overlapping fragments. See
+ // https://reviews.llvm.org/D70121#1849741.
+ DebugVariable ID(Var, Fragment, DL->getInlinedAt());
+ UserValue *&UV = userVarMap[ID];
+ if (!UV) {
+ userValues.push_back(
+ std::make_unique<UserValue>(Var, Fragment, DL, allocator));
+ UV = userValues.back().get();
+ }
+ return UV;
+}
+
+void LDVImpl::mapVirtReg(Register VirtReg, UserValue *EC) {
+ assert(VirtReg.isVirtual() && "Only map VirtRegs");
+ UserValue *&Leader = virtRegToEqClass[VirtReg];
+ Leader = UserValue::merge(Leader, EC);
+}
+
+UserValue *LDVImpl::lookupVirtReg(Register VirtReg) {
+ if (UserValue *UV = virtRegToEqClass.lookup(VirtReg))
+ return UV->getLeader();
+ return nullptr;
+}
+
+bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {
+ // DBG_VALUE loc, offset, variable, expr
+ // DBG_VALUE_LIST variable, expr, locs...
+ if (!MI.isDebugValue()) {
+ LLVM_DEBUG(dbgs() << "Can't handle non-DBG_VALUE*: " << MI);
+ return false;
+ }
+ if (!MI.getDebugVariableOp().isMetadata()) {
+ LLVM_DEBUG(dbgs() << "Can't handle DBG_VALUE* with invalid variable: "
+ << MI);
+ return false;
+ }
+ if (MI.isNonListDebugValue() &&
+ (MI.getNumOperands() != 4 ||
+ !(MI.getDebugOffset().isImm() || MI.getDebugOffset().isReg()))) {
+ LLVM_DEBUG(dbgs() << "Can't handle malformed DBG_VALUE: " << MI);
+ return false;
+ }
+
+ // Detect invalid DBG_VALUE instructions, with a debug-use of a virtual
+ // register that hasn't been defined yet. If we do not remove those here, then
+ // the re-insertion of the DBG_VALUE instruction after register allocation
+ // will be incorrect.
+ bool Discard = false;
+ for (const MachineOperand &Op : MI.debug_operands()) {
+ if (Op.isReg() && Op.getReg().isVirtual()) {
+ const Register Reg = Op.getReg();
+ if (!LIS->hasInterval(Reg)) {
+ // The DBG_VALUE is described by a virtual register that does not have a
+ // live interval. Discard the DBG_VALUE.
+ Discard = true;
+ LLVM_DEBUG(dbgs() << "Discarding debug info (no LIS interval): " << Idx
+ << " " << MI);
+ } else {
+ // The DBG_VALUE is only valid if either Reg is live out from Idx, or
+ // Reg is defined dead at Idx (where Idx is the slot index for the
+ // instruction preceding the DBG_VALUE).
+ const LiveInterval &LI = LIS->getInterval(Reg);
+ LiveQueryResult LRQ = LI.Query(Idx);
+ if (!LRQ.valueOutOrDead()) {
+ // We have found a DBG_VALUE with the value in a virtual register that
+ // is not live. Discard the DBG_VALUE.
+ Discard = true;
+ LLVM_DEBUG(dbgs() << "Discarding debug info (reg not live): " << Idx
+ << " " << MI);
+ }
+ }
+ }
+ }
+
+ // Get or create the UserValue for (variable,offset) here.
+ bool IsIndirect = MI.isDebugOffsetImm();
+ if (IsIndirect)
+ assert(MI.getDebugOffset().getImm() == 0 &&
+ "DBG_VALUE with nonzero offset");
+ bool IsList = MI.isDebugValueList();
+ const DILocalVariable *Var = MI.getDebugVariable();
+ const DIExpression *Expr = MI.getDebugExpression();
+ UserValue *UV = getUserValue(Var, Expr->getFragmentInfo(), MI.getDebugLoc());
+ if (!Discard)
+ UV->addDef(Idx,
+ ArrayRef<MachineOperand>(MI.debug_operands().begin(),
+ MI.debug_operands().end()),
+ IsIndirect, IsList, *Expr);
+ else {
+ MachineOperand MO = MachineOperand::CreateReg(0U, false);
+ MO.setIsDebug();
+ // We should still pass a list the same size as MI.debug_operands() even if
+ // all MOs are undef, so that DbgVariableValue can correctly adjust the
+ // expression while removing the duplicated undefs.
+ SmallVector<MachineOperand, 4> UndefMOs(MI.getNumDebugOperands(), MO);
+ UV->addDef(Idx, UndefMOs, false, IsList, *Expr);
+ }
+ return true;
+}
+
+MachineBasicBlock::iterator LDVImpl::handleDebugInstr(MachineInstr &MI,
+ SlotIndex Idx) {
+ assert(MI.isDebugValueLike() || MI.isDebugPHI());
+
+ // In instruction referencing mode, there should be no DBG_VALUE instructions
+ // that refer to virtual registers. They might still refer to constants.
+ if (MI.isDebugValueLike())
+ assert(none_of(MI.debug_operands(),
+ [](const MachineOperand &MO) {
+ return MO.isReg() && MO.getReg().isVirtual();
+ }) &&
+ "MIs should not refer to Virtual Registers in InstrRef mode.");
+
+ // Unlink the instruction, store it in the debug instructions collection.
+ auto NextInst = std::next(MI.getIterator());
+ auto *MBB = MI.getParent();
+ MI.removeFromParent();
+ StashedDebugInstrs.push_back({&MI, Idx, MBB});
+ return NextInst;
+}
+
+bool LDVImpl::handleDebugLabel(MachineInstr &MI, SlotIndex Idx) {
+ // DBG_LABEL label
+ if (MI.getNumOperands() != 1 || !MI.getOperand(0).isMetadata()) {
+ LLVM_DEBUG(dbgs() << "Can't handle " << MI);
+ return false;
+ }
+
+ // Get or create the UserLabel for label here.
+ const DILabel *Label = MI.getDebugLabel();
+ const DebugLoc &DL = MI.getDebugLoc();
+ bool Found = false;
+ for (auto const &L : userLabels) {
+ if (L->matches(Label, DL->getInlinedAt(), Idx)) {
+ Found = true;
+ break;
+ }
+ }
+ if (!Found)
+ userLabels.push_back(std::make_unique<UserLabel>(Label, DL, Idx));
+
+ return true;
+}
+
+bool LDVImpl::collectDebugValues(MachineFunction &mf, bool InstrRef) {
+ bool Changed = false;
+ for (MachineBasicBlock &MBB : mf) {
+ for (MachineBasicBlock::iterator MBBI = MBB.begin(), MBBE = MBB.end();
+ MBBI != MBBE;) {
+ // Use the first debug instruction in the sequence to get a SlotIndex
+ // for following consecutive debug instructions.
+ if (!MBBI->isDebugOrPseudoInstr()) {
+ ++MBBI;
+ continue;
+ }
+ // Debug instructions has no slot index. Use the previous
+ // non-debug instruction's SlotIndex as its SlotIndex.
+ SlotIndex Idx =
+ MBBI == MBB.begin()
+ ? LIS->getMBBStartIdx(&MBB)
+ : LIS->getInstructionIndex(*std::prev(MBBI)).getRegSlot();
+ // Handle consecutive debug instructions with the same slot index.
+ do {
+ // In instruction referencing mode, pass each instr to handleDebugInstr
+ // to be unlinked. Ignore DBG_VALUE_LISTs -- they refer to vregs, and
+ // need to go through the normal live interval splitting process.
+ if (InstrRef && (MBBI->isNonListDebugValue() || MBBI->isDebugPHI() ||
+ MBBI->isDebugRef())) {
+ MBBI = handleDebugInstr(*MBBI, Idx);
+ Changed = true;
+ // In normal debug mode, use the dedicated DBG_VALUE / DBG_LABEL handler
+ // to track things through register allocation, and erase the instr.
+ } else if ((MBBI->isDebugValue() && handleDebugValue(*MBBI, Idx)) ||
+ (MBBI->isDebugLabel() && handleDebugLabel(*MBBI, Idx))) {
+ MBBI = MBB.erase(MBBI);
+ Changed = true;
+ } else
+ ++MBBI;
+ } while (MBBI != MBBE && MBBI->isDebugOrPseudoInstr());
+ }
+ }
+ return Changed;
+}
+
+void UserValue::extendDef(
+ SlotIndex Idx, DbgVariableValue DbgValue,
+ SmallDenseMap<unsigned, std::pair<LiveRange *, const VNInfo *>>
+ &LiveIntervalInfo,
+ std::optional<std::pair<SlotIndex, SmallVector<unsigned>>> &Kills,
+ LiveIntervals &LIS) {
+ SlotIndex Start = Idx;
+ MachineBasicBlock *MBB = LIS.getMBBFromIndex(Start);
+ SlotIndex Stop = LIS.getMBBEndIdx(MBB);
+ LocMap::iterator I = locInts.find(Start);
+
+ // Limit to the intersection of the VNIs' live ranges.
+ for (auto &LII : LiveIntervalInfo) {
+ LiveRange *LR = LII.second.first;
+ assert(LR && LII.second.second && "Missing range info for Idx.");
+ LiveInterval::Segment *Segment = LR->getSegmentContaining(Start);
+ assert(Segment && Segment->valno == LII.second.second &&
+ "Invalid VNInfo for Idx given?");
+ if (Segment->end < Stop) {
+ Stop = Segment->end;
+ Kills = {Stop, {LII.first}};
+ } else if (Segment->end == Stop && Kills) {
+ // If multiple locations end at the same place, track all of them in
+ // Kills.
+ Kills->second.push_back(LII.first);
+ }
+ }
+
+ // There could already be a short def at Start.
+ if (I.valid() && I.start() <= Start) {
+ // Stop when meeting a different location or an already extended interval.
+ Start = Start.getNextSlot();
+ if (I.value() != DbgValue || I.stop() != Start) {
+ // Clear `Kills`, as we have a new def available.
+ Kills = std::nullopt;
+ return;
+ }
+ // This is a one-slot placeholder. Just skip it.
+ ++I;
+ }
+
+ // Limited by the next def.
+ if (I.valid() && I.start() < Stop) {
+ Stop = I.start();
+ // Clear `Kills`, as we have a new def available.
+ Kills = std::nullopt;
+ }
+
+ if (Start < Stop) {
+ DbgVariableValue ExtDbgValue(DbgValue);
+ I.insert(Start, Stop, std::move(ExtDbgValue));
+ }
+}
+
+void UserValue::addDefsFromCopies(
+ DbgVariableValue DbgValue,
+ SmallVectorImpl<std::pair<unsigned, LiveInterval *>> &LocIntervals,
+ SlotIndex KilledAt,
+ SmallVectorImpl<std::pair<SlotIndex, DbgVariableValue>> &NewDefs,
+ MachineRegisterInfo &MRI, LiveIntervals &LIS) {
+ // Don't track copies from physregs, there are too many uses.
+ if (any_of(LocIntervals,
+ [](auto LocI) { return !LocI.second->reg().isVirtual(); }))
+ return;
+
+ // Collect all the (vreg, valno) pairs that are copies of LI.
+ SmallDenseMap<unsigned,
+ SmallVector<std::pair<LiveInterval *, const VNInfo *>, 4>>
+ CopyValues;
+ for (auto &LocInterval : LocIntervals) {
+ unsigned LocNo = LocInterval.first;
+ LiveInterval *LI = LocInterval.second;
+ for (MachineOperand &MO : MRI.use_nodbg_operands(LI->reg())) {
+ MachineInstr *MI = MO.getParent();
+ // Copies of the full value.
+ if (MO.getSubReg() || !MI->isCopy())
+ continue;
+ Register DstReg = MI->getOperand(0).getReg();
+
+ // Don't follow copies to physregs. These are usually setting up call
+ // arguments, and the argument registers are always call clobbered. We are
+ // better off in the source register which could be a callee-saved
+ // register, or it could be spilled.
+ if (!DstReg.isVirtual())
+ continue;
+
+ // Is the value extended to reach this copy? If not, another def may be
+ // blocking it, or we are looking at a wrong value of LI.
+ SlotIndex Idx = LIS.getInstructionIndex(*MI);
+ LocMap::iterator I = locInts.find(Idx.getRegSlot(true));
+ if (!I.valid() || I.value() != DbgValue)
+ continue;
+
+ if (!LIS.hasInterval(DstReg))
+ continue;
+ LiveInterval *DstLI = &LIS.getInterval(DstReg);
+ const VNInfo *DstVNI = DstLI->getVNInfoAt(Idx.getRegSlot());
+ assert(DstVNI && DstVNI->def == Idx.getRegSlot() && "Bad copy value");
+ CopyValues[LocNo].push_back(std::make_pair(DstLI, DstVNI));
+ }
+ }
+
+ if (CopyValues.empty())
+ return;
+
+#if !defined(NDEBUG)
+ for (auto &LocInterval : LocIntervals)
+ LLVM_DEBUG(dbgs() << "Got " << CopyValues[LocInterval.first].size()
+ << " copies of " << *LocInterval.second << '\n');
+#endif
+
+ // Try to add defs of the copied values for the kill point. Check that there
+ // isn't already a def at Idx.
+ LocMap::iterator I = locInts.find(KilledAt);
+ if (I.valid() && I.start() <= KilledAt)
+ return;
+ DbgVariableValue NewValue(DbgValue);
+ for (auto &LocInterval : LocIntervals) {
+ unsigned LocNo = LocInterval.first;
+ bool FoundCopy = false;
+ for (auto &LIAndVNI : CopyValues[LocNo]) {
+ LiveInterval *DstLI = LIAndVNI.first;
+ const VNInfo *DstVNI = LIAndVNI.second;
+ if (DstLI->getVNInfoAt(KilledAt) != DstVNI)
+ continue;
+ LLVM_DEBUG(dbgs() << "Kill at " << KilledAt << " covered by valno #"
+ << DstVNI->id << " in " << *DstLI << '\n');
+ MachineInstr *CopyMI = LIS.getInstructionFromIndex(DstVNI->def);
+ assert(CopyMI && CopyMI->isCopy() && "Bad copy value");
+ unsigned NewLocNo = getLocationNo(CopyMI->getOperand(0));
+ NewValue = NewValue.changeLocNo(LocNo, NewLocNo);
+ FoundCopy = true;
+ break;
+ }
+ // If there are any killed locations we can't find a copy for, we can't
+ // extend the variable value.
+ if (!FoundCopy)
+ return;
+ }
+ I.insert(KilledAt, KilledAt.getNextSlot(), NewValue);
+ NewDefs.push_back(std::make_pair(KilledAt, NewValue));
+}
+
+void UserValue::computeIntervals(MachineRegisterInfo &MRI,
+ const TargetRegisterInfo &TRI,
+ LiveIntervals &LIS, LexicalScopes &LS) {
+ SmallVector<std::pair<SlotIndex, DbgVariableValue>, 16> Defs;
+
+ // Collect all defs to be extended (Skipping undefs).
+ for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I)
+ if (!I.value().isUndef())
+ Defs.push_back(std::make_pair(I.start(), I.value()));
+
+ // Extend all defs, and possibly add new ones along the way.
+ for (unsigned i = 0; i != Defs.size(); ++i) {
+ SlotIndex Idx = Defs[i].first;
+ DbgVariableValue DbgValue = Defs[i].second;
+ SmallDenseMap<unsigned, std::pair<LiveRange *, const VNInfo *>> LIs;
+ SmallVector<const VNInfo *, 4> VNIs;
+ bool ShouldExtendDef = false;
+ for (unsigned LocNo : DbgValue.loc_nos()) {
+ const MachineOperand &LocMO = locations[LocNo];
+ if (!LocMO.isReg() || !LocMO.getReg().isVirtual()) {
+ ShouldExtendDef |= !LocMO.isReg();
+ continue;
+ }
+ ShouldExtendDef = true;
+ LiveInterval *LI = nullptr;
+ const VNInfo *VNI = nullptr;
+ if (LIS.hasInterval(LocMO.getReg())) {
+ LI = &LIS.getInterval(LocMO.getReg());
+ VNI = LI->getVNInfoAt(Idx);
+ }
+ if (LI && VNI)
+ LIs[LocNo] = {LI, VNI};
+ }
+ if (ShouldExtendDef) {
+ std::optional<std::pair<SlotIndex, SmallVector<unsigned>>> Kills;
+ extendDef(Idx, DbgValue, LIs, Kills, LIS);
+
+ if (Kills) {
+ SmallVector<std::pair<unsigned, LiveInterval *>, 2> KilledLocIntervals;
+ bool AnySubreg = false;
+ for (unsigned LocNo : Kills->second) {
+ const MachineOperand &LocMO = this->locations[LocNo];
+ if (LocMO.getSubReg()) {
+ AnySubreg = true;
+ break;
+ }
+ LiveInterval *LI = &LIS.getInterval(LocMO.getReg());
+ KilledLocIntervals.push_back({LocNo, LI});
+ }
+
+ // FIXME: Handle sub-registers in addDefsFromCopies. The problem is that
+ // if the original location for example is %vreg0:sub_hi, and we find a
+ // full register copy in addDefsFromCopies (at the moment it only
+ // handles full register copies), then we must add the sub1 sub-register
+ // index to the new location. However, that is only possible if the new
+ // virtual register is of the same regclass (or if there is an
+ // equivalent sub-register in that regclass). For now, simply skip
+ // handling copies if a sub-register is involved.
+ if (!AnySubreg)
+ addDefsFromCopies(DbgValue, KilledLocIntervals, Kills->first, Defs,
+ MRI, LIS);
+ }
+ }
+
+ // For physregs, we only mark the start slot idx. DwarfDebug will see it
+ // as if the DBG_VALUE is valid up until the end of the basic block, or
+ // the next def of the physical register. So we do not need to extend the
+ // range. It might actually happen that the DBG_VALUE is the last use of
+ // the physical register (e.g. if this is an unused input argument to a
+ // function).
+ }
+
+ // The computed intervals may extend beyond the range of the debug
+ // location's lexical scope. In this case, splitting of an interval
+ // can result in an interval outside of the scope being created,
+ // causing extra unnecessary DBG_VALUEs to be emitted. To prevent
+ // this, trim the intervals to the lexical scope in the case of inlined
+ // variables, since heavy inlining may cause production of dramatically big
+ // number of DBG_VALUEs to be generated.
+ if (!dl.getInlinedAt())
+ return;
+
+ LexicalScope *Scope = LS.findLexicalScope(dl);
+ if (!Scope)
+ return;
+
+ SlotIndex PrevEnd;
+ LocMap::iterator I = locInts.begin();
+
+ // Iterate over the lexical scope ranges. Each time round the loop
+ // we check the intervals for overlap with the end of the previous
+ // range and the start of the next. The first range is handled as
+ // a special case where there is no PrevEnd.
+ for (const InsnRange &Range : Scope->getRanges()) {
+ SlotIndex RStart = LIS.getInstructionIndex(*Range.first);
+ SlotIndex REnd = LIS.getInstructionIndex(*Range.second);
+
+ // Variable locations at the first instruction of a block should be
+ // based on the block's SlotIndex, not the first instruction's index.
+ if (Range.first == Range.first->getParent()->begin())
+ RStart = LIS.getSlotIndexes()->getIndexBefore(*Range.first);
+
+ // At the start of each iteration I has been advanced so that
+ // I.stop() >= PrevEnd. Check for overlap.
+ if (PrevEnd && I.start() < PrevEnd) {
+ SlotIndex IStop = I.stop();
+ DbgVariableValue DbgValue = I.value();
+
+ // Stop overlaps previous end - trim the end of the interval to
+ // the scope range.
+ I.setStopUnchecked(PrevEnd);
+ ++I;
+
+ // If the interval also overlaps the start of the "next" (i.e.
+ // current) range create a new interval for the remainder (which
+ // may be further trimmed).
+ if (RStart < IStop)
+ I.insert(RStart, IStop, DbgValue);
+ }
+
+ // Advance I so that I.stop() >= RStart, and check for overlap.
+ I.advanceTo(RStart);
+ if (!I.valid())
+ return;
+
+ if (I.start() < RStart) {
+ // Interval start overlaps range - trim to the scope range.
+ I.setStartUnchecked(RStart);
+ // Remember that this interval was trimmed.
+ trimmedDefs.insert(RStart);
+ }
+
+ // The end of a lexical scope range is the last instruction in the
+ // range. To convert to an interval we need the index of the
+ // instruction after it.
+ REnd = REnd.getNextIndex();
+
+ // Advance I to first interval outside current range.
+ I.advanceTo(REnd);
+ if (!I.valid())
+ return;
+
+ PrevEnd = REnd;
+ }
+
+ // Check for overlap with end of final range.
+ if (PrevEnd && I.start() < PrevEnd)
+ I.setStopUnchecked(PrevEnd);
+}
+
+void LDVImpl::computeIntervals() {
+ LexicalScopes LS;
+ LS.initialize(*MF);
+
+ for (unsigned i = 0, e = userValues.size(); i != e; ++i) {
+ userValues[i]->computeIntervals(MF->getRegInfo(), *TRI, *LIS, LS);
+ userValues[i]->mapVirtRegs(this);
+ }
+}
+
+bool LDVImpl::runOnMachineFunction(MachineFunction &mf, bool InstrRef) {
+ clear();
+ MF = &mf;
+ LIS = &pass.getAnalysis<LiveIntervals>();
+ TRI = mf.getSubtarget().getRegisterInfo();
+ LLVM_DEBUG(dbgs() << "********** COMPUTING LIVE DEBUG VARIABLES: "
+ << mf.getName() << " **********\n");
+
+ bool Changed = collectDebugValues(mf, InstrRef);
+ computeIntervals();
+ LLVM_DEBUG(print(dbgs()));
+
+ // Collect the set of VReg / SlotIndexs where PHIs occur; index the sensitive
+ // VRegs too, for when we're notified of a range split.
+ SlotIndexes *Slots = LIS->getSlotIndexes();
+ for (const auto &PHIIt : MF->DebugPHIPositions) {
+ const MachineFunction::DebugPHIRegallocPos &Position = PHIIt.second;
+ MachineBasicBlock *MBB = Position.MBB;
+ Register Reg = Position.Reg;
+ unsigned SubReg = Position.SubReg;
+ SlotIndex SI = Slots->getMBBStartIdx(MBB);
+ PHIValPos VP = {SI, Reg, SubReg};
+ PHIValToPos.insert(std::make_pair(PHIIt.first, VP));
+ RegToPHIIdx[Reg].push_back(PHIIt.first);
+ }
+
+ ModifiedMF = Changed;
+ return Changed;
+}
+
+static void removeDebugInstrs(MachineFunction &mf) {
+ for (MachineBasicBlock &MBB : mf) {
+ for (MachineInstr &MI : llvm::make_early_inc_range(MBB))
+ if (MI.isDebugInstr())
+ MBB.erase(&MI);
+ }
+}
+
+bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) {
+ if (!EnableLDV)
+ return false;
+ if (!mf.getFunction().getSubprogram()) {
+ removeDebugInstrs(mf);
+ return false;
+ }
+
+ // Have we been asked to track variable locations using instruction
+ // referencing?
+ bool InstrRef = mf.useDebugInstrRef();
+
+ if (!pImpl)
+ pImpl = new LDVImpl(this);
+ return static_cast<LDVImpl *>(pImpl)->runOnMachineFunction(mf, InstrRef);
+}
+
+void LiveDebugVariables::releaseMemory() {
+ if (pImpl)
+ static_cast<LDVImpl*>(pImpl)->clear();
+}
+
+LiveDebugVariables::~LiveDebugVariables() {
+ if (pImpl)
+ delete static_cast<LDVImpl*>(pImpl);
+}
+
+//===----------------------------------------------------------------------===//
+// Live Range Splitting
+//===----------------------------------------------------------------------===//
+
+bool
+UserValue::splitLocation(unsigned OldLocNo, ArrayRef<Register> NewRegs,
+ LiveIntervals& LIS) {
+ LLVM_DEBUG({
+ dbgs() << "Splitting Loc" << OldLocNo << '\t';
+ print(dbgs(), nullptr);
+ });
+ bool DidChange = false;
+ LocMap::iterator LocMapI;
+ LocMapI.setMap(locInts);
+ for (Register NewReg : NewRegs) {
+ LiveInterval *LI = &LIS.getInterval(NewReg);
+ if (LI->empty())
+ continue;
+
+ // Don't allocate the new LocNo until it is needed.
+ unsigned NewLocNo = UndefLocNo;
+
+ // Iterate over the overlaps between locInts and LI.
+ LocMapI.find(LI->beginIndex());
+ if (!LocMapI.valid())
+ continue;
+ LiveInterval::iterator LII = LI->advanceTo(LI->begin(), LocMapI.start());
+ LiveInterval::iterator LIE = LI->end();
+ while (LocMapI.valid() && LII != LIE) {
+ // At this point, we know that LocMapI.stop() > LII->start.
+ LII = LI->advanceTo(LII, LocMapI.start());
+ if (LII == LIE)
+ break;
+
+ // Now LII->end > LocMapI.start(). Do we have an overlap?
+ if (LocMapI.value().containsLocNo(OldLocNo) &&
+ LII->start < LocMapI.stop()) {
+ // Overlapping correct location. Allocate NewLocNo now.
+ if (NewLocNo == UndefLocNo) {
+ MachineOperand MO = MachineOperand::CreateReg(LI->reg(), false);
+ MO.setSubReg(locations[OldLocNo].getSubReg());
+ NewLocNo = getLocationNo(MO);
+ DidChange = true;
+ }
+
+ SlotIndex LStart = LocMapI.start();
+ SlotIndex LStop = LocMapI.stop();
+ DbgVariableValue OldDbgValue = LocMapI.value();
+
+ // Trim LocMapI down to the LII overlap.
+ if (LStart < LII->start)
+ LocMapI.setStartUnchecked(LII->start);
+ if (LStop > LII->end)
+ LocMapI.setStopUnchecked(LII->end);
+
+ // Change the value in the overlap. This may trigger coalescing.
+ LocMapI.setValue(OldDbgValue.changeLocNo(OldLocNo, NewLocNo));
+
+ // Re-insert any removed OldDbgValue ranges.
+ if (LStart < LocMapI.start()) {
+ LocMapI.insert(LStart, LocMapI.start(), OldDbgValue);
+ ++LocMapI;
+ assert(LocMapI.valid() && "Unexpected coalescing");
+ }
+ if (LStop > LocMapI.stop()) {
+ ++LocMapI;
+ LocMapI.insert(LII->end, LStop, OldDbgValue);
+ --LocMapI;
+ }
+ }
+
+ // Advance to the next overlap.
+ if (LII->end < LocMapI.stop()) {
+ if (++LII == LIE)
+ break;
+ LocMapI.advanceTo(LII->start);
+ } else {
+ ++LocMapI;
+ if (!LocMapI.valid())
+ break;
+ LII = LI->advanceTo(LII, LocMapI.start());
+ }
+ }
+ }
+
+ // Finally, remove OldLocNo unless it is still used by some interval in the
+ // locInts map. One case when OldLocNo still is in use is when the register
+ // has been spilled. In such situations the spilled register is kept as a
+ // location until rewriteLocations is called (VirtRegMap is mapping the old
+ // register to the spill slot). So for a while we can have locations that map
+ // to virtual registers that have been removed from both the MachineFunction
+ // and from LiveIntervals.
+ //
+ // We may also just be using the location for a value with a different
+ // expression.
+ removeLocationIfUnused(OldLocNo);
+
+ LLVM_DEBUG({
+ dbgs() << "Split result: \t";
+ print(dbgs(), nullptr);
+ });
+ return DidChange;
+}
+
+bool
+UserValue::splitRegister(Register OldReg, ArrayRef<Register> NewRegs,
+ LiveIntervals &LIS) {
+ bool DidChange = false;
+ // Split locations referring to OldReg. Iterate backwards so splitLocation can
+ // safely erase unused locations.
+ for (unsigned i = locations.size(); i ; --i) {
+ unsigned LocNo = i-1;
+ const MachineOperand *Loc = &locations[LocNo];
+ if (!Loc->isReg() || Loc->getReg() != OldReg)
+ continue;
+ DidChange |= splitLocation(LocNo, NewRegs, LIS);
+ }
+ return DidChange;
+}
+
+void LDVImpl::splitPHIRegister(Register OldReg, ArrayRef<Register> NewRegs) {
+ auto RegIt = RegToPHIIdx.find(OldReg);
+ if (RegIt == RegToPHIIdx.end())
+ return;
+
+ std::vector<std::pair<Register, unsigned>> NewRegIdxes;
+ // Iterate over all the debug instruction numbers affected by this split.
+ for (unsigned InstrID : RegIt->second) {
+ auto PHIIt = PHIValToPos.find(InstrID);
+ assert(PHIIt != PHIValToPos.end());
+ const SlotIndex &Slot = PHIIt->second.SI;
+ assert(OldReg == PHIIt->second.Reg);
+
+ // Find the new register that covers this position.
+ for (auto NewReg : NewRegs) {
+ const LiveInterval &LI = LIS->getInterval(NewReg);
+ auto LII = LI.find(Slot);
+ if (LII != LI.end() && LII->start <= Slot) {
+ // This new register covers this PHI position, record this for indexing.
+ NewRegIdxes.push_back(std::make_pair(NewReg, InstrID));
+ // Record that this value lives in a different VReg now.
+ PHIIt->second.Reg = NewReg;
+ break;
+ }
+ }
+
+ // If we do not find a new register covering this PHI, then register
+ // allocation has dropped its location, for example because it's not live.
+ // The old VReg will not be mapped to a physreg, and the instruction
+ // number will have been optimized out.
+ }
+
+ // Re-create register index using the new register numbers.
+ RegToPHIIdx.erase(RegIt);
+ for (auto &RegAndInstr : NewRegIdxes)
+ RegToPHIIdx[RegAndInstr.first].push_back(RegAndInstr.second);
+}
+
+void LDVImpl::splitRegister(Register OldReg, ArrayRef<Register> NewRegs) {
+ // Consider whether this split range affects any PHI locations.
+ splitPHIRegister(OldReg, NewRegs);
+
+ // Check whether any intervals mapped by a DBG_VALUE were split and need
+ // updating.
+ bool DidChange = false;
+ for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext())
+ DidChange |= UV->splitRegister(OldReg, NewRegs, *LIS);
+
+ if (!DidChange)
+ return;
+
+ // Map all of the new virtual registers.
+ UserValue *UV = lookupVirtReg(OldReg);
+ for (Register NewReg : NewRegs)
+ mapVirtReg(NewReg, UV);
+}
+
+void LiveDebugVariables::
+splitRegister(Register OldReg, ArrayRef<Register> NewRegs, LiveIntervals &LIS) {
+ if (pImpl)
+ static_cast<LDVImpl*>(pImpl)->splitRegister(OldReg, NewRegs);
+}
+
+void UserValue::rewriteLocations(VirtRegMap &VRM, const MachineFunction &MF,
+ const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ SpillOffsetMap &SpillOffsets) {
+ // Build a set of new locations with new numbers so we can coalesce our
+ // IntervalMap if two vreg intervals collapse to the same physical location.
+ // Use MapVector instead of SetVector because MapVector::insert returns the
+ // position of the previously or newly inserted element. The boolean value
+ // tracks if the location was produced by a spill.
+ // FIXME: This will be problematic if we ever support direct and indirect
+ // frame index locations, i.e. expressing both variables in memory and
+ // 'int x, *px = &x'. The "spilled" bit must become part of the location.
+ MapVector<MachineOperand, std::pair<bool, unsigned>> NewLocations;
+ SmallVector<unsigned, 4> LocNoMap(locations.size());
+ for (unsigned I = 0, E = locations.size(); I != E; ++I) {
+ bool Spilled = false;
+ unsigned SpillOffset = 0;
+ MachineOperand Loc = locations[I];
+ // Only virtual registers are rewritten.
+ if (Loc.isReg() && Loc.getReg() && Loc.getReg().isVirtual()) {
+ Register VirtReg = Loc.getReg();
+ if (VRM.isAssignedReg(VirtReg) &&
+ Register::isPhysicalRegister(VRM.getPhys(VirtReg))) {
+ // This can create a %noreg operand in rare cases when the sub-register
+ // index is no longer available. That means the user value is in a
+ // non-existent sub-register, and %noreg is exactly what we want.
+ Loc.substPhysReg(VRM.getPhys(VirtReg), TRI);
+ } else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT) {
+ // Retrieve the stack slot offset.
+ unsigned SpillSize;
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ const TargetRegisterClass *TRC = MRI.getRegClass(VirtReg);
+ bool Success = TII.getStackSlotRange(TRC, Loc.getSubReg(), SpillSize,
+ SpillOffset, MF);
+
+ // FIXME: Invalidate the location if the offset couldn't be calculated.
+ (void)Success;
+
+ Loc = MachineOperand::CreateFI(VRM.getStackSlot(VirtReg));
+ Spilled = true;
+ } else {
+ Loc.setReg(0);
+ Loc.setSubReg(0);
+ }
+ }
+
+ // Insert this location if it doesn't already exist and record a mapping
+ // from the old number to the new number.
+ auto InsertResult = NewLocations.insert({Loc, {Spilled, SpillOffset}});
+ unsigned NewLocNo = std::distance(NewLocations.begin(), InsertResult.first);
+ LocNoMap[I] = NewLocNo;
+ }
+
+ // Rewrite the locations and record the stack slot offsets for spills.
+ locations.clear();
+ SpillOffsets.clear();
+ for (auto &Pair : NewLocations) {
+ bool Spilled;
+ unsigned SpillOffset;
+ std::tie(Spilled, SpillOffset) = Pair.second;
+ locations.push_back(Pair.first);
+ if (Spilled) {
+ unsigned NewLocNo = std::distance(&*NewLocations.begin(), &Pair);
+ SpillOffsets[NewLocNo] = SpillOffset;
+ }
+ }
+
+ // Update the interval map, but only coalesce left, since intervals to the
+ // right use the old location numbers. This should merge two contiguous
+ // DBG_VALUE intervals with different vregs that were allocated to the same
+ // physical register.
+ for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) {
+ I.setValueUnchecked(I.value().remapLocNos(LocNoMap));
+ I.setStart(I.start());
+ }
+}
+
+/// Find an iterator for inserting a DBG_VALUE instruction.
+static MachineBasicBlock::iterator
+findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, LiveIntervals &LIS,
+ BlockSkipInstsMap &BBSkipInstsMap) {
+ SlotIndex Start = LIS.getMBBStartIdx(MBB);
+ Idx = Idx.getBaseIndex();
+
+ // Try to find an insert location by going backwards from Idx.
+ MachineInstr *MI;
+ while (!(MI = LIS.getInstructionFromIndex(Idx))) {
+ // We've reached the beginning of MBB.
+ if (Idx == Start) {
+ // Retrieve the last PHI/Label/Debug location found when calling
+ // SkipPHIsLabelsAndDebug last time. Start searching from there.
+ //
+ // Note the iterator kept in BBSkipInstsMap is one step back based
+ // on the iterator returned by SkipPHIsLabelsAndDebug last time.
+ // One exception is when SkipPHIsLabelsAndDebug returns MBB->begin(),
+ // BBSkipInstsMap won't save it. This is to consider the case that
+ // new instructions may be inserted at the beginning of MBB after
+ // last call of SkipPHIsLabelsAndDebug. If we save MBB->begin() in
+ // BBSkipInstsMap, after new non-phi/non-label/non-debug instructions
+ // are inserted at the beginning of the MBB, the iterator in
+ // BBSkipInstsMap won't point to the beginning of the MBB anymore.
+ // Therefore The next search in SkipPHIsLabelsAndDebug will skip those
+ // newly added instructions and that is unwanted.
+ MachineBasicBlock::iterator BeginIt;
+ auto MapIt = BBSkipInstsMap.find(MBB);
+ if (MapIt == BBSkipInstsMap.end())
+ BeginIt = MBB->begin();
+ else
+ BeginIt = std::next(MapIt->second);
+ auto I = MBB->SkipPHIsLabelsAndDebug(BeginIt);
+ if (I != BeginIt)
+ BBSkipInstsMap[MBB] = std::prev(I);
+ return I;
+ }
+ Idx = Idx.getPrevIndex();
+ }
+
+ // Don't insert anything after the first terminator, though.
+ return MI->isTerminator() ? MBB->getFirstTerminator() :
+ std::next(MachineBasicBlock::iterator(MI));
+}
+
+/// Find an iterator for inserting the next DBG_VALUE instruction
+/// (or end if no more insert locations found).
+static MachineBasicBlock::iterator
+findNextInsertLocation(MachineBasicBlock *MBB, MachineBasicBlock::iterator I,
+ SlotIndex StopIdx, ArrayRef<MachineOperand> LocMOs,
+ LiveIntervals &LIS, const TargetRegisterInfo &TRI) {
+ SmallVector<Register, 4> Regs;
+ for (const MachineOperand &LocMO : LocMOs)
+ if (LocMO.isReg())
+ Regs.push_back(LocMO.getReg());
+ if (Regs.empty())
+ return MBB->instr_end();
+
+ // Find the next instruction in the MBB that define the register Reg.
+ while (I != MBB->end() && !I->isTerminator()) {
+ if (!LIS.isNotInMIMap(*I) &&
+ SlotIndex::isEarlierEqualInstr(StopIdx, LIS.getInstructionIndex(*I)))
+ break;
+ if (any_of(Regs, [&I, &TRI](Register &Reg) {
+ return I->definesRegister(Reg, &TRI);
+ }))
+ // The insert location is directly after the instruction/bundle.
+ return std::next(I);
+ ++I;
+ }
+ return MBB->end();
+}
+
+void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
+ SlotIndex StopIdx, DbgVariableValue DbgValue,
+ ArrayRef<bool> LocSpills,
+ ArrayRef<unsigned> SpillOffsets,
+ LiveIntervals &LIS, const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ BlockSkipInstsMap &BBSkipInstsMap) {
+ SlotIndex MBBEndIdx = LIS.getMBBEndIdx(&*MBB);
+ // Only search within the current MBB.
+ StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx;
+ MachineBasicBlock::iterator I =
+ findInsertLocation(MBB, StartIdx, LIS, BBSkipInstsMap);
+ // Undef values don't exist in locations so create new "noreg" register MOs
+ // for them. See getLocationNo().
+ SmallVector<MachineOperand, 8> MOs;
+ if (DbgValue.isUndef()) {
+ MOs.assign(DbgValue.loc_nos().size(),
+ MachineOperand::CreateReg(
+ /* Reg */ 0, /* isDef */ false, /* isImp */ false,
+ /* isKill */ false, /* isDead */ false,
+ /* isUndef */ false, /* isEarlyClobber */ false,
+ /* SubReg */ 0, /* isDebug */ true));
+ } else {
+ for (unsigned LocNo : DbgValue.loc_nos())
+ MOs.push_back(locations[LocNo]);
+ }
+
+ ++NumInsertedDebugValues;
+
+ assert(cast<DILocalVariable>(Variable)
+ ->isValidLocationForIntrinsic(getDebugLoc()) &&
+ "Expected inlined-at fields to agree");
+
+ // If the location was spilled, the new DBG_VALUE will be indirect. If the
+ // original DBG_VALUE was indirect, we need to add DW_OP_deref to indicate
+ // that the original virtual register was a pointer. Also, add the stack slot
+ // offset for the spilled register to the expression.
+ const DIExpression *Expr = DbgValue.getExpression();
+ bool IsIndirect = DbgValue.getWasIndirect();
+ bool IsList = DbgValue.getWasList();
+ for (unsigned I = 0, E = LocSpills.size(); I != E; ++I) {
+ if (LocSpills[I]) {
+ if (!IsList) {
+ uint8_t DIExprFlags = DIExpression::ApplyOffset;
+ if (IsIndirect)
+ DIExprFlags |= DIExpression::DerefAfter;
+ Expr = DIExpression::prepend(Expr, DIExprFlags, SpillOffsets[I]);
+ IsIndirect = true;
+ } else {
+ SmallVector<uint64_t, 4> Ops;
+ DIExpression::appendOffset(Ops, SpillOffsets[I]);
+ Ops.push_back(dwarf::DW_OP_deref);
+ Expr = DIExpression::appendOpsToArg(Expr, Ops, I);
+ }
+ }
+
+ assert((!LocSpills[I] || MOs[I].isFI()) &&
+ "a spilled location must be a frame index");
+ }
+
+ unsigned DbgValueOpcode =
+ IsList ? TargetOpcode::DBG_VALUE_LIST : TargetOpcode::DBG_VALUE;
+ do {
+ BuildMI(*MBB, I, getDebugLoc(), TII.get(DbgValueOpcode), IsIndirect, MOs,
+ Variable, Expr);
+
+ // Continue and insert DBG_VALUES after every redefinition of a register
+ // associated with the debug value within the range
+ I = findNextInsertLocation(MBB, I, StopIdx, MOs, LIS, TRI);
+ } while (I != MBB->end());
+}
+
+void UserLabel::insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx,
+ LiveIntervals &LIS, const TargetInstrInfo &TII,
+ BlockSkipInstsMap &BBSkipInstsMap) {
+ MachineBasicBlock::iterator I =
+ findInsertLocation(MBB, Idx, LIS, BBSkipInstsMap);
+ ++NumInsertedDebugLabels;
+ BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_LABEL))
+ .addMetadata(Label);
+}
+
+void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
+ const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ const SpillOffsetMap &SpillOffsets,
+ BlockSkipInstsMap &BBSkipInstsMap) {
+ MachineFunction::iterator MFEnd = VRM->getMachineFunction().end();
+
+ for (LocMap::const_iterator I = locInts.begin(); I.valid();) {
+ SlotIndex Start = I.start();
+ SlotIndex Stop = I.stop();
+ DbgVariableValue DbgValue = I.value();
+
+ SmallVector<bool> SpilledLocs;
+ SmallVector<unsigned> LocSpillOffsets;
+ for (unsigned LocNo : DbgValue.loc_nos()) {
+ auto SpillIt =
+ !DbgValue.isUndef() ? SpillOffsets.find(LocNo) : SpillOffsets.end();
+ bool Spilled = SpillIt != SpillOffsets.end();
+ SpilledLocs.push_back(Spilled);
+ LocSpillOffsets.push_back(Spilled ? SpillIt->second : 0);
+ }
+
+ // If the interval start was trimmed to the lexical scope insert the
+ // DBG_VALUE at the previous index (otherwise it appears after the
+ // first instruction in the range).
+ if (trimmedDefs.count(Start))
+ Start = Start.getPrevIndex();
+
+ LLVM_DEBUG(auto &dbg = dbgs(); dbg << "\t[" << Start << ';' << Stop << "):";
+ DbgValue.printLocNos(dbg));
+ MachineFunction::iterator MBB = LIS.getMBBFromIndex(Start)->getIterator();
+ SlotIndex MBBEnd = LIS.getMBBEndIdx(&*MBB);
+
+ LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd);
+ insertDebugValue(&*MBB, Start, Stop, DbgValue, SpilledLocs, LocSpillOffsets,
+ LIS, TII, TRI, BBSkipInstsMap);
+ // This interval may span multiple basic blocks.
+ // Insert a DBG_VALUE into each one.
+ while (Stop > MBBEnd) {
+ // Move to the next block.
+ Start = MBBEnd;
+ if (++MBB == MFEnd)
+ break;
+ MBBEnd = LIS.getMBBEndIdx(&*MBB);
+ LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd);
+ insertDebugValue(&*MBB, Start, Stop, DbgValue, SpilledLocs,
+ LocSpillOffsets, LIS, TII, TRI, BBSkipInstsMap);
+ }
+ LLVM_DEBUG(dbgs() << '\n');
+ if (MBB == MFEnd)
+ break;
+
+ ++I;
+ }
+}
+
+void UserLabel::emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII,
+ BlockSkipInstsMap &BBSkipInstsMap) {
+ LLVM_DEBUG(dbgs() << "\t" << loc);
+ MachineFunction::iterator MBB = LIS.getMBBFromIndex(loc)->getIterator();
+
+ LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB));
+ insertDebugLabel(&*MBB, loc, LIS, TII, BBSkipInstsMap);
+
+ LLVM_DEBUG(dbgs() << '\n');
+}
+
+void LDVImpl::emitDebugValues(VirtRegMap *VRM) {
+ LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG VARIABLES **********\n");
+ if (!MF)
+ return;
+
+ BlockSkipInstsMap BBSkipInstsMap;
+ const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
+ SpillOffsetMap SpillOffsets;
+ for (auto &userValue : userValues) {
+ LLVM_DEBUG(userValue->print(dbgs(), TRI));
+ userValue->rewriteLocations(*VRM, *MF, *TII, *TRI, SpillOffsets);
+ userValue->emitDebugValues(VRM, *LIS, *TII, *TRI, SpillOffsets,
+ BBSkipInstsMap);
+ }
+ LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG LABELS **********\n");
+ for (auto &userLabel : userLabels) {
+ LLVM_DEBUG(userLabel->print(dbgs(), TRI));
+ userLabel->emitDebugLabel(*LIS, *TII, BBSkipInstsMap);
+ }
+
+ LLVM_DEBUG(dbgs() << "********** EMITTING DEBUG PHIS **********\n");
+
+ auto Slots = LIS->getSlotIndexes();
+ for (auto &It : PHIValToPos) {
+ // For each ex-PHI, identify its physreg location or stack slot, and emit
+ // a DBG_PHI for it.
+ unsigned InstNum = It.first;
+ auto Slot = It.second.SI;
+ Register Reg = It.second.Reg;
+ unsigned SubReg = It.second.SubReg;
+
+ MachineBasicBlock *OrigMBB = Slots->getMBBFromIndex(Slot);
+ if (VRM->isAssignedReg(Reg) &&
+ Register::isPhysicalRegister(VRM->getPhys(Reg))) {
+ unsigned PhysReg = VRM->getPhys(Reg);
+ if (SubReg != 0)
+ PhysReg = TRI->getSubReg(PhysReg, SubReg);
+
+ auto Builder = BuildMI(*OrigMBB, OrigMBB->begin(), DebugLoc(),
+ TII->get(TargetOpcode::DBG_PHI));
+ Builder.addReg(PhysReg);
+ Builder.addImm(InstNum);
+ } else if (VRM->getStackSlot(Reg) != VirtRegMap::NO_STACK_SLOT) {
+ const MachineRegisterInfo &MRI = MF->getRegInfo();
+ const TargetRegisterClass *TRC = MRI.getRegClass(Reg);
+ unsigned SpillSize, SpillOffset;
+
+ unsigned regSizeInBits = TRI->getRegSizeInBits(*TRC);
+ if (SubReg)
+ regSizeInBits = TRI->getSubRegIdxSize(SubReg);
+
+ // Test whether this location is legal with the given subreg. If the
+ // subregister has a nonzero offset, drop this location, it's too complex
+ // to describe. (TODO: future work).
+ bool Success =
+ TII->getStackSlotRange(TRC, SubReg, SpillSize, SpillOffset, *MF);
+
+ if (Success && SpillOffset == 0) {
+ auto Builder = BuildMI(*OrigMBB, OrigMBB->begin(), DebugLoc(),
+ TII->get(TargetOpcode::DBG_PHI));
+ Builder.addFrameIndex(VRM->getStackSlot(Reg));
+ Builder.addImm(InstNum);
+ // Record how large the original value is. The stack slot might be
+ // merged and altered during optimisation, but we will want to know how
+ // large the value is, at this DBG_PHI.
+ Builder.addImm(regSizeInBits);
+ }
+
+ LLVM_DEBUG(
+ if (SpillOffset != 0) {
+ dbgs() << "DBG_PHI for Vreg " << Reg << " subreg " << SubReg <<
+ " has nonzero offset\n";
+ }
+ );
+ }
+ // If there was no mapping for a value ID, it's optimized out. Create no
+ // DBG_PHI, and any variables using this value will become optimized out.
+ }
+ MF->DebugPHIPositions.clear();
+
+ LLVM_DEBUG(dbgs() << "********** EMITTING INSTR REFERENCES **********\n");
+
+ // Re-insert any debug instrs back in the position they were. We must
+ // re-insert in the same order to ensure that debug instructions don't swap,
+ // which could re-order assignments. Do so in a batch -- once we find the
+ // insert position, insert all instructions at the same SlotIdx. They are
+ // guaranteed to appear in-sequence in StashedDebugInstrs because we insert
+ // them in order.
+ for (auto *StashIt = StashedDebugInstrs.begin();
+ StashIt != StashedDebugInstrs.end(); ++StashIt) {
+ SlotIndex Idx = StashIt->Idx;
+ MachineBasicBlock *MBB = StashIt->MBB;
+ MachineInstr *MI = StashIt->MI;
+
+ auto EmitInstsHere = [this, &StashIt, MBB, Idx,
+ MI](MachineBasicBlock::iterator InsertPos) {
+ // Insert this debug instruction.
+ MBB->insert(InsertPos, MI);
+
+ // Look at subsequent stashed debug instructions: if they're at the same
+ // index, insert those too.
+ auto NextItem = std::next(StashIt);
+ while (NextItem != StashedDebugInstrs.end() && NextItem->Idx == Idx) {
+ assert(NextItem->MBB == MBB && "Instrs with same slot index should be"
+ "in the same block");
+ MBB->insert(InsertPos, NextItem->MI);
+ StashIt = NextItem;
+ NextItem = std::next(StashIt);
+ };
+ };
+
+ // Start block index: find the first non-debug instr in the block, and
+ // insert before it.
+ if (Idx == Slots->getMBBStartIdx(MBB)) {
+ MachineBasicBlock::iterator InsertPos =
+ findInsertLocation(MBB, Idx, *LIS, BBSkipInstsMap);
+ EmitInstsHere(InsertPos);
+ continue;
+ }
+
+ if (MachineInstr *Pos = Slots->getInstructionFromIndex(Idx)) {
+ // Insert at the end of any debug instructions.
+ auto PostDebug = std::next(Pos->getIterator());
+ PostDebug = skipDebugInstructionsForward(PostDebug, MBB->instr_end());
+ EmitInstsHere(PostDebug);
+ } else {
+ // Insert position disappeared; walk forwards through slots until we
+ // find a new one.
+ SlotIndex End = Slots->getMBBEndIdx(MBB);
+ for (; Idx < End; Idx = Slots->getNextNonNullIndex(Idx)) {
+ Pos = Slots->getInstructionFromIndex(Idx);
+ if (Pos) {
+ EmitInstsHere(Pos->getIterator());
+ break;
+ }
+ }
+
+ // We have reached the end of the block and didn't find anywhere to
+ // insert! It's not safe to discard any debug instructions; place them
+ // in front of the first terminator, or in front of end().
+ if (Idx >= End) {
+ auto TermIt = MBB->getFirstTerminator();
+ EmitInstsHere(TermIt);
+ }
+ }
+ }
+
+ EmitDone = true;
+ BBSkipInstsMap.clear();
+}
+
+void LiveDebugVariables::emitDebugValues(VirtRegMap *VRM) {
+ if (pImpl)
+ static_cast<LDVImpl*>(pImpl)->emitDebugValues(VRM);
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+LLVM_DUMP_METHOD void LiveDebugVariables::dump() const {
+ if (pImpl)
+ static_cast<LDVImpl*>(pImpl)->print(dbgs());
+}
+#endif