Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
//======-- 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
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2023-11-09 13:12:31 +00:00
|
|
|
#include "llvm/IR/DebugInfoMetadata.h"
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
#include "llvm/IR/DebugProgramInstruction.h"
|
|
|
|
#include "llvm/IR/DIBuilder.h"
|
|
|
|
#include "llvm/IR/IntrinsicInst.h"
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
|
|
|
DPValue::DPValue(const DbgVariableIntrinsic *DVI)
|
2024-01-16 13:42:50 +00:00
|
|
|
: DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
|
|
|
|
Variable(DVI->getVariable()), Expression(DVI->getExpression()),
|
|
|
|
DbgLoc(DVI->getDebugLoc()), AddressExpression(nullptr) {
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
switch (DVI->getIntrinsicID()) {
|
|
|
|
case Intrinsic::dbg_value:
|
|
|
|
Type = LocationType::Value;
|
|
|
|
break;
|
|
|
|
case Intrinsic::dbg_declare:
|
|
|
|
Type = LocationType::Declare;
|
|
|
|
break;
|
2024-01-16 13:42:50 +00:00
|
|
|
case Intrinsic::dbg_assign: {
|
|
|
|
Type = LocationType::Assign;
|
|
|
|
const DbgAssignIntrinsic *Assign =
|
|
|
|
static_cast<const DbgAssignIntrinsic *>(DVI);
|
|
|
|
resetDebugValue(1, Assign->getRawAddress());
|
|
|
|
AddressExpression = Assign->getAddressExpression();
|
|
|
|
setAssignId(Assign->getAssignID());
|
|
|
|
break;
|
|
|
|
}
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
default:
|
|
|
|
llvm_unreachable(
|
|
|
|
"Trying to create a DPValue with an invalid intrinsic type!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DPValue::DPValue(const DPValue &DPV)
|
2024-01-16 13:42:50 +00:00
|
|
|
: DebugValueUser(DPV.DebugValues), Variable(DPV.getVariable()),
|
|
|
|
Expression(DPV.getExpression()), DbgLoc(DPV.getDebugLoc()),
|
|
|
|
AddressExpression(DPV.AddressExpression), Type(DPV.getType()) {}
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
|
|
|
|
DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
|
2023-12-11 11:34:53 +00:00
|
|
|
const DILocation *DI, LocationType Type)
|
2024-01-16 13:42:50 +00:00
|
|
|
: DebugValueUser({Location, nullptr, nullptr}), Variable(DV),
|
|
|
|
Expression(Expr), DbgLoc(DI), Type(Type) {}
|
|
|
|
|
|
|
|
DPValue::DPValue(Metadata *Value, DILocalVariable *Variable,
|
|
|
|
DIExpression *Expression, DIAssignID *AssignID,
|
|
|
|
Metadata *Address, DIExpression *AddressExpression,
|
|
|
|
const DILocation *DI)
|
|
|
|
: DebugValueUser({Value, Address, AssignID}), Variable(Variable),
|
|
|
|
Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
|
|
|
|
Type(LocationType::Assign) {}
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
|
|
|
|
void DPValue::deleteInstr() { delete this; }
|
|
|
|
|
2024-01-16 09:27:02 +00:00
|
|
|
DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
|
|
|
|
DIExpression *Expr, const DILocation *DI) {
|
|
|
|
return new DPValue(ValueAsMetadata::get(Location), DV, Expr, DI,
|
|
|
|
LocationType::Value);
|
|
|
|
}
|
|
|
|
|
|
|
|
DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
|
|
|
|
DIExpression *Expr, const DILocation *DI,
|
|
|
|
DPValue &InsertBefore) {
|
|
|
|
auto *NewDPValue = createDPValue(Location, DV, Expr, DI);
|
|
|
|
NewDPValue->insertBefore(&InsertBefore);
|
|
|
|
return NewDPValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV,
|
|
|
|
DIExpression *Expr, const DILocation *DI) {
|
|
|
|
return new DPValue(ValueAsMetadata::get(Address), DV, Expr, DI,
|
|
|
|
LocationType::Declare);
|
|
|
|
}
|
|
|
|
|
|
|
|
DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV,
|
|
|
|
DIExpression *Expr, const DILocation *DI,
|
|
|
|
DPValue &InsertBefore) {
|
|
|
|
auto *NewDPVDeclare = createDPVDeclare(Address, DV, Expr, DI);
|
|
|
|
NewDPVDeclare->insertBefore(&InsertBefore);
|
|
|
|
return NewDPVDeclare;
|
|
|
|
}
|
|
|
|
|
2024-01-16 13:42:50 +00:00
|
|
|
DPValue *DPValue::createDPVAssign(Value *Val, DILocalVariable *Variable,
|
|
|
|
DIExpression *Expression,
|
|
|
|
DIAssignID *AssignID, Value *Address,
|
|
|
|
DIExpression *AddressExpression,
|
|
|
|
const DILocation *DI) {
|
|
|
|
return new DPValue(ValueAsMetadata::get(Val), Variable, Expression, AssignID,
|
|
|
|
ValueAsMetadata::get(Address), AddressExpression, DI);
|
|
|
|
}
|
|
|
|
|
|
|
|
DPValue *DPValue::createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val,
|
|
|
|
DILocalVariable *Variable,
|
|
|
|
DIExpression *Expression,
|
|
|
|
Value *Address,
|
|
|
|
DIExpression *AddressExpression,
|
|
|
|
const DILocation *DI) {
|
|
|
|
auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID);
|
|
|
|
assert(Link && "Linked instruction must have DIAssign metadata attached");
|
|
|
|
auto *NewDPVAssign = DPValue::createDPVAssign(Val, Variable, Expression,
|
|
|
|
cast<DIAssignID>(Link), Address,
|
|
|
|
AddressExpression, DI);
|
|
|
|
LinkedInstr->getParent()->insertDPValueAfter(NewDPVAssign, LinkedInstr);
|
|
|
|
return NewDPVAssign;
|
|
|
|
}
|
|
|
|
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
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))};
|
|
|
|
}
|
|
|
|
|
2023-11-09 13:12:31 +00:00
|
|
|
unsigned DPValue::getNumVariableLocationOps() const {
|
|
|
|
if (hasArgList())
|
|
|
|
return cast<DIArgList>(getRawLocation())->getArgs().size();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
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");
|
2024-01-16 13:42:50 +00:00
|
|
|
|
|
|
|
bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress();
|
|
|
|
if (DbgAssignAddrReplaced)
|
|
|
|
setAddress(NewValue);
|
|
|
|
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
auto Locations = location_ops();
|
|
|
|
auto OldIt = find(Locations, OldValue);
|
|
|
|
if (OldIt == Locations.end()) {
|
2024-01-16 13:42:50 +00:00
|
|
|
if (AllowEmpty || DbgAssignAddrReplaced)
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2023-11-09 13:12:31 +00:00
|
|
|
void DPValue::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 DPValue::isKillLocation() const {
|
|
|
|
return (getNumVariableLocationOps() == 0 &&
|
|
|
|
!getExpression()->isComplex()) ||
|
|
|
|
any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
|
|
|
|
}
|
|
|
|
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
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();
|
|
|
|
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;
|
2024-01-16 13:42:50 +00:00
|
|
|
case DPValue::LocationType::Assign:
|
|
|
|
IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign);
|
|
|
|
break;
|
2023-12-12 14:46:01 +00:00
|
|
|
case DPValue::LocationType::End:
|
|
|
|
case DPValue::LocationType::Any:
|
|
|
|
llvm_unreachable("Invalid LocationType");
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create the intrinsic from this DPValue's information, optionally insert
|
|
|
|
// into the target location.
|
2024-01-16 13:42:50 +00:00
|
|
|
DbgVariableIntrinsic *DVI;
|
2024-02-07 13:06:55 +00:00
|
|
|
assert(getRawLocation() && "DPValue's RawLocation should be non-null.");
|
2024-01-16 13:42:50 +00:00
|
|
|
if (isDbgAssign()) {
|
|
|
|
Value *AssignArgs[] = {
|
|
|
|
MetadataAsValue::get(Context, getRawLocation()),
|
|
|
|
MetadataAsValue::get(Context, getVariable()),
|
|
|
|
MetadataAsValue::get(Context, getExpression()),
|
|
|
|
MetadataAsValue::get(Context, getAssignID()),
|
|
|
|
MetadataAsValue::get(Context, getRawAddress()),
|
|
|
|
MetadataAsValue::get(Context, getAddressExpression())};
|
|
|
|
DVI = cast<DbgVariableIntrinsic>(CallInst::Create(
|
|
|
|
IntrinsicFn->getFunctionType(), IntrinsicFn, AssignArgs));
|
|
|
|
} else {
|
|
|
|
Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
|
|
|
|
MetadataAsValue::get(Context, getVariable()),
|
|
|
|
MetadataAsValue::get(Context, getExpression())};
|
|
|
|
DVI = cast<DbgVariableIntrinsic>(
|
|
|
|
CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
|
|
|
|
}
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
DVI->setTailCall();
|
|
|
|
DVI->setDebugLoc(getDebugLoc());
|
|
|
|
if (InsertBefore)
|
|
|
|
DVI->insertBefore(InsertBefore);
|
|
|
|
|
|
|
|
return DVI;
|
|
|
|
}
|
|
|
|
|
2024-01-16 13:42:50 +00:00
|
|
|
Value *DPValue::getAddress() const {
|
|
|
|
auto *MD = getRawAddress();
|
|
|
|
if (auto *V = dyn_cast<ValueAsMetadata>(MD))
|
|
|
|
return V->getValue();
|
|
|
|
|
|
|
|
// When the value goes to null, it gets replaced by an empty MDNode.
|
|
|
|
assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
DIAssignID *DPValue::getAssignID() const {
|
|
|
|
return cast<DIAssignID>(DebugValues[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DPValue::setAssignId(DIAssignID *New) { resetDebugValue(2, New); }
|
|
|
|
|
|
|
|
void DPValue::setKillAddress() {
|
|
|
|
resetDebugValue(
|
|
|
|
1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType())));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DPValue::isKillAddress() const {
|
|
|
|
Value *Addr = getAddress();
|
|
|
|
return !Addr || isa<UndefValue>(Addr);
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
}
|
|
|
|
|
[DebugInfo][RemoveDIs] Add a DPValue implementation for instcombine sinking (#77930)
In instcombine, when we sink an instruction into a successor block, we try
to clone and salvage all the variable assignments that use that Value. This
is a behaviour that's (IMO) flawed, but there are important use cases where
we want to avoid regressions, thus we're implementing this for the
non-instruction debug-info representation.
This patch refactors the dbg.value sinking code into it's own function, and
installs a parallel implementation for DPValues, the non-instruction
debug-info container. This is mostly identical to the dbg.value
implementation, except that we don't have an easy-to-access ordering
between DPValues, and have to jump through extra hoops to establish one in
the (rare) cases where that ordering is required.
The test added represents a common use-case in LLVM where these behaviours
are important: a loop has been completely optimised away, leaving several
dbg.values in a row referring to an instruction that's going to sink. The
dbg.values should sink in both dbg.value and RemoveDIs mode, and
additionally only the last assignment should sink.
2024-01-25 23:28:56 +00:00
|
|
|
const Instruction *DPValue::getInstruction() const {
|
|
|
|
return Marker->MarkedInstr;
|
|
|
|
}
|
|
|
|
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2024-01-16 09:27:02 +00:00
|
|
|
void DPValue::insertBefore(DPValue *InsertBefore) {
|
|
|
|
assert(!getMarker() &&
|
|
|
|
"Cannot insert a DPValue that is already has a DPMarker!");
|
|
|
|
assert(InsertBefore->getMarker() &&
|
|
|
|
"Cannot insert a DPValue before a DPValue that does not have a "
|
|
|
|
"DPMarker!");
|
|
|
|
InsertBefore->getMarker()->insertDPValue(this, InsertBefore);
|
|
|
|
}
|
|
|
|
void DPValue::insertAfter(DPValue *InsertAfter) {
|
|
|
|
assert(!getMarker() &&
|
|
|
|
"Cannot insert a DPValue that is already has a DPMarker!");
|
|
|
|
assert(InsertAfter->getMarker() &&
|
|
|
|
"Cannot insert a DPValue after a DPValue that does not have a "
|
|
|
|
"DPMarker!");
|
|
|
|
InsertAfter->getMarker()->insertDPValueAfter(this, InsertAfter);
|
|
|
|
}
|
|
|
|
void DPValue::moveBefore(DPValue *MoveBefore) {
|
|
|
|
assert(getMarker() &&
|
|
|
|
"Canot move a DPValue that does not currently have a DPMarker!");
|
|
|
|
removeFromParent();
|
|
|
|
insertBefore(MoveBefore);
|
|
|
|
}
|
|
|
|
void DPValue::moveAfter(DPValue *MoveAfter) {
|
|
|
|
assert(getMarker() &&
|
|
|
|
"Canot move a DPValue that does not currently have a DPMarker!");
|
|
|
|
removeFromParent();
|
|
|
|
insertAfter(MoveAfter);
|
|
|
|
}
|
|
|
|
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// 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.
|
2023-11-09 13:35:52 +00:00
|
|
|
DPMarker *NextMarker = Owner->getParent()->getNextMarker(Owner);
|
[DebugInfo][RemoveDIs] Don't allocate one DPMarker per instruction (#79345)
This is an optimisation patch that shouldn't have any functional effect.
There's no need for all instructions to have a DPMarker attached to them,
because not all instructions have adjacent DPValues (aka dbg.values).
This patch inserts the appropriate conditionals into functions like
BasicBlock::spliceDebugInfo to ensure we don't step on a null pointer when
there isn't a DPMarker allocated. Mostly, this is a case of calling
createMarker occasionally, which will create a marker on an instruction
if there isn't one there already.
Also folded into this is the use of adoptDbgValues, which is a natural
extension: if we have a sequence of instructions and debug records:
%foo = add i32 %0,...
# dbg_value { %foo, ...
# dbg_value { %bar, ...
%baz = add i32 %...
%qux = add i32 %...
and delete, for example, the %baz instruction, then the dbg_value records
would naturally be transferred onto the %qux instruction (they "fall down"
onto it). There's no point in creating and splicing DPMarkers in the case
shown when %qux doesn't have a DPMarker already, we can instead just change
the owner of %baz's DPMarker from %baz to %qux. This also avoids calling
setParent on every DPValue.
Update LoopRotationUtils: it was relying on each instruction having it's
own distinct end(), so that we could express ranges and lack-of-ranges.
That's no longer true though: so switch to storing the range of DPValues on
the next instruction when we want to consider it's range next time around
the loop (see the nearby comment).
2024-02-06 13:08:44 +00:00
|
|
|
if (NextMarker) {
|
|
|
|
NextMarker->absorbDebugValues(*this, true);
|
|
|
|
eraseFromParent();
|
|
|
|
} else {
|
|
|
|
// We can avoid a deallocation -- just store this marker onto the next
|
|
|
|
// instruction. Unless we're at the end of the block, in which case this
|
|
|
|
// marker becomes the trailing marker of a degenerate block.
|
|
|
|
BasicBlock::iterator NextIt = std::next(Owner->getIterator());
|
|
|
|
if (NextIt == getParent()->end()) {
|
|
|
|
getParent()->setTrailingDPValues(this);
|
|
|
|
MarkedInstr = nullptr;
|
|
|
|
} else {
|
|
|
|
NextIt->DbgMarker = this;
|
|
|
|
MarkedInstr = &*NextIt;
|
|
|
|
}
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
}
|
[DebugInfo][RemoveDIs] Don't allocate one DPMarker per instruction (#79345)
This is an optimisation patch that shouldn't have any functional effect.
There's no need for all instructions to have a DPMarker attached to them,
because not all instructions have adjacent DPValues (aka dbg.values).
This patch inserts the appropriate conditionals into functions like
BasicBlock::spliceDebugInfo to ensure we don't step on a null pointer when
there isn't a DPMarker allocated. Mostly, this is a case of calling
createMarker occasionally, which will create a marker on an instruction
if there isn't one there already.
Also folded into this is the use of adoptDbgValues, which is a natural
extension: if we have a sequence of instructions and debug records:
%foo = add i32 %0,...
# dbg_value { %foo, ...
# dbg_value { %bar, ...
%baz = add i32 %...
%qux = add i32 %...
and delete, for example, the %baz instruction, then the dbg_value records
would naturally be transferred onto the %qux instruction (they "fall down"
onto it). There's no point in creating and splicing DPMarkers in the case
shown when %qux doesn't have a DPMarker already, we can instead just change
the owner of %baz's DPMarker from %baz to %qux. This also avoids calling
setParent on every DPValue.
Update LoopRotationUtils: it was relying on each instruction having it's
own distinct end(), so that we could express ranges and lack-of-ranges.
That's no longer true though: so switch to storing the range of DPValues on
the next instruction when we want to consider it's range next time around
the loop (see the nearby comment).
2024-02-06 13:08:44 +00:00
|
|
|
Owner->DbgMarker = nullptr;
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
2024-01-16 09:27:02 +00:00
|
|
|
iterator_range<DPValue::const_self_iterator>
|
|
|
|
DPMarker::getDbgValueRange() const {
|
|
|
|
return make_range(StoredDPValues.begin(), StoredDPValues.end());
|
|
|
|
}
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
|
|
|
|
void DPValue::removeFromParent() {
|
|
|
|
getMarker()->StoredDPValues.erase(getIterator());
|
2024-01-16 09:27:02 +00:00
|
|
|
Marker = nullptr;
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2024-01-16 09:27:02 +00:00
|
|
|
void DPMarker::insertDPValue(DPValue *New, DPValue *InsertBefore) {
|
|
|
|
assert(InsertBefore->getMarker() == this &&
|
|
|
|
"DPValue 'InsertBefore' must be contained in this DPMarker!");
|
|
|
|
StoredDPValues.insert(InsertBefore->getIterator(), *New);
|
|
|
|
New->setMarker(this);
|
|
|
|
}
|
|
|
|
void DPMarker::insertDPValueAfter(DPValue *New, DPValue *InsertAfter) {
|
|
|
|
assert(InsertAfter->getMarker() == this &&
|
|
|
|
"DPValue 'InsertAfter' must be contained in this DPMarker!");
|
|
|
|
StoredDPValues.insert(++(InsertAfter->getIterator()), *New);
|
|
|
|
New->setMarker(this);
|
|
|
|
}
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-11-30 12:41:52 +00:00
|
|
|
void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
|
|
|
|
DPMarker &Src, bool InsertAtHead) {
|
|
|
|
for (DPValue &DPV : Range)
|
|
|
|
DPV.setMarker(this);
|
|
|
|
|
|
|
|
auto InsertPos =
|
|
|
|
(InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
|
|
|
|
|
|
|
|
StoredDPValues.splice(InsertPos, Src.StoredDPValues, Range.begin(),
|
|
|
|
Range.end());
|
|
|
|
}
|
|
|
|
|
Reapply 7d77bbef4ad92, adding new debug-info classes
This reverts commit 957efa4ce4f0391147cec62746e997226ee2b836.
Original commit message below -- in this follow up, I've shifted
un-necessary inclusions of DebugProgramInstruction.h into being forward
declarations (fixes clang-compile time I hope), and a memory leak in the
DebugInfoTest.cpp IR unittests.
I also tracked a compile-time regression in D154080, more explanation
there, but the result of which is hiding some of the changes behind the
EXPERIMENTAL_DEBUGINFO_ITERATORS compile-time flag. This is tested by the
"new-debug-iterators" buildbot.
[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-info
This patch adds a variety of classes needed to record variable location
debug-info without using the existing intrinsic approach, see the rationale
at [0].
The two added files and corresponding unit tests are the majority of the
plumbing required for this, but at this point isn't accessible from the
rest of LLVM as we need to stage it into the repo gently. An overview is
that classes are added for recording variable information attached to Real
(TM) instructions, in the form of DPValues and DPMarker objects. The
metadata-uses of DPValues is plumbed into the metadata hierachy, and a
field added to class Instruction, which are all stimulated in the unit
tests. The next few patches in this series add utilities to convert to/from
this new debug-info format and add instruction/block utilities to have
debug-info automatically updated in the background when various operations
occur.
This patch was reviewed in Phab in D153990 and D154080, I've squashed them
together into this commit as there are dependencies between the two
patches, and there's little profit in landing them separately.
[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-11-08 14:58:34 +00:00
|
|
|
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
|
|
|
|
|