Skip to content

Commit eb485fb

Browse files
committed
Add SVE opaque built-in types
This patch adds the SVE built-in types defined by the Procedure Call Standard for the Arm Architecture: https://developer.arm.com/docs/100986/0000 It handles the types in all relevant places that deal with built-in types. At the moment, some of these places bail out with an error, including: (1) trying to generate LLVM IR for the types (2) trying to generate debug info for the types (3) trying to mangle the types using the Microsoft C++ ABI (4) trying to @encode the types in Objective C (1) and (2) are fixed by follow-on patches but (unlike this patch) they deal mostly with target-specific LLVM details, so seemed like a logically separate change. There is currently no spec for (3) and (4), so reporting an error seems like the correct behaviour for now. The intention is that the types will become sizeless types: http://lists.llvm.org/pipermail/cfe-dev/2019-June/062523.html The main purpose of the sizeless type extension is to diagnose impossible or dangerous uses of the types, such as any that would require sizeof to have a meaningful defined value. Until then, the patch sets the alignments of the types to the values specified in the link above. It also sets the sizes of the types to zero, which is chosen to be consistently wrong and shouldn't affect correctly-written code (i.e. code that would compile even with the sizeless type extension). The patch adds the common subset of functionality needed to test the sizeless type extension on the one hand and to provide SVE intrinsic functions on the other. After this patch, the two pieces of work are essentially independent. The patch is based on one by Graham Hunter: https://reviews.llvm.org/D59245 Differential Revision: https://reviews.llvm.org/D62960 llvm-svn: 368413
1 parent 9693d28 commit eb485fb

35 files changed

+547
-6
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
10541054
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
10551055
CanQualType Id##Ty;
10561056
#include "clang/Basic/OpenCLExtensionTypes.def"
1057+
#define SVE_TYPE(Name, Id, SingletonId) \
1058+
CanQualType SingletonId;
1059+
#include "clang/Basic/AArch64SVEACLETypes.def"
10571060

10581061
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
10591062
mutable QualType AutoDeductTy; // Deduction against 'auto'.

clang/include/clang/AST/Type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,6 +2414,9 @@ class BuiltinType : public Type {
24142414
// OpenCL extension types
24152415
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id,
24162416
#include "clang/Basic/OpenCLExtensionTypes.def"
2417+
// SVE Types
2418+
#define SVE_TYPE(Name, Id, SingletonId) Id,
2419+
#include "clang/Basic/AArch64SVEACLETypes.def"
24172420
// All other builtin types
24182421
#define BUILTIN_TYPE(Id, SingletonId) Id,
24192422
#define LAST_BUILTIN_TYPE(Id) LastKind = Id
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===-- AArch64SVEACLETypes.def - Metadata about SVE types ------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines various SVE builtin types. The macros are:
10+
//
11+
// SVE_TYPE(Name, Id, SingletonId) - A builtin type that has not been
12+
// covered by any other #define. Defining this macro covers all
13+
// the builtins.
14+
//
15+
// SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP) -
16+
// An SVE scalable vector.
17+
//
18+
// SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind) - An SVE scalable
19+
// predicate.
20+
//
21+
// where:
22+
//
23+
// - Name is the name of the builtin type.
24+
//
25+
// - BuiltinType::Id is the enumerator defining the type.
26+
//
27+
// - Context.SingletonId is the global singleton of this type.
28+
//
29+
// - ElKind enumerates the type of the elements.
30+
//
31+
// - ElBits is the size of one element in bits.
32+
//
33+
// - IsSigned is true for vectors of signed integer elements and
34+
// for vectors of floating-point elements.
35+
//
36+
// - IsFP is true for vectors of floating-point elements.
37+
//
38+
//===----------------------------------------------------------------------===//
39+
40+
#ifndef SVE_VECTOR_TYPE
41+
#define SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP)\
42+
SVE_TYPE(Name, Id, SingletonId)
43+
#endif
44+
45+
#ifndef SVE_PREDICATE_TYPE
46+
#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind)\
47+
SVE_TYPE(Name, Id, SingletonId)
48+
#endif
49+
50+
//===- Vector point types -----------------------------------------------===//
51+
52+
SVE_VECTOR_TYPE("__SVInt8_t", SveInt8, SveInt8Ty, SveElSInt8, 8, true, false)
53+
SVE_VECTOR_TYPE("__SVInt16_t", SveInt16, SveInt16Ty, SveElSInt16, 16, true, false)
54+
SVE_VECTOR_TYPE("__SVInt32_t", SveInt32, SveInt32Ty, SveElSInt32, 32, true, false)
55+
SVE_VECTOR_TYPE("__SVInt64_t", SveInt64, SveInt64Ty, SveElSInt64, 64, true, false)
56+
57+
SVE_VECTOR_TYPE("__SVUint8_t", SveUint8, SveUint8Ty, SveElUInt8, 8, false, false)
58+
SVE_VECTOR_TYPE("__SVUint16_t", SveUint16, SveUint16Ty, SveElUInt16, 16, false, false)
59+
SVE_VECTOR_TYPE("__SVUint32_t", SveUint32, SveUint32Ty, SveElUInt32, 32, false, false)
60+
SVE_VECTOR_TYPE("__SVUint64_t", SveUint64, SveUint64Ty, SveElUInt64, 64, false, false)
61+
62+
SVE_VECTOR_TYPE("__SVFloat16_t", SveFloat16, SveFloat16Ty, SveElHalf, 16, true, true)
63+
SVE_VECTOR_TYPE("__SVFloat32_t", SveFloat32, SveFloat32Ty, SveElFloat, 32, true, true)
64+
SVE_VECTOR_TYPE("__SVFloat64_t", SveFloat64, SveFloat64Ty, SveElDouble, 64, true, true)
65+
66+
SVE_PREDICATE_TYPE("__SVBool_t", SveBool, SveBoolTy, SveElBool)
67+
68+
#undef SVE_VECTOR_TYPE
69+
#undef SVE_PREDICATE_TYPE
70+
#undef SVE_TYPE

clang/include/clang/Basic/TargetInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ class TargetInfo : public virtual TransferrableTargetInfo,
193193

194194
unsigned IsRenderScriptTarget : 1;
195195

196+
unsigned HasAArch64SVETypes : 1;
197+
196198
// TargetInfo Constructor. Default initializes all fields.
197199
TargetInfo(const llvm::Triple &T);
198200

@@ -789,6 +791,10 @@ class TargetInfo : public virtual TransferrableTargetInfo,
789791
/// Returns true for RenderScript.
790792
bool isRenderScriptTarget() const { return IsRenderScriptTarget; }
791793

794+
/// Returns whether or not the AArch64 SVE built-in types are
795+
/// available on this target.
796+
bool hasAArch64SVETypes() const { return HasAArch64SVETypes; }
797+
792798
/// Returns whether the passed in string is a valid clobber in an
793799
/// inline asm statement.
794800
///

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,9 @@ namespace serialization {
10181018
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
10191019
PREDEF_TYPE_##Id##_ID,
10201020
#include "clang/Basic/OpenCLExtensionTypes.def"
1021+
// \brief SVE types with auto numeration
1022+
#define SVE_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
1023+
#include "clang/Basic/AArch64SVEACLETypes.def"
10211024
};
10221025

10231026
/// The number of predefined type IDs that are reserved for

clang/lib/AST/ASTContext.cpp

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,12 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
12981298
#include "clang/Basic/OpenCLExtensionTypes.def"
12991299
}
13001300

