Skip to content

Commit 93cbf2a

Browse files
sdesmalen-armwwwatermiao
authored andcommitted
[Clang][AArch64] Change SME attributes for shared/new/preserved state. (#76971)
This patch replaces the `__arm_new_za`, `__arm_shared_za` and `__arm_preserves_za` attributes in favour of: * `__arm_new("za")` * `__arm_in("za")` * `__arm_out("za")` * `__arm_inout("za")` * `__arm_preserves("za")` As described in ARM-software/acle#276. One change is that `__arm_in/out/inout/preserves(S)` are all mutually exclusive, whereas previously it was fine to write `__arm_shared_za __arm_preserves_za`. This case is now represented with `__arm_in("za")`. The current implementation uses the same LLVM attributes under the hood, since `__arm_in/out/inout` are all variations of "shared ZA", so can use the existing `aarch64_pstate_za_shared` attribute in LLVM. with SME2. Signed-off-by: chenmiao <[email protected]> Signed-off-by: chenmiao <[email protected]>
1 parent e011988 commit 93cbf2a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1203
-898
lines changed

clang/include/clang/AST/Type.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3973,12 +3973,27 @@ class FunctionType : public Type {
39733973
SME_NormalFunction = 0,
39743974
SME_PStateSMEnabledMask = 1 << 0,
39753975
SME_PStateSMCompatibleMask = 1 << 1,
3976-
SME_PStateZASharedMask = 1 << 2,
3977-
SME_PStateZAPreservedMask = 1 << 3,
3978-
SME_AttributeMask = 0b111'111 // We only support maximum 6 bits because of the
3979-
// bitmask in FunctionTypeExtraBitfields.
3976+
3977+
// Describes the value of the state using ArmStateValue.
3978+
SME_ZAShift = 2,
3979+
SME_ZAMask = 0b111 << SME_ZAShift,
3980+
3981+
SME_AttributeMask = 0b111'111 // We only support maximum 6 bits because of
3982+
// the bitmask in FunctionTypeExtraBitfields.
3983+
};
3984+
3985+
enum ArmStateValue : unsigned {
3986+
ARM_None = 0,
3987+
ARM_Preserves = 1,
3988+
ARM_In = 2,
3989+
ARM_Out = 3,
3990+
ARM_InOut = 4,
39803991
};
39813992

3993+
static ArmStateValue getArmZAState(unsigned AttrBits) {
3994+
return (ArmStateValue)((AttrBits & SME_ZAMask) >> SME_ZAShift);
3995+
}
3996+
39823997
/// A simple holder for various uncommon bits which do not fit in
39833998
/// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the
39843999
/// alignment of subsequent objects in TrailingObjects.

clang/include/clang/Basic/Attr.td

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2445,16 +2445,45 @@ def ArmStreamingCompatible : TypeAttr, TargetSpecificAttr<TargetAArch64> {
24452445
let Documentation = [ArmSmeStreamingCompatibleDocs];
24462446
}
24472447

2448-
def ArmSharedZA : TypeAttr, TargetSpecificAttr<TargetAArch64> {
2449-
let Spellings = [RegularKeyword<"__arm_shared_za">];
2448+
def ArmNew : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
2449+
let Spellings = [RegularKeyword<"__arm_new">];
2450+
let Args = [VariadicStringArgument<"NewArgs">];
2451+
let Subjects = SubjectList<[Function], ErrorDiag>;
2452+
let Documentation = [ArmNewDocs];
2453+
2454+
let AdditionalMembers = [{
2455+
bool isNewZA() const {
2456+
return llvm::is_contained(newArgs(), "za");
2457+
}
2458+
}];
2459+
}
2460+
2461+
def ArmIn : TypeAttr, TargetSpecificAttr<TargetAArch64> {
2462+
let Spellings = [RegularKeyword<"__arm_in">];
2463+
let Args = [VariadicStringArgument<"InArgs">];
2464+
let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
2465+
let Documentation = [ArmInDocs];
2466+
}
2467+
2468+
def ArmOut : TypeAttr, TargetSpecificAttr<TargetAArch64> {
2469+
let Spellings = [RegularKeyword<"__arm_out">];
2470+
let Args = [VariadicStringArgument<"OutArgs">];
2471+
let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
2472+
let Documentation = [ArmOutDocs];
2473+
}
2474+
2475+
def ArmInOut : TypeAttr, TargetSpecificAttr<TargetAArch64> {
2476+
let Spellings = [RegularKeyword<"__arm_inout">];
2477+
let Args = [VariadicStringArgument<"InOutArgs">];
24502478
let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
2451-
let Documentation = [ArmSmeSharedZADocs];
2479+
let Documentation = [ArmInOutDocs];
24522480
}
24532481

2454-
def ArmPreservesZA : TypeAttr, TargetSpecificAttr<TargetAArch64> {
2455-
let Spellings = [RegularKeyword<"__arm_preserves_za">];
2482+
def ArmPreserves : TypeAttr, TargetSpecificAttr<TargetAArch64> {
2483+
let Spellings = [RegularKeyword<"__arm_preserves">];
2484+
let Args = [VariadicStringArgument<"PreserveArgs">];
24562485
let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
2457-
let Documentation = [ArmSmePreservesZADocs];
2486+
let Documentation = [ArmPreservesDocs];
24582487
}
24592488

24602489
def ArmLocallyStreaming : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
@@ -2463,14 +2492,6 @@ def ArmLocallyStreaming : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
24632492
let Documentation = [ArmSmeLocallyStreamingDocs];
24642493
}
24652494

2466-
def ArmNewZA : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
2467-
let Spellings = [RegularKeyword<"__arm_new_za">];
2468-
let Subjects = SubjectList<[Function], ErrorDiag>;
2469-
let Documentation = [ArmSmeNewZADocs];
2470-
}
2471-
def : MutualExclusions<[ArmNewZA, ArmSharedZA]>;
2472-
def : MutualExclusions<[ArmNewZA, ArmPreservesZA]>;
2473-
24742495

