diff --git a/llvm/bindings/go/llvm/DIBuilderBindings.cpp b/llvm/bindings/go/llvm/DIBuilderBindings.cpp index cb7ac8ddd9c4..9126320c0ef6 100644 --- a/llvm/bindings/go/llvm/DIBuilderBindings.cpp +++ b/llvm/bindings/go/llvm/DIBuilderBindings.cpp @@ -18,12 +18,33 @@ using namespace llvm; +static Metadata *unwrapMetadata(LLVMValueRef VRef) { + Value *V = unwrap(VRef); + if (!V) + return nullptr; + if (auto *MD = dyn_cast(V)) + return MD->getMetadata(); + return ValueAsMetadata::get(V); +} + +static SmallVector unwrapMetadataArray(LLVMValueRef *Data, + size_t Length) { + SmallVector Elements; + for (size_t I = 0; I != Length; ++I) + Elements.push_back(unwrapMetadata(Data[I])); + return Elements; +} + namespace { template T unwrapDI(LLVMValueRef v) { - return v ? T(unwrap(v)) : T(); + return T(cast_or_null(unwrapMetadata(v))); } } +static LLVMValueRef wrapDI(DIDescriptor N) { + return wrap(MetadataAsValue::get(N->getContext(), N)); +} + DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder, LLVMDIBuilderRef) LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef mref) { @@ -47,14 +68,14 @@ LLVMValueRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef Dref, DIBuilder *D = unwrap(Dref); DICompileUnit CU = D->createCompileUnit(Lang, File, Dir, Producer, Optimized, Flags, RuntimeVersion); - return wrap(CU); + return wrapDI(CU); } LLVMValueRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Dref, const char *File, const char *Dir) { DIBuilder *D = unwrap(Dref); DIFile F = D->createFile(File, Dir); - return wrap(F); + return wrapDI(F); } LLVMValueRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref, @@ -64,7 +85,7 @@ LLVMValueRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref, DIBuilder *D = unwrap(Dref); DILexicalBlock LB = D->createLexicalBlock( unwrapDI(Scope), unwrapDI(File), Line, Column); - return wrap(LB); + return wrapDI(LB); } LLVMValueRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Dref, @@ -74,7 +95,7 @@ LLVMValueRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Dref, DIBuilder *D = unwrap(Dref); DILexicalBlockFile LBF = D->createLexicalBlockFile( unwrapDI(Scope), unwrapDI(File), Discriminator); - return wrap(LBF); + return wrapDI(LBF); } LLVMValueRef LLVMDIBuilderCreateFunction( @@ -87,7 +108,7 @@ LLVMValueRef LLVMDIBuilderCreateFunction( unwrapDI(Scope), Name, LinkageName, unwrapDI(File), Line, unwrapDI(CompositeType), IsLocalToUnit, IsDefinition, ScopeLine, Flags, IsOptimized, unwrap(Func)); - return wrap(SP); + return wrapDI(SP); } LLVMValueRef LLVMDIBuilderCreateLocalVariable( @@ -98,7 +119,7 @@ LLVMValueRef LLVMDIBuilderCreateLocalVariable( DIVariable V = D->createLocalVariable( Tag, unwrapDI(Scope), Name, unwrapDI(File), Line, unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo); - return wrap(V); + return wrapDI(V); } LLVMValueRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref, @@ -107,7 +128,7 @@ LLVMValueRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref, unsigned Encoding) { DIBuilder *D = unwrap(Dref); DIBasicType T = D->createBasicType(Name, SizeInBits, AlignInBits, Encoding); - return wrap(T); + return wrapDI(T); } LLVMValueRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref, @@ -118,7 +139,7 @@ LLVMValueRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref, DIBuilder *D = unwrap(Dref); DIDerivedType T = D->createPointerType(unwrapDI(PointeeType), SizeInBits, AlignInBits, Name); - return wrap(T); + return wrapDI(T); } LLVMValueRef LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref, @@ -127,7 +148,7 @@ LLVMValueRef LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref, DIBuilder *D = unwrap(Dref); DICompositeType CT = D->createSubroutineType( unwrapDI(File), unwrapDI(ParameterTypes)); - return wrap(CT); + return wrapDI(CT); } LLVMValueRef LLVMDIBuilderCreateStructType( @@ -139,7 +160,7 @@ LLVMValueRef LLVMDIBuilderCreateStructType( unwrapDI(Scope), Name, unwrapDI(File), Line, SizeInBits, AlignInBits, Flags, unwrapDI(DerivedFrom), unwrapDI(ElementTypes)); - return wrap(CT); + return wrapDI(CT); } LLVMValueRef LLVMDIBuilderCreateMemberType( @@ -150,7 +171,7 @@ LLVMValueRef LLVMDIBuilderCreateMemberType( DIDerivedType DT = D->createMemberType( unwrapDI(Scope), Name, unwrapDI(File), Line, SizeInBits, AlignInBits, OffsetInBits, Flags, unwrapDI(Ty)); - return wrap(DT); + return wrapDI(DT); } LLVMValueRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref, @@ -162,7 +183,7 @@ LLVMValueRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref, DICompositeType CT = D->createArrayType(SizeInBits, AlignInBits, unwrapDI(ElementType), unwrapDI(Subscripts)); - return wrap(CT); + return wrapDI(CT); } LLVMValueRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref, LLVMValueRef Ty, @@ -172,40 +193,36 @@ LLVMValueRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref, LLVMValueRef Ty, DIDerivedType DT = D->createTypedef(unwrapDI(Ty), Name, unwrapDI(File), Line, unwrapDI(Context)); - return wrap(DT); + return wrapDI(DT); } LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Dref, int64_t Lo, int64_t Count) { DIBuilder *D = unwrap(Dref); DISubrange S = D->getOrCreateSubrange(Lo, Count); - return wrap(S); + return wrapDI(S); } LLVMValueRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref, LLVMValueRef *Data, size_t Length) { DIBuilder *D = unwrap(Dref); - Value **DataValue = unwrap(Data); - ArrayRef Elements(DataValue, Length); - DIArray A = D->getOrCreateArray(Elements); - return wrap(A); + DIArray A = D->getOrCreateArray(unwrapMetadataArray(Data, Length)); + return wrapDI(A); } LLVMValueRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref, LLVMValueRef *Data, size_t Length) { DIBuilder *D = unwrap(Dref); - Value **DataValue = unwrap(Data); - ArrayRef Elements(DataValue, Length); - DITypeArray A = D->getOrCreateTypeArray(Elements); - return wrap(A); + DITypeArray A = D->getOrCreateTypeArray(unwrapMetadataArray(Data, Length)); + return wrapDI(A); } LLVMValueRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, int64_t *Addr, size_t Length) { DIBuilder *D = unwrap(Dref); DIExpression Expr = D->createExpression(ArrayRef(Addr, Length)); - return wrap(Expr); + return wrapDI(Expr); } LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref, diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 30c75950a5aa..8873fdb67730 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -1157,8 +1157,6 @@ LLVMTypeRef LLVMX86MMXType(void); macro(Argument) \ macro(BasicBlock) \ macro(InlineAsm) \ - macro(MDNode) \ - macro(MDString) \ macro(User) \ macro(Constant) \ macro(BlockAddress) \ @@ -1307,6 +1305,9 @@ LLVMBool LLVMIsUndef(LLVMValueRef Val); LLVMValueRef LLVMIsA##name(LLVMValueRef Val); LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST) +LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val); +LLVMValueRef LLVMIsAMDString(LLVMValueRef Val); + /** * @} */ diff --git a/llvm/include/llvm/CodeGen/LexicalScopes.h b/llvm/include/llvm/CodeGen/LexicalScopes.h index 021fd98750a0..f268a059e7b4 100644 --- a/llvm/include/llvm/CodeGen/LexicalScopes.h +++ b/llvm/include/llvm/CodeGen/LexicalScopes.h @@ -48,6 +48,8 @@ public: LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A) : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), LastInsn(nullptr), FirstInsn(nullptr), DFSIn(0), DFSOut(0) { + assert((!D || D->isResolved()) && "Expected resolved node"); + assert((!I || I->isResolved()) && "Expected resolved node"); if (Parent) Parent->addChild(this); } @@ -116,8 +118,8 @@ public: private: LexicalScope *Parent; // Parent to this scope. - AssertingVH Desc; // Debug info descriptor. - AssertingVH InlinedAtLocation; // Location at which this + const MDNode *Desc; // Debug info descriptor. + const MDNode *InlinedAtLocation; // Location at which this // scope is inlined. bool AbstractScope; // Abstract Scope SmallVector Children; // Scopes defined in scope. diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index d20b45b333db..bcf1f5caaa8c 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -1139,7 +1139,10 @@ public: /// setDebugLoc - Replace current source information with new such. /// Avoid using this, the constructor argument is preferable. /// - void setDebugLoc(const DebugLoc dl) { debugLoc = dl; } + void setDebugLoc(const DebugLoc dl) { + debugLoc = dl; + assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); + } /// RemoveOperand - Erase an operand from an instruction, leaving it with one /// fewer operand than it started with. diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/llvm/include/llvm/CodeGen/MachineModuleInfo.h index 6653333a18f6..287b3ebb0e22 100644 --- a/llvm/include/llvm/CodeGen/MachineModuleInfo.h +++ b/llvm/include/llvm/CodeGen/MachineModuleInfo.h @@ -165,10 +165,13 @@ public: static char ID; // Pass identification, replacement for typeid struct VariableDbgInfo { - TrackingVH Var; - TrackingVH Expr; + TrackingMDNodeRef Var; + TrackingMDNodeRef Expr; unsigned Slot; DebugLoc Loc; + + VariableDbgInfo(MDNode *Var, MDNode *Expr, unsigned Slot, DebugLoc Loc) + : Var(Var), Expr(Expr), Slot(Slot), Loc(Loc) {} }; typedef SmallVector VariableDbgInfoMapTy; VariableDbgInfoMapTy VariableDbgInfos; @@ -393,8 +396,7 @@ public: /// information of a variable. void setVariableDbgInfo(MDNode *Var, MDNode *Expr, unsigned Slot, DebugLoc Loc) { - VariableDbgInfo Info = {Var, Expr, Slot, Loc}; - VariableDbgInfos.push_back(std::move(Info)); + VariableDbgInfos.emplace_back(Var, Expr, Slot, Loc); } VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfos; } diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index acd178892d01..e4ef3db49c26 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -762,6 +762,7 @@ protected: ValueList(VTs.VTs), UseList(nullptr), NumOperands(Ops.size()), NumValues(VTs.NumVTs), debugLoc(dl), IROrder(Order) { + assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); assert(NumOperands == Ops.size() && "NumOperands wasn't wide enough for its operands!"); assert(NumValues == VTs.NumVTs && @@ -780,6 +781,7 @@ protected: SubclassData(0), NodeId(-1), OperandList(nullptr), ValueList(VTs.VTs), UseList(nullptr), NumOperands(0), NumValues(VTs.NumVTs), debugLoc(dl), IROrder(Order) { + assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); assert(NumValues == VTs.NumVTs && "NumValues wasn't wide enough for its operands!"); } diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 3a50609d6858..859bd52bda50 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -18,6 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/DebugInfo.h" +#include "llvm/IR/TrackingMDRef.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/DataTypes.h" @@ -65,22 +66,34 @@ namespace llvm { Function *DeclareFn; // llvm.dbg.declare Function *ValueFn; // llvm.dbg.value - SmallVector AllEnumTypes; - /// Use TrackingVH to collect RetainTypes, since they can be updated - /// later on. - SmallVector, 4> AllRetainTypes; - SmallVector AllSubprograms; - SmallVector AllGVs; - SmallVector, 4> AllImportedModules; + SmallVector AllEnumTypes; + /// Track the RetainTypes, since they can be updated later on. + SmallVector AllRetainTypes; + SmallVector AllSubprograms; + SmallVector AllGVs; + SmallVector AllImportedModules; + + /// \brief Track nodes that may be unresolved. + SmallVector UnresolvedNodes; + bool AllowUnresolvedNodes; /// Each subprogram's preserved local variables. - DenseMap>> PreservedVariables; + DenseMap> PreservedVariables; DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION; void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION; + /// \brief Create a temporary. + /// + /// Create an \a MDNodeFwdDecl and track it in \a UnresolvedNodes. + void trackIfUnresolved(MDNode *N); + public: - explicit DIBuilder(Module &M); + /// \brief Construct a builder for a module. + /// + /// If \c AllowUnresolved, collect unresolved nodes attached to the module + /// in order to resolve cycles during \a finalize(). + explicit DIBuilder(Module &M, bool AllowUnresolved = true); enum DebugEmissionKind { FullDebug=1, LineTablesOnly }; /// finalize - Construct any deferred debug info descriptors. @@ -437,10 +450,10 @@ namespace llvm { DIBasicType createUnspecifiedParameter(); /// getOrCreateArray - Get a DIArray, create one if required. - DIArray getOrCreateArray(ArrayRef Elements); + DIArray getOrCreateArray(ArrayRef Elements); /// getOrCreateTypeArray - Get a DITypeArray, create one if required. - DITypeArray getOrCreateTypeArray(ArrayRef Elements); + DITypeArray getOrCreateTypeArray(ArrayRef Elements); /// getOrCreateSubrange - Create a descriptor for a value range. This /// implicitly uniques the values returned. diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h index 4bc746438929..a17ebbc0d3eb 100644 --- a/llvm/include/llvm/IR/DebugInfo.h +++ b/llvm/include/llvm/IR/DebugInfo.h @@ -168,8 +168,9 @@ public: bool Verify() const; - operator MDNode *() const { return const_cast(DbgNode); } - MDNode *operator->() const { return const_cast(DbgNode); } + MDNode *get() const { return const_cast(DbgNode); } + operator MDNode *() const { return get(); } + MDNode *operator->() const { return get(); } // An explicit operator bool so that we can do testing of DI values // easily. @@ -740,7 +741,7 @@ public: DIScopeRef getContext() const { return getFieldAs(1); } DITypeRef getType() const { return getFieldAs(2); } - Value *getValue() const; + Metadata *getValue() const; StringRef getFilename() const { return getFieldAs(4).getFilename(); } StringRef getDirectory() const { return getFieldAs(4).getDirectory(); diff --git a/llvm/include/llvm/IR/DebugLoc.h b/llvm/include/llvm/IR/DebugLoc.h index 3d969a8b7532..b238b0d56efe 100644 --- a/llvm/include/llvm/IR/DebugLoc.h +++ b/llvm/include/llvm/IR/DebugLoc.h @@ -16,50 +16,40 @@ #define LLVM_IR_DEBUGLOC_H #include "llvm/Support/DataTypes.h" +#include "llvm/IR/TrackingMDRef.h" namespace llvm { - template struct DenseMapInfo; - class MDNode; + class LLVMContext; class raw_ostream; + class MDNode; /// DebugLoc - Debug location id. This is carried by Instruction, SDNode, /// and MachineInstr to compactly encode file/line/scope information for an /// operation. class DebugLoc { - friend struct DenseMapInfo; + TrackingMDNodeRef Loc; - /// getEmptyKey() - A private constructor that returns an unknown that is - /// not equal to the tombstone key or DebugLoc(). - static DebugLoc getEmptyKey() { - DebugLoc DL; - DL.LineCol = 1; - return DL; - } - - /// getTombstoneKey() - A private constructor that returns an unknown that - /// is not equal to the empty key or DebugLoc(). - static DebugLoc getTombstoneKey() { - DebugLoc DL; - DL.LineCol = 2; - return DL; - } - - /// LineCol - This 32-bit value encodes the line and column number for the - /// location, encoded as 24-bits for line and 8 bits for col. A value of 0 - /// for either means unknown. - uint32_t LineCol; - - /// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information, - /// decoded by LLVMContext. 0 is unknown. - int ScopeIdx; public: - DebugLoc() : LineCol(0), ScopeIdx(0) {} // Defaults to unknown. + DebugLoc() {} + DebugLoc(DebugLoc &&X) : Loc(std::move(X.Loc)) {} + DebugLoc(const DebugLoc &X) : Loc(X.Loc) {} + DebugLoc &operator=(DebugLoc &&X) { + Loc = std::move(X.Loc); + return *this; + } + DebugLoc &operator=(const DebugLoc &X) { + Loc = X.Loc; + return *this; + } + + /// \brief Check whether this has a trivial destructor. + bool hasTrivialDestructor() const { return Loc.hasTrivialDestructor(); } /// get - Get a new DebugLoc that corresponds to the specified line/col /// scope/inline location. - static DebugLoc get(unsigned Line, unsigned Col, - MDNode *Scope, MDNode *InlinedAt = nullptr); + static DebugLoc get(unsigned Line, unsigned Col, MDNode *Scope, + MDNode *InlinedAt = nullptr); /// getFromDILocation - Translate the DILocation quad into a DebugLoc. static DebugLoc getFromDILocation(MDNode *N); @@ -68,56 +58,54 @@ namespace llvm { static DebugLoc getFromDILexicalBlock(MDNode *N); /// isUnknown - Return true if this is an unknown location. - bool isUnknown() const { return ScopeIdx == 0; } + bool isUnknown() const { return !Loc; } - unsigned getLine() const { - return (LineCol << 8) >> 8; // Mask out column. - } - - unsigned getCol() const { - return LineCol >> 24; - } + unsigned getLine() const; + unsigned getCol() const; /// getScope - This returns the scope pointer for this DebugLoc, or null if /// invalid. - MDNode *getScope(const LLVMContext &Ctx) const; + MDNode *getScope() const; + MDNode *getScope(const LLVMContext &) const { return getScope(); } /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or /// null if invalid or not present. - MDNode *getInlinedAt(const LLVMContext &Ctx) const; + MDNode *getInlinedAt() const; + MDNode *getInlinedAt(const LLVMContext &) const { return getInlinedAt(); } /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values. + void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const; void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, - const LLVMContext &Ctx) const; + const LLVMContext &) const { + return getScopeAndInlinedAt(Scope, IA); + } /// getScopeNode - Get MDNode for DebugLoc's scope, or null if invalid. - MDNode *getScopeNode(const LLVMContext &Ctx) const; + MDNode *getScopeNode() const; + MDNode *getScopeNode(const LLVMContext &) const { return getScopeNode(); } // getFnDebugLoc - Walk up the scope chain of given debug loc and find line // number info for the function. - DebugLoc getFnDebugLoc(const LLVMContext &Ctx) const; + DebugLoc getFnDebugLoc() const; + DebugLoc getFnDebugLoc(const LLVMContext &) const { + return getFnDebugLoc(); + } /// getAsMDNode - This method converts the compressed DebugLoc node into a /// DILocation compatible MDNode. - MDNode *getAsMDNode(const LLVMContext &Ctx) const; + MDNode *getAsMDNode() const; + MDNode *getAsMDNode(LLVMContext &) const { return getAsMDNode(); } - bool operator==(const DebugLoc &DL) const { - return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx; - } + bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; } bool operator!=(const DebugLoc &DL) const { return !(*this == DL); } - void dump(const LLVMContext &Ctx) const; + void dump() const; + void dump(const LLVMContext &) const { dump(); } /// \brief prints source location /path/to/file.exe:line:col @[inlined at] - void print(const LLVMContext &Ctx, raw_ostream &OS) const; + void print(raw_ostream &OS) const; + void print(const LLVMContext &, raw_ostream &OS) const { print(OS); } }; - template <> - struct DenseMapInfo { - static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); } - static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); } - static unsigned getHashValue(const DebugLoc &Key); - static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; } - }; } // end namespace llvm #endif /* LLVM_SUPPORT_DEBUGLOC_H */ diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h index d4cb67af7285..c227ea080167 100644 --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -28,6 +28,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Metadata.h" namespace llvm { /// IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic @@ -81,8 +82,14 @@ namespace llvm { class DbgDeclareInst : public DbgInfoIntrinsic { public: Value *getAddress() const; - MDNode *getVariable() const { return cast(getArgOperand(1)); } - MDNode *getExpression() const { return cast(getArgOperand(2)); } + MDNode *getVariable() const { + return cast( + cast(getArgOperand(1))->getMetadata()); + } + MDNode *getExpression() const { + return cast( + cast(getArgOperand(2))->getMetadata()); + } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const IntrinsicInst *I) { @@ -103,8 +110,14 @@ namespace llvm { return cast( const_cast(getArgOperand(1)))->getZExtValue(); } - MDNode *getVariable() const { return cast(getArgOperand(2)); } - MDNode *getExpression() const { return cast(getArgOperand(3)); } + MDNode *getVariable() const { + return cast( + cast(getArgOperand(2))->getMetadata()); + } + MDNode *getExpression() const { + return cast( + cast(getArgOperand(3))->getMetadata()); + } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const IntrinsicInst *I) { diff --git a/llvm/include/llvm/IR/MDBuilder.h b/llvm/include/llvm/IR/MDBuilder.h index d29512ce1fff..91a6685f6125 100644 --- a/llvm/include/llvm/IR/MDBuilder.h +++ b/llvm/include/llvm/IR/MDBuilder.h @@ -24,6 +24,8 @@ namespace llvm { class APInt; template class ArrayRef; class LLVMContext; +class Constant; +class ConstantAsMetadata; class MDNode; class MDString; @@ -36,6 +38,9 @@ public: /// \brief Return the given string as metadata. MDString *createString(StringRef Str); + /// \brief Return the given constant as metadata. + ConstantAsMetadata *createConstant(Constant *C); + //===------------------------------------------------------------------===// // FPMath metadata. //===------------------------------------------------------------------===// diff --git a/llvm/include/llvm/IR/Metadata.def b/llvm/include/llvm/IR/Metadata.def new file mode 100644 index 000000000000..75e0e3ef4827 --- /dev/null +++ b/llvm/include/llvm/IR/Metadata.def @@ -0,0 +1,44 @@ +//===- llvm/Metadata.def - Metadata definitions -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Macros for running through all types of metadata. +// +//===----------------------------------------------------------------------===// + +#if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \ + defined HANDLE_METADATA_BRANCH) +#error "Missing macro definition of HANDLE_METADATA*" +#endif + +// Handler for all types of metadata. +#ifndef HANDLE_METADATA +#define HANDLE_METADATA(CLASS) +#endif + +// Handler for leaf nodes in the class hierarchy. +#ifndef HANDLE_METADATA_LEAF +#define HANDLE_METADATA_LEAF(CLASS) HANDLE_METADATA(CLASS) +#endif + +// Handler for non-leaf nodes in the class hierarchy. +#ifndef HANDLE_METADATA_BRANCH +#define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS) +#endif + +HANDLE_METADATA_LEAF(MDString) +HANDLE_METADATA_BRANCH(ValueAsMetadata) +HANDLE_METADATA_LEAF(ConstantAsMetadata) +HANDLE_METADATA_LEAF(LocalAsMetadata) +HANDLE_METADATA_BRANCH(MDNode) +HANDLE_METADATA_LEAF(MDNodeFwdDecl) +HANDLE_METADATA_LEAF(GenericMDNode) + +#undef HANDLE_METADATA +#undef HANDLE_METADATA_LEAF +#undef HANDLE_METADATA_BRANCH diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h index 189ea3e73d66..56699b0fc4d2 100644 --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -18,11 +18,13 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/IR/Constant.h" +#include "llvm/IR/MetadataTracking.h" #include "llvm/IR/Value.h" #include "llvm/Support/ErrorHandling.h" +#include namespace llvm { class LLVMContext; @@ -38,20 +40,388 @@ enum LLVMConstants : uint32_t { /// \brief Root of the metadata hierarchy. /// /// This is a root class for typeless data in the IR. -/// -/// TODO: Detach from the Value hierarchy. -class Metadata : public Value { +class Metadata { + friend class ReplaceableMetadataImpl; + + /// \brief RTTI. + const unsigned char SubclassID; + protected: - Metadata(LLVMContext &Context, unsigned ID); + /// \brief Storage flag for non-uniqued, otherwise unowned, metadata. + bool IsDistinctInContext : 1; + // TODO: expose remaining bits to subclasses. + + unsigned short SubclassData16; + unsigned SubclassData32; public: + enum MetadataKind { + GenericMDNodeKind, + MDNodeFwdDeclKind, + ConstantAsMetadataKind, + LocalAsMetadataKind, + MDStringKind + }; + +protected: + Metadata(unsigned ID) + : SubclassID(ID), IsDistinctInContext(false), SubclassData16(0), + SubclassData32(0) {} + ~Metadata() {} + + /// \brief Store this in a big non-uniqued untyped bucket. + bool isStoredDistinctInContext() const { return IsDistinctInContext; } + + /// \brief Default handling of a changed operand, which asserts. + /// + /// If subclasses pass themselves in as owners to a tracking node reference, + /// they must provide an implementation of this method. + void handleChangedOperand(void *, Metadata *) { + llvm_unreachable("Unimplemented in Metadata subclass"); + } + +public: + unsigned getMetadataID() const { return SubclassID; } + + /// \brief User-friendly dump. + void dump() const; + void print(raw_ostream &OS) const; + void printAsOperand(raw_ostream &OS, bool PrintType = true, + const Module *M = nullptr) const; +}; + +#define HANDLE_METADATA(CLASS) class CLASS; +#include "llvm/IR/Metadata.def" + +inline raw_ostream &operator<<(raw_ostream &OS, const Metadata &MD) { + MD.print(OS); + return OS; +} + +/// \brief Metadata wrapper in the Value hierarchy. +/// +/// A member of the \a Value hierarchy to represent a reference to metadata. +/// This allows, e.g., instrinsics to have metadata as operands. +/// +/// Notably, this is the only thing in either hierarchy that is allowed to +/// reference \a LocalAsMetadata. +class MetadataAsValue : public Value { + friend class ReplaceableMetadataImpl; + friend class LLVMContextImpl; + + Metadata *MD; + + MetadataAsValue(Type *Ty, Metadata *MD); + ~MetadataAsValue(); + +public: + static MetadataAsValue *get(LLVMContext &Context, Metadata *MD); + static MetadataAsValue *getIfExists(LLVMContext &Context, Metadata *MD); + Metadata *getMetadata() const { return MD; } + static bool classof(const Value *V) { - return V->getValueID() == GenericMDNodeVal || - V->getValueID() == MDNodeFwdDeclVal || - V->getValueID() == MDStringVal; + return V->getValueID() == MetadataAsValueVal; + } + +private: + void handleChangedMetadata(Metadata *MD); + void track(); + void untrack(); +}; + +/// \brief Shared implementation of use-lists for replaceable metadata. +/// +/// Most metadata cannot be RAUW'ed. This is a shared implementation of +/// use-lists and associated API for the two that support it (\a ValueAsMetadata +/// and \a TempMDNode). +class ReplaceableMetadataImpl { + friend class MetadataTracking; + +public: + typedef MetadataTracking::OwnerTy OwnerTy; + +private: + SmallDenseMap UseMap; + +public: + ~ReplaceableMetadataImpl() { + assert(UseMap.empty() && "Cannot destroy in-use replaceable metadata"); + } + + /// \brief Replace all uses of this with MD. + /// + /// Replace all uses of this with \c MD, which is allowed to be null. + void replaceAllUsesWith(Metadata *MD); + + /// \brief Resolve all uses of this. + /// + /// Resolve all uses of this, turning off RAUW permanently. If \c + /// ResolveUsers, call \a GenericMDNode::resolve() on any users whose last + /// operand is resolved. + void resolveAllUses(bool ResolveUsers = true); + +private: + void addRef(void *Ref, OwnerTy Owner); + void dropRef(void *Ref); + void moveRef(void *Ref, void *New, const Metadata &MD); + + static ReplaceableMetadataImpl *get(Metadata &MD); +}; + +/// \brief Value wrapper in the Metadata hierarchy. +/// +/// This is a custom value handle that allows other metadata to refer to +/// classes in the Value hierarchy. +/// +/// Because of full uniquing support, each value is only wrapped by a single \a +/// ValueAsMetadata object, so the lookup maps are far more efficient than +/// those using ValueHandleBase. +class ValueAsMetadata : public Metadata, ReplaceableMetadataImpl { + friend class ReplaceableMetadataImpl; + friend class LLVMContextImpl; + + Value *V; + +protected: + ValueAsMetadata(LLVMContext &Context, unsigned ID, Value *V) + : Metadata(ID), V(V) { + assert(V && "Expected valid value"); + } + ~ValueAsMetadata() {} + +public: + static ValueAsMetadata *get(Value *V); + static ConstantAsMetadata *getConstant(Value *C) { + return cast(get(C)); + } + static LocalAsMetadata *getLocal(Value *Local) { + return cast(get(Local)); + } + + static ValueAsMetadata *getIfExists(Value *V); + static ConstantAsMetadata *getConstantIfExists(Value *C) { + return cast_or_null(getIfExists(C)); + } + static LocalAsMetadata *getLocalIfExists(Value *Local) { + return cast_or_null(getIfExists(Local)); + } + + Value *getValue() const { return V; } + Type *getType() const { return V->getType(); } + LLVMContext &getContext() const { return V->getContext(); } + + static void handleDeletion(Value *V); + static void handleRAUW(Value *From, Value *To); + +protected: + /// \brief Handle collisions after \a Value::replaceAllUsesWith(). + /// + /// RAUW isn't supported directly for \a ValueAsMetadata, but if the wrapped + /// \a Value gets RAUW'ed and the target already exists, this is used to + /// merge the two metadata nodes. + void replaceAllUsesWith(Metadata *MD) { + ReplaceableMetadataImpl::replaceAllUsesWith(MD); + } + +public: + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == LocalAsMetadataKind || + MD->getMetadataID() == ConstantAsMetadataKind; } }; +class ConstantAsMetadata : public ValueAsMetadata { + friend class ValueAsMetadata; + + ConstantAsMetadata(LLVMContext &Context, Constant *C) + : ValueAsMetadata(Context, ConstantAsMetadataKind, C) {} + +public: + static ConstantAsMetadata *get(Constant *C) { + return ValueAsMetadata::getConstant(C); + } + static ConstantAsMetadata *getIfExists(Constant *C) { + return ValueAsMetadata::getConstantIfExists(C); + } + + Constant *getValue() const { + return cast(ValueAsMetadata::getValue()); + } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == ConstantAsMetadataKind; + } +}; + +class LocalAsMetadata : public ValueAsMetadata { + friend class ValueAsMetadata; + + LocalAsMetadata(LLVMContext &Context, Value *Local) + : ValueAsMetadata(Context, LocalAsMetadataKind, Local) { + assert(!isa(Local) && "Expected local value"); + } + +public: + static LocalAsMetadata *get(Value *Local) { + return ValueAsMetadata::getLocal(Local); + } + static LocalAsMetadata *getIfExists(Value *Local) { + return ValueAsMetadata::getLocalIfExists(Local); + } + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == LocalAsMetadataKind; + } +}; + +/// \brief Transitional API for extracting constants from Metadata. +/// +/// This namespace contains transitional functions for metadata that points to +/// \a Constants. +/// +/// In prehistory -- when metadata was a subclass of \a Value -- \a MDNode +/// operands could refer to any \a Value. There's was a lot of code like this: +/// +/// \code +/// MDNode *N = ...; +/// auto *CI = dyn_cast(N->getOperand(2)); +/// \endcode +/// +/// Now that \a Value and \a Metadata are in separate hierarchies, maintaining +/// the semantics for \a isa(), \a cast(), \a dyn_cast() (etc.) requires three +/// steps: cast in the \a Metadata hierarchy, extraction of the \a Value, and +/// cast in the \a Value hierarchy. Besides creating boiler-plate, this +/// requires subtle control flow changes. +/// +/// The end-goal is to create a new type of metadata, called (e.g.) \a MDInt, +/// so that metadata can refer to numbers without traversing a bridge to the \a +/// Value hierarchy. In this final state, the code above would look like this: +/// +/// \code +/// MDNode *N = ...; +/// auto *MI = dyn_cast(N->getOperand(2)); +/// \endcode +/// +/// The API in this namespace supports the transition. \a MDInt doesn't exist +/// yet, and even once it does, changing each metadata schema to use it is its +/// own mini-project. In the meantime this API prevents us from introducing +/// complex and bug-prone control flow that will disappear in the end. In +/// particular, the above code looks like this: +/// +/// \code +/// MDNode *N = ...; +/// auto *CI = mdconst::dyn_extract(N->getOperand(2)); +/// \endcode +/// +/// The full set of provided functions includes: +/// +/// mdconst::hasa <=> isa +/// mdconst::extract <=> cast +/// mdconst::extract_or_null <=> cast_or_null +/// mdconst::dyn_extract <=> dyn_cast +/// mdconst::dyn_extract_or_null <=> dyn_cast_or_null +/// +/// The target of the cast must be a subclass of \a Constant. +namespace mdconst { + +namespace detail { +template T &make(); +template struct HasDereference { + typedef char Yes[1]; + typedef char No[2]; + template struct SFINAE {}; + + template + static Yes &hasDereference(SFINAE(*make()))> * = 0); + template static No &hasDereference(...); + + static const bool value = + sizeof(hasDereference(nullptr)) == sizeof(Yes); +}; +template struct IsValidPointer { + static const bool value = std::is_base_of::value && + HasDereference::value; +}; +template struct IsValidReference { + static const bool value = std::is_base_of::value && + std::is_convertible::value; +}; +} // end namespace detail + +/// \brief Check whether Metadata has a Value. +/// +/// As an analogue to \a isa(), check whether \c MD has an \a Value inside of +/// type \c X. +template +inline typename std::enable_if::value, bool>::type +hasa(Y &&MD) { + assert(MD && "Null pointer sent into hasa"); + if (auto *V = dyn_cast(MD)) + return isa(V->getValue()); + return false; +} +template +inline + typename std::enable_if::value, bool>::type + hasa(Y &MD) { + return hasa(&MD); +} + +/// \brief Extract a Value from Metadata. +/// +/// As an analogue to \a cast(), extract the \a Value subclass \c X from \c MD. +template +inline typename std::enable_if::value, X *>::type +extract(Y &&MD) { + return cast(cast(MD)->getValue()); +} +template +inline + typename std::enable_if::value, X *>::type + extract(Y &MD) { + return extract(&MD); +} + +/// \brief Extract a Value from Metadata, allowing null. +/// +/// As an analogue to \a cast_or_null(), extract the \a Value subclass \c X +/// from \c MD, allowing \c MD to be null. +template +inline typename std::enable_if::value, X *>::type +extract_or_null(Y &&MD) { + if (auto *V = cast_or_null(MD)) + return cast(V->getValue()); + return nullptr; +} + +/// \brief Extract a Value from Metadata, if any. +/// +/// As an analogue to \a dyn_cast_or_null(), extract the \a Value subclass \c X +/// from \c MD, return null if \c MD doesn't contain a \a Value or if the \a +/// Value it does contain is of the wrong subclass. +template +inline typename std::enable_if::value, X *>::type +dyn_extract(Y &&MD) { + if (auto *V = dyn_cast(MD)) + return dyn_cast(V->getValue()); + return nullptr; +} + +/// \brief Extract a Value from Metadata, if any, allowing null. +/// +/// As an analogue to \a dyn_cast_or_null(), extract the \a Value subclass \c X +/// from \c MD, return null if \c MD doesn't contain a \a Value or if the \a +/// Value it does contain is of the wrong subclass, allowing \c MD to be null. +template +inline typename std::enable_if::value, X *>::type +dyn_extract_or_null(Y &&MD) { + if (auto *V = dyn_cast_or_null(MD)) + return dyn_cast(V->getValue()); + return nullptr; +} + +} // end namespace mdconst + //===----------------------------------------------------------------------===// /// \brief A single uniqued string. /// @@ -60,15 +430,13 @@ public: class MDString : public Metadata { friend class StringMapEntry; - virtual void anchor(); MDString(const MDString &) LLVM_DELETED_FUNCTION; + MDString &operator=(MDString &&) LLVM_DELETED_FUNCTION; + MDString &operator=(const MDString &) LLVM_DELETED_FUNCTION; StringMapEntry *Entry; - explicit MDString(LLVMContext &Context) - : Metadata(Context, Value::MDStringVal), Entry(nullptr) {} - - /// \brief Shadow Value::getName() to prevent its use. - StringRef getName() const LLVM_DELETED_FUNCTION; + MDString() : Metadata(MDStringKind), Entry(nullptr) {} + MDString(MDString &&) : Metadata(MDStringKind) {} public: static MDString *get(LLVMContext &Context, StringRef Str); @@ -89,8 +457,8 @@ public: iterator end() const { return getString().end(); } /// \brief Methods for support type inquiry through isa, cast, and dyn_cast. - static bool classof(const Value *V) { - return V->getValueID() == MDStringVal; + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == MDStringKind; } }; @@ -138,18 +506,80 @@ struct DenseMapInfo { } }; -class MDNodeOperand; +/// \brief Tracking metadata reference owned by Metadata. +/// +/// Similar to \a TrackingMDRef, but it's expected to be owned by an instance +/// of \a Metadata, which has the option of registering itself for callbacks to +/// re-unique itself. +/// +/// In particular, this is used by \a MDNode. +class MDOperand { + MDOperand(MDOperand &&) LLVM_DELETED_FUNCTION; + MDOperand(const MDOperand &) LLVM_DELETED_FUNCTION; + MDOperand &operator=(MDOperand &&) LLVM_DELETED_FUNCTION; + MDOperand &operator=(const MDOperand &) LLVM_DELETED_FUNCTION; + + Metadata *MD; + +public: + MDOperand() : MD(nullptr) {} + ~MDOperand() { untrack(); } + + LLVM_EXPLICIT operator bool() const { return get(); } + Metadata *get() const { return MD; } + operator Metadata *() const { return get(); } + Metadata *operator->() const { return get(); } + Metadata &operator*() const { return *get(); } + + void reset() { + untrack(); + MD = nullptr; + } + void reset(Metadata *MD, Metadata *Owner) { + untrack(); + this->MD = MD; + track(Owner); + } + +private: + void track(Metadata *Owner) { + if (MD) { + if (Owner) + MetadataTracking::track(this, *MD, *Owner); + else + MetadataTracking::track(MD); + } + } + void untrack() { + assert(static_cast(this) == &MD && "Expected same address"); + if (MD) + MetadataTracking::untrack(MD); + } +}; + +template <> struct simplify_type { + typedef Metadata *SimpleType; + static SimpleType getSimplifiedValue(MDOperand &MD) { return MD.get(); } +}; + +template <> struct simplify_type { + typedef Metadata *SimpleType; + static SimpleType getSimplifiedValue(const MDOperand &MD) { return MD.get(); } +}; //===----------------------------------------------------------------------===// /// \brief Tuple of metadata. class MDNode : public Metadata { MDNode(const MDNode &) LLVM_DELETED_FUNCTION; void operator=(const MDNode &) LLVM_DELETED_FUNCTION; - friend class MDNodeOperand; - friend class LLVMContextImpl; void *operator new(size_t) LLVM_DELETED_FUNCTION; + LLVMContext &Context; + unsigned NumOperands; + protected: + unsigned MDNodeSubclassData; + void *operator new(size_t Size, unsigned NumOps); /// \brief Required by std, but never called. @@ -165,83 +595,83 @@ protected: llvm_unreachable("Constructor throws?"); } - /// \brief Subclass data enums. - enum { - /// FunctionLocalBit - This bit is set if this MDNode is function local. - /// This is true when it (potentially transitively) contains a reference to - /// something in a function, like an argument, basicblock, or instruction. - FunctionLocalBit = 1 << 0, + MDNode(LLVMContext &Context, unsigned ID, ArrayRef MDs); + ~MDNode() { dropAllReferences(); } - /// NotUniquedBit - This is set on MDNodes that are not uniqued because they - /// have a null operand. - NotUniquedBit = 1 << 1 - }; + void dropAllReferences(); + void storeDistinctInContext(); - /// \brief FunctionLocal enums. - enum FunctionLocalness { - FL_Unknown = -1, - FL_No = 0, - FL_Yes = 1 - }; + static MDNode *getMDNode(LLVMContext &C, ArrayRef MDs, + bool Insert = true); - /// \brief Replace each instance of the given operand with a new value. - void replaceOperand(MDNodeOperand *Op, Value *NewVal); + MDOperand *mutable_begin() { return mutable_end() - NumOperands; } + MDOperand *mutable_end() { return reinterpret_cast(this); } - MDNode(LLVMContext &C, unsigned ID, ArrayRef Vals, - bool isFunctionLocal); - ~MDNode() {} - - static MDNode *getMDNode(LLVMContext &C, ArrayRef Vals, - FunctionLocalness FL, bool Insert = true); public: - static MDNode *get(LLVMContext &Context, ArrayRef Vals); - /// \brief Construct MDNode with an explicit function-localness. - /// - /// Don't analyze Vals; trust isFunctionLocal. + static MDNode *get(LLVMContext &Context, ArrayRef MDs) { + return getMDNode(Context, MDs, true); + } static MDNode *getWhenValsUnresolved(LLVMContext &Context, - ArrayRef Vals, - bool isFunctionLocal); + ArrayRef MDs) { + // TODO: Remove this. + return get(Context, MDs); + } - static MDNode *getIfExists(LLVMContext &Context, ArrayRef Vals); + static MDNode *getIfExists(LLVMContext &Context, ArrayRef MDs) { + return getMDNode(Context, MDs, false); + } /// \brief Return a temporary MDNode /// /// For use in constructing cyclic MDNode structures. A temporary MDNode is /// not uniqued, may be RAUW'd, and must be manually deleted with /// deleteTemporary. - static MDNode *getTemporary(LLVMContext &Context, ArrayRef Vals); + static MDNodeFwdDecl *getTemporary(LLVMContext &Context, + ArrayRef MDs); /// \brief Deallocate a node created by getTemporary. /// /// The node must not have any users. static void deleteTemporary(MDNode *N); - /// \brief Replace a specific operand. - void replaceOperandWith(unsigned i, Value *NewVal); + LLVMContext &getContext() const { return Context; } - /// \brief Return specified operand. - Value *getOperand(unsigned i) const LLVM_READONLY; + /// \brief Replace a specific operand. + void replaceOperandWith(unsigned I, Metadata *New); + + /// \brief Check if node is fully resolved. + bool isResolved() const; + +protected: + /// \brief Set an operand. + /// + /// Sets the operand directly, without worrying about uniquing. + void setOperand(unsigned I, Metadata *New); + +public: + typedef const MDOperand *op_iterator; + typedef iterator_range op_range; + + op_iterator op_begin() const { + return const_cast(this)->mutable_begin(); + } + op_iterator op_end() const { + return const_cast(this)->mutable_end(); + } + op_range operands() const { return op_range(op_begin(), op_end()); } + + const MDOperand &getOperand(unsigned I) const { + assert(I < NumOperands && "Out of range"); + return op_begin()[I]; + } /// \brief Return number of MDNode operands. unsigned getNumOperands() const { return NumOperands; } - /// \brief Return whether MDNode is local to a function. - bool isFunctionLocal() const { - return (getSubclassDataFromValue() & FunctionLocalBit) != 0; - } - - /// \brief Return the first function-local operand's function. - /// - /// If this metadata is function-local and recursively has a function-local - /// operand, return the first such operand's parent function. Otherwise, - /// return null. getFunction() should not be used for performance- critical - /// code because it recursively visits all the MDNode's operands. - const Function *getFunction() const; - /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: - static bool classof(const Value *V) { - return V->getValueID() == GenericMDNodeVal || - V->getValueID() == MDNodeFwdDeclVal; + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == GenericMDNodeKind || + MD->getMetadataID() == MDNodeFwdDeclKind; } /// \brief Check whether MDNode is a vtable access. @@ -254,18 +684,6 @@ public: static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B); static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B); static MDNode *getMostGenericRange(MDNode *A, MDNode *B); - -protected: - bool isNotUniqued() const { - return (getSubclassDataFromValue() & NotUniquedBit) != 0; - } - void setIsNotUniqued(); - - // Shadow Value::setValueSubclassData with a private forwarding method so that - // any future subclasses cannot accidentally use it. - void setValueSubclassData(unsigned short D) { - Value::setValueSubclassData(D); - } }; /// \brief Generic metadata node. @@ -279,24 +697,59 @@ protected: /// TODO: Make uniquing opt-out (status: mandatory, sometimes dropped). /// TODO: Drop support for RAUW. class GenericMDNode : public MDNode { + friend class Metadata; friend class MDNode; friend class LLVMContextImpl; + friend class ReplaceableMetadataImpl; - unsigned Hash; + /// \brief Support RAUW as long as one of its arguments is replaceable. + /// + /// If an operand is an \a MDNodeFwdDecl (or a replaceable \a GenericMDNode), + /// support RAUW to support uniquing as forward declarations are resolved. + /// As soon as operands have been resolved, drop support. + /// + /// FIXME: Save memory by storing this in a pointer union with the + /// LLVMContext, and adding an LLVMContext reference to RMI. + std::unique_ptr ReplaceableUses; - GenericMDNode(LLVMContext &C, ArrayRef Vals, bool isFunctionLocal) - : MDNode(C, GenericMDNodeVal, Vals, isFunctionLocal), Hash(0) {} + GenericMDNode(LLVMContext &C, ArrayRef Vals); ~GenericMDNode(); - void dropAllReferences(); + void setHash(unsigned Hash) { MDNodeSubclassData = Hash; } public: /// \brief Get the hash, if any. - unsigned getHash() const { return Hash; } + unsigned getHash() const { return MDNodeSubclassData; } - static bool classof(const Value *V) { - return V->getValueID() == GenericMDNodeVal; + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == GenericMDNodeKind; } + + /// \brief Check whether any operands are forward declarations. + /// + /// Returns \c true as long as any operands (or their operands, etc.) are \a + /// MDNodeFwdDecl. + /// + /// As forward declarations are resolved, their containers should get + /// resolved automatically. However, if this (or one of its operands) is + /// involved in a cycle, \a resolveCycles() needs to be called explicitly. + bool isResolved() const { return !ReplaceableUses; } + + /// \brief Resolve cycles. + /// + /// Once all forward declarations have been resolved, force cycles to be + /// resolved. + /// + /// \pre No operands (or operands' operands, etc.) are \a MDNodeFwdDecl. + void resolveCycles(); + +private: + void handleChangedOperand(void *Ref, Metadata *New); + + bool hasUnresolvedOperands() const { return SubclassData32; } + void incrementUnresolvedOperands() { ++SubclassData32; } + void decrementUnresolvedOperands() { --SubclassData32; } + void resolve(); }; /// \brief Forward declaration of metadata. @@ -304,17 +757,21 @@ public: /// Forward declaration of metadata, in the form of a metadata node. Unlike \a /// GenericMDNode, this class has support for RAUW and is suitable for forward /// references. -class MDNodeFwdDecl : public MDNode { +class MDNodeFwdDecl : public MDNode, ReplaceableMetadataImpl { + friend class Metadata; friend class MDNode; + friend class ReplaceableMetadataImpl; - MDNodeFwdDecl(LLVMContext &C, ArrayRef Vals, bool isFunctionLocal) - : MDNode(C, MDNodeFwdDeclVal, Vals, isFunctionLocal) {} + MDNodeFwdDecl(LLVMContext &C, ArrayRef Vals) + : MDNode(C, MDNodeFwdDeclKind, Vals) {} ~MDNodeFwdDecl() {} public: - static bool classof(const Value *V) { - return V->getValueID() == MDNodeFwdDeclVal; + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == MDNodeFwdDeclKind; } + + using ReplaceableMetadataImpl::replaceAllUsesWith; }; //===----------------------------------------------------------------------===// @@ -333,7 +790,7 @@ class NamedMDNode : public ilist_node { std::string Name; Module *Parent; - void *Operands; // SmallVector, 4> + void *Operands; // SmallVector void setParent(Module *M) { Parent = M; } diff --git a/llvm/include/llvm/IR/MetadataTracking.h b/llvm/include/llvm/IR/MetadataTracking.h new file mode 100644 index 000000000000..541d9b3b1245 --- /dev/null +++ b/llvm/include/llvm/IR/MetadataTracking.h @@ -0,0 +1,99 @@ +//===- llvm/IR/MetadataTracking.h - Metadata tracking ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Low-level functions to enable tracking of metadata that could RAUW. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_METADATATRACKING_H +#define LLVM_IR_METADATATRACKING_H + +#include "llvm/ADT/PointerUnion.h" +#include "llvm/Support/Casting.h" +#include + +namespace llvm { + +class Metadata; +class MetadataAsValue; + +/// \brief API for tracking metadata references through RAUW and deletion. +/// +/// Shared API for updating \a Metadata pointers in subclasses that support +/// RAUW. +/// +/// This API is not meant to be used directly. See \a TrackingMDRef for a +/// user-friendly tracking reference. +class MetadataTracking { +public: + /// \brief Track the reference to metadata. + /// + /// Register \c MD with \c *MD, if the subclass supports tracking. If \c *MD + /// gets RAUW'ed, \c MD will be updated to the new address. If \c *MD gets + /// deleted, \c MD will be set to \c nullptr. + /// + /// If tracking isn't supported, \c *MD will not change. + /// + /// \return true iff tracking is supported by \c MD. + static bool track(Metadata *&MD) { + return track(&MD, *MD, static_cast(nullptr)); + } + + /// \brief Track the reference to metadata for \a Metadata. + /// + /// As \a track(Metadata*&), but with support for calling back to \c Owner to + /// tell it that its operand changed. This could trigger \c Owner being + /// re-uniqued. + static bool track(void *Ref, Metadata &MD, Metadata &Owner) { + return track(Ref, MD, &Owner); + } + + /// \brief Track the reference to metadata for \a MetadataAsValue. + /// + /// As \a track(Metadata*&), but with support for calling back to \c Owner to + /// tell it that its operand changed. This could trigger \c Owner being + /// re-uniqued. + static bool track(void *Ref, Metadata &MD, MetadataAsValue &Owner) { + return track(Ref, MD, &Owner); + } + + /// \brief Stop tracking a reference to metadata. + /// + /// Stops \c *MD from tracking \c MD. + static void untrack(Metadata *&MD) { untrack(&MD, *MD); } + static void untrack(void *Ref, Metadata &MD); + + /// \brief Move tracking from one reference to another. + /// + /// Semantically equivalent to \c untrack(MD) followed by \c track(New), + /// except that ownership callbacks are maintained. + /// + /// Note: it is an error if \c *MD does not equal \c New. + /// + /// \return true iff tracking is supported by \c MD. + static bool retrack(Metadata *&MD, Metadata *&New) { + return retrack(&MD, *MD, &New); + } + static bool retrack(void *Ref, Metadata &MD, void *New); + + /// \brief Check whether metadata is replaceable. + static bool isReplaceable(const Metadata &MD); + + typedef PointerUnion OwnerTy; + +private: + /// \brief Track a reference to metadata for an owner. + /// + /// Generalized version of tracking. + static bool track(void *Ref, Metadata &MD, OwnerTy Owner); +}; + +} // end namespace llvm + +#endif diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index f4a6258c7624..475b2c2de846 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -188,16 +188,16 @@ public: ModFlagBehaviorLastVal = AppendUnique }; - /// Checks if Value represents a valid ModFlagBehavior, and stores the + /// Checks if Metadata represents a valid ModFlagBehavior, and stores the /// converted result in MFB. - static bool isValidModFlagBehavior(Value *V, ModFlagBehavior &MFB); + static bool isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB); struct ModuleFlagEntry { ModFlagBehavior Behavior; MDString *Key; - Value *Val; - ModuleFlagEntry(ModFlagBehavior B, MDString *K, Value *V) - : Behavior(B), Key(K), Val(V) {} + Metadata *Val; + ModuleFlagEntry(ModFlagBehavior B, MDString *K, Metadata *V) + : Behavior(B), Key(K), Val(V) {} }; /// @} @@ -442,7 +442,7 @@ public: /// Return the corresponding value if Key appears in module flags, otherwise /// return null. - Value *getModuleFlag(StringRef Key) const; + Metadata *getModuleFlag(StringRef Key) const; /// Returns the NamedMDNode in the module that represents module-level flags. /// This method returns null if there are no module-level flags. @@ -455,7 +455,8 @@ public: /// Add a module-level flag to the module-level flags metadata. It will create /// the module-level flags named metadata if it doesn't already exist. - void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Value *Val); + void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Metadata *Val); + void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Constant *Val); void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, uint32_t Val); void addModuleFlag(MDNode *Node); diff --git a/llvm/include/llvm/IR/TrackingMDRef.h b/llvm/include/llvm/IR/TrackingMDRef.h new file mode 100644 index 000000000000..972ccaa5fe72 --- /dev/null +++ b/llvm/include/llvm/IR/TrackingMDRef.h @@ -0,0 +1,166 @@ +//===- llvm/IR/TrackingMDRef.h - Tracking Metadata references -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// References to metadata that track RAUW. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_TRACKINGMDREF_H +#define LLVM_IR_TRACKINGMDREF_H + +#include "llvm/IR/MetadataTracking.h" +#include "llvm/Support/Casting.h" + +namespace llvm { + +class Metadata; +class MDNode; +class ValueAsMetadata; + +/// \brief Tracking metadata reference. +/// +/// This class behaves like \a TrackingVH, but for metadata. +class TrackingMDRef { + Metadata *MD; + +public: + TrackingMDRef() : MD(nullptr) {} + explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); } + + TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); } + TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); } + TrackingMDRef &operator=(TrackingMDRef &&X) { + if (&X == this) + return *this; + + untrack(); + MD = X.MD; + retrack(X); + return *this; + } + TrackingMDRef &operator=(const TrackingMDRef &X) { + if (&X == this) + return *this; + + untrack(); + MD = X.MD; + track(); + return *this; + } + ~TrackingMDRef() { untrack(); } + + LLVM_EXPLICIT operator bool() const { return get(); } + Metadata *get() const { return MD; } + operator Metadata *() const { return get(); } + Metadata *operator->() const { return get(); } + Metadata &operator*() const { return *get(); } + + void reset() { + untrack(); + MD = nullptr; + } + void reset(Metadata *MD) { + untrack(); + this->MD = MD; + track(); + } + + /// \brief Check whether this has a trivial destructor. + /// + /// If \c MD isn't replaceable, the destructor will be a no-op. + bool hasTrivialDestructor() const { + return !MD || !MetadataTracking::isReplaceable(*MD); + } + +private: + void track() { + if (MD) + MetadataTracking::track(MD); + } + void untrack() { + if (MD) + MetadataTracking::untrack(MD); + } + void retrack(TrackingMDRef &X) { + assert(MD == X.MD && "Expected values to match"); + if (X.MD) { + MetadataTracking::retrack(X.MD, MD); + X.MD = nullptr; + } + } +}; + +/// \brief Typed tracking ref. +/// +/// Track refererences of a particular type. It's useful to use this for \a +/// MDNode and \a ValueAsMetadata. +template class TypedTrackingMDRef { + TrackingMDRef Ref; + +public: + TypedTrackingMDRef() {} + explicit TypedTrackingMDRef(T *MD) : Ref(static_cast(MD)) {} + + TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {} + TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {} + TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) { + Ref = std::move(X.Ref); + return *this; + } + TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) { + Ref = X.Ref; + return *this; + } + + LLVM_EXPLICIT operator bool() const { return get(); } + T *get() const { return (T *)Ref.get(); } + operator T *() const { return get(); } + T *operator->() const { return get(); } + T &operator*() const { return *get(); } + + void reset() { Ref.reset(); } + void reset(T *MD) { Ref.reset(static_cast(MD)); } + + /// \brief Check whether this has a trivial destructor. + bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); } +}; + +typedef TypedTrackingMDRef TrackingMDNodeRef; +typedef TypedTrackingMDRef TrackingValueAsMetadataRef; + +// Expose the underlying metadata to casting. +template <> struct simplify_type { + typedef Metadata *SimpleType; + static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); } +}; + +template <> struct simplify_type { + typedef Metadata *SimpleType; + static SimpleType getSimplifiedValue(const TrackingMDRef &MD) { + return MD.get(); + } +}; + +template struct simplify_type> { + typedef T *SimpleType; + static SimpleType getSimplifiedValue(TypedTrackingMDRef &MD) { + return MD.get(); + } +}; + +template struct simplify_type> { + typedef T *SimpleType; + static SimpleType getSimplifiedValue(const TypedTrackingMDRef &MD) { + return MD.get(); + } +}; + +} // end namespace llvm + +#endif diff --git a/llvm/include/llvm/IR/TypeFinder.h b/llvm/include/llvm/IR/TypeFinder.h index cea66a4ab069..73a63ad0349e 100644 --- a/llvm/include/llvm/IR/TypeFinder.h +++ b/llvm/include/llvm/IR/TypeFinder.h @@ -31,6 +31,7 @@ class TypeFinder { // To avoid walking constant expressions multiple times and other IR // objects, we keep several helper maps. DenseSet VisitedConstants; + DenseSet VisitedMetadata; DenseSet VisitedTypes; std::vector StructTypes; diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h index 7541ffbe6e21..92070210f2c4 100644 --- a/llvm/include/llvm/IR/Value.h +++ b/llvm/include/llvm/IR/Value.h @@ -37,7 +37,6 @@ class GlobalVariable; class InlineAsm; class Instruction; class LLVMContext; -class MDNode; class Module; class StringRef; class Twine; @@ -70,9 +69,9 @@ class Value { Type *VTy; Use *UseList; - friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name. + friend class ValueAsMetadata; // Allow access to NameAndIsUsedByMD. friend class ValueHandleBase; - ValueName *Name; + PointerIntPair NameAndIsUsedByMD; const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast) unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this? @@ -226,10 +225,14 @@ public: LLVMContext &getContext() const; // \brief All values can potentially be named. - bool hasName() const { return Name != nullptr; } - ValueName *getValueName() const { return Name; } - void setValueName(ValueName *VN) { Name = VN; } + bool hasName() const { return getValueName() != nullptr; } + ValueName *getValueName() const { return NameAndIsUsedByMD.getPointer(); } + void setValueName(ValueName *VN) { NameAndIsUsedByMD.setPointer(VN); } +private: + void destroyValueName(); + +public: /// \brief Return a constant reference to the value's name. /// /// This is cheap and guaranteed to return the same reference as long as the @@ -352,9 +355,7 @@ public: ConstantStructVal, // This is an instance of ConstantStruct ConstantVectorVal, // This is an instance of ConstantVector ConstantPointerNullVal, // This is an instance of ConstantPointerNull - GenericMDNodeVal, // This is an instance of GenericMDNode - MDNodeFwdDeclVal, // This is an instance of MDNodeFwdDecl - MDStringVal, // This is an instance of MDString + MetadataAsValueVal, // This is an instance of MetadataAsValue InlineAsmVal, // This is an instance of InlineAsm InstructionVal, // This is an instance of Instruction // Enum values starting at InstructionVal are used for Instructions; @@ -404,6 +405,9 @@ public: /// \brief Return true if there is a value handle associated with this value. bool hasValueHandle() const { return HasValueHandle; } + /// \brief Return true if there is metadata referencing this value. + bool isUsedByMetadata() const { return NameAndIsUsedByMD.getInt(); } + /// \brief Strip off pointer casts, all-zero GEPs, and aliases. /// /// Returns the original uncasted value. If this is called on a non-pointer @@ -687,13 +691,6 @@ template <> struct isa_impl { } }; -template <> struct isa_impl { - static inline bool doit(const Value &Val) { - return Val.getValueID() == Value::GenericMDNodeVal || - Val.getValueID() == Value::MDNodeFwdDeclVal; - } -}; - // Value* is only 4-byte aligned. template<> class PointerLikeTypeTraits { diff --git a/llvm/include/llvm/IR/ValueMap.h b/llvm/include/llvm/IR/ValueMap.h index aa8a29dc771d..91d09f1cda4b 100644 --- a/llvm/include/llvm/IR/ValueMap.h +++ b/llvm/include/llvm/IR/ValueMap.h @@ -27,6 +27,7 @@ #define LLVM_IR_VALUEMAP_H #include "llvm/ADT/DenseMap.h" +#include "llvm/IR/TrackingMDRef.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/UniqueLock.h" @@ -79,8 +80,10 @@ class ValueMap { friend class ValueMapCallbackVH; typedef ValueMapCallbackVH ValueMapCVH; typedef DenseMap > MapT; + typedef DenseMap MDMapT; typedef typename Config::ExtraData ExtraData; MapT Map; + std::unique_ptr MDMap; ExtraData Data; ValueMap(const ValueMap&) LLVM_DELETED_FUNCTION; ValueMap& operator=(const ValueMap&) LLVM_DELETED_FUNCTION; @@ -91,12 +94,19 @@ public: typedef unsigned size_type; explicit ValueMap(unsigned NumInitBuckets = 64) - : Map(NumInitBuckets), Data() {} + : Map(NumInitBuckets), Data() {} explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64) - : Map(NumInitBuckets), Data(Data) {} + : Map(NumInitBuckets), Data(Data) {} ~ValueMap() {} + bool hasMD() const { return MDMap; } + MDMapT &MD() { + if (!MDMap) + MDMap.reset(new MDMapT); + return *MDMap; + } + typedef ValueMapIterator iterator; typedef ValueMapConstIterator const_iterator; inline iterator begin() { return iterator(Map.begin()); } @@ -110,7 +120,10 @@ public: /// Grow the map so that it has at least Size buckets. Does not shrink void resize(size_t Size) { Map.resize(Size); } - void clear() { Map.clear(); } + void clear() { + Map.clear(); + MDMap.reset(); + } /// Return 1 if the specified key is in the map, 0 otherwise. size_type count(const KeyT &Val) const { diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h index 5774763575d3..cc57c8d7d45b 100644 --- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h +++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h @@ -71,20 +71,23 @@ namespace llvm { ValueMapTypeRemapper *TypeMapper = nullptr, ValueMaterializer *Materializer = nullptr); + Metadata *MapValue(const Metadata *MD, ValueToValueMapTy &VM, + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = nullptr, + ValueMaterializer *Materializer = nullptr); + + /// MapValue - provide versions that preserve type safety for MDNodes. + MDNode *MapValue(const MDNode *MD, ValueToValueMapTy &VM, + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = nullptr, + ValueMaterializer *Materializer = nullptr); + void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags = RF_None, ValueMapTypeRemapper *TypeMapper = nullptr, ValueMaterializer *Materializer = nullptr); - /// MapValue - provide versions that preserve type safety for MDNode and - /// Constants. - inline MDNode *MapValue(const MDNode *V, ValueToValueMapTy &VM, - RemapFlags Flags = RF_None, - ValueMapTypeRemapper *TypeMapper = nullptr, - ValueMaterializer *Materializer = nullptr) { - return cast(MapValue((const Value*)V, VM, Flags, TypeMapper, - Materializer)); - } + /// MapValue - provide versions that preserve type safety for Constants. inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM, RemapFlags Flags = RF_None, ValueMapTypeRemapper *TypeMapper = nullptr, diff --git a/llvm/lib/Analysis/BranchProbabilityInfo.cpp b/llvm/lib/Analysis/BranchProbabilityInfo.cpp index bbd875059522..2b39d47e5faf 100644 --- a/llvm/lib/Analysis/BranchProbabilityInfo.cpp +++ b/llvm/lib/Analysis/BranchProbabilityInfo.cpp @@ -196,7 +196,8 @@ bool BranchProbabilityInfo::calcMetadataWeights(BasicBlock *BB) { SmallVector Weights; Weights.reserve(TI->getNumSuccessors()); for (unsigned i = 1, e = WeightsNode->getNumOperands(); i != e; ++i) { - ConstantInt *Weight = dyn_cast(WeightsNode->getOperand(i)); + ConstantInt *Weight = + mdconst::dyn_extract(WeightsNode->getOperand(i)); if (!Weight) return false; Weights.push_back( diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 792542eab255..177bd23030a7 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -3750,8 +3750,10 @@ static Optional GetRangeFromMetadata(Value *V) { assert(NumRanges >= 1); for (unsigned i = 0; i < NumRanges; ++i) { - ConstantInt *Lower = cast(MD->getOperand(2*i + 0)); - ConstantInt *Upper = cast(MD->getOperand(2*i + 1)); + ConstantInt *Lower = + mdconst::extract(MD->getOperand(2 * i + 0)); + ConstantInt *Upper = + mdconst::extract(MD->getOperand(2 * i + 1)); ConstantRange Range(Lower->getValue(), Upper->getValue()); TotalRange = TotalRange.unionWith(Range); } diff --git a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp index f347eb5f1915..085ce920139b 100644 --- a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -167,7 +167,7 @@ namespace { bool TypeIsImmutable() const { if (Node->getNumOperands() < 3) return false; - ConstantInt *CI = dyn_cast(Node->getOperand(2)); + ConstantInt *CI = mdconst::dyn_extract(Node->getOperand(2)); if (!CI) return false; return CI->getValue()[0]; @@ -194,7 +194,7 @@ namespace { return dyn_cast_or_null(Node->getOperand(1)); } uint64_t getOffset() const { - return cast(Node->getOperand(2))->getZExtValue(); + return mdconst::extract(Node->getOperand(2))->getZExtValue(); } /// TypeIsImmutable - Test if this TBAAStructTagNode represents a type for /// objects which are not modified (by any means) in the context where this @@ -202,7 +202,7 @@ namespace { bool TypeIsImmutable() const { if (Node->getNumOperands() < 4) return false; - ConstantInt *CI = dyn_cast(Node->getOperand(3)); + ConstantInt *CI = mdconst::dyn_extract(Node->getOperand(3)); if (!CI) return false; return CI->getValue()[0]; @@ -233,8 +233,10 @@ namespace { // Fast path for a scalar type node and a struct type node with a single // field. if (Node->getNumOperands() <= 3) { - uint64_t Cur = Node->getNumOperands() == 2 ? 0 : - cast(Node->getOperand(2))->getZExtValue(); + uint64_t Cur = Node->getNumOperands() == 2 + ? 0 + : mdconst::extract(Node->getOperand(2)) + ->getZExtValue(); Offset -= Cur; MDNode *P = dyn_cast_or_null(Node->getOperand(1)); if (!P) @@ -246,8 +248,8 @@ namespace { // the current offset is bigger than the given offset. unsigned TheIdx = 0; for (unsigned Idx = 1; Idx < Node->getNumOperands(); Idx += 2) { - uint64_t Cur = cast(Node->getOperand(Idx + 1))-> - getZExtValue(); + uint64_t Cur = mdconst::extract(Node->getOperand(Idx + 1)) + ->getZExtValue(); if (Cur > Offset) { assert(Idx >= 3 && "TBAAStructTypeNode::getParent should have an offset match!"); @@ -258,8 +260,8 @@ namespace { // Move along the last field. if (TheIdx == 0) TheIdx = Node->getNumOperands() - 2; - uint64_t Cur = cast(Node->getOperand(TheIdx + 1))-> - getZExtValue(); + uint64_t Cur = mdconst::extract(Node->getOperand(TheIdx + 1)) + ->getZExtValue(); Offset -= Cur; MDNode *P = dyn_cast_or_null(Node->getOperand(TheIdx)); if (!P) @@ -608,7 +610,8 @@ MDNode *MDNode::getMostGenericTBAA(MDNode *A, MDNode *B) { return nullptr; // We need to convert from a type node to a tag node. Type *Int64 = IntegerType::get(A->getContext(), 64); - Value *Ops[3] = { Ret, Ret, ConstantInt::get(Int64, 0) }; + Metadata *Ops[3] = {Ret, Ret, + ConstantAsMetadata::get(ConstantInt::get(Int64, 0))}; return MDNode::get(A->getContext(), Ops); } diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index ced5151582fb..fa428fa108d2 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -312,8 +312,10 @@ void llvm::computeKnownBitsFromRangeMetadata(const MDNode &Ranges, // Use the high end of the ranges to find leading zeros. unsigned MinLeadingZeros = BitWidth; for (unsigned i = 0; i < NumRanges; ++i) { - ConstantInt *Lower = cast(Ranges.getOperand(2*i + 0)); - ConstantInt *Upper = cast(Ranges.getOperand(2*i + 1)); + ConstantInt *Lower = + mdconst::extract(Ranges.getOperand(2 * i + 0)); + ConstantInt *Upper = + mdconst::extract(Ranges.getOperand(2 * i + 1)); ConstantRange Range(Lower->getValue(), Upper->getValue()); if (Range.isWrappedSet()) MinLeadingZeros = 0; // -1 has no zeros @@ -1504,8 +1506,10 @@ static bool rangeMetadataExcludesValue(MDNode* Ranges, const unsigned NumRanges = Ranges->getNumOperands() / 2; assert(NumRanges >= 1); for (unsigned i = 0; i < NumRanges; ++i) { - ConstantInt *Lower = cast(Ranges->getOperand(2*i + 0)); - ConstantInt *Upper = cast(Ranges->getOperand(2*i + 1)); + ConstantInt *Lower = + mdconst::extract(Ranges->getOperand(2 * i + 0)); + ConstantInt *Upper = + mdconst::extract(Ranges->getOperand(2 * i + 1)); ConstantRange Range(Lower->getValue(), Upper->getValue()); if (Range.contains(Value)) return false; diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index a682f97ceb23..ca4ba6e07f35 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -62,8 +62,6 @@ bool LLParser::ValidateEndOfModule() { NumberedMetadata[SlotNo] == nullptr) return Error(MDList[i].Loc, "use of undefined metadata '!" + Twine(SlotNo) + "'"); - assert(!NumberedMetadata[SlotNo]->isFunctionLocal() && - "Unexpected function-local metadata"); Inst->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]); } } @@ -169,6 +167,10 @@ bool LLParser::ValidateEndOfModule() { "use of undefined metadata '!" + Twine(ForwardRefMDNodes.begin()->first) + "'"); + // Resolve metadata cycles. + for (auto &N : NumberedMetadata) + if (auto *G = cast_or_null(N)) + G->resolveCycles(); // Look for intrinsic functions and CallInst that need to be upgraded for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) @@ -561,12 +563,12 @@ bool LLParser::ParseMDNodeID(MDNode *&Result) { if (Result) return false; // Otherwise, create MDNode forward reference. - MDNode *FwdNode = MDNode::getTemporary(Context, None); + MDNodeFwdDecl *FwdNode = MDNode::getTemporary(Context, None); ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc()); if (NumberedMetadata.size() <= MID) NumberedMetadata.resize(MID+1); - NumberedMetadata[MID] = FwdNode; + NumberedMetadata[MID].reset(FwdNode); Result = FwdNode; return false; } @@ -609,23 +611,18 @@ bool LLParser::ParseStandaloneMetadata() { LocTy TyLoc; Type *Ty = nullptr; - SmallVector Elts; + MDNode *Init; if (ParseUInt32(MetadataID) || ParseToken(lltok::equal, "expected '=' here") || ParseType(Ty, TyLoc) || ParseToken(lltok::exclaim, "Expected '!' here") || - ParseToken(lltok::lbrace, "Expected '{' here") || - ParseMDNodeVector(Elts, nullptr) || - ParseToken(lltok::rbrace, "expected end of metadata node")) + ParseMDNode(Init)) return true; - MDNode *Init = MDNode::get(Context, Elts); - // See if this was forward referenced, if so, handle it. - std::map, LocTy> >::iterator - FI = ForwardRefMDNodes.find(MetadataID); + auto FI = ForwardRefMDNodes.find(MetadataID); if (FI != ForwardRefMDNodes.end()) { - MDNode *Temp = FI->second.first; + auto *Temp = FI->second.first; Temp->replaceAllUsesWith(Init); MDNode::deleteTemporary(Temp); ForwardRefMDNodes.erase(FI); @@ -637,7 +634,7 @@ bool LLParser::ParseStandaloneMetadata() { if (NumberedMetadata[MetadataID] != nullptr) return TokError("Metadata id is already used"); - NumberedMetadata[MetadataID] = Init; + NumberedMetadata[MetadataID].reset(Init); } return false; @@ -1527,18 +1524,15 @@ bool LLParser::ParseInstructionMetadata(Instruction *Inst, if (ParseToken(lltok::exclaim, "expected '!' here")) return true; - // This code is similar to that of ParseMetadataValue, however it needs to + // This code is similar to that of ParseMetadata, however it needs to // have special-case code for a forward reference; see the comments on // ForwardRefInstMetadata for details. Also, MDStrings are not supported // at the top level here. if (Lex.getKind() == lltok::lbrace) { - ValID ID; - if (ParseMetadataListValue(ID, PFS)) + MDNode *N; + if (ParseMDNode(N)) return true; - assert(ID.Kind == ValID::t_MDNode); - if (ID.MDNodeVal->isFunctionLocal()) - return Error(Loc, "unexpected function-local metadata"); - Inst->setMetadata(MDK, ID.MDNodeVal); + Inst->setMetadata(MDK, N); } else { unsigned NodeID = 0; if (ParseMDNodeID(Node, NodeID)) @@ -2395,7 +2389,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ID.Kind = ValID::t_LocalName; break; case lltok::exclaim: // !42, !{...}, or !"foo" - return ParseMetadataValue(ID, PFS); + return ParseMetadataAsValue(ID, PFS); case lltok::APSInt: ID.APSIntVal = Lex.getAPSIntVal(); ID.Kind = ValID::t_APSInt; @@ -2935,45 +2929,69 @@ bool LLParser::ParseGlobalValueVector(SmallVectorImpl &Elts) { return false; } -bool LLParser::ParseMetadataListValue(ValID &ID, PerFunctionState *PFS) { - assert(Lex.getKind() == lltok::lbrace); - Lex.Lex(); - - SmallVector Elts; - if (ParseMDNodeVector(Elts, PFS) || - ParseToken(lltok::rbrace, "expected end of metadata node")) +bool LLParser::ParseMDNode(MDNode *&MD) { + SmallVector Elts; + if (ParseMDNodeVector(Elts, nullptr)) return true; - ID.MDNodeVal = MDNode::get(Context, Elts); - ID.Kind = ValID::t_MDNode; + MD = MDNode::get(Context, Elts); return false; } -/// ParseMetadataValue +bool LLParser::ParseMDNodeOrLocal(Metadata *&MD, PerFunctionState *PFS) { + SmallVector Elts; + if (ParseMDNodeVector(Elts, PFS)) + return true; + + // Check for function-local metadata masquerading as an MDNode. + if (PFS && Elts.size() == 1 && Elts[0] && isa(Elts[0])) { + MD = Elts[0]; + return false; + } + + MD = MDNode::get(Context, Elts); + return false; +} + +bool LLParser::ParseMetadataAsValue(ValID &ID, PerFunctionState *PFS) { + Metadata *MD; + if (ParseMetadata(MD, PFS)) + return true; + + ID.Kind = ValID::t_Metadata; + ID.MetadataVal = MetadataAsValue::get(Context, MD); + return false; +} + +/// ParseMetadata /// ::= !42 /// ::= !{...} /// ::= !"string" -bool LLParser::ParseMetadataValue(ValID &ID, PerFunctionState *PFS) { +bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) { assert(Lex.getKind() == lltok::exclaim); Lex.Lex(); // MDNode: // !{ ... } if (Lex.getKind() == lltok::lbrace) - return ParseMetadataListValue(ID, PFS); + return ParseMDNodeOrLocal(MD, PFS); // Standalone metadata reference // !42 if (Lex.getKind() == lltok::APSInt) { - if (ParseMDNodeID(ID.MDNodeVal)) return true; - ID.Kind = ValID::t_MDNode; + MDNode *N; + if (ParseMDNodeID(N)) + return true; + MD = N; return false; } // MDString: // ::= '!' STRINGCONSTANT - if (ParseMDString(ID.MDStringVal)) return true; - ID.Kind = ValID::t_MDString; + MDString *S; + if (ParseMDString(S)) + return true; + MD = S; return false; } @@ -3006,15 +3024,10 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, (ID.UIntVal>>1)&1, (InlineAsm::AsmDialect(ID.UIntVal>>2))); return false; } - case ValID::t_MDNode: + case ValID::t_Metadata: if (!Ty->isMetadataTy()) return Error(ID.Loc, "metadata value must have metadata type"); - V = ID.MDNodeVal; - return false; - case ValID::t_MDString: - if (!Ty->isMetadataTy()) - return Error(ID.Loc, "metadata value must have metadata type"); - V = ID.MDStringVal; + V = ID.MetadataVal; return false; case ValID::t_GlobalName: V = GetGlobalVal(ID.StrVal, Ty, ID.Loc); @@ -4668,13 +4681,16 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { //===----------------------------------------------------------------------===// /// ParseMDNodeVector -/// ::= Element (',' Element)* +/// ::= { Element (',' Element)* } /// Element /// ::= 'null' | TypeAndValue -bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts, +bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts, PerFunctionState *PFS) { + assert(Lex.getKind() == lltok::lbrace); + Lex.Lex(); + // Check for an empty list. - if (Lex.getKind() == lltok::rbrace) + if (EatIfPresent(lltok::rbrace)) return false; bool IsLocal = false; @@ -4688,13 +4704,26 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts, continue; } - Value *V = nullptr; - if (ParseTypeAndValue(V, PFS)) return true; - Elts.push_back(V); + Type *Ty = nullptr; + if (ParseType(Ty)) + return true; - if (isa(V) && cast(V)->isFunctionLocal()) - return TokError("unexpected nested function-local metadata"); - if (!V->getType()->isMetadataTy() && !isa(V)) { + if (Ty->isMetadataTy()) { + // No function-local metadata here. + Metadata *MD = nullptr; + if (ParseMetadata(MD, nullptr)) + return true; + Elts.push_back(MD); + continue; + } + + Value *V = nullptr; + if (ParseValue(Ty, V, PFS)) + return true; + assert(V && "Expected valid value"); + Elts.push_back(ValueAsMetadata::get(V)); + + if (isa(Elts.back())) { assert(PFS && "Unexpected function-local metadata without PFS"); if (Elts.size() > 1) return TokError("unexpected function-local metadata"); @@ -4702,7 +4731,7 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl &Elts, } } while (EatIfPresent(lltok::comma)); - return false; + return ParseToken(lltok::rbrace, "expected end of metadata node"); } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index aa62bcc8daf0..d32e58e83f87 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -52,8 +52,7 @@ namespace llvm { t_EmptyArray, // No value: [] t_Constant, // Value in ConstantVal. t_InlineAsm, // Value in StrVal/StrVal2/UIntVal. - t_MDNode, // Value in MDNodeVal. - t_MDString, // Value in MDStringVal. + t_Metadata, // Value in MetadataVal. t_ConstantStruct, // Value in ConstantStructElts. t_PackedConstantStruct // Value in ConstantStructElts. } Kind; @@ -64,8 +63,7 @@ namespace llvm { APSInt APSIntVal; APFloat APFloatVal; Constant *ConstantVal; - MDNode *MDNodeVal; - MDString *MDStringVal; + MetadataAsValue *MetadataVal; Constant **ConstantStructElts; ValID() : Kind(t_LocalID), APFloatVal(0.0) {} @@ -115,8 +113,8 @@ namespace llvm { StringMap > NamedTypes; std::vector > NumberedTypes; - std::vector > NumberedMetadata; - std::map, LocTy> > ForwardRefMDNodes; + std::vector NumberedMetadata; + std::map> ForwardRefMDNodes; // Global Value reference information. std::map > ForwardRefVals; @@ -382,9 +380,12 @@ namespace llvm { bool ParseGlobalTypeAndValue(Constant *&V); bool ParseGlobalValueVector(SmallVectorImpl &Elts); bool parseOptionalComdat(Comdat *&C); - bool ParseMetadataListValue(ValID &ID, PerFunctionState *PFS); - bool ParseMetadataValue(ValID &ID, PerFunctionState *PFS); - bool ParseMDNodeVector(SmallVectorImpl &, PerFunctionState *PFS); + bool ParseMetadataAsValue(ValID &ID, PerFunctionState *PFS); + bool ParseMetadata(Metadata *&MD, PerFunctionState *PFS); + bool ParseMDNode(MDNode *&MD); + bool ParseMDNodeOrLocal(Metadata *&MD, PerFunctionState *PFS); + bool ParseMDNodeVector(SmallVectorImpl &, + PerFunctionState *PFS); bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS); // Function Parsing. diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 72f823c2e3e8..cc6180693610 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -438,43 +438,58 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() { } } -void BitcodeReaderMDValueList::AssignValue(Value *V, unsigned Idx) { +void BitcodeReaderMDValueList::AssignValue(Metadata *MD, unsigned Idx) { if (Idx == size()) { - push_back(V); + push_back(MD); return; } if (Idx >= size()) resize(Idx+1); - WeakVH &OldV = MDValuePtrs[Idx]; - if (!OldV) { - OldV = V; + TrackingMDRef &OldMD = MDValuePtrs[Idx]; + if (!OldMD) { + OldMD.reset(MD); return; } // If there was a forward reference to this value, replace it. - MDNode *PrevVal = cast(OldV); - OldV->replaceAllUsesWith(V); - MDNode::deleteTemporary(PrevVal); - // Deleting PrevVal sets Idx value in MDValuePtrs to null. Set new - // value for Idx. - MDValuePtrs[Idx] = V; + MDNodeFwdDecl *PrevMD = cast(OldMD.get()); + PrevMD->replaceAllUsesWith(MD); + MDNode::deleteTemporary(PrevMD); + --NumFwdRefs; } -Value *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) { +Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) { if (Idx >= size()) resize(Idx + 1); - if (Value *V = MDValuePtrs[Idx]) { - assert(V->getType()->isMetadataTy() && "Type mismatch in value table!"); - return V; - } + if (Metadata *MD = MDValuePtrs[Idx]) + return MD; // Create and return a placeholder, which will later be RAUW'd. - Value *V = MDNode::getTemporary(Context, None); - MDValuePtrs[Idx] = V; - return V; + AnyFwdRefs = true; + ++NumFwdRefs; + Metadata *MD = MDNode::getTemporary(Context, None); + MDValuePtrs[Idx].reset(MD); + return MD; +} + +void BitcodeReaderMDValueList::tryToResolveCycles() { + if (!AnyFwdRefs) + // Nothing to do. + return; + + if (NumFwdRefs) + // Still forward references... can't resolve cycles. + return; + + // Resolve any cycles. + for (auto &MD : MDValuePtrs) { + assert(!(MD && isa(MD)) && "Unexpected forward reference"); + if (auto *G = dyn_cast_or_null(MD)) + G->resolveCycles(); + } } Type *BitcodeReader::getTypeByID(unsigned ID) { @@ -1066,6 +1081,7 @@ std::error_code BitcodeReader::ParseMetadata() { case BitstreamEntry::Error: return Error(BitcodeError::MalformedBlock); case BitstreamEntry::EndBlock: + MDValueList.tryToResolveCycles(); return std::error_code(); case BitstreamEntry::Record: // The interesting case. @@ -1100,13 +1116,13 @@ std::error_code BitcodeReader::ParseMetadata() { break; } case bitc::METADATA_FN_NODE: { - // This is a function-local node. + // This is a LocalAsMetadata record, the only type of function-local + // metadata. if (Record.size() % 2 == 1) return Error(BitcodeError::InvalidRecord); - // If this isn't a single-operand node that directly references - // non-metadata, we're dropping it. This used to be legal, but there's - // no upgrade path. + // If this isn't a LocalAsMetadata record, we're dropping it. This used + // to be legal, but there's no upgrade path. auto dropRecord = [&] { MDValueList.AssignValue(MDNode::get(Context, None), NextMDValueNo++); }; @@ -1121,10 +1137,9 @@ std::error_code BitcodeReader::ParseMetadata() { break; } - Value *Elts[] = {ValueList.getValueFwdRef(Record[1], Ty)}; - Value *V = MDNode::getWhenValsUnresolved(Context, Elts, - /*IsFunctionLocal*/ true); - MDValueList.AssignValue(V, NextMDValueNo++); + MDValueList.AssignValue( + LocalAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)), + NextMDValueNo++); break; } case bitc::METADATA_NODE: { @@ -1132,28 +1147,30 @@ std::error_code BitcodeReader::ParseMetadata() { return Error(BitcodeError::InvalidRecord); unsigned Size = Record.size(); - SmallVector Elts; + SmallVector Elts; for (unsigned i = 0; i != Size; i += 2) { Type *Ty = getTypeByID(Record[i]); if (!Ty) return Error(BitcodeError::InvalidRecord); if (Ty->isMetadataTy()) Elts.push_back(MDValueList.getValueFwdRef(Record[i+1])); - else if (!Ty->isVoidTy()) - Elts.push_back(ValueList.getValueFwdRef(Record[i+1], Ty)); - else + else if (!Ty->isVoidTy()) { + auto *MD = + ValueAsMetadata::get(ValueList.getValueFwdRef(Record[i + 1], Ty)); + assert(isa(MD) && + "Expected non-function-local metadata"); + Elts.push_back(MD); + } else Elts.push_back(nullptr); } - Value *V = MDNode::getWhenValsUnresolved(Context, Elts, - /*IsFunctionLocal*/ false); - MDValueList.AssignValue(V, NextMDValueNo++); + MDValueList.AssignValue(MDNode::get(Context, Elts), NextMDValueNo++); break; } case bitc::METADATA_STRING: { std::string String(Record.begin(), Record.end()); llvm::UpgradeMDStringConstant(String); - Value *V = MDString::get(Context, String); - MDValueList.AssignValue(V, NextMDValueNo++); + Metadata *MD = MDString::get(Context, String); + MDValueList.AssignValue(MD, NextMDValueNo++); break; } case bitc::METADATA_KIND: { @@ -2359,12 +2376,12 @@ std::error_code BitcodeReader::ParseMetadataAttachment() { MDKindMap.find(Kind); if (I == MDKindMap.end()) return Error(BitcodeError::InvalidID); - MDNode *Node = cast(MDValueList.getValueFwdRef(Record[i+1])); - if (Node->isFunctionLocal()) + Metadata *Node = MDValueList.getValueFwdRef(Record[i + 1]); + if (isa(Node)) // Drop the attachment. This used to be legal, but there's no // upgrade path. break; - Inst->setMetadata(I->second, Node); + Inst->setMetadata(I->second, cast(Node)); if (I->second == LLVMContext::MD_tbaa) InstsWithTBAATag.push_back(Inst); } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.h b/llvm/lib/Bitcode/Reader/BitcodeReader.h index 10f870b59b80..639ddb903504 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.h +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.h @@ -19,7 +19,9 @@ #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/GVMaterializer.h" +#include "llvm/IR/Metadata.h" #include "llvm/IR/OperandTraits.h" +#include "llvm/IR/TrackingMDRef.h" #include "llvm/IR/Type.h" #include "llvm/IR/ValueHandle.h" #include @@ -95,22 +97,25 @@ public: //===----------------------------------------------------------------------===// class BitcodeReaderMDValueList { - std::vector MDValuePtrs; + unsigned NumFwdRefs; + bool AnyFwdRefs; + std::vector MDValuePtrs; LLVMContext &Context; public: - BitcodeReaderMDValueList(LLVMContext& C) : Context(C) {} + BitcodeReaderMDValueList(LLVMContext &C) + : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {} // vector compatibility methods unsigned size() const { return MDValuePtrs.size(); } void resize(unsigned N) { MDValuePtrs.resize(N); } - void push_back(Value *V) { MDValuePtrs.push_back(V); } + void push_back(Metadata *MD) { MDValuePtrs.emplace_back(MD); } void clear() { MDValuePtrs.clear(); } - Value *back() const { return MDValuePtrs.back(); } + Metadata *back() const { return MDValuePtrs.back(); } void pop_back() { MDValuePtrs.pop_back(); } bool empty() const { return MDValuePtrs.empty(); } - Value *operator[](unsigned i) const { + Metadata *operator[](unsigned i) const { assert(i < MDValuePtrs.size()); return MDValuePtrs[i]; } @@ -120,8 +125,9 @@ public: MDValuePtrs.resize(N); } - Value *getValueFwdRef(unsigned Idx); - void AssignValue(Value *V, unsigned Idx); + Metadata *getValueFwdRef(unsigned Idx); + void AssignValue(Metadata *MD, unsigned Idx); + void tryToResolveCycles(); }; class BitcodeReader : public GVMaterializer { @@ -248,9 +254,12 @@ private: Type *getTypeByID(unsigned ID); Value *getFnValueByID(unsigned ID, Type *Ty) { if (Ty && Ty->isMetadataTy()) - return MDValueList.getValueFwdRef(ID); + return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); return ValueList.getValueFwdRef(ID, Ty); } + Metadata *getFnMetadataByID(unsigned ID) { + return MDValueList.getValueFwdRef(ID); + } BasicBlock *getBasicBlock(unsigned ID) const { if (ID >= FunctionBBs.size()) return nullptr; // Invalid ID return FunctionBBs[ID]; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 2e6701156cac..0de929eaa992 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -737,44 +737,79 @@ static uint64_t GetOptimizationFlags(const Value *V) { return Flags; } +static void WriteValueAsMetadataImpl(const ValueAsMetadata *MD, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &Record, + unsigned Code) { + // Mimic an MDNode with a value as one operand. + Value *V = MD->getValue(); + Record.push_back(VE.getTypeID(V->getType())); + Record.push_back(VE.getValueID(V)); + Stream.EmitRecord(Code, Record, 0); + Record.clear(); +} + +static void WriteLocalAsMetadata(const LocalAsMetadata *MD, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &Record) { + WriteValueAsMetadataImpl(MD, VE, Stream, Record, bitc::METADATA_FN_NODE); +} + +static void WriteConstantAsMetadata(const ConstantAsMetadata *MD, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &Record) { + WriteValueAsMetadataImpl(MD, VE, Stream, Record, bitc::METADATA_NODE); +} + static void WriteMDNode(const MDNode *N, const ValueEnumerator &VE, BitstreamWriter &Stream, SmallVectorImpl &Record) { for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (N->getOperand(i)) { - Record.push_back(VE.getTypeID(N->getOperand(i)->getType())); - Record.push_back(VE.getValueID(N->getOperand(i))); - } else { + Metadata *MD = N->getOperand(i); + if (!MD) { Record.push_back(VE.getTypeID(Type::getVoidTy(N->getContext()))); Record.push_back(0); + continue; } + if (auto *V = dyn_cast(MD)) { + Record.push_back(VE.getTypeID(V->getValue()->getType())); + Record.push_back(VE.getValueID(V->getValue())); + continue; + } + assert(!isa(MD) && "Unexpected function-local metadata"); + Record.push_back(VE.getTypeID(Type::getMetadataTy(N->getContext()))); + Record.push_back(VE.getMetadataID(MD)); } - unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE : - bitc::METADATA_NODE; - Stream.EmitRecord(MDCode, Record, 0); + Stream.EmitRecord(bitc::METADATA_NODE, Record, 0); Record.clear(); } static void WriteModuleMetadata(const Module *M, const ValueEnumerator &VE, BitstreamWriter &Stream) { - const auto &Vals = VE.getMDValues(); + const auto &MDs = VE.getMDs(); bool StartedMetadataBlock = false; unsigned MDSAbbrev = 0; SmallVector Record; - for (unsigned i = 0, e = Vals.size(); i != e; ++i) { - - if (const MDNode *N = dyn_cast(Vals[i])) { - if (!N->isFunctionLocal() || !N->getFunction()) { - if (!StartedMetadataBlock) { - Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); - StartedMetadataBlock = true; - } - WriteMDNode(N, VE, Stream, Record); + for (unsigned i = 0, e = MDs.size(); i != e; ++i) { + if (const MDNode *N = dyn_cast(MDs[i])) { + if (!StartedMetadataBlock) { + Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); + StartedMetadataBlock = true; } - } else if (const MDString *MDS = dyn_cast(Vals[i])) { - if (!StartedMetadataBlock) { + WriteMDNode(N, VE, Stream, Record); + } else if (const auto *MDC = dyn_cast(MDs[i])) { + if (!StartedMetadataBlock) { + Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); + StartedMetadataBlock = true; + } + WriteConstantAsMetadata(MDC, VE, Stream, Record); + } else if (const MDString *MDS = dyn_cast(MDs[i])) { + if (!StartedMetadataBlock) { Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); // Abbrev for METADATA_STRING. @@ -813,7 +848,7 @@ static void WriteModuleMetadata(const Module *M, // Write named metadata operands. for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) - Record.push_back(VE.getValueID(NMD->getOperand(i))); + Record.push_back(VE.getMetadataID(NMD->getOperand(i))); Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0); Record.clear(); } @@ -827,16 +862,16 @@ static void WriteFunctionLocalMetadata(const Function &F, BitstreamWriter &Stream) { bool StartedMetadataBlock = false; SmallVector Record; - const SmallVectorImpl &Vals = VE.getFunctionLocalMDValues(); - for (unsigned i = 0, e = Vals.size(); i != e; ++i) - if (const MDNode *N = Vals[i]) - if (N->isFunctionLocal() && N->getFunction() == &F) { - if (!StartedMetadataBlock) { - Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); - StartedMetadataBlock = true; - } - WriteMDNode(N, VE, Stream, Record); - } + const SmallVectorImpl &MDs = + VE.getFunctionLocalMDs(); + for (unsigned i = 0, e = MDs.size(); i != e; ++i) { + assert(MDs[i] && "Expected valid function-local metadata"); + if (!StartedMetadataBlock) { + Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); + StartedMetadataBlock = true; + } + WriteLocalAsMetadata(MDs[i], VE, Stream, Record); + } if (StartedMetadataBlock) Stream.ExitBlock(); @@ -866,7 +901,7 @@ static void WriteMetadataAttachment(const Function &F, for (unsigned i = 0, e = MDs.size(); i != e; ++i) { Record.push_back(MDs[i].first); - Record.push_back(VE.getValueID(MDs[i].second)); + Record.push_back(VE.getMetadataID(MDs[i].second)); } Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); Record.clear(); @@ -1686,11 +1721,12 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, } else { MDNode *Scope, *IA; DL.getScopeAndInlinedAt(Scope, IA, I->getContext()); + assert(Scope && "Expected valid scope"); Vals.push_back(DL.getLine()); Vals.push_back(DL.getCol()); - Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0); - Vals.push_back(IA ? VE.getValueID(IA)+1 : 0); + Vals.push_back(Scope ? VE.getMetadataID(Scope) + 1 : 0); + Vals.push_back(IA ? VE.getMetadataID(IA) + 1 : 0); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); Vals.clear(); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 22b7f52387a4..cae20a86af9f 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -326,6 +326,12 @@ ValueEnumerator::ValueEnumerator(const Module &M) { if (I->hasPrologueData()) EnumerateValue(I->getPrologueData()); + // Enumerate the metadata type. + // + // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode + // only encodes the metadata type when it's used as a value. + EnumerateType(Type::getMetadataTy(M.getContext())); + // Insert constants and metadata that are named at module level into the slot // pool so that the module symbol table can refer to them... EnumerateValueSymbolTable(M.getValueSymbolTable()); @@ -341,11 +347,17 @@ ValueEnumerator::ValueEnumerator(const Module &M) { for (const BasicBlock &BB : F) for (const Instruction &I : BB) { for (const Use &Op : I.operands()) { - if (MDNode *MD = dyn_cast(&Op)) - if (MD->isFunctionLocal() && MD->getFunction()) - // These will get enumerated during function-incorporation. - continue; - EnumerateOperandType(Op); + auto *MD = dyn_cast(&Op); + if (!MD) { + EnumerateOperandType(Op); + continue; + } + + // Local metadata is enumerated during function-incorporation. + if (isa(MD->getMetadata())) + continue; + + EnumerateMetadata(MD->getMetadata()); } EnumerateType(I.getType()); if (const CallInst *CI = dyn_cast(&I)) @@ -389,17 +401,20 @@ void ValueEnumerator::setInstructionID(const Instruction *I) { } unsigned ValueEnumerator::getValueID(const Value *V) const { - if (isa(V) || isa(V)) { - ValueMapType::const_iterator I = MDValueMap.find(V); - assert(I != MDValueMap.end() && "Value not in slotcalculator!"); - return I->second-1; - } + if (auto *MD = dyn_cast(V)) + return getMetadataID(MD->getMetadata()); ValueMapType::const_iterator I = ValueMap.find(V); assert(I != ValueMap.end() && "Value not in slotcalculator!"); return I->second-1; } +unsigned ValueEnumerator::getMetadataID(const Metadata *MD) const { + auto I = MDValueMap.find(MD); + assert(I != MDValueMap.end() && "Metadata not in slotcalculator!"); + return I->second - 1; +} + void ValueEnumerator::dump() const { print(dbgs(), ValueMap, "Default"); dbgs() << '\n'; @@ -436,6 +451,18 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map, } } +void ValueEnumerator::print(raw_ostream &OS, const MetadataMapType &Map, + const char *Name) const { + + OS << "Map Name: " << Name << "\n"; + OS << "Size: " << Map.size() << "\n"; + for (auto I = Map.begin(), E = Map.end(); I != E; ++I) { + const Metadata *MD = I->first; + OS << "Metadata: slot = " << I->second << "\n"; + MD->dump(); + } +} + /// OptimizeConstants - Reorder constant pool for denser encoding. void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) { if (CstStart == CstEnd || CstStart+1 == CstEnd) return; @@ -493,25 +520,24 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) { /// and types referenced by the given MDNode. void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) { for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (Value *V = N->getOperand(i)) { - if (isa(V) || isa(V)) - EnumerateMetadata(V); - else if (!isa(V) && !isa(V)) - EnumerateValue(V); - } else + Metadata *MD = N->getOperand(i); + if (!MD) { EnumerateType(Type::getVoidTy(N->getContext())); + continue; + } + assert(!isa(MD) && "MDNodes cannot be function-local"); + if (auto *C = dyn_cast(MD)) { + EnumerateValue(C->getValue()); + continue; + } + EnumerateMetadata(MD); } } -void ValueEnumerator::EnumerateMetadata(const Value *MD) { - assert((isa(MD) || isa(MD)) && "Invalid metadata kind"); - - // Skip function-local nodes themselves, but walk their operands. - const MDNode *N = dyn_cast(MD); - if (N && N->isFunctionLocal() && N->getFunction()) { - EnumerateMDNodeOperands(N); - return; - } +void ValueEnumerator::EnumerateMetadata(const Metadata *MD) { + assert( + (isa(MD) || isa(MD) || isa(MD)) && + "Invalid metadata kind"); // Insert a dummy ID to block the co-recursive call to // EnumerateMDNodeOperands() from re-visiting MD in a cyclic graph. @@ -520,55 +546,39 @@ void ValueEnumerator::EnumerateMetadata(const Value *MD) { if (!MDValueMap.insert(std::make_pair(MD, 0)).second) return; - // Enumerate the type of this value. - EnumerateType(MD->getType()); - // Visit operands first to minimize RAUW. - if (N) + if (auto *N = dyn_cast(MD)) EnumerateMDNodeOperands(N); + else if (auto *C = dyn_cast(MD)) + EnumerateValue(C->getValue()); // Replace the dummy ID inserted above with the correct one. MDValueMap may // have changed by inserting operands, so we need a fresh lookup here. - MDValues.push_back(MD); - MDValueMap[MD] = MDValues.size(); + MDs.push_back(MD); + MDValueMap[MD] = MDs.size(); } /// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata -/// information reachable from the given MDNode. -void ValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) { - assert(N->isFunctionLocal() && N->getFunction() && - "EnumerateFunctionLocalMetadata called on non-function-local mdnode!"); - - // Enumerate the type of this value. - EnumerateType(N->getType()); - +/// information reachable from the metadata. +void ValueEnumerator::EnumerateFunctionLocalMetadata( + const LocalAsMetadata *Local) { // Check to see if it's already in! - unsigned &MDValueID = MDValueMap[N]; + unsigned &MDValueID = MDValueMap[Local]; if (MDValueID) return; - MDValues.push_back(N); - MDValueID = MDValues.size(); + MDs.push_back(Local); + MDValueID = MDs.size(); - // To incoroporate function-local information visit all function-local - // MDNodes and all function-local values they reference. - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) - if (Value *V = N->getOperand(i)) { - if (MDNode *O = dyn_cast(V)) { - if (O->isFunctionLocal() && O->getFunction()) - EnumerateFunctionLocalMetadata(O); - } else if (isa(V) || isa(V)) - EnumerateValue(V); - } + EnumerateValue(Local->getValue()); - // Also, collect all function-local MDNodes for easy access. - FunctionLocalMDs.push_back(N); + // Also, collect all function-local metadata for easy access. + FunctionLocalMDs.push_back(Local); } void ValueEnumerator::EnumerateValue(const Value *V) { assert(!V->getType()->isVoidTy() && "Can't insert void values!"); - assert(!isa(V) && !isa(V) && - "EnumerateValue doesn't handle Metadata!"); + assert(!isa(V) && "EnumerateValue doesn't handle Metadata!"); // Check to see if it's already in! unsigned &ValueID = ValueMap[V]; @@ -657,30 +667,35 @@ void ValueEnumerator::EnumerateType(Type *Ty) { void ValueEnumerator::EnumerateOperandType(const Value *V) { EnumerateType(V->getType()); - if (const Constant *C = dyn_cast(V)) { - // If this constant is already enumerated, ignore it, we know its type must - // be enumerated. - if (ValueMap.count(V)) return; + if (auto *MD = dyn_cast(V)) { + assert(!isa(MD->getMetadata()) && + "Function-local metadata should be left for later"); - // This constant may have operands, make sure to enumerate the types in - // them. - for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { - const Value *Op = C->getOperand(i); + EnumerateMetadata(MD->getMetadata()); + return; + } - // Don't enumerate basic blocks here, this happens as operands to - // blockaddress. - if (isa(Op)) continue; + const Constant *C = dyn_cast(V); + if (!C) + return; - EnumerateOperandType(Op); - } + // If this constant is already enumerated, ignore it, we know its type must + // be enumerated. + if (ValueMap.count(C)) + return; - if (const MDNode *N = dyn_cast(V)) { - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) - if (Value *Elem = N->getOperand(i)) - EnumerateOperandType(Elem); - } - } else if (isa(V) || isa(V)) - EnumerateMetadata(V); + // This constant may have operands, make sure to enumerate the types in + // them. + for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { + const Value *Op = C->getOperand(i); + + // Don't enumerate basic blocks here, this happens as operands to + // blockaddress. + if (isa(Op)) + continue; + + EnumerateOperandType(Op); + } } void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) { @@ -708,7 +723,7 @@ void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) { void ValueEnumerator::incorporateFunction(const Function &F) { InstructionCount = 0; NumModuleValues = Values.size(); - NumModuleMDValues = MDValues.size(); + NumModuleMDs = MDs.size(); // Adding function arguments to the value table. for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); @@ -739,24 +754,16 @@ void ValueEnumerator::incorporateFunction(const Function &F) { FirstInstID = Values.size(); - SmallVector FnLocalMDVector; + SmallVector FnLocalMDVector; // Add all of the instructions. for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI) { - if (MDNode *MD = dyn_cast(*OI)) - if (MD->isFunctionLocal() && MD->getFunction()) + if (auto *MD = dyn_cast(&*OI)) + if (auto *Local = dyn_cast(MD->getMetadata())) // Enumerate metadata after the instructions they might refer to. - FnLocalMDVector.push_back(MD); - } - - SmallVector, 8> MDs; - I->getAllMetadataOtherThanDebugLoc(MDs); - for (unsigned i = 0, e = MDs.size(); i != e; ++i) { - MDNode *N = MDs[i].second; - if (N->isFunctionLocal() && N->getFunction()) - FnLocalMDVector.push_back(N); + FnLocalMDVector.push_back(Local); } if (!I->getType()->isVoidTy()) @@ -773,13 +780,13 @@ void ValueEnumerator::purgeFunction() { /// Remove purged values from the ValueMap. for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i) ValueMap.erase(Values[i].first); - for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i) - MDValueMap.erase(MDValues[i]); + for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i) + MDValueMap.erase(MDs[i]); for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) ValueMap.erase(BasicBlocks[i]); Values.resize(NumModuleValues); - MDValues.resize(NumModuleMDValues); + MDs.resize(NumModuleMDs); BasicBlocks.clear(); FunctionLocalMDs.clear(); } diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h index 563c21442532..3b1b3137e39f 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -30,6 +30,8 @@ class BasicBlock; class Comdat; class Function; class Module; +class Metadata; +class LocalAsMetadata; class MDNode; class NamedMDNode; class AttributeSet; @@ -58,9 +60,10 @@ private: typedef UniqueVector ComdatSetType; ComdatSetType Comdats; - std::vector MDValues; - SmallVector FunctionLocalMDs; - ValueMapType MDValueMap; + std::vector MDs; + SmallVector FunctionLocalMDs; + typedef DenseMap MetadataMapType; + MetadataMapType MDValueMap; typedef DenseMap AttributeGroupMapType; AttributeGroupMapType AttributeGroupMap; @@ -88,7 +91,7 @@ private: /// When a function is incorporated, this is the size of the MDValues list /// before incorporation. - unsigned NumModuleMDValues; + unsigned NumModuleMDs; unsigned FirstFuncConstantID; unsigned FirstInstID; @@ -100,8 +103,11 @@ public: void dump() const; void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const; + void print(raw_ostream &OS, const MetadataMapType &Map, + const char *Name) const; unsigned getValueID(const Value *V) const; + unsigned getMetadataID(const Metadata *V) const; unsigned getTypeID(Type *T) const { TypeMapType::const_iterator I = TypeMap.find(T); @@ -134,8 +140,8 @@ public: } const ValueList &getValues() const { return Values; } - const std::vector &getMDValues() const { return MDValues; } - const SmallVectorImpl &getFunctionLocalMDValues() const { + const std::vector &getMDs() const { return MDs; } + const SmallVectorImpl &getFunctionLocalMDs() const { return FunctionLocalMDs; } const TypeList &getTypes() const { return Types; } @@ -167,8 +173,8 @@ private: void OptimizeConstants(unsigned CstStart, unsigned CstEnd); void EnumerateMDNodeOperands(const MDNode *N); - void EnumerateMetadata(const Value *MD); - void EnumerateFunctionLocalMetadata(const MDNode *N); + void EnumerateMetadata(const Metadata *MD); + void EnumerateFunctionLocalMetadata(const LocalAsMetadata *Local); void EnumerateNamedMDNode(const NamedMDNode *NMD); void EnumerateValue(const Value *V); void EnumerateType(Type *T); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index cca5f229c2fc..8cfaba68d20b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -64,7 +64,7 @@ static void srcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo) { if (LocInfo->getNumOperands() != 0) if (const ConstantInt *CI = - dyn_cast(LocInfo->getOperand(ErrorLine))) + mdconst::dyn_extract(LocInfo->getOperand(ErrorLine))) LocCookie = CI->getZExtValue(); } @@ -467,7 +467,8 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const { if (MI->getOperand(i-1).isMetadata() && (LocMD = MI->getOperand(i-1).getMetadata()) && LocMD->getNumOperands() != 0) { - if (const ConstantInt *CI = dyn_cast(LocMD->getOperand(0))) { + if (const ConstantInt *CI = + mdconst::dyn_extract(LocMD->getOperand(0))) { LocCookie = CI->getZExtValue(); break; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 76ba663bb84e..6c5a630edb1b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1192,10 +1192,10 @@ DwarfUnit::constructTemplateValueParameterDIE(DIE &Buffer, addType(ParamDIE, resolve(VP.getType())); if (!VP.getName().empty()) addString(ParamDIE, dwarf::DW_AT_name, VP.getName()); - if (Value *Val = VP.getValue()) { - if (ConstantInt *CI = dyn_cast(Val)) + if (Metadata *Val = VP.getValue()) { + if (ConstantInt *CI = mdconst::dyn_extract(Val)) addConstantValue(ParamDIE, CI, resolve(VP.getType())); - else if (GlobalValue *GV = dyn_cast(Val)) { + else if (GlobalValue *GV = mdconst::dyn_extract(Val)) { // For declaration non-type template parameters (such as global values and // functions) DIELoc *Loc = new (DIEValueAllocator) DIELoc(); diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 96e2d3d74dee..577c048ba60e 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -3810,8 +3810,10 @@ static bool extractBranchMetadata(BranchInst *BI, if (!ProfileData || ProfileData->getNumOperands() != 3) return false; - const auto *CITrue = dyn_cast(ProfileData->getOperand(1)); - const auto *CIFalse = dyn_cast(ProfileData->getOperand(2)); + const auto *CITrue = + mdconst::dyn_extract(ProfileData->getOperand(1)); + const auto *CIFalse = + mdconst::dyn_extract(ProfileData->getOperand(2)); if (!CITrue || !CIFalse) return false; diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 7ad0d9426efc..968ec2c68e8c 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -397,7 +397,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { break; case MachineOperand::MO_Metadata: OS << '<'; - getMetadata()->printAsOperand(OS, /*PrintType=*/false); + getMetadata()->printAsOperand(OS); OS << '>'; break; case MachineOperand::MO_MCSymbol: @@ -537,7 +537,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { if (const MDNode *TBAAInfo = MMO.getAAInfo().TBAA) { OS << "(tbaa="; if (TBAAInfo->getNumOperands() > 0) - TBAAInfo->getOperand(0)->printAsOperand(OS, /*PrintType=*/false); + TBAAInfo->getOperand(0)->printAsOperand(OS); else OS << ""; OS << ")"; @@ -548,7 +548,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { OS << "(alias.scope="; if (ScopeInfo->getNumOperands() > 0) for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { - ScopeInfo->getOperand(i)->printAsOperand(OS, /*PrintType=*/false); + ScopeInfo->getOperand(i)->printAsOperand(OS); if (i != ie-1) OS << ","; } @@ -562,7 +562,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { OS << "(noalias="; if (NoAliasInfo->getNumOperands() > 0) for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { - NoAliasInfo->getOperand(i)->printAsOperand(OS, /*PrintType=*/false); + NoAliasInfo->getOperand(i)->printAsOperand(OS); if (i != ie-1) OS << ","; } @@ -599,6 +599,8 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0), AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr), debugLoc(dl) { + assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); + // Reserve space for the expected number of operands. if (unsigned NumOps = MCID->getNumOperands() + MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) { @@ -617,6 +619,8 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) Flags(0), AsmPrinterFlags(0), NumMemRefs(MI.NumMemRefs), MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc()) { + assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); + CapOperands = OperandCapacity::get(MI.getNumOperands()); Operands = MF.allocateOperandArray(CapOperands); @@ -1960,7 +1964,8 @@ void MachineInstr::emitError(StringRef Msg) const { if (getOperand(i-1).isMetadata() && (LocMD = getOperand(i-1).getMetadata()) && LocMD->getNumOperands() != 0) { - if (const ConstantInt *CI = dyn_cast(LocMD->getOperand(0))) { + if (const ConstantInt *CI = + mdconst::dyn_extract(LocMD->getOperand(0))) { LocCookie = CI->getZExtValue(); break; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index cab3cbf8ab56..c573339c7bfa 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4714,7 +4714,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { return nullptr; case Intrinsic::read_register: { Value *Reg = I.getArgOperand(0); - SDValue RegName = DAG.getMDNode(cast(Reg)); + SDValue RegName = + DAG.getMDNode(cast(cast(Reg)->getMetadata())); EVT VT = TLI.getValueType(I.getType()); setValue(&I, DAG.getNode(ISD::READ_REGISTER, sdl, VT, RegName)); return nullptr; @@ -4723,7 +4724,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { Value *Reg = I.getArgOperand(0); Value *RegValue = I.getArgOperand(1); SDValue Chain = getValue(RegValue).getOperand(0); - SDValue RegName = DAG.getMDNode(cast(Reg)); + SDValue RegName = + DAG.getMDNode(cast(cast(Reg)->getMetadata())); DAG.setRoot(DAG.getNode(ISD::WRITE_REGISTER, sdl, MVT::Other, Chain, RegName, getValue(RegValue))); return nullptr; diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp index dcf1b448a910..faf94b67fe77 100644 --- a/llvm/lib/CodeGen/StackColoring.cpp +++ b/llvm/lib/CodeGen/StackColoring.cpp @@ -463,7 +463,8 @@ void StackColoring::remapInstructions(DenseMap &SlotRemap) { if (!VI.Var) continue; if (SlotRemap.count(VI.Slot)) { - DEBUG(dbgs()<<"Remapping debug info for ["<getName()<<"].\n"); + DEBUG(dbgs() << "Remapping debug info for [" + << DIVariable(VI.Var).getName() << "].\n"); VI.Slot = SlotRemap[VI.Slot]; FixedDbg++; } diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index e52552af5e4f..55cc016cc983 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -464,15 +464,15 @@ emitModuleFlags(MCStreamer &Streamer, continue; StringRef Key = MFE.Key->getString(); - Value *Val = MFE.Val; + Metadata *Val = MFE.Val; if (Key == "Objective-C Image Info Version") { - VersionVal = cast(Val)->getZExtValue(); + VersionVal = mdconst::extract(Val)->getZExtValue(); } else if (Key == "Objective-C Garbage Collection" || Key == "Objective-C GC Only" || Key == "Objective-C Is Simulated" || Key == "Objective-C Image Swift Version") { - ImageInfoFlags |= cast(Val)->getZExtValue(); + ImageInfoFlags |= mdconst::extract(Val)->getZExtValue(); } else if (Key == "Objective-C Image Info Section") { SectionVal = cast(Val)->getString(); } else if (Key == "Linker Options") { @@ -966,7 +966,7 @@ emitModuleFlags(MCStreamer &Streamer, i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) { const Module::ModuleFlagEntry &MFE = *i; StringRef Key = MFE.Key->getString(); - Value *Val = MFE.Val; + Metadata *Val = MFE.Val; if (Key == "Linker Options") { LinkerOptions = cast(Val); break; diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 4af03465f41d..8fe03c061664 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -634,13 +634,6 @@ static SlotTracker *createSlotTracker(const Value *V) { if (const Function *Func = dyn_cast(V)) return new SlotTracker(Func); - if (const MDNode *MD = dyn_cast(V)) { - if (!MD->isFunctionLocal()) - return new SlotTracker(MD->getFunction()); - - return new SlotTracker((Function *)nullptr); - } - return nullptr; } @@ -653,16 +646,14 @@ static SlotTracker *createSlotTracker(const Value *V) { // Module level constructor. Causes the contents of the Module (sans functions) // to be added to the slot table. SlotTracker::SlotTracker(const Module *M) - : TheModule(M), TheFunction(nullptr), FunctionProcessed(false), - mNext(0), fNext(0), mdnNext(0), asNext(0) { -} + : TheModule(M), TheFunction(nullptr), FunctionProcessed(false), mNext(0), + fNext(0), mdnNext(0), asNext(0) {} // Function level constructor. Causes the contents of the Module and the one // function provided to be added to the slot table. SlotTracker::SlotTracker(const Function *F) - : TheModule(F ? F->getParent() : nullptr), TheFunction(F), - FunctionProcessed(false), mNext(0), fNext(0), mdnNext(0), asNext(0) { -} + : TheModule(F ? F->getParent() : nullptr), TheFunction(F), + FunctionProcessed(false), mNext(0), fNext(0), mdnNext(0), asNext(0) {} inline void SlotTracker::initialize() { if (TheModule) { @@ -744,8 +735,9 @@ void SlotTracker::processFunction() { if (Function *F = CI->getCalledFunction()) if (F->isIntrinsic()) for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (MDNode *N = dyn_cast_or_null(I->getOperand(i))) - CreateMetadataSlot(N); + if (auto *V = dyn_cast_or_null(I->getOperand(i))) + if (MDNode *N = dyn_cast(V->getMetadata())) + CreateMetadataSlot(N); // Add all the call attributes to the table. AttributeSet Attrs = CI->getAttributes().getFnAttributes(); @@ -856,16 +848,10 @@ void SlotTracker::CreateFunctionSlot(const Value *V) { void SlotTracker::CreateMetadataSlot(const MDNode *N) { assert(N && "Can't insert a null Value into SlotTracker!"); - // Don't insert if N is a function-local metadata, these are always printed - // inline. - if (!N->isFunctionLocal()) { - mdn_iterator I = mdnMap.find(N); - if (I != mdnMap.end()) - return; - - unsigned DestSlot = mdnNext++; - mdnMap[N] = DestSlot; - } + unsigned DestSlot = mdnNext; + if (!mdnMap.insert(std::make_pair(N, DestSlot)).second) + return; + ++mdnNext; // Recursively add any MDNodes referenced by operands. for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) @@ -894,6 +880,11 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, SlotTracker *Machine, const Module *Context); +static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD, + TypePrinting *TypePrinter, + SlotTracker *Machine, const Module *Context, + bool FromValue = false); + static const char *getPredicateText(unsigned predicate) { const char * pred = "unknown"; switch (predicate) { @@ -1264,14 +1255,17 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, const Module *Context) { Out << "!{"; for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) { - const Value *V = Node->getOperand(mi); - if (!V) + const Metadata *MD = Node->getOperand(mi); + if (!MD) Out << "null"; - else { + else if (auto *MDV = dyn_cast(MD)) { + Value *V = MDV->getValue(); TypePrinter->print(V->getType(), Out); Out << ' '; - WriteAsOperandInternal(Out, Node->getOperand(mi), - TypePrinter, Machine, Context); + WriteAsOperandInternal(Out, V, TypePrinter, Machine, Context); + } else { + Out << "metadata "; + WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context); } if (mi + 1 != me) Out << ", "; @@ -1315,31 +1309,9 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, return; } - if (const MDNode *N = dyn_cast(V)) { - if (N->isFunctionLocal()) { - // Print metadata inline, not via slot reference number. - WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine, Context); - return; - } - - if (!Machine) { - if (N->isFunctionLocal()) - Machine = new SlotTracker(N->getFunction()); - else - Machine = new SlotTracker(Context); - } - int Slot = Machine->getMetadataSlot(N); - if (Slot == -1) - Out << ""; - else - Out << '!' << Slot; - return; - } - - if (const MDString *MDS = dyn_cast(V)) { - Out << "!\""; - PrintEscapedString(MDS->getString(), Out); - Out << '"'; + if (auto *MD = dyn_cast(V)) { + WriteAsOperandInternal(Out, MD->getMetadata(), TypePrinter, Machine, + Context, /* FromValue */ true); return; } @@ -1382,6 +1354,42 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, Out << ""; } +static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD, + TypePrinting *TypePrinter, + SlotTracker *Machine, const Module *Context, + bool FromValue) { + if (const MDNode *N = dyn_cast(MD)) { + if (!Machine) + Machine = new SlotTracker(Context); + int Slot = Machine->getMetadataSlot(N); + if (Slot == -1) + Out << ""; + else + Out << '!' << Slot; + return; + } + + if (const MDString *MDS = dyn_cast(MD)) { + Out << "!\""; + PrintEscapedString(MDS->getString(), Out); + Out << '"'; + return; + } + + auto *V = cast(MD); + assert(TypePrinter && "TypePrinter required for metadata values"); + assert((FromValue || !isa(V)) && + "Unexpected function-local metadata outside of value argument"); + + if (FromValue) + Out << "!{"; + TypePrinter->print(V->getValue()->getType(), Out); + Out << ' '; + WriteAsOperandInternal(Out, V->getValue(), TypePrinter, Machine, Context); + if (FromValue) + Out << "}"; +} + void AssemblyWriter::init() { if (!TheModule) return; @@ -2351,7 +2359,7 @@ static void WriteMDNodeComment(const MDNode *Node, if (Node->getNumOperands() < 1) return; - Value *Op = Node->getOperand(0); + Metadata *Op = Node->getOperand(0); if (!Op || !isa(Op)) return; @@ -2522,18 +2530,14 @@ void Value::print(raw_ostream &ROS) const { W.printFunction(F); else W.printAlias(cast(GV)); - } else if (const MDNode *N = dyn_cast(this)) { - const Function *F = N->getFunction(); - SlotTracker SlotTable(F); - AssemblyWriter W(OS, SlotTable, F ? F->getParent() : nullptr, nullptr); - W.printMDNodeBody(N); + } else if (const MetadataAsValue *V = dyn_cast(this)) { + V->getMetadata()->print(ROS); } else if (const Constant *C = dyn_cast(this)) { TypePrinting TypePrinter; TypePrinter.print(C->getType(), OS); OS << ' '; WriteConstantInternal(OS, C, TypePrinter, nullptr, nullptr); - } else if (isa(this) || isa(this) || - isa(this)) { + } else if (isa(this) || isa(this)) { this->printAsOperand(OS); } else { llvm_unreachable("Unknown value to print out!"); @@ -2543,9 +2547,8 @@ void Value::print(raw_ostream &ROS) const { void Value::printAsOperand(raw_ostream &O, bool PrintType, const Module *M) const { // Fast path: Don't construct and populate a TypePrinting object if we // won't be needing any types printed. - if (!PrintType && - ((!isa(this) && !isa(this)) || - hasName() || isa(this))) { + if (!PrintType && ((!isa(this) && !isa(this)) || + hasName() || isa(this))) { WriteAsOperandInternal(O, this, nullptr, nullptr, M); return; } @@ -2564,6 +2567,35 @@ void Value::printAsOperand(raw_ostream &O, bool PrintType, const Module *M) cons WriteAsOperandInternal(O, this, &TypePrinter, nullptr, M); } +void Metadata::print(raw_ostream &ROS) const { + formatted_raw_ostream OS(ROS); + if (auto *N = dyn_cast(this)) { + OS << "metadata "; + SlotTracker SlotTable(static_cast(nullptr)); + AssemblyWriter W(OS, SlotTable, nullptr, nullptr); + W.printMDNodeBody(N); + + return; + } + printAsOperand(OS); +} + +void Metadata::printAsOperand(raw_ostream &ROS, bool PrintType, + const Module *M) const { + formatted_raw_ostream OS(ROS); + if (PrintType) + OS << "metadata "; + + std::unique_ptr TypePrinter; + if (PrintType) { + TypePrinter.reset(new TypePrinting); + if (M) + TypePrinter->incorporateTypes(*M); + } + WriteAsOperandInternal(OS, this, TypePrinter.get(), nullptr, M, + /* FromValue */ true); +} + // Value::dump - allow easy printing of Values from the debugger. void Value::dump() const { print(dbgs()); dbgs() << '\n'; } @@ -2578,3 +2610,8 @@ void Comdat::dump() const { print(dbgs()); } // NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger. void NamedMDNode::dump() const { print(dbgs()); } + +void Metadata::dump() const { + print(dbgs()); + dbgs() << '\n'; +} diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index c24dfead433d..512bca1c0182 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -260,14 +260,15 @@ static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) { return dyn_cast_or_null(DbgNode->getOperand(Elt)); } -static DIExpression getExpression(Value *VarOperand, Function *F) { +static MetadataAsValue *getExpression(Value *VarOperand, Function *F) { // Old-style DIVariables have an optional expression as the 8th element. - DIExpression Expr(getNodeField(cast(VarOperand), 8)); + DIExpression Expr(getNodeField( + cast(cast(VarOperand)->getMetadata()), 8)); if (!Expr) { - DIBuilder DIB(*F->getParent()); + DIBuilder DIB(*F->getParent(), /*AllowUnresolved*/ false); Expr = DIB.createExpression(); } - return Expr; + return MetadataAsValue::get(F->getContext(), Expr); } // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the @@ -306,8 +307,9 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Builder.SetInsertPoint(CI->getParent(), CI); Module *M = F->getParent(); - SmallVector Elts; - Elts.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); + SmallVector Elts; + Elts.push_back( + ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1))); MDNode *Node = MDNode::get(C, Elts); Value *Arg0 = CI->getArgOperand(0); @@ -578,22 +580,18 @@ void llvm::UpgradeInstWithTBAATag(Instruction *I) { return; if (MD->getNumOperands() == 3) { - Value *Elts[] = { - MD->getOperand(0), - MD->getOperand(1) - }; + Metadata *Elts[] = {MD->getOperand(0), MD->getOperand(1)}; MDNode *ScalarType = MDNode::get(I->getContext(), Elts); // Create a MDNode - Value *Elts2[] = { - ScalarType, ScalarType, - Constant::getNullValue(Type::getInt64Ty(I->getContext())), - MD->getOperand(2) - }; + Metadata *Elts2[] = {ScalarType, ScalarType, + ConstantAsMetadata::get(Constant::getNullValue( + Type::getInt64Ty(I->getContext()))), + MD->getOperand(2)}; I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts2)); } else { // Create a MDNode - Value *Elts[] = {MD, MD, - Constant::getNullValue(Type::getInt64Ty(I->getContext()))}; + Metadata *Elts[] = {MD, MD, ConstantAsMetadata::get(Constant::getNullValue( + Type::getInt64Ty(I->getContext())))}; I->setMetadata(LLVMContext::MD_tbaa, MDNode::get(I->getContext(), Elts)); } } diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt index 144c086bf0ef..3b149e8690ac 100644 --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -32,6 +32,7 @@ add_llvm_library(LLVMCore MDBuilder.cpp Mangler.cpp Metadata.cpp + MetadataTracking.cpp Module.cpp Pass.cpp PassManager.cpp diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 3576137dd306..a25c4d66d3bb 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -556,12 +556,17 @@ int LLVMHasMetadata(LLVMValueRef Inst) { } LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) { - return wrap(unwrap(Inst)->getMetadata(KindID)); + auto *I = unwrap(Inst); + assert(I && "Expected instruction"); + if (auto *MD = I->getMetadata(KindID)) + return wrap(MetadataAsValue::get(I->getContext(), MD)); + return nullptr; } void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) { - unwrap(Inst) - ->setMetadata(KindID, MD ? unwrap(MD) : nullptr); + MDNode *N = + MD ? cast(unwrap(MD)->getMetadata()) : nullptr; + unwrap(Inst)->setMetadata(KindID, N); } /*--.. Conversion functions ................................................--*/ @@ -573,6 +578,21 @@ void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) { LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DEFINE_VALUE_CAST) +LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val) { + if (auto *MD = dyn_cast_or_null(unwrap(Val))) + if (isa(MD->getMetadata()) || + isa(MD->getMetadata())) + return Val; + return nullptr; +} + +LLVMValueRef LLVMIsAMDString(LLVMValueRef Val) { + if (auto *MD = dyn_cast_or_null(unwrap(Val))) + if (isa(MD->getMetadata())) + return Val; + return nullptr; +} + /*--.. Operations on Uses ..................................................--*/ LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) { Value *V = unwrap(Val); @@ -598,10 +618,28 @@ LLVMValueRef LLVMGetUsedValue(LLVMUseRef U) { } /*--.. Operations on Users .................................................--*/ + +static LLVMValueRef getMDNodeOperandImpl(LLVMContext &Context, const MDNode *N, + unsigned Index) { + Metadata *Op = N->getOperand(Index); + if (!Op) + return nullptr; + if (auto *C = dyn_cast(Op)) + return wrap(C->getValue()); + return wrap(MetadataAsValue::get(Context, Op)); +} + LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index) { Value *V = unwrap(Val); - if (MDNode *MD = dyn_cast(V)) - return wrap(MD->getOperand(Index)); + if (auto *MD = dyn_cast(V)) { + if (auto *L = dyn_cast(MD->getMetadata())) { + assert(Index == 0 && "Function-local metadata can only have one operand"); + return wrap(L->getValue()); + } + return getMDNodeOperandImpl(V->getContext(), + cast(MD->getMetadata()), Index); + } + return wrap(cast(V)->getOperand(Index)); } @@ -616,8 +654,9 @@ void LLVMSetOperand(LLVMValueRef Val, unsigned Index, LLVMValueRef Op) { int LLVMGetNumOperands(LLVMValueRef Val) { Value *V = unwrap(Val); - if (MDNode *MD = dyn_cast(V)) - return MD->getNumOperands(); + if (isa(V)) + return LLVMGetMDNodeNumOperands(Val); + return cast(V)->getNumOperands(); } @@ -658,7 +697,9 @@ LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty) { LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str, unsigned SLen) { - return wrap(MDString::get(*unwrap(C), StringRef(Str, SLen))); + LLVMContext &Context = *unwrap(C); + return wrap(MetadataAsValue::get( + Context, MDString::get(Context, StringRef(Str, SLen)))); } LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) { @@ -667,8 +708,29 @@ LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) { LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, unsigned Count) { - return wrap(MDNode::get(*unwrap(C), - makeArrayRef(unwrap(Vals, Count), Count))); + LLVMContext &Context = *unwrap(C); + SmallVector MDs; + for (auto *OV : makeArrayRef(Vals, Count)) { + Value *V = unwrap(OV); + Metadata *MD; + if (!V) + MD = nullptr; + else if (auto *C = dyn_cast(V)) + MD = ConstantAsMetadata::get(C); + else if (auto *MDV = dyn_cast(V)) { + MD = MDV->getMetadata(); + assert(!isa(MD) && "Unexpected function-local metadata " + "outside of direct argument to call"); + } else { + // This is function-local metadata. Pretend to make an MDNode. + assert(Count == 1 && + "Expected only one operand to function-local metadata"); + return wrap(MetadataAsValue::get(Context, LocalAsMetadata::get(V))); + } + + MDs.push_back(MD); + } + return wrap(MetadataAsValue::get(Context, MDNode::get(Context, MDs))); } LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) { @@ -676,25 +738,35 @@ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) { } const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len) { - if (const MDString *S = dyn_cast(unwrap(V))) { - *Len = S->getString().size(); - return S->getString().data(); - } + if (const auto *MD = dyn_cast(unwrap(V))) + if (const MDString *S = dyn_cast(MD->getMetadata())) { + *Len = S->getString().size(); + return S->getString().data(); + } *Len = 0; return nullptr; } unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V) { - return cast(unwrap(V))->getNumOperands(); + auto *MD = cast(unwrap(V)); + if (isa(MD->getMetadata())) + return 1; + return cast(MD->getMetadata())->getNumOperands(); } void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest) { - const MDNode *N = cast(unwrap(V)); + auto *MD = cast(unwrap(V)); + if (auto *MDV = dyn_cast(MD->getMetadata())) { + *Dest = wrap(MDV->getValue()); + return; + } + const auto *N = cast(MD->getMetadata()); const unsigned numOperands = N->getNumOperands(); + LLVMContext &Context = unwrap(V)->getContext(); for (unsigned i = 0; i < numOperands; i++) - Dest[i] = wrap(N->getOperand(i)); + Dest[i] = getMDNodeOperandImpl(Context, N, i); } unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name) @@ -710,8 +782,9 @@ void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRe NamedMDNode *N = unwrap(M)->getNamedMetadata(name); if (!N) return; + LLVMContext &Context = unwrap(M)->getContext(); for (unsigned i=0;igetNumOperands();i++) - Dest[i] = wrap(N->getOperand(i)); + Dest[i] = wrap(MetadataAsValue::get(Context, N->getOperand(i))); } void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name, @@ -720,9 +793,9 @@ void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name, NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(name); if (!N) return; - MDNode *Op = Val ? unwrap(Val) : nullptr; - if (Op) - N->addOperand(Op); + if (!Val) + return; + N->addOperand(cast(unwrap(Val)->getMetadata())); } /*--.. Operations on scalar constants ......................................--*/ @@ -2092,13 +2165,16 @@ void LLVMDisposeBuilder(LLVMBuilderRef Builder) { /*--.. Metadata builders ...................................................--*/ void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) { - MDNode *Loc = L ? unwrap(L) : nullptr; + MDNode *Loc = + L ? cast(unwrap(L)->getMetadata()) : nullptr; unwrap(Builder)->SetCurrentDebugLocation(DebugLoc::getFromDILocation(Loc)); } LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) { - return wrap(unwrap(Builder)->getCurrentDebugLocation() - .getAsMDNode(unwrap(Builder)->getContext())); + LLVMContext &Context = unwrap(Builder)->getContext(); + return wrap(MetadataAsValue::get( + Context, + unwrap(Builder)->getCurrentDebugLocation().getAsMDNode(Context))); } void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) { diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index fa2d5a19768c..ee7e6a2b21bf 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -48,21 +48,36 @@ public: }; } -DIBuilder::DIBuilder(Module &m) +DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes) : M(m), VMContext(M.getContext()), TempEnumTypes(nullptr), TempRetainTypes(nullptr), TempSubprograms(nullptr), TempGVs(nullptr), - DeclareFn(nullptr), ValueFn(nullptr) {} + DeclareFn(nullptr), ValueFn(nullptr), + AllowUnresolvedNodes(AllowUnresolvedNodes) {} + +static bool isUnresolved(MDNode *N) { + return N && (isa(N) || !cast(N)->isResolved()); +} + +void DIBuilder::trackIfUnresolved(MDNode *N) { + if (!AllowUnresolvedNodes) { + assert(!isUnresolved(N) && "Cannot handle unresolved nodes"); + return; + } + if (isUnresolved(N)) + UnresolvedNodes.emplace_back(N); + return; +} void DIBuilder::finalize() { DIArray Enums = getOrCreateArray(AllEnumTypes); DIType(TempEnumTypes).replaceAllUsesWith(Enums); - SmallVector RetainValues; + SmallVector RetainValues; // Declarations and definitions of the same type may be retained. Some // clients RAUW these pairs, leaving duplicates in the retained types // list. Use a set to remove the duplicates while we transform the // TrackingVHs back into Values. - SmallPtrSet RetainSet; + SmallPtrSet RetainSet; for (unsigned I = 0, E = AllRetainTypes.size(); I < E; I++) if (RetainSet.insert(AllRetainTypes[I]).second) RetainValues.push_back(AllRetainTypes[I]); @@ -74,8 +89,8 @@ void DIBuilder::finalize() { for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { DISubprogram SP(SPs.getElement(i)); if (MDNode *Temp = SP.getVariablesNodes()) { - SmallVector Variables; - for (Value *V : PreservedVariables.lookup(SP)) + SmallVector Variables; + for (Metadata *V : PreservedVariables.lookup(SP)) Variables.push_back(V); DIArray AV = getOrCreateArray(Variables); DIType(Temp).replaceAllUsesWith(AV); @@ -85,11 +100,21 @@ void DIBuilder::finalize() { DIArray GVs = getOrCreateArray(AllGVs); DIType(TempGVs).replaceAllUsesWith(GVs); - SmallVector RetainValuesI; + SmallVector RetainValuesI; for (unsigned I = 0, E = AllImportedModules.size(); I < E; I++) RetainValuesI.push_back(AllImportedModules[I]); DIArray IMs = getOrCreateArray(RetainValuesI); DIType(TempImportedModules).replaceAllUsesWith(IMs); + + // Now that all temp nodes have been replaced or deleted, resolve remaining + // cycles. + for (const auto &N : UnresolvedNodes) + if (N) + cast(N)->resolveCycles(); + UnresolvedNodes.clear(); + + // Can't handle unresolved nodes anymore. + AllowUnresolvedNodes = false; } /// If N is compile unit return NULL otherwise return N. @@ -102,10 +127,8 @@ static MDNode *getNonCompileUnitScope(MDNode *N) { static MDNode *createFilePathPair(LLVMContext &VMContext, StringRef Filename, StringRef Directory) { assert(!Filename.empty() && "Unable to create file without name"); - Value *Pair[] = { - MDString::get(VMContext, Filename), - MDString::get(VMContext, Directory) - }; + Metadata *Pair[] = {MDString::get(VMContext, Filename), + MDString::get(VMContext, Directory)}; return MDNode::get(VMContext, Pair); } @@ -122,7 +145,7 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, "Invalid Language tag"); assert(!Filename.empty() && "Unable to create compile unit without filename"); - Value *TElts[] = {HeaderBuilder::get(DW_TAG_base_type).get(VMContext)}; + Metadata *TElts[] = {HeaderBuilder::get(DW_TAG_base_type).get(VMContext)}; TempEnumTypes = MDNode::getTemporary(VMContext, TElts); TempRetainTypes = MDNode::getTemporary(VMContext, TElts); @@ -133,18 +156,18 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, TempImportedModules = MDNode::getTemporary(VMContext, TElts); - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_compile_unit) - .concat(Lang) - .concat(Producer) - .concat(isOptimized) - .concat(Flags) - .concat(RunTimeVer) - .concat(SplitName) - .concat(Kind) - .get(VMContext), - createFilePathPair(VMContext, Filename, Directory), - TempEnumTypes, TempRetainTypes, TempSubprograms, TempGVs, - TempImportedModules}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_compile_unit) + .concat(Lang) + .concat(Producer) + .concat(isOptimized) + .concat(Flags) + .concat(RunTimeVer) + .concat(SplitName) + .concat(Kind) + .get(VMContext), + createFilePathPair(VMContext, Filename, Directory), + TempEnumTypes, TempRetainTypes, TempSubprograms, TempGVs, + TempImportedModules}; MDNode *CUNode = MDNode::get(VMContext, Elts); @@ -158,20 +181,21 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, NMD->addOperand(CUNode); } + trackIfUnresolved(CUNode); return DICompileUnit(CUNode); } static DIImportedEntity createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope Context, - Value *NS, unsigned Line, StringRef Name, - SmallVectorImpl> &AllImportedModules) { + Metadata *NS, unsigned Line, StringRef Name, + SmallVectorImpl &AllImportedModules) { const MDNode *R; - Value *Elts[] = {HeaderBuilder::get(Tag).concat(Line).concat(Name).get(C), - Context, NS}; + Metadata *Elts[] = {HeaderBuilder::get(Tag).concat(Line).concat(Name).get(C), + Context, NS}; R = MDNode::get(C, Elts); DIImportedEntity M(R); assert(M.Verify() && "Imported module should be valid"); - AllImportedModules.push_back(TrackingVH(M)); + AllImportedModules.emplace_back(M.get()); return M; } @@ -194,7 +218,8 @@ DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, unsigned Line, StringRef Name) { // Make sure to use the unique identifier based metadata reference for // types that have one. - Value *V = Decl.isType() ? static_cast(DIType(Decl).getRef()) : Decl; + Metadata *V = + Decl.isType() ? static_cast(DIType(Decl).getRef()) : Decl; return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, Context, V, Line, Name, AllImportedModules); @@ -208,16 +233,18 @@ DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, } DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) { - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_file_type).get(VMContext), - createFilePathPair(VMContext, Filename, Directory)}; + Metadata *Elts[] = { + HeaderBuilder::get(dwarf::DW_TAG_file_type).get(VMContext), + createFilePathPair(VMContext, Filename, Directory)}; return DIFile(MDNode::get(VMContext, Elts)); } DIEnumerator DIBuilder::createEnumerator(StringRef Name, int64_t Val) { assert(!Name.empty() && "Unable to create enumerator without name"); - Value *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_enumerator).concat(Name).concat(Val).get( - VMContext)}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_enumerator) + .concat(Name) + .concat(Val) + .get(VMContext)}; return DIEnumerator(MDNode::get(VMContext, Elts)); } @@ -225,7 +252,7 @@ DIBasicType DIBuilder::createUnspecifiedType(StringRef Name) { assert(!Name.empty() && "Unable to create type without name"); // Unspecified types are encoded in DIBasicType format. Line number, filename, // size, alignment, offset and flags are always empty here. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_unspecified_type) .concat(Name) .concat(0) @@ -251,7 +278,7 @@ DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, assert(!Name.empty() && "Unable to create type without name"); // Basic types are encoded in DIBasicType format. Line number, filename, // offset and flags are always empty here. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_base_type) .concat(Name) .concat(0) // Line @@ -269,17 +296,17 @@ DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, DIDerivedType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) { // Qualified types are encoded in DIDerivedType format. - Value *Elts[] = {HeaderBuilder::get(Tag) - .concat(StringRef()) // Name - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, // Filename - nullptr, // Unused - FromTy.getRef()}; + Metadata *Elts[] = {HeaderBuilder::get(Tag) + .concat(StringRef()) // Name + .concat(0) // Line + .concat(0) // Size + .concat(0) // Align + .concat(0) // Offset + .concat(0) // Flags + .get(VMContext), + nullptr, // Filename + nullptr, // Unused + FromTy.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -287,68 +314,68 @@ DIDerivedType DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits, uint64_t AlignInBits, StringRef Name) { // Pointer types are encoded in DIDerivedType format. - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_pointer_type) - .concat(Name) - .concat(0) // Line - .concat(SizeInBits) - .concat(AlignInBits) - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, // Filename - nullptr, // Unused - PointeeTy.getRef()}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_pointer_type) + .concat(Name) + .concat(0) // Line + .concat(SizeInBits) + .concat(AlignInBits) + .concat(0) // Offset + .concat(0) // Flags + .get(VMContext), + nullptr, // Filename + nullptr, // Unused + PointeeTy.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); } DIDerivedType DIBuilder::createMemberPointerType(DIType PointeeTy, DIType Base) { // Pointer types are encoded in DIDerivedType format. - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_ptr_to_member_type) - .concat(StringRef()) - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, // Filename - nullptr, // Unused - PointeeTy.getRef(), Base.getRef()}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_ptr_to_member_type) + .concat(StringRef()) + .concat(0) // Line + .concat(0) // Size + .concat(0) // Align + .concat(0) // Offset + .concat(0) // Flags + .get(VMContext), + nullptr, // Filename + nullptr, // Unused + PointeeTy.getRef(), Base.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); } DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) { assert(RTy.isType() && "Unable to create reference type"); // References are encoded in DIDerivedType format. - Value *Elts[] = {HeaderBuilder::get(Tag) - .concat(StringRef()) // Name - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, // Filename - nullptr, // TheCU, - RTy.getRef()}; + Metadata *Elts[] = {HeaderBuilder::get(Tag) + .concat(StringRef()) // Name + .concat(0) // Line + .concat(0) // Size + .concat(0) // Align + .concat(0) // Offset + .concat(0) // Flags + .get(VMContext), + nullptr, // Filename + nullptr, // TheCU, + RTy.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); } DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File, unsigned LineNo, DIDescriptor Context) { // typedefs are encoded in DIDerivedType format. - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_typedef) - .concat(Name) - .concat(LineNo) - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - File.getFileNode(), - DIScope(getNonCompileUnitScope(Context)).getRef(), - Ty.getRef()}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_typedef) + .concat(Name) + .concat(LineNo) + .concat(0) // Size + .concat(0) // Align + .concat(0) // Offset + .concat(0) // Flags + .get(VMContext), + File.getFileNode(), + DIScope(getNonCompileUnitScope(Context)).getRef(), + Ty.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -356,15 +383,15 @@ DIDerivedType DIBuilder::createFriend(DIType Ty, DIType FriendTy) { // typedefs are encoded in DIDerivedType format. assert(Ty.isType() && "Invalid type!"); assert(FriendTy.isType() && "Invalid friend type!"); - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_friend) - .concat(StringRef()) // Name - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, Ty.getRef(), FriendTy.getRef()}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_friend) + .concat(StringRef()) // Name + .concat(0) // Line + .concat(0) // Size + .concat(0) // Align + .concat(0) // Offset + .concat(0) // Flags + .get(VMContext), + nullptr, Ty.getRef(), FriendTy.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -373,15 +400,15 @@ DIDerivedType DIBuilder::createInheritance(DIType Ty, DIType BaseTy, unsigned Flags) { assert(Ty.isType() && "Unable to create inheritance"); // TAG_inheritance is encoded in DIDerivedType format. - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_inheritance) - .concat(StringRef()) // Name - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(BaseOffset) - .concat(Flags) - .get(VMContext), - nullptr, Ty.getRef(), BaseTy.getRef()}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_inheritance) + .concat(StringRef()) // Name + .concat(0) // Line + .concat(0) // Size + .concat(0) // Align + .concat(BaseOffset) + .concat(Flags) + .get(VMContext), + nullptr, Ty.getRef(), BaseTy.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -392,20 +419,26 @@ DIDerivedType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, uint64_t OffsetInBits, unsigned Flags, DIType Ty) { // TAG_member is encoded in DIDerivedType format. - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) - .concat(Name) - .concat(LineNumber) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(OffsetInBits) - .concat(Flags) - .get(VMContext), - File.getFileNode(), - DIScope(getNonCompileUnitScope(Scope)).getRef(), - Ty.getRef()}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) + .concat(Name) + .concat(LineNumber) + .concat(SizeInBits) + .concat(AlignInBits) + .concat(OffsetInBits) + .concat(Flags) + .get(VMContext), + File.getFileNode(), + DIScope(getNonCompileUnitScope(Scope)).getRef(), + Ty.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); } +static Metadata *getConstantOrNull(Constant *C) { + if (C) + return ConstantAsMetadata::get(C); + return nullptr; +} + DIDerivedType DIBuilder::createStaticMemberType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, DIType Ty, @@ -413,17 +446,17 @@ DIDerivedType DIBuilder::createStaticMemberType(DIDescriptor Scope, llvm::Constant *Val) { // TAG_member is encoded in DIDerivedType format. Flags |= DIDescriptor::FlagStaticMember; - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) - .concat(Name) - .concat(LineNumber) - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(Flags) - .get(VMContext), - File.getFileNode(), - DIScope(getNonCompileUnitScope(Scope)).getRef(), Ty.getRef(), - Val}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) + .concat(Name) + .concat(LineNumber) + .concat(0) // Size + .concat(0) // Align + .concat(0) // Offset + .concat(Flags) + .get(VMContext), + File.getFileNode(), + DIScope(getNonCompileUnitScope(Scope)).getRef(), + Ty.getRef(), getConstantOrNull(Val)}; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -434,16 +467,16 @@ DIDerivedType DIBuilder::createObjCIVar(StringRef Name, DIFile File, uint64_t OffsetInBits, unsigned Flags, DIType Ty, MDNode *PropertyNode) { // TAG_member is encoded in DIDerivedType format. - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) - .concat(Name) - .concat(LineNumber) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(OffsetInBits) - .concat(Flags) - .get(VMContext), - File.getFileNode(), getNonCompileUnitScope(File), Ty, - PropertyNode}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) + .concat(Name) + .concat(LineNumber) + .concat(SizeInBits) + .concat(AlignInBits) + .concat(OffsetInBits) + .concat(Flags) + .get(VMContext), + File.getFileNode(), getNonCompileUnitScope(File), Ty, + PropertyNode}; return DIDerivedType(MDNode::get(VMContext, Elts)); } @@ -451,14 +484,14 @@ DIObjCProperty DIBuilder::createObjCProperty(StringRef Name, DIFile File, unsigned LineNumber, StringRef GetterName, StringRef SetterName, unsigned PropertyAttributes, DIType Ty) { - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_APPLE_property) - .concat(Name) - .concat(LineNumber) - .concat(GetterName) - .concat(SetterName) - .concat(PropertyAttributes) - .get(VMContext), - File, Ty}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_APPLE_property) + .concat(Name) + .concat(LineNumber) + .concat(GetterName) + .concat(SetterName) + .concat(PropertyAttributes) + .get(VMContext), + File, Ty}; return DIObjCProperty(MDNode::get(VMContext, Elts)); } @@ -466,24 +499,23 @@ DITemplateTypeParameter DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name, DIType Ty, MDNode *File, unsigned LineNo, unsigned ColumnNo) { - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_template_type_parameter) - .concat(Name) - .concat(LineNo) - .concat(ColumnNo) - .get(VMContext), - DIScope(getNonCompileUnitScope(Context)).getRef(), - Ty.getRef(), File}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_template_type_parameter) + .concat(Name) + .concat(LineNo) + .concat(ColumnNo) + .get(VMContext), + DIScope(getNonCompileUnitScope(Context)).getRef(), + Ty.getRef(), File}; return DITemplateTypeParameter(MDNode::get(VMContext, Elts)); } static DITemplateValueParameter createTemplateValueParameterHelper( LLVMContext &VMContext, unsigned Tag, DIDescriptor Context, StringRef Name, - DIType Ty, Value *Val, MDNode *File, unsigned LineNo, unsigned ColumnNo) { - Value *Elts[] = { + DIType Ty, Metadata *MD, MDNode *File, unsigned LineNo, unsigned ColumnNo) { + Metadata *Elts[] = { HeaderBuilder::get(Tag).concat(Name).concat(LineNo).concat(ColumnNo).get( VMContext), - DIScope(getNonCompileUnitScope(Context)).getRef(), Ty.getRef(), Val, - File}; + DIScope(getNonCompileUnitScope(Context)).getRef(), Ty.getRef(), MD, File}; return DITemplateValueParameter(MDNode::get(VMContext, Elts)); } @@ -492,8 +524,8 @@ DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name, DIType Ty, Constant *Val, MDNode *File, unsigned LineNo, unsigned ColumnNo) { return createTemplateValueParameterHelper( - VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty, Val, - File, LineNo, ColumnNo); + VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty, + getConstantOrNull(Val), File, LineNo, ColumnNo); } DITemplateValueParameter @@ -529,7 +561,7 @@ DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, assert((!Context || Context.isScope() || Context.isType()) && "createClassType should be called with a valid Context"); // TAG_class_type is encoded in DICompositeType format. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_class_type) .concat(Name) .concat(LineNumber) @@ -562,7 +594,7 @@ DICompositeType DIBuilder::createStructType(DIDescriptor Context, DIType VTableHolder, StringRef UniqueIdentifier) { // TAG_structure_type is encoded in DICompositeType format. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_structure_type) .concat(Name) .concat(LineNumber) @@ -592,7 +624,7 @@ DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, unsigned RunTimeLang, StringRef UniqueIdentifier) { // TAG_union_type is encoded in DICompositeType format. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_union_type) .concat(Name) .concat(LineNumber) @@ -616,7 +648,7 @@ DISubroutineType DIBuilder::createSubroutineType(DIFile File, DITypeArray ParameterTypes, unsigned Flags) { // TAG_subroutine_type is encoded in DICompositeType format. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_subroutine_type) .concat(StringRef()) .concat(0) // Line @@ -637,7 +669,7 @@ DICompositeType DIBuilder::createEnumerationType( uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements, DIType UnderlyingType, StringRef UniqueIdentifier) { // TAG_enumeration_type is encoded in DICompositeType format. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_enumeration_type) .concat(Name) .concat(LineNumber) @@ -661,7 +693,7 @@ DICompositeType DIBuilder::createEnumerationType( DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, DIType Ty, DIArray Subscripts) { // TAG_array_type is encoded in DICompositeType format. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_array_type) .concat(StringRef()) .concat(0) // Line @@ -682,7 +714,7 @@ DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, DICompositeType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, DIType Ty, DIArray Subscripts) { // A vector is an array type with the FlagVector flag applied. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_array_type) .concat("") .concat(0) // Line @@ -716,7 +748,7 @@ static HeaderBuilder setTypeFlagsInHeader(StringRef Header, static DIType createTypeWithFlags(LLVMContext &Context, DIType Ty, unsigned FlagsToSet) { - SmallVector Elts; + SmallVector Elts; MDNode *N = Ty; assert(N && "Unexpected input DIType!"); // Update header field. @@ -740,9 +772,7 @@ DIType DIBuilder::createObjectPointerType(DIType Ty) { return createTypeWithFlags(VMContext, Ty, Flags); } -void DIBuilder::retainType(DIType T) { - AllRetainTypes.push_back(TrackingVH(T)); -} +void DIBuilder::retainType(DIType T) { AllRetainTypes.emplace_back(T); } DIBasicType DIBuilder::createUnspecifiedParameter() { return DIBasicType(); @@ -754,7 +784,7 @@ DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, uint64_t SizeInBits, uint64_t AlignInBits, StringRef UniqueIdentifier) { // Create a temporary MDNode. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(Tag) .concat(Name) .concat(Line) @@ -783,7 +813,7 @@ DICompositeType DIBuilder::createReplaceableForwardDecl( unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits, StringRef UniqueIdentifier) { // Create a temporary MDNode. - Value *Elts[] = { + Metadata *Elts[] = { HeaderBuilder::get(Tag) .concat(Name) .concat(Line) @@ -798,8 +828,7 @@ DICompositeType DIBuilder::createReplaceableForwardDecl( nullptr, // TemplateParams UniqueIdentifier.empty() ? nullptr : MDString::get(VMContext, UniqueIdentifier)}; - MDNode *Node = MDNode::getTemporary(VMContext, Elts); - DICompositeType RetTy(Node); + DICompositeType RetTy(MDNode::getTemporary(VMContext, Elts)); assert(RetTy.isCompositeType() && "createReplaceableForwardDecl result should be a DIType"); if (!UniqueIdentifier.empty()) @@ -807,12 +836,12 @@ DICompositeType DIBuilder::createReplaceableForwardDecl( return RetTy; } -DIArray DIBuilder::getOrCreateArray(ArrayRef Elements) { +DIArray DIBuilder::getOrCreateArray(ArrayRef Elements) { return DIArray(MDNode::get(VMContext, Elements)); } -DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef Elements) { - SmallVector Elts; +DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef Elements) { + SmallVector Elts; for (unsigned i = 0, e = Elements.size(); i != e; ++i) { if (Elements[i] && isa(Elements[i])) Elts.push_back(DIType(cast(Elements[i])).getRef()); @@ -823,10 +852,10 @@ DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef Elements) { } DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) { - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subrange_type) - .concat(Lo) - .concat(Count) - .get(VMContext)}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subrange_type) + .concat(Lo) + .concat(Count) + .get(VMContext)}; return DISubrange(MDNode::get(VMContext, Elts)); } @@ -835,7 +864,7 @@ static DIGlobalVariable createGlobalVariableHelper( LLVMContext &VMContext, DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F, unsigned LineNumber, DITypeRef Ty, bool isLocalToUnit, Constant *Val, MDNode *Decl, bool isDefinition, - std::function)> CreateFunc) { + std::function)> CreateFunc) { MDNode *TheCtx = getNonCompileUnitScope(Context); if (DIScope(TheCtx).isCompositeType()) { @@ -843,16 +872,16 @@ static DIGlobalVariable createGlobalVariableHelper( "Context of a global variable should not be a type with identifier"); } - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_variable) - .concat(Name) - .concat(Name) - .concat(LinkageName) - .concat(LineNumber) - .concat(isLocalToUnit) - .concat(isDefinition) - .get(VMContext), - TheCtx, F, Ty, Val, - DIDescriptor(Decl)}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_variable) + .concat(Name) + .concat(Name) + .concat(LinkageName) + .concat(LineNumber) + .concat(isLocalToUnit) + .concat(isDefinition) + .get(VMContext), + TheCtx, F, Ty, getConstantOrNull(Val), + DIDescriptor(Decl)}; return DIGlobalVariable(CreateFunc(Elts)); } @@ -861,13 +890,13 @@ DIGlobalVariable DIBuilder::createGlobalVariable( DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F, unsigned LineNumber, DITypeRef Ty, bool isLocalToUnit, Constant *Val, MDNode *Decl) { - return createGlobalVariableHelper(VMContext, Context, Name, LinkageName, F, - LineNumber, Ty, isLocalToUnit, Val, Decl, true, - [&] (ArrayRef Elts) -> MDNode * { - MDNode *Node = MDNode::get(VMContext, Elts); - AllGVs.push_back(Node); - return Node; - }); + return createGlobalVariableHelper( + VMContext, Context, Name, LinkageName, F, LineNumber, Ty, isLocalToUnit, + Val, Decl, true, [&](ArrayRef Elts) -> MDNode *{ + MDNode *Node = MDNode::get(VMContext, Elts); + AllGVs.push_back(Node); + return Node; + }); } DIGlobalVariable DIBuilder::createTempGlobalVariableFwdDecl( @@ -875,10 +904,10 @@ DIGlobalVariable DIBuilder::createTempGlobalVariableFwdDecl( unsigned LineNumber, DITypeRef Ty, bool isLocalToUnit, Constant *Val, MDNode *Decl) { return createGlobalVariableHelper(VMContext, Context, Name, LinkageName, F, - LineNumber, Ty, isLocalToUnit, Val, Decl, false, - [&] (ArrayRef Elts) { - return MDNode::getTemporary(VMContext, Elts); - }); + LineNumber, Ty, isLocalToUnit, Val, Decl, + false, [&](ArrayRef Elts) { + return MDNode::getTemporary(VMContext, Elts); + }); } DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, @@ -889,12 +918,12 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, DIDescriptor Context(getNonCompileUnitScope(Scope)); assert((!Context || Context.isScope()) && "createLocalVariable should be called with a valid Context"); - Value *Elts[] = {HeaderBuilder::get(Tag) - .concat(Name) - .concat(LineNo | (ArgNo << 24)) - .concat(Flags) - .get(VMContext), - getNonCompileUnitScope(Scope), File, Ty}; + Metadata *Elts[] = {HeaderBuilder::get(Tag) + .concat(Name) + .concat(LineNo | (ArgNo << 24)) + .concat(Flags) + .get(VMContext), + getNonCompileUnitScope(Scope), File, Ty}; MDNode *Node = MDNode::get(VMContext, Elts); if (AlwaysPreserve) { // The optimizer may remove local variable. If there is an interest @@ -902,7 +931,7 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, // named mdnode. DISubprogram Fn(getDISubprogram(Scope)); assert(Fn && "Missing subprogram for local variable"); - PreservedVariables[Fn].push_back(Node); + PreservedVariables[Fn].emplace_back(Node); } DIVariable RetVar(Node); assert(RetVar.isVariable() && @@ -914,7 +943,7 @@ DIExpression DIBuilder::createExpression(ArrayRef Addr) { auto Header = HeaderBuilder::get(DW_TAG_expression); for (int64_t I : Addr) Header.concat(I); - Value *Elts[] = {Header.get(VMContext)}; + Metadata *Elts[] = {Header.get(VMContext)}; return DIExpression(MDNode::get(VMContext, Elts)); } @@ -939,31 +968,30 @@ DISubprogram DIBuilder::createFunction(DIScopeRef Context, StringRef Name, Flags, isOptimized, Fn, TParams, Decl); } -static DISubprogram -createFunctionHelper(LLVMContext &VMContext, DIDescriptor Context, StringRef Name, - StringRef LinkageName, DIFile File, unsigned LineNo, - DICompositeType Ty, bool isLocalToUnit, bool isDefinition, - unsigned ScopeLine, unsigned Flags, bool isOptimized, - Function *Fn, MDNode *TParams, MDNode *Decl, MDNode *Vars, - std::function)> CreateFunc) { +static DISubprogram createFunctionHelper( + LLVMContext &VMContext, DIDescriptor Context, StringRef Name, + StringRef LinkageName, DIFile File, unsigned LineNo, DICompositeType Ty, + bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags, + bool isOptimized, Function *Fn, MDNode *TParams, MDNode *Decl, MDNode *Vars, + std::function)> CreateFunc) { assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && "function types should be subroutines"); - Value *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_subprogram) - .concat(Name) - .concat(Name) - .concat(LinkageName) - .concat(LineNo) - .concat(isLocalToUnit) - .concat(isDefinition) - .concat(0) - .concat(0) - .concat(Flags) - .concat(isOptimized) - .concat(ScopeLine) - .get(VMContext), - File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), Ty, - nullptr, Fn, TParams, Decl, Vars}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subprogram) + .concat(Name) + .concat(Name) + .concat(LinkageName) + .concat(LineNo) + .concat(isLocalToUnit) + .concat(isDefinition) + .concat(0) + .concat(0) + .concat(Flags) + .concat(isOptimized) + .concat(ScopeLine) + .get(VMContext), + File.getFileNode(), + DIScope(getNonCompileUnitScope(Context)).getRef(), Ty, + nullptr, getConstantOrNull(Fn), TParams, Decl, Vars}; DISubprogram S(CreateFunc(Elts)); assert(S.isSubprogram() && @@ -980,17 +1008,17 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, bool isOptimized, Function *Fn, MDNode *TParams, MDNode *Decl) { return createFunctionHelper(VMContext, Context, Name, LinkageName, File, - LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine, - Flags, isOptimized, Fn, TParams, Decl, + LineNo, Ty, isLocalToUnit, isDefinition, + ScopeLine, Flags, isOptimized, Fn, TParams, Decl, MDNode::getTemporary(VMContext, None), - [&] (ArrayRef Elts) -> MDNode *{ - MDNode *Node = MDNode::get(VMContext, Elts); - // Create a named metadata so that we - // do not lose this mdnode. - if (isDefinition) - AllSubprograms.push_back(Node); - return Node; - }); + [&](ArrayRef Elts) -> MDNode *{ + MDNode *Node = MDNode::get(VMContext, Elts); + // Create a named metadata so that we + // do not lose this mdnode. + if (isDefinition) + AllSubprograms.push_back(Node); + return Node; + }); } DISubprogram @@ -1002,11 +1030,11 @@ DIBuilder::createTempFunctionFwdDecl(DIDescriptor Context, StringRef Name, bool isOptimized, Function *Fn, MDNode *TParams, MDNode *Decl) { return createFunctionHelper(VMContext, Context, Name, LinkageName, File, - LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine, - Flags, isOptimized, Fn, TParams, Decl, nullptr, - [&] (ArrayRef Elts) { - return MDNode::getTemporary(VMContext, Elts); - }); + LineNo, Ty, isLocalToUnit, isDefinition, + ScopeLine, Flags, isOptimized, Fn, TParams, Decl, + nullptr, [&](ArrayRef Elts) { + return MDNode::getTemporary(VMContext, Elts); + }); } DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, @@ -1022,22 +1050,23 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, assert(getNonCompileUnitScope(Context) && "Methods should have both a Context and a context that isn't " "the compile unit."); - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subprogram) - .concat(Name) - .concat(Name) - .concat(LinkageName) - .concat(LineNo) - .concat(isLocalToUnit) - .concat(isDefinition) - .concat(VK) - .concat(VIndex) - .concat(Flags) - .concat(isOptimized) - .concat(LineNo) - // FIXME: Do we want to use different scope/lines? - .get(VMContext), - F.getFileNode(), DIScope(Context).getRef(), Ty, - VTableHolder.getRef(), Fn, TParam, nullptr, nullptr}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subprogram) + .concat(Name) + .concat(Name) + .concat(LinkageName) + .concat(LineNo) + .concat(isLocalToUnit) + .concat(isDefinition) + .concat(VK) + .concat(VIndex) + .concat(Flags) + .concat(isOptimized) + .concat(LineNo) + // FIXME: Do we want to use different scope/lines? + .get(VMContext), + F.getFileNode(), DIScope(Context).getRef(), Ty, + VTableHolder.getRef(), getConstantOrNull(Fn), TParam, + nullptr, nullptr}; MDNode *Node = MDNode::get(VMContext, Elts); if (isDefinition) AllSubprograms.push_back(Node); @@ -1048,11 +1077,11 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNo) { - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_namespace) - .concat(Name) - .concat(LineNo) - .get(VMContext), - File.getFileNode(), getNonCompileUnitScope(Scope)}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_namespace) + .concat(Name) + .concat(LineNo) + .get(VMContext), + File.getFileNode(), getNonCompileUnitScope(Scope)}; DINameSpace R(MDNode::get(VMContext, Elts)); assert(R.Verify() && "createNameSpace should return a verifiable DINameSpace"); @@ -1062,10 +1091,10 @@ DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name, DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope, DIFile File, unsigned Discriminator) { - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block) - .concat(Discriminator) - .get(VMContext), - File.getFileNode(), Scope}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block) + .concat(Discriminator) + .get(VMContext), + File.getFileNode(), Scope}; DILexicalBlockFile R(MDNode::get(VMContext, Elts)); assert( R.Verify() && @@ -1084,41 +1113,52 @@ DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, // Defeat MDNode uniquing for lexical blocks by using unique id. static unsigned int unique_id = 0; - Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block) - .concat(Line) - .concat(Col) - .concat(unique_id++) - .get(VMContext), - File.getFileNode(), getNonCompileUnitScope(Scope)}; + Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block) + .concat(Line) + .concat(Col) + .concat(unique_id++) + .get(VMContext), + File.getFileNode(), getNonCompileUnitScope(Scope)}; DILexicalBlock R(MDNode::get(VMContext, Elts)); assert(R.Verify() && "createLexicalBlock should return a verifiable DILexicalBlock"); return R; } +static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) { + assert(V && "no value passed to dbg intrinsic"); + return MetadataAsValue::get(VMContext, ValueAsMetadata::get(V)); +} + Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, DIExpression Expr, Instruction *InsertBefore) { - assert(Storage && "no storage passed to dbg.declare"); assert(VarInfo.isVariable() && "empty or invalid DIVariable passed to dbg.declare"); if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Args[] = {MDNode::get(Storage->getContext(), Storage), VarInfo, Expr}; + trackIfUnresolved(VarInfo); + trackIfUnresolved(Expr); + Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, Storage), + MetadataAsValue::get(VMContext, VarInfo), + MetadataAsValue::get(VMContext, Expr)}; return CallInst::Create(DeclareFn, Args, "", InsertBefore); } Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, DIExpression Expr, BasicBlock *InsertAtEnd) { - assert(Storage && "no storage passed to dbg.declare"); assert(VarInfo.isVariable() && "empty or invalid DIVariable passed to dbg.declare"); if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Args[] = {MDNode::get(Storage->getContext(), Storage), VarInfo, Expr}; + trackIfUnresolved(VarInfo); + trackIfUnresolved(Expr); + Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, Storage), + MetadataAsValue::get(VMContext, VarInfo), + MetadataAsValue::get(VMContext, Expr)}; // If this block already has a terminator then insert this intrinsic // before the terminator. @@ -1138,9 +1178,12 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); - Value *Args[] = {MDNode::get(V->getContext(), V), - ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), - VarInfo, Expr}; + trackIfUnresolved(VarInfo); + trackIfUnresolved(Expr); + Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, V), + ConstantInt::get(Type::getInt64Ty(VMContext), Offset), + MetadataAsValue::get(VMContext, VarInfo), + MetadataAsValue::get(VMContext, Expr)}; return CallInst::Create(ValueFn, Args, "", InsertBefore); } @@ -1154,8 +1197,11 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); - Value *Args[] = {MDNode::get(V->getContext(), V), - ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), - VarInfo, Expr}; + trackIfUnresolved(VarInfo); + trackIfUnresolved(Expr); + Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, V), + ConstantInt::get(Type::getInt64Ty(VMContext), Offset), + MetadataAsValue::get(VMContext, VarInfo), + MetadataAsValue::get(VMContext, Expr)}; return CallInst::Create(ValueFn, Args, "", InsertAtEnd); } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index c6e4c872c1bf..c31cd6dd9153 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -52,7 +52,7 @@ bool DIDescriptor::Verify() const { DIImportedEntity(DbgNode).Verify() || DIExpression(DbgNode).Verify()); } -static Value *getField(const MDNode *DbgNode, unsigned Elt) { +static Metadata *getField(const MDNode *DbgNode, unsigned Elt) { if (!DbgNode || Elt >= DbgNode->getNumOperands()) return nullptr; return DbgNode->getOperand(Elt); @@ -73,25 +73,17 @@ StringRef DIDescriptor::getStringField(unsigned Elt) const { } uint64_t DIDescriptor::getUInt64Field(unsigned Elt) const { - if (!DbgNode) - return 0; - - if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI = - dyn_cast_or_null(DbgNode->getOperand(Elt))) + if (auto *C = getConstantField(Elt)) + if (ConstantInt *CI = dyn_cast(C)) return CI->getZExtValue(); return 0; } int64_t DIDescriptor::getInt64Field(unsigned Elt) const { - if (!DbgNode) - return 0; - - if (Elt < DbgNode->getNumOperands()) - if (ConstantInt *CI = - dyn_cast_or_null(DbgNode->getOperand(Elt))) - return CI->getSExtValue(); + if (auto *C = getConstantField(Elt)) + if (ConstantInt *CI = dyn_cast(C)) + return CI->getZExtValue(); return 0; } @@ -102,12 +94,7 @@ DIDescriptor DIDescriptor::getDescriptorField(unsigned Elt) const { } GlobalVariable *DIDescriptor::getGlobalVariableField(unsigned Elt) const { - if (!DbgNode) - return nullptr; - - if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null(DbgNode->getOperand(Elt)); - return nullptr; + return dyn_cast_or_null(getConstantField(Elt)); } Constant *DIDescriptor::getConstantField(unsigned Elt) const { @@ -115,17 +102,14 @@ Constant *DIDescriptor::getConstantField(unsigned Elt) const { return nullptr; if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null(DbgNode->getOperand(Elt)); + if (auto *C = + dyn_cast_or_null(DbgNode->getOperand(Elt))) + return C->getValue(); return nullptr; } Function *DIDescriptor::getFunctionField(unsigned Elt) const { - if (!DbgNode) - return nullptr; - - if (Elt < DbgNode->getNumOperands()) - return dyn_cast_or_null(DbgNode->getOperand(Elt)); - return nullptr; + return dyn_cast_or_null(getConstantField(Elt)); } void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { @@ -134,7 +118,7 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { if (Elt < DbgNode->getNumOperands()) { MDNode *Node = const_cast(DbgNode); - Node->replaceOperandWith(Elt, F); + Node->replaceOperandWith(Elt, F ? ConstantAsMetadata::get(F) : nullptr); } } @@ -347,27 +331,23 @@ void DIDescriptor::replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D) { // itself. const MDNode *DN = D; if (DbgNode == DN) { - SmallVector Ops(DbgNode->getNumOperands()); + SmallVector Ops(DbgNode->getNumOperands()); for (size_t i = 0; i != Ops.size(); ++i) Ops[i] = DbgNode->getOperand(i); DN = MDNode::get(VMContext, Ops); } - MDNode *Node = const_cast(DbgNode); - const Value *V = cast_or_null(DN); - Node->replaceAllUsesWith(const_cast(V)); + auto *Node = cast(const_cast(DbgNode)); + Node->replaceAllUsesWith(const_cast(DN)); MDNode::deleteTemporary(Node); DbgNode = DN; } void DIDescriptor::replaceAllUsesWith(MDNode *D) { - assert(DbgNode && "Trying to replace an unverified type!"); assert(DbgNode != D && "This replacement should always happen"); - MDNode *Node = const_cast(DbgNode); - const MDNode *DN = D; - const Value *V = cast_or_null(DN); - Node->replaceAllUsesWith(const_cast(V)); + auto *Node = cast(const_cast(DbgNode)); + Node->replaceAllUsesWith(D); MDNode::deleteTemporary(Node); } @@ -398,7 +378,7 @@ bool DIObjCProperty::Verify() const { static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) { // FIXME: This function should return true, if the field is null or the field // is indeed a MDNode: return !Fld || isa(Fld). - Value *Fld = getField(DbgNode, Elt); + Metadata *Fld = getField(DbgNode, Elt); if (Fld && isa(Fld) && !cast(Fld)->getString().empty()) return false; return true; @@ -406,7 +386,7 @@ static bool fieldIsMDNode(const MDNode *DbgNode, unsigned Elt) { /// \brief Check if a field at position Elt of a MDNode is a MDString. static bool fieldIsMDString(const MDNode *DbgNode, unsigned Elt) { - Value *Fld = getField(DbgNode, Elt); + Metadata *Fld = getField(DbgNode, Elt); return !Fld || isa(Fld); } @@ -533,7 +513,6 @@ bool DISubprogram::Verify() const { // If a DISubprogram has an llvm::Function*, then scope chains from all // instructions within the function should lead to this DISubprogram. if (auto *F = getFunction()) { - LLVMContext &Ctxt = F->getContext(); for (auto &BB : *F) { for (auto &I : BB) { DebugLoc DL = I.getDebugLoc(); @@ -543,15 +522,15 @@ bool DISubprogram::Verify() const { MDNode *Scope = nullptr; MDNode *IA = nullptr; // walk the inlined-at scopes - while (DL.getScopeAndInlinedAt(Scope, IA, F->getContext()), IA) + while ((IA = DL.getInlinedAt())) DL = DebugLoc::getFromDILocation(IA); - DL.getScopeAndInlinedAt(Scope, IA, Ctxt); + DL.getScopeAndInlinedAt(Scope, IA); assert(!IA); while (!DIDescriptor(Scope).isSubprogram()) { DILexicalBlockFile D(Scope); Scope = D.isLexicalBlockFile() ? D.getScope() - : DebugLoc::getFromDILexicalBlock(Scope).getScope(Ctxt); + : DebugLoc::getFromDILexicalBlock(Scope).getScope(); } if (!DISubprogram(Scope).describes(F)) return false; @@ -678,7 +657,7 @@ MDString *DICompositeType::getIdentifier() const { static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) { for (unsigned i = 0; i != LHS->getNumOperands(); ++i) { // Skip the 'empty' list (that's a single i32 0, rather than truly empty). - if (i == 0 && isa(LHS->getOperand(i))) + if (i == 0 && mdconst::hasa(LHS->getOperand(i))) continue; const MDNode *E = cast(LHS->getOperand(i)); bool found = false; @@ -690,7 +669,7 @@ static void VerifySubsetOf(const MDNode *LHS, const MDNode *RHS) { #endif void DICompositeType::setArraysHelper(MDNode *Elements, MDNode *TParams) { - TrackingVH N(*this); + TrackingMDNodeRef N(*this); if (Elements) { #ifndef NDEBUG // Check that the new list of members contains all the old members as well. @@ -714,7 +693,7 @@ DIScopeRef DIScope::getRef() const { } void DICompositeType::setContainingType(DICompositeType ContainingType) { - TrackingVH N(*this); + TrackingMDNodeRef N(*this); N->replaceOperandWith(5, ContainingType.getRef()); DbgNode = N; } @@ -748,8 +727,8 @@ DIArray DISubprogram::getVariables() const { return DIArray(getNodeField(DbgNode, 8)); } -Value *DITemplateValueParameter::getValue() const { - return getField(DbgNode, 3); +Metadata *DITemplateValueParameter::getValue() const { + return DbgNode->getOperand(3); } DIScopeRef DIScope::getContext() const { @@ -851,7 +830,7 @@ void DICompileUnit::replaceGlobalVariables(DIArray GlobalVariables) { DILocation DILocation::copyWithNewScope(LLVMContext &Ctx, DILexicalBlockFile NewScope) { - SmallVector Elts; + SmallVector Elts; assert(Verify()); for (unsigned I = 0; I < DbgNode->getNumOperands(); ++I) { if (I != 2) @@ -875,7 +854,7 @@ DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope, return cleanseInlinedVariable(DV, VMContext); // Insert inlined scope. - SmallVector Elts; + SmallVector Elts; for (unsigned I = 0, E = DIVariableInlinedAtIndex; I != E; ++I) Elts.push_back(DV->getOperand(I)); Elts.push_back(InlinedScope); @@ -891,7 +870,7 @@ DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { return DIVariable(DV); // Remove inlined scope. - SmallVector Elts; + SmallVector Elts; for (unsigned I = 0, E = DIVariableInlinedAtIndex; I != E; ++I) Elts.push_back(DV->getOperand(I)); @@ -923,7 +902,7 @@ DISubprogram llvm::getDISubprogram(const Function *F) { if (Inst == BB.end()) continue; DebugLoc DLoc = Inst->getDebugLoc(); - const MDNode *Scope = DLoc.getScopeNode(F->getParent()->getContext()); + const MDNode *Scope = DLoc.getScopeNode(); DISubprogram Subprogram = getDISubprogram(Scope); return Subprogram.describes(F) ? Subprogram : DISubprogram(); } @@ -1533,10 +1512,10 @@ bool llvm::StripDebugInfo(Module &M) { } unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) { - Value *Val = M.getModuleFlag("Debug Info Version"); - if (!Val) - return 0; - return cast(Val)->getZExtValue(); + if (auto *Val = mdconst::extract_or_null( + M.getModuleFlag("Debug Info Version"))) + return Val->getZExtValue(); + return 0; } llvm::DenseMap diff --git a/llvm/lib/IR/DebugLoc.cpp b/llvm/lib/IR/DebugLoc.cpp index 718da852fec3..88f2dbc5410c 100644 --- a/llvm/lib/IR/DebugLoc.cpp +++ b/llvm/lib/IR/DebugLoc.cpp @@ -17,67 +17,29 @@ using namespace llvm; // DebugLoc Implementation //===----------------------------------------------------------------------===// -MDNode *DebugLoc::getScope(const LLVMContext &Ctx) const { - if (ScopeIdx == 0) return nullptr; - - if (ScopeIdx > 0) { - // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at - // position specified. - assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() && - "Invalid ScopeIdx!"); - return Ctx.pImpl->ScopeRecords[ScopeIdx-1].get(); - } - - // Otherwise, the index is in the ScopeInlinedAtRecords array. - assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() && - "Invalid ScopeIdx"); - return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get(); -} +unsigned DebugLoc::getLine() const { return DILocation(Loc).getLineNumber(); } +unsigned DebugLoc::getCol() const { return DILocation(Loc).getColumnNumber(); } -MDNode *DebugLoc::getInlinedAt(const LLVMContext &Ctx) const { - // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at - // position specified. Zero is invalid. - if (ScopeIdx >= 0) return nullptr; - - // Otherwise, the index is in the ScopeInlinedAtRecords array. - assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() && - "Invalid ScopeIdx"); - return Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get(); +MDNode *DebugLoc::getScope() const { return DILocation(Loc).getScope(); } + +MDNode *DebugLoc::getInlinedAt() const { + return DILocation(Loc).getOrigLocation(); } /// Return both the Scope and the InlinedAt values. -void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, - const LLVMContext &Ctx) const { - if (ScopeIdx == 0) { - Scope = IA = nullptr; - return; - } - - if (ScopeIdx > 0) { - // Positive ScopeIdx is an index into ScopeRecords, which has no inlined-at - // position specified. - assert(unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() && - "Invalid ScopeIdx!"); - Scope = Ctx.pImpl->ScopeRecords[ScopeIdx-1].get(); - IA = nullptr; - return; - } - - // Otherwise, the index is in the ScopeInlinedAtRecords array. - assert(unsigned(-ScopeIdx) <= Ctx.pImpl->ScopeInlinedAtRecords.size() && - "Invalid ScopeIdx"); - Scope = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].first.get(); - IA = Ctx.pImpl->ScopeInlinedAtRecords[-ScopeIdx-1].second.get(); +void DebugLoc::getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const { + Scope = getScope(); + IA = getInlinedAt(); } -MDNode *DebugLoc::getScopeNode(const LLVMContext &Ctx) const { - if (MDNode *InlinedAt = getInlinedAt(Ctx)) - return DebugLoc::getFromDILocation(InlinedAt).getScopeNode(Ctx); - return getScope(Ctx); +MDNode *DebugLoc::getScopeNode() const { + if (MDNode *InlinedAt = getInlinedAt()) + return DebugLoc::getFromDILocation(InlinedAt).getScopeNode(); + return getScope(); } -DebugLoc DebugLoc::getFnDebugLoc(const LLVMContext &Ctx) const { - const MDNode *Scope = getScopeNode(Ctx); +DebugLoc DebugLoc::getFnDebugLoc() const { + const MDNode *Scope = getScopeNode(); DISubprogram SP = getDISubprogram(Scope); if (SP.isSubprogram()) return DebugLoc::get(SP.getScopeLineNumber(), 0, SP); @@ -87,53 +49,32 @@ DebugLoc DebugLoc::getFnDebugLoc(const LLVMContext &Ctx) const { DebugLoc DebugLoc::get(unsigned Line, unsigned Col, MDNode *Scope, MDNode *InlinedAt) { - DebugLoc Result; - // If no scope is available, this is an unknown location. - if (!Scope) return Result; + if (!Scope) + return DebugLoc(); // Saturate line and col to "unknown". + // FIXME: Allow 16-bits for columns. if (Col > 255) Col = 0; if (Line >= (1 << 24)) Line = 0; - Result.LineCol = Line | (Col << 24); - - LLVMContext &Ctx = Scope->getContext(); - - // If there is no inlined-at location, use the ScopeRecords array. - if (!InlinedAt) - Result.ScopeIdx = Ctx.pImpl->getOrAddScopeRecordIdxEntry(Scope, 0); - else - Result.ScopeIdx = Ctx.pImpl->getOrAddScopeInlinedAtIdxEntry(Scope, - InlinedAt, 0); - return Result; + LLVMContext &Context = Scope->getContext(); + Type *Int32 = Type::getInt32Ty(Context); + Metadata *Elts[] = {ConstantAsMetadata::get(ConstantInt::get(Int32, Line)), + ConstantAsMetadata::get(ConstantInt::get(Int32, Col)), + Scope, InlinedAt}; + return getFromDILocation(MDNode::get(Context, Elts)); } /// getAsMDNode - This method converts the compressed DebugLoc node into a /// DILocation-compatible MDNode. -MDNode *DebugLoc::getAsMDNode(const LLVMContext &Ctx) const { - if (isUnknown()) return nullptr; - - MDNode *Scope, *IA; - getScopeAndInlinedAt(Scope, IA, Ctx); - assert(Scope && "If scope is null, this should be isUnknown()"); - - LLVMContext &Ctx2 = Scope->getContext(); - Type *Int32 = Type::getInt32Ty(Ctx2); - Value *Elts[] = { - ConstantInt::get(Int32, getLine()), ConstantInt::get(Int32, getCol()), - Scope, IA - }; - return MDNode::get(Ctx2, Elts); -} +MDNode *DebugLoc::getAsMDNode() const { return Loc; } /// getFromDILocation - Translate the DILocation quad into a DebugLoc. DebugLoc DebugLoc::getFromDILocation(MDNode *N) { - DILocation Loc(N); - MDNode *Scope = Loc.getScope(); - if (!Scope) return DebugLoc(); - return get(Loc.getLineNumber(), Loc.getColumnNumber(), Scope, - Loc.getOrigLocation()); + DebugLoc Loc; + Loc.Loc.reset(N); + return Loc; } /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc. @@ -145,26 +86,26 @@ DebugLoc DebugLoc::getFromDILexicalBlock(MDNode *N) { nullptr); } -void DebugLoc::dump(const LLVMContext &Ctx) const { +void DebugLoc::dump() const { #ifndef NDEBUG if (!isUnknown()) { dbgs() << getLine(); if (getCol() != 0) dbgs() << ',' << getCol(); - DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx)); + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt()); if (!InlinedAtDL.isUnknown()) { dbgs() << " @ "; - InlinedAtDL.dump(Ctx); + InlinedAtDL.dump(); } else dbgs() << "\n"; } #endif } -void DebugLoc::print(const LLVMContext &Ctx, raw_ostream &OS) const { +void DebugLoc::print(raw_ostream &OS) const { if (!isUnknown()) { // Print source line info. - DIScope Scope(getScope(Ctx)); + DIScope Scope(getScope()); assert((!Scope || Scope.isScope()) && "Scope of a DebugLoc should be null or a DIScope."); if (Scope) @@ -174,179 +115,11 @@ void DebugLoc::print(const LLVMContext &Ctx, raw_ostream &OS) const { OS << ':' << getLine(); if (getCol() != 0) OS << ':' << getCol(); - DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx)); + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt()); if (!InlinedAtDL.isUnknown()) { OS << " @[ "; - InlinedAtDL.print(Ctx, OS); + InlinedAtDL.print(OS); OS << " ]"; } } } - -//===----------------------------------------------------------------------===// -// DenseMap specialization -//===----------------------------------------------------------------------===// - -unsigned DenseMapInfo::getHashValue(const DebugLoc &Key) { - return static_cast(hash_combine(Key.LineCol, Key.ScopeIdx)); -} - -//===----------------------------------------------------------------------===// -// LLVMContextImpl Implementation -//===----------------------------------------------------------------------===// - -int LLVMContextImpl::getOrAddScopeRecordIdxEntry(MDNode *Scope, - int ExistingIdx) { - // If we already have an entry for this scope, return it. - int &Idx = ScopeRecordIdx[Scope]; - if (Idx) return Idx; - - // If we don't have an entry, but ExistingIdx is specified, use it. - if (ExistingIdx) - return Idx = ExistingIdx; - - // Otherwise add a new entry. - - // Start out ScopeRecords with a minimal reasonable size to avoid - // excessive reallocation starting out. - if (ScopeRecords.empty()) - ScopeRecords.reserve(128); - - // Index is biased by 1 for index. - Idx = ScopeRecords.size()+1; - ScopeRecords.push_back(DebugRecVH(Scope, this, Idx)); - return Idx; -} - -int LLVMContextImpl::getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA, - int ExistingIdx) { - // If we already have an entry, return it. - int &Idx = ScopeInlinedAtIdx[std::make_pair(Scope, IA)]; - if (Idx) return Idx; - - // If we don't have an entry, but ExistingIdx is specified, use it. - if (ExistingIdx) - return Idx = ExistingIdx; - - // Start out ScopeInlinedAtRecords with a minimal reasonable size to avoid - // excessive reallocation starting out. - if (ScopeInlinedAtRecords.empty()) - ScopeInlinedAtRecords.reserve(128); - - // Index is biased by 1 and negated. - Idx = -ScopeInlinedAtRecords.size()-1; - ScopeInlinedAtRecords.push_back(std::make_pair(DebugRecVH(Scope, this, Idx), - DebugRecVH(IA, this, Idx))); - return Idx; -} - - -//===----------------------------------------------------------------------===// -// DebugRecVH Implementation -//===----------------------------------------------------------------------===// - -/// deleted - The MDNode this is pointing to got deleted, so this pointer needs -/// to drop to null and we need remove our entry from the DenseMap. -void DebugRecVH::deleted() { - // If this is a non-canonical reference, just drop the value to null, we know - // it doesn't have a map entry. - if (Idx == 0) { - setValPtr(nullptr); - return; - } - - MDNode *Cur = get(); - - // If the index is positive, it is an entry in ScopeRecords. - if (Idx > 0) { - assert(Ctx->ScopeRecordIdx[Cur] == Idx && "Mapping out of date!"); - Ctx->ScopeRecordIdx.erase(Cur); - // Reset this VH to null and we're done. - setValPtr(nullptr); - Idx = 0; - return; - } - - // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it - // is the scope or the inlined-at record entry. - assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size()); - std::pair &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1]; - assert((this == &Entry.first || this == &Entry.second) && - "Mapping out of date!"); - - MDNode *OldScope = Entry.first.get(); - MDNode *OldInlinedAt = Entry.second.get(); - assert(OldScope && OldInlinedAt && - "Entry should be non-canonical if either val dropped to null"); - - // Otherwise, we do have an entry in it, nuke it and we're done. - assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&& - "Mapping out of date"); - Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt)); - - // Reset this VH to null. Drop both 'Idx' values to null to indicate that - // we're in non-canonical form now. - setValPtr(nullptr); - Entry.first.Idx = Entry.second.Idx = 0; -} - -void DebugRecVH::allUsesReplacedWith(Value *NewVa) { - // If being replaced with a non-mdnode value (e.g. undef) handle this as if - // the mdnode got deleted. - MDNode *NewVal = dyn_cast(NewVa); - if (!NewVal) return deleted(); - - // If this is a non-canonical reference, just change it, we know it already - // doesn't have a map entry. - if (Idx == 0) { - setValPtr(NewVa); - return; - } - - MDNode *OldVal = get(); - assert(OldVal != NewVa && "Node replaced with self?"); - - // If the index is positive, it is an entry in ScopeRecords. - if (Idx > 0) { - assert(Ctx->ScopeRecordIdx[OldVal] == Idx && "Mapping out of date!"); - Ctx->ScopeRecordIdx.erase(OldVal); - setValPtr(NewVal); - - int NewEntry = Ctx->getOrAddScopeRecordIdxEntry(NewVal, Idx); - - // If NewVal already has an entry, this becomes a non-canonical reference, - // just drop Idx to 0 to signify this. - if (NewEntry != Idx) - Idx = 0; - return; - } - - // Otherwise, it is an entry in ScopeInlinedAtRecords, we don't know if it - // is the scope or the inlined-at record entry. - assert(unsigned(-Idx-1) < Ctx->ScopeInlinedAtRecords.size()); - std::pair &Entry = Ctx->ScopeInlinedAtRecords[-Idx-1]; - assert((this == &Entry.first || this == &Entry.second) && - "Mapping out of date!"); - - MDNode *OldScope = Entry.first.get(); - MDNode *OldInlinedAt = Entry.second.get(); - assert(OldScope && OldInlinedAt && - "Entry should be non-canonical if either val dropped to null"); - - // Otherwise, we do have an entry in it, nuke it and we're done. - assert(Ctx->ScopeInlinedAtIdx[std::make_pair(OldScope, OldInlinedAt)] == Idx&& - "Mapping out of date"); - Ctx->ScopeInlinedAtIdx.erase(std::make_pair(OldScope, OldInlinedAt)); - - // Reset this VH to the new value. - setValPtr(NewVal); - - int NewIdx = Ctx->getOrAddScopeInlinedAtIdxEntry(Entry.first.get(), - Entry.second.get(), Idx); - // If NewVal already has an entry, this becomes a non-canonical reference, - // just drop Idx to 0 to signify this. - if (NewIdx != Idx) { - std::pair &Entry=Ctx->ScopeInlinedAtRecords[-Idx-1]; - Entry.first.Idx = Entry.second.Idx = 0; - } -} diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp index 37cce2b0d781..cfb699a31717 100644 --- a/llvm/lib/IR/DiagnosticInfo.cpp +++ b/llvm/lib/IR/DiagnosticInfo.cpp @@ -98,7 +98,8 @@ DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I, Instr(&I) { if (const MDNode *SrcLoc = I.getMetadata("srcloc")) { if (SrcLoc->getNumOperands() != 0) - if (const ConstantInt *CI = dyn_cast(SrcLoc->getOperand(0))) + if (const auto *CI = + mdconst::dyn_extract(SrcLoc->getOperand(0))) LocCookie = CI->getZExtValue(); } } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index f4c6a289b804..132800efeeb3 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -796,11 +796,8 @@ void BranchInst::swapSuccessors() { return; // The first operand is the name. Fetch them backwards and build a new one. - Value *Ops[] = { - ProfileData->getOperand(0), - ProfileData->getOperand(2), - ProfileData->getOperand(1) - }; + Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2), + ProfileData->getOperand(1)}; setMetadata(LLVMContext::MD_prof, MDNode::get(ProfileData->getContext(), Ops)); } @@ -2076,7 +2073,7 @@ float FPMathOperator::getFPAccuracy() const { cast(this)->getMetadata(LLVMContext::MD_fpmath); if (!MD) return 0.0; - ConstantFP *Accuracy = cast(MD->getOperand(0)); + ConstantFP *Accuracy = mdconst::extract(MD->getOperand(0)); return Accuracy->getValueAPF().convertToFloat(); } diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp index 57252840bf01..b9b5a29091df 100644 --- a/llvm/lib/IR/IntrinsicInst.cpp +++ b/llvm/lib/IR/IntrinsicInst.cpp @@ -49,15 +49,25 @@ Value *DbgInfoIntrinsic::StripCast(Value *C) { return dyn_cast(C); } +static Value *getValueImpl(Value *Op) { + auto *MD = cast(Op)->getMetadata(); + if (auto *V = dyn_cast(MD)) + return V->getValue(); + + // When the value goes to null, it gets replaced by an empty MDNode. + assert(!cast(MD)->getNumOperands() && "Expected an empty MDNode"); + return nullptr; +} + //===----------------------------------------------------------------------===// /// DbgDeclareInst - This represents the llvm.dbg.declare instruction. /// Value *DbgDeclareInst::getAddress() const { - if (MDNode* MD = cast_or_null(getArgOperand(0))) - return MD->getOperand(0); - else + if (!getArgOperand(0)) return nullptr; + + return getValueImpl(getArgOperand(0)); } //===----------------------------------------------------------------------===// @@ -65,9 +75,7 @@ Value *DbgDeclareInst::getAddress() const { /// const Value *DbgValueInst::getValue() const { - return cast(getArgOperand(0))->getOperand(0); + return const_cast(this)->getValue(); } -Value *DbgValueInst::getValue() { - return cast(getArgOperand(0))->getOperand(0); -} +Value *DbgValueInst::getValue() { return getValueImpl(getArgOperand(0)); } diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp index 3fd0bb37a4d4..7c34f0949a4e 100644 --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -120,6 +120,21 @@ LLVMContextImpl::~LLVMContextImpl() { delete &*Elem; } + // Destroy MetadataAsValues. + { + SmallVector MDVs; + MDVs.reserve(MetadataAsValues.size()); + for (auto &Pair : MetadataAsValues) + MDVs.push_back(Pair.second); + MetadataAsValues.clear(); + for (auto *V : MDVs) + delete V; + } + + // Destroy ValuesAsMetadata. + for (auto &Pair : ValuesAsMetadata) + delete Pair.second; + // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet // and the NonUniquedMDNodes sets, so copy the values out first. SmallVector MDNodes; diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 09102b1d56b3..a9de5c788227 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -172,29 +172,29 @@ struct FunctionTypeKeyInfo { /// the operands. struct GenericMDNodeInfo { struct KeyTy { - ArrayRef Ops; + ArrayRef RawOps; + ArrayRef Ops; unsigned Hash; - KeyTy(ArrayRef Ops) - : Ops(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {} + KeyTy(ArrayRef Ops) + : RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {} - KeyTy(GenericMDNode *N, SmallVectorImpl &Storage) { - Storage.resize(N->getNumOperands()); - for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I) - Storage[I] = N->getOperand(I); - Ops = Storage; - Hash = hash_combine_range(Ops.begin(), Ops.end()); - } + KeyTy(GenericMDNode *N) + : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {} bool operator==(const GenericMDNode *RHS) const { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; - if (Hash != RHS->getHash() || Ops.size() != RHS->getNumOperands()) + if (Hash != RHS->getHash()) return false; - for (unsigned I = 0, E = Ops.size(); I != E; ++I) - if (Ops[I] != RHS->getOperand(I)) - return false; - return true; + assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?"); + return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS); + } + template + static bool compareOps(ArrayRef Ops, const GenericMDNode *RHS) { + if (Ops.size() != RHS->getNumOperands()) + return false; + return std::equal(Ops.begin(), Ops.end(), RHS->op_begin()); } }; static inline GenericMDNode *getEmptyKey() { @@ -215,29 +215,6 @@ struct GenericMDNodeInfo { } }; -/// DebugRecVH - This is a CallbackVH used to keep the Scope -> index maps -/// up to date as MDNodes mutate. This class is implemented in DebugLoc.cpp. -class DebugRecVH : public CallbackVH { - /// Ctx - This is the LLVM Context being referenced. - LLVMContextImpl *Ctx; - - /// Idx - The index into either ScopeRecordIdx or ScopeInlinedAtRecords that - /// this reference lives in. If this is zero, then it represents a - /// non-canonical entry that has no DenseMap value. This can happen due to - /// RAUW. - int Idx; -public: - DebugRecVH(MDNode *n, LLVMContextImpl *ctx, int idx) - : CallbackVH(n), Ctx(ctx), Idx(idx) {} - - MDNode *get() const { - return cast_or_null(getValPtr()); - } - - void deleted() override; - void allUsesReplacedWith(Value *VNew) override; -}; - class LLVMContextImpl { public: /// OwnedModules - The set of modules instantiated in this context, and which @@ -265,6 +242,8 @@ public: FoldingSet AttrsSetNodes; StringMap MDStringCache; + DenseMap ValuesAsMetadata; + DenseMap MetadataAsValues; DenseSet MDNodeSet; @@ -301,7 +280,8 @@ public: ConstantInt *TheFalseVal; LeakDetectorImpl LLVMObjects; - + LeakDetectorImpl LLVMMDObjects; + // Basic type instances. Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy; Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy; @@ -335,32 +315,14 @@ public: /// CustomMDKindNames - Map to hold the metadata string to ID mapping. StringMap CustomMDKindNames; - - typedef std::pair > MDPairTy; + + typedef std::pair MDPairTy; typedef SmallVector MDMapTy; /// MetadataStore - Collection of per-instruction metadata used in this /// context. DenseMap MetadataStore; - /// ScopeRecordIdx - This is the index in ScopeRecords for an MDNode scope - /// entry with no "inlined at" element. - DenseMap ScopeRecordIdx; - - /// ScopeRecords - These are the actual mdnodes (in a value handle) for an - /// index. The ValueHandle ensures that ScopeRecordIdx stays up to date if - /// the MDNode is RAUW'd. - std::vector ScopeRecords; - - /// ScopeInlinedAtIdx - This is the index in ScopeInlinedAtRecords for an - /// scope/inlined-at pair. - DenseMap, int> ScopeInlinedAtIdx; - - /// ScopeInlinedAtRecords - These are the actual mdnodes (in value handles) - /// for an index. The ValueHandle ensures that ScopeINlinedAtIdx stays up - /// to date. - std::vector > ScopeInlinedAtRecords; - /// DiscriminatorTable - This table maps file:line locations to an /// integer representing the next DWARF path discriminator to assign to /// instructions in different blocks at the same location. diff --git a/llvm/lib/IR/MDBuilder.cpp b/llvm/lib/IR/MDBuilder.cpp index 3ec613c2f664..c7fcf7a2c347 100644 --- a/llvm/lib/IR/MDBuilder.cpp +++ b/llvm/lib/IR/MDBuilder.cpp @@ -21,11 +21,16 @@ MDString *MDBuilder::createString(StringRef Str) { return MDString::get(Context, Str); } +ConstantAsMetadata *MDBuilder::createConstant(Constant *C) { + return ConstantAsMetadata::get(C); +} + MDNode *MDBuilder::createFPMath(float Accuracy) { if (Accuracy == 0.0) return nullptr; assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); - Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); + auto *Op = + createConstant(ConstantFP::get(Type::getFloatTy(Context), Accuracy)); return MDNode::get(Context, Op); } @@ -38,12 +43,12 @@ MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight, MDNode *MDBuilder::createBranchWeights(ArrayRef Weights) { assert(Weights.size() >= 2 && "Need at least two branch weights!"); - SmallVector Vals(Weights.size() + 1); + SmallVector Vals(Weights.size() + 1); Vals[0] = createString("branch_weights"); Type *Int32Ty = Type::getInt32Ty(Context); for (unsigned i = 0, e = Weights.size(); i != e; ++i) - Vals[i + 1] = ConstantInt::get(Int32Ty, Weights[i]); + Vals[i + 1] = createConstant(ConstantInt::get(Int32Ty, Weights[i])); return MDNode::get(Context, Vals); } @@ -56,7 +61,8 @@ MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) { // Return the range [Lo, Hi). Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); - Value *Range[2] = {ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi)}; + Metadata *Range[2] = {createConstant(ConstantInt::get(Ty, Lo)), + createConstant(ConstantInt::get(Ty, Hi))}; return MDNode::get(Context, Range); } @@ -64,7 +70,7 @@ MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) { // To ensure uniqueness the root node is self-referential. MDNode *Dummy = MDNode::getTemporary(Context, None); - SmallVector Args(1, Dummy); + SmallVector Args(1, Dummy); if (Extra) Args.push_back(Extra); if (!Name.empty()) @@ -92,10 +98,10 @@ MDNode *MDBuilder::createTBAANode(StringRef Name, MDNode *Parent, bool isConstant) { if (isConstant) { Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); - Value *Ops[3] = {createString(Name), Parent, Flags}; + Metadata *Ops[3] = {createString(Name), Parent, createConstant(Flags)}; return MDNode::get(Context, Ops); } else { - Value *Ops[2] = {createString(Name), Parent}; + Metadata *Ops[2] = {createString(Name), Parent}; return MDNode::get(Context, Ops); } } @@ -105,18 +111,18 @@ MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) { } MDNode *MDBuilder::createAliasScope(StringRef Name, MDNode *Domain) { - Value *Ops[2] = { createString(Name), Domain }; + Metadata *Ops[2] = {createString(Name), Domain}; return MDNode::get(Context, Ops); } /// \brief Return metadata for a tbaa.struct node with the given /// struct field descriptions. MDNode *MDBuilder::createTBAAStructNode(ArrayRef Fields) { - SmallVector Vals(Fields.size() * 3); + SmallVector Vals(Fields.size() * 3); Type *Int64 = Type::getInt64Ty(Context); for (unsigned i = 0, e = Fields.size(); i != e; ++i) { - Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset); - Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size); + Vals[i * 3 + 0] = createConstant(ConstantInt::get(Int64, Fields[i].Offset)); + Vals[i * 3 + 1] = createConstant(ConstantInt::get(Int64, Fields[i].Size)); Vals[i * 3 + 2] = Fields[i].TBAA; } return MDNode::get(Context, Vals); @@ -126,12 +132,12 @@ MDNode *MDBuilder::createTBAAStructNode(ArrayRef Fields) { /// with the given name, a list of pairs (offset, field type in the type DAG). MDNode *MDBuilder::createTBAAStructTypeNode( StringRef Name, ArrayRef> Fields) { - SmallVector Ops(Fields.size() * 2 + 1); + SmallVector Ops(Fields.size() * 2 + 1); Type *Int64 = Type::getInt64Ty(Context); Ops[0] = createString(Name); for (unsigned i = 0, e = Fields.size(); i != e; ++i) { Ops[i * 2 + 1] = Fields[i].first; - Ops[i * 2 + 2] = ConstantInt::get(Int64, Fields[i].second); + Ops[i * 2 + 2] = createConstant(ConstantInt::get(Int64, Fields[i].second)); } return MDNode::get(Context, Ops); } @@ -141,7 +147,7 @@ MDNode *MDBuilder::createTBAAStructTypeNode( MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent, uint64_t Offset) { ConstantInt *Off = ConstantInt::get(Type::getInt64Ty(Context), Offset); - Value *Ops[3] = {createString(Name), Parent, Off}; + Metadata *Ops[3] = {createString(Name), Parent, createConstant(Off)}; return MDNode::get(Context, Ops); } @@ -150,6 +156,7 @@ MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent, MDNode *MDBuilder::createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, uint64_t Offset) { Type *Int64 = Type::getInt64Ty(Context); - Value *Ops[3] = {BaseType, AccessType, ConstantInt::get(Int64, Offset)}; + Metadata *Ops[3] = {BaseType, AccessType, + createConstant(ConstantInt::get(Int64, Offset))}; return MDNode::get(Context, Ops); } diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index a2c7838bb83f..150a186424cb 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -28,23 +28,320 @@ using namespace llvm; -Metadata::Metadata(LLVMContext &Context, unsigned ID) - : Value(Type::getMetadataTy(Context), ID) {} +MetadataAsValue::MetadataAsValue(Type *Ty, Metadata *MD) + : Value(Ty, MetadataAsValueVal), MD(MD) { + track(); +} + +MetadataAsValue::~MetadataAsValue() { + getType()->getContext().pImpl->MetadataAsValues.erase(MD); + untrack(); +} + +/// \brief Canonicalize metadata arguments to intrinsics. +/// +/// To support bitcode upgrades (and assembly semantic sugar) for \a +/// MetadataAsValue, we need to canonicalize certain metadata. +/// +/// - nullptr is replaced by an empty MDNode. +/// - An MDNode with a single null operand is replaced by an empty MDNode. +/// - An MDNode whose only operand is a \a ConstantAsMetadata gets skipped. +/// +/// This maintains readability of bitcode from when metadata was a type of +/// value, and these bridges were unnecessary. +static Metadata *canonicalizeMetadataForValue(LLVMContext &Context, + Metadata *MD) { + if (!MD) + // !{} + return MDNode::get(Context, None); + + // Return early if this isn't a single-operand MDNode. + auto *N = dyn_cast(MD); + if (!N || N->getNumOperands() != 1) + return MD; + + if (!N->getOperand(0)) + // !{} + return MDNode::get(Context, None); + + if (auto *C = dyn_cast(N->getOperand(0))) + // Look through the MDNode. + return C; + + return MD; +} + +MetadataAsValue *MetadataAsValue::get(LLVMContext &Context, Metadata *MD) { + MD = canonicalizeMetadataForValue(Context, MD); + auto *&Entry = Context.pImpl->MetadataAsValues[MD]; + if (!Entry) + Entry = new MetadataAsValue(Type::getMetadataTy(Context), MD); + return Entry; +} + +MetadataAsValue *MetadataAsValue::getIfExists(LLVMContext &Context, + Metadata *MD) { + MD = canonicalizeMetadataForValue(Context, MD); + auto &Store = Context.pImpl->MetadataAsValues; + auto I = Store.find(MD); + return I == Store.end() ? nullptr : I->second; +} + +void MetadataAsValue::handleChangedMetadata(Metadata *MD) { + LLVMContext &Context = getContext(); + MD = canonicalizeMetadataForValue(Context, MD); + auto &Store = Context.pImpl->MetadataAsValues; + + // Stop tracking the old metadata. + Store.erase(this->MD); + untrack(); + this->MD = nullptr; + + // Start tracking MD, or RAUW if necessary. + auto *&Entry = Store[MD]; + if (Entry) { + replaceAllUsesWith(Entry); + delete this; + return; + } + + this->MD = MD; + track(); + Entry = this; +} + +void MetadataAsValue::track() { + if (MD) + MetadataTracking::track(&MD, *MD, *this); +} + +void MetadataAsValue::untrack() { + if (MD) + MetadataTracking::untrack(MD); +} + +void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) { + bool WasInserted = UseMap.insert(std::make_pair(Ref, Owner)).second; + (void)WasInserted; + assert(WasInserted && "Expected to add a reference"); +} + +void ReplaceableMetadataImpl::dropRef(void *Ref) { + bool WasErased = UseMap.erase(Ref); + (void)WasErased; + assert(WasErased && "Expected to drop a reference"); +} + +void ReplaceableMetadataImpl::moveRef(void *Ref, void *New, + const Metadata &MD) { + auto I = UseMap.find(Ref); + assert(I != UseMap.end() && "Expected to move a reference"); + OwnerTy Owner = I->second; + UseMap.erase(I); + addRef(New, Owner); + + // Check that the references are direct if there's no owner. + (void)MD; + assert((Owner || *static_cast(Ref) == &MD) && + "Reference without owner must be direct"); + assert((Owner || *static_cast(New) == &MD) && + "Reference without owner must be direct"); +} + +void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) { + assert(!(MD && isa(MD)) && "Expected non-temp node"); + + if (UseMap.empty()) + return; + + // Copy out uses since UseMap will get touched below. + SmallVector, 8> Uses(UseMap.begin(), UseMap.end()); + for (const auto &Pair : Uses) { + if (!Pair.second) { + // Update unowned tracking references directly. + Metadata *&Ref = *static_cast(Pair.first); + Ref = MD; + MetadataTracking::track(Ref); + UseMap.erase(Pair.first); + continue; + } + + // Check for MetadataAsValue. + if (Pair.second.is()) { + Pair.second.get()->handleChangedMetadata(MD); + continue; + } + + // There's a Metadata owner -- dispatch. + Metadata *Owner = Pair.second.get(); + switch (Owner->getMetadataID()) { +#define HANDLE_METADATA_LEAF(CLASS) \ + case Metadata::CLASS##Kind: \ + cast(Owner)->handleChangedOperand(Pair.first, MD); \ + continue; +#include "llvm/IR/Metadata.def" + default: + llvm_unreachable("Invalid metadata subclass"); + } + } + assert(UseMap.empty() && "Expected all uses to be replaced"); +} + +void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) { + if (UseMap.empty()) + return; + + if (!ResolveUsers) { + UseMap.clear(); + return; + } + + // Copy out uses since UseMap could get touched below. + SmallVector, 8> Uses(UseMap.begin(), UseMap.end()); + UseMap.clear(); + for (const auto &Pair : Uses) { + if (!Pair.second) + continue; + if (Pair.second.is()) + continue; + + // Resolve GenericMDNodes that point at this. + auto *Owner = dyn_cast(Pair.second.get()); + if (!Owner) + continue; + if (Owner->isResolved()) + continue; + Owner->decrementUnresolvedOperands(); + if (!Owner->hasUnresolvedOperands()) + Owner->resolve(); + } +} + +static Function *getLocalFunction(Value *V) { + assert(V && "Expected value"); + if (auto *A = dyn_cast(V)) + return A->getParent(); + if (BasicBlock *BB = cast(V)->getParent()) + return BB->getParent(); + return nullptr; +} + +ValueAsMetadata *ValueAsMetadata::get(Value *V) { + assert(V && "Unexpected null Value"); + + auto &Context = V->getContext(); + auto *&Entry = Context.pImpl->ValuesAsMetadata[V]; + if (!Entry) { + assert((isa(V) || isa(V) || isa(V)) && + "Expected constant or function-local value"); + assert(!V->NameAndIsUsedByMD.getInt() && + "Expected this to be the only metadata use"); + V->NameAndIsUsedByMD.setInt(true); + if (auto *C = dyn_cast(V)) + Entry = new ConstantAsMetadata(Context, C); + else + Entry = new LocalAsMetadata(Context, V); + } + + return Entry; +} + +ValueAsMetadata *ValueAsMetadata::getIfExists(Value *V) { + assert(V && "Unexpected null Value"); + return V->getContext().pImpl->ValuesAsMetadata.lookup(V); +} + +void ValueAsMetadata::handleDeletion(Value *V) { + assert(V && "Expected valid value"); + + auto &Store = V->getType()->getContext().pImpl->ValuesAsMetadata; + auto I = Store.find(V); + if (I == Store.end()) + return; + + // Remove old entry from the map. + ValueAsMetadata *MD = I->second; + assert(MD && "Expected valid metadata"); + assert(MD->getValue() == V && "Expected valid mapping"); + Store.erase(I); + + // Delete the metadata. + MD->replaceAllUsesWith(nullptr); + delete MD; +} + +void ValueAsMetadata::handleRAUW(Value *From, Value *To) { + assert(From && "Expected valid value"); + assert(To && "Expected valid value"); + assert(From != To && "Expected changed value"); + assert(From->getType() == To->getType() && "Unexpected type change"); + + LLVMContext &Context = From->getType()->getContext(); + auto &Store = Context.pImpl->ValuesAsMetadata; + auto I = Store.find(From); + if (I == Store.end()) { + assert(!From->NameAndIsUsedByMD.getInt() && + "Expected From not to be used by metadata"); + return; + } + + // Remove old entry from the map. + assert(From->NameAndIsUsedByMD.getInt() && + "Expected From to be used by metadata"); + From->NameAndIsUsedByMD.setInt(false); + ValueAsMetadata *MD = I->second; + assert(MD && "Expected valid metadata"); + assert(MD->getValue() == From && "Expected valid mapping"); + Store.erase(I); + + if (isa(MD)) { + if (auto *C = dyn_cast(To)) { + // Local became a constant. + MD->replaceAllUsesWith(ConstantAsMetadata::get(C)); + delete MD; + return; + } + if (getLocalFunction(From) && getLocalFunction(To) && + getLocalFunction(From) != getLocalFunction(To)) { + // Function changed. + MD->replaceAllUsesWith(nullptr); + delete MD; + return; + } + } else if (!isa(To)) { + // Changed to function-local value. + MD->replaceAllUsesWith(nullptr); + delete MD; + return; + } + + auto *&Entry = Store[To]; + if (Entry) { + // The target already exists. + MD->replaceAllUsesWith(Entry); + delete MD; + return; + } + + // Update MD in place (and update the map entry). + assert(!To->NameAndIsUsedByMD.getInt() && + "Expected this to be the only metadata use"); + To->NameAndIsUsedByMD.setInt(true); + MD->V = To; + Entry = MD; +} //===----------------------------------------------------------------------===// // MDString implementation. // -void MDString::anchor() { } - MDString *MDString::get(LLVMContext &Context, StringRef Str) { auto &Store = Context.pImpl->MDStringCache; auto I = Store.find(Str); if (I != Store.end()) return &I->second; - auto *Entry = - StringMapEntry::Create(Str, Store.getAllocator(), Context); + auto *Entry = StringMapEntry::Create(Str, Store.getAllocator()); bool WasInserted = Store.insert(Entry); (void)WasInserted; assert(WasInserted && "Expected entry to be inserted"); @@ -57,323 +354,254 @@ StringRef MDString::getString() const { return Entry->first(); } -//===----------------------------------------------------------------------===// -// MDNodeOperand implementation. -// - -// Use CallbackVH to hold MDNode operands. -namespace llvm { -class MDNodeOperand : public CallbackVH { - MDNode *getParent() { - MDNodeOperand *Cur = this; - - while (Cur->getValPtrInt() != 1) - ++Cur; - - assert(Cur->getValPtrInt() == 1 && - "Couldn't find the end of the operand list!"); - return reinterpret_cast(Cur + 1); - } - -public: - MDNodeOperand() {} - virtual ~MDNodeOperand(); - - void set(Value *V) { - unsigned IsLast = this->getValPtrInt(); - this->setValPtr(V); - this->setAsLastOperand(IsLast); - } - - /// \brief Accessor method to mark the operand as the first in the list. - void setAsLastOperand(unsigned I) { this->setValPtrInt(I); } - - void deleted() override; - void allUsesReplacedWith(Value *NV) override; -}; -} // end namespace llvm. - -// Provide out-of-line definition to prevent weak vtable. -MDNodeOperand::~MDNodeOperand() {} - -void MDNodeOperand::deleted() { - getParent()->replaceOperand(this, nullptr); -} - -void MDNodeOperand::allUsesReplacedWith(Value *NV) { - getParent()->replaceOperand(this, NV); -} - //===----------------------------------------------------------------------===// // MDNode implementation. // -/// \brief Get the MDNodeOperand's coallocated on the end of the MDNode. -static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) { - // Use <= instead of < to permit a one-past-the-end address. - assert(Op <= N->getNumOperands() && "Invalid operand number"); - return reinterpret_cast(N) - N->getNumOperands() + Op; -} - -void MDNode::replaceOperandWith(unsigned i, Value *Val) { - MDNodeOperand *Op = getOperandPtr(this, i); - replaceOperand(Op, Val); -} - void *MDNode::operator new(size_t Size, unsigned NumOps) { - void *Ptr = ::operator new(Size + NumOps * sizeof(MDNodeOperand)); - MDNodeOperand *Op = static_cast(Ptr); - if (NumOps) { - MDNodeOperand *Last = Op + NumOps; - for (; Op != Last; ++Op) - new (Op) MDNodeOperand(); - (Op - 1)->setAsLastOperand(1); - } - return Op; + void *Ptr = ::operator new(Size + NumOps * sizeof(MDOperand)); + MDOperand *First = new (Ptr) MDOperand[NumOps]; + return First + NumOps; } void MDNode::operator delete(void *Mem) { MDNode *N = static_cast(Mem); - MDNodeOperand *Op = static_cast(Mem); - for (unsigned I = 0, E = N->NumOperands; I != E; ++I) - (--Op)->~MDNodeOperand(); - ::operator delete(Op); + MDOperand *Last = static_cast(Mem); + ::operator delete(Last - N->NumOperands); } -MDNode::MDNode(LLVMContext &C, unsigned ID, ArrayRef Vals, - bool isFunctionLocal) - : Metadata(C, ID) { - NumOperands = Vals.size(); +MDNode::MDNode(LLVMContext &Context, unsigned ID, ArrayRef MDs) + : Metadata(ID), Context(Context), NumOperands(MDs.size()), + MDNodeSubclassData(0) { + for (unsigned I = 0, E = MDs.size(); I != E; ++I) + setOperand(I, MDs[I]); +} - if (isFunctionLocal) - setValueSubclassData(getSubclassDataFromValue() | FunctionLocalBit); +bool MDNode::isResolved() const { + if (isa(this)) + return false; + return cast(this)->isResolved(); +} - // Initialize the operand list. - unsigned i = 0; - for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op + NumOperands; - Op != E; ++Op, ++i) - Op->set(Vals[i]); +static bool isOperandUnresolved(Metadata *Op) { + if (auto *N = dyn_cast_or_null(Op)) + return !N->isResolved(); + return false; +} + +GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef Vals) + : MDNode(C, GenericMDNodeKind, Vals) { + // Check whether any operands are unresolved, requiring re-uniquing. + for (const auto &Op : operands()) + if (isOperandUnresolved(Op)) + incrementUnresolvedOperands(); + + if (hasUnresolvedOperands()) + ReplaceableUses.reset(new ReplaceableMetadataImpl); } GenericMDNode::~GenericMDNode() { - LLVMContextImpl *pImpl = getType()->getContext().pImpl; - if (isNotUniqued()) { + LLVMContextImpl *pImpl = getContext().pImpl; + if (isStoredDistinctInContext()) pImpl->NonUniquedMDNodes.erase(this); - } else { + else pImpl->MDNodeSet.erase(this); +} + +void GenericMDNode::resolve() { + assert(!isResolved() && "Expected this to be unresolved"); + + // Move the map, so that this immediately looks resolved. + auto Uses = std::move(ReplaceableUses); + SubclassData32 = 0; + assert(isResolved() && "Expected this to be resolved"); + + // Drop RAUW support. + Uses->resolveAllUses(); +} + +void GenericMDNode::resolveCycles() { + if (isResolved()) + return; + + // Resolve this node immediately. + resolve(); + + // Resolve all operands. + for (const auto &Op : operands()) { + if (!Op) + continue; + assert(!isa(Op) && + "Expected all forward declarations to be resolved"); + if (auto *N = dyn_cast(Op)) + if (!N->isResolved()) + N->resolveCycles(); } } -void GenericMDNode::dropAllReferences() { - for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op + NumOperands; - Op != E; ++Op) - Op->set(nullptr); +void MDNode::dropAllReferences() { + for (unsigned I = 0, E = NumOperands; I != E; ++I) + setOperand(I, nullptr); + if (auto *G = dyn_cast(this)) + if (!G->isResolved()) { + G->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false); + G->ReplaceableUses.reset(); + } } -static const Function *getFunctionForValue(Value *V) { - if (!V) return nullptr; - if (Instruction *I = dyn_cast(V)) { - BasicBlock *BB = I->getParent(); - return BB ? BB->getParent() : nullptr; +namespace llvm { +/// \brief Make MDOperand transparent for hashing. +/// +/// This overload of an implementation detail of the hashing library makes +/// MDOperand hash to the same value as a \a Metadata pointer. +/// +/// Note that overloading \a hash_value() as follows: +/// +/// \code +/// size_t hash_value(const MDOperand &X) { return hash_value(X.get()); } +/// \endcode +/// +/// does not cause MDOperand to be transparent. In particular, a bare pointer +/// doesn't get hashed before it's combined, whereas \a MDOperand would. +static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); } +} + +void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { + unsigned Op = static_cast(Ref) - op_begin(); + assert(Op < getNumOperands() && "Expected valid operand"); + + if (isStoredDistinctInContext()) { + assert(isResolved() && "Expected distinct node to be resolved"); + + // This node is not uniqued. Just set the operand and be done with it. + setOperand(Op, New); + return; } - if (Argument *A = dyn_cast(V)) - return A->getParent(); - if (BasicBlock *BB = dyn_cast(V)) - return BB->getParent(); - if (MDNode *MD = dyn_cast(V)) - return MD->getFunction(); - return nullptr; + + auto &Store = getContext().pImpl->MDNodeSet; + Store.erase(this); + + Metadata *Old = getOperand(Op); + setOperand(Op, New); + + // Drop uniquing for self-reference cycles or if an operand drops to null. + // + // FIXME: Stop dropping uniquing when an operand drops to null. The original + // motivation was to prevent madness during teardown of LLVMContextImpl, but + // dropAllReferences() fixes that problem in a better way. (It's just here + // now for better staging of semantic changes.) + if (New == this || !New) { + storeDistinctInContext(); + setHash(0); + if (!isResolved()) + resolve(); + return; + } + + // Re-calculate the hash. + setHash(hash_combine_range(op_begin(), op_end())); +#ifndef NDEBUG + { + SmallVector MDs(op_begin(), op_end()); + unsigned RawHash = hash_combine_range(MDs.begin(), MDs.end()); + assert(getHash() == RawHash && + "Expected hash of MDOperand to equal hash of Metadata*"); + } +#endif + + // Re-unique the node. + GenericMDNodeInfo::KeyTy Key(this); + auto I = Store.find_as(Key); + if (I == Store.end()) { + Store.insert(this); + + if (!isResolved()) { + // Check if the last unresolved operand has just been resolved; if so, + // resolve this as well. + if (isOperandUnresolved(Old)) + decrementUnresolvedOperands(); + if (isOperandUnresolved(New)) + incrementUnresolvedOperands(); + if (!hasUnresolvedOperands()) + resolve(); + } + + return; + } + + // Collision. + if (!isResolved()) { + // Still unresolved, so RAUW. + ReplaceableUses->replaceAllUsesWith(*I); + delete this; + return; + } + + // Store in non-uniqued form if this node has already been resolved. + setHash(0); + storeDistinctInContext(); } -// getFunction - If this metadata is function-local and recursively has a -// function-local operand, return the first such operand's parent function. -// Otherwise, return null. getFunction() should not be used for performance- -// critical code because it recursively visits all the MDNode's operands. -const Function *MDNode::getFunction() const { - if (!isFunctionLocal()) - return nullptr; - assert(getNumOperands() == 1 && - "Expected one operand for function-local metadata"); - assert(getOperand(0) && - "Expected non-null operand for function-local metadata"); - assert(!getOperand(0)->getType()->isMetadataTy() && - "Expected non-metadata as operand of function-local metadata"); - return getFunctionForValue(getOperand(0)); -} - -/// \brief Check if the Value would require a function-local MDNode. -static bool isFunctionLocalValue(Value *V) { - return isa(V) || isa(V) || isa(V) || - (isa(V) && cast(V)->isFunctionLocal()); -} - -MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef Vals, - FunctionLocalness FL, bool Insert) { +MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef MDs, + bool Insert) { auto &Store = Context.pImpl->MDNodeSet; - GenericMDNodeInfo::KeyTy Key(Vals); + GenericMDNodeInfo::KeyTy Key(MDs); auto I = Store.find_as(Key); if (I != Store.end()) return *I; if (!Insert) return nullptr; - bool isFunctionLocal = false; - switch (FL) { - case FL_Unknown: - for (Value *V : Vals) { - if (!V) continue; - if (isFunctionLocalValue(V)) { - isFunctionLocal = true; - break; - } - } - break; - case FL_No: - isFunctionLocal = false; - break; - case FL_Yes: - isFunctionLocal = true; - break; - } - - if (isFunctionLocal) { - assert(Vals.size() == 1 && - "Expected exactly one operand for function-local metadata"); - assert(Vals[0] && "Expected non-null operand for function-local metadata"); - assert(!Vals[0]->getType()->isMetadataTy() && - "Expected non-metadata as operand of function-local metadata"); - } - // Coallocate space for the node and Operands together, then placement new. - GenericMDNode *N = - new (Vals.size()) GenericMDNode(Context, Vals, isFunctionLocal); - - N->Hash = Key.Hash; + GenericMDNode *N = new (MDs.size()) GenericMDNode(Context, MDs); + N->setHash(Key.Hash); Store.insert(N); return N; } -MDNode *MDNode::get(LLVMContext &Context, ArrayRef Vals) { - return getMDNode(Context, Vals, FL_Unknown); -} - -MDNode *MDNode::getWhenValsUnresolved(LLVMContext &Context, - ArrayRef Vals, - bool isFunctionLocal) { - return getMDNode(Context, Vals, isFunctionLocal ? FL_Yes : FL_No); -} - -MDNode *MDNode::getIfExists(LLVMContext &Context, ArrayRef Vals) { - return getMDNode(Context, Vals, FL_Unknown, false); -} - -MDNode *MDNode::getTemporary(LLVMContext &Context, ArrayRef Vals) { - MDNode *N = new (Vals.size()) MDNodeFwdDecl(Context, Vals, FL_No); - N->setValueSubclassData(N->getSubclassDataFromValue() | NotUniquedBit); +MDNodeFwdDecl *MDNode::getTemporary(LLVMContext &Context, + ArrayRef MDs) { + MDNodeFwdDecl *N = new (MDs.size()) MDNodeFwdDecl(Context, MDs); LeakDetector::addGarbageObject(N); return N; } void MDNode::deleteTemporary(MDNode *N) { - assert(N->use_empty() && "Temporary MDNode has uses!"); assert(isa(N) && "Expected forward declaration"); - assert((N->getSubclassDataFromValue() & NotUniquedBit) && - "Temporary MDNode does not have NotUniquedBit set!"); LeakDetector::removeGarbageObject(N); delete cast(N); } -/// \brief Return specified operand. -Value *MDNode::getOperand(unsigned i) const { - assert(i < getNumOperands() && "Invalid operand number"); - return *getOperandPtr(const_cast(this), i); -} - -void MDNode::setIsNotUniqued() { - setValueSubclassData(getSubclassDataFromValue() | NotUniquedBit); - LLVMContextImpl *pImpl = getType()->getContext().pImpl; +void MDNode::storeDistinctInContext() { + assert(!IsDistinctInContext && "Expected newly distinct metadata"); + IsDistinctInContext = true; auto *G = cast(this); - G->Hash = 0; - pImpl->NonUniquedMDNodes.insert(G); + G->setHash(0); + getContext().pImpl->NonUniquedMDNodes.insert(G); } // Replace value from this node's operand list. -void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { - Value *From = *Op; - - // If is possible that someone did GV->RAUW(inst), replacing a global variable - // with an instruction or some other function-local object. If this is a - // non-function-local MDNode, it can't point to a function-local object. - // Handle this case by implicitly dropping the MDNode reference to null. - // Likewise if the MDNode is function-local but for a different function. - if (To && isFunctionLocalValue(To)) { - assert(!To->getType()->isMetadataTy() && - "Expected non-metadata as operand of function-local metadata"); - if (!isFunctionLocal()) - To = nullptr; - else { - const Function *F = getFunction(); - const Function *FV = getFunctionForValue(To); - // Metadata can be function-local without having an associated function. - // So only consider functions to have changed if non-null. - if (F && FV && F != FV) - To = nullptr; - } - } - - if (From == To) +void MDNode::replaceOperandWith(unsigned I, Metadata *New) { + if (getOperand(I) == New) return; - // If this MDValue was previously function-local but no longer is, clear - // its function-local flag. - if (isFunctionLocal() && !(To && isFunctionLocalValue(To))) { - assert(getNumOperands() == 1 && - "Expected function-local metadata to have exactly one operand"); - setValueSubclassData(getSubclassDataFromValue() & ~FunctionLocalBit); - } - - // If this node is already not being uniqued (because one of the operands - // already went to null), then there is nothing else to do here. - if (isNotUniqued()) { - Op->set(To); + if (auto *N = dyn_cast(this)) { + N->handleChangedOperand(mutable_begin() + I, New); return; } - auto &Store = getContext().pImpl->MDNodeSet; - auto *N = cast(this); + assert(isa(this) && "Expected an MDNode"); + setOperand(I, New); +} - // Remove "this" from the context map. - Store.erase(N); - - // Update the operand. - Op->set(To); - - // If we are dropping an argument to null, we choose to not unique the MDNode - // anymore. This commonly occurs during destruction, and uniquing these - // brings little reuse. Also, this means we don't need to include - // isFunctionLocal bits in the hash for MDNodes. - // - // Also drop uniquing if this has a reference to itself. - if (!To || To == this) { - setIsNotUniqued(); - return; - } - - // Now that the node is out of the table, get ready to reinsert it. First, - // check to see if another node with the same operands already exists in the - // set. If so, then this node is redundant. - SmallVector Vals; - GenericMDNodeInfo::KeyTy Key(N, Vals); - auto I = Store.find_as(Key); - if (I != Store.end()) { - N->replaceAllUsesWith(*I); - delete N; - return; - } - - N->Hash = Key.Hash; - Store.insert(N); +void MDNode::setOperand(unsigned I, Metadata *New) { + assert(I < NumOperands); + if (isStoredDistinctInContext() || isa(this)) + // No need for a callback, this isn't uniqued. + mutable_begin()[I].reset(New, nullptr); + else + mutable_begin()[I].reset(New, this); } /// \brief Get a node, or a self-reference that looks like it. @@ -382,7 +610,8 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { /// MDNode::concatenate() and \a MDNode::intersect() to maintain behaviour from /// when self-referencing nodes were still uniqued. If the first operand has /// the same operands as \c Ops, return the first operand instead. -static MDNode *getOrSelfReference(LLVMContext &Context, ArrayRef Ops) { +static MDNode *getOrSelfReference(LLVMContext &Context, + ArrayRef Ops) { if (!Ops.empty()) if (MDNode *N = dyn_cast_or_null(Ops[0])) if (N->getNumOperands() == Ops.size() && N == N->getOperand(0)) { @@ -401,45 +630,44 @@ MDNode *MDNode::concatenate(MDNode *A, MDNode *B) { if (!B) return A; - SmallVector Vals(A->getNumOperands() + - B->getNumOperands()); + SmallVector MDs(A->getNumOperands() + B->getNumOperands()); unsigned j = 0; for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) - Vals[j++] = A->getOperand(i); + MDs[j++] = A->getOperand(i); for (unsigned i = 0, ie = B->getNumOperands(); i != ie; ++i) - Vals[j++] = B->getOperand(i); + MDs[j++] = B->getOperand(i); // FIXME: This preserves long-standing behaviour, but is it really the right // behaviour? Or was that an unintended side-effect of node uniquing? - return getOrSelfReference(A->getContext(), Vals); + return getOrSelfReference(A->getContext(), MDs); } MDNode *MDNode::intersect(MDNode *A, MDNode *B) { if (!A || !B) return nullptr; - SmallVector Vals; + SmallVector MDs; for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) { - Value *V = A->getOperand(i); + Metadata *MD = A->getOperand(i); for (unsigned j = 0, je = B->getNumOperands(); j != je; ++j) - if (V == B->getOperand(j)) { - Vals.push_back(V); + if (MD == B->getOperand(j)) { + MDs.push_back(MD); break; } } // FIXME: This preserves long-standing behaviour, but is it really the right // behaviour? Or was that an unintended side-effect of node uniquing? - return getOrSelfReference(A->getContext(), Vals); + return getOrSelfReference(A->getContext(), MDs); } MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) { if (!A || !B) return nullptr; - APFloat AVal = cast(A->getOperand(0))->getValueAPF(); - APFloat BVal = cast(B->getOperand(0))->getValueAPF(); + APFloat AVal = mdconst::extract(A->getOperand(0))->getValueAPF(); + APFloat BVal = mdconst::extract(B->getOperand(0))->getValueAPF(); if (AVal.compare(BVal) == APFloat::cmpLessThan) return A; return B; @@ -453,25 +681,27 @@ static bool canBeMerged(const ConstantRange &A, const ConstantRange &B) { return !A.intersectWith(B).isEmptySet() || isContiguous(A, B); } -static bool tryMergeRange(SmallVectorImpl &EndPoints, ConstantInt *Low, - ConstantInt *High) { +static bool tryMergeRange(SmallVectorImpl &EndPoints, + ConstantInt *Low, ConstantInt *High) { ConstantRange NewRange(Low->getValue(), High->getValue()); unsigned Size = EndPoints.size(); - APInt LB = cast(EndPoints[Size - 2])->getValue(); - APInt LE = cast(EndPoints[Size - 1])->getValue(); + APInt LB = EndPoints[Size - 2]->getValue(); + APInt LE = EndPoints[Size - 1]->getValue(); ConstantRange LastRange(LB, LE); if (canBeMerged(NewRange, LastRange)) { ConstantRange Union = LastRange.unionWith(NewRange); Type *Ty = High->getType(); - EndPoints[Size - 2] = ConstantInt::get(Ty, Union.getLower()); - EndPoints[Size - 1] = ConstantInt::get(Ty, Union.getUpper()); + EndPoints[Size - 2] = + cast(ConstantInt::get(Ty, Union.getLower())); + EndPoints[Size - 1] = + cast(ConstantInt::get(Ty, Union.getUpper())); return true; } return false; } -static void addRange(SmallVectorImpl &EndPoints, ConstantInt *Low, - ConstantInt *High) { +static void addRange(SmallVectorImpl &EndPoints, + ConstantInt *Low, ConstantInt *High) { if (!EndPoints.empty()) if (tryMergeRange(EndPoints, Low, High)) return; @@ -493,31 +723,33 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) { // First, walk both lists in older of the lower boundary of each interval. // At each step, try to merge the new interval to the last one we adedd. - SmallVector EndPoints; + SmallVector EndPoints; int AI = 0; int BI = 0; int AN = A->getNumOperands() / 2; int BN = B->getNumOperands() / 2; while (AI < AN && BI < BN) { - ConstantInt *ALow = cast(A->getOperand(2 * AI)); - ConstantInt *BLow = cast(B->getOperand(2 * BI)); + ConstantInt *ALow = mdconst::extract(A->getOperand(2 * AI)); + ConstantInt *BLow = mdconst::extract(B->getOperand(2 * BI)); if (ALow->getValue().slt(BLow->getValue())) { - addRange(EndPoints, ALow, cast(A->getOperand(2 * AI + 1))); + addRange(EndPoints, ALow, + mdconst::extract(A->getOperand(2 * AI + 1))); ++AI; } else { - addRange(EndPoints, BLow, cast(B->getOperand(2 * BI + 1))); + addRange(EndPoints, BLow, + mdconst::extract(B->getOperand(2 * BI + 1))); ++BI; } } while (AI < AN) { - addRange(EndPoints, cast(A->getOperand(2 * AI)), - cast(A->getOperand(2 * AI + 1))); + addRange(EndPoints, mdconst::extract(A->getOperand(2 * AI)), + mdconst::extract(A->getOperand(2 * AI + 1))); ++AI; } while (BI < BN) { - addRange(EndPoints, cast(B->getOperand(2 * BI)), - cast(B->getOperand(2 * BI + 1))); + addRange(EndPoints, mdconst::extract(B->getOperand(2 * BI)), + mdconst::extract(B->getOperand(2 * BI + 1))); ++BI; } @@ -525,8 +757,8 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) { // the last and first ones. unsigned Size = EndPoints.size(); if (Size > 4) { - ConstantInt *FB = cast(EndPoints[0]); - ConstantInt *FE = cast(EndPoints[1]); + ConstantInt *FB = EndPoints[0]; + ConstantInt *FE = EndPoints[1]; if (tryMergeRange(EndPoints, FB, FE)) { for (unsigned i = 0; i < Size - 2; ++i) { EndPoints[i] = EndPoints[i + 2]; @@ -538,26 +770,29 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) { // If in the end we have a single range, it is possible that it is now the // full range. Just drop the metadata in that case. if (EndPoints.size() == 2) { - ConstantRange Range(cast(EndPoints[0])->getValue(), - cast(EndPoints[1])->getValue()); + ConstantRange Range(EndPoints[0]->getValue(), EndPoints[1]->getValue()); if (Range.isFullSet()) return nullptr; } - return MDNode::get(A->getContext(), EndPoints); + SmallVector MDs; + MDs.reserve(EndPoints.size()); + for (auto *I : EndPoints) + MDs.push_back(ConstantAsMetadata::get(I)); + return MDNode::get(A->getContext(), MDs); } //===----------------------------------------------------------------------===// // NamedMDNode implementation. // -static SmallVector, 4> &getNMDOps(void *Operands) { - return *(SmallVector, 4> *)Operands; +static SmallVector &getNMDOps(void *Operands) { + return *(SmallVector *)Operands; } NamedMDNode::NamedMDNode(const Twine &N) : Name(N.str()), Parent(nullptr), - Operands(new SmallVector, 4>()) {} + Operands(new SmallVector()) {} NamedMDNode::~NamedMDNode() { dropAllReferences(); @@ -570,14 +805,13 @@ unsigned NamedMDNode::getNumOperands() const { MDNode *NamedMDNode::getOperand(unsigned i) const { assert(i < getNumOperands() && "Invalid Operand number!"); - return &*getNMDOps(Operands)[i]; + auto *N = getNMDOps(Operands)[i].get(); + if (N && i > 10000) + N->dump(); + return cast_or_null(N); } -void NamedMDNode::addOperand(MDNode *M) { - assert(!M->isFunctionLocal() && - "NamedMDNode operands must not be function-local!"); - getNMDOps(Operands).push_back(TrackingVH(M)); -} +void NamedMDNode::addOperand(MDNode *M) { getNMDOps(Operands).emplace_back(M); } void NamedMDNode::eraseFromParent() { getParent()->eraseNamedMetadata(this); @@ -636,7 +870,7 @@ void Instruction::dropUnknownMetadata(ArrayRef KnownIDs) { continue; } - Info[I] = Info.back(); + Info[I] = std::move(Info.back()); Info.pop_back(); --E; } @@ -664,8 +898,6 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { // Handle the case when we're adding/updating metadata on an instruction. if (Node) { - assert(!Node->isFunctionLocal() && - "Function-local metadata cannot be attached to instructions"); LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this]; assert(!Info.empty() == hasMetadataHashEntry() && "HasMetadata bit is wonked"); @@ -675,13 +907,14 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { // Handle replacement of an existing value. for (auto &P : Info) if (P.first == KindID) { - P.second = Node; + P.second.reset(Node); return; } } // No replacement, just add it to the list. - Info.push_back(std::make_pair(KindID, Node)); + Info.emplace_back(std::piecewise_construct, std::make_tuple(KindID), + std::make_tuple(Node)); return; } @@ -703,7 +936,7 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { // Handle removal of an existing value. for (unsigned i = 0, e = Info.size(); i != e; ++i) if (Info[i].first == KindID) { - Info[i] = Info.back(); + Info[i] = std::move(Info.back()); Info.pop_back(); assert(!Info.empty() && "Removing last entry should be handled above"); return; @@ -720,8 +953,8 @@ void Instruction::setAAMetadata(const AAMDNodes &N) { MDNode *Instruction::getMetadataImpl(unsigned KindID) const { // Handle 'dbg' as a special case since it is not stored in the hash table. if (KindID == LLVMContext::MD_dbg) - return DbgLoc.getAsMDNode(getContext()); - + return DbgLoc.getAsMDNode(); + if (!hasMetadataHashEntry()) return nullptr; LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this]; @@ -739,8 +972,8 @@ void Instruction::getAllMetadataImpl( // Handle 'dbg' as a special case since it is not stored in the hash table. if (!DbgLoc.isUnknown()) { - Result.push_back(std::make_pair((unsigned)LLVMContext::MD_dbg, - DbgLoc.getAsMDNode(getContext()))); + Result.push_back( + std::make_pair((unsigned)LLVMContext::MD_dbg, DbgLoc.getAsMDNode())); if (!hasMetadataHashEntry()) return; } @@ -751,7 +984,9 @@ void Instruction::getAllMetadataImpl( getContext().pImpl->MetadataStore.find(this)->second; assert(!Info.empty() && "Shouldn't have called this"); - Result.append(Info.begin(), Info.end()); + Result.reserve(Result.size() + Info.size()); + for (auto &I : Info) + Result.push_back(std::make_pair(I.first, cast(I.second.get()))); // Sort the resulting array so it is stable. if (Result.size() > 1) @@ -767,7 +1002,9 @@ void Instruction::getAllMetadataOtherThanDebugLocImpl( const LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore.find(this)->second; assert(!Info.empty() && "Shouldn't have called this"); - Result.append(Info.begin(), Info.end()); + Result.reserve(Result.size() + Info.size()); + for (auto &I : Info) + Result.push_back(std::make_pair(I.first, cast(I.second.get()))); // Sort the resulting array so it is stable. if (Result.size() > 1) diff --git a/llvm/lib/IR/MetadataTracking.cpp b/llvm/lib/IR/MetadataTracking.cpp new file mode 100644 index 000000000000..5b4b55586a92 --- /dev/null +++ b/llvm/lib/IR/MetadataTracking.cpp @@ -0,0 +1,58 @@ +//===- MetadataTracking.cpp - Implement metadata tracking -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements Metadata tracking. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/MetadataTracking.h" +#include "llvm/IR/Metadata.h" + +using namespace llvm; + +ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) { + if (auto *N = dyn_cast(&MD)) { + if (auto *G = dyn_cast(N)) + return G->ReplaceableUses.get(); + return cast(N); + } + return dyn_cast(&MD); +} + +bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) { + assert(Ref && "Expected live reference"); + assert((Owner || *static_cast(Ref) == &MD) && + "Reference without owner must be direct"); + if (auto *R = ReplaceableMetadataImpl::get(MD)) { + R->addRef(Ref, Owner); + return true; + } + return false; +} + +void MetadataTracking::untrack(void *Ref, Metadata &MD) { + assert(Ref && "Expected live reference"); + if (auto *R = ReplaceableMetadataImpl::get(MD)) + R->dropRef(Ref); +} + +bool MetadataTracking::retrack(void *Ref, Metadata &MD, void *New) { + assert(Ref && "Expected live reference"); + assert(New && "Expected live reference"); + assert(Ref != New && "Expected change"); + if (auto *R = ReplaceableMetadataImpl::get(MD)) { + R->moveRef(Ref, New, MD); + return true; + } + return false; +} + +bool MetadataTracking::isReplaceable(const Metadata &MD) { + return ReplaceableMetadataImpl::get(const_cast(MD)); +} diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 065c66e14917..0781ea4b8082 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -260,8 +260,8 @@ void Module::eraseNamedMetadata(NamedMDNode *NMD) { NamedMDList.erase(NMD); } -bool Module::isValidModFlagBehavior(Value *V, ModFlagBehavior &MFB) { - if (ConstantInt *Behavior = dyn_cast(V)) { +bool Module::isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB) { + if (ConstantInt *Behavior = mdconst::dyn_extract(MD)) { uint64_t Val = Behavior->getLimitedValue(); if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) { MFB = static_cast(Val); @@ -285,7 +285,7 @@ getModuleFlagsMetadata(SmallVectorImpl &Flags) const { // Check the operands of the MDNode before accessing the operands. // The verifier will actually catch these failures. MDString *Key = cast(Flag->getOperand(1)); - Value *Val = Flag->getOperand(2); + Metadata *Val = Flag->getOperand(2); Flags.push_back(ModuleFlagEntry(MFB, Key, Val)); } } @@ -293,7 +293,7 @@ getModuleFlagsMetadata(SmallVectorImpl &Flags) const { /// Return the corresponding value if Key appears in module flags, otherwise /// return null. -Value *Module::getModuleFlag(StringRef Key) const { +Metadata *Module::getModuleFlag(StringRef Key) const { SmallVector ModuleFlags; getModuleFlagsMetadata(ModuleFlags); for (const ModuleFlagEntry &MFE : ModuleFlags) { @@ -321,13 +321,17 @@ NamedMDNode *Module::getOrInsertModuleFlagsMetadata() { /// metadata. It will create the module-level flags named metadata if it doesn't /// already exist. void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, - Value *Val) { + Metadata *Val) { Type *Int32Ty = Type::getInt32Ty(Context); - Value *Ops[3] = { - ConstantInt::get(Int32Ty, Behavior), MDString::get(Context, Key), Val - }; + Metadata *Ops[3] = { + ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Behavior)), + MDString::get(Context, Key), Val}; getOrInsertModuleFlagsMetadata()->addOperand(MDNode::get(Context, Ops)); } +void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, + Constant *Val) { + addModuleFlag(Behavior, Key, ConstantAsMetadata::get(Val)); +} void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, uint32_t Val) { Type *Int32Ty = Type::getInt32Ty(Context); @@ -336,7 +340,7 @@ void Module::addModuleFlag(ModFlagBehavior Behavior, StringRef Key, void Module::addModuleFlag(MDNode *Node) { assert(Node->getNumOperands() == 3 && "Invalid number of operands for module flag!"); - assert(isa(Node->getOperand(0)) && + assert(mdconst::hasa(Node->getOperand(0)) && isa(Node->getOperand(1)) && "Invalid operand types for module flag!"); getOrInsertModuleFlagsMetadata()->addOperand(Node); @@ -459,10 +463,10 @@ void Module::dropAllReferences() { } unsigned Module::getDwarfVersion() const { - Value *Val = getModuleFlag("Dwarf Version"); + auto *Val = cast_or_null(getModuleFlag("Dwarf Version")); if (!Val) return dwarf::DWARF_VERSION; - return cast(Val)->getZExtValue(); + return cast(Val->getValue())->getZExtValue(); } Comdat *Module::getOrInsertComdat(StringRef Name) { @@ -472,12 +476,13 @@ Comdat *Module::getOrInsertComdat(StringRef Name) { } PICLevel::Level Module::getPICLevel() const { - Value *Val = getModuleFlag("PIC Level"); + auto *Val = cast_or_null(getModuleFlag("PIC Level")); if (Val == NULL) return PICLevel::Default; - return static_cast(cast(Val)->getZExtValue()); + return static_cast( + cast(Val->getValue())->getZExtValue()); } void Module::setPICLevel(PICLevel::Level PL) { diff --git a/llvm/lib/IR/TypeFinder.cpp b/llvm/lib/IR/TypeFinder.cpp index 7e92818db5e2..e2fb8f84b186 100644 --- a/llvm/lib/IR/TypeFinder.cpp +++ b/llvm/lib/IR/TypeFinder.cpp @@ -125,8 +125,13 @@ void TypeFinder::incorporateType(Type *Ty) { /// other ways. GlobalValues, basic blocks, instructions, and inst operands are /// all explicitly enumerated. void TypeFinder::incorporateValue(const Value *V) { - if (const MDNode *M = dyn_cast(V)) - return incorporateMDNode(M); + if (const auto *M = dyn_cast(V)) { + if (const auto *N = dyn_cast(M->getMetadata())) + return incorporateMDNode(N); + if (const auto *MDV = dyn_cast(M->getMetadata())) + return incorporateValue(MDV->getValue()); + return; + } if (!isa(V) || isa(V)) return; @@ -152,11 +157,21 @@ void TypeFinder::incorporateValue(const Value *V) { /// find types hiding within. void TypeFinder::incorporateMDNode(const MDNode *V) { // Already visited? - if (!VisitedConstants.insert(V).second) + if (!VisitedMetadata.insert(V).second) return; // Look in operands for types. - for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i) - if (Value *Op = V->getOperand(i)) - incorporateValue(Op); + for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i) { + Metadata *Op = V->getOperand(i); + if (!Op) + continue; + if (auto *N = dyn_cast(Op)) { + incorporateMDNode(N); + continue; + } + if (auto *C = dyn_cast(Op)) { + incorporateValue(C->getValue()); + continue; + } + } } diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index 33b9ed20d14e..d790f9e10898 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -44,9 +44,8 @@ static inline Type *checkType(Type *Ty) { } Value::Value(Type *ty, unsigned scid) - : VTy(checkType(ty)), UseList(nullptr), Name(nullptr), SubclassID(scid), - HasValueHandle(0), SubclassOptionalData(0), SubclassData(0), - NumOperands(0) { + : VTy(checkType(ty)), UseList(nullptr), SubclassID(scid), HasValueHandle(0), + SubclassOptionalData(0), SubclassData(0), NumOperands(0) { // FIXME: Why isn't this in the subclass gunk?? // Note, we cannot call isa before the CallInst has been // constructed. @@ -63,6 +62,8 @@ Value::~Value() { // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsDeleted(this); + if (isUsedByMetadata()) + ValueAsMetadata::handleDeletion(this); #ifndef NDEBUG // Only in -g mode... // Check to make sure that there are no uses of this value that are still @@ -82,13 +83,19 @@ Value::~Value() { // If this value is named, destroy the name. This should not be in a symtab // at this point. - if (Name && SubclassID != MDStringVal) - Name->Destroy(); + destroyValueName(); // There should be no uses of this object anymore, remove it. LeakDetector::removeGarbageObject(this); } +void Value::destroyValueName() { + ValueName *Name = getValueName(); + if (Name) + Name->Destroy(); + setValueName(nullptr); +} + bool Value::hasNUses(unsigned N) const { const_use_iterator UI = use_begin(), E = use_end(); @@ -146,9 +153,7 @@ static bool getSymTab(Value *V, ValueSymbolTable *&ST) { } else if (Argument *A = dyn_cast(V)) { if (Function *P = A->getParent()) ST = &P->getValueSymbolTable(); - } else if (isa(V)) - return true; - else { + } else { assert(isa(V) && "Unknown value type!"); return true; // no name is setable for this. } @@ -159,14 +164,12 @@ StringRef Value::getName() const { // Make sure the empty string is still a C string. For historical reasons, // some clients want to call .data() on the result and expect it to be null // terminated. - if (!Name) return StringRef("", 0); - return Name->getKey(); + if (!getValueName()) + return StringRef("", 0); + return getValueName()->getKey(); } void Value::setName(const Twine &NewName) { - assert(SubclassID != MDStringVal && - "Cannot set the name of MDString with this method!"); - // Fast path for common IRBuilder case of setName("") when there is no name. if (NewName.isTriviallyEmpty() && !hasName()) return; @@ -193,20 +196,17 @@ void Value::setName(const Twine &NewName) { if (!ST) { // No symbol table to update? Just do the change. if (NameRef.empty()) { // Free the name for this value. - Name->Destroy(); - Name = nullptr; + destroyValueName(); return; } - if (Name) - Name->Destroy(); - // NOTE: Could optimize for the case the name is shrinking to not deallocate // then reallocated. + destroyValueName(); // Create the new name. - Name = ValueName::Create(NameRef); - Name->setValue(this); + setValueName(ValueName::Create(NameRef)); + getValueName()->setValue(this); return; } @@ -214,21 +214,18 @@ void Value::setName(const Twine &NewName) { // then reallocated. if (hasName()) { // Remove old name. - ST->removeValueName(Name); - Name->Destroy(); - Name = nullptr; + ST->removeValueName(getValueName()); + destroyValueName(); if (NameRef.empty()) return; } // Name is changing to something new. - Name = ST->createValueName(NameRef, this); + setValueName(ST->createValueName(NameRef, this)); } void Value::takeName(Value *V) { - assert(SubclassID != MDStringVal && "Cannot take the name of an MDString!"); - ValueSymbolTable *ST = nullptr; // If this value has a name, drop it. if (hasName()) { @@ -242,9 +239,8 @@ void Value::takeName(Value *V) { // Remove old name. if (ST) - ST->removeValueName(Name); - Name->Destroy(); - Name = nullptr; + ST->removeValueName(getValueName()); + destroyValueName(); } // Now we know that this has no name. @@ -270,9 +266,9 @@ void Value::takeName(Value *V) { // This works even if both values have no symtab yet. if (ST == VST) { // Take the name! - Name = V->Name; - V->Name = nullptr; - Name->setValue(this); + setValueName(V->getValueName()); + V->setValueName(nullptr); + getValueName()->setValue(this); return; } @@ -280,10 +276,10 @@ void Value::takeName(Value *V) { // then reinsert it into ST. if (VST) - VST->removeValueName(V->Name); - Name = V->Name; - V->Name = nullptr; - Name->setValue(this); + VST->removeValueName(V->getValueName()); + setValueName(V->getValueName()); + V->setValueName(nullptr); + getValueName()->setValue(this); if (ST) ST->reinsertValue(this); @@ -334,6 +330,8 @@ void Value::replaceAllUsesWith(Value *New) { // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsRAUWd(this, New); + if (isUsedByMetadata()) + ValueAsMetadata::handleRAUW(this, New); while (!use_empty()) { Use &U = *UseList; diff --git a/llvm/lib/IR/ValueSymbolTable.cpp b/llvm/lib/IR/ValueSymbolTable.cpp index 2b23f6dd15b6..4f078f09c226 100644 --- a/llvm/lib/IR/ValueSymbolTable.cpp +++ b/llvm/lib/IR/ValueSymbolTable.cpp @@ -38,8 +38,8 @@ void ValueSymbolTable::reinsertValue(Value* V) { assert(V->hasName() && "Can't insert nameless Value into symbol table"); // Try inserting the name, assuming it won't conflict. - if (vmap.insert(V->Name)) { - //DEBUG(dbgs() << " Inserted value: " << V->Name << ": " << *V << "\n"); + if (vmap.insert(V->getValueName())) { + //DEBUG(dbgs() << " Inserted value: " << V->getValueName() << ": " << *V << "\n"); return; } @@ -47,8 +47,8 @@ void ValueSymbolTable::reinsertValue(Value* V) { SmallString<256> UniqueName(V->getName().begin(), V->getName().end()); // The name is too already used, just free it so we can allocate a new name. - V->Name->Destroy(); - + V->getValueName()->Destroy(); + unsigned BaseSize = UniqueName.size(); while (1) { // Trim any suffix off and append the next number. @@ -59,7 +59,7 @@ void ValueSymbolTable::reinsertValue(Value* V) { auto IterBool = vmap.insert(std::make_pair(UniqueName, V)); if (IterBool.second) { // Newly inserted name. Success! - V->Name = &*IterBool.first; + V->setValueName(&*IterBool.first); //DEBUG(dbgs() << " Inserted value: " << UniqueName << ": " << *V << "\n"); return; } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index c025a958385a..6545361793e6 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -102,6 +102,13 @@ struct VerifierSupport { } } + void WriteMetadata(const Metadata *MD) { + if (!MD) + return; + MD->printAsOperand(OS, true, M); + OS << '\n'; + } + void WriteType(Type *T) { if (!T) return; @@ -128,6 +135,24 @@ struct VerifierSupport { Broken = true; } + void CheckFailed(const Twine &Message, const Metadata *V1, const Metadata *V2, + const Metadata *V3 = nullptr, const Metadata *V4 = nullptr) { + OS << Message.str() << "\n"; + WriteMetadata(V1); + WriteMetadata(V2); + WriteMetadata(V3); + WriteMetadata(V4); + Broken = true; + } + + void CheckFailed(const Twine &Message, const Metadata *V1, + const Value *V2 = nullptr) { + OS << Message.str() << "\n"; + WriteMetadata(V1); + WriteValue(V2); + Broken = true; + } + void CheckFailed(const Twine &Message, const Value *V1, Type *T2, const Value *V3 = nullptr) { OS << Message.str() << "\n"; @@ -167,7 +192,7 @@ class Verifier : public InstVisitor, VerifierSupport { SmallPtrSet InstsInThisBlock; /// \brief Keep track of the metadata nodes that have been checked already. - SmallPtrSet MDNodes; + SmallPtrSet MDNodes; /// \brief The personality function referenced by the LandingPadInsts. /// All LandingPadInsts within the same function must use the same @@ -261,7 +286,9 @@ private: void visitAliaseeSubExpr(SmallPtrSetImpl &Visited, const GlobalAlias &A, const Constant &C); void visitNamedMDNode(const NamedMDNode &NMD); - void visitMDNode(MDNode &MD, Function *F); + void visitMDNode(MDNode &MD); + void visitMetadataAsValue(MetadataAsValue &MD, Function *F); + void visitValueAsMetadata(ValueAsMetadata &MD, Function *F); void visitComdat(const Comdat &C); void visitModuleIdents(const Module &M); void visitModuleFlags(const Module &M); @@ -560,46 +587,77 @@ void Verifier::visitNamedMDNode(const NamedMDNode &NMD) { if (!MD) continue; - Assert1(!MD->isFunctionLocal(), - "Named metadata operand cannot be function local!", MD); - visitMDNode(*MD, nullptr); + visitMDNode(*MD); } } -void Verifier::visitMDNode(MDNode &MD, Function *F) { +void Verifier::visitMDNode(MDNode &MD) { // Only visit each node once. Metadata can be mutually recursive, so this // avoids infinite recursion here, as well as being an optimization. if (!MDNodes.insert(&MD).second) return; for (unsigned i = 0, e = MD.getNumOperands(); i != e; ++i) { - Value *Op = MD.getOperand(i); + Metadata *Op = MD.getOperand(i); if (!Op) continue; - if (isa(Op) || isa(Op)) - continue; - if (MDNode *N = dyn_cast(Op)) { - Assert2(MD.isFunctionLocal() || !N->isFunctionLocal(), - "Global metadata operand cannot be function local!", &MD, N); - visitMDNode(*N, F); + Assert2(!isa(Op), "Invalid operand for global metadata!", + &MD, Op); + if (auto *N = dyn_cast(Op)) { + visitMDNode(*N); + continue; + } + if (auto *V = dyn_cast(Op)) { + visitValueAsMetadata(*V, nullptr); continue; } - Assert2(MD.isFunctionLocal(), "Invalid operand for global metadata!", &MD, Op); - - // If this was an instruction, bb, or argument, verify that it is in the - // function that we expect. - Function *ActualF = nullptr; - if (Instruction *I = dyn_cast(Op)) - ActualF = I->getParent()->getParent(); - else if (BasicBlock *BB = dyn_cast(Op)) - ActualF = BB->getParent(); - else if (Argument *A = dyn_cast(Op)) - ActualF = A->getParent(); - assert(ActualF && "Unimplemented function local metadata case!"); - - Assert2(ActualF == F, "function-local metadata used in wrong function", - &MD, Op); } + + // Check these last, so we diagnose problems in operands first. + Assert1(!isa(MD), "Expected no forward declarations!", &MD); + Assert1(MD.isResolved(), "All nodes should be resolved!", &MD); +} + +void Verifier::visitValueAsMetadata(ValueAsMetadata &MD, Function *F) { + Assert1(MD.getValue(), "Expected valid value", &MD); + Assert2(!MD.getValue()->getType()->isMetadataTy(), + "Unexpected metadata round-trip through values", &MD, MD.getValue()); + + auto *L = dyn_cast(&MD); + if (!L) + return; + + Assert1(F, "function-local metadata used outside a function", L); + + // If this was an instruction, bb, or argument, verify that it is in the + // function that we expect. + Function *ActualF = nullptr; + if (Instruction *I = dyn_cast(L->getValue())) { + Assert2(I->getParent(), "function-local metadata not in basic block", L, I); + ActualF = I->getParent()->getParent(); + } else if (BasicBlock *BB = dyn_cast(L->getValue())) + ActualF = BB->getParent(); + else if (Argument *A = dyn_cast(L->getValue())) + ActualF = A->getParent(); + assert(ActualF && "Unimplemented function local metadata case!"); + + Assert1(ActualF == F, "function-local metadata used in wrong function", L); +} + +void Verifier::visitMetadataAsValue(MetadataAsValue &MDV, Function *F) { + Metadata *MD = MDV.getMetadata(); + if (auto *N = dyn_cast(MD)) { + visitMDNode(*N); + return; + } + + // Only visit each node once. Metadata can be mutually recursive, so this + // avoids infinite recursion here, as well as being an optimization. + if (!MDNodes.insert(MD).second) + return; + + if (auto *V = dyn_cast(MD)) + visitValueAsMetadata(*V, F); } void Verifier::visitComdat(const Comdat &C) { @@ -650,7 +708,7 @@ void Verifier::visitModuleFlags(const Module &M) { for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { const MDNode *Requirement = Requirements[I]; const MDString *Flag = cast(Requirement->getOperand(0)); - const Value *ReqValue = Requirement->getOperand(1); + const Metadata *ReqValue = Requirement->getOperand(1); const MDNode *Op = SeenIDs.lookup(Flag); if (!Op) { @@ -679,7 +737,7 @@ Verifier::visitModuleFlag(const MDNode *Op, Module::ModFlagBehavior MFB; if (!Module::isValidModFlagBehavior(Op->getOperand(0), MFB)) { Assert1( - dyn_cast(Op->getOperand(0)), + mdconst::dyn_extract(Op->getOperand(0)), "invalid behavior operand in module flag (expected constant integer)", Op->getOperand(0)); Assert1(false, @@ -1907,9 +1965,11 @@ void Verifier::visitRangeMetadata(Instruction& I, ConstantRange LastRange(1); // Dummy initial value for (unsigned i = 0; i < NumRanges; ++i) { - ConstantInt *Low = dyn_cast(Range->getOperand(2*i)); + ConstantInt *Low = + mdconst::dyn_extract(Range->getOperand(2 * i)); Assert1(Low, "The lower limit must be an integer!", Low); - ConstantInt *High = dyn_cast(Range->getOperand(2*i + 1)); + ConstantInt *High = + mdconst::dyn_extract(Range->getOperand(2 * i + 1)); Assert1(High, "The upper limit must be an integer!", High); Assert1(High->getType() == Low->getType() && High->getType() == Ty, "Range types must match instruction type!", @@ -1932,9 +1992,9 @@ void Verifier::visitRangeMetadata(Instruction& I, } if (NumRanges > 2) { APInt FirstLow = - dyn_cast(Range->getOperand(0))->getValue(); + mdconst::dyn_extract(Range->getOperand(0))->getValue(); APInt FirstHigh = - dyn_cast(Range->getOperand(1))->getValue(); + mdconst::dyn_extract(Range->getOperand(1))->getValue(); ConstantRange FirstRange(FirstLow, FirstHigh); Assert1(FirstRange.intersectWith(LastRange).isEmptySet(), "Intervals are overlapping", Range); @@ -2278,8 +2338,8 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(I.getType()->isFPOrFPVectorTy(), "fpmath requires a floating point result!", &I); Assert1(MD->getNumOperands() == 1, "fpmath takes one operand!", &I); - Value *Op0 = MD->getOperand(0); - if (ConstantFP *CFP0 = dyn_cast_or_null(Op0)) { + if (ConstantFP *CFP0 = + mdconst::dyn_extract_or_null(MD->getOperand(0))) { APFloat Accuracy = CFP0->getValueAPF(); Assert1(Accuracy.isFiniteNonZero() && !Accuracy.isNegative(), "fpmath accuracy not a positive number!", &I); @@ -2496,8 +2556,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { // If the intrinsic takes MDNode arguments, verify that they are either global // or are local to *this* function. for (unsigned i = 0, e = CI.getNumArgOperands(); i != e; ++i) - if (MDNode *MD = dyn_cast(CI.getArgOperand(i))) - visitMDNode(*MD, CI.getParent()->getParent()); + if (auto *MD = dyn_cast(CI.getArgOperand(i))) + visitMetadataAsValue(*MD, CI.getParent()->getParent()); switch (ID) { default: @@ -2509,11 +2569,8 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { "constant int", &CI); break; case Intrinsic::dbg_declare: { // llvm.dbg.declare - Assert1(CI.getArgOperand(0) && isa(CI.getArgOperand(0)), - "invalid llvm.dbg.declare intrinsic call 1", &CI); - MDNode *MD = cast(CI.getArgOperand(0)); - Assert1(MD->getNumOperands() == 1, - "invalid llvm.dbg.declare intrinsic call 2", &CI); + Assert1(CI.getArgOperand(0) && isa(CI.getArgOperand(0)), + "invalid llvm.dbg.declare intrinsic call 1", &CI); } break; case Intrinsic::memcpy: case Intrinsic::memmove: diff --git a/llvm/lib/LTO/LTOModule.cpp b/llvm/lib/LTO/LTOModule.cpp index 4108ef25be0b..678b1801c4a9 100644 --- a/llvm/lib/LTO/LTOModule.cpp +++ b/llvm/lib/LTO/LTOModule.cpp @@ -604,7 +604,7 @@ bool LTOModule::parseSymbols(std::string &errMsg) { /// parseMetadata - Parse metadata from the module void LTOModule::parseMetadata() { // Linker Options - if (Value *Val = getModule().getModuleFlag("Linker Options")) { + if (Metadata *Val = getModule().getModuleFlag("Linker Options")) { MDNode *LinkerOptions = cast(Val); for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { MDNode *MDOptions = cast(LinkerOptions->getOperand(i)); diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index dd637be05aab..bb59400de47c 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -1265,7 +1265,7 @@ bool ModuleLinker::linkModuleFlagsMetadata() { SmallSetVector Requirements; for (unsigned I = 0, E = DstModFlags->getNumOperands(); I != E; ++I) { MDNode *Op = DstModFlags->getOperand(I); - ConstantInt *Behavior = cast(Op->getOperand(0)); + ConstantInt *Behavior = mdconst::extract(Op->getOperand(0)); MDString *ID = cast(Op->getOperand(1)); if (Behavior->getZExtValue() == Module::Require) { @@ -1280,7 +1280,8 @@ bool ModuleLinker::linkModuleFlagsMetadata() { bool HasErr = false; for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) { MDNode *SrcOp = SrcModFlags->getOperand(I); - ConstantInt *SrcBehavior = cast(SrcOp->getOperand(0)); + ConstantInt *SrcBehavior = + mdconst::extract(SrcOp->getOperand(0)); MDString *ID = cast(SrcOp->getOperand(1)); MDNode *DstOp = Flags.lookup(ID); unsigned SrcBehaviorValue = SrcBehavior->getZExtValue(); @@ -1303,7 +1304,8 @@ bool ModuleLinker::linkModuleFlagsMetadata() { } // Otherwise, perform a merge. - ConstantInt *DstBehavior = cast(DstOp->getOperand(0)); + ConstantInt *DstBehavior = + mdconst::extract(DstOp->getOperand(0)); unsigned DstBehaviorValue = DstBehavior->getZExtValue(); // If either flag has override behavior, handle it first. @@ -1317,7 +1319,7 @@ bool ModuleLinker::linkModuleFlagsMetadata() { continue; } else if (SrcBehaviorValue == Module::Override) { // Update the destination flag to that of the source. - DstOp->replaceOperandWith(0, SrcBehavior); + DstOp->replaceOperandWith(0, ConstantAsMetadata::get(SrcBehavior)); DstOp->replaceOperandWith(2, SrcOp->getOperand(2)); continue; } @@ -1352,29 +1354,26 @@ bool ModuleLinker::linkModuleFlagsMetadata() { case Module::Append: { MDNode *DstValue = cast(DstOp->getOperand(2)); MDNode *SrcValue = cast(SrcOp->getOperand(2)); - unsigned NumOps = DstValue->getNumOperands() + SrcValue->getNumOperands(); - Value **VP, **Values = VP = new Value*[NumOps]; - for (unsigned i = 0, e = DstValue->getNumOperands(); i != e; ++i, ++VP) - *VP = DstValue->getOperand(i); - for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i, ++VP) - *VP = SrcValue->getOperand(i); - DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), - ArrayRef(Values, - NumOps))); - delete[] Values; + SmallVector MDs; + MDs.reserve(DstValue->getNumOperands() + SrcValue->getNumOperands()); + for (unsigned i = 0, e = DstValue->getNumOperands(); i != e; ++i) + MDs.push_back(DstValue->getOperand(i)); + for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i) + MDs.push_back(SrcValue->getOperand(i)); + DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), MDs)); break; } case Module::AppendUnique: { - SmallSetVector Elts; + SmallSetVector Elts; MDNode *DstValue = cast(DstOp->getOperand(2)); MDNode *SrcValue = cast(SrcOp->getOperand(2)); for (unsigned i = 0, e = DstValue->getNumOperands(); i != e; ++i) Elts.insert(DstValue->getOperand(i)); for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i) Elts.insert(SrcValue->getOperand(i)); - DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), - ArrayRef(Elts.begin(), - Elts.end()))); + DstOp->replaceOperandWith( + 2, MDNode::get(DstM->getContext(), + makeArrayRef(Elts.begin(), Elts.end()))); break; } } @@ -1384,7 +1383,7 @@ bool ModuleLinker::linkModuleFlagsMetadata() { for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { MDNode *Requirement = Requirements[I]; MDString *Flag = cast(Requirement->getOperand(0)); - Value *ReqValue = Requirement->getOperand(1); + Metadata *ReqValue = Requirement->getOperand(1); MDNode *Op = Flags[Flag]; if (!Op || Op->getOperand(2) != ReqValue) { diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 90f16f58afc6..d3fdbcca2ddc 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -798,7 +798,7 @@ void ARMAsmPrinter::emitAttributes() { if (const Module *SourceModule = MMI->getModule()) { // ABI_PCS_wchar_t to indicate wchar_t width // FIXME: There is no way to emit value 0 (wchar_t prohibited). - if (auto WCharWidthValue = cast_or_null( + if (auto WCharWidthValue = mdconst::extract_or_null( SourceModule->getModuleFlag("wchar_size"))) { int WCharWidth = WCharWidthValue->getZExtValue(); assert((WCharWidth == 2 || WCharWidth == 4) && @@ -809,7 +809,7 @@ void ARMAsmPrinter::emitAttributes() { // ABI_enum_size to indicate enum width // FIXME: There is no way to emit value 0 (enums prohibited) or value 3 // (all enums contain a value needing 32 bits to encode). - if (auto EnumWidthValue = cast_or_null( + if (auto EnumWidthValue = mdconst::extract_or_null( SourceModule->getModuleFlag("min_enum_size"))) { int EnumWidth = EnumWidthValue->getZExtValue(); assert((EnumWidth == 1 || EnumWidth == 4) && diff --git a/llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp b/llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp index 58fa95b54ac4..e50f6de01e13 100644 --- a/llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp @@ -394,31 +394,34 @@ void GenericToNVVM::remapNamedMDNode(Module *M, NamedMDNode *N) { MDNode *GenericToNVVM::remapMDNode(Module *M, MDNode *N) { bool OperandChanged = false; - SmallVector NewOperands; + SmallVector NewOperands; unsigned NumOperands = N->getNumOperands(); // Check if any operand is or contains a global variable in GVMap, and thus // converted to another value. for (unsigned i = 0; i < NumOperands; ++i) { - Value *Operand = N->getOperand(i); - Value *NewOperand = Operand; + Metadata *Operand = N->getOperand(i); + Metadata *NewOperand = Operand; if (Operand) { - if (isa(Operand)) { - GVMapTy::iterator I = GVMap.find(cast(Operand)); - if (I != GVMap.end()) { - NewOperand = I->second; - if (++i < NumOperands) { - NewOperands.push_back(NewOperand); - // Address space of the global variable follows the global variable - // in the global variable debug info (see createGlobalVariable in - // lib/Analysis/DIBuilder.cpp). - NewOperand = - ConstantInt::get(Type::getInt32Ty(M->getContext()), - I->second->getType()->getAddressSpace()); + if (auto *N = dyn_cast(Operand)) { + NewOperand = remapMDNode(M, N); + } else if (auto *C = dyn_cast(Operand)) { + if (auto *G = dyn_cast(C->getValue())) { + GVMapTy::iterator I = GVMap.find(G); + if (I != GVMap.end()) { + NewOperand = ConstantAsMetadata::get(I->second); + if (++i < NumOperands) { + NewOperands.push_back(NewOperand); + // Address space of the global variable follows the global + // variable + // in the global variable debug info (see createGlobalVariable in + // lib/Analysis/DIBuilder.cpp). + NewOperand = ConstantAsMetadata::get( + ConstantInt::get(Type::getInt32Ty(M->getContext()), + I->second->getType()->getAddressSpace())); + } } } - } else if (isa(Operand)) { - NewOperand = remapMDNode(M, cast(Operand)); } } OperandChanged |= Operand != NewOperand; diff --git a/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp b/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp index 5caa8bd12caf..5d896b462096 100644 --- a/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp @@ -52,7 +52,7 @@ static void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) { assert(prop && "Annotation property not a string"); // value - ConstantInt *Val = dyn_cast(md->getOperand(i + 1)); + ConstantInt *Val = mdconst::dyn_extract(md->getOperand(i + 1)); assert(Val && "Value operand not a constant int"); std::string keyname = prop->getString().str(); @@ -75,7 +75,8 @@ static void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) { for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { const MDNode *elem = NMD->getOperand(i); - Value *entity = elem->getOperand(0); + GlobalValue *entity = + mdconst::dyn_extract_or_null(elem->getOperand(0)); // entity may be null due to DCE if (!entity) continue; @@ -322,7 +323,7 @@ bool llvm::getAlign(const CallInst &I, unsigned index, unsigned &align) { if (MDNode *alignNode = I.getMetadata("callalign")) { for (int i = 0, n = alignNode->getNumOperands(); i < n; i++) { if (const ConstantInt *CI = - dyn_cast(alignNode->getOperand(i))) { + mdconst::dyn_extract(alignNode->getOperand(i))) { unsigned v = CI->getZExtValue(); if ((v >> 16) == index) { align = v & 0xFFFF; diff --git a/llvm/lib/Transforms/IPO/StripSymbols.cpp b/llvm/lib/Transforms/IPO/StripSymbols.cpp index 3412b9e915e2..816978ea9ce6 100644 --- a/llvm/lib/Transforms/IPO/StripSymbols.cpp +++ b/llvm/lib/Transforms/IPO/StripSymbols.cpp @@ -301,8 +301,8 @@ bool StripDeadDebugInfo::runOnModule(Module &M) { // For each compile unit, find the live set of global variables/functions and // replace the current list of potentially dead global variables/functions // with the live list. - SmallVector LiveGlobalVariables; - SmallVector LiveSubprograms; + SmallVector LiveGlobalVariables; + SmallVector LiveSubprograms; DenseSet VisitedSet; for (DICompileUnit DIC : F.compile_units()) { diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 1dd828602a33..f70d8f3530a6 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -119,15 +119,14 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { // If the memcpy has metadata describing the members, see if we can // get the TBAA tag describing our copy. if (MDNode *M = MI->getMetadata(LLVMContext::MD_tbaa_struct)) { - if (M->getNumOperands() == 3 && - M->getOperand(0) && - isa(M->getOperand(0)) && - cast(M->getOperand(0))->isNullValue() && + if (M->getNumOperands() == 3 && M->getOperand(0) && + mdconst::hasa(M->getOperand(0)) && + mdconst::extract(M->getOperand(0))->isNullValue() && M->getOperand(1) && - isa(M->getOperand(1)) && - cast(M->getOperand(1))->getValue() == Size && - M->getOperand(2) && - isa(M->getOperand(2))) + mdconst::hasa(M->getOperand(1)) && + mdconst::extract(M->getOperand(1))->getValue() == + Size && + M->getOperand(2) && isa(M->getOperand(2))) CopyMD = cast(M->getOperand(2)); } } @@ -1129,7 +1128,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { cast(RHS)->isNullValue()) { LoadInst* LI = cast(LHS); if (isValidAssumeForContext(II, LI, DL, DT)) { - MDNode* MD = MDNode::get(II->getContext(), ArrayRef()); + MDNode *MD = MDNode::get(II->getContext(), None); LI->setMetadata(LLVMContext::MD_nonnull, MD); return EraseInstFromFunction(*II); } diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 5072d09b2378..b6fcea8ae13d 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -220,8 +220,10 @@ struct LocationMetadata { assert(MDN->getNumOperands() == 3); MDString *MDFilename = cast(MDN->getOperand(0)); Filename = MDFilename->getString(); - LineNo = cast(MDN->getOperand(1))->getLimitedValue(); - ColumnNo = cast(MDN->getOperand(2))->getLimitedValue(); + LineNo = + mdconst::extract(MDN->getOperand(1))->getLimitedValue(); + ColumnNo = + mdconst::extract(MDN->getOperand(2))->getLimitedValue(); } }; @@ -249,23 +251,22 @@ class GlobalsMetadata { for (auto MDN : Globals->operands()) { // Metadata node contains the global and the fields of "Entry". assert(MDN->getNumOperands() == 5); - Value *V = MDN->getOperand(0); + auto *GV = mdconst::extract_or_null(MDN->getOperand(0)); // The optimizer may optimize away a global entirely. - if (!V) + if (!GV) continue; - GlobalVariable *GV = cast(V); // We can already have an entry for GV if it was merged with another // global. Entry &E = Entries[GV]; - if (Value *Loc = MDN->getOperand(1)) - E.SourceLoc.parse(cast(Loc)); - if (Value *Name = MDN->getOperand(2)) { - MDString *MDName = cast(Name); - E.Name = MDName->getString(); - } - ConstantInt *IsDynInit = cast(MDN->getOperand(3)); + if (auto *Loc = cast_or_null(MDN->getOperand(1))) + E.SourceLoc.parse(Loc); + if (auto *Name = cast_or_null(MDN->getOperand(2))) + E.Name = Name->getString(); + ConstantInt *IsDynInit = + mdconst::extract(MDN->getOperand(3)); E.IsDynInit |= IsDynInit->isOne(); - ConstantInt *IsBlacklisted = cast(MDN->getOperand(4)); + ConstantInt *IsBlacklisted = + mdconst::extract(MDN->getOperand(4)); E.IsBlacklisted |= IsBlacklisted->isOne(); } } @@ -496,9 +497,9 @@ struct FunctionStackPoisoner : public InstVisitor { AllocaForValueMapTy AllocaForValue; FunctionStackPoisoner(Function &F, AddressSanitizer &ASan) - : F(F), ASan(ASan), DIB(*F.getParent()), C(ASan.C), - IntptrTy(ASan.IntptrTy), IntptrPtrTy(PointerType::get(IntptrTy, 0)), - Mapping(ASan.Mapping), + : F(F), ASan(ASan), DIB(*F.getParent(), /*AllowUnresolved*/ false), + C(ASan.C), IntptrTy(ASan.IntptrTy), + IntptrPtrTy(PointerType::get(IntptrTy, 0)), Mapping(ASan.Mapping), StackAlignment(1 << Mapping.Scale) {} bool runOnFunction() { diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 34f5ae96b139..7d86e1c8af06 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -275,7 +275,7 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, Load->setAtomic(Monotonic); Load->setAlignment(1); Load->setMetadata(F.getParent()->getMDKindID("nosanitize"), - MDNode::get(*C, ArrayRef())); + MDNode::get(*C, None)); Value *Cmp = IRB.CreateICmpEQ(Constant::getNullValue(Int8Ty), Load); Instruction *Ins = SplitBlockAndInsertIfThen( Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index 95c66742d950..76932e6b600b 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -880,11 +880,9 @@ static void AppendMDNodeToInstForPtr(unsigned NodeId, Sequence OldSeq, Sequence NewSeq) { MDNode *Node = nullptr; - Value *tmp[3] = {PtrSourceMDNodeID, - SequenceToMDString(Inst->getContext(), - OldSeq), - SequenceToMDString(Inst->getContext(), - NewSeq)}; + Metadata *tmp[3] = {PtrSourceMDNodeID, + SequenceToMDString(Inst->getContext(), OldSeq), + SequenceToMDString(Inst->getContext(), NewSeq)}; Node = MDNode::get(Inst->getContext(), tmp); Inst->setMetadata(NodeId, Node); diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp index f60d9903a55f..7844008eb347 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -272,7 +272,8 @@ static unsigned UnrollCountPragmaValue(const Loop *L) { if (MD) { assert(MD->getNumOperands() == 2 && "Unroll count hint metadata should have two operands."); - unsigned Count = cast(MD->getOperand(1))->getZExtValue(); + unsigned Count = + mdconst::extract(MD->getOperand(1))->getZExtValue(); assert(Count >= 1 && "Unroll count must be positive."); return Count; } @@ -288,9 +289,9 @@ static void SetLoopAlreadyUnrolled(Loop *L) { if (!LoopID) return; // First remove any existing loop unrolling metadata. - SmallVector Vals; + SmallVector MDs; // Reserve first location for self reference to the LoopID metadata node. - Vals.push_back(nullptr); + MDs.push_back(nullptr); for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i) { bool IsUnrollMetadata = false; MDNode *MD = dyn_cast(LoopID->getOperand(i)); @@ -298,17 +299,18 @@ static void SetLoopAlreadyUnrolled(Loop *L) { const MDString *S = dyn_cast(MD->getOperand(0)); IsUnrollMetadata = S && S->getString().startswith("llvm.loop.unroll."); } - if (!IsUnrollMetadata) Vals.push_back(LoopID->getOperand(i)); + if (!IsUnrollMetadata) + MDs.push_back(LoopID->getOperand(i)); } // Add unroll(disable) metadata to disable future unrolling. LLVMContext &Context = L->getHeader()->getContext(); - SmallVector DisableOperands; + SmallVector DisableOperands; DisableOperands.push_back(MDString::get(Context, "llvm.loop.unroll.disable")); MDNode *DisableNode = MDNode::get(Context, DisableOperands); - Vals.push_back(DisableNode); + MDs.push_back(DisableNode); - MDNode *NewLoopID = MDNode::get(Context, Vals); + MDNode *NewLoopID = MDNode::get(Context, MDs); // Set operand 0 to refer to the loop id itself. NewLoopID->replaceOperandWith(0, NewLoopID); L->setLoopID(NewLoopID); diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index f9ebd75ec717..45b66674bc95 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -807,12 +807,14 @@ public: void run(const SmallVectorImpl &Insts) { // Retain the debug information attached to the alloca for use when // rewriting loads and stores. - if (MDNode *DebugNode = MDNode::getIfExists(AI.getContext(), &AI)) { - for (User *U : DebugNode->users()) - if (DbgDeclareInst *DDI = dyn_cast(U)) - DDIs.push_back(DDI); - else if (DbgValueInst *DVI = dyn_cast(U)) - DVIs.push_back(DVI); + if (auto *L = LocalAsMetadata::getIfExists(&AI)) { + if (auto *DebugNode = MetadataAsValue::getIfExists(AI.getContext(), L)) { + for (User *U : DebugNode->users()) + if (DbgDeclareInst *DDI = dyn_cast(U)) + DDIs.push_back(DDI); + else if (DbgValueInst *DVI = dyn_cast(U)) + DVIs.push_back(DVI); + } } LoadAndStorePromoter::run(Insts); @@ -3614,7 +3616,7 @@ bool SROA::promoteAllocas(Function &F) { DEBUG(dbgs() << "Promoting allocas with SSAUpdater...\n"); SSAUpdater SSA; - DIBuilder DIB(*F.getParent()); + DIBuilder DIB(*F.getParent(), /*AllowUnresolved*/ false); SmallVector Insts; // We need a worklist to walk the uses of each alloca. diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index f7fa91718620..20644611d2e8 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1068,12 +1068,14 @@ public: void run(AllocaInst *AI, const SmallVectorImpl &Insts) { // Remember which alloca we're promoting (for isInstInList). this->AI = AI; - if (MDNode *DebugNode = MDNode::getIfExists(AI->getContext(), AI)) { - for (User *U : DebugNode->users()) - if (DbgDeclareInst *DDI = dyn_cast(U)) - DDIs.push_back(DDI); - else if (DbgValueInst *DVI = dyn_cast(U)) - DVIs.push_back(DVI); + if (auto *L = LocalAsMetadata::getIfExists(AI)) { + if (auto *DebugNode = MetadataAsValue::getIfExists(AI->getContext(), L)) { + for (User *U : DebugNode->users()) + if (DbgDeclareInst *DDI = dyn_cast(U)) + DDIs.push_back(DDI); + else if (DbgValueInst *DVI = dyn_cast(U)) + DVIs.push_back(DVI); + } } LoadAndStorePromoter::run(Insts); @@ -1420,7 +1422,7 @@ bool SROA::performPromotion(Function &F) { AssumptionTracker *AT = &getAnalysis(); BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function - DIBuilder DIB(*F.getParent()); + DIBuilder DIB(*F.getParent(), /*AllowUnresolved*/ false); bool Changed = false; SmallVector Insts; while (1) { diff --git a/llvm/lib/Transforms/Utils/AddDiscriminators.cpp b/llvm/lib/Transforms/Utils/AddDiscriminators.cpp index f8e5af5c768b..820544bcebf0 100644 --- a/llvm/lib/Transforms/Utils/AddDiscriminators.cpp +++ b/llvm/lib/Transforms/Utils/AddDiscriminators.cpp @@ -167,7 +167,7 @@ bool AddDiscriminators::runOnFunction(Function &F) { bool Changed = false; Module *M = F.getParent(); LLVMContext &Ctx = M->getContext(); - DIBuilder Builder(*M); + DIBuilder Builder(*M, /*AllowUnresolved*/ false); // Traverse all the blocks looking for instructions in different // blocks that are at the same file:line location. diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index 6b86378bc2e4..affe0194d9a7 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -164,8 +164,8 @@ static MDNode* FindSubprogram(const Function *F, DebugInfoFinder &Finder) { // Add an operand to an existing MDNode. The new operand will be added at the // back of the operand list. -static void AddOperand(DICompileUnit CU, DIArray SPs, Value *NewSP) { - SmallVector NewSPs; +static void AddOperand(DICompileUnit CU, DIArray SPs, Metadata *NewSP) { + SmallVector NewSPs; NewSPs.reserve(SPs->getNumOperands() + 1); for (unsigned I = 0, E = SPs->getNumOperands(); I != E; ++I) NewSPs.push_back(SPs->getOperand(I)); diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 2d0b7dcc71c9..147237edbcb5 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -308,7 +308,7 @@ static void CloneAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap) { // Walk the existing metadata, adding the complete (perhaps cyclic) chain to // the set. - SmallVector Queue(MD.begin(), MD.end()); + SmallVector Queue(MD.begin(), MD.end()); while (!Queue.empty()) { const MDNode *M = cast(Queue.pop_back_val()); for (unsigned i = 0, ie = M->getNumOperands(); i != ie; ++i) @@ -320,12 +320,12 @@ static void CloneAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap) { // Now we have a complete set of all metadata in the chains used to specify // the noalias scopes and the lists of those scopes. SmallVector DummyNodes; - DenseMap > MDMap; + DenseMap MDMap; for (SetVector::iterator I = MD.begin(), IE = MD.end(); I != IE; ++I) { MDNode *Dummy = MDNode::getTemporary(CalledFunc->getContext(), None); DummyNodes.push_back(Dummy); - MDMap[*I] = Dummy; + MDMap[*I].reset(Dummy); } // Create new metadata nodes to replace the dummy nodes, replacing old @@ -333,17 +333,17 @@ static void CloneAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap) { // node. for (SetVector::iterator I = MD.begin(), IE = MD.end(); I != IE; ++I) { - SmallVector NewOps; + SmallVector NewOps; for (unsigned i = 0, ie = (*I)->getNumOperands(); i != ie; ++i) { - const Value *V = (*I)->getOperand(i); + const Metadata *V = (*I)->getOperand(i); if (const MDNode *M = dyn_cast(V)) NewOps.push_back(MDMap[M]); else - NewOps.push_back(const_cast(V)); + NewOps.push_back(const_cast(V)); } - MDNode *NewM = MDNode::get(CalledFunc->getContext(), NewOps), - *TempM = MDMap[*I]; + MDNode *NewM = MDNode::get(CalledFunc->getContext(), NewOps); + MDNodeFwdDecl *TempM = cast(MDMap[*I]); TempM->replaceAllUsesWith(NewM); } @@ -516,7 +516,7 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, // need to go through several PHIs to see it, and thus could be // repeated in the Objects list. SmallPtrSet ObjSet; - SmallVector Scopes, NoAliases; + SmallVector Scopes, NoAliases; SmallSetVector NAPtrArgs; for (unsigned i = 0, ie = PtrArgs.size(); i != ie; ++i) { @@ -869,8 +869,9 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI, if (DbgValueInst *DVI = dyn_cast(BI)) { LLVMContext &Ctx = BI->getContext(); MDNode *InlinedAt = BI->getDebugLoc().getInlinedAt(Ctx); - DVI->setOperand(2, createInlinedVariable(DVI->getVariable(), - InlinedAt, Ctx)); + DVI->setOperand(2, MetadataAsValue::get( + Ctx, createInlinedVariable(DVI->getVariable(), + InlinedAt, Ctx))); } } } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index f8f62a9273d5..5decfe506261 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -137,7 +137,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, SmallVector Weights; for (unsigned MD_i = 1, MD_e = MD->getNumOperands(); MD_i < MD_e; ++MD_i) { - ConstantInt* CI = dyn_cast(MD->getOperand(MD_i)); + ConstantInt *CI = + mdconst::dyn_extract(MD->getOperand(MD_i)); assert(CI); Weights.push_back(CI->getValue().getZExtValue()); } @@ -208,8 +209,10 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, SI->getDefaultDest()); MDNode *MD = SI->getMetadata(LLVMContext::MD_prof); if (MD && MD->getNumOperands() == 3) { - ConstantInt *SICase = dyn_cast(MD->getOperand(2)); - ConstantInt *SIDef = dyn_cast(MD->getOperand(1)); + ConstantInt *SICase = + mdconst::dyn_extract(MD->getOperand(2)); + ConstantInt *SIDef = + mdconst::dyn_extract(MD->getOperand(1)); assert(SICase && SIDef); // The TrueWeight should be the weight for the single case of SI. NewBr->setMetadata(LLVMContext::MD_prof, @@ -1048,7 +1051,7 @@ static bool isArray(AllocaInst *AI) { /// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set /// of llvm.dbg.value intrinsics. bool llvm::LowerDbgDeclare(Function &F) { - DIBuilder DIB(*F.getParent()); + DIBuilder DIB(*F.getParent(), /*AllowUnresolved*/ false); SmallVector Dbgs; for (auto &FI : F) for (BasicBlock::iterator BI : FI) @@ -1091,10 +1094,11 @@ bool llvm::LowerDbgDeclare(Function &F) { /// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic describing the /// alloca 'V', if any. DbgDeclareInst *llvm::FindAllocaDbgDeclare(Value *V) { - if (MDNode *DebugNode = MDNode::getIfExists(V->getContext(), V)) - for (User *U : DebugNode->users()) - if (DbgDeclareInst *DDI = dyn_cast(U)) - return DDI; + if (auto *L = LocalAsMetadata::getIfExists(V)) + if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L)) + for (User *U : MDV->users()) + if (DbgDeclareInst *DDI = dyn_cast(U)) + return DDI; return nullptr; } diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index 3d9133684db1..f12cd61d463a 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -217,9 +217,9 @@ static void CloneLoopBlocks(Loop *L, Value *NewIter, const bool UnrollProlog, } if (NewLoop) { // Add unroll disable metadata to disable future unrolling for this loop. - SmallVector Vals; + SmallVector MDs; // Reserve first location for self reference to the LoopID metadata node. - Vals.push_back(nullptr); + MDs.push_back(nullptr); MDNode *LoopID = NewLoop->getLoopID(); if (LoopID) { // First remove any existing loop unrolling metadata. @@ -230,17 +230,18 @@ static void CloneLoopBlocks(Loop *L, Value *NewIter, const bool UnrollProlog, const MDString *S = dyn_cast(MD->getOperand(0)); IsUnrollMetadata = S && S->getString().startswith("llvm.loop.unroll."); } - if (!IsUnrollMetadata) Vals.push_back(LoopID->getOperand(i)); + if (!IsUnrollMetadata) + MDs.push_back(LoopID->getOperand(i)); } } LLVMContext &Context = NewLoop->getHeader()->getContext(); - SmallVector DisableOperands; + SmallVector DisableOperands; DisableOperands.push_back(MDString::get(Context, "llvm.loop.unroll.disable")); MDNode *DisableNode = MDNode::get(Context, DisableOperands); - Vals.push_back(DisableNode); + MDs.push_back(DisableNode); - MDNode *NewLoopID = MDNode::get(Context, Vals); + MDNode *NewLoopID = MDNode::get(Context, MDs); // Set operand 0 to refer to the loop id itself. NewLoopID->replaceOperandWith(0, NewLoopID); NewLoop->setLoopID(NewLoopID); diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index 1fd70711f531..1b1da6963cf5 100644 --- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -284,7 +284,8 @@ public: PromoteMem2Reg(ArrayRef Allocas, DominatorTree &DT, AliasSetTracker *AST, AssumptionTracker *AT) : Allocas(Allocas.begin(), Allocas.end()), DT(DT), - DIB(*DT.getRoot()->getParent()->getParent()), AST(AST), AT(AT) {} + DIB(*DT.getRoot()->getParent()->getParent(), /*AllowUnresolved*/ false), + AST(AST), AT(AT) {} void run(); @@ -415,7 +416,8 @@ static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, // Record debuginfo for the store and remove the declaration's // debuginfo. if (DbgDeclareInst *DDI = Info.DbgDeclare) { - DIBuilder DIB(*AI->getParent()->getParent()->getParent()); + DIBuilder DIB(*AI->getParent()->getParent()->getParent(), + /*AllowUnresolved*/ false); ConvertDebugDeclareToDebugValue(DDI, Info.OnlyStore, DIB); DDI->eraseFromParent(); LBI.deleteValue(DDI); @@ -498,7 +500,8 @@ static void promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info, StoreInst *SI = cast(AI->user_back()); // Record debuginfo for the store before removing it. if (DbgDeclareInst *DDI = Info.DbgDeclare) { - DIBuilder DIB(*AI->getParent()->getParent()->getParent()); + DIBuilder DIB(*AI->getParent()->getParent()->getParent(), + /*AllowUnresolved*/ false); ConvertDebugDeclareToDebugValue(DDI, SI, DIB); } SI->eraseFromParent(); diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index daa576cfbdc9..5f55b89b0f90 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -713,8 +713,7 @@ SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI, if (HasWeight) for (unsigned MD_i = 1, MD_e = MD->getNumOperands(); MD_i < MD_e; ++MD_i) { - ConstantInt* CI = dyn_cast(MD->getOperand(MD_i)); - assert(CI); + ConstantInt *CI = mdconst::extract(MD->getOperand(MD_i)); Weights.push_back(CI->getValue().getZExtValue()); } for (SwitchInst::CaseIt i = SI->case_end(), e = SI->case_begin(); i != e;) { @@ -819,7 +818,7 @@ static void GetBranchWeights(TerminatorInst *TI, MDNode *MD = TI->getMetadata(LLVMContext::MD_prof); assert(MD); for (unsigned i = 1, e = MD->getNumOperands(); i < e; ++i) { - ConstantInt *CI = cast(MD->getOperand(i)); + ConstantInt *CI = mdconst::extract(MD->getOperand(i)); Weights.push_back(CI->getValue().getZExtValue()); } @@ -2037,8 +2036,10 @@ static bool ExtractBranchMetadata(BranchInst *BI, "Looking for probabilities on unconditional branch?"); MDNode *ProfileData = BI->getMetadata(LLVMContext::MD_prof); if (!ProfileData || ProfileData->getNumOperands() != 3) return false; - ConstantInt *CITrue = dyn_cast(ProfileData->getOperand(1)); - ConstantInt *CIFalse = dyn_cast(ProfileData->getOperand(2)); + ConstantInt *CITrue = + mdconst::dyn_extract(ProfileData->getOperand(1)); + ConstantInt *CIFalse = + mdconst::dyn_extract(ProfileData->getOperand(2)); if (!CITrue || !CIFalse) return false; ProbTrue = CITrue->getValue().getZExtValue(); ProbFalse = CIFalse->getValue().getZExtValue(); diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index a2f69d1f10b4..d735e279d08b 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -40,7 +40,7 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags, // Global values do not need to be seeded into the VM if they // are using the identity mapping. - if (isa(V) || isa(V)) + if (isa(V)) return VM[V] = const_cast(V); if (const InlineAsm *IA = dyn_cast(V)) { @@ -56,57 +56,24 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags, return VM[V] = const_cast(V); } - - if (const MDNode *MD = dyn_cast(V)) { + if (const auto *MDV = dyn_cast(V)) { + const Metadata *MD = MDV->getMetadata(); // If this is a module-level metadata and we know that nothing at the module // level is changing, then use an identity mapping. - if (!MD->isFunctionLocal() && (Flags & RF_NoModuleLevelChanges)) - return VM[V] = const_cast(V); - - // Create a dummy node in case we have a metadata cycle. - MDNode *Dummy = MDNode::getTemporary(V->getContext(), None); - VM[V] = Dummy; - - // Check all operands to see if any need to be remapped. - for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) { - Value *OP = MD->getOperand(i); - if (!OP) continue; - Value *Mapped_OP = MapValue(OP, VM, Flags, TypeMapper, Materializer); - // Use identity map if Mapped_Op is null and we can ignore missing - // entries. - if (Mapped_OP == OP || - (Mapped_OP == nullptr && (Flags & RF_IgnoreMissingEntries))) - continue; + if (!isa(MD) && (Flags & RF_NoModuleLevelChanges)) + return VM[V] = const_cast(V); - // Ok, at least one operand needs remapping. - SmallVector Elts; - Elts.reserve(MD->getNumOperands()); - for (i = 0; i != e; ++i) { - Value *Op = MD->getOperand(i); - if (!Op) - Elts.push_back(nullptr); - else { - Value *Mapped_Op = MapValue(Op, VM, Flags, TypeMapper, Materializer); - // Use identity map if Mapped_Op is null and we can ignore missing - // entries. - if (Mapped_Op == nullptr && (Flags & RF_IgnoreMissingEntries)) - Mapped_Op = Op; - Elts.push_back(Mapped_Op); - } - } - MDNode *NewMD = MDNode::get(V->getContext(), Elts); - Dummy->replaceAllUsesWith(NewMD); - VM[V] = NewMD; - MDNode::deleteTemporary(Dummy); - return NewMD; - } + auto *MappedMD = MapValue(MD, VM, Flags, TypeMapper, Materializer); + if (MD == MappedMD || (!MappedMD && (Flags & RF_IgnoreMissingEntries))) + return VM[V] = const_cast(V); - VM[V] = const_cast(V); - MDNode::deleteTemporary(Dummy); - - // No operands needed remapping. Use an identity mapping. - return const_cast(V); + // FIXME: This assert crashes during bootstrap, but I think it should be + // correct. For now, just match behaviour from before the metadata/value + // split. + // + // assert(MappedMD && "Referenced metadata value not in value map"); + return VM[V] = MetadataAsValue::get(V->getContext(), MappedMD); } // Okay, this either must be a constant (which may or may not be mappable) or @@ -177,6 +144,120 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags, return VM[V] = ConstantPointerNull::get(cast(NewTy)); } +static Metadata *map(ValueToValueMapTy &VM, const Metadata *Key, + Metadata *Val) { + VM.MD()[Key].reset(Val); + return Val; +} + +static Metadata *mapToSelf(ValueToValueMapTy &VM, const Metadata *MD) { + return map(VM, MD, const_cast(MD)); +} + +static Metadata *MapValueImpl(const Metadata *MD, ValueToValueMapTy &VM, + RemapFlags Flags, + ValueMapTypeRemapper *TypeMapper, + ValueMaterializer *Materializer) { + // If the value already exists in the map, use it. + if (Metadata *NewMD = VM.MD().lookup(MD).get()) + return NewMD; + + if (isa(MD)) + return mapToSelf(VM, MD); + + if (isa(MD)) + if ((Flags & RF_NoModuleLevelChanges)) + return mapToSelf(VM, MD); + + if (const auto *VMD = dyn_cast(MD)) { + Value *MappedV = + MapValue(VMD->getValue(), VM, Flags, TypeMapper, Materializer); + if (VMD->getValue() == MappedV || + (!MappedV && (Flags & RF_IgnoreMissingEntries))) + return mapToSelf(VM, MD); + + // FIXME: This assert crashes during bootstrap, but I think it should be + // correct. For now, just match behaviour from before the metadata/value + // split. + // + // assert(MappedV && "Referenced metadata not in value map!"); + if (MappedV) + return map(VM, MD, ValueAsMetadata::get(MappedV)); + return nullptr; + } + + const MDNode *Node = cast(MD); + assert(Node->isResolved() && "Unexpected unresolved node"); + + auto getMappedOp = [&](Metadata *Op) -> Metadata *{ + if (!Op) + return nullptr; + if (Metadata *MappedOp = + MapValueImpl(Op, VM, Flags, TypeMapper, Materializer)) + return MappedOp; + // Use identity map if MappedOp is null and we can ignore missing entries. + if (Flags & RF_IgnoreMissingEntries) + return Op; + + // FIXME: This assert crashes during bootstrap, but I think it should be + // correct. For now, just match behaviour from before the metadata/value + // split. + // + // llvm_unreachable("Referenced metadata not in value map!"); + return nullptr; + }; + + // If this is a module-level metadata and we know that nothing at the + // module level is changing, then use an identity mapping. + if (Flags & RF_NoModuleLevelChanges) + return mapToSelf(VM, MD); + + // Create a dummy node in case we have a metadata cycle. + MDNodeFwdDecl *Dummy = MDNode::getTemporary(Node->getContext(), None); + map(VM, Node, Dummy); + + // Check all operands to see if any need to be remapped. + for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I) { + Metadata *Op = Node->getOperand(I); + Metadata *MappedOp = getMappedOp(Op); + if (Op == MappedOp) + continue; + + // Ok, at least one operand needs remapping. + SmallVector Elts; + Elts.reserve(Node->getNumOperands()); + for (I = 0; I != E; ++I) + Elts.push_back(getMappedOp(Node->getOperand(I))); + + MDNode *NewMD = MDNode::get(Node->getContext(), Elts); + Dummy->replaceAllUsesWith(NewMD); + MDNode::deleteTemporary(Dummy); + return map(VM, Node, NewMD); + } + + // No operands needed remapping. Use an identity mapping. + mapToSelf(VM, MD); + MDNode::deleteTemporary(Dummy); + return const_cast(MD); +} + +Metadata *llvm::MapValue(const Metadata *MD, ValueToValueMapTy &VM, + RemapFlags Flags, ValueMapTypeRemapper *TypeMapper, + ValueMaterializer *Materializer) { + Metadata *NewMD = MapValueImpl(MD, VM, Flags, TypeMapper, Materializer); + if (NewMD && NewMD != MD) + if (auto *G = dyn_cast(NewMD)) + G->resolveCycles(); + return NewMD; +} + +MDNode *llvm::MapValue(const MDNode *MD, ValueToValueMapTy &VM, + RemapFlags Flags, ValueMapTypeRemapper *TypeMapper, + ValueMaterializer *Materializer) { + return cast(MapValue(static_cast(MD), VM, Flags, + TypeMapper, Materializer)); +} + /// RemapInstruction - Convert the instruction operands from referencing the /// current values into those specified by VMap. /// diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 83e19f406dec..3c543530a438 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1097,7 +1097,7 @@ private: for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i) { const MDString *S = nullptr; - SmallVector Args; + SmallVector Args; // The expected hint is either a MDString or a MDNode with the first // operand a MDString. @@ -1123,12 +1123,12 @@ private: } /// Checks string hint with one operand and set value if valid. - void setHint(StringRef Name, Value *Arg) { + void setHint(StringRef Name, Metadata *Arg) { if (!Name.startswith(Prefix())) return; Name = Name.substr(Prefix().size(), StringRef::npos); - const ConstantInt *C = dyn_cast(Arg); + const ConstantInt *C = mdconst::dyn_extract(Arg); if (!C) return; unsigned Val = C->getZExtValue(); @@ -1147,9 +1147,10 @@ private: /// Create a new hint from name / value pair. MDNode *createHintMetadata(StringRef Name, unsigned V) const { LLVMContext &Context = TheLoop->getHeader()->getContext(); - Value *Vals[] = {MDString::get(Context, Name), - ConstantInt::get(Type::getInt32Ty(Context), V)}; - return MDNode::get(Context, Vals); + Metadata *MDs[] = {MDString::get(Context, Name), + ConstantAsMetadata::get( + ConstantInt::get(Type::getInt32Ty(Context), V))}; + return MDNode::get(Context, MDs); } /// Matches metadata with hint name. @@ -1170,7 +1171,7 @@ private: return; // Reserve the first element to LoopID (see below). - SmallVector Vals(1); + SmallVector MDs(1); // If the loop already has metadata, then ignore the existing operands. MDNode *LoopID = TheLoop->getLoopID(); if (LoopID) { @@ -1178,18 +1179,17 @@ private: MDNode *Node = cast(LoopID->getOperand(i)); // If node in update list, ignore old value. if (!matchesHintMetadataName(Node, HintTypes)) - Vals.push_back(Node); + MDs.push_back(Node); } } // Now, add the missing hints. for (auto H : HintTypes) - Vals.push_back( - createHintMetadata(Twine(Prefix(), H.Name).str(), H.Value)); + MDs.push_back(createHintMetadata(Twine(Prefix(), H.Name).str(), H.Value)); // Replace current metadata node with new one. LLVMContext &Context = TheLoop->getHeader()->getContext(); - MDNode *NewLoopID = MDNode::get(Context, Vals); + MDNode *NewLoopID = MDNode::get(Context, MDs); // Set operand 0 to refer to the loop id itself. NewLoopID->replaceOperandWith(0, NewLoopID); diff --git a/llvm/test/Assembler/functionlocal-metadata-attachments.ll b/llvm/test/Assembler/functionlocal-metadata-attachments.ll index 71d8fa1b0e1f..20cb0a9218c5 100644 --- a/llvm/test/Assembler/functionlocal-metadata-attachments.ll +++ b/llvm/test/Assembler/functionlocal-metadata-attachments.ll @@ -2,6 +2,6 @@ define void @foo(i32 %v) { entry: -; CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: unexpected function-local metadata +; CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: invalid use of function-local name ret void, !foo !{i32 %v} } diff --git a/llvm/test/Assembler/functionlocal-metadata-complex-3.ll b/llvm/test/Assembler/functionlocal-metadata-complex-3.ll index 1590efa72b6d..647f93ecabe0 100644 --- a/llvm/test/Assembler/functionlocal-metadata-complex-3.ll +++ b/llvm/test/Assembler/functionlocal-metadata-complex-3.ll @@ -2,7 +2,7 @@ define void @foo(i32 %v) { entry: -; CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: unexpected nested function-local metadata +; CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: invalid use of function-local name call void @llvm.bar(metadata !{metadata !{i32 %v}}) ret void } diff --git a/llvm/test/Feature/metadata.ll b/llvm/test/Feature/metadata.ll index f83b7fe9c329..d1cc706fb1f3 100644 --- a/llvm/test/Feature/metadata.ll +++ b/llvm/test/Feature/metadata.ll @@ -2,7 +2,7 @@ ; PR7105 define void @foo(i32 %x) { - call void @llvm.zonk(metadata !1, i64 0, metadata !1) + call void @llvm.zonk(metadata !{i32 %x}, i64 0, metadata !1) store i32 0, i32* null, !whatever !0, !whatever_else !{}, !more !{metadata !"hello"} store i32 0, i32* null, !whatever !{metadata !"hello", metadata !1, metadata !{}, metadata !2} ret void diff --git a/llvm/test/Linker/Inputs/unique-fwd-decl-order.ll b/llvm/test/Linker/Inputs/unique-fwd-decl-order.ll new file mode 100644 index 000000000000..756e37903cab --- /dev/null +++ b/llvm/test/Linker/Inputs/unique-fwd-decl-order.ll @@ -0,0 +1,6 @@ +!named = !{!0} + +; These nodes are intentionally in the opposite order from the test-driver. +; However, they are numbered the same for the reader's convenience. +!1 = metadata !{} +!0 = metadata !{metadata !1} diff --git a/llvm/test/Linker/unique-fwd-decl-order.ll b/llvm/test/Linker/unique-fwd-decl-order.ll new file mode 100644 index 000000000000..d356cf36a3f4 --- /dev/null +++ b/llvm/test/Linker/unique-fwd-decl-order.ll @@ -0,0 +1,20 @@ +; RUN: llvm-link %s %S/Inputs/unique-fwd-decl-order.ll -S -o - | FileCheck %s +; RUN: llvm-link %S/Inputs/unique-fwd-decl-order.ll %s -S -o - | FileCheck %s + +; This test exercises MDNode hashing. For the nodes to be correctly uniqued, +; the hash of a to-be-created MDNode has to match the hash of an +; operand-just-changed MDNode (with the same operands). +; +; Note that these two assembly files number the nodes identically, even though +; the nodes are in a different order. This is for the reader's convenience. + +; CHECK: !named = !{!0, !0} +!named = !{!0} + +; CHECK: !0 = metadata !{metadata !1} +!0 = metadata !{metadata !1} + +; CHECK: !1 = metadata !{} +!1 = metadata !{} + +; CHECK-NOT: !2 diff --git a/llvm/test/Transforms/GlobalOpt/metadata.ll b/llvm/test/Transforms/GlobalOpt/metadata.ll index cfa2926e18c0..f3740e1a58c3 100644 --- a/llvm/test/Transforms/GlobalOpt/metadata.ll +++ b/llvm/test/Transforms/GlobalOpt/metadata.ll @@ -13,15 +13,20 @@ define i32 @main(i32 %argc, i8** %argv) { } define void @foo(i32 %x) { - call void @llvm.foo(metadata !{i8*** @G}) -; CHECK: call void @llvm.foo(metadata !0) +; Note: these arguments look like MDNodes, but they're really syntactic sugar +; for 'MetadataAsValue::get(ValueAsMetadata::get(Value*))'. When @G drops to +; null, the ValueAsMetadata instance gets replaced by metadata !{}, or +; MDNode::get({}). + call void @llvm.foo(metadata !{i8*** @G}, metadata !{i32 %x}) +; CHECK: call void @llvm.foo(metadata ![[EMPTY:[0-9]+]], metadata !{i32 %x}) ret void } -declare void @llvm.foo(metadata) nounwind readnone +declare void @llvm.foo(metadata, metadata) nounwind readnone !named = !{!0} -; CHECK: !named = !{!0} +; CHECK: !named = !{![[NULL:[0-9]+]]} !0 = metadata !{i8*** @G} -; CHECK: !0 = metadata !{null} +; CHECK-DAG: ![[NULL]] = metadata !{null} +; CHECK-DAG: ![[EMPTY]] = metadata !{} diff --git a/llvm/unittests/IR/MDBuilderTest.cpp b/llvm/unittests/IR/MDBuilderTest.cpp index fc4674ea1357..ab2d34e89db6 100644 --- a/llvm/unittests/IR/MDBuilderTest.cpp +++ b/llvm/unittests/IR/MDBuilderTest.cpp @@ -36,10 +36,10 @@ TEST_F(MDBuilderTest, createFPMath) { EXPECT_EQ(MD0, (MDNode *)nullptr); EXPECT_NE(MD1, (MDNode *)nullptr); EXPECT_EQ(MD1->getNumOperands(), 1U); - Value *Op = MD1->getOperand(0); - EXPECT_TRUE(isa(Op)); - EXPECT_TRUE(Op->getType()->isFloatingPointTy()); - ConstantFP *Val = cast(Op); + Metadata *Op = MD1->getOperand(0); + EXPECT_TRUE(mdconst::hasa(Op)); + ConstantFP *Val = mdconst::extract(Op); + EXPECT_TRUE(Val->getType()->isFloatingPointTy()); EXPECT_TRUE(Val->isExactlyValue(1.0)); } TEST_F(MDBuilderTest, createRangeMetadata) { @@ -50,10 +50,10 @@ TEST_F(MDBuilderTest, createRangeMetadata) { EXPECT_EQ(R0, (MDNode *)nullptr); EXPECT_NE(R1, (MDNode *)nullptr); EXPECT_EQ(R1->getNumOperands(), 2U); - EXPECT_TRUE(isa(R1->getOperand(0))); - EXPECT_TRUE(isa(R1->getOperand(1))); - ConstantInt *C0 = cast(R1->getOperand(0)); - ConstantInt *C1 = cast(R1->getOperand(1)); + EXPECT_TRUE(mdconst::hasa(R1->getOperand(0))); + EXPECT_TRUE(mdconst::hasa(R1->getOperand(1))); + ConstantInt *C0 = mdconst::extract(R1->getOperand(0)); + ConstantInt *C1 = mdconst::extract(R1->getOperand(1)); EXPECT_EQ(C0->getValue(), A); EXPECT_EQ(C1->getValue(), B); } @@ -101,7 +101,8 @@ TEST_F(MDBuilderTest, createTBAANode) { EXPECT_EQ(N0->getOperand(1), R); EXPECT_EQ(N1->getOperand(1), R); EXPECT_EQ(N2->getOperand(1), R); - EXPECT_TRUE(isa(N2->getOperand(2))); - EXPECT_EQ(cast(N2->getOperand(2))->getZExtValue(), 1U); + EXPECT_TRUE(mdconst::hasa(N2->getOperand(2))); + EXPECT_EQ(mdconst::extract(N2->getOperand(2))->getZExtValue(), + 1U); } } diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index 0e2599051fe1..d45aaae9316e 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -13,7 +13,6 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" -#include "llvm/IR/ValueHandle.h" #include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" using namespace llvm; @@ -80,17 +79,18 @@ TEST_F(MDNodeTest, Simple) { MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); MDString *s2 = MDString::get(Context, StringRef(&y[0], 3)); - ConstantInt *CI = ConstantInt::get(getGlobalContext(), APInt(8, 0)); + ConstantAsMetadata *CI = ConstantAsMetadata::get( + ConstantInt::get(getGlobalContext(), APInt(8, 0))); - std::vector V; + std::vector V; V.push_back(s1); V.push_back(CI); V.push_back(s2); MDNode *n1 = MDNode::get(Context, V); - Value *const c1 = n1; + Metadata *const c1 = n1; MDNode *n2 = MDNode::get(Context, c1); - Value *const c2 = n2; + Metadata *const c2 = n2; MDNode *n3 = MDNode::get(Context, V); MDNode *n4 = MDNode::getIfExists(Context, V); MDNode *n5 = MDNode::getIfExists(Context, c1); @@ -99,7 +99,7 @@ TEST_F(MDNodeTest, Simple) { EXPECT_EQ(n1, n3); EXPECT_EQ(n4, n1); EXPECT_EQ(n5, n2); - EXPECT_EQ(n6, (Value*)nullptr); + EXPECT_EQ(n6, (Metadata *)nullptr); EXPECT_EQ(3u, n1->getNumOperands()); EXPECT_EQ(s1, n1->getOperand(0)); @@ -114,9 +114,9 @@ TEST_F(MDNodeTest, Delete) { Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1); Instruction *I = new BitCastInst(C, Type::getInt32Ty(getGlobalContext())); - Value *const V = I; + Metadata *const V = LocalAsMetadata::get(I); MDNode *n = MDNode::get(Context, V); - WeakVH wvh = n; + TrackingMDRef wvh(n); EXPECT_EQ(n, wvh); @@ -128,7 +128,7 @@ TEST_F(MDNodeTest, SelfReference) { // !1 = metadata !{metadata !0} { MDNode *Temp = MDNode::getTemporary(Context, None); - Value *Args[] = {Temp}; + Metadata *Args[] = {Temp}; MDNode *Self = MDNode::get(Context, Args); Self->replaceOperandWith(0, Self); MDNode::deleteTemporary(Temp); @@ -147,7 +147,7 @@ TEST_F(MDNodeTest, SelfReference) { // !1 = metadata !{metadata !0, metadata !{}} { MDNode *Temp = MDNode::getTemporary(Context, None); - Value *Args[] = {Temp, MDNode::get(Context, None)}; + Metadata *Args[] = {Temp, MDNode::get(Context, None)}; MDNode *Self = MDNode::get(Context, Args); Self->replaceOperandWith(0, Self); MDNode::deleteTemporary(Temp); @@ -163,13 +163,59 @@ TEST_F(MDNodeTest, SelfReference) { } } +typedef MetadataTest MetadataAsValueTest; + +TEST_F(MetadataAsValueTest, MDNode) { + MDNode *N = MDNode::get(Context, None); + auto *V = MetadataAsValue::get(Context, N); + EXPECT_TRUE(V->getType()->isMetadataTy()); + EXPECT_EQ(N, V->getMetadata()); + + auto *V2 = MetadataAsValue::get(Context, N); + EXPECT_EQ(V, V2); +} + +TEST_F(MetadataAsValueTest, MDNodeMDNode) { + MDNode *N = MDNode::get(Context, None); + Metadata *Ops[] = {N}; + MDNode *N2 = MDNode::get(Context, Ops); + auto *V = MetadataAsValue::get(Context, N2); + EXPECT_TRUE(V->getType()->isMetadataTy()); + EXPECT_EQ(N2, V->getMetadata()); + + auto *V2 = MetadataAsValue::get(Context, N2); + EXPECT_EQ(V, V2); + + auto *V3 = MetadataAsValue::get(Context, N); + EXPECT_TRUE(V3->getType()->isMetadataTy()); + EXPECT_NE(V, V3); + EXPECT_EQ(N, V3->getMetadata()); +} + +TEST_F(MetadataAsValueTest, MDNodeConstant) { + auto *C = ConstantInt::getTrue(Context); + auto *MD = ConstantAsMetadata::get(C); + Metadata *Ops[] = {MD}; + auto *N = MDNode::get(Context, Ops); + + auto *V = MetadataAsValue::get(Context, MD); + EXPECT_TRUE(V->getType()->isMetadataTy()); + EXPECT_EQ(MD, V->getMetadata()); + + auto *V2 = MetadataAsValue::get(Context, N); + EXPECT_EQ(MD, V2->getMetadata()); + EXPECT_EQ(V, V2); +} + TEST(NamedMDNodeTest, Search) { LLVMContext Context; - Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1); - Constant *C2 = ConstantInt::get(Type::getInt32Ty(Context), 2); + ConstantAsMetadata *C = + ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 1)); + ConstantAsMetadata *C2 = + ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 2)); - Value *const V = C; - Value *const V2 = C2; + Metadata *const V = C; + Metadata *const V2 = C2; MDNode *n = MDNode::get(Context, V); MDNode *n2 = MDNode::get(Context, V2);