1301+
if (Target.hasAArch64SVETypes()) {
1302+
#define SVE_TYPE(Name, Id, SingletonId) \
1303+
InitBuiltinType(SingletonId, BuiltinType::Id);
1304+
#include "clang/Basic/AArch64SVEACLETypes.def"
1305+
}
1306+
13011307
// Builtin type for __objc_yes and __objc_no
13021308
ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ?
13031309
SignedCharTy : BoolTy);
@@ -1968,6 +1974,25 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
19681974
Width = Target->getPointerWidth(AS);
19691975
Align = Target->getPointerAlign(AS);
19701976
break;
1977+
// The SVE types are effectively target-specific. The length of an
1978+
// SVE_VECTOR_TYPE is only known at runtime, but it is always a multiple
1979+
// of 128 bits. There is one predicate bit for each vector byte, so the
1980+
// length of an SVE_PREDICATE_TYPE is always a multiple of 16 bits.
1981+
//
1982+
// Because the length is only known at runtime, we use a dummy value
1983+
// of 0 for the static length. The alignment values are those defined
1984+
// by the Procedure Call Standard for the Arm Architecture.
1985+
#define SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP)\
1986+
case BuiltinType::Id: \
1987+
Width = 0; \
1988+
Align = 128; \
1989+
break;
1990+
#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind) \
1991+
case BuiltinType::Id: \
1992+
Width = 0; \
1993+
Align = 16; \
1994+
break;
1995+
#include "clang/Basic/AArch64SVEACLETypes.def"
19711996
}
19721997
break;
19731998
case Type::ObjCObjectPointer:
@@ -6556,8 +6581,9 @@ void ASTContext::getObjCEncodingForPropertyType(QualType T,
65566581
/*Field=*/nullptr);
65576582
}
65586583

