[llvm-branch-commits] [clang] 8e89598 - [ClassicFlang] Merge PGI changes from release_90 branch
Bryan Chan via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jun 24 08:40:56 PDT 2020
Author: Bryan Chan
Date: 2020-06-23T06:29:57-04:00
New Revision: 8e89598ddff8d61e4a4399104cebdfdcbe3ae233
URL: https://github.com/llvm/llvm-project/commit/8e89598ddff8d61e4a4399104cebdfdcbe3ae233
DIFF: https://github.com/llvm/llvm-project/commit/8e89598ddff8d61e4a4399104cebdfdcbe3ae233.diff
LOG: [ClassicFlang] Merge PGI changes from release_90 branch
Cherry-picked 2085211cfcca70411dc63f0d08763facc8a02090 by Eric Schweitz, and
resolved merge conflicts.
Added:
Modified:
clang/lib/CodeGen/CGDebugInfo.cpp
llvm/include/llvm-c/DebugInfo.h
llvm/include/llvm/Analysis/TargetLibraryInfo.h
llvm/include/llvm/Bitcode/LLVMBitCodes.h
llvm/include/llvm/IR/DIBuilder.h
llvm/include/llvm/IR/DebugInfoMetadata.h
llvm/include/llvm/IR/Metadata.def
llvm/lib/Analysis/TargetLibraryInfo.cpp
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/Bitcode/Reader/MetadataLoader.cpp
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp
llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
llvm/lib/IR/AsmWriter.cpp
llvm/lib/IR/DIBuilder.cpp
llvm/lib/IR/DebugInfo.cpp
llvm/lib/IR/DebugInfoMetadata.cpp
llvm/lib/IR/LLVMContextImpl.h
llvm/lib/IR/Verifier.cpp
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
llvm/tools/llvm-c-test/debuginfo.c
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index cbd524eda9d0..b0ac528fade2 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3430,7 +3430,8 @@ CGDebugInfo::getGlobalVariableForwardDeclaration(const VarDecl *VD) {
auto Align = getDeclAlignIfRequired(VD, CGM.getContext());
auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit),
- !VD->isExternallyVisible(), nullptr, TemplateParameters, Align);
+ !VD->isExternallyVisible(), nullptr, TemplateParameters,
+ llvm::DINode::FlagZero, Align);
FwdDeclReplaceMap.emplace_back(
std::piecewise_construct,
std::make_tuple(cast<VarDecl>(VD->getCanonicalDecl())),
@@ -4506,7 +4507,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
Var->hasLocalLinkage(), true,
Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
- Align);
+ llvm::DINode::FlagZero, Align);
Var->addDebugInfo(GVE);
}
DeclCache[D->getCanonicalDecl()].reset(GVE);
@@ -4607,7 +4608,7 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
GV.reset(DBuilder.createGlobalVariableExpression(
DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty,
true, true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
- TemplateParameters, Align));
+ TemplateParameters, llvm::DINode::FlagZero, Align));
}
void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var,
@@ -4625,7 +4626,8 @@ void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var,
llvm::DIGlobalVariableExpression *GVE =
DBuilder.createGlobalVariableExpression(
DContext, Name, StringRef(), Unit, getLineNumber(D->getLocation()),
- Ty, false, false, nullptr, nullptr, nullptr, Align);
+ Ty, false, false, nullptr, nullptr, nullptr, llvm::DINode::FlagZero,
+ Align);
Var->addDebugInfo(GVE);
}
diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h
index e933fe4b3f92..db16bc48966c 100644
--- a/llvm/include/llvm-c/DebugInfo.h
+++ b/llvm/include/llvm-c/DebugInfo.h
@@ -159,6 +159,9 @@ enum {
LLVMDIImportedEntityMetadataKind,
LLVMDIMacroMetadataKind,
LLVMDIMacroFileMetadataKind,
+ LLVMDIStringTypeMetadataKind,
+ LLVMDIFortranArrayTypeMetadataKind,
+ LLVMDIFortranSubrangeMetadataKind,
LLVMDICommonBlockMetadataKind
};
typedef unsigned LLVMMetadataKind;
@@ -1115,7 +1118,8 @@ LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File,
unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
- LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits);
+ LLVMMetadataRef Expr, LLVMMetadataRef Decl, LLVMDIFlags Flags,
+ uint32_t AlignInBits);
/**
* Retrieves the \c DIVariable associated with this global variable expression.
@@ -1207,7 +1211,7 @@ LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File,
unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
- LLVMMetadataRef Decl, uint32_t AlignInBits);
+ LLVMMetadataRef Decl, LLVMDIFlags Flags, uint32_t AlignInBits);
/**
* Insert a new llvm.dbg.declare intrinsic call before the given instruction.
diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index 1bd9db756bb3..4ab30dcd884f 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -89,6 +89,7 @@ class TargetLibraryInfoImpl {
NoLibrary, // Don't use any vector library.
Accelerate, // Use Accelerate framework.
MASSV, // IBM MASS vector library.
+ PGMATH, // PGI math library.
SVML // Intel short vector math library.
};
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 2cfd66b96502..ed4bcebd1932 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -331,6 +331,9 @@ enum MetadataCodes {
METADATA_INDEX_OFFSET = 38, // [offset]
METADATA_INDEX = 39, // [bitpos]
METADATA_LABEL = 40, // [distinct, scope, name, file, line]
+ METADATA_STRING_TYPE = 41, // [distinct, name, size, align, ...]
+ METADATA_FORTRAN_ARRAY_TYPE = 42, // [distinct, name, [bounds ...], ...]
+ METADATA_FORTRAN_SUBRANGE = 43, // [distinct, lbound, lbnde, ubound, ubnde]
METADATA_COMMON_BLOCK = 44, // [distinct, scope, name, variable,...]
};
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index f7c242554f6a..4f17fc30f208 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -195,6 +195,12 @@ namespace llvm {
unsigned Encoding,
DINode::DIFlags Flags = DINode::FlagZero);
+ /// Create debugging information entry for a string
+ /// type.
+ /// \param Name Type name.
+ /// \param SizeInBits Size of the type.
+ DIStringType *createStringType(StringRef Name, uint64_t SizeInBits);
+
/// Create debugging information entry for a qualified
/// type, e.g. 'const int'.
/// \param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
@@ -484,6 +490,14 @@ namespace llvm {
DICompositeType *createArrayType(uint64_t Size, uint32_t AlignInBits,
DIType *Ty, DINodeArray Subscripts);
+ /// Create debugging information entry for a Fortran array.
+ /// \param Size Array size.
+ /// \param AlignInBits Alignment.
+ /// \param Ty Element type.
+ /// \param Subscripts Subscripts.
+ DIFortranArrayType *createFortranArrayType(
+ uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subs);
+
/// Create debugging information entry for a vector type.
/// \param Size Array size.
/// \param AlignInBits Alignment.
@@ -567,6 +581,12 @@ namespace llvm {
DISubrange *getOrCreateSubrange(int64_t Lo, int64_t Count);
DISubrange *getOrCreateSubrange(int64_t Lo, Metadata *CountNode);
+ /// Create a descriptor for a value range. This
+ /// implicitly uniques the values returned.
+ DIFortranSubrange *getOrCreateFortranSubrange(
+ int64_t CLBound, int64_t CUBound, bool NoUBound, Metadata *Lbound,
+ Metadata * Lbndexp, Metadata *Ubound, Metadata * Ubndexp);
+
/// Create a new descriptor for the specified variable.
/// \param Context Variable scope.
/// \param Name Name of the variable.
@@ -585,14 +605,16 @@ namespace llvm {
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DIType *Ty, bool IsLocalToUnit, bool isDefined = true,
DIExpression *Expr = nullptr, MDNode *Decl = nullptr,
- MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0);
+ MDTuple *TemplateParams = nullptr,
+ DINode::DIFlags Flags = DINode::FlagZero, uint32_t AlignInBits = 0);
/// Identical to createGlobalVariable
/// except that the resulting DbgNode is temporary and meant to be RAUWed.
DIGlobalVariable *createTempGlobalVariableFwdDecl(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
- unsigned LineNo, DIType *Ty, bool IsLocalToUnit, MDNode *Decl = nullptr,
- MDTuple *TemplateParams= nullptr, uint32_t AlignInBits = 0);
+ unsigned LineNo, DIType *Ty, bool isLocalToUnit, MDNode *Decl = nullptr,
+ MDTuple *TemplateParams = nullptr,
+ DINode::DIFlags Flags = DINode::FlagZero, uint32_t AlignInBits = 0);
/// Create a new descriptor for an auto variable. This is a local variable
/// that is not a subprogram parameter.
@@ -718,6 +740,17 @@ namespace llvm {
StringRef Name, DIFile *File,
unsigned LineNo);
+ /// Create common block entry for a Fortran common block
+ /// \param Scope Scope of this common block
+ /// \param Name The name of this common block
+ /// \param File The file this common block is defined
+ /// \param LineNo Line number
+ /// \param VarList List of variables that a located in common block
+ /// \param AlignInBits Common block alignment
+ DICommonBlock *createCommonBlock(DIScope *Scope, DIGlobalVariable *decl,
+ StringRef Name, DIFile *File,
+ unsigned LineNo, uint32_t AlignInBits = 0);
+
/// This creates new descriptor for a namespace with the specified
/// parent scope.
/// \param Scope Namespace scope
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index d6bfe504dd94..22966f7522c1 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -180,10 +180,13 @@ class DINode : public MDNode {
return false;
case GenericDINodeKind:
case DISubrangeKind:
+ case DIFortranSubrangeKind:
case DIEnumeratorKind:
case DIBasicTypeKind:
+ case DIStringTypeKind:
case DIDerivedTypeKind:
case DICompositeTypeKind:
+ case DIFortranArrayTypeKind:
case DISubroutineTypeKind:
case DIFileKind:
case DICompileUnitKind:
@@ -340,6 +343,71 @@ class DISubrange : public DINode {
}
};
+/// Fortran array subrange
+class DIFortranSubrange : public DINode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ int64_t CLowerBound;
+ int64_t CUpperBound;
+ bool NoUpperBound;
+
+ DIFortranSubrange(LLVMContext &C, StorageType Storage, int64_t CLowerBound,
+ int64_t CUpperBound, bool NoUpperBound,
+ ArrayRef<Metadata *> Ops)
+ : DINode(C, DIFortranSubrangeKind, Storage,
+ dwarf::DW_TAG_subrange_type, Ops), CLowerBound(CLowerBound),
+ CUpperBound(CUpperBound), NoUpperBound(NoUpperBound) {}
+ ~DIFortranSubrange() = default;
+
+ static DIFortranSubrange *getImpl(LLVMContext &Context, int64_t CLBound,
+ int64_t CUBound, bool NoUpperBound,
+ Metadata *Lbound, Metadata *Lbndexp,
+ Metadata *Ubound, Metadata *Ubndexp,
+ StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDIFortranSubrange cloneImpl() const {
+ return getTemporary(getContext(), getCLowerBound(), getCUpperBound(),
+ noUpperBound(), getRawLowerBound(),
+ getRawLowerBoundExpression(), getRawUpperBound(),
+ getRawUpperBoundExpression());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIFortranSubrange, (int64_t CLB, int64_t CUB, bool NUB,
+ Metadata *LBound, Metadata *LBndExp,
+ Metadata *UBound, Metadata *UBndExp),
+ (CLB, CUB, NUB, LBound, LBndExp, UBound, UBndExp))
+
+ TempDIFortranSubrange clone() const { return cloneImpl(); }
+
+ DIVariable *getLowerBound() const {
+ return cast_or_null<DIVariable>(getRawLowerBound());
+ }
+ DIExpression *getLowerBoundExp() const {
+ return cast_or_null<DIExpression>(getRawLowerBoundExpression());
+ }
+ DIVariable *getUpperBound() const {
+ return cast_or_null<DIVariable>(getRawUpperBound());
+ }
+ DIExpression *getUpperBoundExp() const {
+ return cast_or_null<DIExpression>(getRawUpperBoundExpression());
+ }
+
+ int64_t getCLowerBound() const { return CLowerBound; }
+ int64_t getCUpperBound() const { return CUpperBound; }
+ Metadata *getRawLowerBound() const { return getOperand(0); }
+ Metadata *getRawLowerBoundExpression() const { return getOperand(1); }
+ Metadata *getRawUpperBound() const { return getOperand(2); }
+ Metadata *getRawUpperBoundExpression() const { return getOperand(3); }
+ bool noUpperBound() const { return NoUpperBound; }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIFortranSubrangeKind;
+ }
+};
+
/// Enumeration value.
///
/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
@@ -429,8 +497,10 @@ class DIScope : public DINode {
default:
return false;
case DIBasicTypeKind:
+ case DIStringTypeKind:
case DIDerivedTypeKind:
case DICompositeTypeKind:
+ case DIFortranArrayTypeKind:
case DISubroutineTypeKind:
case DIFileKind:
case DICompileUnitKind:
@@ -674,8 +744,10 @@ class DIType : public DIScope {
default:
return false;
case DIBasicTypeKind:
+ case DIStringTypeKind:
case DIDerivedTypeKind:
case DICompositeTypeKind:
+ case DIFortranArrayTypeKind:
case DISubroutineTypeKind:
return true;
}
@@ -723,6 +795,12 @@ class DIBasicType : public DIType {
public:
DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
(Tag, Name, 0, 0, 0, FlagZero))
+ DEFINE_MDNODE_GET(DIBasicType,
+ (unsigned Tag, StringRef Name, uint64_t SizeInBits),
+ (Tag, Name, SizeInBits, 0, 0, FlagZero))
+ DEFINE_MDNODE_GET(DIBasicType,
+ (unsigned Tag, MDString *Name, uint64_t SizeInBits),
+ (Tag, Name, SizeInBits, 0, 0, FlagZero))
DEFINE_MDNODE_GET(DIBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
@@ -747,6 +825,99 @@ class DIBasicType : public DIType {
}
};
+/// String type, Fortran CHARACTER(n)
+class DIStringType : public DIType {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Encoding;
+
+ DIStringType(LLVMContext &C, StorageType Storage, unsigned Tag,
+ uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
+ ArrayRef<Metadata *> Ops)
+ : DIType(C, DIStringTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
+ FlagZero, Ops),
+ Encoding(Encoding) {}
+ ~DIStringType() = default;
+
+ static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
+ StringRef Name, Metadata *StringLength,
+ Metadata *StrLenExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
+ StringLength, StrLenExp, SizeInBits, AlignInBits, Encoding,
+ Storage, ShouldCreate);
+ }
+ static DIStringType *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, Metadata *StringLength,
+ Metadata *StrLenExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempDIStringType cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getName(), getRawStringLength(),
+ getRawStringLengthExp(), getSizeInBits(),
+ getAlignInBits(), getEncoding());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIStringType, (unsigned Tag, StringRef Name),
+ (Tag, Name, nullptr, nullptr, 0, 0, 0))
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, StringRef Name, uint64_t SizeInBits,
+ uint32_t AlignInBits),
+ (Tag, Name, nullptr, nullptr, SizeInBits, AlignInBits, 0))
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, MDString *Name, uint64_t SizeInBits,
+ uint32_t AlignInBits),
+ (Tag, Name, nullptr, nullptr, SizeInBits, AlignInBits, 0))
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, StringRef Name, Metadata *StringLength,
+ Metadata *StringLengthExp, uint64_t SizeInBits,
+ uint32_t AlignInBits),
+ (Tag, Name, StringLength, StringLengthExp, SizeInBits,
+ AlignInBits, 0))
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, MDString *Name, Metadata *StringLength,
+ Metadata *StringLengthExp, uint64_t SizeInBits,
+ uint32_t AlignInBits),
+ (Tag, Name, StringLength, StringLengthExp, SizeInBits,
+ AlignInBits, 0))
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, StringRef Name, Metadata *StringLength,
+ Metadata *StringLengthExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding),
+ (Tag, Name, StringLength, StringLengthExp, SizeInBits,
+ AlignInBits, Encoding))
+ DEFINE_MDNODE_GET(DIStringType,
+ (unsigned Tag, MDString *Name, Metadata *StringLength,
+ Metadata *StringLengthExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding),
+ (Tag, Name, StringLength, StringLengthExp, SizeInBits,
+ AlignInBits, Encoding))
+
+ TempDIStringType clone() const { return cloneImpl(); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIStringTypeKind;
+ }
+
+ DIVariable *getStringLength() const {
+ return cast_or_null<DIVariable>(getRawStringLength());
+ }
+
+ DIExpression *getStringLengthExp() const {
+ return cast_or_null<DIExpression>(getRawStringLengthExp());
+ }
+
+ unsigned getEncoding() const { return Encoding; }
+
+ Metadata *getRawStringLength() const { return getOperand(3); }
+
+ Metadata *getRawStringLengthExp() const { return getOperand(4); }
+};
+
/// Derived types.
///
/// This includes qualified types, pointers, references, friends, typedefs, and
@@ -1055,6 +1226,90 @@ class DICompositeType : public DIType {
}
};
+/// Fortran array types.
+class DIFortranArrayType : public DIType {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ DIFortranArrayType(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
+ uint64_t OffsetInBits, DIFlags Flags,
+ ArrayRef<Metadata *> Ops)
+ : DIType(C, DIFortranArrayTypeKind, Storage, Tag, Line, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Ops) {}
+ ~DIFortranArrayType() = default;
+
+ static DIFortranArrayType *
+ getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
+ unsigned Line, DIScope *Scope, DIType *BaseType,
+ uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
+ DIFlags Flags, DINodeArray Elements, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(
+ Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
+ Storage, ShouldCreate);
+ }
+ static DIFortranArrayType *
+ getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
+ DIFlags Flags, Metadata *Elements, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDIFortranArrayType cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
+ getScope(), getBaseType(), getSizeInBits(),
+ getAlignInBits(), getOffsetInBits(), getFlags(),
+ getElements());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIFortranArrayType,
+ (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
+ DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
+ uint32_t AlignInBits, uint64_t OffsetInBits,
+ DIFlags Flags, DINodeArray Elements),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements))
+ DEFINE_MDNODE_GET(DIFortranArrayType,
+ (unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ uint64_t SizeInBits, uint32_t AlignInBits,
+ uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements))
+
+ TempDIFortranArrayType clone() const { return cloneImpl(); }
+
+ DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
+ DINodeArray getElements() const {
+ return cast_or_null<MDTuple>(getRawElements());
+ }
+
+ Metadata *getRawBaseType() const { return getOperand(3); }
+ Metadata *getRawElements() const { return getOperand(4); }
+
+ /// Replace operands.
+ ///
+ /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
+ /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
+ /// of its movement if necessary.
+ /// @{
+ void replaceElements(DINodeArray Elements) {
+#ifndef NDEBUG
+ for (DINode *Op : getElements())
+ assert(is_contained(Elements->operands(), Op) &&
+ "Lost a member during member list replacement");
+#endif
+ replaceOperandWith(4, Elements.get());
+ }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIFortranArrayTypeKind;
+ }
+};
+
/// Type array for a subprogram.
///
/// TODO: Fold the array of types in directly as operands.
@@ -2626,12 +2881,14 @@ class DIGlobalVariable : public DIVariable {
bool IsLocalToUnit;
bool IsDefinition;
+ DIFlags Flags;
DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
- bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
- ArrayRef<Metadata *> Ops)
+ bool IsLocalToUnit, bool IsDefinition, DIFlags Flags,
+ uint32_t AlignInBits, ArrayRef<Metadata *> Ops)
: DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
- IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
+ IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition),
+ Flags(Flags) {}
~DIGlobalVariable() = default;
static DIGlobalVariable *
@@ -2639,25 +2896,27 @@ class DIGlobalVariable : public DIVariable {
StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type,
bool IsLocalToUnit, bool IsDefinition,
DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
- uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) {
+ DIFlags Flags, uint32_t AlignInBits, StorageType Storage,
+ bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, LinkageName), File, Line, Type,
IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
- cast_or_null<Metadata>(TemplateParams), AlignInBits, Storage,
- ShouldCreate);
+ cast_or_null<Metadata>(TemplateParams), Flags, AlignInBits,
+ Storage, ShouldCreate);
}
static DIGlobalVariable *
getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
- uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true);
+ DIFlags Flags, uint32_t AlignInBits, StorageType Storage,
+ bool ShouldCreate = true);
TempDIGlobalVariable cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
getFile(), getLine(), getType(), isLocalToUnit(),
isDefinition(), getStaticDataMemberDeclaration(),
- getTemplateParams(), getAlignInBits());
+ getTemplateParams(), getFlags(), getAlignInBits());
}
public:
@@ -2666,24 +2925,28 @@ class DIGlobalVariable : public DIVariable {
DIFile *File, unsigned Line, DIType *Type,
bool IsLocalToUnit, bool IsDefinition,
DIDerivedType *StaticDataMemberDeclaration,
- MDTuple *TemplateParams, uint32_t AlignInBits),
+ MDTuple *TemplateParams, DIFlags Flags,
+ uint32_t AlignInBits),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration, TemplateParams,
- AlignInBits))
+ Flags, AlignInBits))
DEFINE_MDNODE_GET(DIGlobalVariable,
(Metadata * Scope, MDString *Name, MDString *LinkageName,
Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration,
- Metadata *TemplateParams, uint32_t AlignInBits),
+ Metadata *TemplateParams, DIFlags Flags,
+ uint32_t AlignInBits),
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, StaticDataMemberDeclaration, TemplateParams,
- AlignInBits))
+ Flags, AlignInBits))
TempDIGlobalVariable clone() const { return cloneImpl(); }
bool isLocalToUnit() const { return IsLocalToUnit; }
bool isDefinition() const { return IsDefinition; }
+ DIFlags getFlags() const { return Flags; }
+ bool isArtificial() const { return getFlags() & FlagArtificial; }
StringRef getDisplayName() const { return getStringOperand(4); }
StringRef getLinkageName() const { return getStringOperand(5); }
DIDerivedType *getStaticDataMemberDeclaration() const {
diff --git a/llvm/include/llvm/IR/Metadata.def b/llvm/include/llvm/IR/Metadata.def
index 1df60cadac08..48ea4b1dd7a5 100644
--- a/llvm/include/llvm/IR/Metadata.def
+++ b/llvm/include/llvm/IR/Metadata.def
@@ -113,6 +113,9 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIImportedEntity)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile)
+HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIStringType)
+HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIFortranArrayType)
+HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIFortranSubrange)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICommonBlock)
#undef HANDLE_METADATA
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 1a32adf4723a..6896564c7658 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -27,7 +27,9 @@ static cl::opt<TargetLibraryInfoImpl::VectorLibrary> ClVectorLibrary(
clEnumValN(TargetLibraryInfoImpl::MASSV, "MASSV",
"IBM MASS vector library"),
clEnumValN(TargetLibraryInfoImpl::SVML, "SVML",
- "Intel SVML library")));
+ "Intel SVML library"),
+ clEnumValN(TargetLibraryInfoImpl::PGMATH, "PGMATH",
+ "PGI math library")));
StringLiteral const TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] =
{
@@ -563,7 +565,6 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl() {
TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) {
// Default to everything being available.
memset(AvailableArray, -1, sizeof(AvailableArray));
-
initialize(*this, T, StandardNames);
}
@@ -1545,6 +1546,456 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
addVectorizableFunctions(VecFuncs);
break;
}
+
+ // NOTE: All routines listed here are not available on all the architectures.
+ // Based on the size of vector registers available and the size of data, the
+ // vector width should be chosen correctly.
+ case PGMATH: {
+ const VecDesc VecFuncs[] = {
+ {"__fd_sin_1", "__fd_sin_2", 2},
+ {"__fd_sin_1", "__fd_sin_4", 4},
+ {"__fd_sin_1", "__fd_sin_8", 8},
+
+ {"__fs_sin_1", "__fs_sin_4", 4},
+ {"__fs_sin_1", "__fs_sin_8", 8},
+ {"__fs_sin_1", "__fs_sin_16", 16},
+
+ {"__pd_sin_1", "__pd_sin_2", 2},
+ {"__pd_sin_1", "__pd_sin_4", 4},
+ {"__pd_sin_1", "__pd_sin_8", 8},
+
+ {"__ps_sin_1", "__ps_sin_4", 4},
+ {"__ps_sin_1", "__ps_sin_8", 8},
+ {"__ps_sin_1", "__ps_sin_16", 16},
+
+ {"__rd_sin_1", "__rd_sin_2", 2},
+ {"__rd_sin_1", "__rd_sin_4", 4},
+ {"__rd_sin_1", "__rd_sin_8", 8},
+
+ {"__rs_sin_1", "__rs_sin_4", 4},
+ {"__rs_sin_1", "__rs_sin_8", 8},
+ {"__rs_sin_1", "__rs_sin_16", 16},
+
+ {"__fd_cos_1", "__fd_cos_2", 2},
+ {"__fd_cos_1", "__fd_cos_4", 4},
+ {"__fd_cos_1", "__fd_cos_8", 8},
+
+ {"__fs_cos_1", "__fs_cos_4", 4},
+ {"__fs_cos_1", "__fs_cos_8", 8},
+ {"__fs_cos_1", "__fs_cos_16", 16},
+
+ {"__pd_cos_1", "__pd_cos_2", 2},
+ {"__pd_cos_1", "__pd_cos_4", 4},
+ {"__pd_cos_1", "__pd_cos_8", 8},
+
+ {"__ps_cos_1", "__ps_cos_4", 4},
+ {"__ps_cos_1", "__ps_cos_8", 8},
+ {"__ps_cos_1", "__ps_cos_16", 16},
+
+ {"__rd_cos_1", "__rd_cos_2", 2},
+ {"__rd_cos_1", "__rd_cos_4", 4},
+ {"__rd_cos_1", "__rd_cos_8", 8},
+
+ {"__rs_cos_1", "__rs_cos_4", 4},
+ {"__rs_cos_1", "__rs_cos_8", 8},
+ {"__rs_cos_1", "__rs_cos_16", 16},
+
+ {"__fd_sincos_1", "__fd_sincos_2", 2},
+ {"__fd_sincos_1", "__fd_sincos_4", 4},
+ {"__fd_sincos_1", "__fd_sincos_8", 8},
+
+ {"__fs_sincos_1", "__fs_sincos_4", 4},
+ {"__fs_sincos_1", "__fs_sincos_8", 8},
+ {"__fs_sincos_1", "__fs_sincos_16", 16},
+
+ {"__pd_sincos_1", "__pd_sincos_2", 2},
+ {"__pd_sincos_1", "__pd_sincos_4", 4},
+ {"__pd_sincos_1", "__pd_sincos_8", 8},
+
+ {"__ps_sincos_1", "__ps_sincos_4", 4},
+ {"__ps_sincos_1", "__ps_sincos_8", 8},
+ {"__ps_sincos_1", "__ps_sincos_16", 16},
+
+ {"__rd_sincos_1", "__rd_sincos_2", 2},
+ {"__rd_sincos_1", "__rd_sincos_4", 4},
+ {"__rd_sincos_1", "__rd_sincos_8", 8},
+
+ {"__rs_sincos_1", "__rs_sincos_4", 4},
+ {"__rs_sincos_1", "__rs_sincos_8", 8},
+ {"__rs_sincos_1", "__rs_sincos_16", 16},
+
+ {"__fd_tan_1", "__fd_tan_2", 2},
+ {"__fd_tan_1", "__fd_tan_4", 4},
+ {"__fd_tan_1", "__fd_tan_8", 8},
+
+ {"__fs_tan_1", "__fs_tan_4", 4},
+ {"__fs_tan_1", "__fs_tan_8", 8},
+ {"__fs_tan_1", "__fs_tan_16", 16},
+
+ {"__pd_tan_1", "__pd_tan_2", 2},
+ {"__pd_tan_1", "__pd_tan_4", 4},
+ {"__pd_tan_1", "__pd_tan_8", 8},
+
+ {"__ps_tan_1", "__ps_tan_4", 4},
+ {"__ps_tan_1", "__ps_tan_8", 8},
+ {"__ps_tan_1", "__ps_tan_16", 16},
+
+ {"__rd_tan_1", "__rd_tan_2", 2},
+ {"__rd_tan_1", "__rd_tan_4", 4},
+ {"__rd_tan_1", "__rd_tan_8", 8},
+
+ {"__rs_tan_1", "__rs_tan_4", 4},
+ {"__rs_tan_1", "__rs_tan_8", 8},
+ {"__rs_tan_1", "__rs_tan_16", 16},
+
+ {"__fd_sinh_1", "__fd_sinh_2", 2},
+ {"__fd_sinh_1", "__fd_sinh_4", 4},
+ {"__fd_sinh_1", "__fd_sinh_8", 8},
+
+ {"__fs_sinh_1", "__fs_sinh_4", 4},
+ {"__fs_sinh_1", "__fs_sinh_8", 8},
+ {"__fs_sinh_1", "__fs_sinh_16", 16},
+
+ {"__pd_sinh_1", "__pd_sinh_2", 2},
+ {"__pd_sinh_1", "__pd_sinh_4", 4},
+ {"__pd_sinh_1", "__pd_sinh_8", 8},
+
+ {"__ps_sinh_1", "__ps_sinh_4", 4},
+ {"__ps_sinh_1", "__ps_sinh_8", 8},
+ {"__ps_sinh_1", "__ps_sinh_16", 16},
+
+ {"__rd_sinh_1", "__rd_sinh_2", 2},
+ {"__rd_sinh_1", "__rd_sinh_4", 4},
+ {"__rd_sinh_1", "__rd_sinh_8", 8},
+
+ {"__rs_sinh_1", "__rs_sinh_4", 4},
+ {"__rs_sinh_1", "__rs_sinh_8", 8},
+ {"__rs_sinh_1", "__rs_sinh_16", 16},
+
+ {"__fd_cosh_1", "__fd_cosh_2", 2},
+ {"__fd_cosh_1", "__fd_cosh_4", 4},
+ {"__fd_cosh_1", "__fd_cosh_8", 8},
+
+ {"__fs_cosh_1", "__fs_cosh_4", 4},
+ {"__fs_cosh_1", "__fs_cosh_8", 8},
+ {"__fs_cosh_1", "__fs_cosh_16", 16},
+
+ {"__pd_cosh_1", "__pd_cosh_2", 2},
+ {"__pd_cosh_1", "__pd_cosh_4", 4},
+ {"__pd_cosh_1", "__pd_cosh_8", 8},
+
+ {"__ps_cosh_1", "__ps_cosh_4", 4},
+ {"__ps_cosh_1", "__ps_cosh_8", 8},
+ {"__ps_cosh_1", "__ps_cosh_16", 16},
+
+ {"__rd_cosh_1", "__rd_cosh_2", 2},
+ {"__rd_cosh_1", "__rd_cosh_4", 4},
+ {"__rd_cosh_1", "__rd_cosh_8", 8},
+
+ {"__rs_cosh_1", "__rs_cosh_4", 4},
+ {"__rs_cosh_1", "__rs_cosh_8", 8},
+ {"__rs_cosh_1", "__rs_cosh_16", 16},
+
+ {"__fd_tanh_1", "__fd_tanh_2", 2},
+ {"__fd_tanh_1", "__fd_tanh_4", 4},
+ {"__fd_tanh_1", "__fd_tanh_8", 8},
+
+ {"__fs_tanh_1", "__fs_tanh_4", 4},
+ {"__fs_tanh_1", "__fs_tanh_8", 8},
+ {"__fs_tanh_1", "__fs_tanh_16", 16},
+
+ {"__pd_tanh_1", "__pd_tanh_2", 2},
+ {"__pd_tanh_1", "__pd_tanh_4", 4},
+ {"__pd_tanh_1", "__pd_tanh_8", 8},
+
+ {"__ps_tanh_1", "__ps_tanh_4", 4},
+ {"__ps_tanh_1", "__ps_tanh_8", 8},
+ {"__ps_tanh_1", "__ps_tanh_16", 16},
+
+ {"__rd_tanh_1", "__rd_tanh_2", 2},
+ {"__rd_tanh_1", "__rd_tanh_4", 4},
+ {"__rd_tanh_1", "__rd_tanh_8", 8},
+
+ {"__rs_tanh_1", "__rs_tanh_4", 4},
+ {"__rs_tanh_1", "__rs_tanh_8", 8},
+ {"__rs_tanh_1", "__rs_tanh_16", 16},
+
+ {"__fd_asin_1", "__fd_asin_2", 2},
+ {"__fd_asin_1", "__fd_asin_4", 4},
+ {"__fd_asin_1", "__fd_asin_8", 8},
+
+ {"__fs_asin_1", "__fs_asin_4", 4},
+ {"__fs_asin_1", "__fs_asin_8", 8},
+ {"__fs_asin_1", "__fs_asin_16", 16},
+
+ {"__pd_asin_1", "__pd_asin_2", 2},
+ {"__pd_asin_1", "__pd_asin_4", 4},
+ {"__pd_asin_1", "__pd_asin_8", 8},
+
+ {"__ps_asin_1", "__ps_asin_4", 4},
+ {"__ps_asin_1", "__ps_asin_8", 8},
+ {"__ps_asin_1", "__ps_asin_16", 16},
+
+ {"__rd_asin_1", "__rd_asin_2", 2},
+ {"__rd_asin_1", "__rd_asin_4", 4},
+ {"__rd_asin_1", "__rd_asin_8", 8},
+
+ {"__rs_asin_1", "__rs_asin_4", 4},
+ {"__rs_asin_1", "__rs_asin_8", 8},
+ {"__rs_asin_1", "__rs_asin_16", 16},
+
+ {"__fd_acos_1", "__fd_acos_2", 2},
+ {"__fd_acos_1", "__fd_acos_4", 4},
+ {"__fd_acos_1", "__fd_acos_8", 8},
+
+ {"__fs_acos_1", "__fs_acos_4", 4},
+ {"__fs_acos_1", "__fs_acos_8", 8},
+ {"__fs_acos_1", "__fs_acos_16", 16},
+
+ {"__pd_acos_1", "__pd_acos_2", 2},
+ {"__pd_acos_1", "__pd_acos_4", 4},
+ {"__pd_acos_1", "__pd_acos_8", 8},
+
+ {"__ps_acos_1", "__ps_acos_4", 4},
+ {"__ps_acos_1", "__ps_acos_8", 8},
+ {"__ps_acos_1", "__ps_acos_16", 16},
+
+ {"__rd_acos_1", "__rd_acos_2", 2},
+ {"__rd_acos_1", "__rd_acos_4", 4},
+ {"__rd_acos_1", "__rd_acos_8", 8},
+
+ {"__rs_acos_1", "__rs_acos_4", 4},
+ {"__rs_acos_1", "__rs_acos_8", 8},
+ {"__rs_acos_1", "__rs_acos_16", 16},
+
+ {"__fd_atan_1", "__fd_atan_2", 2},
+ {"__fd_atan_1", "__fd_atan_4", 4},
+ {"__fd_atan_1", "__fd_atan_8", 8},
+
+ {"__fs_atan_1", "__fs_atan_4", 4},
+ {"__fs_atan_1", "__fs_atan_8", 8},
+ {"__fs_atan_1", "__fs_atan_16", 16},
+
+ {"__pd_atan_1", "__pd_atan_2", 2},
+ {"__pd_atan_1", "__pd_atan_4", 4},
+ {"__pd_atan_1", "__pd_atan_8", 8},
+
+ {"__ps_atan_1", "__ps_atan_4", 4},
+ {"__ps_atan_1", "__ps_atan_8", 8},
+ {"__ps_atan_1", "__ps_atan_16", 16},
+
+ {"__rd_atan_1", "__rd_atan_2", 2},
+ {"__rd_atan_1", "__rd_atan_4", 4},
+ {"__rd_atan_1", "__rd_atan_8", 8},
+
+ {"__rs_atan_1", "__rs_atan_4", 4},
+ {"__rs_atan_1", "__rs_atan_8", 8},
+ {"__rs_atan_1", "__rs_atan_16", 16},
+
+ {"__fd_atan2_1", "__fd_atan2_2", 2},
+ {"__fd_atan2_1", "__fd_atan2_4", 4},
+ {"__fd_atan2_1", "__fd_atan2_8", 8},
+
+ {"__fs_atan2_1", "__fs_atan2_4", 4},
+ {"__fs_atan2_1", "__fs_atan2_8", 8},
+ {"__fs_atan2_1", "__fs_atan2_16", 16},
+
+ {"__pd_atan2_1", "__pd_atan2_2", 2},
+ {"__pd_atan2_1", "__pd_atan2_4", 4},
+ {"__pd_atan2_1", "__pd_atan2_8", 8},
+
+ {"__ps_atan2_1", "__ps_atan2_4", 4},
+ {"__ps_atan2_1", "__ps_atan2_8", 8},
+ {"__ps_atan2_1", "__ps_atan2_16", 16},
+
+ {"__rd_atan2_1", "__rd_atan2_2", 2},
+ {"__rd_atan2_1", "__rd_atan2_4", 4},
+ {"__rd_atan2_1", "__rd_atan2_8", 8},
+
+ {"__rs_atan2_1", "__rs_atan2_4", 4},
+ {"__rs_atan2_1", "__rs_atan2_8", 8},
+ {"__rs_atan2_1", "__rs_atan2_16", 16},
+
+ {"__fd_pow_1", "__fd_pow_2", 2},
+ {"__fd_pow_1", "__fd_pow_4", 4},
+ {"__fd_pow_1", "__fd_pow_8", 8},
+
+ {"__fs_pow_1", "__fs_pow_4", 4},
+ {"__fs_pow_1", "__fs_pow_8", 8},
+ {"__fs_pow_1", "__fs_pow_16", 16},
+
+ {"__pd_pow_1", "__pd_pow_2", 2},
+ {"__pd_pow_1", "__pd_pow_4", 4},
+ {"__pd_pow_1", "__pd_pow_8", 8},
+
+ {"__ps_pow_1", "__ps_pow_4", 4},
+ {"__ps_pow_1", "__ps_pow_8", 8},
+ {"__ps_pow_1", "__ps_pow_16", 16},
+
+ {"__rd_pow_1", "__rd_pow_2", 2},
+ {"__rd_pow_1", "__rd_pow_4", 4},
+ {"__rd_pow_1", "__rd_pow_8", 8},
+
+ {"__rs_pow_1", "__rs_pow_4", 4},
+ {"__rs_pow_1", "__rs_pow_8", 8},
+ {"__rs_pow_1", "__rs_pow_16", 16},
+
+ {"__fs_powi_1", "__fs_powi_4", 4},
+ {"__fs_powi_1", "__fs_powi_8", 8},
+ {"__fs_powi_1", "__fs_powi_16", 16},
+
+ {"__ps_powi_1", "__ps_powi_4", 4},
+ {"__ps_powi_1", "__ps_powi_8", 8},
+ {"__ps_powi_1", "__ps_powi_16", 16},
+
+ {"__rs_powi_1", "__rs_powi_4", 4},
+ {"__rs_powi_1", "__rs_powi_8", 8},
+ {"__rs_powi_1", "__rs_powi_16", 16},
+
+ {"__fd_powi1_1", "__fd_powi1_2", 2},
+ {"__fd_powi1_1", "__fd_powi1_4", 4},
+ {"__fd_powi1_1", "__fd_powi1_8", 8},
+
+ {"__fs_powi1_1", "__fs_powi1_4", 4},
+ {"__fs_powi1_1", "__fs_powi1_8", 8},
+ {"__fs_powi1_1", "__fs_powi1_16", 16},
+
+ {"__pd_powi1_1", "__pd_powi1_2", 2},
+ {"__pd_powi1_1", "__pd_powi1_4", 4},
+ {"__pd_powi1_1", "__pd_powi1_8", 8},
+
+ {"__ps_powi1_1", "__ps_powi1_4", 4},
+ {"__ps_powi1_1", "__ps_powi1_8", 8},
+ {"__ps_powi1_1", "__ps_powi1_16", 16},
+
+ {"__rd_powi1_1", "__rd_powi1_2", 2},
+ {"__rd_powi1_1", "__rd_powi1_4", 4},
+ {"__rd_powi1_1", "__rd_powi1_8", 8},
+
+ {"__rs_powi1_1", "__rs_powi1_4", 4},
+ {"__rs_powi1_1", "__rs_powi1_8", 8},
+ {"__rs_powi1_1", "__rs_powi1_16", 16},
+
+ {"__fd_powk_1", "__fd_powk_2", 2},
+ {"__fd_powk_1", "__fd_powk_4", 4},
+ {"__fd_powk_1", "__fd_powk_8", 8},
+
+ {"__fs_powk_1", "__fs_powk_4", 4},
+ {"__fs_powk_1", "__fs_powk_8", 8},
+ {"__fs_powk_1", "__fs_powk_16", 16},
+
+ {"__pd_powk_1", "__pd_powk_2", 2},
+ {"__pd_powk_1", "__pd_powk_4", 4},
+ {"__pd_powk_1", "__pd_powk_8", 8},
+
+ {"__ps_powk_1", "__ps_powk_4", 4},
+ {"__ps_powk_1", "__ps_powk_8", 8},
+ {"__ps_powk_1", "__ps_powk_16", 16},
+
+ {"__rd_powk_1", "__rd_powk_2", 2},
+ {"__rd_powk_1", "__rd_powk_4", 4},
+ {"__rd_powk_1", "__rd_powk_8", 8},
+
+ {"__rs_powk_1", "__rs_powk_4", 4},
+ {"__rs_powk_1", "__rs_powk_8", 8},
+ {"__rs_powk_1", "__rs_powk_16", 16},
+
+ {"__fd_powk1_1", "__fd_powk1_2", 2},
+ {"__fd_powk1_1", "__fd_powk1_4", 4},
+ {"__fd_powk1_1", "__fd_powk1_8", 8},
+
+ {"__fs_powk1_1", "__fs_powk1_4", 4},
+ {"__fs_powk1_1", "__fs_powk1_8", 8},
+ {"__fs_powk1_1", "__fs_powk1_16", 16},
+
+ {"__pd_powk1_1", "__pd_powk1_2", 2},
+ {"__pd_powk1_1", "__pd_powk1_4", 4},
+ {"__pd_powk1_1", "__pd_powk1_8", 8},
+
+ {"__ps_powk1_1", "__ps_powk1_4", 4},
+ {"__ps_powk1_1", "__ps_powk1_8", 8},
+ {"__ps_powk1_1", "__ps_powk1_16", 16},
+
+ {"__rd_powk1_1", "__rd_powk1_2", 2},
+ {"__rd_powk1_1", "__rd_powk1_4", 4},
+ {"__rd_powk1_1", "__rd_powk1_8", 8},
+
+ {"__rs_powk1_1", "__rs_powk1_4", 4},
+ {"__rs_powk1_1", "__rs_powk1_8", 8},
+ {"__rs_powk1_1", "__rs_powk1_16", 16},
+
+ {"__fd_log10_1", "__fd_log10_2", 2},
+ {"__fd_log10_1", "__fd_log10_4", 4},
+ {"__fd_log10_1", "__fd_log10_8", 8},
+
+ {"__fs_log10_1", "__fs_log10_4", 4},
+ {"__fs_log10_1", "__fs_log10_8", 8},
+ {"__fs_log10_1", "__fs_log10_16", 16},
+
+ {"__pd_log10_1", "__pd_log10_2", 2},
+ {"__pd_log10_1", "__pd_log10_4", 4},
+ {"__pd_log10_1", "__pd_log10_8", 8},
+
+ {"__ps_log10_1", "__ps_log10_4", 4},
+ {"__ps_log10_1", "__ps_log10_8", 8},
+ {"__ps_log10_1", "__ps_log10_16", 16},
+
+ {"__rd_log10_1", "__rd_log10_2", 2},
+ {"__rd_log10_1", "__rd_log10_4", 4},
+ {"__rd_log10_1", "__rd_log10_8", 8},
+
+ {"__rs_log10_1", "__rs_log10_4", 4},
+ {"__rs_log10_1", "__rs_log10_8", 8},
+ {"__rs_log10_1", "__rs_log10_16", 16},
+
+ {"__fd_log_1", "__fd_log_2", 2},
+ {"__fd_log_1", "__fd_log_4", 4},
+ {"__fd_log_1", "__fd_log_8", 8},
+
+ {"__fs_log_1", "__fs_log_4", 4},
+ {"__fs_log_1", "__fs_log_8", 8},
+ {"__fs_log_1", "__fs_log_16", 16},
+
+ {"__pd_log_1", "__pd_log_2", 2},
+ {"__pd_log_1", "__pd_log_4", 4},
+ {"__pd_log_1", "__pd_log_8", 8},
+
+ {"__ps_log_1", "__ps_log_4", 4},
+ {"__ps_log_1", "__ps_log_8", 8},
+ {"__ps_log_1", "__ps_log_16", 16},
+
+ {"__rd_log_1", "__rd_log_2", 2},
+ {"__rd_log_1", "__rd_log_4", 4},
+ {"__rd_log_1", "__rd_log_8", 8},
+
+ {"__rs_log_1", "__rs_log_4", 4},
+ {"__rs_log_1", "__rs_log_8", 8},
+ {"__rs_log_1", "__rs_log_16", 16},
+
+ {"__fs_exp_1", "__fs_exp_4", 4},
+ {"__fs_exp_1", "__fs_exp_8", 8},
+ {"__fs_exp_1", "__fs_exp_16", 16},
+
+ {"__pd_exp_1", "__pd_exp_2", 2},
+ {"__pd_exp_1", "__pd_exp_4", 4},
+ {"__pd_exp_1", "__pd_exp_8", 8},
+
+ {"__ps_exp_1", "__ps_exp_4", 4},
+ {"__ps_exp_1", "__ps_exp_8", 8},
+ {"__ps_exp_1", "__ps_exp_16", 16},
+
+ {"__rd_exp_1", "__rd_exp_2", 2},
+ {"__rd_exp_1", "__rd_exp_4", 4},
+ {"__rd_exp_1", "__rd_exp_8", 8},
+
+ {"__rs_exp_1", "__rs_exp_4", 4},
+ {"__rs_exp_1", "__rs_exp_8", 8},
+ {"__rs_exp_1", "__rs_exp_16", 16}
+ };
+ addVectorizableFunctions(VecFuncs);
+ break;
+ }
+
case NoLibrary:
break;
}
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 1a17f633ae16..e3612f0e9a38 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -4465,6 +4465,28 @@ bool LLParser::ParseDISubrange(MDNode *&Result, bool IsDistinct) {
return false;
}
+/// ParseDIFortranSubrange:
+/// ::= !DIFortranSubrange(lowerBound: 2)
+bool LLParser::ParseDIFortranSubrange(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(constLowerBound, MDSignedField, (0, INT64_MIN, INT64_MAX)); \
+ OPTIONAL(constUpperBound, MDSignedField, (0, INT64_MIN, INT64_MAX)); \
+ OPTIONAL(lowerBound, MDField, ); \
+ OPTIONAL(lowerBoundExpression, MDField, ); \
+ OPTIONAL(upperBound, MDField, ); \
+ OPTIONAL(upperBoundExpression, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIFortranSubrange,
+ (Context, constLowerBound.Val, constUpperBound.Val,
+ (!constUpperBound.Seen) && (!upperBound.Seen),
+ lowerBound.Val, lowerBoundExpression.Val,
+ upperBound.Val, upperBoundExpression.Val));
+ return false;
+}
+
+
/// ParseDIEnumerator:
/// ::= !DIEnumerator(value: 30, isUnsigned: true, name: "SomeKind")
bool LLParser::ParseDIEnumerator(MDNode *&Result, bool IsDistinct) {
@@ -4506,6 +4528,26 @@ bool LLParser::ParseDIBasicType(MDNode *&Result, bool IsDistinct) {
return false;
}
+/// ParseDIStringType:
+/// ::= !DIStringType(name: "character(4)", size: 32, align: 32)
+bool LLParser::ParseDIStringType(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_string_type)); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(stringLength, MDField, ); \
+ OPTIONAL(stringLengthExpression, MDField, ); \
+ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(encoding, DwarfAttEncodingField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ Result = GET_OR_DISTINCT(DIStringType, (Context, tag.Val, name.Val,
+ stringLength.Val, stringLengthExpression.Val, size.Val, align.Val,
+ encoding.Val));
+ return false;
+}
+
/// ParseDIDerivedType:
/// ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0,
/// line: 7, scope: !1, baseType: !2, size: 32,
@@ -4583,6 +4625,31 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
return false;
}
+bool LLParser::ParseDIFortranArrayType(MDNode *&Result, bool IsDistinct) {
+#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
+ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_array_type)); \
+ OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(file, MDField, ); \
+ OPTIONAL(line, LineField, ); \
+ OPTIONAL(scope, MDField, ); \
+ OPTIONAL(baseType, MDField, ); \
+ OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
+ OPTIONAL(elements, MDField, );
+ PARSE_MD_FIELDS();
+#undef VISIT_MD_FIELDS
+
+ // Create a new node, and save it in the context if it belongs in the type
+ // map.
+ Result = GET_OR_DISTINCT(
+ DIFortranArrayType,
+ (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
+ size.Val, align.Val, offset.Val, flags.Val, elements.Val));
+ return false;
+}
+
bool LLParser::ParseDISubroutineType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(flags, DIFlagField, ); \
@@ -4875,7 +4942,7 @@ bool LLParser::ParseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) {
/// declaration: !4, align: 8)
bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \
+ OPTIONAL(name, MDStringField, (/* AllowEmpty */ true)); \
OPTIONAL(scope, MDField, ); \
OPTIONAL(linkageName, MDStringField, ); \
OPTIONAL(file, MDField, ); \
@@ -4885,6 +4952,7 @@ bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
OPTIONAL(isDefinition, MDBoolField, (true)); \
OPTIONAL(templateParams, MDField, ); \
OPTIONAL(declaration, MDField, ); \
+ OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
@@ -4893,7 +4961,8 @@ bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
GET_OR_DISTINCT(DIGlobalVariable,
(Context, scope.Val, name.Val, linkageName.Val, file.Val,
line.Val, type.Val, isLocal.Val, isDefinition.Val,
- declaration.Val, templateParams.Val, align.Val));
+ declaration.Val, templateParams.Val, flags.Val,
+ align.Val));
return false;
}
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index d16c3b0ff59d..a5cde1608bc4 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -851,10 +851,13 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
case bitc::METADATA_LOCATION:
case bitc::METADATA_GENERIC_DEBUG:
case bitc::METADATA_SUBRANGE:
+ case bitc::METADATA_FORTRAN_SUBRANGE:
case bitc::METADATA_ENUMERATOR:
case bitc::METADATA_BASIC_TYPE:
+ case bitc::METADATA_STRING_TYPE:
case bitc::METADATA_DERIVED_TYPE:
case bitc::METADATA_COMPOSITE_TYPE:
+ case bitc::METADATA_FORTRAN_ARRAY_TYPE:
case bitc::METADATA_SUBROUTINE_TYPE:
case bitc::METADATA_MODULE:
case bitc::METADATA_FILE:
@@ -1276,6 +1279,20 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
NextMetadataNo++;
break;
}
+ case bitc::METADATA_FORTRAN_SUBRANGE: {
+ if (Record.size() != 8)
+ return error("Invalid record");
+
+ IsDistinct = Record[0];
+ MetadataList.assignValue(
+ GET_OR_DISTINCT(DIFortranSubrange,
+ (Context, Record[1], Record[2], Record[3],
+ getMDOrNull(Record[4]), getMDOrNull(Record[5]),
+ getMDOrNull(Record[6]), getMDOrNull(Record[7]))),
+ NextMetadataNo);
+ NextMetadataNo++;
+ break;
+ }
case bitc::METADATA_ENUMERATOR: {
if (Record.size() != 3)
return error("Invalid record");
@@ -1305,6 +1322,20 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
NextMetadataNo++;
break;
}
+ case bitc::METADATA_STRING_TYPE: {
+ if (Record.size() != 8)
+ return error("Invalid record");
+
+ IsDistinct = Record[0];
+ MetadataList.assignValue(
+ GET_OR_DISTINCT(DIStringType,
+ (Context, Record[1], getMDString(Record[2]),
+ getMDOrNull(Record[3]), getMDOrNull(Record[4]),
+ Record[5], Record[6], Record[7])),
+ NextMetadataNo);
+ NextMetadataNo++;
+ break;
+ }
case bitc::METADATA_DERIVED_TYPE: {
if (Record.size() < 12 || Record.size() > 13)
return error("Invalid record");
@@ -1398,6 +1429,38 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
NextMetadataNo++;
break;
}
+ case bitc::METADATA_FORTRAN_ARRAY_TYPE: {
+ if (Record.size() != 12)
+ return error("Invalid record");
+
+ // If we have a UUID and this is not a forward declaration, lookup the
+ // mapping.
+ IsDistinct = Record[0] & 0x1;
+ unsigned Tag = Record[1];
+ MDString *Name = getMDString(Record[2]);
+ Metadata *File = getMDOrNull(Record[3]);
+ unsigned Line = Record[4];
+ Metadata *Scope = getDITypeRefOrNull(Record[5]);
+ Metadata *BaseType = nullptr;
+ uint64_t SizeInBits = Record[7];
+ if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
+ return error("Alignment value is too large");
+ uint32_t AlignInBits = Record[8];
+ uint64_t OffsetInBits = 0;
+ DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
+ Metadata *Elements = nullptr;
+ BaseType = getDITypeRefOrNull(Record[6]);
+ OffsetInBits = Record[9];
+ Elements = getMDOrNull(Record[11]);
+ DIFortranArrayType *CT =
+ GET_OR_DISTINCT(DIFortranArrayType,
+ (Context, Tag, Name, File, Line, Scope, BaseType,
+ SizeInBits, AlignInBits, OffsetInBits, Flags,
+ Elements));
+ MetadataList.assignValue(CT, NextMetadataNo);
+ NextMetadataNo++;
+ break;
+ }
case bitc::METADATA_SUBROUTINE_TYPE: {
if (Record.size() < 3 || Record.size() > 4)
return error("Invalid record");
@@ -1693,20 +1756,34 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_GLOBAL_VAR: {
- if (Record.size() < 11 || Record.size() > 13)
+ if (Record.size() < 11 || Record.size() > 14)
return error("Invalid record");
IsDistinct = Record[0] & 1;
unsigned Version = Record[0] >> 1;
- if (Version == 2) {
+ if (Version == 3) {
+ // Add support for DIFlags
+ MetadataList.assignValue(
+ GET_OR_DISTINCT(
+ DIGlobalVariable,
+ (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
+ getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
+ getDITypeRefOrNull(Record[6]), Record[7], Record[8],
+ getMDOrNull(Record[9]), getMDOrNull(Record[10]),
+ static_cast<DINode::DIFlags>(Record[11]), Record[12])),
+ NextMetadataNo);
+
+ NextMetadataNo++;
+ } else if (Version == 2) {
MetadataList.assignValue(
GET_OR_DISTINCT(
DIGlobalVariable,
(Context, getMDOrNull(Record[1]), getMDString(Record[2]),
getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- getMDOrNull(Record[9]), getMDOrNull(Record[10]), Record[11])),
+ getMDOrNull(Record[9]), getMDOrNull(Record[10]),
+ DINode::FlagZero, Record[11])),
NextMetadataNo);
NextMetadataNo++;
@@ -1719,7 +1796,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
getMDString(Record[2]), getMDString(Record[3]),
getMDOrNull(Record[4]), Record[5],
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- getMDOrNull(Record[10]), nullptr, Record[11])),
+ getMDOrNull(Record[10]), nullptr, DINode::FlagZero,
+ Record[11])),
NextMetadataNo);
NextMetadataNo++;
@@ -1752,7 +1830,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
(Context, getMDOrNull(Record[1]), getMDString(Record[2]),
getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
- getMDOrNull(Record[10]), nullptr, AlignInBits));
+ getMDOrNull(Record[10]), nullptr, DINode::FlagZero, Record[11]));
DIGlobalVariableExpression *DGVE = nullptr;
if (Attach || Expr)
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index dcff7c421fc4..2b2e41094fde 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -297,14 +297,22 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {
SmallVectorImpl<uint64_t> &Record, unsigned &Abbrev);
void writeDISubrange(const DISubrange *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
+ void writeDIFortranSubrange(const DIFortranSubrange *N,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev);
void writeDIEnumerator(const DIEnumerator *N,
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
void writeDIBasicType(const DIBasicType *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
+ void writeDIStringType(const DIStringType *N,
+ SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
void writeDIDerivedType(const DIDerivedType *N,
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
void writeDICompositeType(const DICompositeType *N,
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
+ void writeDIFortranArrayType(const DIFortranArrayType *N,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev);
void writeDISubroutineType(const DISubroutineType *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
@@ -1523,6 +1531,22 @@ void ModuleBitcodeWriter::writeDISubrange(const DISubrange *N,
Record.clear();
}
+void ModuleBitcodeWriter::writeDIFortranSubrange(
+ const DIFortranSubrange *N, SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getCLowerBound());
+ Record.push_back(N->getCUpperBound());
+ Record.push_back(N->noUpperBound());
+ Record.push_back(VE.getMetadataOrNullID(N->getLowerBound()));
+ Record.push_back(VE.getMetadataOrNullID(N->getLowerBoundExp()));
+ Record.push_back(VE.getMetadataOrNullID(N->getUpperBound()));
+ Record.push_back(VE.getMetadataOrNullID(N->getUpperBoundExp()));
+
+ Stream.EmitRecord(bitc::METADATA_FORTRAN_SUBRANGE, Record, Abbrev);
+ Record.clear();
+}
+
void ModuleBitcodeWriter::writeDIEnumerator(const DIEnumerator *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
@@ -1549,6 +1573,22 @@ void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N,
Record.clear();
}
+void ModuleBitcodeWriter::writeDIStringType(const DIStringType *N,
+ SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getStringLength()));
+ Record.push_back(VE.getMetadataOrNullID(N->getStringLengthExp()));
+ Record.push_back(N->getSizeInBits());
+ Record.push_back(N->getAlignInBits());
+ Record.push_back(N->getEncoding());
+
+ Stream.EmitRecord(bitc::METADATA_STRING_TYPE, Record, Abbrev);
+ Record.clear();
+}
+
void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
@@ -1602,6 +1642,26 @@ void ModuleBitcodeWriter::writeDICompositeType(
Record.clear();
}
+void ModuleBitcodeWriter::writeDIFortranArrayType(
+ const DIFortranArrayType *N, SmallVectorImpl<uint64_t> &Record,
+ unsigned Abbrev) {
+ Record.push_back(N->isDistinct());
+ Record.push_back(N->getTag());
+ Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
+ Record.push_back(VE.getMetadataOrNullID(N->getFile()));
+ Record.push_back(N->getLine());
+ Record.push_back(VE.getMetadataOrNullID(N->getScope()));
+ Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
+ Record.push_back(N->getSizeInBits());
+ Record.push_back(N->getAlignInBits());
+ Record.push_back(N->getOffsetInBits());
+ Record.push_back(N->getFlags());
+ Record.push_back(VE.getMetadataOrNullID(N->getElements().get()));
+
+ Stream.EmitRecord(bitc::METADATA_FORTRAN_ARRAY_TYPE, Record, Abbrev);
+ Record.clear();
+}
+
void ModuleBitcodeWriter::writeDISubroutineType(
const DISubroutineType *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
@@ -1808,7 +1868,7 @@ void ModuleBitcodeWriter::writeDITemplateValueParameter(
void ModuleBitcodeWriter::writeDIGlobalVariable(
const DIGlobalVariable *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
- const uint64_t Version = 2 << 1;
+ const uint64_t Version = 3 << 1;
Record.push_back((uint64_t)N->isDistinct() | Version);
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
@@ -1820,6 +1880,7 @@ void ModuleBitcodeWriter::writeDIGlobalVariable(
Record.push_back(N->isDefinition());
Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration()));
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams()));
+ Record.push_back(N->getFlags());
Record.push_back(N->getAlignInBits());
Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 36278f2e9e2d..4ac02a24f275 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -178,6 +178,9 @@ class DebugLocEntry {
DebugLocStream::ListBuilder &List,
const DIBasicType *BT,
DwarfCompileUnit &TheCU);
+
+ void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List,
+ const DIStringType *ST, DwarfCompileUnit &TheCU);
};
/// Compare two DbgValueLocs for equality.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp
index 8c6109880afc..2db86b2aa94a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp
@@ -37,7 +37,10 @@ void DebugLocStream::finalizeEntry() {
"Popped off more entries than are in the list");
}
-DebugLocStream::ListBuilder::~ListBuilder() {
+void DebugLocStream::ListBuilder::finalize() {
+ if (Finalized)
+ return;
+ Finalized = true;
if (!Locs.finalizeList(Asm))
return;
V.initializeDbgValue(&MI);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
index 10019a4720e6..9dfce4e4b093 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
@@ -160,22 +160,25 @@ class DebugLocStream::ListBuilder {
const MachineInstr &MI;
size_t ListIndex;
Optional<uint8_t> TagOffset;
+ bool Finalized;
public:
ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm,
DbgVariable &V, const MachineInstr &MI)
: Locs(Locs), Asm(Asm), V(V), MI(MI), ListIndex(Locs.startList(&CU)),
- TagOffset(None) {}
+ TagOffset(None), Finalized(false) {}
void setTagOffset(uint8_t TO) {
TagOffset = TO;
}
+ void finalize();
+
/// Finalize the list.
///
/// If the list is empty, delete it. Otherwise, finalize it by creating a
/// temp symbol in \a Asm and setting up the \a DbgVariable.
- ~ListBuilder();
+ ~ListBuilder() { finalize(); }
DebugLocStream &getLocs() { return Locs; }
};
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index e97bcd62e8c7..86638a031ecb 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -153,7 +153,8 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
} else {
DeclContext = GV->getScope();
// Add name and type.
- addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
+ if (!GV->getDisplayName().empty())
+ addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
addType(*VariableDIE, GTy);
// Add scoping info.
@@ -169,6 +170,9 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
else
addGlobalName(GV->getName(), *VariableDIE, DeclContext);
+ if (GV->isArtificial())
+ addFlag(*VariableDIE, dwarf::DW_AT_artificial);
+
if (uint32_t AlignInBytes = GV->getAlignInBytes())
addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
AlignInBytes);
@@ -183,7 +187,12 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
}
void DwarfCompileUnit::addLocationAttribute(
- DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
+ DIE *VariableDIE, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
+ addLocationBlock(VariableDIE, dwarf::DW_AT_location, GV, GlobalExprs);
+}
+
+void DwarfCompileUnit::addLocationBlock(DIE *VariableDIE,
+ dwarf::Attribute Attribute, const DIGlobalVariable *GV, ArrayRef<GlobalExpr> GlobalExprs) {
bool addToAccelTable = false;
DIELoc *Loc = nullptr;
Optional<unsigned> NVPTXAddressSpace;
@@ -292,7 +301,7 @@ void DwarfCompileUnit::addLocationAttribute(
NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_global_space);
}
if (Loc)
- addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
+ addBlock(*VariableDIE, Attribute, DwarfExpr->finalize());
if (DD->useAllLinkageNames())
addLinkageName(*VariableDIE, GV->getLinkageName());
@@ -308,6 +317,13 @@ void DwarfCompileUnit::addLocationAttribute(
}
}
+ArrayRef<DwarfCompileUnit::GlobalExpr>
+DwarfCompileUnit::findGlobalExprList(DIGlobalVariable *GV) {
+ if (globalVarMap)
+ return (*globalVarMap)[GV];
+ return SmallVector<GlobalExpr, 1>();
+}
+
DIE *DwarfCompileUnit::getOrCreateCommonBlock(
const DICommonBlock *CB, ArrayRef<GlobalExpr> GlobalExprs) {
// Construct the context before querying for the existence of the DIE in case
@@ -607,21 +623,28 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
}
// Add variable address.
+ constructDieLocation(*VariableDie, dwarf::DW_AT_location, DV);
+ return VariableDie;
+}
- unsigned Offset = DV.getDebugLocListIndex();
- if (Offset != ~0U) {
- addLocationList(*VariableDie, dwarf::DW_AT_location, Offset);
- auto TagOffset = DV.getDebugLocListTagOffset();
- if (TagOffset)
- addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
- *TagOffset);
- return VariableDie;
+void DwarfCompileUnit::constructDieLocation(
+ DIE &Die, dwarf::Attribute Attribute, const DbgVariable &DV) {
+ if (Attribute == dwarf::DW_AT_location) {
+ unsigned Offset = DV.getDebugLocListIndex();
+ if (Offset != ~0U) {
+ addLocationList(Die, Attribute, Offset);
+ auto TagOffset = DV.getDebugLocListTagOffset();
+ if (TagOffset)
+ addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
+ *TagOffset);
+ return;
+ }
}
// Check if variable has a single location description.
if (auto *DVal = DV.getValueLoc()) {
if (DVal->isLocation())
- addVariableAddress(DV, *VariableDie, DVal->getLoc());
+ addVariableAddress(DV, Die, DVal->getLoc());
else if (DVal->isInt()) {
auto *Expr = DV.getSingleExpression();
if (Expr && Expr->getNumElements()) {
@@ -631,24 +654,23 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
DwarfExpr.addFragmentOffset(Expr);
DwarfExpr.addUnsignedConstant(DVal->getInt());
DwarfExpr.addExpression(Expr);
- addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
+ addBlock(Die, dwarf::DW_AT_location, DwarfExpr.finalize());
if (DwarfExpr.TagOffset)
- addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
+ addUInt(Die, dwarf::DW_AT_LLVM_tag_offset,
dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
-
} else
- addConstantValue(*VariableDie, DVal->getInt(), DV.getType());
+ addConstantValue(Die, DVal->getInt(), DV.getType());
} else if (DVal->isConstantFP()) {
- addConstantFPValue(*VariableDie, DVal->getConstantFP());
+ addConstantFPValue(Die, DVal->getConstantFP());
} else if (DVal->isConstantInt()) {
- addConstantValue(*VariableDie, DVal->getConstantInt(), DV.getType());
+ addConstantValue(Die, DVal->getConstantInt(), DV.getType());
}
- return VariableDie;
+ return;
}
// .. else use frame index.
if (!DV.hasFrameIndexExprs())
- return VariableDie;
+ return;
Optional<unsigned> NVPTXAddressSpace;
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
@@ -693,15 +715,52 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
// cuda-gdb requires DW_AT_address_class for all variables to be able to
// correctly interpret address space of the variable address.
const unsigned NVPTX_ADDR_local_space = 6;
- addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
+ addUInt(Die, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_local_space);
}
- addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
+ addBlock(Die, dwarf::DW_AT_location, DwarfExpr.finalize());
if (DwarfExpr.TagOffset)
- addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
+ addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
*DwarfExpr.TagOffset);
- return VariableDie;
+ return;
+}
+
+void DwarfCompileUnit::constructDieLocationAddExpr(
+ DIE &Die, dwarf::Attribute Attribute, const DbgVariable &DV,
+ DIExpression *SubExpr) {
+ if (Attribute == dwarf::DW_AT_location)
+ return; // clients like gdb don't handle location lists correctly
+ if (DV.getValueLoc())
+ return; // temp should not have a DBG_VALUE instruction
+ if (!DV.hasFrameIndexExprs())
+ return; // but it should have a frame index expression
+
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
+ for (auto &Fragment : DV.getFrameIndexExprs()) {
+ unsigned FrameReg = 0;
+ const DIExpression *Expr = Fragment.Expr;
+ const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
+ int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
+ DwarfExpr.addFragmentOffset(Expr);
+ SmallVector<uint64_t, 8> Ops;
+ Ops.push_back(dwarf::DW_OP_plus_uconst);
+ Ops.push_back(Offset);
+ Ops.append(Expr->elements_begin(), Expr->elements_end());
+ if (SubExpr) {
+ for (unsigned SEOp : SubExpr->getElements())
+ Ops.push_back(SEOp);
+ } else {
+ Ops.push_back(dwarf::DW_OP_deref);
+ }
+ DIExpressionCursor Cursor(Ops);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addMachineRegExpression(
+ *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
+ DwarfExpr.addExpression(std::move(Cursor));
+ }
+ addBlock(Die, Attribute, DwarfExpr.finalize());
}
DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 8491d078ed89..4c1750e40f1d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -139,6 +139,15 @@ class DwarfCompileUnit final : public DwarfUnit {
std::vector<BaseTypeRef> ExprRefedBaseTypes;
+private:
+ DenseMap<DIGlobalVariable *, SmallVector<GlobalExpr, 1>> *globalVarMap;
+public:
+ void setGlobalVarMap(
+ DenseMap<DIGlobalVariable *, SmallVector<GlobalExpr, 1>> *p = nullptr) {
+ globalVarMap = p;
+ }
+ ArrayRef<GlobalExpr> findGlobalExprList(DIGlobalVariable *GV);
+
/// Get or create global variable DIE.
DIE *
getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV,
@@ -149,6 +158,9 @@ class DwarfCompileUnit final : public DwarfUnit {
void addLocationAttribute(DIE *ToDIE, const DIGlobalVariable *GV,
ArrayRef<GlobalExpr> GlobalExprs);
+ void addLocationBlock(DIE *ToDIE, dwarf::Attribute Attr,
+ const DIGlobalVariable *GV,
+ ArrayRef<GlobalExpr> GlobalExprs);
/// addLabelAddress - Add a dwarf label attribute data and value using
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
@@ -358,6 +370,12 @@ class DwarfCompileUnit final : public DwarfUnit {
uint64_t getDWOId() const { return DWOId; }
void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
+ void constructDieLocation(DIE &Die, dwarf::Attribute Attribute,
+ const DbgVariable &DV);
+ void constructDieLocationAddExpr(DIE &Die, dwarf::Attribute Attribute,
+ const DbgVariable &DV,
+ DIExpression *SubExpr);
+
bool hasDwarfPubSections() const;
void addBaseTypeRef(DIEValueList &Die, int64_t Idx);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 6e643ad26410..b25db9f818b6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1030,11 +1030,13 @@ void DwarfDebug::beginModule() {
GVMapEntry.push_back({nullptr, Expr});
}
DenseSet<DIGlobalVariable *> Processed;
+ CU.setGlobalVarMap(&GVMap);
for (auto *GVE : CUNode->getGlobalVariables()) {
DIGlobalVariable *GV = GVE->getVariable();
if (Processed.insert(GV).second)
CU.getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV]));
}
+ CU.setGlobalVarMap();
for (auto *Ty : CUNode->getEnumTypes()) {
// The enum types array by design contains pointers to
@@ -1304,6 +1306,56 @@ void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
CU.createAbstractEntity(Node, Scope);
}
+DIE *DwarfDebug::getSubrangeDie(const DIFortranSubrange *SR) const {
+ auto I = SubrangeDieMap.find(SR);
+ return (I == SubrangeDieMap.end()) ? nullptr : I->second;
+}
+
+void DwarfDebug::constructSubrangeDie(const DIFortranArrayType *AT,
+ DbgVariable &DV,
+ DwarfCompileUnit &TheCU) {
+ const DIFortranSubrange *WFS = nullptr;
+ DIExpression *WUEx = nullptr;
+ DIExpression *WLEx = nullptr;
+ const DIVariable *DI = DV.getVariable();
+ DINodeArray Elements = AT->getElements();
+
+ for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
+ DINode *Element = cast<DINode>(Elements[i]);
+ if (const DIFortranSubrange *FS = dyn_cast<DIFortranSubrange>(Element)) {
+ if (DIVariable *UBV = FS->getUpperBound())
+ if (UBV == DI) {
+ WFS = FS;
+ WUEx = FS->getUpperBoundExp();
+ }
+ if (DIVariable *LBV = FS->getLowerBound())
+ if (LBV == DI) {
+ WFS = FS;
+ WLEx = FS->getLowerBoundExp();
+ }
+ }
+ if (WFS) {
+ DIE *Die;
+ auto I = SubrangeDieMap.find(WFS);
+ if (I == SubrangeDieMap.end()) {
+ Die = DIE::get(DIEValueAllocator, dwarf::DW_TAG_subrange_type);
+ SubrangeDieMap[WFS] = Die;
+ } else {
+ Die = I->second;
+ }
+
+ assert(Die);
+ if (WLEx)
+ TheCU.constructDieLocationAddExpr(
+ *Die, dwarf::DW_AT_lower_bound, DV, WLEx);
+ if (WUEx)
+ TheCU.constructDieLocationAddExpr(
+ *Die, dwarf::DW_AT_upper_bound, DV, WUEx);
+ WFS = nullptr;
+ }
+ }
+}
+
// Collect variable information from side table maintained by MF.
void DwarfDebug::collectVariableInfoFromMFTable(
DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) {
@@ -1326,6 +1378,11 @@ void DwarfDebug::collectVariableInfoFromMFTable(
auto RegVar = std::make_unique<DbgVariable>(
cast<DILocalVariable>(Var.first), Var.second);
RegVar->initializeMMI(VI.Expr, VI.Slot);
+ if (VariableInDependentType.count(VI.Var)) {
+ const DIType *DT = VariableInDependentType[VI.Var];
+ if (const DIFortranArrayType *AT = dyn_cast<DIFortranArrayType>(DT))
+ constructSubrangeDie(AT, *RegVar.get(), TheCU);
+ }
if (DbgVariable *DbgVar = MFVars.lookup(Var))
DbgVar->addMMIEntry(*RegVar);
else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
@@ -1548,10 +1605,36 @@ DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU,
return ConcreteEntities.back().get();
}
+void DwarfDebug::populateDependentTypeMap() {
+ for (const auto &I : DbgValues) {
+ InlinedEntity IV = I.first;
+ if (I.second.empty())
+ continue;
+ if (const DIVariable *DIV = dyn_cast<DIVariable>(IV.first)) {
+ if (const DIStringType *ST = dyn_cast<DIStringType>(
+ static_cast<const Metadata *>(DIV->getType())))
+ if (const DIVariable *LV = ST->getStringLength())
+ VariableInDependentType[LV] = ST;
+
+ if (const DIFortranArrayType *AT = dyn_cast<DIFortranArrayType>(
+ static_cast<const Metadata *>(DIV->getType())))
+ for (const DINode *S : AT->getElements())
+ if (const DIFortranSubrange *FS = dyn_cast<DIFortranSubrange>(S)) {
+ if (const DIVariable *LBV = FS->getLowerBound())
+ VariableInDependentType[LBV] = AT;
+ if (const DIVariable *UBV = FS->getUpperBound())
+ VariableInDependentType[UBV] = AT;
+ }
+ }
+ }
+}
+
// Find variables for each lexical scope.
void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
const DISubprogram *SP,
DenseSet<InlinedEntity> &Processed) {
+ clearDependentTracking();
+ populateDependentTypeMap();
// Grab the variable info that was squirreled away in the MMI side-table.
collectVariableInfoFromMFTable(TheCU, Processed);
@@ -1566,7 +1649,9 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
continue;
LexicalScope *Scope = nullptr;
- const DILocalVariable *LocalVar = cast<DILocalVariable>(IV.first);
+ const DILocalVariable *LocalVar = dyn_cast<DILocalVariable>(IV.first);
+ if (!LocalVar)
+ continue;
if (const DILocation *IA = IV.second)
Scope = LScopes.findInlinedScope(LocalVar->getScope(), IA);
else
@@ -1625,6 +1710,22 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
// Finalize the entry by lowering it into a DWARF bytestream.
for (auto &Entry : Entries)
Entry.finalize(*Asm, List, BT, TheCU);
+ List.finalize();
+
+ if (VariableInDependentType.count(LocalVar)) {
+ const DIType *DT = VariableInDependentType[LocalVar];
+ if (const DIStringType *ST = dyn_cast<DIStringType>(DT)) {
+ unsigned Offset;
+ DbgVariable TVar = {LocalVar, IV.second};
+ DebugLocStream::ListBuilder LB(DebugLocs, TheCU, *Asm, TVar, *MInsn);
+ for (auto &Entry : Entries)
+ Entry.finalize(*Asm, LB, ST, TheCU);
+ LB.finalize();
+ Offset = TVar.getDebugLocListIndex();
+ if (Offset != ~0u)
+ addStringTypeLoc(ST, Offset);
+ }
+ }
}
// For each InlinedEntity collected from DBG_LABEL instructions, convert to
@@ -2295,6 +2396,33 @@ void DebugLocEntry::finalize(const AsmPrinter &AP,
List.setTagOffset(*DwarfExpr.TagOffset);
}
+inline static DbgValueLoc mkDbgValueLoc(const DIExpression *expr,
+ DbgValueLoc &value) {
+ if (value.isInt())
+ return DbgValueLoc(expr, value.getInt());
+ if (value.isLocation())
+ return DbgValueLoc(expr, value.getLoc());
+ if (value.isConstantInt())
+ return DbgValueLoc(expr, value.getConstantInt());
+ assert(value.isConstantFP());
+ return DbgValueLoc(expr, value.getConstantFP());
+}
+
+void DebugLocEntry::finalize(const AsmPrinter &AP,
+ DebugLocStream::ListBuilder &List,
+ const DIStringType *ST,
+ DwarfCompileUnit &TheCU) {
+ DebugLocStream::EntryBuilder Entry(List, Begin, End);
+ BufferByteStreamer Streamer = Entry.getStreamer();
+ DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer, TheCU);
+ DbgValueLoc &Value = Values[0];
+ assert(!Value.isFragment());
+ assert(Values.size() == 1 && "only fragments may have >1 value");
+ Value = mkDbgValueLoc(ST->getStringLengthExp(), Value);
+ DwarfDebug::emitDebugLocValue(AP, nullptr, Value, DwarfExpr);
+ DwarfExpr.finalize();
+}
+
void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry,
const DwarfCompileUnit *CU) {
// Emit the size.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index f90dd48458ea..85b6bcfb2fbf 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -285,6 +285,8 @@ struct SymbolCU {
DwarfCompileUnit *CU;
};
+class DummyDwarfExpression;
+
/// The kind of accelerator tables we should emit.
enum class AccelTableKind {
Default, ///< Platform default.
@@ -406,6 +408,14 @@ class DwarfDebug : public DebugHandlerBase {
bool SingleCU;
bool IsDarwin;
+ /// Map for tracking Fortran deferred CHARACTER lengths
+ DenseMap<const DIStringType*, unsigned> StringTypeLocMap;
+
+ /// Map for tracking Fortran assumed shape array descriptors
+ DenseMap<const DIFortranSubrange*, DIE*> SubrangeDieMap;
+
+ DenseMap<const DIVariable*,const DIType*> VariableInDependentType;
+
AddressPool AddrPool;
/// Accelerator tables.
@@ -593,6 +603,12 @@ class DwarfDebug : public DebugHandlerBase {
/// Emit the reference to the section.
void emitSectionReference(const DwarfCompileUnit &CU);
+ /// Populate dependent type variable map
+ void populateDependentTypeMap();
+
+ /// Clear dependent type tracking map
+ void clearDependentTracking() { VariableInDependentType.clear(); }
+
protected:
/// Gather pre-function debug information.
void beginFunctionImpl(const MachineFunction *MF) override;
@@ -754,6 +770,21 @@ class DwarfDebug : public DebugHandlerBase {
return CUDieMap.lookup(Die);
}
+ unsigned getStringTypeLoc(const DIStringType *ST) const {
+ auto I = StringTypeLocMap.find(ST);
+ return I != StringTypeLocMap.end() ? I->second : 0;
+ }
+
+ void addStringTypeLoc(const DIStringType *ST, unsigned Loc) {
+ assert(ST);
+ if (Loc)
+ StringTypeLocMap[ST] = Loc;
+ }
+
+ DIE *getSubrangeDie(const DIFortranSubrange *SR) const;
+ void constructSubrangeDie(const DIFortranArrayType *AT,
+ DbgVariable &DV, DwarfCompileUnit &TheCU);
+
/// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger.
///
/// Returns whether we are "tuning" for a given debugger.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 53747aef77fd..7ed28d983fc8 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -655,8 +655,12 @@ DIE *DwarfUnit::createTypeDIE(const DIScope *Context, DIE &ContextDIE,
if (auto *BT = dyn_cast<DIBasicType>(Ty))
constructTypeDIE(TyDIE, BT);
+ else if (auto *ST = dyn_cast<DIStringType>(Ty))
+ constructTypeDIE(TyDIE, ST);
else if (auto *STy = dyn_cast<DISubroutineType>(Ty))
constructTypeDIE(TyDIE, STy);
+ else if (auto *ATy = dyn_cast<DIFortranArrayType>(Ty))
+ constructArrayTypeDIE(TyDIE, ATy);
else if (auto *CTy = dyn_cast<DICompositeType>(Ty)) {
if (DD->generateTypeUnits() && !Ty->isForwardDecl() &&
(Ty->getRawName() || CTy->getRawIdentifier())) {
@@ -773,8 +777,9 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {
if (BTy->getTag() == dwarf::DW_TAG_unspecified_type)
return;
- addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
- BTy->getEncoding());
+ if (BTy->getTag() != dwarf::DW_TAG_string_type)
+ addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
+ BTy->getEncoding());
uint64_t Size = BTy->getSizeInBits() >> 3;
addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
@@ -785,6 +790,31 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {
addUInt(Buffer, dwarf::DW_AT_endianity, None, dwarf::DW_END_little);
}
+void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIStringType *STy) {
+ // Get core information.
+ StringRef Name = STy->getName();
+ // Add name if not anonymous or intermediate type.
+ if (!Name.empty())
+ addString(Buffer, dwarf::DW_AT_name, Name);
+
+ if (unsigned LLI = DD->getStringTypeLoc(STy)) {
+ // DW_TAG_string_type has a DW_AT_string_length location
+ dwarf::Form Form = (DD->getDwarfVersion() >= 4)
+ ? dwarf::DW_FORM_sec_offset : dwarf::DW_FORM_data4;
+ Buffer.addValue(DIEValueAllocator, dwarf::DW_AT_string_length, Form,
+ DIELocList(LLI));
+ }
+
+ uint64_t Size = STy->getSizeInBits() >> 3;
+ addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
+
+ if (STy->getEncoding()) {
+ // for eventual unicode support
+ addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
+ STy->getEncoding());
+ }
+}
+
void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) {
// Get core information.
StringRef Name = DTy->getName();
@@ -1349,6 +1379,48 @@ void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,
addUInt(DW_Subrange, dwarf::DW_AT_count, None, Count);
}
+void DwarfUnit::constructFortranSubrangeDIE(DIE &Buffer,
+ const DIFortranSubrange *SR) {
+ DIE *IndexTy = getIndexTyDie();
+ DIE *Die = DD->getSubrangeDie(SR);
+ if ((!Die) || Die->getParent())
+ Die = DIE::get(DIEValueAllocator, dwarf::DW_TAG_subrange_type);
+ DIE &DW_Subrange = Buffer.addChild(Die);
+ addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy);
+
+ if (DIVariable *GV = SR->getLowerBound()) {
+ if (DIGlobalVariable *GVar = dyn_cast<DIGlobalVariable>(GV)) {
+ ArrayRef<DwarfCompileUnit::GlobalExpr> GEL = getCU().findGlobalExprList(GVar);
+ if (GEL.size() >= 1) {
+ DwarfCompileUnit::GlobalExpr GE = {GEL.front().Var, SR->getLowerBoundExp()};
+ SmallVector<DwarfCompileUnit::GlobalExpr, 1> GEV;
+ GEV.emplace_back(GE);
+ getCU().addLocationBlock(Die, dwarf::DW_AT_lower_bound, GVar, GEV);
+ }
+ }
+ } else {
+ int64_t BVC = SR->getCLowerBound();
+ addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, dwarf::DW_FORM_sdata, BVC);
+ }
+
+ if (SR->noUpperBound()) {
+ // do nothing
+ } else if (DIVariable *GV = SR->getUpperBound()) {
+ if (DIGlobalVariable *GVar = dyn_cast<DIGlobalVariable>(GV)) {
+ ArrayRef<DwarfCompileUnit::GlobalExpr> GEL = getCU().findGlobalExprList(GVar);
+ if (GEL.size() >= 1) {
+ DwarfCompileUnit::GlobalExpr GE = {GEL.front().Var, SR->getUpperBoundExp()};
+ SmallVector<DwarfCompileUnit::GlobalExpr, 1> GEV;
+ GEV.emplace_back(GE);
+ getCU().addLocationBlock(Die, dwarf::DW_AT_upper_bound, GVar, GEV);
+ }
+ }
+ } else {
+ int64_t BVC = SR->getCUpperBound();
+ addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, dwarf::DW_FORM_sdata, BVC);
+ }
+}
+
DIE *DwarfUnit::getIndexTyDie() {
if (IndexTyDie)
return IndexTyDie;
@@ -1416,6 +1488,20 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
}
}
+void DwarfUnit::constructArrayTypeDIE(DIE &Buffer,
+ const DIFortranArrayType *ATy) {
+ // Emit the element type.
+ addType(Buffer, ATy->getBaseType());
+
+ // Add subranges to array type.
+ DINodeArray Elements = ATy->getElements();
+ for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
+ DINode *Element = cast<DINode>(Elements[i]);
+ if (const DIFortranSubrange *FS = dyn_cast<DIFortranSubrange>(Element))
+ constructFortranSubrangeDIE(Buffer, FS);
+ }
+}
+
void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
const DIType *DTy = CTy->getBaseType();
bool IsUnsigned = DTy && isUnsignedDIType(DD, DTy);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 46c52a1faf4b..69ef19482f6f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -307,10 +307,14 @@ class DwarfUnit : public DIEUnit {
private:
void constructTypeDIE(DIE &Buffer, const DIBasicType *BTy);
+ void constructTypeDIE(DIE &Buffer, const DIStringType *BTy);
+ void constructTypeDIE(DIE &Buffer, const DIFortranArrayType *ATy);
void constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy);
void constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy);
void constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, DIE *IndexTy);
+ void constructFortranSubrangeDIE(DIE &Buffer, const DIFortranSubrange *SR);
void constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy);
+ void constructArrayTypeDIE(DIE &Buffer, const DIFortranArrayType *ATy);
void constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy);
DIE &constructMemberDIE(DIE &Buffer, const DIDerivedType *DT);
void constructTemplateTypeParameterDIE(DIE &Buffer,
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 1f978d136049..10fa3fc4bad6 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1813,6 +1813,24 @@ static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
Out << ")";
}
+static void writeDIFortranSubrange(raw_ostream &Out, const DIFortranSubrange *N,
+ TypePrinting *TypePrinter,
+ SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!DIFortranSubrange(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printInt("constLowerBound", N->getCLowerBound(), false);
+ if (!N->noUpperBound())
+ Printer.printInt("constUpperBound", N->getCUpperBound(), false);
+ Printer.printMetadata("lowerBound", N->getRawLowerBound());
+ Printer.printMetadata("lowerBoundExpression",
+ N->getRawLowerBoundExpression());
+ Printer.printMetadata("upperBound", N->getRawUpperBound());
+ Printer.printMetadata("upperBoundExpression",
+ N->getRawUpperBoundExpression());
+ Out << ")";
+}
+
static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
TypePrinting *, SlotTracker *, const Module *) {
Out << "!DIEnumerator(";
@@ -1843,6 +1861,23 @@ static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
Out << ")";
}
+static void writeDIStringType(raw_ostream &Out, const DIStringType *N,
+ TypePrinting *TypePrinter, SlotTracker *Machine,
+ const Module *Context) {
+ Out << "!DIStringType(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ if (N->getTag() != dwarf::DW_TAG_string_type)
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("stringLength", N->getRawStringLength());
+ Printer.printMetadata("stringLengthExpression", N->getRawStringLengthExp());
+ Printer.printInt("size", N->getSizeInBits());
+ Printer.printInt("align", N->getAlignInBits());
+ Printer.printDwarfEnum("encoding", N->getEncoding(),
+ dwarf::AttributeEncodingString);
+ Out << ")";
+}
+
static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
@@ -1891,6 +1926,25 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
Out << ")";
}
+static void writeDIFortranArrayType(
+ raw_ostream &Out, const DIFortranArrayType *N, TypePrinting *TypePrinter,
+ SlotTracker *Machine, const Module *Context) {
+ Out << "!DIFortranArrayType(";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("scope", N->getRawScope());
+ Printer.printMetadata("file", N->getRawFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("baseType", N->getRawBaseType());
+ Printer.printInt("size", N->getSizeInBits());
+ Printer.printInt("align", N->getAlignInBits());
+ Printer.printInt("offset", N->getOffsetInBits());
+ Printer.printDIFlags("flags", N->getFlags());
+ Printer.printMetadata("elements", N->getRawElements());
+ Out << ")";
+}
+
static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N,
TypePrinting *TypePrinter,
SlotTracker *Machine, const Module *Context) {
@@ -2104,6 +2158,7 @@ static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
Printer.printBool("isDefinition", N->isDefinition());
Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
Printer.printMetadata("templateParams", N->getRawTemplateParams());
+ Printer.printDIFlags("flags", N->getFlags());
Printer.printInt("align", N->getAlignInBits());
Out << ")";
}
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index c89f404e4296..d0431e5f9aac 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -265,6 +265,12 @@ DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
0, Encoding, Flags);
}
+DIStringType *DIBuilder::createStringType(StringRef Name, uint64_t SizeInBits) {
+ assert(!Name.empty() && "Unable to create type without name");
+ return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name,
+ SizeInBits, 0);
+}
+
DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) {
return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0,
0, 0, None, DINode::FlagZero);
@@ -526,6 +532,15 @@ DICompositeType *DIBuilder::createArrayType(uint64_t Size,
return R;
}
+DIFortranArrayType *DIBuilder::createFortranArrayType(
+ uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts) {
+ auto *R = DIFortranArrayType::get(VMContext, dwarf::DW_TAG_array_type, "",
+ nullptr, 0, nullptr, Ty, Size, AlignInBits,
+ 0, DINode::FlagZero, Subscripts);
+ trackIfUnresolved(R);
+ return R;
+}
+
DICompositeType *DIBuilder::createVectorType(uint64_t Size,
uint32_t AlignInBits, DIType *Ty,
DINodeArray Subscripts) {
@@ -629,6 +644,12 @@ DISubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, Metadata *CountNode) {
return DISubrange::get(VMContext, CountNode, Lo);
}
+DIFortranSubrange *DIBuilder::getOrCreateFortranSubrange(
+ int64_t CLB, int64_t CUB, bool NUB, Metadata *LB, Metadata *LBE,
+ Metadata *UB, Metadata *UBE) {
+ return DIFortranSubrange::get(VMContext, CLB, CUB, NUB, LB, LBE, UB, UBE);
+}
+
static void checkGlobalVariableScope(DIScope *Context) {
#ifndef NDEBUG
if (auto *CT =
@@ -641,14 +662,15 @@ static void checkGlobalVariableScope(DIScope *Context) {
DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
unsigned LineNumber, DIType *Ty, bool IsLocalToUnit,
- bool isDefined, DIExpression *Expr,
- MDNode *Decl, MDTuple *TemplateParams, uint32_t AlignInBits) {
+ bool IsDefined, DIExpression *Expr,
+ MDNode *Decl, MDTuple *TemplateParams, DINode::DIFlags Flags,
+ uint32_t AlignInBits) {
checkGlobalVariableScope(Context);
auto *GV = DIGlobalVariable::getDistinct(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
- LineNumber, Ty, IsLocalToUnit, isDefined, cast_or_null<DIDerivedType>(Decl),
- TemplateParams, AlignInBits);
+ LineNumber, Ty, IsLocalToUnit, IsDefined, cast_or_null<DIDerivedType>(Decl),
+ TemplateParams, Flags, AlignInBits);
if (!Expr)
Expr = createExpression();
auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr);
@@ -659,13 +681,14 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression(
DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, MDNode *Decl,
- MDTuple *TemplateParams, uint32_t AlignInBits) {
+ MDTuple *TemplateParams, DINode::DIFlags Flags, uint32_t AlignInBits) {
checkGlobalVariableScope(Context);
return DIGlobalVariable::getTemporary(
VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
LineNumber, Ty, IsLocalToUnit, false,
- cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits)
+ cast_or_null<DIDerivedType>(Decl), TemplateParams, Flags,
+ AlignInBits)
.release();
}
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index fe8311923109..e7aaff2704cb 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -1285,12 +1285,13 @@ LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File,
unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
- LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits) {
+ LLVMMetadataRef Expr, LLVMMetadataRef Decl, LLVMDIFlags Flags,
+ uint32_t AlignInBits) {
return wrap(unwrap(Builder)->createGlobalVariableExpression(
unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LinkLen},
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit,
true, unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl),
- nullptr, AlignInBits));
+ nullptr, map_from_llvmDIFlags(Flags), AlignInBits));
}
LLVMMetadataRef LLVMDIGlobalVariableExpressionGetVariable(LLVMMetadataRef GVE) {
@@ -1335,11 +1336,12 @@ LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File,
unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
- LLVMMetadataRef Decl, uint32_t AlignInBits) {
+ LLVMMetadataRef Decl, LLVMDIFlags Flags, uint32_t AlignInBits) {
return wrap(unwrap(Builder)->createTempGlobalVariableFwdDecl(
unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LnkLen},
unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit,
- unwrapDI<MDNode>(Decl), nullptr, AlignInBits));
+ unwrapDI<MDNode>(Decl), nullptr, map_from_llvmDIFlags(Flags),
+ AlignInBits));
}
LLVMValueRef
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index d3ecd9b0e03d..f9da8c6aa4ac 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -332,6 +332,15 @@ DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
DEFINE_GETIMPL_STORE(DISubrange, (CountNode, Lo), Ops);
}
+DIFortranSubrange *DIFortranSubrange::getImpl(
+ LLVMContext &Context, int64_t CLB, int64_t CUB, bool NUB, Metadata *LB,
+ Metadata *LBE, Metadata *UB, Metadata *UBE, StorageType Storage,
+ bool ShouldCreate) {
+ DEFINE_GETIMPL_LOOKUP(DIFortranSubrange, (CLB, CUB, NUB, LB, LBE, UB, UBE));
+ Metadata *Ops[] = {LB, LBE, UB, UBE};
+ DEFINE_GETIMPL_STORE(DIFortranSubrange, (CLB, CUB, NUB), Ops);
+}
+
DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, int64_t Value,
bool IsUnsigned, MDString *Name,
StorageType Storage, bool ShouldCreate) {
@@ -354,6 +363,21 @@ DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
Flags), Ops);
}
+DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, Metadata *StringLength,
+ Metadata *StringLengthExp,
+ uint64_t SizeInBits, uint32_t AlignInBits,
+ unsigned Encoding, StorageType Storage,
+ bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+ DEFINE_GETIMPL_LOOKUP(DIStringType,
+ (Tag, Name, StringLength, StringLengthExp, SizeInBits,
+ AlignInBits, Encoding));
+ Metadata *Ops[] = {nullptr, nullptr, Name, StringLength, StringLengthExp};
+ DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding),
+ Ops);
+}
+
Optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
switch (getEncoding()) {
case dwarf::DW_ATE_signed:
@@ -384,6 +408,22 @@ DIDerivedType *DIDerivedType::getImpl(
DWARFAddressSpace, Flags), Ops);
}
+DIFortranArrayType *DIFortranArrayType::getImpl(
+ LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
+ uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
+ Metadata *Elements, StorageType Storage, bool ShouldCreate) {
+ assert(isCanonical(Name) && "Expected canonical MDString");
+
+ // Keep this in sync with buildODRType.
+ DEFINE_GETIMPL_LOOKUP(
+ DIFortranArrayType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements));
+ Metadata *Ops[] = {File, Scope, Name, BaseType, Elements};
+ DEFINE_GETIMPL_STORE(DIFortranArrayType, (Tag, Line, SizeInBits, AlignInBits,
+ OffsetInBits, Flags), Ops);
+}
+
DICompositeType *DICompositeType::getImpl(
LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
@@ -749,14 +789,15 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line,
Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration,
- Metadata *TemplateParams, uint32_t AlignInBits,
- StorageType Storage, bool ShouldCreate) {
+ Metadata *TemplateParams, DIFlags Flags,
+ uint32_t AlignInBits, StorageType Storage,
+ bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
assert(isCanonical(LinkageName) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition,
StaticDataMemberDeclaration,
- TemplateParams, AlignInBits));
+ TemplateParams, Flags, AlignInBits));
Metadata *Ops[] = {Scope,
Name,
File,
@@ -766,7 +807,8 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
StaticDataMemberDeclaration,
TemplateParams};
DEFINE_GETIMPL_STORE(DIGlobalVariable,
- (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
+ (Line, IsLocalToUnit, IsDefinition, Flags, AlignInBits),
+ Ops);
}
DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope,
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 6f5d5752b38d..ece84ca75d62 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -354,6 +354,42 @@ template <> struct MDNodeKeyImpl<DISubrange> {
}
};
+template <> struct MDNodeKeyImpl<DIFortranSubrange> {
+ int64_t CLBound;
+ int64_t CUBound;
+ bool NoUBound;
+ Metadata *LowerBound;
+ Metadata *LowerBoundExp;
+ Metadata *UpperBound;
+ Metadata *UpperBoundExp;
+
+ MDNodeKeyImpl(int64_t CLB, int64_t CUB, bool NUB, Metadata *LB, Metadata *LBE,
+ Metadata *UB, Metadata *UBE)
+ : CLBound(CLB), CUBound(CUB), NoUBound(NUB), LowerBound(LB),
+ LowerBoundExp(LBE), UpperBound(UB), UpperBoundExp(UBE) {}
+ MDNodeKeyImpl(const DIFortranSubrange *N)
+ : CLBound(N->getCLowerBound()), CUBound(N->getCUpperBound()),
+ NoUBound(N->noUpperBound()), LowerBound(N->getRawLowerBound()),
+ LowerBoundExp(N->getRawLowerBoundExpression()),
+ UpperBound(N->getRawUpperBound()),
+ UpperBoundExp(N->getRawUpperBoundExpression()) {}
+
+ bool isKeyOf(const DIFortranSubrange *RHS) const {
+ return CLBound == RHS->getCLowerBound() &&
+ CUBound == RHS->getCUpperBound() &&
+ NoUBound == RHS->noUpperBound() &&
+ LowerBound == RHS->getRawLowerBound() &&
+ LowerBoundExp == RHS->getRawLowerBoundExpression() &&
+ UpperBound == RHS->getRawUpperBound() &&
+ UpperBoundExp == RHS->getRawUpperBoundExpression();
+ }
+
+ unsigned getHashValue() const {
+ return hash_combine(CLBound, CUBound, NoUBound, UpperBound, UpperBoundExp,
+ LowerBound, LowerBoundExp);
+ }
+};
+
template <> struct MDNodeKeyImpl<DIEnumerator> {
int64_t Value;
MDString *Name;
@@ -402,6 +438,39 @@ template <> struct MDNodeKeyImpl<DIBasicType> {
}
};
+template <> struct MDNodeKeyImpl<DIStringType> {
+ unsigned Tag;
+ MDString *Name;
+ Metadata *StringLength;
+ Metadata *StringLengthExp;
+ uint64_t SizeInBits;
+ uint32_t AlignInBits;
+ unsigned Encoding;
+
+ MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *StringLength,
+ Metadata *StringLengthExp, uint64_t SizeInBits,
+ uint32_t AlignInBits, unsigned Encoding)
+ : Tag(Tag), Name(Name), StringLength(StringLength),
+ StringLengthExp(StringLengthExp), SizeInBits(SizeInBits),
+ AlignInBits(AlignInBits), Encoding(Encoding) {}
+ MDNodeKeyImpl(const DIStringType *N)
+ : Tag(N->getTag()), Name(N->getRawName()),
+ StringLength(N->getRawStringLength()),
+ StringLengthExp(N->getRawStringLengthExp()),
+ SizeInBits(N->getSizeInBits()),
+ AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()) {}
+
+ bool isKeyOf(const DIStringType *RHS) const {
+ return Tag == RHS->getTag() && Name == RHS->getRawName() &&
+ SizeInBits == RHS->getSizeInBits() &&
+ AlignInBits == RHS->getAlignInBits() &&
+ Encoding == RHS->getEncoding();
+ }
+ unsigned getHashValue() const {
+ return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding);
+ }
+};
+
template <> struct MDNodeKeyImpl<DIDerivedType> {
unsigned Tag;
MDString *Name;
@@ -558,6 +627,52 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
}
};
+template <> struct MDNodeKeyImpl<DIFortranArrayType> {
+ unsigned Tag;
+ MDString *Name;
+ Metadata *File;
+ unsigned Line;
+ Metadata *Scope;
+ Metadata *BaseType;
+ uint64_t SizeInBits;
+ uint64_t OffsetInBits;
+ uint32_t AlignInBits;
+ unsigned Flags;
+ Metadata *Elements;
+
+ MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
+ Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
+ uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
+ Metadata *Elements)
+ : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
+ BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
+ AlignInBits(AlignInBits), Flags(Flags), Elements(Elements) {}
+ MDNodeKeyImpl(const DIFortranArrayType *N)
+ : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
+ Line(N->getLine()), Scope(N->getRawScope()),
+ BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
+ OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
+ Flags(N->getFlags()), Elements(N->getRawElements()) {}
+
+ bool isKeyOf(const DIFortranArrayType *RHS) const {
+ return Tag == RHS->getTag() && Name == RHS->getRawName() &&
+ File == RHS->getRawFile() && Line == RHS->getLine() &&
+ Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
+ SizeInBits == RHS->getSizeInBits() &&
+ AlignInBits == RHS->getAlignInBits() &&
+ OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
+ Elements == RHS->getRawElements();
+ }
+
+ unsigned getHashValue() const {
+ // Intentionally computes the hash on a subset of the operands for
+ // performance reason. The subset has to be significant enough to avoid
+ // collision "most of the time". There is no correctness issue in case of
+ // collision because of the full check above.
+ return hash_combine(Name, File, Line, BaseType, Scope, Elements);
+ }
+};
+
template <> struct MDNodeKeyImpl<DISubroutineType> {
unsigned Flags;
uint8_t CC;
@@ -889,25 +1004,27 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
bool IsDefinition;
Metadata *StaticDataMemberDeclaration;
Metadata *TemplateParams;
+ unsigned Flags;
uint32_t AlignInBits;
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition,
Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
- uint32_t AlignInBits)
+ unsigned Flags, uint32_t AlignInBits)
: Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
IsDefinition(IsDefinition),
StaticDataMemberDeclaration(StaticDataMemberDeclaration),
- TemplateParams(TemplateParams), AlignInBits(AlignInBits) {}
+ TemplateParams(TemplateParams), Flags(Flags),
+ AlignInBits(AlignInBits) {}
MDNodeKeyImpl(const DIGlobalVariable *N)
: Scope(N->getRawScope()), Name(N->getRawName()),
LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
Line(N->getLine()), Type(N->getRawType()),
IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
- TemplateParams(N->getRawTemplateParams()),
+ TemplateParams(N->getRawTemplateParams()), Flags(N->getFlags()),
AlignInBits(N->getAlignInBits()) {}
bool isKeyOf(const DIGlobalVariable *RHS) const {
@@ -919,6 +1036,7 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
StaticDataMemberDeclaration ==
RHS->getRawStaticDataMemberDeclaration() &&
TemplateParams == RHS->getRawTemplateParams() &&
+ Flags == RHS->getFlags() &&
AlignInBits == RHS->getAlignInBits();
}
@@ -932,7 +1050,7 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> {
// TODO: make hashing work fine with such situations
return hash_combine(Scope, Name, LinkageName, File, Line, Type,
IsLocalToUnit, IsDefinition, /* AlignInBits, */
- StaticDataMemberDeclaration);
+ StaticDataMemberDeclaration, Flags);
}
};
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 7711a11b766d..202fda5aff44 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -899,6 +899,14 @@ void Verifier::visitDISubrange(const DISubrange &N) {
"invalid subrange count", &N);
}
+void Verifier::visitDIFortranSubrange(const DIFortranSubrange &N) {
+ AssertDI(N.getTag() == dwarf::DW_TAG_subrange_type, "invalid tag", &N);
+ AssertDI(N.getLowerBound() ? (N.getLowerBoundExp() != nullptr) : true,
+ "no lower bound", &N);
+ AssertDI(N.getUpperBound() ? (N.getUpperBoundExp() != nullptr) : true,
+ "no upper bound", &N);
+}
+
void Verifier::visitDIEnumerator(const DIEnumerator &N) {
AssertDI(N.getTag() == dwarf::DW_TAG_enumerator, "invalid tag", &N);
}
@@ -912,6 +920,11 @@ void Verifier::visitDIBasicType(const DIBasicType &N) {
"has conflicting flags", &N);
}
+void Verifier::visitDIStringType(const DIStringType &N) {
+ AssertDI( N.getTag() == dwarf::DW_TAG_string_type,
+ "invalid tag", &N);
+}
+
void Verifier::visitDIDerivedType(const DIDerivedType &N) {
// Common scope checks.
visitDIScope(N);
@@ -1012,6 +1025,22 @@ void Verifier::visitDICompositeType(const DICompositeType &N) {
}
}
+void Verifier::visitDIFortranArrayType(const DIFortranArrayType &N) {
+ // Common scope checks.
+ visitDIScope(N);
+
+ AssertDI(N.getTag() == dwarf::DW_TAG_array_type, "invalid tag", &N);
+
+ AssertDI(isScope(N.getRawScope()), "invalid scope", &N, N.getRawScope());
+ AssertDI(isType(N.getRawBaseType()), "invalid base type", &N,
+ N.getRawBaseType());
+
+ AssertDI(!N.getRawElements() || isa<MDTuple>(N.getRawElements()),
+ "invalid composite elements", &N, N.getRawElements());
+ AssertDI(!hasConflictingReferenceFlags(N.getFlags()),
+ "invalid reference flags", &N);
+}
+
void Verifier::visitDISubroutineType(const DISubroutineType &N) {
AssertDI(N.getTag() == dwarf::DW_TAG_subroutine_type, "invalid tag", &N);
if (auto *Types = N.getRawTypeArray()) {
@@ -1250,6 +1279,8 @@ void Verifier::visitDIGlobalVariable(const DIGlobalVariable &N) {
visitDIVariable(N);
AssertDI(N.getTag() == dwarf::DW_TAG_variable, "invalid tag", &N);
+ AssertDI(!N.getName().empty() || N.isArtificial(),
+ "missing global variable name", &N);
AssertDI(isType(N.getRawType()), "invalid type ref", &N, N.getRawType());
AssertDI(N.getType(), "missing global variable type", &N);
if (auto *Member = N.getRawStaticDataMemberDeclaration()) {
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index ebfd5fe8b762..5c41d8a74b6b 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -5143,8 +5143,10 @@ LoopVectorizationCostModel::getSmallestAndWidestTypes() {
if (ValuesToIgnore.find(&I) != ValuesToIgnore.end())
continue;
- // Only examine Loads, Stores and PHINodes.
- if (!isa<LoadInst>(I) && !isa<StoreInst>(I) && !isa<PHINode>(I))
+ // Examine Loads, Stores, PHINodes
+ // Also examine instructions which convert to a float/double
+ if (!isa<LoadInst>(I) && !isa<StoreInst>(I) && !isa<PHINode>(I) &&
+ !isa<FPExtInst>(I) && !isa<SIToFPInst>(I) && !isa<UIToFPInst>(I))
continue;
// Examine PHI nodes that are reduction variables. Update the type to
diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c
index b5080f01193b..70ba6b174ca2 100644
--- a/llvm/tools/llvm-c-test/debuginfo.c
+++ b/llvm/tools/llvm-c-test/debuginfo.c
@@ -64,7 +64,7 @@ int llvm_test_dibuilder(void) {
LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
LLVMDIBuilderCreateGlobalVariableExpression(
DIB, Module, "globalClass", 11, "", 0, File, 1, ClassTy, true,
- GlobalClassValueExpr, NULL, 0);
+ GlobalClassValueExpr, NULL, LLVMDIFlagZero, 0);
LLVMMetadataRef Int64Ty =
LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero);
@@ -75,7 +75,7 @@ int llvm_test_dibuilder(void) {
LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
LLVMDIBuilderCreateGlobalVariableExpression(
DIB, Module, "global", 6, "", 0, File, 1, Int64TypeDef, true,
- GlobalVarValueExpr, NULL, 0);
+ GlobalVarValueExpr, NULL, LLVMDIFlagZero, 0);
LLVMMetadataRef NameSpace =
LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false);
More information about the llvm-branch-commits
mailing list