24752496
def Pure : InheritableAttr {
24762497
let Spellings = [GCC<"pure">];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6652,30 +6652,73 @@ without changing modes.
66526652
}];
66536653
}
66546654

6655-
def ArmSmeSharedZADocs : Documentation {
6655+
def ArmInDocs : Documentation {
66566656
let Category = DocCatArmSmeAttributes;
66576657
let Content = [{
6658-
The ``__arm_shared_za`` keyword applies to prototyped function types and specifies
6659-
that the function shares SME's matrix storage (ZA) with its caller. This
6660-
means that:
6658+
The ``__arm_in`` keyword applies to prototyped function types and specifies
6659+
that the function shares a given state S with its caller. For ``__arm_in``, the
6660+
function takes the state S as input and returns with the state S unchanged.
66616661

6662-
* the function requires that the processor implements the Scalable Matrix
6663-
Extension (SME).
6662+
The attribute takes string arguments to instruct the compiler which state
6663+
is shared. The supported states for S are:
66646664

6665-
* the function enters with ZA in an active state.
6665+
* ``"za"`` for Matrix Storage (requires SME)
66666666

6667-
* the function returns with ZA in an active state.
6667+
The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
6668+
``__arm_preserves(S)`` are all mutually exclusive for the same state S.
66686669
}];
66696670
}
66706671

6671-
def ArmSmePreservesZADocs : Documentation {
6672+
def ArmOutDocs : Documentation {
66726673
let Category = DocCatArmSmeAttributes;
66736674
let Content = [{
6674-
The ``__arm_preserves_za`` keyword applies to prototyped function types and
6675-
specifies that the function does not modify ZA state.
6675+
The ``__arm_out`` keyword applies to prototyped function types and specifies
6676+
that the function shares a given state S with its caller. For ``__arm_out``,
6677+
the function ignores the incoming state for S and returns new state for S.
6678+
6679+
The attribute takes string arguments to instruct the compiler which state
6680+
is shared. The supported states for S are:
6681+
6682+
* ``"za"`` for Matrix Storage (requires SME)
6683+
6684+
The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
6685+
``__arm_preserves(S)`` are all mutually exclusive for the same state S.
66766686
}];
66776687
}
66786688

6689+
def ArmInOutDocs : Documentation {
6690+
let Category = DocCatArmSmeAttributes;
6691+
let Content = [{
6692+
The ``__arm_inout`` keyword applies to prototyped function types and specifies
6693+
that the function shares a given state S with its caller. For ``__arm_inout``,
6694+
the function takes the state S as input and returns new state for S.
6695+
6696+
The attribute takes string arguments to instruct the compiler which state
6697+
is shared. The supported states for S are:
6698+
6699+
* ``"za"`` for Matrix Storage (requires SME)
6700+
6701+
The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
6702+
``__arm_preserves(S)`` are all mutually exclusive for the same state S.
6703+
}];
6704+
}
6705+
6706+
def ArmPreservesDocs : Documentation {
6707+
let Category = DocCatArmSmeAttributes;
6708+
let Content = [{
6709+
The ``__arm_preserves`` keyword applies to prototyped function types and
6710+
specifies that the function does not read a given state S and returns
6711+
with state S unchanged.
6712+
6713+
The attribute takes string arguments to instruct the compiler which state
6714+
is shared. The supported states for S are:
6715+
6716+
* ``"za"`` for Matrix Storage (requires SME)
6717+
6718+
The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
6719+
``__arm_preserves(S)`` are all mutually exclusive for the same state S.
6720+
}];
6721+
}
66796722

66806723
def ArmSmeLocallyStreamingDocs : Documentation {
66816724
let Category = DocCatArmSmeAttributes;
@@ -6698,13 +6741,18 @@ at the end of the function.
66986741
}];
66996742
}
67006743

