summaryrefslogtreecommitdiffstats
path: root/clang/include
diff options
context:
space:
mode:
authorMomchil Velikov <momchil.velikov@arm.com>2018-07-30 17:48:23 +0000
committerMomchil Velikov <momchil.velikov@arm.com>2018-07-30 17:48:23 +0000
commit20208cc046c206a1436edb714e94bd52a0bc8572 (patch)
tree24548919809d313e32c81ace99e7da457dbf1d1b /clang/include
parentfa3bee47569b1583e4319bbdbcd3f129345caa25 (diff)
downloadbcm5719-llvm-20208cc046c206a1436edb714e94bd52a0bc8572.tar.gz
bcm5719-llvm-20208cc046c206a1436edb714e94bd52a0bc8572.zip
[ARM, AArch64]: Use unadjusted alignment when passing composites as arguments
The "Procedure Call Procedure Call Standard for the ARMĀ® Architecture" (https://static.docs.arm.com/ihi0042/f/IHI0042F_aapcs.pdf), specifies that composite types are passed according to their "natural alignment", i.e. the alignment before alignment adjustment on the entire composite is applied. The same applies for AArch64 ABI. Clang, however, used the adjusted alignment. GCC already implements the ABI correctly. With this patch Clang becomes compatible with GCC and passes such arguments in accordance with AAPCS. Differential Revision: https://reviews.llvm.org/D46013 llvm-svn: 338279
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang/AST/ASTContext.h22
-rw-r--r--clang/include/clang/AST/RecordLayout.h10
2 files changed, 32 insertions, 0 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index c6f8e2973e8..7a50ce8d52d 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -226,6 +226,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
using TypeInfoMap = llvm::DenseMap<const Type *, struct TypeInfo>;
mutable TypeInfoMap MemoizedTypeInfo;
+ /// A cache from types to unadjusted alignment information. Only ARM and
+ /// AArch64 targets need this information, keeping it separate prevents
+ /// imposing overhead on TypeInfo size.
+ using UnadjustedAlignMap = llvm::DenseMap<const Type *, unsigned>;
+ mutable UnadjustedAlignMap MemoizedUnadjustedAlign;
+
/// A cache mapping from CXXRecordDecls to key functions.
llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions;
@@ -2067,6 +2073,16 @@ public:
unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }
unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).Align; }
+ /// Return the ABI-specified natural alignment of a (complete) type \p T,
+ /// before alignment adjustments, in bits.
+ ///
+ /// This alignment is curently used only by ARM and AArch64 when passing
+ /// arguments of a composite type.
+ unsigned getTypeUnadjustedAlign(QualType T) const {
+ return getTypeUnadjustedAlign(T.getTypePtr());
+ }
+ unsigned getTypeUnadjustedAlign(const Type *T) const;
+
/// Return the ABI-specified alignment of a type, in bits, or 0 if
/// the type is incomplete and we cannot determine the alignment (for
/// example, from alignment attributes).
@@ -2077,6 +2093,12 @@ public:
CharUnits getTypeAlignInChars(QualType T) const;
CharUnits getTypeAlignInChars(const Type *T) const;
+ /// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a type,
+ /// in characters, before alignment adjustments. This method does not work on
+ /// incomplete types.
+ CharUnits getTypeUnadjustedAlignInChars(QualType T) const;
+ CharUnits getTypeUnadjustedAlignInChars(const Type *T) const;
+
// getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
// type is a record, its data size is returned.
std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const;
diff --git a/clang/include/clang/AST/RecordLayout.h b/clang/include/clang/AST/RecordLayout.h
index dc60ef892b0..ba60008589a 100644
--- a/clang/include/clang/AST/RecordLayout.h
+++ b/clang/include/clang/AST/RecordLayout.h
@@ -71,6 +71,10 @@ private:
// Alignment - Alignment of record in characters.
CharUnits Alignment;
+ // UnadjustedAlignment - Maximum of the alignments of the record members in
+ // characters.
+ CharUnits UnadjustedAlignment;
+
/// RequiredAlignment - The required alignment of the object. In the MS-ABI
/// the __declspec(align()) trumps #pramga pack and must always be obeyed.
CharUnits RequiredAlignment;
@@ -136,6 +140,7 @@ private:
CXXRecordLayoutInfo *CXXInfo = nullptr;
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
+ CharUnits unadjustedAlignment,
CharUnits requiredAlignment, CharUnits datasize,
ArrayRef<uint64_t> fieldoffsets);
@@ -144,6 +149,7 @@ private:
// Constructor for C++ records.
ASTRecordLayout(const ASTContext &Ctx,
CharUnits size, CharUnits alignment,
+ CharUnits unadjustedAlignment,
CharUnits requiredAlignment,
bool hasOwnVFPtr, bool hasExtendableVFPtr,
CharUnits vbptroffset,
@@ -170,6 +176,10 @@ public:
/// getAlignment - Get the record alignment in characters.
CharUnits getAlignment() const { return Alignment; }
+ /// getUnadjustedAlignment - Get the record alignment in characters, before
+ /// alignment adjustement.
+ CharUnits getUnadjustedAlignment() const { return UnadjustedAlignment; }
+
/// getSize - Get the record size in characters.
CharUnits getSize() const { return Size; }
OpenPOWER on IntegriCloud