[llvm] 957efa4 - Revert "[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info"
Jeremy Morse via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 2 10:42:02 PDT 2023
Author: Jeremy Morse
Date: 2023-11-02T17:41:36Z
New Revision: 957efa4ce4f0391147cec62746e997226ee2b836
URL: https://github.com/llvm/llvm-project/commit/957efa4ce4f0391147cec62746e997226ee2b836
DIFF: https://github.com/llvm/llvm-project/commit/957efa4ce4f0391147cec62746e997226ee2b836.diff
LOG: Revert "[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info"
And some intervening fixups. There are two remaining problems:
* A memory leak via https://lab.llvm.org/buildbot/#/builders/236/builds/7120/steps/10/logs/stdio
* A performance slowdown with -g where I'm not completely sure what the cause it
These might be fairly straightforwards to fix, but it's the end of the day
hear, so I figure I'll clear the buildbots til tomorrow.
This reverts commit 7d77bbef4ad9230f6f427649373fe46a668aa909.
This reverts commit 9026f35afe6ffdc5e55b6615efcbd36f25b11558.
This reverts commit d97b2b389a0e511c65af6845119eb08b8a2cb473.
Added:
Modified:
llvm/include/llvm/IR/BasicBlock.h
llvm/include/llvm/IR/DebugInfoMetadata.h
llvm/include/llvm/IR/Function.h
llvm/include/llvm/IR/Instruction.h
llvm/include/llvm/IR/Metadata.h
llvm/include/llvm/IR/Module.h
llvm/lib/IR/BasicBlock.cpp
llvm/lib/IR/CMakeLists.txt
llvm/lib/IR/DebugInfoMetadata.cpp
llvm/lib/IR/Function.cpp
llvm/lib/IR/LLVMContextImpl.cpp
llvm/lib/IR/LLVMContextImpl.h
llvm/lib/IR/Metadata.cpp
llvm/lib/IR/Module.cpp
llvm/lib/IR/Verifier.cpp
llvm/lib/Linker/IRMover.cpp
llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
llvm/lib/Transforms/Utils/CloneFunction.cpp
llvm/unittests/IR/DebugInfoTest.cpp
llvm/unittests/Transforms/Utils/LocalTest.cpp
llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
Removed:
llvm/include/llvm/IR/DebugProgramInstruction.h
llvm/lib/IR/DebugProgramInstruction.cpp
################################################################################
diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h
index 347e1406b38d293..ab291c24e5b6c75 100644
--- a/llvm/include/llvm/IR/BasicBlock.h
+++ b/llvm/include/llvm/IR/BasicBlock.h
@@ -19,7 +19,6 @@
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/IR/DebugProgramInstruction.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/Value.h"
@@ -57,9 +56,6 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
public ilist_node_with_parent<BasicBlock, Function> {
public:
using InstListType = SymbolTableList<Instruction, ilist_iterator_bits<true>>;
- /// Flag recording whether or not this block stores debug-info in the form
- /// of intrinsic instructions (false) or non-instruction records (true).
- bool IsNewDbgInfoFormat;
private:
friend class BlockAddress;
@@ -68,55 +64,6 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
InstListType InstList;
Function *Parent;
-public:
- /// Attach a DPMarker to the given instruction. Enables the storage of any
- /// debug-info at this position in the program.
- DPMarker *createMarker(Instruction *I);
- DPMarker *createMarker(InstListType::iterator It);
-
- /// Convert variable location debugging information stored in dbg.value
- /// intrinsics into DPMarker / DPValue records. Deletes all dbg.values in
- /// the process and sets IsNewDbgInfoFormat = true. Only takes effect if
- /// the UseNewDbgInfoFormat LLVM command line option is given.
- void convertToNewDbgValues();
-
- /// Convert variable location debugging information stored in DPMarkers and
- /// DPValues into the dbg.value intrinsic representation. Sets
- /// IsNewDbgInfoFormat = false.
- void convertFromNewDbgValues();
-
- /// Ensure the block is in "old" dbg.value format (\p NewFlag == false) or
- /// in the new format (\p NewFlag == true), converting to the desired format
- /// if necessary.
- void setIsNewDbgInfoFormat(bool NewFlag);
-
- /// Validate any DPMarkers / DPValues attached to instructions in this block,
- /// and block-level stored data too (TrailingDPValues).
- /// \p Assert Should this method fire an assertion if a problem is found?
- /// \p Msg Should this method print a message to errs() if a problem is found?
- /// \p OS Output stream to write errors to.
- /// \returns True if a problem is found.
- bool validateDbgValues(bool Assert = true, bool Msg = false,
- raw_ostream *OS = nullptr);
-
- /// Record that the collection of DPValues in \p M "trails" after the last
- /// instruction of this block. These are equivalent to dbg.value intrinsics
- /// that exist at the end of a basic block with no terminator (a transient
- /// state that occurs regularly).
- void setTrailingDPValues(DPMarker *M);
-
- /// Fetch the collection of DPValues that "trail" after the last instruction
- /// of this block, see \ref setTrailingDPValues. If there are none, returns
- /// nullptr.
- DPMarker *getTrailingDPValues();
-
- /// Delete any trailing DPValues at the end of this block, see
- /// \ref setTrailingDPValues.
- void deleteTrailingDPValues();
-
- void dumpDbgValues() const;
-
-private:
void setParent(Function *parent);
/// Constructor.
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 1fe054316b75c82..b347664883fd9f2 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -3765,10 +3765,6 @@ class DIArgList : public MDNode {
iterator args_begin() { return Args.begin(); }
iterator args_end() { return Args.end(); }
- ReplaceableMetadataImpl *getReplaceableUses() {
- return Context.getReplaceableUses();
- }
-
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIArgListKind;
}
diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
deleted file mode 100644
index 1a1f487a5ab553f..000000000000000
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ /dev/null
@@ -1,384 +0,0 @@
-//===-- llvm/DebugProgramInstruction.h - Stream of debug info -------*- C++ -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Data structures for storing variable assignment information in LLVM. In the
-// dbg.value design, a dbg.value intrinsic specifies the position in a block
-// a source variable take on an LLVM Value:
-//
-// %foo = add i32 1, %0
-// dbg.value(metadata i32 %foo, ...)
-// %bar = void call @ext(%foo);
-//
-// and all information is stored in the Value / Metadata hierachy defined
-// elsewhere in LLVM. In the "DPValue" design, each instruction /may/ have a
-// connection with a DPMarker, which identifies a position immediately before the
-// instruction, and each DPMarker /may/ then have connections to DPValues which
-// record the variable assignment information. To illustrate:
-//
-// %foo = add i32 1, %0
-// ; foo->DbgMarker == nullptr
-// ;; There are no variable assignments / debug records "in front" of
-// ;; the instruction for %foo, therefore it has no DbgMarker.
-// %bar = void call @ext(%foo)
-// ; bar->DbgMarker = {
-// ; StoredDPValues = {
-// ; DPValue(metadata i32 %foo, ...)
-// ; }
-// ; }
-// ;; There is a debug-info record in front of the %bar instruction,
-// ;; thus it points at a DPMarker object. That DPMarker contains a
-// ;; DPValue in it's ilist, storing the equivalent information to the
-// ;; dbg.value above: the Value, DILocalVariable, etc.
-//
-// This structure separates the two concerns of the position of the debug-info
-// in the function, and the Value that it refers to. It also creates a new
-// "place" in-between the Value / Metadata hierachy where we can customise
-// storage and allocation techniques to better suite debug-info workloads.
-// NB: as of the initial prototype, none of that has actually been attempted
-// yet.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
-#define LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Bitfields.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/ilist_node.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/DebugLoc.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/SymbolTableListTraits.h"
-#include "llvm/IR/TrackingMDRef.h"
-#include "llvm/Support/AtomicOrdering.h"
-#include <cstdint>
-#include <utility>
-
-namespace llvm {
-
-class Instruction;
-class BasicBlock;
-class MDNode;
-class Module;
-class DbgVariableIntrinsic;
-class DPMarker;
-class DPValue;
-class raw_ostream;
-
-/// Record of a variable value-assignment, aka a non instruction representation
-/// of the dbg.value intrinsic. Features various methods copied across from the
-/// Instruction class to aid ease-of-use. DPValue objects should always be
-/// linked into a DPMarker's StoredDPValues list. The marker connects a DPValue
-/// back to it's position in the BasicBlock.
-///
-/// This class inherits from DebugValueUser to allow LLVM's metadata facilities
-/// to update our references to metadata beneath our feet.
-class DPValue : public ilist_node<DPValue>, private DebugValueUser {
- friend class DebugValueUser;
-
- // NB: there is no explicit "Value" field in this class, it's effectively the
- // DebugValueUser superclass instead. The referred to Value can either be a
- // ValueAsMetadata or a DIArgList.
-
- DILocalVariable *Variable;
- DIExpression *Expression;
- DebugLoc DbgLoc;
-
-public:
- void deleteInstr();
-
- const BasicBlock *getParent() const;
- BasicBlock *getParent();
- void dump() const;
- void removeFromParent();
- void eraseFromParent();
-
- using self_iterator = simple_ilist<DPValue>::iterator;
- using const_self_iterator = simple_ilist<DPValue>::const_iterator;
-
- enum class LocationType {
- Declare,
- Value,
- };
- /// Classification of the debug-info record that this DPValue represents.
- /// Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not
- /// currently supported, but it would be trivial to do so.
- LocationType Type;
-
- /// Marker that this DPValue is linked into.
- DPMarker *Marker = nullptr;
-
- /// Create a new DPValue representing the intrinsic \p DVI, for example the
- /// assignment represented by a dbg.value.
- DPValue(const DbgVariableIntrinsic *DVI);
- DPValue(const DPValue &DPV);
- /// Directly construct a new DPValue representing a dbg.value intrinsic
- /// assigning \p Location to the DV / Expr / DI variable.
- DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
- const DILocation *DI);
-
- /// Iterator for ValueAsMetadata that internally uses direct pointer iteration
- /// over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the
- /// ValueAsMetadata .
- class location_op_iterator
- : public iterator_facade_base<location_op_iterator,
- std::bidirectional_iterator_tag, Value *> {
- PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
-
- public:
- location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {}
- location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {}
-
- location_op_iterator(const location_op_iterator &R) : I(R.I) {}
- location_op_iterator &operator=(const location_op_iterator &R) {
- I = R.I;
- return *this;
- }
- bool operator==(const location_op_iterator &RHS) const {
- return I == RHS.I;
- }
- const Value *operator*() const {
- ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
- ? I.get<ValueAsMetadata *>()
- : *I.get<ValueAsMetadata **>();
- return VAM->getValue();
- };
- Value *operator*() {
- ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
- ? I.get<ValueAsMetadata *>()
- : *I.get<ValueAsMetadata **>();
- return VAM->getValue();
- }
- location_op_iterator &operator++() {
- if (I.is<ValueAsMetadata *>())
- I = I.get<ValueAsMetadata *>() + 1;
- else
- I = I.get<ValueAsMetadata **>() + 1;
- return *this;
- }
- location_op_iterator &operator--() {
- if (I.is<ValueAsMetadata *>())
- I = I.get<ValueAsMetadata *>() - 1;
- else
- I = I.get<ValueAsMetadata **>() - 1;
- return *this;
- }
- };
-
- /// Get the locations corresponding to the variable referenced by the debug
- /// info intrinsic. Depending on the intrinsic, this could be the
- /// variable's value or its address.
- iterator_range<location_op_iterator> location_ops() const;
-
- Value *getVariableLocationOp(unsigned OpIdx) const;
-
- void replaceVariableLocationOp(Value *OldValue, Value *NewValue,
- bool AllowEmpty = false);
- void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue);
- /// Adding a new location operand will always result in this intrinsic using
- /// an ArgList, and must always be accompanied by a new expression that uses
- /// the new operand.
- void addVariableLocationOps(ArrayRef<Value *> NewValues,
- DIExpression *NewExpr);
-
- void setVariable(DILocalVariable *NewVar) { Variable = NewVar; }
-
- void setExpression(DIExpression *NewExpr) { Expression = NewExpr; }
-
- unsigned getNumVariableLocationOps() const {
- if (hasArgList())
- return cast<DIArgList>(getRawLocation())->getArgs().size();
- return 1;
- }
-
- bool hasArgList() const { return isa<DIArgList>(getRawLocation()); }
- /// Returns true if this DPValue has no empty MDNodes in its location list.
- bool hasValidLocation() const { return getVariableLocationOp(0) != nullptr; }
-
- /// Does this describe the address of a local variable. True for dbg.addr
- /// and dbg.declare, but not dbg.value, which describes its value.
- bool isAddressOfVariable() const { return Type != LocationType::Value; }
- LocationType getType() const { return Type; }
-
- DebugLoc getDebugLoc() const { return DbgLoc; }
- void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
-
- void setKillLocation() {
- // TODO: When/if we remove duplicate values from DIArgLists, we don't need
- // this set anymore.
- SmallPtrSet<Value *, 4> RemovedValues;
- for (Value *OldValue : location_ops()) {
- if (!RemovedValues.insert(OldValue).second)
- continue;
- Value *Poison = PoisonValue::get(OldValue->getType());
- replaceVariableLocationOp(OldValue, Poison);
- }
- }
-
- bool isKillLocation() const {
- return (getNumVariableLocationOps() == 0 &&
- !getExpression()->isComplex()) ||
- any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
- }
-
- DILocalVariable *getVariable() const { return Variable; }
-
- DIExpression *getExpression() const { return Expression; }
-
- Metadata *getRawLocation() const { return DebugValue; }
-
- /// Use of this should generally be avoided; instead,
- /// replaceVariableLocationOp and addVariableLocationOps should be used where
- /// possible to avoid creating invalid state.
- void setRawLocation(Metadata *NewLocation) {
- assert(
- (isa<ValueAsMetadata>(NewLocation) || isa<DIArgList>(NewLocation) ||
- isa<MDNode>(NewLocation)) &&
- "Location for a DPValue must be either ValueAsMetadata or DIArgList");
- resetDebugValue(NewLocation);
- }
-
- /// Get the size (in bits) of the variable, or fragment of the variable that
- /// is described.
- std::optional<uint64_t> getFragmentSizeInBits() const;
-
- DPValue *clone() const;
- /// Convert this DPValue back into a dbg.value intrinsic.
- /// \p InsertBefore Optional position to insert this intrinsic.
- /// \returns A new dbg.value intrinsic representiung this DPValue.
- DbgVariableIntrinsic *createDebugIntrinsic(Module *M,
- Instruction *InsertBefore) const;
- /// Handle changes to the location of the Value(s) that we refer to happening
- /// "under our feet".
- void handleChangedLocation(Metadata *NewLocation);
-
- void setMarker(DPMarker *M) { Marker = M; }
-
- DPMarker *getMarker() { return Marker; }
- const DPMarker *getMarker() const { return Marker; }
-
- BasicBlock *getBlock();
- const BasicBlock *getBlock() const;
-
- Function *getFunction();
- const Function *getFunction() const;
-
- Module *getModule();
- const Module *getModule() const;
-
- LLVMContext &getContext();
- const LLVMContext &getContext() const;
-
- void print(raw_ostream &O, bool IsForDebug = false) const;
- void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
-};
-
-/// Per-instruction record of debug-info. If an Instruction is the position of
-/// some debugging information, it points at a DPMarker storing that info. Each
-/// marker points back at the instruction that owns it. Various utilities are
-/// provided for manipulating the DPValues contained within this marker.
-///
-/// This class has a rough surface area, because it's needed to preserve the one
-/// arefact that we can't yet eliminate from the intrinsic / dbg.value
-/// debug-info design: the order of DPValues/records is significant, and
-/// duplicates can exist. Thus, if one has a run of debug-info records such as:
-/// dbg.value(...
-/// %foo = barinst
-/// dbg.value(...
-/// and remove barinst, then the dbg.values must be preserved in the correct
-/// order. Hence, the use of iterators to select positions to insert things
-/// into, or the occasional InsertAtHead parameter indicating that new records
-/// should go at the start of the list.
-///
-/// There are only five or six places in LLVM that truly rely on this ordering,
-/// which we can improve in the future. Additionally, many improvements in the
-/// way that debug-info is stored can be achieved in this class, at a future
-/// date.
-class DPMarker {
-public:
- DPMarker() {}
- /// Link back to the Instruction that owns this marker. Can be null during
- /// operations that move a marker from one instruction to another.
- Instruction *MarkedInstr;
-
- /// List of DPValues, each recording a single variable assignment, the
- /// equivalent of a dbg.value intrinsic. There is a one-to-one relationship
- /// between each dbg.value in a block and each DPValue once the
- /// representation has been converted, and the ordering of DPValues is
- /// meaningful in the same was a dbg.values.
- simple_ilist<DPValue> StoredDPValues;
-
- const BasicBlock *getParent() const;
- BasicBlock *getParent();
-
- /// Handle the removal of a marker: the position of debug-info has gone away,
- /// but the stored debug records should not. Drop them onto the next
- /// instruction, or otherwise work out what to do with them.
- void removeMarker();
- void dump() const;
-
- void removeFromParent();
- void eraseFromParent();
-
- /// Implement operator<< on DPMarker.
- void print(raw_ostream &O, bool IsForDebug = false) const;
- void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
-
- /// Produce a range over all the DPValues in this Marker.
- iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange();
- /// Transfer any DPValues from \p Src into this DPMarker. If \p InsertAtHead
- /// is true, place them before existing DPValues, otherwise afterwards.
- void absorbDebugValues(DPMarker &Src, bool InsertAtHead);
- /// Insert a DPValue into this DPMarker, at the end of the list. If
- /// \p InsertAtHead is true, at the start.
- void insertDPValue(DPValue *New, bool InsertAtHead);
- /// Clone all DPMarkers from \p From into this marker. There are numerous
- /// options to customise the source/destination, due to gnarliness, see class
- /// comment.
- /// \p FromHere If non-null, copy from FromHere to the end of From's DPValues
- /// \p InsertAtHead Place the cloned DPValues at the start of StoredDPValues
- /// \returns Range over all the newly cloned DPValues
- iterator_range<simple_ilist<DPValue>::iterator>
- cloneDebugInfoFrom(DPMarker *From,
- std::optional<simple_ilist<DPValue>::iterator> FromHere,
- bool InsertAtHead = false);
- /// Erase all DPValues in this DPMarker.
- void dropDPValues();
- /// Erase a single DPValue from this marker. In an ideal future, we would
- /// never erase an assignment in this way, but it's the equivalent to
- /// erasing a dbg.value from a block.
- void dropOneDPValue(DPValue *DPV);
-
- /// We generally act like all llvm Instructions have a range of DPValues
- /// attached to them, but in reality sometimes we don't allocate the DPMarker
- /// to save time and memory, but still have to return ranges of DPValues. When
- /// we need to describe such an unallocated DPValue range, use this static
- /// markers range instead. This will bite us if someone tries to insert a
- /// DPValue in that range, but they should be using the Official (TM) API for
- /// that.
- static DPMarker EmptyDPMarker;
- static iterator_range<simple_ilist<DPValue>::iterator> getEmptyDPValueRange(){
- return make_range(EmptyDPMarker.StoredDPValues.end(), EmptyDPMarker.StoredDPValues.end());
- }
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const DPMarker &Marker) {
- Marker.print(OS);
- return OS;
-}
-
-inline raw_ostream &operator<<(raw_ostream &OS, const DPValue &Value) {
- Value.print(OS);
- return OS;
-}
-
-} // namespace llvm
-
-#endif // LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 1628aafe320dadb..692ef7535f0e6b1 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -97,28 +97,15 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
friend class SymbolTableListTraits<Function>;
-public:
- /// Is this function using intrinsics to record the position of debugging
- /// information, or non-intrinsic records? See IsNewDbgInfoFormat in
- /// \ref BasicBlock.
- bool IsNewDbgInfoFormat;
-
/// hasLazyArguments/CheckLazyArguments - The argument list of a function is
/// built on demand, so that the list isn't allocated until the first client
/// needs it. The hasLazyArguments predicate returns true if the arg list
/// hasn't been set up yet.
+public:
bool hasLazyArguments() const {
return getSubclassDataFromValue() & (1<<0);
}
- /// \see BasicBlock::convertToNewDbgValues.
- void convertToNewDbgValues();
-
- /// \see BasicBlock::convertFromNewDbgValues.
- void convertFromNewDbgValues();
-
- void setIsNewDbgInfoFormat(bool NewVal);
-
private:
void CheckLazyArguments() const {
if (hasLazyArguments())
@@ -705,7 +692,6 @@ class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
/// Insert \p BB in the basic block list at \p Position. \Returns an iterator
/// to the newly inserted BB.
Function::iterator insert(Function::iterator Position, BasicBlock *BB) {
- BB->setIsNewDbgInfoFormat(IsNewDbgInfoFormat);
return BasicBlocks.insert(Position, BB);
}
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index c86c9e5e009dc47..b5ccdf020a4c006 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -29,7 +29,6 @@
namespace llvm {
class BasicBlock;
-class DPMarker;
class FastMathFlags;
class MDNode;
class Module;
@@ -52,12 +51,6 @@ class Instruction : public User,
/// O(1) local dominance checks between instructions.
mutable unsigned Order = 0;
-public:
- /// Optional marker recording the position for debugging information that
- /// takes effect immediately before this instruction. Null unless there is
- /// debugging information present.
- DPMarker *DbgMarker = nullptr;
-
protected:
// The 15 first bits of `Value::SubclassData` are available for subclasses of
// `Instruction` to use.
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index a245dabe086f045..9659dbe4f281e42 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -43,7 +43,6 @@ namespace llvm {
class Module;
class ModuleSlotTracker;
class raw_ostream;
-class DPValue;
template <typename T> class StringMapEntry;
template <typename ValueTy> class StringMapEntryStorage;
class Type;
@@ -202,78 +201,6 @@ class MetadataAsValue : public Value {
void untrack();
};
-/// Base class for tracking ValueAsMetadata/DIArgLists with user lookups and
-/// Owner callbacks outside of ValueAsMetadata.
-///
-/// Currently only inherited by DPValue; if other classes need to use it, then
-/// a SubclassID will need to be added (either as a new field or by making
-/// DebugValue into a PointerIntUnion) to discriminate between the subclasses in
-/// lookup and callback handling.
-class DebugValueUser {
-protected:
- Metadata *DebugValue;
-
-public:
- DPValue *getUser();
- const DPValue *getUser() const;
- void handleChangedValue(Metadata *NewDebugValue);
- DebugValueUser() = default;
- explicit DebugValueUser(Metadata *DebugValue) : DebugValue(DebugValue) {
- trackDebugValue();
- }
-
- DebugValueUser(DebugValueUser &&X) : DebugValue(X.DebugValue) {
- retrackDebugValue(X);
- }
- DebugValueUser(const DebugValueUser &X) : DebugValue(X.DebugValue) {
- trackDebugValue();
- }
-
- DebugValueUser &operator=(DebugValueUser &&X) {
- if (&X == this)
- return *this;
-
- untrackDebugValue();
- DebugValue = X.DebugValue;
- retrackDebugValue(X);
- return *this;
- }
-
- DebugValueUser &operator=(const DebugValueUser &X) {
- if (&X == this)
- return *this;
-
- untrackDebugValue();
- DebugValue = X.DebugValue;
- trackDebugValue();
- return *this;
- }
-
- ~DebugValueUser() { untrackDebugValue(); }
-
- void resetDebugValue() {
- untrackDebugValue();
- DebugValue = nullptr;
- }
- void resetDebugValue(Metadata *DebugValue) {
- untrackDebugValue();
- this->DebugValue = DebugValue;
- trackDebugValue();
- }
-
- bool operator==(const DebugValueUser &X) const {
- return DebugValue == X.DebugValue;
- }
- bool operator!=(const DebugValueUser &X) const {
- return DebugValue != X.DebugValue;
- }
-
-private:
- void trackDebugValue();
- void untrackDebugValue();
- void retrackDebugValue(DebugValueUser &X);
-};
-
/// API for tracking metadata references through RAUW and deletion.
///
/// Shared API for updating \a Metadata pointers in subclasses that support
@@ -314,15 +241,6 @@ class MetadataTracking {
return track(Ref, MD, &Owner);
}
- /// Track the reference to metadata for \a DebugValueUser.
- ///
- /// As \a track(Metadata*&), but with support for calling back to \c Owner to
- /// tell it that its operand changed. This could trigger \c Owner being
- /// re-uniqued.
- static bool track(void *Ref, Metadata &MD, DebugValueUser &Owner) {
- return track(Ref, MD, &Owner);
- }
-
/// Stop tracking a reference to metadata.
///
/// Stops \c *MD from tracking \c MD.
@@ -345,7 +263,7 @@ class MetadataTracking {
/// Check whether metadata is replaceable.
static bool isReplaceable(const Metadata &MD);
- using OwnerTy = PointerUnion<MetadataAsValue *, Metadata *, DebugValueUser *>;
+ using OwnerTy = PointerUnion<MetadataAsValue *, Metadata *>;
private:
/// Track a reference to metadata for an owner.
@@ -357,8 +275,8 @@ class MetadataTracking {
/// Shared implementation of use-lists for replaceable metadata.
///
/// Most metadata cannot be RAUW'ed. This is a shared implementation of
-/// use-lists and associated API for the three that support it (
-/// \a ValueAsMetadata, \a TempMDNode, and \a DIArgList).
+/// use-lists and associated API for the two that support it (\a ValueAsMetadata
+/// and \a TempMDNode).
class ReplaceableMetadataImpl {
friend class MetadataTracking;
@@ -387,8 +305,6 @@ class ReplaceableMetadataImpl {
static void SalvageDebugInfo(const Constant &C);
/// Returns the list of all DIArgList users of this.
SmallVector<Metadata *> getAllArgListUsers();
- /// Returns the list of all DPValue users of this.
- SmallVector<DPValue *> getAllDPValueUsers();
/// Resolve all uses of this.
///
@@ -472,9 +388,6 @@ class ValueAsMetadata : public Metadata, ReplaceableMetadataImpl {
SmallVector<Metadata *> getAllArgListUsers() {
return ReplaceableMetadataImpl::getAllArgListUsers();
}
- SmallVector<DPValue *> getAllDPValueUsers() {
- return ReplaceableMetadataImpl::getAllDPValueUsers();
- }
static void handleDeletion(Value *V);
static void handleRAUW(Value *From, Value *To);
@@ -1220,15 +1133,11 @@ class MDNode : public Metadata {
bool isDistinct() const { return Storage == Distinct; }
bool isTemporary() const { return Storage == Temporary; }
- bool isReplaceable() const {
- return isTemporary() || getMetadataID() == DIArgListKind;
- }
-
/// RAUW a temporary.
///
/// \pre \a isTemporary() must be \c true.
void replaceAllUsesWith(Metadata *MD) {
- assert(isReplaceable() && "Expected temporary/replaceable node");
+ assert(isTemporary() && "Expected temporary node");
if (Context.hasReplaceableUses())
Context.getReplaceableUses()->replaceAllUsesWith(MD);
}
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 68a89dc45c2834a..70beddddc1c1615 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -213,27 +213,6 @@ class LLVM_EXTERNAL_VISIBILITY Module {
/// @name Constructors
/// @{
public:
- /// Is this Module using intrinsics to record the position of debugging
- /// information, or non-intrinsic records? See IsNewDbgInfoFormat in
- /// \ref BasicBlock.
- bool IsNewDbgInfoFormat;
-
- /// \see BasicBlock::convertToNewDbgValues.
- void convertToNewDbgValues() {
- for (auto &F : *this) {
- F.convertToNewDbgValues();
- }
- IsNewDbgInfoFormat = true;
- }
-
- /// \see BasicBlock::convertFromNewDbgValues.
- void convertFromNewDbgValues() {
- for (auto &F : *this) {
- F.convertFromNewDbgValues();
- }
- IsNewDbgInfoFormat = false;
- }
-
/// The Module constructor. Note that there is no default constructor. You
/// must provide a name for the module upon construction.
explicit Module(StringRef ModuleID, LLVMContext& C);
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index 0aba608290e05b7..46b1a3b37132bee 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -20,171 +20,12 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Type.h"
-#include "llvm/Support/CommandLine.h"
-
-#include "LLVMContextImpl.h"
using namespace llvm;
#define DEBUG_TYPE "ir"
STATISTIC(NumInstrRenumberings, "Number of renumberings across all blocks");
-cl::opt<bool>
- UseNewDbgInfoFormat("experimental-debuginfo-iterators",
- cl::desc("Enable communicating debuginfo positions "
- "through iterators, eliminating intrinsics"),
- cl::init(false));
-
-DPMarker *BasicBlock::createMarker(Instruction *I) {
- assert(IsNewDbgInfoFormat &&
- "Tried to create a marker in a non new debug-info block!");
- assert(I->DbgMarker == nullptr &&
- "Tried to create marker for instuction that already has one!");
- DPMarker *Marker = new DPMarker();
- Marker->MarkedInstr = I;
- I->DbgMarker = Marker;
- return Marker;
-}
-
-DPMarker *BasicBlock::createMarker(InstListType::iterator It) {
- assert(IsNewDbgInfoFormat &&
- "Tried to create a marker in a non new debug-info block!");
- if (It != end())
- return createMarker(&*It);
- DPMarker *DPM = getTrailingDPValues();
- if (DPM)
- return DPM;
- DPM = new DPMarker();
- setTrailingDPValues(DPM);
- return DPM;
-}
-
-void BasicBlock::convertToNewDbgValues() {
- // Is the command line option set?
- if (!UseNewDbgInfoFormat)
- return;
-
- IsNewDbgInfoFormat = true;
-
- // Iterate over all instructions in the instruction list, collecting dbg.value
- // instructions and converting them to DPValues. Once we find a "real"
- // instruction, attach all those DPValues to a DPMarker in that instruction.
- SmallVector<DPValue *, 4> DPVals;
- for (Instruction &I : make_early_inc_range(InstList)) {
- assert(!I.DbgMarker && "DbgMarker already set on old-format instrs?");
- if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(&I)) {
- // Convert this dbg.value to a DPValue.
- DPValue *Value = new DPValue(DVI);
- DPVals.push_back(Value);
- DVI->eraseFromParent();
- continue;
- }
-
- // Create a marker to store DPValues in. Technically we don't need to store
- // one marker per instruction, but that's a future optimisation.
- createMarker(&I);
- DPMarker *Marker = I.DbgMarker;
-
- for (DPValue *DPV : DPVals)
- Marker->insertDPValue(DPV, false);
-
- DPVals.clear();
- }
-}
-
-void BasicBlock::convertFromNewDbgValues() {
- invalidateOrders();
- IsNewDbgInfoFormat = false;
-
- // Iterate over the block, finding instructions annotated with DPMarkers.
- // Convert any attached DPValues to dbg.values and insert ahead of the
- // instruction.
- for (auto &Inst : *this) {
- if (!Inst.DbgMarker)
- continue;
-
- DPMarker &Marker = *Inst.DbgMarker;
- for (DPValue &DPV : Marker.getDbgValueRange())
- InstList.insert(Inst.getIterator(),
- DPV.createDebugIntrinsic(getModule(), nullptr));
-
- Marker.eraseFromParent();
- };
-
- // Assume no trailing DPValues: we could technically create them at the end
- // of the block, after a terminator, but this would be non-cannonical and
- // indicates that something else is broken somewhere.
- assert(!getTrailingDPValues());
-}
-
-bool BasicBlock::validateDbgValues(bool Assert, bool Msg, raw_ostream *OS) {
- bool RetVal = false;
- if (!OS)
- OS = &errs();
-
- // Helper lambda for reporting failures: via assertion, printing, and return
- // value.
- auto TestFailure = [Assert, Msg, &RetVal, OS](bool Val, const char *Text) {
- // Did the test fail?
- if (Val)
- return;
-
- // If we're asserting, then fire off an assertion.
- if (Assert)
- llvm_unreachable(Text);
-
- if (Msg)
- *OS << Text << "\n";
- RetVal = true;
- };
-
- // We should have the same debug-format as the parent function.
- TestFailure(getParent()->IsNewDbgInfoFormat == IsNewDbgInfoFormat,
- "Parent function doesn't have the same debug-info format");
-
- // Only validate if we are using the new format.
- if (!IsNewDbgInfoFormat)
- return RetVal;
-
- // Match every DPMarker to every Instruction and vice versa, and
- // verify that there are no invalid DPValues.
- for (auto It = begin(); It != end(); ++It) {
- if (!It->DbgMarker)
- continue;
-
- // Validate DebugProgramMarkers.
- DPMarker *CurrentDebugMarker = It->DbgMarker;
-
- // If this is a marker, it should match the instruction and vice versa.
- TestFailure(CurrentDebugMarker->MarkedInstr == &*It,
- "Debug Marker points to incorrect instruction?");
-
- // Now validate any DPValues in the marker.
- for (DPValue &DPV : CurrentDebugMarker->getDbgValueRange()) {
- // Validate DebugProgramValues.
- TestFailure(DPV.getMarker() == CurrentDebugMarker,
- "Not pointing at correct next marker!");
-
- // Verify that no DbgValues appear prior to PHIs.
- TestFailure(
- !isa<PHINode>(It),
- "DebugProgramValues must not appear before PHI nodes in a block!");
- }
- }
-
- // Except transiently when removing + re-inserting the block terminator, there
- // should be no trailing DPValues.
- TestFailure(!getTrailingDPValues(), "Trailing DPValues in block");
- return RetVal;
-}
-
-void BasicBlock::setIsNewDbgInfoFormat(bool NewFlag) {
- if (NewFlag && !IsNewDbgInfoFormat)
- convertToNewDbgValues();
- else if (!NewFlag && IsNewDbgInfoFormat)
- convertFromNewDbgValues();
-}
-
ValueSymbolTable *BasicBlock::getValueSymbolTable() {
if (Function *F = getParent())
return F->getValueSymbolTable();
@@ -206,8 +47,7 @@ template class llvm::SymbolTableListTraits<Instruction,
BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
BasicBlock *InsertBefore)
- : Value(Type::getLabelTy(C), Value::BasicBlockVal),
- IsNewDbgInfoFormat(false), Parent(nullptr) {
+ : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(nullptr) {
if (NewParent)
insertInto(NewParent, InsertBefore);
@@ -216,16 +56,12 @@ BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
"Cannot insert block before another block with no function!");
setName(Name);
- if (NewParent)
- setIsNewDbgInfoFormat(NewParent->IsNewDbgInfoFormat);
}
void BasicBlock::insertInto(Function *NewParent, BasicBlock *InsertBefore) {
assert(NewParent && "Expected a parent");
assert(!Parent && "Already has a parent");
- setIsNewDbgInfoFormat(NewParent->IsNewDbgInfoFormat);
-
if (InsertBefore)
NewParent->insert(InsertBefore->getIterator(), this);
else
@@ -255,11 +91,6 @@ BasicBlock::~BasicBlock() {
assert(getParent() == nullptr && "BasicBlock still linked into the program!");
dropAllReferences();
- for (auto &Inst : *this) {
- if (!Inst.DbgMarker)
- continue;
- Inst.DbgMarker->eraseFromParent();
- }
InstList.clear();
}
@@ -757,16 +588,3 @@ void BasicBlock::validateInstrOrdering() const {
}
}
#endif
-
-void BasicBlock::setTrailingDPValues(DPMarker *foo) {
- getContext().pImpl->setTrailingDPValues(this, foo);
-}
-
-DPMarker *BasicBlock::getTrailingDPValues() {
- return getContext().pImpl->getTrailingDPValues(this);
-}
-
-void BasicBlock::deleteTrailingDPValues() {
- getContext().pImpl->deleteTrailingDPValues(this);
-}
-
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 5fe3d8029e7d35f..d9656a24d0ed3fb 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -17,7 +17,6 @@ add_llvm_component_library(LLVMCore
DataLayout.cpp
DebugInfo.cpp
DebugInfoMetadata.cpp
- DebugProgramInstruction.cpp
DebugLoc.cpp
DiagnosticHandler.cpp
DiagnosticInfo.cpp
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index e05fd29d3bac2bc..f7f36129ec8557c 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -2135,14 +2135,8 @@ void DIArgList::handleChangedOperand(void *Ref, Metadata *New) {
}
}
if (Uniq) {
- MDNode *UniqueArgList = uniquify();
- if (UniqueArgList != this) {
- replaceAllUsesWith(UniqueArgList);
- // Clear this here so we don't try to untrack in the destructor.
- Args.clear();
- delete this;
- return;
- }
+ if (uniquify() != this)
+ storeDistinctInContext();
}
track();
}
diff --git a/llvm/lib/IR/DebugProgramInstruction.cpp b/llvm/lib/IR/DebugProgramInstruction.cpp
deleted file mode 100644
index 3f39bae983253d0..000000000000000
--- a/llvm/lib/IR/DebugProgramInstruction.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-//======-- DebugProgramInstruction.cpp - Implement DPValues/DPMarkers --======//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/DebugProgramInstruction.h"
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/IntrinsicInst.h"
-
-namespace llvm {
-
-DPValue::DPValue(const DbgVariableIntrinsic *DVI)
- : DebugValueUser(DVI->getRawLocation()), Variable(DVI->getVariable()),
- Expression(DVI->getExpression()), DbgLoc(DVI->getDebugLoc()) {
- switch (DVI->getIntrinsicID()) {
- case Intrinsic::dbg_value:
- Type = LocationType::Value;
- break;
- case Intrinsic::dbg_declare:
- Type = LocationType::Declare;
- break;
- default:
- llvm_unreachable(
- "Trying to create a DPValue with an invalid intrinsic type!");
- }
-}
-
-DPValue::DPValue(const DPValue &DPV)
- : DebugValueUser(DPV.getRawLocation()),
- Variable(DPV.getVariable()), Expression(DPV.getExpression()),
- DbgLoc(DPV.getDebugLoc()), Type(DPV.getType()) {}
-
-DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
- const DILocation *DI)
- : DebugValueUser(Location), Variable(DV), Expression(Expr), DbgLoc(DI),
- Type(LocationType::Value) {
-}
-
-void DPValue::deleteInstr() { delete this; }
-
-iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const {
- auto *MD = getRawLocation();
- // If a Value has been deleted, the "location" for this DPValue will be
- // replaced by nullptr. Return an empty range.
- if (!MD)
- return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
- location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
-
- // If operand is ValueAsMetadata, return a range over just that operand.
- if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))
- return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
-
- // If operand is DIArgList, return a range over its args.
- if (auto *AL = dyn_cast<DIArgList>(MD))
- return {location_op_iterator(AL->args_begin()),
- location_op_iterator(AL->args_end())};
-
- // Operand is an empty metadata tuple, so return empty iterator.
- assert(cast<MDNode>(MD)->getNumOperands() == 0);
- return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
- location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
-}
-
-Value *DPValue::getVariableLocationOp(unsigned OpIdx) const {
- auto *MD = getRawLocation();
- if (!MD)
- return nullptr;
-
- if (auto *AL = dyn_cast<DIArgList>(MD))
- return AL->getArgs()[OpIdx]->getValue();
- if (isa<MDNode>(MD))
- return nullptr;
- assert(isa<ValueAsMetadata>(MD) &&
- "Attempted to get location operand from DPValue with none.");
- auto *V = cast<ValueAsMetadata>(MD);
- assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "
- "single location operand.");
- return V->getValue();
-}
-
-static ValueAsMetadata *getAsMetadata(Value *V) {
- return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(
- cast<MetadataAsValue>(V)->getMetadata())
- : ValueAsMetadata::get(V);
-}
-
-void DPValue::replaceVariableLocationOp(Value *OldValue, Value *NewValue,
- bool AllowEmpty) {
- assert(NewValue && "Values must be non-null");
- auto Locations = location_ops();
- auto OldIt = find(Locations, OldValue);
- if (OldIt == Locations.end()) {
- if (AllowEmpty)
- return;
- llvm_unreachable("OldValue must be a current location");
- }
-
- if (!hasArgList()) {
- // Set our location to be the MAV wrapping the new Value.
- setRawLocation(isa<MetadataAsValue>(NewValue)
- ? cast<MetadataAsValue>(NewValue)->getMetadata()
- : ValueAsMetadata::get(NewValue));
- return;
- }
-
- // We must be referring to a DIArgList, produce a new operands vector with the
- // old value replaced, generate a new DIArgList and set it as our location.
- SmallVector<ValueAsMetadata *, 4> MDs;
- ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
- for (auto *VMD : Locations)
- MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));
- setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
-}
-
-void DPValue::replaceVariableLocationOp(unsigned OpIdx, Value *NewValue) {
- assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index");
-
- if (!hasArgList()) {
- setRawLocation(isa<MetadataAsValue>(NewValue)
- ? cast<MetadataAsValue>(NewValue)->getMetadata()
- : ValueAsMetadata::get(NewValue));
- return;
- }
-
- SmallVector<ValueAsMetadata *, 4> MDs;
- ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
- for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx)
- MDs.push_back(Idx == OpIdx ? NewOperand
- : getAsMetadata(getVariableLocationOp(Idx)));
-
- setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
-}
-
-void DPValue::addVariableLocationOps(ArrayRef<Value *> NewValues,
- DIExpression *NewExpr) {
- assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +
- NewValues.size()) &&
- "NewExpr for debug variable intrinsic does not reference every "
- "location operand.");
- assert(!is_contained(NewValues, nullptr) && "New values must be non-null");
- setExpression(NewExpr);
- SmallVector<ValueAsMetadata *, 4> MDs;
- for (auto *VMD : location_ops())
- MDs.push_back(getAsMetadata(VMD));
- for (auto *VMD : NewValues)
- MDs.push_back(getAsMetadata(VMD));
- setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
-}
-
-std::optional<uint64_t> DPValue::getFragmentSizeInBits() const {
- if (auto Fragment = getExpression()->getFragmentInfo())
- return Fragment->SizeInBits;
- return getVariable()->getSizeInBits();
-}
-
-DPValue *DPValue::clone() const { return new DPValue(*this); }
-
-DbgVariableIntrinsic *
-DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
- [[maybe_unused]] DICompileUnit *Unit =
- getDebugLoc().get()->getScope()->getSubprogram()->getUnit();
- assert(M && Unit &&
- "Cannot clone from BasicBlock that is not part of a Module or "
- "DICompileUnit!");
- LLVMContext &Context = getDebugLoc()->getContext();
- Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
- MetadataAsValue::get(Context, getVariable()),
- MetadataAsValue::get(Context, getExpression())};
- Function *IntrinsicFn;
-
- // Work out what sort of intrinsic we're going to produce.
- switch (getType()) {
- case DPValue::LocationType::Declare:
- IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
- break;
- case DPValue::LocationType::Value:
- IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
- break;
- }
-
- // Create the intrinsic from this DPValue's information, optionally insert
- // into the target location.
- DbgVariableIntrinsic *DVI = cast<DbgVariableIntrinsic>(
- CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
- DVI->setTailCall();
- DVI->setDebugLoc(getDebugLoc());
- if (InsertBefore)
- DVI->insertBefore(InsertBefore);
-
- return DVI;
-}
-
-void DPValue::handleChangedLocation(Metadata *NewLocation) {
- resetDebugValue(NewLocation);
-}
-
-const BasicBlock *DPValue::getParent() const {
- return Marker->MarkedInstr->getParent();
-}
-
-BasicBlock *DPValue::getParent() { return Marker->MarkedInstr->getParent(); }
-
-BasicBlock *DPValue::getBlock() { return Marker->getParent(); }
-
-const BasicBlock *DPValue::getBlock() const { return Marker->getParent(); }
-
-Function *DPValue::getFunction() { return getBlock()->getParent(); }
-
-const Function *DPValue::getFunction() const { return getBlock()->getParent(); }
-
-Module *DPValue::getModule() { return getFunction()->getParent(); }
-
-const Module *DPValue::getModule() const { return getFunction()->getParent(); }
-
-LLVMContext &DPValue::getContext() { return getBlock()->getContext(); }
-
-const LLVMContext &DPValue::getContext() const {
- return getBlock()->getContext();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-// An empty, global, DPMarker for the purpose of describing empty ranges of
-// DPValues.
-DPMarker DPMarker::EmptyDPMarker;
-
-void DPMarker::dropDPValues() {
- while (!StoredDPValues.empty()) {
- auto It = StoredDPValues.begin();
- DPValue *DPV = &*It;
- StoredDPValues.erase(It);
- DPV->deleteInstr();
- }
-}
-
-void DPMarker::dropOneDPValue(DPValue *DPV) {
- assert(DPV->getMarker() == this);
- StoredDPValues.erase(DPV->getIterator());
- DPV->deleteInstr();
-}
-
-const BasicBlock *DPMarker::getParent() const {
- return MarkedInstr->getParent();
-}
-
-BasicBlock *DPMarker::getParent() { return MarkedInstr->getParent(); }
-
-void DPMarker::removeMarker() {
- // Are there any DPValues in this DPMarker? If not, nothing to preserve.
- Instruction *Owner = MarkedInstr;
- if (StoredDPValues.empty()) {
- eraseFromParent();
- Owner->DbgMarker = nullptr;
- return;
- }
-
- // The attached DPValues need to be preserved; attach them to the next
- // instruction. If there isn't a next instruction, put them on the
- // "trailing" list.
- // (This logic gets refactored in a future patch, needed to break some
- // dependencies here).
- BasicBlock::iterator NextInst = std::next(Owner->getIterator());
- DPMarker *NextMarker;
- if (NextInst == Owner->getParent()->end()) {
- NextMarker = new DPMarker();
- Owner->getParent()->setTrailingDPValues(NextMarker);
- } else {
- NextMarker = NextInst->DbgMarker;
- }
- NextMarker->absorbDebugValues(*this, true);
-
- eraseFromParent();
-}
-
-void DPMarker::removeFromParent() {
- MarkedInstr->DbgMarker = nullptr;
- MarkedInstr = nullptr;
-}
-
-void DPMarker::eraseFromParent() {
- if (MarkedInstr)
- removeFromParent();
- dropDPValues();
- delete this;
-}
-
-iterator_range<DPValue::self_iterator> DPMarker::getDbgValueRange() {
- return make_range(StoredDPValues.begin(), StoredDPValues.end());
-}
-
-void DPValue::removeFromParent() {
- getMarker()->StoredDPValues.erase(getIterator());
-}
-
-void DPValue::eraseFromParent() {
- removeFromParent();
- deleteInstr();
-}
-
-void DPMarker::insertDPValue(DPValue *New, bool InsertAtHead) {
- auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
- StoredDPValues.insert(It, *New);
- New->setMarker(this);
-}
-
-void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) {
- auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
- for (DPValue &DPV : Src.StoredDPValues)
- DPV.setMarker(this);
-
- StoredDPValues.splice(It, Src.StoredDPValues);
-}
-
-iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom(
- DPMarker *From, std::optional<simple_ilist<DPValue>::iterator> from_here,
- bool InsertAtHead) {
- DPValue *First = nullptr;
- // Work out what range of DPValues to clone: normally all the contents of the
- // "From" marker, optionally we can start from the from_here position down to
- // end().
- auto Range =
- make_range(From->StoredDPValues.begin(), From->StoredDPValues.end());
- if (from_here.has_value())
- Range = make_range(*from_here, From->StoredDPValues.end());
-
- // Clone each DPValue and insert into StoreDPValues; optionally place them at
- // the start or the end of the list.
- auto Pos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
- for (DPValue &DPV : Range) {
- DPValue *New = DPV.clone();
- New->setMarker(this);
- StoredDPValues.insert(Pos, *New);
- if (!First)
- First = New;
- }
-
- if (!First)
- return {StoredDPValues.end(), StoredDPValues.end()};
-
- if (InsertAtHead)
- // If InsertAtHead is set, we cloned a range onto the front of of the
- // StoredDPValues collection, return that range.
- return {StoredDPValues.begin(), Pos};
- else
- // We inserted a block at the end, return that range.
- return {First->getIterator(), StoredDPValues.end()};
-}
-
-} // end namespace llvm
-
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 49e0c1c5883c265..658aa67a38c937f 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -81,27 +81,6 @@ static cl::opt<unsigned> NonGlobalValueMaxNameSize(
"non-global-value-max-name-size", cl::Hidden, cl::init(1024),
cl::desc("Maximum size for the name of non-global values."));
-void Function::convertToNewDbgValues() {
- IsNewDbgInfoFormat = true;
- for (auto &BB : *this) {
- BB.convertToNewDbgValues();
- }
-}
-
-void Function::convertFromNewDbgValues() {
- IsNewDbgInfoFormat = false;
- for (auto &BB : *this) {
- BB.convertFromNewDbgValues();
- }
-}
-
-void Function::setIsNewDbgInfoFormat(bool NewFlag) {
- if (NewFlag && !IsNewDbgInfoFormat)
- convertToNewDbgValues();
- else if (!NewFlag && IsNewDbgInfoFormat)
- convertFromNewDbgValues();
-}
-
//===----------------------------------------------------------------------===//
// Argument Implementation
//===----------------------------------------------------------------------===//
@@ -423,7 +402,7 @@ Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace,
: GlobalObject(Ty, Value::FunctionVal,
OperandTraits<Function>::op_begin(this), 0, Linkage, name,
computeAddrSpace(AddrSpace, ParentModule)),
- NumArgs(Ty->getNumParams()), IsNewDbgInfoFormat(false) {
+ NumArgs(Ty->getNumParams()) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
"invalid return type");
setGlobalObjectSubClassData(0);
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index 406850b7de24816..2076eeed9417691 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/lib/IR/LLVMContextImpl.cpp
@@ -45,14 +45,6 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) {}
LLVMContextImpl::~LLVMContextImpl() {
-#ifndef NDEBUG
- // Check that any variable location records that fell off the end of a block
- // when it's terminator was removed were eventually replaced. This assertion
- // firing indicates that DPValues went missing during the lifetime of the
- // LLVMContext.
- assert(TrailingDPValues.empty() && "DPValue records in blocks not cleaned");
-#endif
-
// NOTE: We need to delete the contents of OwnedModules, but Module's dtor
// will call LLVMContextImpl::removeModule, thus invalidating iterators into
// the container. Avoid iterators during this operation:
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index ebc444fcb6896e9..4cc3f8da6b75b5d 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -57,7 +57,6 @@ class AttributeListImpl;
class AttributeSetNode;
class BasicBlock;
struct DiagnosticHandler;
-class DPMarker;
class ElementCount;
class Function;
class GlobalObject;
@@ -1634,36 +1633,6 @@ class LLVMContextImpl {
/// The lifetime of the object must be guaranteed to extend as long as the
/// LLVMContext is used by compilation.
void setOptPassGate(OptPassGate &);
-
- /// Mapping of blocks to collections of "trailing" DPValues. As part of the
- /// "RemoveDIs" project, debug-info variable location records are going to
- /// cease being instructions... which raises the problem of where should they
- /// be recorded when we remove the terminator of a blocks, such as:
- ///
- /// %foo = add i32 0, 0
- /// br label %bar
- ///
- /// If the branch is removed, a legitimate transient state while editing a
- /// block, any debug-records between those two instructions will not have a
- /// location. Each block thus records any DPValue records that "trail" in
- /// such a way. These are stored in LLVMContext because typically LLVM only
- /// edits a small number of blocks at a time, so there's no need to bloat
- /// BasicBlock with such a data structure.
- SmallDenseMap<BasicBlock *, DPMarker *> TrailingDPValues;
-
- // Set, get and delete operations for TrailingDPValues.
- void setTrailingDPValues(BasicBlock *B, DPMarker *M) {
- assert(!TrailingDPValues.count(B));
- TrailingDPValues[B] = M;
- }
-
- DPMarker *getTrailingDPValues(BasicBlock *B) {
- return TrailingDPValues.lookup(B);
- }
-
- void deleteTrailingDPValues(BasicBlock *B) {
- TrailingDPValues.erase(B);
- }
};
} // end namespace llvm
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 5d0cd33fb94c48a..7860280619bb941 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -147,32 +147,6 @@ void MetadataAsValue::untrack() {
MetadataTracking::untrack(MD);
}
-DPValue *DebugValueUser::getUser() { return static_cast<DPValue *>(this); }
-const DPValue *DebugValueUser::getUser() const {
- return static_cast<const DPValue *>(this);
-}
-void DebugValueUser::handleChangedValue(Metadata *NewMD) {
- getUser()->handleChangedLocation(NewMD);
-}
-
-void DebugValueUser::trackDebugValue() {
- if (DebugValue)
- MetadataTracking::track(&DebugValue, *DebugValue, *this);
-}
-
-void DebugValueUser::untrackDebugValue() {
- if (DebugValue)
- MetadataTracking::untrack(DebugValue);
-}
-
-void DebugValueUser::retrackDebugValue(DebugValueUser &X) {
- assert(DebugValue == X.DebugValue && "Expected values to match");
- if (X.DebugValue) {
- MetadataTracking::retrack(X.DebugValue, DebugValue);
- X.DebugValue = nullptr;
- }
-}
-
bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) {
assert(Ref && "Expected live reference");
assert((Owner || *static_cast<Metadata **>(Ref) == &MD) &&
@@ -221,8 +195,6 @@ SmallVector<Metadata *> ReplaceableMetadataImpl::getAllArgListUsers() {
SmallVector<std::pair<OwnerTy, uint64_t> *> MDUsersWithID;
for (auto Pair : UseMap) {
OwnerTy Owner = Pair.second.first;
- if (Owner.isNull())
- continue;
if (!isa<Metadata *>(Owner))
continue;
Metadata *OwnerMD = cast<Metadata *>(Owner);
@@ -238,25 +210,6 @@ SmallVector<Metadata *> ReplaceableMetadataImpl::getAllArgListUsers() {
return MDUsers;
}
-SmallVector<DPValue *> ReplaceableMetadataImpl::getAllDPValueUsers() {
- SmallVector<std::pair<OwnerTy, uint64_t> *> DPVUsersWithID;
- for (auto Pair : UseMap) {
- OwnerTy Owner = Pair.second.first;
- if (Owner.isNull())
- continue;
- if (!Owner.is<DebugValueUser *>())
- continue;
- DPVUsersWithID.push_back(&UseMap[Pair.first]);
- }
- llvm::sort(DPVUsersWithID, [](auto UserA, auto UserB) {
- return UserA->second < UserB->second;
- });
- SmallVector<DPValue *> DPVUsers;
- for (auto UserWithID : DPVUsersWithID)
- DPVUsers.push_back(UserWithID->first.get<DebugValueUser *>()->getUser());
- return DPVUsers;
-}
-
void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) {
bool WasInserted =
UseMap.insert(std::make_pair(Ref, std::make_pair(Owner, NextIndex)))
@@ -355,11 +308,6 @@ void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
continue;
}
- if (Owner.is<DebugValueUser *>()) {
- Owner.get<DebugValueUser *>()->getUser()->handleChangedLocation(MD);
- continue;
- }
-
// There's a Metadata owner -- dispatch.
Metadata *OwnerMD = cast<Metadata *>(Owner);
switch (OwnerMD->getMetadataID()) {
@@ -395,7 +343,7 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) {
auto Owner = Pair.second.first;
if (!Owner)
continue;
- if (!Owner.is<Metadata *>())
+ if (isa<MetadataAsValue *>(Owner))
continue;
// Resolve MDNodes that point at this.
@@ -409,25 +357,18 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) {
}
ReplaceableMetadataImpl *ReplaceableMetadataImpl::getOrCreate(Metadata &MD) {
- if (auto ArgList = dyn_cast<DIArgList>(&MD))
- return ArgList->Context.getOrCreateReplaceableUses();
if (auto *N = dyn_cast<MDNode>(&MD))
return N->isResolved() ? nullptr : N->Context.getOrCreateReplaceableUses();
return dyn_cast<ValueAsMetadata>(&MD);
}
ReplaceableMetadataImpl *ReplaceableMetadataImpl::getIfExists(Metadata &MD) {
- if (auto ArgList = dyn_cast<DIArgList>(&MD)) {
- return ArgList->Context.getOrCreateReplaceableUses();
- }
if (auto *N = dyn_cast<MDNode>(&MD))
return N->isResolved() ? nullptr : N->Context.getReplaceableUses();
return dyn_cast<ValueAsMetadata>(&MD);
}
bool ReplaceableMetadataImpl::isReplaceable(const Metadata &MD) {
- if (isa<DIArgList>(&MD))
- return true;
if (auto *N = dyn_cast<MDNode>(&MD))
return !N->isResolved();
return isa<ValueAsMetadata>(&MD);
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 17efe7956a21c5d..dba660bbe5bafd3 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -71,8 +71,7 @@ template class llvm::SymbolTableListTraits<GlobalIFunc>;
Module::Module(StringRef MID, LLVMContext &C)
: Context(C), ValSymTab(std::make_unique<ValueSymbolTable>(-1)),
- ModuleID(std::string(MID)), SourceFileName(std::string(MID)), DL(""),
- IsNewDbgInfoFormat(false) {
+ ModuleID(std::string(MID)), SourceFileName(std::string(MID)), DL("") {
Context.addModule(this);
}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index e35f9fbdcf0b243..d3db7a16dc0d607 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2941,14 +2941,6 @@ void Verifier::visitBasicBlock(BasicBlock &BB) {
{
Check(I.getParent() == &BB, "Instruction has bogus parent pointer!");
}
-
- // Confirm that no issues arise from the debug program.
- if (BB.IsNewDbgInfoFormat) {
- // Configure the validate function to not fire assertions, instead print
- // errors and return true if there's a problem.
- bool RetVal = BB.validateDbgValues(false, true, OS);
- Check(!RetVal, "Invalid configuration of new-debug-info data found");
- }
}
void Verifier::visitTerminator(Instruction &I) {
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index e335def36647adb..2d45d8557f2ef6d 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -1135,7 +1135,6 @@ Error IRLinker::linkFunctionBody(Function &Dst, Function &Src) {
Dst.setPrologueData(Src.getPrologueData());
if (Src.hasPersonalityFn())
Dst.setPersonalityFn(Src.getPersonalityFn());
- assert(Src.IsNewDbgInfoFormat == Dst.IsNewDbgInfoFormat);
// Copy over the metadata attachments without remapping.
Dst.copyMetadata(&Src, 0);
@@ -1546,8 +1545,6 @@ Error IRLinker::run() {
if (Error Err = SrcM->getMaterializer()->materializeMetadata())
return Err;
- DstM.IsNewDbgInfoFormat = SrcM->IsNewDbgInfoFormat;
-
// Inherit the target data from the source module if the destination module
// doesn't have one already.
if (DstM.getDataLayout().isDefault())
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
index e2055db496d75e0..2fde7afc0c14ffb 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
@@ -331,8 +331,6 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) {
NewFunc->removeRetAttrs(RetAttrs);
// TODO: How to preserve metadata?
- NewFunc->setIsNewDbgInfoFormat(F.IsNewDbgInfoFormat);
-
// Move the body of the function into the new rewritten function, and replace
// this function with a stub.
NewFunc->splice(NewFunc->begin(), &F);
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index fb3fa8d23daa087..db9d5bc5a2cd2f3 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -161,7 +161,6 @@ doPromotion(Function *F, FunctionAnalysisManager &FAM,
F->getName());
NF->copyAttributesFrom(F);
NF->copyMetadata(F, 0);
- NF->setIsNewDbgInfoFormat(F->IsNewDbgInfoFormat);
// The new function will have the !dbg metadata copied from the original
// function. The original function may not be deleted, and dbg metadata need
diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
index 3bd0888f71d30be..01834015f3fdd42 100644
--- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -174,7 +174,6 @@ bool DeadArgumentEliminationPass::deleteDeadVarargs(Function &F) {
NF->setComdat(F.getComdat());
F.getParent()->getFunctionList().insert(F.getIterator(), NF);
NF->takeName(&F);
- NF->IsNewDbgInfoFormat = F.IsNewDbgInfoFormat;
// Loop over all the callers of the function, transforming the call sites
// to pass in a smaller number of arguments into the new function.
@@ -878,7 +877,6 @@ bool DeadArgumentEliminationPass::removeDeadStuffFromFunction(Function *F) {
// it again.
F->getParent()->getFunctionList().insert(F->getIterator(), NF);
NF->takeName(F);
- NF->IsNewDbgInfoFormat = F->IsNewDbgInfoFormat;
// Loop over all the callers of the function, transforming the call sites to
// pass in a smaller number of arguments into the new function.
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 104210564a1882a..39ac48c99ca398d 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -44,7 +44,6 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
ClonedCodeInfo *CodeInfo,
DebugInfoFinder *DIFinder) {
BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), "", F);
- NewBB->IsNewDbgInfoFormat = BB->IsNewDbgInfoFormat;
if (BB->hasName())
NewBB->setName(BB->getName() + NameSuffix);
@@ -478,7 +477,6 @@ void PruningFunctionCloner::CloneBlock(
BasicBlock *NewBB;
Twine NewName(BB->hasName() ? Twine(BB->getName()) + NameSuffix : "");
BBEntry = NewBB = BasicBlock::Create(BB->getContext(), NewName, NewFunc);
- NewBB->IsNewDbgInfoFormat = BB->IsNewDbgInfoFormat;
// It is only legal to clone a function if a block address within that
// function is never referenced outside of the function. Given that, we
diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp
index f2cde8a8c5d7b13..84ed73333416c11 100644
--- a/llvm/unittests/IR/DebugInfoTest.cpp
+++ b/llvm/unittests/IR/DebugInfoTest.cpp
@@ -23,8 +23,6 @@
using namespace llvm;
-extern cl::opt<bool> UseNewDbgInfoFormat;
-
static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
SMDiagnostic Err;
std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
@@ -745,307 +743,4 @@ TEST(AssignmentTrackingTest, InstrMethods) {
}
}
-// Test some very straight-forward operations on DPValues -- these are
-// dbg.values that have been converted to a non-instruction format.
-TEST(MetadataTest, ConvertDbgToDPValue) {
- LLVMContext C;
- std::unique_ptr<Module> M = parseIR(C, R"(
- define i16 @f(i16 %a) !dbg !6 {
- call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11
- %b = add i16 %a, 1, !dbg !11
- call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
- ret i16 0, !dbg !11
-
- exit:
- %c = add i16 %b, 1, !dbg !11
- ret i16 0, !dbg !11
- }
- declare void @llvm.dbg.value(metadata, metadata, metadata) #0
- attributes #0 = { nounwind readnone speculatable willreturn }
-
- !llvm.dbg.cu = !{!0}
- !llvm.module.flags = !{!5}
-
- !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
- !1 = !DIFile(filename: "t.ll", directory: "/")
- !2 = !{}
- !5 = !{i32 2, !"Debug Info Version", i32 3}
- !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
- !7 = !DISubroutineType(types: !2)
- !8 = !{!9}
- !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
- !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
- !11 = !DILocation(line: 1, column: 1, scope: !6)
-)");
-
- // Find the first dbg.value,
- Instruction &I = *M->getFunction("f")->getEntryBlock().getFirstNonPHI();
- const DILocalVariable *Var = nullptr;
- const DIExpression *Expr = nullptr;
- const DILocation *Loc = nullptr;
- const Metadata *MLoc = nullptr;
- DPValue *DPV1 = nullptr;
- {
- DbgValueInst *DPI = dyn_cast<DbgValueInst>(&I);
- ASSERT_TRUE(DPI);
- Var = DPI->getVariable();
- Expr = DPI->getExpression();
- Loc = DPI->getDebugLoc().get();
- MLoc = DPI->getRawLocation();
-
- // Test the creation of a DPValue and it's conversion back to a dbg.value.
- DPV1 = new DPValue(DPI);
- EXPECT_EQ(DPV1->getVariable(), Var);
- EXPECT_EQ(DPV1->getExpression(), Expr);
- EXPECT_EQ(DPV1->getDebugLoc().get(), Loc);
- EXPECT_EQ(DPV1->getRawLocation(), MLoc);
-
- // Erase dbg.value,
- DPI->eraseFromParent();
- // Re-create from DPV1, inserting at front.
- DPV1->createDebugIntrinsic(&*M,
- &M->getFunction("f")->getEntryBlock().front());
-
- Instruction *NewDPI = &M->getFunction("f")->getEntryBlock().front();
- DbgValueInst *DPI2 = dyn_cast<DbgValueInst>(NewDPI);
- ASSERT_TRUE(DPI2);
- EXPECT_EQ(DPI2->getVariable(), Var);
- EXPECT_EQ(DPI2->getExpression(), Expr);
- EXPECT_EQ(DPI2->getDebugLoc().get(), Loc);
- EXPECT_EQ(DPI2->getRawLocation(), MLoc);
- }
-
- // Fetch the second dbg.value, convert it to a DPValue,
- BasicBlock::iterator It = M->getFunction("f")->getEntryBlock().begin();
- It = std::next(std::next(It));
- DbgValueInst *DPI3 = dyn_cast<DbgValueInst>(It);
- ASSERT_TRUE(DPI3);
- DPValue *DPV2 = new DPValue(DPI3);
-
- // These dbg.values are supposed to refer to
diff erent values.
- EXPECT_NE(DPV1->getRawLocation(), DPV2->getRawLocation());
-
- // Try manipulating DPValues and markers in the exit block.
- BasicBlock *ExitBlock = &*std::next(M->getFunction("f")->getEntryBlock().getIterator());
- Instruction *FirstInst = &ExitBlock->front();
- Instruction *RetInst = &*std::next(FirstInst->getIterator());
-
- // Set-up DPMarkers in this block.
- ExitBlock->IsNewDbgInfoFormat = true;
- ExitBlock->createMarker(FirstInst);
- ExitBlock->createMarker(RetInst);
-
- // Insert DPValues into markers, order should come out DPV2, DPV1.
- FirstInst->DbgMarker->insertDPValue(DPV1, false);
- FirstInst->DbgMarker->insertDPValue(DPV2, true);
- unsigned int ItCount = 0;
- for (DPValue &Item : FirstInst->DbgMarker->getDbgValueRange()) {
- EXPECT_TRUE((&Item == DPV2 && ItCount == 0) ||
- (&Item == DPV1 && ItCount == 1));
- EXPECT_EQ(Item.getMarker(), FirstInst->DbgMarker);
- ++ItCount;
- }
-
- // Clone them onto the second marker -- should allocate new DPVs.
- RetInst->DbgMarker->cloneDebugInfoFrom(FirstInst->DbgMarker, std::nullopt, false);
- EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 2u);
- ItCount = 0;
- // Check these things store the same information; but that they're not the same
- // objects.
- for (DPValue &Item : RetInst->DbgMarker->getDbgValueRange()) {
- EXPECT_TRUE((Item.getRawLocation() == DPV2->getRawLocation() && ItCount == 0) ||
- (Item.getRawLocation() == DPV1->getRawLocation() && ItCount == 1));
-
- EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker);
- EXPECT_NE(&Item, DPV1);
- EXPECT_NE(&Item, DPV2);
- ++ItCount;
- }
-
- RetInst->DbgMarker->dropDPValues();
- EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 0u);
-
- // Try cloning one single DPValue.
- auto DIIt = std::next(FirstInst->DbgMarker->getDbgValueRange().begin());
- RetInst->DbgMarker->cloneDebugInfoFrom(FirstInst->DbgMarker, DIIt, false);
- EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 1u);
- // The second DPValue should have been cloned; it should have the same values
- // as DPV1.
- EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.begin()->getRawLocation(),
- DPV1->getRawLocation());
- // We should be able to drop individual DPValues.
- RetInst->DbgMarker->dropOneDPValue(&*RetInst->DbgMarker->StoredDPValues.begin());
-
- // "Aborb" a DPMarker: this means pretend that the instruction it's attached
- // to is disappearing so it needs to be transferred into "this" marker.
- RetInst->DbgMarker->absorbDebugValues(*FirstInst->DbgMarker, true);
- EXPECT_EQ(RetInst->DbgMarker->StoredDPValues.size(), 2u);
- // Should be the DPV1 and DPV2 objects.
- ItCount = 0;
- for (DPValue &Item : RetInst->DbgMarker->getDbgValueRange()) {
- EXPECT_TRUE((&Item == DPV2 && ItCount == 0) ||
- (&Item == DPV1 && ItCount == 1));
- EXPECT_EQ(Item.getMarker(), RetInst->DbgMarker);
- ++ItCount;
- }
-
- // Finally -- there are two DPValues left over. If we remove evrything in the
- // basic block, then they should sink down into the "TrailingDPValues"
- // container for dangling debug-info. Future facilities will restore them
- // back when a terminator is inserted.
- FirstInst->DbgMarker->removeMarker();
- FirstInst->eraseFromParent();
- RetInst->DbgMarker->removeMarker();
- RetInst->eraseFromParent();
-
- DPMarker *EndMarker = ExitBlock->getTrailingDPValues();
- ASSERT_NE(EndMarker, nullptr);
- EXPECT_EQ(EndMarker->StoredDPValues.size(), 2u);
- // Test again that it's those two DPValues, DPV1 and DPV2.
- ItCount = 0;
- for (DPValue &Item : EndMarker->getDbgValueRange()) {
- EXPECT_TRUE((&Item == DPV2 && ItCount == 0) ||
- (&Item == DPV1 && ItCount == 1));
- EXPECT_EQ(Item.getMarker(), EndMarker);
- ++ItCount;
- }
-
- // Those trailing DPValues would dangle and cause an assertion failure if
- // they lived until the end of the LLVMContext,
- ExitBlock->deleteTrailingDPValues();
-}
-
-TEST(MetadataTest, DPValueConversionRoutines) {
- LLVMContext C;
-
- // For the purpose of this test, set and un-set the command line option
- // corresponding to UseNewDbgInfoFormat.
- UseNewDbgInfoFormat = true;
-
- std::unique_ptr<Module> M = parseIR(C, R"(
- define i16 @f(i16 %a) !dbg !6 {
- call void @llvm.dbg.value(metadata i16 %a, metadata !9, metadata !DIExpression()), !dbg !11
- %b = add i16 %a, 1, !dbg !11
- call void @llvm.dbg.value(metadata i16 %b, metadata !9, metadata !DIExpression()), !dbg !11
- ret i16 0, !dbg !11
-
- exit:
- %c = add i16 %b, 1, !dbg !11
- ret i16 0, !dbg !11
- }
- declare void @llvm.dbg.value(metadata, metadata, metadata) #0
- attributes #0 = { nounwind readnone speculatable willreturn }
-
- !llvm.dbg.cu = !{!0}
- !llvm.module.flags = !{!5}
-
- !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
- !1 = !DIFile(filename: "t.ll", directory: "/")
- !2 = !{}
- !5 = !{i32 2, !"Debug Info Version", i32 3}
- !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
- !7 = !DISubroutineType(types: !2)
- !8 = !{!9}
- !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
- !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
- !11 = !DILocation(line: 1, column: 1, scope: !6)
-)");
-
- // Check that the conversion routines and utilities between dbg.value
- // debug-info format and DPValues works.
- Function *F = M->getFunction("f");
- BasicBlock *BB1 = &F->getEntryBlock();
- // First instruction should be a dbg.value.
- EXPECT_TRUE(isa<DbgValueInst>(BB1->front()));
- EXPECT_FALSE(BB1->IsNewDbgInfoFormat);
- // Validating the block for DPValues / DPMarkers shouldn't fail -- there's
- // no data stored right now.
- EXPECT_FALSE(BB1->validateDbgValues(false, false));
-
- // Function and module should be marked as not having the new format too.
- EXPECT_FALSE(F->IsNewDbgInfoFormat);
- EXPECT_FALSE(M->IsNewDbgInfoFormat);
-
- // Now convert.
- M->convertToNewDbgValues();
- EXPECT_TRUE(M->IsNewDbgInfoFormat);
- EXPECT_TRUE(F->IsNewDbgInfoFormat);
- EXPECT_TRUE(BB1->IsNewDbgInfoFormat);
-
- // There should now be no dbg.value instructions!
- // Ensure the first instruction exists, the test all of them.
- EXPECT_FALSE(isa<DbgValueInst>(BB1->front()));
- for (auto &BB : *F)
- for (auto &I : BB)
- EXPECT_FALSE(isa<DbgValueInst>(I));
-
- // There should be a DPMarker on each of the two instructions in the entry
- // block, each containing one DPValue.
- EXPECT_EQ(BB1->size(), 2u);
- Instruction *FirstInst = &BB1->front();
- Instruction *SecondInst = FirstInst->getNextNode();
- ASSERT_TRUE(FirstInst->DbgMarker);
- ASSERT_TRUE(SecondInst->DbgMarker);
- EXPECT_NE(FirstInst->DbgMarker, SecondInst->DbgMarker);
- EXPECT_EQ(FirstInst, FirstInst->DbgMarker->MarkedInstr);
- EXPECT_EQ(SecondInst, SecondInst->DbgMarker->MarkedInstr);
-
- EXPECT_EQ(FirstInst->DbgMarker->StoredDPValues.size(), 1u);
- DPValue *DPV1 = &*FirstInst->DbgMarker->getDbgValueRange().begin();
- EXPECT_EQ(DPV1->getMarker(), FirstInst->DbgMarker);
- // Should point at %a, an argument.
- EXPECT_TRUE(isa<Argument>(DPV1->getVariableLocationOp(0)));
-
- EXPECT_EQ(SecondInst->DbgMarker->StoredDPValues.size(), 1u);
- DPValue *DPV2 = &*SecondInst->DbgMarker->getDbgValueRange().begin();
- EXPECT_EQ(DPV2->getMarker(), SecondInst->DbgMarker);
- // Should point at FirstInst.
- EXPECT_EQ(DPV2->getVariableLocationOp(0), FirstInst);
-
- // There should be no DPValues / DPMarkers in the second block, but it should
- // be marked as being in the new format.
- BasicBlock *BB2 = BB1->getNextNode();
- EXPECT_TRUE(BB2->IsNewDbgInfoFormat);
- for (auto &Inst : *BB2)
- // Either there should be no marker, or it should be empty.
- EXPECT_TRUE(!Inst.DbgMarker || Inst.DbgMarker->StoredDPValues.empty());
-
- // Validating the first block should continue to not be a problem,
- EXPECT_FALSE(BB1->validateDbgValues(false, false));
- // But if we were to break something, it should be able to fire. Don't attempt
- // to comprehensively test the validator, it's a smoke-test rather than a
- // "proper" verification pass.
- DPV1->setMarker(nullptr);
- // A marker pointing the wrong way should be an error.
- EXPECT_TRUE(BB1->validateDbgValues(false, false));
- DPV1->setMarker(FirstInst->DbgMarker);
-
- DILocalVariable *DLV1 = DPV1->getVariable();
- DIExpression *Expr1 = DPV1->getExpression();
- DILocalVariable *DLV2 = DPV2->getVariable();
- DIExpression *Expr2 = DPV2->getExpression();
-
- // Convert everything back to the "old" format and ensure it's right.
- M->convertFromNewDbgValues();
- EXPECT_FALSE(M->IsNewDbgInfoFormat);
- EXPECT_FALSE(F->IsNewDbgInfoFormat);
- EXPECT_FALSE(BB1->IsNewDbgInfoFormat);
-
- EXPECT_EQ(BB1->size(), 4u);
- ASSERT_TRUE(isa<DbgValueInst>(BB1->front()));
- DbgValueInst *DVI1 = cast<DbgValueInst>(&BB1->front());
- // These dbg.values should still point at the same places.
- EXPECT_TRUE(isa<Argument>(DVI1->getVariableLocationOp(0)));
- DbgValueInst *DVI2 = cast<DbgValueInst>(DVI1->getNextNode()->getNextNode());
- EXPECT_EQ(DVI2->getVariableLocationOp(0), FirstInst);
-
- // Check a few fields too,
- EXPECT_EQ(DVI1->getVariable(), DLV1);
- EXPECT_EQ(DVI1->getExpression(), Expr1);
- EXPECT_EQ(DVI2->getVariable(), DLV2);
- EXPECT_EQ(DVI2->getExpression(), Expr2);
-
- UseNewDbgInfoFormat = false;
-}
-
} // end namespace
diff --git a/llvm/unittests/Transforms/Utils/LocalTest.cpp b/llvm/unittests/Transforms/Utils/LocalTest.cpp
index 1318163793b83a3..a27af6efb2c8104 100644
--- a/llvm/unittests/Transforms/Utils/LocalTest.cpp
+++ b/llvm/unittests/Transforms/Utils/LocalTest.cpp
@@ -1277,69 +1277,3 @@ TEST(Local, ExpressionForConstant) {
Expr = createExpression(ConstantFP::get(PPC_FP128Ty, 32), PPC_FP128Ty);
EXPECT_EQ(Expr, nullptr);
}
-
-TEST(Local, ReplaceDPValue) {
- LLVMContext C;
-
- // Test that RAUW also replaces the operands of DPValue objects, i.e.
- // non-instruction stored debugging information.
- std::unique_ptr<Module> M = parseIR(C,
- R"(
- declare void @llvm.dbg.value(metadata, metadata, metadata)
- define void @f(i32 %a) !dbg !8 {
- entry:
- %foo = add i32 %a, 1, !dbg !13
- %bar = add i32 %foo, 0, !dbg !13
- call void @llvm.dbg.value(metadata i32 %bar, metadata !11, metadata !DIExpression()), !dbg !13
- ret void, !dbg !14
- }
- !llvm.dbg.cu = !{!0}
- !llvm.module.flags = !{!3, !4}
- !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
- !1 = !DIFile(filename: "t2.c", directory: "foo")
- !2 = !{}
- !3 = !{i32 2, !"Dwarf Version", i32 4}
- !4 = !{i32 2, !"Debug Info Version", i32 3}
- !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2)
- !9 = !DISubroutineType(types: !10)
- !10 = !{null}
- !11 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !12)
- !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
- !13 = !DILocation(line: 2, column: 7, scope: !8)
- !14 = !DILocation(line: 3, column: 1, scope: !8)
- )");
- auto *GV = M->getNamedValue("f");
- ASSERT_TRUE(GV);
- auto *F = dyn_cast<Function>(GV);
- ASSERT_TRUE(F);
- BasicBlock::iterator It = F->front().begin();
- Instruction *FooInst = &*It;
- It = std::next(It);
- Instruction *BarInst = &*It;
- It = std::next(It);
- DbgValueInst *DVI = dyn_cast<DbgValueInst>(It);
- ASSERT_TRUE(DVI);
- It = std::next(It);
- Instruction *RetInst = &*It;
-
- // Convert DVI into a DPValue.
- RetInst->DbgMarker = new DPMarker();
- RetInst->DbgMarker->MarkedInstr = RetInst;
- DPValue *DPV = new DPValue(DVI);
- RetInst->DbgMarker->insertDPValue(DPV, false);
- // ... and erase the dbg.value.
- DVI->eraseFromParent();
-
- // DPV should originally refer to %bar,
- EXPECT_EQ(DPV->getVariableLocationOp(0), BarInst);
-
- // Now try to replace the computation of %bar with %foo -- this should cause
- // the DPValue's to have it's operand updated beneath it.
- BarInst->replaceAllUsesWith(FooInst);
- // Check DPV now points at %foo.
- EXPECT_EQ(DPV->getVariableLocationOp(0), FooInst);
-
- // Teardown.
- RetInst->DbgMarker->eraseFromParent();
-}
-
diff --git a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
index 8c2e8abad4a54d4..298f449e4d2ca41 100644
--- a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
@@ -31,7 +31,6 @@ static_library("IR") {
"DataLayout.cpp",
"DebugInfo.cpp",
"DebugInfoMetadata.cpp",
- "DebugProgramInstruction.cpp",
"DebugLoc.cpp",
"DiagnosticHandler.cpp",
"DiagnosticInfo.cpp",
More information about the llvm-commits
mailing list