Skip to content

[builtins][arm64] Implement __init_cpu_features_resolver on Apple platforms #75636

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler-rt/lib/builtins/cpu_model/aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ struct {

// The formatter wants to re-order these includes, but doing so is incorrect:
// clang-format off
#if defined(__FreeBSD__)
#if defined(__APPLE__)
#include "aarch64/fmv/apple.inc"
#elif defined(__FreeBSD__)
#include "aarch64/fmv/mrs.inc"
#include "aarch64/fmv/freebsd.inc"
#elif defined(__Fuchsia__)
Expand Down
69 changes: 69 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/apple.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <TargetConditionals.h>
#if TARGET_OS_OSX || TARGET_OS_IPHONE
#include <dispatch/dispatch.h>
#include <sys/sysctl.h>

static bool isKnownAndSupported(const char *name) {
int32_t val = 0;
size_t size = sizeof(val);
if (sysctlbyname(name, &val, &size, NULL, 0))
return false;
return val;
}

void __init_cpu_features_resolver(void) {
// On Darwin platforms, this may be called concurrently by multiple threads
// because the resolvers that use it are called lazily at runtime (unlike on
// ELF platforms, where IFuncs are resolved serially at load time). This
// function's effect on __aarch64_cpu_features should be idempotent, but even
// so we need dispatch_once to resolve the race condition. Dispatch is
// available through libSystem, which we need anyway for the sysctl, so this
// does not add a new dependency.

static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
static struct {
const char *sysctl_name;
enum CPUFeatures feature;
} features[] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need support for AdvSIMD_HPFPCvt, FEAT_LSE2, FEAT_SHA512 or for other feature in Function Multi Versioning? Specification is not final yet and open to proposals.

Copy link
Contributor Author

@jroelofs jroelofs Dec 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I can add entries for those. Looks like I missed them in my manual intersection of the sysctl docs with the FEAT_* table.

edit: I see you're asking a different question than I thought. Yeah, those three would probably be useful.

Specification is not final yet and open to proposals.

Any word on when FMV might come out of beta?

Copy link
Contributor Author

@jroelofs jroelofs Dec 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we're just about out of bits in __aarch64_cpu_features.features.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing that came up when discussing the frontend attributes for these: we may want to have user-selectable overrides for the priorities for (hypothetical) cases where the prescribed numbers in the table don't match the selection behavior we need at runtime. I don't have a concrete example in mind yet.

Copy link
Contributor

@ilinpv ilinpv Dec 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we're just about out of bits in __aarch64_cpu_features.features.

Next field features2 can be added to __aarch64_cpu_features with setting FEAT_EXT bit to 1 and changing initialization condition to if (__aarch64_cpu_features.features & (1ULL << FEAT_INIT) )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any word on when FMV might come out of beta?

There's no specific deadline right now, possibly within a year or half - we want to collect and address all feedback on FMV from partners and compilers communities.

{"hw.optional.arm.FEAT_FlagM", FEAT_FLAGM},
{"hw.optional.arm.FEAT_FlagM2", FEAT_FLAGM2},
{"hw.optional.arm.FEAT_FHM", FEAT_FP16FML},
{"hw.optional.arm.FEAT_DotProd", FEAT_DOTPROD},
{"hw.optional.arm.FEAT_RDM", FEAT_RDM},
{"hw.optional.arm.FEAT_LSE", FEAT_LSE},
{"hw.optional.floatingpoint", FEAT_FP},
{"hw.optional.AdvSIMD", FEAT_SIMD},
{"hw.optional.armv8_crc32", FEAT_CRC},
{"hw.optional.arm.FEAT_SHA1", FEAT_SHA1},
{"hw.optional.arm.FEAT_SHA256", FEAT_SHA2},
{"hw.optional.arm.FEAT_SHA3", FEAT_SHA3},
{"hw.optional.arm.FEAT_AES", FEAT_AES},
{"hw.optional.arm.FEAT_PMULL", FEAT_PMULL},
{"hw.optional.arm.FEAT_FP16", FEAT_FP16},
{"hw.optional.arm.FEAT_DIT", FEAT_DIT},
{"hw.optional.arm.FEAT_DPB", FEAT_DPB},
{"hw.optional.arm.FEAT_DPB2", FEAT_DPB2},
{"hw.optional.arm.FEAT_JSCVT", FEAT_JSCVT},
{"hw.optional.arm.FEAT_FCMA", FEAT_FCMA},
{"hw.optional.arm.FEAT_LRCPC", FEAT_RCPC},
{"hw.optional.arm.FEAT_LRCPC2", FEAT_RCPC2},
{"hw.optional.arm.FEAT_FRINTTS", FEAT_FRINTTS},
{"hw.optional.arm.FEAT_I8MM", FEAT_I8MM},
{"hw.optional.arm.FEAT_BF16", FEAT_BF16},
{"hw.optional.arm.FEAT_SB", FEAT_SB},
{"hw.optional.arm.FEAT_SPECRES", FEAT_PREDRES},
{"hw.optional.arm.FEAT_SSBS", FEAT_SSBS2},
{"hw.optional.arm.FEAT_BTI", FEAT_BTI},
};

for (size_t I = 0, E = sizeof(features) / sizeof(features[0]); I != E; ++I)
if (isKnownAndSupported(features[I].sysctl_name))
__aarch64_cpu_features.features |= (1ULL << features[I].feature);

__aarch64_cpu_features.features |= (1ULL << FEAT_INIT);
});
}

#endif // TARGET_OS_OSX || TARGET_OS_IPHONE