6701-
def ArmSmeNewZADocs : Documentation {
6744+
def ArmNewDocs : Documentation {
67026745
let Category = DocCatArmSmeAttributes;
67036746
let Content = [{
6704-
The ``__arm_new_za`` keyword applies to function declarations and specifies
6705-
that the function will be set up with a fresh ZA context.
6747+
The ``__arm_new`` keyword applies to function declarations and specifies
6748+
that the function will create a new scope for state S.
6749+
6750+
The attribute takes string arguments to instruct the compiler for which state
6751+
to create new scope. The supported states for S are:
6752+
6753+
* ``"za"`` for Matrix Storage (requires SME)
67066754

6707-
This means that:
6755+
For state ``"za"``, this means that:
67086756

67096757
* the function requires that the target processor implements the Scalable Matrix
67106758
Extension (SME).
@@ -6715,8 +6763,8 @@ This means that:
67156763

67166764
* the function will disable PSTATE.ZA (by setting it to 0) before returning.
67176765

6718-
For ``__arm_new_za`` functions Clang will set up the ZA context automatically
6719-
on entry to the function, and disable it before returning. For example, if ZA is
6766+
For ``__arm_new("za")`` functions Clang will set up the ZA context automatically
6767+
on entry to the function and disable it before returning. For example, if ZA is
67206768
in a dormant state Clang will generate the code to commit a lazy-save and set up
67216769
a new ZA state before executing user code.
67226770
}];

clang/include/clang/Basic/AttributeCommonInfo.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,19 @@ class AttributeCommonInfo {
235235
return SpellingIndex != SpellingNotCalculated;
236236
}
237237
};
238+
239+
inline bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind) {
240+
switch (Kind) {
241+
default:
242+
return false;
243+
#define KEYWORD_ATTRIBUTE(NAME, HASARG, ...) \
244+
case tok::kw_##NAME: \
245+
return HASARG;
246+
#include "clang/Basic/RegularKeywordAttrInfo.inc"
247+
#undef KEYWORD_ATTRIBUTE
248+
}
249+
}
250+
238251
} // namespace clang
239252

240253
#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H

clang/include/clang/Basic/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ clang_tablegen(AttrSubMatchRulesList.inc -gen-clang-attr-subject-match-rule-list
4848
SOURCE Attr.td
4949
TARGET ClangAttrSubjectMatchRuleList)
5050

51-
clang_tablegen(AttrTokenKinds.inc -gen-clang-attr-token-kinds
51+
clang_tablegen(RegularKeywordAttrInfo.inc -gen-clang-regular-keyword-attr-info
5252
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
5353
SOURCE Attr.td
54-
TARGET ClangAttrTokenKinds
54+
TARGET ClangRegularKeywordAttrInfo
5555
)
5656

5757
clang_tablegen(AttrHasAttributeImpl.inc -gen-clang-attr-has-attribute-impl

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3641,6 +3641,12 @@ def err_sme_definition_using_sm_in_non_sme_target : Error<
36413641
"function executed in streaming-SVE mode requires 'sme'">;
36423642
def err_sme_definition_using_za_in_non_sme_target : Error<
36433643
"function using ZA state requires 'sme'">;
3644+
def err_conflicting_attributes_arm_state : Error<
3645+
"conflicting attributes for state '%0'">;
3646+
def err_unknown_arm_state : Error<
3647+
"unknown state '%0'">;
3648+
def err_missing_arm_state : Error<
3649+
"missing state for %0">;
36443650
def err_cconv_change : Error<
36453651
"function declared '%0' here was previously declared "
36463652
"%select{'%2'|without calling convention}1">;

clang/include/clang/Basic/TokenKinds.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -753,9 +753,9 @@ KEYWORD(__builtin_sycl_unique_stable_name, KEYSYCL)
753753

754754
// Keywords defined by Attr.td.
755755
#ifndef KEYWORD_ATTRIBUTE
756-
#define KEYWORD_ATTRIBUTE(X, EMPTY) KEYWORD(EMPTY ## X, KEYALL)
756+
#define KEYWORD_ATTRIBUTE(X, HASARG, EMPTY) KEYWORD(EMPTY ## X, KEYALL)
757757
#endif
758-
#include "clang/Basic/AttrTokenKinds.inc"
758+
#include "clang/Basic/RegularKeywordAttrInfo.inc"
759759

760760
// Clang-specific keywords enabled only in testing.
761761
TESTING_KEYWORD(__unknown_anytype , KEYALL)

clang/include/clang/Basic/TokenKinds.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ bool isPragmaAnnotation(TokenKind K);
110110
inline constexpr bool isRegularKeywordAttribute(TokenKind K) {
111111
return (false
112112
#define KEYWORD_ATTRIBUTE(X, ...) || (K == tok::kw_##X)
113-
#include "clang/Basic/AttrTokenKinds.inc"
113+
#include "clang/Basic/RegularKeywordAttrInfo.inc"
114114
);
115115
}
116116

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7076,15 +7076,7 @@ class Sema final {
70767076
NestedNameSpecInfo &IdInfo,
70777077
bool EnteringContext);
70787078

7079-
/// The kind of conversion to check for. Either all attributes must match exactly,
7080-
/// or the converted type may add/drop '__arm_preserves_za'.
7081-
enum class AArch64SMECallConversionKind {
7082-
MatchExactly,
7083-
MayAddPreservesZA,
7084-
MayDropPreservesZA,
7085-
};
7086-
bool IsInvalidSMECallConversion(QualType FromType, QualType ToType,
7087-
AArch64SMECallConversionKind C);
7079+
bool IsInvalidSMECallConversion(QualType FromType, QualType ToType);
70887080

70897081
/// The parser has parsed a nested-name-specifier
70907082
/// 'template[opt] template-name < template-args >::'.

clang/lib/AST/TypePrinter.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -937,15 +937,20 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
937937
OS << ')';
938938

939939
FunctionType::ExtInfo Info = T->getExtInfo();
940+
unsigned SMEBits = T->getAArch64SMEAttributes();
940941

941-
if ((T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMCompatibleMask))
942+
if (SMEBits & FunctionType::SME_PStateSMCompatibleMask)
942943
OS << " __arm_streaming_compatible";
943-
if ((T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask))
944+
if (SMEBits & FunctionType::SME_PStateSMEnabledMask)
944945
OS << " __arm_streaming";
945-
if ((T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask))
946-
OS << " __arm_shared_za";
947-
if ((T->getAArch64SMEAttributes() & FunctionType::SME_PStateZAPreservedMask))
948-
OS << " __arm_preserves_za";
946+
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Preserves)
947+
OS << " __arm_preserves(\"za\")";
948+
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_In)
949+
OS << " __arm_in(\"za\")";
950+
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Out)
951+
OS << " __arm_out(\"za\")";
952+
if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_InOut)
953+
OS << " __arm_inout(\"za\")";
949954

950955
printFunctionAfter(Info, OS);
951956

@@ -1785,14 +1790,6 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
17851790
OS << "__arm_streaming_compatible";
17861791
return;
17871792
}
1788-
if (T->getAttrKind() == attr::ArmSharedZA) {
1789-
OS << "__arm_shared_za";
1790-
return;
1791-
}
1792-
if (T->getAttrKind() == attr::ArmPreservesZA) {
1793-
OS << "__arm_preserves_za";
1794-
return;
1795-
}
17961793

17971794
OS << " __attribute__((";
17981795
switch (T->getAttrKind()) {
@@ -1836,8 +1833,10 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
18361833
case attr::WebAssemblyFuncref:
18371834
case attr::ArmStreaming:
18381835
case attr::ArmStreamingCompatible:
1839-
case attr::ArmSharedZA:
1840-
case attr::ArmPreservesZA:
1836+
case attr::ArmIn:
1837+
case attr::ArmOut:
1838+
case attr::ArmInOut:
1839+
case attr::ArmPreserves:
18411840
llvm_unreachable("This attribute should have been handled already");
18421841

18431842
case attr::NSReturnsRetained:

0 commit comments

Comments
 (0)