6559-
static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
6560-
BuiltinType::Kind kind) {
6584+
static char getObjCEncodingForPrimitiveType(const ASTContext *C,
6585+
const BuiltinType *BT) {
6586+
BuiltinType::Kind kind = BT->getKind();
65616587
switch (kind) {
65626588
case BuiltinType::Void: return 'v';
65636589
case BuiltinType::Bool: return 'B';
@@ -6617,6 +6643,17 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
66176643
// FIXME: potentially need @encodes for these!
66186644
return ' ';
66196645

6646+
#define SVE_TYPE(Name, Id, SingletonId) \
6647+
case BuiltinType::Id:
6648+
#include "clang/Basic/AArch64SVEACLETypes.def"
6649+
{
6650+
DiagnosticsEngine &Diags = C->getDiagnostics();
6651+
unsigned DiagID = Diags.getCustomDiagID(
6652+
DiagnosticsEngine::Error, "cannot yet @encode type %0");
6653+
Diags.Report(DiagID) << BT->getName(C->getPrintingPolicy());
6654+
return ' ';
6655+
}
6656+
66206657
case BuiltinType::ObjCId:
66216658
case BuiltinType::ObjCClass:
66226659
case BuiltinType::ObjCSel:
@@ -6653,7 +6690,7 @@ static char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) {
66536690

66546691
// The encoding of a fixed enum type matches its fixed underlying type.
66556692
const auto *BT = Enum->getIntegerType()->castAs<BuiltinType>();
6656-
return getObjCEncodingForPrimitiveKind(C, BT->getKind());
6693+
return getObjCEncodingForPrimitiveType(C, BT);
66576694
}
66586695

66596696
static void EncodeBitField(const ASTContext *Ctx, std::string& S,
@@ -6693,7 +6730,7 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,
66936730
S += ObjCEncodingForEnumType(Ctx, ET);
66946731
else {
66956732
const auto *BT = T->castAs<BuiltinType>();
6696-
S += getObjCEncodingForPrimitiveKind(Ctx, BT->getKind());
6733+
S += getObjCEncodingForPrimitiveType(Ctx, BT);
66976734
}
66986735
}
66996736
S += llvm::utostr(FD->getBitWidthValue(*Ctx));
@@ -6711,7 +6748,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
67116748
if (FD && FD->isBitField())
67126749
return EncodeBitField(this, S, T, FD);
67136750
if (const auto *BT = dyn_cast<BuiltinType>(CT))
6714-
S += getObjCEncodingForPrimitiveKind(this, BT->getKind());
6751+
S += getObjCEncodingForPrimitiveType(this, BT);
67156752
else
67166753
S += ObjCEncodingForEnumType(this, cast<EnumType>(CT));
67176754
return;

clang/lib/AST/ASTImporter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,10 @@ ExpectedType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
959959
case BuiltinType::Id: \
960960
return Importer.getToContext().Id##Ty;
961961
#include "clang/Basic/OpenCLExtensionTypes.def"
962+
#define SVE_TYPE(Name, Id, SingletonId) \
963+
case BuiltinType::Id: \
964+
return Importer.getToContext().SingletonId;
965+
#include "clang/Basic/AArch64SVEACLETypes.def"
962966
#define SHARED_SINGLETON_TYPE(Expansion)
963967
#define BUILTIN_TYPE(Id, SingletonId) \
964968
case BuiltinType::Id: return Importer.getToContext().SingletonId;

clang/lib/AST/ExprConstant.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9008,6 +9008,9 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) {
90089008
case BuiltinType::OCLClkEvent:
90099009
case BuiltinType::OCLQueue:
90109010
case BuiltinType::OCLReserveID:
9011+
#define SVE_TYPE(Name, Id, SingletonId) \
9012+
case BuiltinType::Id:
9013+
#include "clang/Basic/AArch64SVEACLETypes.def"
90119014
return GCCTypeClass::None;
90129015

90139016
case BuiltinType::Dependent:

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,6 +2671,15 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
26712671
Out << type_name.size() << type_name; \
26722672
break;
26732673
#include "clang/Basic/OpenCLExtensionTypes.def"
2674+
// The SVE types are effectively target-specific. The mangling scheme
2675+
// is defined in the appendices to the Procedure Call Standard for the
2676+
// Arm Architecture.
2677+
#define SVE_TYPE(Name, Id, SingletonId) \
2678+
case BuiltinType::Id: \
2679+
type_name = Name; \
2680+
Out << 'u' << type_name.size() << type_name; \
2681+
break;
2682+
#include "clang/Basic/AArch64SVEACLETypes.def"
26742683
}
26752684
}
26762685

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,6 +2109,9 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
21092109
mangleArtificialTagType(TTK_Struct, "_Half", {"__clang"});
21102110
break;
21112111

2112+
#define SVE_TYPE(Name, Id, SingletonId) \
2113+
case BuiltinType::Id:
2114+
#include "clang/Basic/AArch64SVEACLETypes.def"
21122115
case BuiltinType::ShortAccum:
21132116
case BuiltinType::Accum:
21142117
case BuiltinType::LongAccum:

0 commit comments

Comments
 (0)