Skip to content
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

is-valid-utf8.c tweaks #449

Merged
merged 6 commits into from
Dec 7, 2021
Merged

Conversation

Bodigrim
Copy link
Contributor

@Bodigrim Bodigrim commented Dec 6, 2021

This branch was triggered into existence by GHC CI failures, but I used the opportunity to deduplicate some code as well.

The precise issue is that some GHC builds (https://gitlab.haskell.org/ghc/ghc/-/jobs/876320#L4200) are unhappy with our usage of __cpu_indicator_init. It's more likely GHC make who is at fault here, but fighting it is so difficult. We use __get_cpuid for CPU capabilities detection in SIMD code for count:

bytestring/cbits/fpstring.c

Lines 237 to 243 in 12303b8

uint32_t ecx1 = 0;
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
ecx1 = ecx;
}
const bool has_xsave = ecx1 & (1 << 26);
const bool has_popcnt = ecx1 & (1 << 23);

and I also have good experience with __get_cpuid in text (https://github.com/haskell/text/blob/master/cbits/measure_off.c).

This PR replaces __cpu_indicator_init with __get_cpuid. Then we make SSE2 detection a runtime dispatch as well, similar to existing SSSE3 and AVX2 checks. This allows us to use fallback function on any platform, not only x86. Finally, I deduplicated fallback functions - there seems to be no measurable impact except extremely short strings, and I think that code clarity is more important here.

@Bodigrim Bodigrim requested a review from sjakobi December 6, 2021 21:27
Copy link
Member

@sjakobi sjakobi left a comment

Choose a reason for hiding this comment

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

The direction seems reasonable, but the code goes way over my head. Maybe someone else can give you feedback on it.

@Bodigrim
Copy link
Contributor Author

Bodigrim commented Dec 6, 2021

@kozross could you possibly give this a quick look?

cbits/is-valid-utf8.c Outdated Show resolved Hide resolved
cbits/is-valid-utf8.c Show resolved Hide resolved
@Bodigrim Bodigrim merged commit 286aa59 into haskell:master Dec 7, 2021
@Bodigrim Bodigrim deleted the is-valid-utf8-tweaks branch December 7, 2021 23:06
@Bodigrim Bodigrim added this to the 0.11.2.0 milestone Dec 7, 2021
Bodigrim added a commit to Bodigrim/bytestring that referenced this pull request Dec 7, 2021
* Cabal check does not recognise arch(arm64)

* is-valid-utf8: use __get_cpuid_count instead of __builtin_cpu_supports because of GHC make build issues

* Check SSE2 support in runtime instead of compile time

* Avoid code duplication: use bytestring_is_valid_utf8 on any arch without vectorised instructions

* Further deduplication

* Mark has_foo as static inline
noughtmare pushed a commit to noughtmare/bytestring that referenced this pull request Dec 12, 2021
* Cabal check does not recognise arch(arm64)

* is-valid-utf8: use __get_cpuid_count instead of __builtin_cpu_supports because of GHC make build issues

* Check SSE2 support in runtime instead of compile time

* Avoid code duplication: use bytestring_is_valid_utf8 on any arch without vectorised instructions

* Further deduplication

* Mark has_foo as static inline
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants