diff options
Diffstat (limited to 'lib/IR/LLVMContextImpl.h')
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 402 |
1 files changed, 273 insertions, 129 deletions
diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index d42047d4e775..7820e2ab958d 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -32,6 +32,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/ValueHandle.h" +#include "llvm/Support/Dwarf.h" #include <vector> namespace llvm { @@ -211,6 +212,17 @@ public: template <class NodeTy> struct MDNodeKeyImpl; template <class NodeTy> struct MDNodeInfo; +/// Configuration point for MDNodeInfo::isEqual(). +template <class NodeTy> struct MDNodeSubsetEqualImpl { + typedef MDNodeKeyImpl<NodeTy> KeyTy; + static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) { + return false; + } + static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) { + return false; + } +}; + /// \brief DenseMapInfo for MDTuple. /// /// Note that we don't need the is-function-local bit, since that's implicit in @@ -255,14 +267,14 @@ template <> struct MDNodeKeyImpl<DILocation> { /// \brief DenseMapInfo for GenericDINode. template <> struct MDNodeKeyImpl<GenericDINode> : MDNodeOpsKey { unsigned Tag; - StringRef Header; - MDNodeKeyImpl(unsigned Tag, StringRef Header, ArrayRef<Metadata *> DwarfOps) + MDString *Header; + MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps) : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {} MDNodeKeyImpl(const GenericDINode *N) - : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getHeader()) {} + : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getRawHeader()) {} bool isKeyOf(const GenericDINode *RHS) const { - return Tag == RHS->getTag() && Header == RHS->getHeader() && + return Tag == RHS->getTag() && Header == RHS->getRawHeader() && compareOps(RHS, 1); } @@ -290,35 +302,35 @@ template <> struct MDNodeKeyImpl<DISubrange> { template <> struct MDNodeKeyImpl<DIEnumerator> { int64_t Value; - StringRef Name; + MDString *Name; - MDNodeKeyImpl(int64_t Value, StringRef Name) : Value(Value), Name(Name) {} + MDNodeKeyImpl(int64_t Value, MDString *Name) : Value(Value), Name(Name) {} MDNodeKeyImpl(const DIEnumerator *N) - : Value(N->getValue()), Name(N->getName()) {} + : Value(N->getValue()), Name(N->getRawName()) {} bool isKeyOf(const DIEnumerator *RHS) const { - return Value == RHS->getValue() && Name == RHS->getName(); + return Value == RHS->getValue() && Name == RHS->getRawName(); } unsigned getHashValue() const { return hash_combine(Value, Name); } }; template <> struct MDNodeKeyImpl<DIBasicType> { unsigned Tag; - StringRef Name; + MDString *Name; uint64_t SizeInBits; uint64_t AlignInBits; unsigned Encoding; - MDNodeKeyImpl(unsigned Tag, StringRef Name, uint64_t SizeInBits, + MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding) : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits), Encoding(Encoding) {} MDNodeKeyImpl(const DIBasicType *N) - : Tag(N->getTag()), Name(N->getName()), SizeInBits(N->getSizeInBits()), + : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()) {} bool isKeyOf(const DIBasicType *RHS) const { - return Tag == RHS->getTag() && Name == RHS->getName() && + return Tag == RHS->getTag() && Name == RHS->getRawName() && SizeInBits == RHS->getSizeInBits() && AlignInBits == RHS->getAlignInBits() && Encoding == RHS->getEncoding(); @@ -330,7 +342,7 @@ template <> struct MDNodeKeyImpl<DIBasicType> { template <> struct MDNodeKeyImpl<DIDerivedType> { unsigned Tag; - StringRef Name; + MDString *Name; Metadata *File; unsigned Line; Metadata *Scope; @@ -341,7 +353,7 @@ template <> struct MDNodeKeyImpl<DIDerivedType> { unsigned Flags; Metadata *ExtraData; - MDNodeKeyImpl(unsigned Tag, StringRef Name, Metadata *File, unsigned Line, + MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, Metadata *ExtraData) @@ -349,14 +361,14 @@ template <> struct MDNodeKeyImpl<DIDerivedType> { BaseType(BaseType), SizeInBits(SizeInBits), AlignInBits(AlignInBits), OffsetInBits(OffsetInBits), Flags(Flags), ExtraData(ExtraData) {} MDNodeKeyImpl(const DIDerivedType *N) - : Tag(N->getTag()), Name(N->getName()), File(N->getRawFile()), + : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()), ExtraData(N->getRawExtraData()) {} bool isKeyOf(const DIDerivedType *RHS) const { - return Tag == RHS->getTag() && Name == RHS->getName() && + return Tag == RHS->getTag() && Name == RHS->getRawName() && File == RHS->getRawFile() && Line == RHS->getLine() && Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() && SizeInBits == RHS->getSizeInBits() && @@ -365,14 +377,53 @@ template <> struct MDNodeKeyImpl<DIDerivedType> { ExtraData == RHS->getRawExtraData(); } unsigned getHashValue() const { - return hash_combine(Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, Flags, ExtraData); + // If this is a member inside an ODR type, only hash the type and the name. + // Otherwise the hash will be stronger than + // MDNodeSubsetEqualImpl::isODRMember(). + if (Tag == dwarf::DW_TAG_member && Name) + if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope)) + if (CT->getRawIdentifier()) + return hash_combine(Name, Scope); + + // Intentionally computes the hash on a subset of the operands for + // performance reason. The subset has to be significant enough to avoid + // collision "most of the time". There is no correctness issue in case of + // collision because of the full check above. + return hash_combine(Tag, Name, File, Line, Scope, BaseType, Flags); + } +}; + +template <> struct MDNodeSubsetEqualImpl<DIDerivedType> { + typedef MDNodeKeyImpl<DIDerivedType> KeyTy; + static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) { + return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS); + } + static bool isSubsetEqual(const DIDerivedType *LHS, const DIDerivedType *RHS) { + return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(), + RHS); + } + + /// Subprograms compare equal if they declare the same function in an ODR + /// type. + static bool isODRMember(unsigned Tag, const Metadata *Scope, + const MDString *Name, const DIDerivedType *RHS) { + // Check whether the LHS is eligible. + if (Tag != dwarf::DW_TAG_member || !Name) + return false; + + auto *CT = dyn_cast_or_null<DICompositeType>(Scope); + if (!CT || !CT->getRawIdentifier()) + return false; + + // Compare to the RHS. + return Tag == RHS->getTag() && Name == RHS->getRawName() && + Scope == RHS->getRawScope(); } }; template <> struct MDNodeKeyImpl<DICompositeType> { unsigned Tag; - StringRef Name; + MDString *Name; Metadata *File; unsigned Line; Metadata *Scope; @@ -385,31 +436,31 @@ template <> struct MDNodeKeyImpl<DICompositeType> { unsigned RuntimeLang; Metadata *VTableHolder; Metadata *TemplateParams; - StringRef Identifier; + MDString *Identifier; - MDNodeKeyImpl(unsigned Tag, StringRef Name, Metadata *File, unsigned Line, + MDNodeKeyImpl(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, - StringRef Identifier) + MDString *Identifier) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), AlignInBits(AlignInBits), OffsetInBits(OffsetInBits), Flags(Flags), Elements(Elements), RuntimeLang(RuntimeLang), VTableHolder(VTableHolder), TemplateParams(TemplateParams), Identifier(Identifier) {} MDNodeKeyImpl(const DICompositeType *N) - : Tag(N->getTag()), Name(N->getName()), File(N->getRawFile()), + : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), AlignInBits(N->getAlignInBits()), OffsetInBits(N->getOffsetInBits()), Flags(N->getFlags()), Elements(N->getRawElements()), RuntimeLang(N->getRuntimeLang()), VTableHolder(N->getRawVTableHolder()), TemplateParams(N->getRawTemplateParams()), - Identifier(N->getIdentifier()) {} + Identifier(N->getRawIdentifier()) {} bool isKeyOf(const DICompositeType *RHS) const { - return Tag == RHS->getTag() && Name == RHS->getName() && + return Tag == RHS->getTag() && Name == RHS->getRawName() && File == RHS->getRawFile() && Line == RHS->getLine() && Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() && SizeInBits == RHS->getSizeInBits() && @@ -419,49 +470,55 @@ template <> struct MDNodeKeyImpl<DICompositeType> { RuntimeLang == RHS->getRuntimeLang() && VTableHolder == RHS->getRawVTableHolder() && TemplateParams == RHS->getRawTemplateParams() && - Identifier == RHS->getIdentifier(); + Identifier == RHS->getRawIdentifier(); } unsigned getHashValue() const { - return hash_combine(Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, - VTableHolder, TemplateParams, Identifier); + // Intentionally computes the hash on a subset of the operands for + // performance reason. The subset has to be significant enough to avoid + // collision "most of the time". There is no correctness issue in case of + // collision because of the full check above. + return hash_combine(Name, File, Line, BaseType, Scope, Elements, + TemplateParams); } }; template <> struct MDNodeKeyImpl<DISubroutineType> { unsigned Flags; + uint8_t CC; Metadata *TypeArray; - MDNodeKeyImpl(int64_t Flags, Metadata *TypeArray) - : Flags(Flags), TypeArray(TypeArray) {} + MDNodeKeyImpl(unsigned Flags, uint8_t CC, Metadata *TypeArray) + : Flags(Flags), CC(CC), TypeArray(TypeArray) {} MDNodeKeyImpl(const DISubroutineType *N) - : Flags(N->getFlags()), TypeArray(N->getRawTypeArray()) {} + : Flags(N->getFlags()), CC(N->getCC()), TypeArray(N->getRawTypeArray()) {} bool isKeyOf(const DISubroutineType *RHS) const { - return Flags == RHS->getFlags() && TypeArray == RHS->getRawTypeArray(); + return Flags == RHS->getFlags() && CC == RHS->getCC() && + TypeArray == RHS->getRawTypeArray(); } - unsigned getHashValue() const { return hash_combine(Flags, TypeArray); } + unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); } }; template <> struct MDNodeKeyImpl<DIFile> { - StringRef Filename; - StringRef Directory; + MDString *Filename; + MDString *Directory; - MDNodeKeyImpl(StringRef Filename, StringRef Directory) + MDNodeKeyImpl(MDString *Filename, MDString *Directory) : Filename(Filename), Directory(Directory) {} MDNodeKeyImpl(const DIFile *N) - : Filename(N->getFilename()), Directory(N->getDirectory()) {} + : Filename(N->getRawFilename()), Directory(N->getRawDirectory()) {} bool isKeyOf(const DIFile *RHS) const { - return Filename == RHS->getFilename() && Directory == RHS->getDirectory(); + return Filename == RHS->getRawFilename() && + Directory == RHS->getRawDirectory(); } unsigned getHashValue() const { return hash_combine(Filename, Directory); } }; template <> struct MDNodeKeyImpl<DISubprogram> { Metadata *Scope; - StringRef Name; - StringRef LinkageName; + MDString *Name; + MDString *LinkageName; Metadata *File; unsigned Line; Metadata *Type; @@ -471,57 +528,102 @@ template <> struct MDNodeKeyImpl<DISubprogram> { Metadata *ContainingType; unsigned Virtuality; unsigned VirtualIndex; + int ThisAdjustment; unsigned Flags; bool IsOptimized; + Metadata *Unit; Metadata *TemplateParams; Metadata *Declaration; Metadata *Variables; - MDNodeKeyImpl(Metadata *Scope, StringRef Name, StringRef LinkageName, + MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, - unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - Metadata *TemplateParams, Metadata *Declaration, - Metadata *Variables) + unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, + bool IsOptimized, Metadata *Unit, Metadata *TemplateParams, + Metadata *Declaration, Metadata *Variables) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), ScopeLine(ScopeLine), ContainingType(ContainingType), Virtuality(Virtuality), - VirtualIndex(VirtualIndex), Flags(Flags), IsOptimized(IsOptimized), + VirtualIndex(VirtualIndex), ThisAdjustment(ThisAdjustment), + Flags(Flags), IsOptimized(IsOptimized), Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration), Variables(Variables) {} MDNodeKeyImpl(const DISubprogram *N) - : Scope(N->getRawScope()), Name(N->getName()), - LinkageName(N->getLinkageName()), File(N->getRawFile()), + : Scope(N->getRawScope()), Name(N->getRawName()), + LinkageName(N->getRawLinkageName()), File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()), IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), ScopeLine(N->getScopeLine()), ContainingType(N->getRawContainingType()), Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()), - Flags(N->getFlags()), IsOptimized(N->isOptimized()), + ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()), + IsOptimized(N->isOptimized()), Unit(N->getRawUnit()), TemplateParams(N->getRawTemplateParams()), Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()) {} bool isKeyOf(const DISubprogram *RHS) const { - return Scope == RHS->getRawScope() && Name == RHS->getName() && - LinkageName == RHS->getLinkageName() && File == RHS->getRawFile() && - Line == RHS->getLine() && Type == RHS->getRawType() && - IsLocalToUnit == RHS->isLocalToUnit() && + return Scope == RHS->getRawScope() && Name == RHS->getRawName() && + LinkageName == RHS->getRawLinkageName() && + File == RHS->getRawFile() && Line == RHS->getLine() && + Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() && IsDefinition == RHS->isDefinition() && ScopeLine == RHS->getScopeLine() && ContainingType == RHS->getRawContainingType() && Virtuality == RHS->getVirtuality() && - VirtualIndex == RHS->getVirtualIndex() && Flags == RHS->getFlags() && - IsOptimized == RHS->isOptimized() && + VirtualIndex == RHS->getVirtualIndex() && + ThisAdjustment == RHS->getThisAdjustment() && + Flags == RHS->getFlags() && IsOptimized == RHS->isOptimized() && + Unit == RHS->getUnit() && TemplateParams == RHS->getRawTemplateParams() && Declaration == RHS->getRawDeclaration() && Variables == RHS->getRawVariables(); } unsigned getHashValue() const { - return hash_combine(Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, Flags, IsOptimized, - TemplateParams, Declaration, Variables); + // If this is a declaration inside an ODR type, only hash the type and the + // name. Otherwise the hash will be stronger than + // MDNodeSubsetEqualImpl::isDeclarationOfODRMember(). + if (!IsDefinition && LinkageName) + if (auto *CT = dyn_cast_or_null<DICompositeType>(Scope)) + if (CT->getRawIdentifier()) + return hash_combine(LinkageName, Scope); + + // Intentionally computes the hash on a subset of the operands for + // performance reason. The subset has to be significant enough to avoid + // collision "most of the time". There is no correctness issue in case of + // collision because of the full check above. + return hash_combine(Name, Scope, File, Type, Line); + } +}; + +template <> struct MDNodeSubsetEqualImpl<DISubprogram> { + typedef MDNodeKeyImpl<DISubprogram> KeyTy; + static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) { + return isDeclarationOfODRMember(LHS.IsDefinition, LHS.Scope, + LHS.LinkageName, RHS); + } + static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) { + return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(), + LHS->getRawLinkageName(), RHS); + } + + /// Subprograms compare equal if they declare the same function in an ODR + /// type. + static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope, + const MDString *LinkageName, + const DISubprogram *RHS) { + // Check whether the LHS is eligible. + if (IsDefinition || !Scope || !LinkageName) + return false; + + auto *CT = dyn_cast_or_null<DICompositeType>(Scope); + if (!CT || !CT->getRawIdentifier()) + return false; + + // Compare to the RHS. + return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() && + LinkageName == RHS->getRawLinkageName(); } }; @@ -569,18 +671,18 @@ template <> struct MDNodeKeyImpl<DILexicalBlockFile> { template <> struct MDNodeKeyImpl<DINamespace> { Metadata *Scope; Metadata *File; - StringRef Name; + MDString *Name; unsigned Line; - MDNodeKeyImpl(Metadata *Scope, Metadata *File, StringRef Name, unsigned Line) + MDNodeKeyImpl(Metadata *Scope, Metadata *File, MDString *Name, unsigned Line) : Scope(Scope), File(File), Name(Name), Line(Line) {} MDNodeKeyImpl(const DINamespace *N) - : Scope(N->getRawScope()), File(N->getRawFile()), Name(N->getName()), + : Scope(N->getRawScope()), File(N->getRawFile()), Name(N->getRawName()), Line(N->getLine()) {} bool isKeyOf(const DINamespace *RHS) const { return Scope == RHS->getRawScope() && File == RHS->getRawFile() && - Name == RHS->getName() && Line == RHS->getLine(); + Name == RHS->getRawName() && Line == RHS->getLine(); } unsigned getHashValue() const { return hash_combine(Scope, File, Name, Line); @@ -589,26 +691,24 @@ template <> struct MDNodeKeyImpl<DINamespace> { template <> struct MDNodeKeyImpl<DIModule> { Metadata *Scope; - StringRef Name; - StringRef ConfigurationMacros; - StringRef IncludePath; - StringRef ISysRoot; - MDNodeKeyImpl(Metadata *Scope, StringRef Name, - StringRef ConfigurationMacros, - StringRef IncludePath, - StringRef ISysRoot) - : Scope(Scope), Name(Name), ConfigurationMacros(ConfigurationMacros), - IncludePath(IncludePath), ISysRoot(ISysRoot) {} + MDString *Name; + MDString *ConfigurationMacros; + MDString *IncludePath; + MDString *ISysRoot; + MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, + MDString *IncludePath, MDString *ISysRoot) + : Scope(Scope), Name(Name), ConfigurationMacros(ConfigurationMacros), + IncludePath(IncludePath), ISysRoot(ISysRoot) {} MDNodeKeyImpl(const DIModule *N) - : Scope(N->getRawScope()), Name(N->getName()), - ConfigurationMacros(N->getConfigurationMacros()), - IncludePath(N->getIncludePath()), ISysRoot(N->getISysRoot()) {} + : Scope(N->getRawScope()), Name(N->getRawName()), + ConfigurationMacros(N->getRawConfigurationMacros()), + IncludePath(N->getRawIncludePath()), ISysRoot(N->getRawISysRoot()) {} bool isKeyOf(const DIModule *RHS) const { - return Scope == RHS->getRawScope() && Name == RHS->getName() && - ConfigurationMacros == RHS->getConfigurationMacros() && - IncludePath == RHS->getIncludePath() && - ISysRoot == RHS->getISysRoot(); + return Scope == RHS->getRawScope() && Name == RHS->getRawName() && + ConfigurationMacros == RHS->getRawConfigurationMacros() && + IncludePath == RHS->getRawIncludePath() && + ISysRoot == RHS->getRawISysRoot(); } unsigned getHashValue() const { return hash_combine(Scope, Name, @@ -617,33 +717,33 @@ template <> struct MDNodeKeyImpl<DIModule> { }; template <> struct MDNodeKeyImpl<DITemplateTypeParameter> { - StringRef Name; + MDString *Name; Metadata *Type; - MDNodeKeyImpl(StringRef Name, Metadata *Type) : Name(Name), Type(Type) {} + MDNodeKeyImpl(MDString *Name, Metadata *Type) : Name(Name), Type(Type) {} MDNodeKeyImpl(const DITemplateTypeParameter *N) - : Name(N->getName()), Type(N->getRawType()) {} + : Name(N->getRawName()), Type(N->getRawType()) {} bool isKeyOf(const DITemplateTypeParameter *RHS) const { - return Name == RHS->getName() && Type == RHS->getRawType(); + return Name == RHS->getRawName() && Type == RHS->getRawType(); } unsigned getHashValue() const { return hash_combine(Name, Type); } }; template <> struct MDNodeKeyImpl<DITemplateValueParameter> { unsigned Tag; - StringRef Name; + MDString *Name; Metadata *Type; Metadata *Value; - MDNodeKeyImpl(unsigned Tag, StringRef Name, Metadata *Type, Metadata *Value) + MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, Metadata *Value) : Tag(Tag), Name(Name), Type(Type), Value(Value) {} MDNodeKeyImpl(const DITemplateValueParameter *N) - : Tag(N->getTag()), Name(N->getName()), Type(N->getRawType()), + : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()), Value(N->getValue()) {} bool isKeyOf(const DITemplateValueParameter *RHS) const { - return Tag == RHS->getTag() && Name == RHS->getName() && + return Tag == RHS->getTag() && Name == RHS->getRawName() && Type == RHS->getRawType() && Value == RHS->getValue(); } unsigned getHashValue() const { return hash_combine(Tag, Name, Type, Value); } @@ -651,8 +751,8 @@ template <> struct MDNodeKeyImpl<DITemplateValueParameter> { template <> struct MDNodeKeyImpl<DIGlobalVariable> { Metadata *Scope; - StringRef Name; - StringRef LinkageName; + MDString *Name; + MDString *LinkageName; Metadata *File; unsigned Line; Metadata *Type; @@ -661,7 +761,7 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> { Metadata *Variable; Metadata *StaticDataMemberDeclaration; - MDNodeKeyImpl(Metadata *Scope, StringRef Name, StringRef LinkageName, + MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *Variable, Metadata *StaticDataMemberDeclaration) @@ -670,18 +770,18 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> { IsDefinition(IsDefinition), Variable(Variable), StaticDataMemberDeclaration(StaticDataMemberDeclaration) {} MDNodeKeyImpl(const DIGlobalVariable *N) - : Scope(N->getRawScope()), Name(N->getName()), - LinkageName(N->getLinkageName()), File(N->getRawFile()), + : Scope(N->getRawScope()), Name(N->getRawName()), + LinkageName(N->getRawLinkageName()), File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()), IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), Variable(N->getRawVariable()), StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()) {} bool isKeyOf(const DIGlobalVariable *RHS) const { - return Scope == RHS->getRawScope() && Name == RHS->getName() && - LinkageName == RHS->getLinkageName() && File == RHS->getRawFile() && - Line == RHS->getLine() && Type == RHS->getRawType() && - IsLocalToUnit == RHS->isLocalToUnit() && + return Scope == RHS->getRawScope() && Name == RHS->getRawName() && + LinkageName == RHS->getRawLinkageName() && + File == RHS->getRawFile() && Line == RHS->getLine() && + Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() && IsDefinition == RHS->isDefinition() && Variable == RHS->getRawVariable() && StaticDataMemberDeclaration == @@ -696,24 +796,24 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> { template <> struct MDNodeKeyImpl<DILocalVariable> { Metadata *Scope; - StringRef Name; + MDString *Name; Metadata *File; unsigned Line; Metadata *Type; unsigned Arg; unsigned Flags; - MDNodeKeyImpl(Metadata *Scope, StringRef Name, Metadata *File, unsigned Line, + MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags) : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg), Flags(Flags) {} MDNodeKeyImpl(const DILocalVariable *N) - : Scope(N->getRawScope()), Name(N->getName()), File(N->getRawFile()), + : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()), Flags(N->getFlags()) {} bool isKeyOf(const DILocalVariable *RHS) const { - return Scope == RHS->getRawScope() && Name == RHS->getName() && + return Scope == RHS->getRawScope() && Name == RHS->getRawName() && File == RHS->getRawFile() && Line == RHS->getLine() && Type == RHS->getRawType() && Arg == RHS->getArg() && Flags == RHS->getFlags(); @@ -738,28 +838,28 @@ template <> struct MDNodeKeyImpl<DIExpression> { }; template <> struct MDNodeKeyImpl<DIObjCProperty> { - StringRef Name; + MDString *Name; Metadata *File; unsigned Line; - StringRef GetterName; - StringRef SetterName; + MDString *GetterName; + MDString *SetterName; unsigned Attributes; Metadata *Type; - MDNodeKeyImpl(StringRef Name, Metadata *File, unsigned Line, - StringRef GetterName, StringRef SetterName, unsigned Attributes, + MDNodeKeyImpl(MDString *Name, Metadata *File, unsigned Line, + MDString *GetterName, MDString *SetterName, unsigned Attributes, Metadata *Type) : Name(Name), File(File), Line(Line), GetterName(GetterName), SetterName(SetterName), Attributes(Attributes), Type(Type) {} MDNodeKeyImpl(const DIObjCProperty *N) - : Name(N->getName()), File(N->getRawFile()), Line(N->getLine()), - GetterName(N->getGetterName()), SetterName(N->getSetterName()), + : Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), + GetterName(N->getRawGetterName()), SetterName(N->getRawSetterName()), Attributes(N->getAttributes()), Type(N->getRawType()) {} bool isKeyOf(const DIObjCProperty *RHS) const { - return Name == RHS->getName() && File == RHS->getRawFile() && - Line == RHS->getLine() && GetterName == RHS->getGetterName() && - SetterName == RHS->getSetterName() && + return Name == RHS->getRawName() && File == RHS->getRawFile() && + Line == RHS->getLine() && GetterName == RHS->getRawGetterName() && + SetterName == RHS->getRawSetterName() && Attributes == RHS->getAttributes() && Type == RHS->getRawType(); } unsigned getHashValue() const { @@ -773,19 +873,19 @@ template <> struct MDNodeKeyImpl<DIImportedEntity> { Metadata *Scope; Metadata *Entity; unsigned Line; - StringRef Name; + MDString *Name; MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, unsigned Line, - StringRef Name) + MDString *Name) : Tag(Tag), Scope(Scope), Entity(Entity), Line(Line), Name(Name) {} MDNodeKeyImpl(const DIImportedEntity *N) : Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()), - Line(N->getLine()), Name(N->getName()) {} + Line(N->getLine()), Name(N->getRawName()) {} bool isKeyOf(const DIImportedEntity *RHS) const { return Tag == RHS->getTag() && Scope == RHS->getRawScope() && Entity == RHS->getRawEntity() && Line == RHS->getLine() && - Name == RHS->getName(); + Name == RHS->getRawName(); } unsigned getHashValue() const { return hash_combine(Tag, Scope, Entity, Line, Name); @@ -795,18 +895,18 @@ template <> struct MDNodeKeyImpl<DIImportedEntity> { template <> struct MDNodeKeyImpl<DIMacro> { unsigned MIType; unsigned Line; - StringRef Name; - StringRef Value; + MDString *Name; + MDString *Value; - MDNodeKeyImpl(unsigned MIType, unsigned Line, StringRef Name, StringRef Value) + MDNodeKeyImpl(unsigned MIType, unsigned Line, MDString *Name, MDString *Value) : MIType(MIType), Line(Line), Name(Name), Value(Value) {} MDNodeKeyImpl(const DIMacro *N) - : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getName()), - Value(N->getValue()) {} + : MIType(N->getMacinfoType()), Line(N->getLine()), Name(N->getRawName()), + Value(N->getRawValue()) {} bool isKeyOf(const DIMacro *RHS) const { return MIType == RHS->getMacinfoType() && Line == RHS->getLine() && - Name == RHS->getName() && Value == RHS->getValue(); + Name == RHS->getRawName() && Value == RHS->getRawValue(); } unsigned getHashValue() const { return hash_combine(MIType, Line, Name, Value); @@ -838,6 +938,7 @@ template <> struct MDNodeKeyImpl<DIMacroFile> { /// \brief DenseMapInfo for MDNode subclasses. template <class NodeTy> struct MDNodeInfo { typedef MDNodeKeyImpl<NodeTy> KeyTy; + typedef MDNodeSubsetEqualImpl<NodeTy> SubsetEqualTy; static inline NodeTy *getEmptyKey() { return DenseMapInfo<NodeTy *>::getEmptyKey(); } @@ -851,10 +952,14 @@ template <class NodeTy> struct MDNodeInfo { static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; - return LHS.isKeyOf(RHS); + return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS); } static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) { - return LHS == RHS; + if (LHS == RHS) + return true; + if (RHS == getEmptyKey() || RHS == getTombstoneKey()) + return false; + return SubsetEqualTy::isSubsetEqual(LHS, RHS); } }; @@ -899,6 +1004,33 @@ public: } }; +/// Multimap-like storage for metadata attachments for globals. This differs +/// from MDAttachmentMap in that it allows multiple attachments per metadata +/// kind. +class MDGlobalAttachmentMap { + struct Attachment { + unsigned MDKind; + TrackingMDNodeRef Node; + }; + SmallVector<Attachment, 1> Attachments; + +public: + bool empty() const { return Attachments.empty(); } + + /// Appends all attachments with the given ID to \c Result in insertion order. + /// If the global has no attachments with the given ID, or if ID is invalid, + /// leaves Result unchanged. + void get(unsigned ID, SmallVectorImpl<MDNode *> &Result); + + void insert(unsigned ID, MDNode &MD); + void erase(unsigned ID); + + /// Appends all attachments for the global to \c Result, sorting by attachment + /// ID. Attachments with the same ID appear in insertion order. This function + /// does \em not clear \c Result. + void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const; +}; + class LLVMContextImpl { public: /// OwnedModules - The set of modules instantiated in this context, and which @@ -911,6 +1043,7 @@ public: LLVMContext::DiagnosticHandlerTy DiagnosticHandler; void *DiagnosticContext; bool RespectDiagnosticFilters; + bool DiagnosticHotnessRequested; LLVMContext::YieldCallbackTy YieldCallback; void *YieldOpaqueHandle; @@ -925,7 +1058,7 @@ public: FoldingSet<AttributeSetImpl> AttrsLists; FoldingSet<AttributeSetNode> AttrsSetNodes; - StringMap<MDString> MDStringCache; + StringMap<MDString, BumpPtrAllocator> MDStringCache; DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata; DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues; @@ -935,11 +1068,14 @@ public: DenseSet<CLASS *, CLASS##Info> CLASS##s; #include "llvm/IR/Metadata.def" + // Optional map for looking up composite types by identifier. + Optional<DenseMap<const MDString *, DICompositeType *>> DITypeMap; + // MDNodes may be uniqued or not uniqued. When they're not uniqued, they // aren't in the MDNodeSet, but they're still shared between objects, so no - // one object can destroy them. This set allows us to at least destroy them - // on Context destruction. - SmallPtrSet<MDNode *, 1> DistinctMDNodes; + // one object can destroy them. Keep track of them here so we can delete + // them on context teardown. + std::vector<MDNode *> DistinctMDNodes; DenseMap<Type*, ConstantAggregateZero*> CAZConstants; @@ -1006,8 +1142,8 @@ public: /// Collection of per-instruction metadata used in this context. DenseMap<const Instruction *, MDAttachmentMap> InstructionMetadata; - /// Collection of per-function metadata used in this context. - DenseMap<const Function *, MDAttachmentMap> FunctionMetadata; + /// Collection of per-GlobalObject metadata used in this context. + DenseMap<const GlobalObject *, MDGlobalAttachmentMap> GlobalObjectMetadata; /// DiscriminatorTable - This table maps file:line locations to an /// integer representing the next DWARF path discriminator to assign to @@ -1034,11 +1170,19 @@ public: /// clients which do use GC. DenseMap<const Function*, std::string> GCNames; + /// Flag to indicate if Value (other than GlobalValue) retains their name or + /// not. + bool DiscardValueNames = false; + LLVMContextImpl(LLVMContext &C); ~LLVMContextImpl(); /// Destroy the ConstantArrays if they are not used. void dropTriviallyDeadConstantArrays(); + + /// \brief Access the object which manages optimization bisection for failure + /// analysis. + OptBisect &getOptBisect(); }; } |