mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
IR: getOrInsertODRUniquedType => DICompositeType::getODRType, NFC
Lift the API for debug info ODR type uniquing up a layer. Instead of clients managing the map directly on the LLVMContext, add a static method to DICompositeType called getODRType and handle the map in the background. Also adds DICompositeType::getODRTypeIfExists, so far just for convenience in the unit tests. This simplifies the logic in LLParser and BitcodeReader. Because of argument spam there are actually a few more lines of code now; I'll see if I come up with a reasonable way to clean that up. llvm-svn: 266742
This commit is contained in:
parent
74624754a7
commit
e6893b5521
@ -825,6 +825,23 @@ public:
|
|||||||
|
|
||||||
TempDICompositeType clone() const { return cloneImpl(); }
|
TempDICompositeType clone() const { return cloneImpl(); }
|
||||||
|
|
||||||
|
/// Get a DICompositeType with the given ODR identifier.
|
||||||
|
///
|
||||||
|
/// If \a LLVMContext::isODRUniquingDebugTypes(), gets the mapped
|
||||||
|
/// DICompositeType for the given ODR \c Identifier. If none exists, creates
|
||||||
|
/// a new node.
|
||||||
|
///
|
||||||
|
/// Else, returns \c nullptr.
|
||||||
|
static DICompositeType *
|
||||||
|
getODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
|
||||||
|
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
|
||||||
|
Metadata *BaseType, uint64_t SizeInBits, uint64_t AlignInBits,
|
||||||
|
uint64_t OffsetInBits, unsigned Flags, Metadata *Elements,
|
||||||
|
unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
|
Metadata *TemplateParams);
|
||||||
|
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
|
||||||
|
MDString &Identifier);
|
||||||
|
|
||||||
DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
|
DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
|
||||||
DINodeArray getElements() const {
|
DINodeArray getElements() const {
|
||||||
return cast_or_null<MDTuple>(getRawElements());
|
return cast_or_null<MDTuple>(getRawElements());
|
||||||
|
@ -121,17 +121,6 @@ public:
|
|||||||
void enableDebugTypeODRUniquing();
|
void enableDebugTypeODRUniquing();
|
||||||
void disableDebugTypeODRUniquing();
|
void disableDebugTypeODRUniquing();
|
||||||
|
|
||||||
/// Get or insert the DICompositeType mapped to the given string.
|
|
||||||
///
|
|
||||||
/// Returns the address of the current \a DICompositeType pointer mapped to
|
|
||||||
/// \c S, inserting a mapping to \c nullptr if \c S was not previously
|
|
||||||
/// mapped. This method has no effect (and returns \c nullptr instead of a
|
|
||||||
/// valid address) if \a isODRUniquingDebugTypes() is \c false.
|
|
||||||
///
|
|
||||||
/// \post If \a isODRUniquingDebugTypes(), \c S will have a (possibly null)
|
|
||||||
/// mapping. \note The returned address is only valid until the next call.
|
|
||||||
DICompositeType **getOrInsertODRUniquedType(const MDString &S);
|
|
||||||
|
|
||||||
typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
|
typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
|
||||||
unsigned LocCookie);
|
unsigned LocCookie);
|
||||||
|
|
||||||
|
@ -3841,13 +3841,15 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||||||
|
|
||||||
// If this isn't a forward declaration and it has a UUID, check for it in the
|
// If this isn't a forward declaration and it has a UUID, check for it in the
|
||||||
// type map in the context.
|
// type map in the context.
|
||||||
DICompositeType **MappedT = nullptr;
|
if (!(flags.Val & DINode::FlagFwdDecl) && identifier.Val)
|
||||||
if (!(flags.Val & DINode::FlagFwdDecl) && identifier.Val &&
|
if (auto *CT = DICompositeType::getODRType(
|
||||||
(MappedT = Context.getOrInsertODRUniquedType(*identifier.Val)) &&
|
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
|
||||||
*MappedT) {
|
scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val,
|
||||||
Result = *MappedT;
|
elements.Val, runtimeLang.Val, vtableHolder.Val,
|
||||||
return false;
|
templateParams.Val)) {
|
||||||
}
|
Result = CT;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new node, and save it in the context if it belongs in the type
|
// Create a new node, and save it in the context if it belongs in the type
|
||||||
// map.
|
// map.
|
||||||
@ -3856,8 +3858,6 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||||||
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
|
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
|
||||||
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
|
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
|
||||||
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val));
|
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val));
|
||||||
if (MappedT)
|
|
||||||
*MappedT = cast<DICompositeType>(Result);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2190,25 +2190,36 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
|
|||||||
|
|
||||||
// If we have a UUID and this is not a forward declaration, lookup the
|
// If we have a UUID and this is not a forward declaration, lookup the
|
||||||
// mapping.
|
// mapping.
|
||||||
|
bool IsDistinct = Record[0];
|
||||||
|
unsigned Tag = Record[1];
|
||||||
|
MDString *Name = getMDString(Record[2]);
|
||||||
|
Metadata *File = getMDOrNull(Record[3]);
|
||||||
|
unsigned Line = Record[4];
|
||||||
|
Metadata *Scope = getMDOrNull(Record[5]);
|
||||||
|
Metadata *BaseType = getMDOrNull(Record[6]);
|
||||||
|
uint64_t SizeInBits = Record[7];
|
||||||
|
uint64_t AlignInBits = Record[8];
|
||||||
|
uint64_t OffsetInBits = Record[9];
|
||||||
unsigned Flags = Record[10];
|
unsigned Flags = Record[10];
|
||||||
|
Metadata *Elements = getMDOrNull(Record[11]);
|
||||||
|
unsigned RuntimeLang = Record[12];
|
||||||
|
Metadata *VTableHolder = getMDOrNull(Record[13]);
|
||||||
|
Metadata *TemplateParams = getMDOrNull(Record[14]);
|
||||||
auto *Identifier = getMDString(Record[15]);
|
auto *Identifier = getMDString(Record[15]);
|
||||||
DICompositeType **MappedT = nullptr;
|
DICompositeType *CT = nullptr;
|
||||||
if (!(Flags & DINode::FlagFwdDecl) && Identifier)
|
if (!(Flags & DINode::FlagFwdDecl) && Identifier)
|
||||||
MappedT = Context.getOrInsertODRUniquedType(*Identifier);
|
CT = DICompositeType::getODRType(
|
||||||
|
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
|
||||||
|
SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
|
||||||
|
VTableHolder, TemplateParams);
|
||||||
|
|
||||||
// Use the mapped type node, or create a new one if necessary.
|
// Create a node if we didn't get a lazy ODR type.
|
||||||
DICompositeType *CT = MappedT ? *MappedT : nullptr;
|
if (!CT)
|
||||||
if (!CT) {
|
CT = GET_OR_DISTINCT(DICompositeType, IsDistinct,
|
||||||
CT = GET_OR_DISTINCT(
|
(Context, Tag, Name, File, Line, Scope, BaseType,
|
||||||
DICompositeType, Record[0],
|
SizeInBits, AlignInBits, OffsetInBits, Flags,
|
||||||
(Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]),
|
Elements, RuntimeLang, VTableHolder,
|
||||||
Record[4], getMDOrNull(Record[5]), getMDOrNull(Record[6]),
|
TemplateParams, Identifier));
|
||||||
Record[7], Record[8], Record[9], Flags, getMDOrNull(Record[11]),
|
|
||||||
Record[12], getMDOrNull(Record[13]), getMDOrNull(Record[14]),
|
|
||||||
Identifier));
|
|
||||||
if (MappedT)
|
|
||||||
*MappedT = CT;
|
|
||||||
}
|
|
||||||
|
|
||||||
MetadataList.assignValue(CT, NextMetadataNo++);
|
MetadataList.assignValue(CT, NextMetadataNo++);
|
||||||
break;
|
break;
|
||||||
|
@ -266,6 +266,32 @@ DICompositeType *DICompositeType::getImpl(
|
|||||||
Ops);
|
Ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DICompositeType *DICompositeType::getODRType(
|
||||||
|
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
|
||||||
|
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
|
||||||
|
uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
|
||||||
|
unsigned Flags, Metadata *Elements, unsigned RuntimeLang,
|
||||||
|
Metadata *VTableHolder, Metadata *TemplateParams) {
|
||||||
|
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
||||||
|
if (!Context.isODRUniquingDebugTypes())
|
||||||
|
return nullptr;
|
||||||
|
auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
|
||||||
|
if (!CT)
|
||||||
|
CT = DICompositeType::getDistinct(
|
||||||
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
||||||
|
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
|
||||||
|
TemplateParams, &Identifier);
|
||||||
|
return CT;
|
||||||
|
}
|
||||||
|
|
||||||
|
DICompositeType *DICompositeType::getODRTypeIfExists(LLVMContext &Context,
|
||||||
|
MDString &Identifier) {
|
||||||
|
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
||||||
|
if (!Context.isODRUniquingDebugTypes())
|
||||||
|
return nullptr;
|
||||||
|
return Context.pImpl->DITypeMap->lookup(&Identifier);
|
||||||
|
}
|
||||||
|
|
||||||
DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context,
|
DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context,
|
||||||
unsigned Flags, Metadata *TypeArray,
|
unsigned Flags, Metadata *TypeArray,
|
||||||
StorageType Storage,
|
StorageType Storage,
|
||||||
|
@ -323,12 +323,6 @@ void LLVMContext::enableDebugTypeODRUniquing() {
|
|||||||
|
|
||||||
void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }
|
void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }
|
||||||
|
|
||||||
DICompositeType **LLVMContext::getOrInsertODRUniquedType(const MDString &S) {
|
|
||||||
if (!isODRUniquingDebugTypes())
|
|
||||||
return nullptr;
|
|
||||||
return &(*pImpl->DITypeMap)[&S];
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLVMContext::setDiscardValueNames(bool Discard) {
|
void LLVMContext::setDiscardValueNames(bool Discard) {
|
||||||
pImpl->DiscardValueNames = Discard;
|
pImpl->DiscardValueNames = Discard;
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,11 @@
|
|||||||
!named = !{!0, !1}
|
!named = !{!0, !1}
|
||||||
|
|
||||||
; Check both directions.
|
; Check both directions.
|
||||||
; CHECK: !1 = !DICompositeType(
|
; CHECK: !1 = distinct !DICompositeType(
|
||||||
; CHECK-SAME: name: "T1"
|
; CHECK-SAME: name: "T1"
|
||||||
; CHECK-SAME: identifier: "T"
|
; CHECK-SAME: identifier: "T"
|
||||||
; CHECK-NOT: identifier: "T"
|
; CHECK-NOT: identifier: "T"
|
||||||
; REVERSE: !1 = !DICompositeType(
|
; REVERSE: !1 = distinct !DICompositeType(
|
||||||
; REVERSE-SAME: name: "T2"
|
; REVERSE-SAME: name: "T2"
|
||||||
; REVERSE-SAME: identifier: "T"
|
; REVERSE-SAME: identifier: "T"
|
||||||
; REVERSE-NOT: identifier: "T"
|
; REVERSE-NOT: identifier: "T"
|
||||||
|
@ -25,35 +25,41 @@ TEST(LLVMContextTest, enableDebugTypeODRUniquing) {
|
|||||||
|
|
||||||
TEST(LLVMContextTest, getOrInsertODRUniquedType) {
|
TEST(LLVMContextTest, getOrInsertODRUniquedType) {
|
||||||
LLVMContext Context;
|
LLVMContext Context;
|
||||||
const MDString &S = *MDString::get(Context, "string");
|
MDString &UUID = *MDString::get(Context, "string");
|
||||||
|
|
||||||
// Without a type map, this should return null.
|
// Without a type map, this should return null.
|
||||||
EXPECT_FALSE(Context.getOrInsertODRUniquedType(S));
|
EXPECT_FALSE(DICompositeType::getODRType(
|
||||||
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||||
|
nullptr, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr));
|
||||||
|
|
||||||
// Get the mapping.
|
// Enable the mapping. There still shouldn't be a type.
|
||||||
Context.enableDebugTypeODRUniquing();
|
Context.enableDebugTypeODRUniquing();
|
||||||
DICompositeType **Mapping = Context.getOrInsertODRUniquedType(S);
|
EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||||
ASSERT_TRUE(Mapping);
|
|
||||||
|
|
||||||
// Create some type and add it to the mapping.
|
// Create some ODR-uniqued type.
|
||||||
auto &CT = *DICompositeType::get(Context, dwarf::DW_TAG_class_type, "name",
|
auto &CT = *DICompositeType::getODRType(
|
||||||
nullptr, 0, nullptr, nullptr, 0, 0, 0, 0,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||||
nullptr, 0, nullptr, nullptr, S.getString());
|
nullptr, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr);
|
||||||
ASSERT_EQ(S.getString(), CT.getIdentifier());
|
EXPECT_EQ(UUID.getString(), CT.getIdentifier());
|
||||||
*Mapping = &CT;
|
|
||||||
|
|
||||||
// Check that we get it back.
|
// Check that we get it back, even if we change a field.
|
||||||
Mapping = Context.getOrInsertODRUniquedType(S);
|
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||||
ASSERT_TRUE(Mapping);
|
EXPECT_EQ(
|
||||||
EXPECT_EQ(&CT, *Mapping);
|
&CT, DICompositeType::getODRType(Context, UUID, dwarf::DW_TAG_class_type,
|
||||||
|
nullptr, nullptr, 0, nullptr, nullptr, 0,
|
||||||
|
0, 0, 0, nullptr, 0, nullptr, nullptr));
|
||||||
|
EXPECT_EQ(&CT, DICompositeType::getODRType(
|
||||||
|
Context, UUID, dwarf::DW_TAG_class_type,
|
||||||
|
MDString::get(Context, "name"), nullptr, 0, nullptr,
|
||||||
|
nullptr, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr));
|
||||||
|
|
||||||
// Check that it's discarded with the type map.
|
// Check that it's discarded with the type map.
|
||||||
Context.disableDebugTypeODRUniquing();
|
Context.disableDebugTypeODRUniquing();
|
||||||
EXPECT_FALSE(Context.getOrInsertODRUniquedType(S));
|
EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||||
|
|
||||||
// And it shouldn't magically reappear...
|
// And it shouldn't magically reappear...
|
||||||
Context.enableDebugTypeODRUniquing();
|
Context.enableDebugTypeODRUniquing();
|
||||||
EXPECT_FALSE(*Context.getOrInsertODRUniquedType(S));
|
EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user