[llvm] [DebugInfo] Make DIExpression inherit from Metadata and it always should be unique (PR #79335)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 24 09:29:02 PST 2024
https://github.com/phyBrackets created https://github.com/llvm/llvm-project/pull/79335
`DIExpression` no longer inherits from `MDNode`. This change was motivated by the need to ensure that `DIExpression` instances have a unique storage type and there was a bit discussion over on [discourse]( https://discourse.llvm.org/t/distinction-of-diexpression-node/71747 ) .
>From b577ea3a85367df9af067619b01ee2a0cca8894d Mon Sep 17 00:00:00 2001
From: Shivam Kunwar <shivam.kunwar at kdab.com>
Date: Wed, 24 Jan 2024 22:16:02 +0530
Subject: [PATCH] [DebugInfo] Make DIExpression inherit from Metadata and it
always should be unique
---
llvm/include/llvm/AsmParser/LLParser.h | 1 +
.../CodeGen/GlobalISel/MachineIRBuilder.h | 8 ++--
.../llvm/CodeGen/MachineInstrBuilder.h | 19 ++++++--
llvm/include/llvm/CodeGen/MachineOperand.h | 16 ++++++-
llvm/include/llvm/IR/DebugInfoMetadata.h | 26 +++++------
llvm/include/llvm/IR/Metadata.def | 2 +-
llvm/lib/AsmParser/LLParser.cpp | 22 ++++-----
llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 3 +-
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 13 ++++--
.../CodeGen/GlobalISel/MachineIRBuilder.cpp | 8 ++--
llvm/lib/CodeGen/MIRParser/MIParser.cpp | 15 +++---
llvm/lib/CodeGen/MachineInstr.cpp | 8 ++--
.../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 +-
llvm/lib/IR/DIBuilder.cpp | 2 -
llvm/lib/IR/DebugInfoMetadata.cpp | 19 ++++++--
llvm/lib/IR/LLVMContextImpl.h | 46 +++++++++++++++++++
llvm/lib/IR/Verifier.cpp | 1 +
.../WebAssembly/WebAssemblyDebugFixup.cpp | 2 +-
llvm/lib/Transforms/Utils/ValueMapper.cpp | 12 ++++-
llvm/unittests/IR/MetadataTest.cpp | 3 --
20 files changed, 152 insertions(+), 76 deletions(-)
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index cf358c384f52033..af4423cb4a7ca15 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -579,6 +579,7 @@ namespace llvm {
bool parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
PerFunctionState *PFS);
bool parseDIArgList(Metadata *&MD, PerFunctionState *PFS);
+ bool parseDIExpression(Metadata *&MD);
bool parseMetadata(Metadata *&MD, PerFunctionState *PFS);
bool parseMDTuple(MDNode *&MD, bool IsDistinct = false);
bool parseMDNode(MDNode *&N);
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 1387a0a37561c4b..2691188d9cffc17 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -410,26 +410,26 @@ class MachineIRBuilder {
/// Build and insert a DBG_VALUE instruction expressing the fact that the
/// associated \p Variable lives in \p Reg (suitably modified by \p Expr).
MachineInstrBuilder buildDirectDbgValue(Register Reg, const MDNode *Variable,
- const MDNode *Expr);
+ const Metadata *Expr);
/// Build and insert a DBG_VALUE instruction expressing the fact that the
/// associated \p Variable lives in memory at \p Reg (suitably modified by \p
/// Expr).
MachineInstrBuilder buildIndirectDbgValue(Register Reg,
const MDNode *Variable,
- const MDNode *Expr);
+ const Metadata *Expr);
/// Build and insert a DBG_VALUE instruction expressing the fact that the
/// associated \p Variable lives in the stack slot specified by \p FI
/// (suitably modified by \p Expr).
MachineInstrBuilder buildFIDbgValue(int FI, const MDNode *Variable,
- const MDNode *Expr);
+ const Metadata *Expr);
/// Build and insert a DBG_VALUE instructions specifying that \p Variable is
/// given by \p C (suitably modified by \p Expr).
MachineInstrBuilder buildConstDbgValue(const Constant &C,
const MDNode *Variable,
- const MDNode *Expr);
+ const Metadata *Expr);
/// Build and insert a DBG_LABEL instructions specifying that \p Label is
/// given. Convert "llvm.dbg.label Label" to "DBG_LABEL Label".
diff --git a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h
index 954d8e6770a294f..c0c2a4ea4c0c23a 100644
--- a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -245,6 +245,17 @@ class MachineInstrBuilder {
return *this;
}
+ const MachineInstrBuilder &addMetadata(const Metadata *MD) const {
+ MI->addOperand(*MF, MachineOperand::CreateMetadata(MD));
+ assert((MI->isDebugValueLike() ? static_cast<bool>(MI->getDebugVariable())
+ : true) &&
+ "first MDNode argument of a DBG_VALUE not a variable");
+ assert((MI->isDebugLabel() ? static_cast<bool>(MI->getDebugLabel())
+ : true) &&
+ "first MDNode argument of a DBG_LABEL not a label");
+ return *this;
+ }
+
const MachineInstrBuilder &addCFIIndex(unsigned CFIIndex) const {
MI->addOperand(*MF, MachineOperand::CreateCFIIndex(CFIIndex));
return *this;
@@ -488,14 +499,14 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
Register Reg, const MDNode *Variable,
- const MDNode *Expr);
+ const Metadata *Expr);
/// This version of the builder builds a DBG_VALUE or DBG_VALUE_LIST intrinsic
/// for a MachineOperand.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
ArrayRef<MachineOperand> MOs,
- const MDNode *Variable, const MDNode *Expr);
+ const MDNode *Variable, const Metadata *Expr);
/// This version of the builder builds a DBG_VALUE intrinsic
/// for either a value in a register or a register-indirect
@@ -504,7 +515,7 @@ MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
Register Reg, const MDNode *Variable,
- const MDNode *Expr);
+ const Metadata *Expr);
/// This version of the builder builds a DBG_VALUE, DBG_INSTR_REF, or
/// DBG_VALUE_LIST intrinsic for a machine operand and inserts it at position I.
@@ -512,7 +523,7 @@ MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
ArrayRef<MachineOperand> MOs,
- const MDNode *Variable, const MDNode *Expr);
+ const MDNode *Variable, const Metadata *Expr);
/// Clone a DBG_VALUE whose value has been spilled to FrameIndex.
MachineInstr *buildDbgValueForSpill(MachineBasicBlock &BB,
diff --git a/llvm/include/llvm/CodeGen/MachineOperand.h b/llvm/include/llvm/CodeGen/MachineOperand.h
index 63a172134538c42..9d5532c7d812ec1 100644
--- a/llvm/include/llvm/CodeGen/MachineOperand.h
+++ b/llvm/include/llvm/CodeGen/MachineOperand.h
@@ -31,6 +31,7 @@ class MachineInstr;
class MachineRegisterInfo;
class MCCFIInstruction;
class MDNode;
+class Metadata;
class ModuleSlotTracker;
class TargetIntrinsicInfo;
class TargetRegisterInfo;
@@ -173,6 +174,7 @@ class MachineOperand {
int64_t ImmVal; // For MO_Immediate.
const uint32_t *RegMask; // For MO_RegisterMask and MO_RegisterLiveOut.
const MDNode *MD; // For MO_Metadata.
+ const Metadata* Expr;
MCSymbol *Sym; // For MO_MCSymbol.
unsigned CFIIndex; // For MO_CFI.
Intrinsic::ID IntrinsicID; // For MO_IntrinsicID.
@@ -677,6 +679,11 @@ class MachineOperand {
return Contents.MD;
}
+ const Metadata *getMetadataDI() const {
+ assert(isMetadata() && "Wrong MachineOperand accessor");
+ return Contents.Expr;
+ }
+
//===--------------------------------------------------------------------===//
// Mutators for various operand types.
//===--------------------------------------------------------------------===//
@@ -710,9 +717,9 @@ class MachineOperand {
Contents.OffsetedInfo.Val.Index = Idx;
}
- void setMetadata(const MDNode *MD) {
+ void setMetadata(const Metadata *MD) {
assert(isMetadata() && "Wrong MachineOperand mutator");
- Contents.MD = MD;
+ Contents.Expr = MD;
}
void setInstrRefInstrIndex(unsigned InstrIdx) {
@@ -946,6 +953,11 @@ class MachineOperand {
Op.Contents.MD = Meta;
return Op;
}
+ static MachineOperand CreateMetadata(const Metadata *Meta) {
+ MachineOperand Op(MachineOperand::MO_Metadata);
+ Op.Contents.Expr = Meta;
+ return Op;
+ }
static MachineOperand CreateMCSymbol(MCSymbol *Sym,
unsigned TargetFlags = 0) {
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 156f6eb49253de7..207deed8a78dd97 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2656,31 +2656,27 @@ class DIVariable : public DINode {
/// DW_OP_stack_value) is the constant variable value.
///
/// TODO: Co-allocate the expression elements.
-/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
-/// storage types.
-class DIExpression : public MDNode {
+class DIExpression : public Metadata, ReplaceableMetadataImpl {
+ friend class ReplaceableMetadataImpl;
friend class LLVMContextImpl;
- friend class MDNode;
std::vector<uint64_t> Elements;
- DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
- : MDNode(C, DIExpressionKind, Storage, std::nullopt),
+ DIExpression(LLVMContext &C, ArrayRef<uint64_t> Elements)
+ : Metadata(DIExpressionKind, Uniqued), ReplaceableMetadataImpl(C),
Elements(Elements.begin(), Elements.end()) {}
~DIExpression() = default;
static DIExpression *getImpl(LLVMContext &Context,
- ArrayRef<uint64_t> Elements, StorageType Storage,
- bool ShouldCreate = true);
-
- TempDIExpression cloneImpl() const {
- return getTemporary(getContext(), getElements());
- }
+ ArrayRef<uint64_t> Elements);
public:
- DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
-
- TempDIExpression clone() const { return cloneImpl(); }
+ LLVMContext &getContext() const {
+ return ReplaceableMetadataImpl::getContext();
+ }
+ static inline DIExpression *get(LLVMContext &Context, ArrayRef<uint64_t> Elements) {
+ return getImpl(Context, Elements);
+ }
ArrayRef<uint64_t> getElements() const { return Elements; }
diff --git a/llvm/include/llvm/IR/Metadata.def b/llvm/include/llvm/IR/Metadata.def
index a3cfb9ad6e3e785..0edbe931c75ed8e 100644
--- a/llvm/include/llvm/IR/Metadata.def
+++ b/llvm/include/llvm/IR/Metadata.def
@@ -81,7 +81,7 @@ HANDLE_METADATA_LEAF(DIArgList)
HANDLE_MDNODE_BRANCH(MDNode)
HANDLE_MDNODE_LEAF_UNIQUABLE(MDTuple)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation)
-HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIExpression)
+HANDLE_METADATA_LEAF(DIExpression)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGlobalVariableExpression)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DINode)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(GenericDINode)
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d6c5993797de111..e7b06f8c5fef702 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -892,16 +892,7 @@ bool LLParser::parseNamedMetadata() {
if (Lex.getKind() != lltok::rbrace)
do {
MDNode *N = nullptr;
- // parse DIExpressions inline as a special case. They are still MDNodes,
- // so they can still appear in named metadata. Remove this logic if they
- // become plain Metadata.
- if (Lex.getKind() == lltok::MetadataVar &&
- Lex.getStrVal() == "DIExpression") {
- if (parseDIExpression(N, /*IsDistinct=*/false))
- return true;
- // DIArgLists should only appear inline in a function, as they may
- // contain LocalAsMetadata arguments which require a function context.
- } else if (Lex.getKind() == lltok::MetadataVar &&
+ if (Lex.getKind() == lltok::MetadataVar &&
Lex.getStrVal() == "DIArgList") {
return tokError("found DIArgList outside of function");
} else if (parseToken(lltok::exclaim, "Expected '!' here") ||
@@ -5569,7 +5560,7 @@ bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) {
/// parseDIExpression:
/// ::= !DIExpression(0, 7, -1)
-bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
+bool LLParser::parseDIExpression(Metadata *&Result) {
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
Lex.Lex();
@@ -5611,7 +5602,7 @@ bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
if (parseToken(lltok::rparen, "expected ')' here"))
return true;
- Result = GET_OR_DISTINCT(DIExpression, (Context, Elements));
+ Result = DIExpression::get(Context, Elements);
return false;
}
@@ -5760,6 +5751,13 @@ bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
MD = AL;
return false;
}
+ else if (Lex.getStrVal() == "DIExpression") {
+ Metadata *Expr;
+ if (parseDIExpression(Expr))
+ return true;
+ MD = Expr;
+ return false;
+ }
MDNode *N;
if (parseSpecializedMDNode(N)) {
return true;
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 770eb83af17f9b0..6ee44110d47a145 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -2145,7 +2145,6 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Record.size() < 1)
return error("Invalid record");
- IsDistinct = Record[0] & 1;
uint64_t Version = Record[0] >> 1;
auto Elts = MutableArrayRef<uint64_t>(Record).slice(1);
@@ -2153,7 +2152,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
if (Error Err = upgradeDIExpression(Version, Elts, Buffer))
return Err;
- MetadataList.assignValue(GET_OR_DISTINCT(DIExpression, (Context, Elts)),
+ MetadataList.assignValue(DIExpression::get(Context, Elts),
NextMetadataNo);
NextMetadataNo++;
break;
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index a5fc267b1883bfe..d2f05597deb5a58 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -355,7 +355,7 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {
void writeDILabel(const DILabel *N,
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
void writeDIExpression(const DIExpression *N,
- SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
+ SmallVectorImpl<uint64_t> &Record);
void writeDIGlobalVariableExpression(const DIGlobalVariableExpression *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
@@ -2138,14 +2138,13 @@ void ModuleBitcodeWriter::writeDILabel(
}
void ModuleBitcodeWriter::writeDIExpression(const DIExpression *N,
- SmallVectorImpl<uint64_t> &Record,
- unsigned Abbrev) {
+ SmallVectorImpl<uint64_t> &Record) {
Record.reserve(N->getElements().size() + 1);
const uint64_t Version = 3 << 1;
- Record.push_back((uint64_t)N->isDistinct() | Version);
+ Record.push_back(Version);
Record.append(N->elements_begin(), N->elements_end());
- Stream.EmitRecord(bitc::METADATA_EXPRESSION, Record, Abbrev);
+ Stream.EmitRecord(bitc::METADATA_EXPRESSION, Record);
Record.clear();
}
@@ -2305,6 +2304,10 @@ void ModuleBitcodeWriter::writeMetadataRecords(
writeDIArgList(AL, Record);
continue;
}
+ if (auto *AL = dyn_cast<DIExpression>(MD)) {
+ writeDIExpression(AL, Record);
+ continue;
+ }
writeValueAsMetadata(cast<ValueAsMetadata>(MD), Record);
}
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index a5827c26c04f48b..21aebf0166e5684 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -48,7 +48,7 @@ MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) {
MachineInstrBuilder
MachineIRBuilder::buildDirectDbgValue(Register Reg, const MDNode *Variable,
- const MDNode *Expr) {
+ const Metadata *Expr) {
assert(isa<DILocalVariable>(Variable) && "not a variable");
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
assert(
@@ -61,7 +61,7 @@ MachineIRBuilder::buildDirectDbgValue(Register Reg, const MDNode *Variable,
MachineInstrBuilder
MachineIRBuilder::buildIndirectDbgValue(Register Reg, const MDNode *Variable,
- const MDNode *Expr) {
+ const Metadata *Expr) {
assert(isa<DILocalVariable>(Variable) && "not a variable");
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
assert(
@@ -74,7 +74,7 @@ MachineIRBuilder::buildIndirectDbgValue(Register Reg, const MDNode *Variable,
MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI,
const MDNode *Variable,
- const MDNode *Expr) {
+ const Metadata *Expr) {
assert(isa<DILocalVariable>(Variable) && "not a variable");
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
assert(
@@ -89,7 +89,7 @@ MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI,
MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C,
const MDNode *Variable,
- const MDNode *Expr) {
+ const Metadata *Expr) {
assert(isa<DILocalVariable>(Variable) && "not a variable");
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
assert(
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index ede4291fe26dc95..d545e21c3d12ace 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -472,7 +472,7 @@ class MIParser {
bool parseExternalSymbolOperand(MachineOperand &Dest);
bool parseMCSymbolOperand(MachineOperand &Dest);
[[nodiscard]] bool parseMDNode(MDNode *&Node);
- bool parseDIExpression(MDNode *&Expr);
+ bool parseDIExpression(Metadata *&Expr);
bool parseDILocation(MDNode *&Expr);
bool parseMetadataOperand(MachineOperand &Dest);
bool parseCFIOffset(int &Offset);
@@ -1269,9 +1269,6 @@ bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
if (Token.is(MIToken::exclaim)) {
if (parseMDNode(Node))
return true;
- } else if (Token.is(MIToken::md_diexpr)) {
- if (parseDIExpression(Node))
- return true;
} else if (Token.is(MIToken::md_dilocation)) {
if (parseDILocation(Node))
return true;
@@ -2292,7 +2289,7 @@ bool MIParser::parseMDNode(MDNode *&Node) {
return false;
}
-bool MIParser::parseDIExpression(MDNode *&Expr) {
+bool MIParser::parseDIExpression(Metadata *&Expr) {
assert(Token.is(MIToken::md_diexpr));
lex();
@@ -2442,15 +2439,15 @@ bool MIParser::parseDILocation(MDNode *&Loc) {
}
bool MIParser::parseMetadataOperand(MachineOperand &Dest) {
- MDNode *Node = nullptr;
+ Metadata *Meta = nullptr;
if (Token.is(MIToken::exclaim)) {
- if (parseMDNode(Node))
+ if (parseMDNode(reinterpret_cast<MDNode *&>(Meta)))
return true;
} else if (Token.is(MIToken::md_diexpr)) {
- if (parseDIExpression(Node))
+ if (parseDIExpression(Meta))
return true;
}
- Dest = MachineOperand::CreateMetadata(Node);
+ Dest = MachineOperand::CreateMetadata(reinterpret_cast<MDNode *>(Meta));
return false;
}
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 27eae372f8ad764..740edf06eb2b205 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -2153,7 +2153,7 @@ void MachineInstr::emitError(StringRef Msg) const {
MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
Register Reg, const MDNode *Variable,
- const MDNode *Expr) {
+ const Metadata *Expr) {
assert(isa<DILocalVariable>(Variable) && "not a variable");
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
@@ -2169,7 +2169,7 @@ MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
const MCInstrDesc &MCID, bool IsIndirect,
ArrayRef<MachineOperand> DebugOps,
- const MDNode *Variable, const MDNode *Expr) {
+ const MDNode *Variable, const Metadata *Expr) {
assert(isa<DILocalVariable>(Variable) && "not a variable");
assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
@@ -2204,7 +2204,7 @@ MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
const DebugLoc &DL, const MCInstrDesc &MCID,
bool IsIndirect, Register Reg,
- const MDNode *Variable, const MDNode *Expr) {
+ const MDNode *Variable, const Metadata *Expr) {
MachineFunction &MF = *BB.getParent();
MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Variable, Expr);
BB.insert(I, MI);
@@ -2216,7 +2216,7 @@ MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
const DebugLoc &DL, const MCInstrDesc &MCID,
bool IsIndirect,
ArrayRef<MachineOperand> DebugOps,
- const MDNode *Variable, const MDNode *Expr) {
+ const MDNode *Variable, const Metadata *Expr) {
MachineFunction &MF = *BB.getParent();
MachineInstr *MI =
BuildMI(MF, DL, MCID, IsIndirect, DebugOps, Variable, Expr);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 359d738d2ca09fd..6de40d703a9286b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -614,7 +614,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
MachineInstr *Def = RegInfo->getVRegDef(LDI->second);
MachineBasicBlock::iterator InsertPos = Def;
const MDNode *Variable = MI->getDebugVariable();
- const MDNode *Expr = MI->getDebugExpression();
+ const DIExpression *Expr = MI->getDebugExpression();
DebugLoc DL = MI->getDebugLoc();
bool IsIndirect = MI->isIndirectDebugValue();
if (IsIndirect)
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 62efaba025344b5..392d33242cb25f7 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -1045,7 +1045,6 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,
DeclareFn = getDeclareIntrin(M);
trackIfUnresolved(VarInfo);
- trackIfUnresolved(Expr);
Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, Storage),
MetadataAsValue::get(VMContext, VarInfo),
MetadataAsValue::get(VMContext, Expr)};
@@ -1071,7 +1070,6 @@ Instruction *DIBuilder::insertDbgIntrinsic(llvm::Function *IntrinsicFn,
"Expected matching subprograms");
trackIfUnresolved(VarInfo);
- trackIfUnresolved(Expr);
Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, V),
MetadataAsValue::get(VMContext, VarInfo),
MetadataAsValue::get(VMContext, Expr)};
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 51950fc937f0aba..d2a039876fe2412 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1351,12 +1351,21 @@ DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
Metadata *Ops[] = {Scope, Name, File};
DEFINE_GETIMPL_STORE(DILabel, (Line), Ops);
}
+DIExpression *DIExpression::getImpl(LLVMContext &Context, ArrayRef<uint64_t> Elements) {
+ auto &DIExpressions = Context.pImpl->DIExpressions;
+ DIExpressionKeyInfo Key(Elements);
-DIExpression *DIExpression::getImpl(LLVMContext &Context,
- ArrayRef<uint64_t> Elements,
- StorageType Storage, bool ShouldCreate) {
- DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements));
- DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements));
+ // Check if an existing expression matches the key
+ auto It = DIExpressions.find_as(Key);
+ if (It != DIExpressions.end())
+ return *It;
+
+ // Create a new DIExpression if not found
+ DIExpression *NewExpr = new DIExpression(Context, Elements);
+
+ // Insert the new expression into the set
+ DIExpressions.insert(NewExpr);
+ return NewExpr;
}
bool DIExpression::isEntryValue() const {
if (auto singleLocElts = getSingleLocationExpressionElements()) {
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 6a20291344989dd..37f1471bb5005fb 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1350,6 +1350,51 @@ struct DIArgListInfo {
}
};
+struct DIExpressionKeyInfo {
+ ArrayRef<uint64_t> Elements;
+
+ DIExpressionKeyInfo(ArrayRef<uint64_t> Elements) : Elements(Elements) {}
+ DIExpressionKeyInfo(const DIExpression *Expr) : Elements(Expr->getElements()) {}
+
+ bool isKeyOf(const DIExpression *RHS) const {
+ return Elements == RHS->getElements();
+ }
+
+ unsigned getHashValue() const {
+ return hash_combine_range(Elements.begin(), Elements.end());
+ }
+};
+
+struct DIExpressionInfo {
+ using KeyTy = DIExpressionKeyInfo;
+
+ static inline DIExpression *getEmptyKey() {
+ return DenseMapInfo<DIExpression *>::getEmptyKey();
+ }
+
+ static inline DIExpression *getTombstoneKey() {
+ return DenseMapInfo<DIExpression *>::getTombstoneKey();
+ }
+
+ static unsigned getHashValue(const KeyTy &Key) {
+ return Key.getHashValue();
+ }
+
+ static unsigned getHashValue(const DIExpression *Expr) {
+ return KeyTy(Expr).getHashValue();
+ }
+
+ static bool isEqual(const KeyTy &LHS, const DIExpression *RHS) {
+ if (RHS == getEmptyKey() || RHS == getTombstoneKey())
+ return false;
+ return LHS.isKeyOf(RHS);
+ }
+
+ static bool isEqual(const DIExpression *LHS, const DIExpression *RHS) {
+ return LHS == RHS;
+ }
+};
+
/// DenseMapInfo for MDNode subclasses.
template <class NodeTy> struct MDNodeInfo {
using KeyTy = MDNodeKeyImpl<NodeTy>;
@@ -1499,6 +1544,7 @@ class LLVMContextImpl {
DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
DenseSet<DIArgList *, DIArgListInfo> DIArgLists;
+ DenseSet<DIExpression *, DIExpressionInfo> DIExpressions;
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
DenseSet<CLASS *, CLASS##Info> CLASS##s;
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 91cf91fbc788bd9..a11d5400f78b1fe 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -488,6 +488,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
void visitMetadataAsValue(const MetadataAsValue &MD, Function *F);
void visitValueAsMetadata(const ValueAsMetadata &MD, Function *F);
void visitDIArgList(const DIArgList &AL, Function *F);
+ void visitDIExpression(const DIExpression &DI);
void visitComdat(const Comdat &C);
void visitModuleIdents();
void visitModuleCommandLines();
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugFixup.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyDebugFixup.cpp
index 4a75bab6b95ddcd..6fc6b0ebd9b03bf 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugFixup.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugFixup.cpp
@@ -140,7 +140,7 @@ bool WebAssemblyDebugFixup::runOnMachineFunction(MachineFunction &MF) {
Prev.DebugValue->getDebugLoc(),
TII->get(WebAssembly::DBG_VALUE), false, Register(),
Prev.DebugValue->getOperand(2).getMetadata(),
- Prev.DebugValue->getOperand(3).getMetadata());
+ Prev.DebugValue->getOperand(3).getMetadataDI());
}
}
}
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 380541ffdd49d6e..eddc37d133e46cc 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -615,7 +615,7 @@ std::optional<Metadata *> MDNodeMapper::tryToMapOperand(const Metadata *Op) {
M.getVM().getMappedMD(Op)) &&
"Expected Value to be memoized");
else
- assert((isa<MDString>(Op) || M.getVM().getMappedMD(Op)) &&
+ assert((isa<DIExpression>(Op) || isa<MDString>(Op) || M.getVM().getMappedMD(Op)) &&
"Expected result to be memoized");
#endif
return *MappedOp;
@@ -807,7 +807,12 @@ void MDNodeMapper::mapNodesInPOT(UniquedGraph &G) {
return *MappedOp;
(void)D;
assert(G.Info[Old].ID > D.ID && "Expected a forward reference");
- return &G.getFwdReference(*cast<MDNode>(Old));
+ if (auto *MDN = dyn_cast<MDNode>(Old)) {
+ // Handle MDNode
+ return &G.getFwdReference(*MDN);
+ } else if (isa<DIExpression>(Old)) {
+ return Old;
+ }
});
auto *NewN = MDNode::replaceWithUniqued(std::move(ClonedN));
@@ -878,6 +883,9 @@ std::optional<Metadata *> Mapper::mapSimpleMetadata(const Metadata *MD) {
if (isa<MDString>(MD))
return const_cast<Metadata *>(MD);
+
+ if(isa<DIExpression>(MD))
+ return const_cast<Metadata *>(MD);
// This is a module-level metadata. If nothing at the module level is
// changing, use an identity mapping.
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 767dd1a59d2b9e9..27ba21cb7d512be 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -3094,9 +3094,6 @@ TEST_F(DIExpressionTest, get) {
EXPECT_EQ(78u, N->getElement(3));
EXPECT_EQ(0u, N->getElement(4));
- TempDIExpression Temp = N->clone();
- EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
-
// Test DIExpression::prepend().
uint64_t Elts0[] = {dwarf::DW_OP_LLVM_fragment, 0, 32};
auto *N0 = DIExpression::get(Context, Elts0);
More information about the llvm-commits
mailing list