This is an archive of the discontinued LLVM Phabricator instance.

[clang] Adding Platform/Architecture Specific Resource Header Installation Targets
ClosedPublic

Authored by qiongsiwu1 on Apr 11 2022, 5:43 AM.

Details

Summary

The goal of this patch is to improve distribution build's flexibility to include only applicable header files.

Currently, the clang-resource-headers target contains nearly all the files in clang/lib/Headers. Most of these files are platform specific (e.g. immintrin.h is x86 specific). A distribution build will have to either include all the headers for all the platforms, or not include any headers. For example, if a distribution build for powerpc includes the clang-resource-headers target, it will include all the x86 specific headers, even-though the x86 specific headers cannot be used.

This patch breaks up the clang-resource-headers list to a core list and platform specific lists. With the patch, a distribution build can now include the ppc-resource-headers to include the headers applicable to the powerpc platform.

Specifically, one can now have

cmake ... LLVM_DISTRIBUTION_COMPONENTS="clang;ppc-resource-headers" ... ../llvm

ninja install-distribution then installs the powerpc headers.

Similarly, one can do

cmake ... LLVM_DISTRIBUTION_COMPONENTS="clang;x86-resource-headers" ... ../llvm

to include headers applicable to the x86 platform in a distribution installation.

To implement this behaviour, the patch does two things

  1. It breaks up the long files header file list to a core list and platform specific lists.
  2. It adds numerous platform specific installation targets.

This may or may not be a good way to break up the long header list to add new targets, so I am all ears for suggestions/feedback! Also, we may need to add other reviewers. May I get some suggestions on that as well?

Thanks so much!

Diff Detail

Event Timeline

qiongsiwu1 created this revision.Apr 11 2022, 5:43 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 11 2022, 5:43 AM
qiongsiwu1 requested review of this revision.Apr 11 2022, 5:43 AM
qiongsiwu1 edited the summary of this revision. (Show Details)Apr 11 2022, 5:48 AM
jsji added a comment.Apr 11 2022, 6:48 AM

@qiongsiwu1 Please also add reviewers from other targets. Thanks.

No concerns about the WebAssembly changes. Will the default installation for folks who don't touch LLVM_DISTRIBUTION_COMPONENTS change?

qiongsiwu1 added a comment.EditedApr 11 2022, 10:04 AM

No concerns about the WebAssembly changes. Will the default installation for folks who don't touch LLVM_DISTRIBUTION_COMPONENTS change?

Thanks Thomas! No, the default installations that use clang-resource-headers (e.g. here) do not change. This PR adds new targets without changing the contents of the existing clang-resource-headers target.

Edit: Sorry I misread the question. No, the default installations that do not use LLVM_DISTRIBUTION_COMPONENTS do not change either.

this LGTM from a systemz perspective! thanks for refactoring

clang/lib/Headers/CMakeLists.txt
173

nit: There are some x86 headers here that appear to be x86 only. Should these be moved to x86_files list?

This revision is now accepted and ready to land.Apr 11 2022, 10:31 AM

May I get some comments from the rest of the reviewers for the respective platforms?
@momchil.velikov @chill: arm
@pengfei : x86
@jdoerfert: cuda
@yaxunl : opencl
@kaz7 : ve
@bcain : hexagon
@sdardis : mips

Thanks so much!

clang/lib/Headers/CMakeLists.txt
173

Thanks for the comment! Yes indeed. I think currently the x86gprintrin.h header is in the x86_files list (list starts at line 88). Did I miss some other x86 files?

Pls add @Anastasia for OpenCL.

LGTM for HIP. HIP headers depend on some of CUDA headers, but LGTM.

chill added a comment.Apr 13 2022, 7:50 AM

Should these lists contain only source tree headers or also generated header files? I'm not seeing arm_mve.h, for example.

Is there any reason to have an AArch64 specific section? A lot of the files do apply to both Arm and AArch64 but for example the mve file Momchil mentioned does not.

Would make sense if you wanted AArch64 only there'd be an aarch64-resource-headers, even if it just makes the config command clearer. (I would expect some overlap in the file list though)

Then again a lot of Arm systems can run 32 bit code as well so there is a situation where you might include both.

pengfei accepted this revision.Apr 13 2022, 8:56 AM

LGTM for X86.

clang/lib/Headers/CMakeLists.txt
88

Verified the list is correct to X86. Nit: should make them in alphabetical order?

194

Is it only used by X86 for now?

clang/lib/Headers/CMakeLists.txt
173

Ah sorry, you're right, I think I read the list wrong. Thanks!

qiongsiwu1 added subscribers: abdulras, compnerd.

Addressing review comments:

  1. @chill pointed out that the generated headers are missing. The generated headers are added now.
  2. @pengfei pointed out that some x86 headers are listed out of order. The list is sorted now.
  3. @pengfei also commented on mm_malloc.h. I think it is needed for x86 and ppc. The header is added to these two targets.

@abdulras @compnerd May I get your comments on the riscv target?

Thank you all!

Is there any reason to have an AArch64 specific section? A lot of the files do apply to both Arm and AArch64 but for example the mve file Momchil mentioned does not.

Would make sense if you wanted AArch64 only there'd be an aarch64-resource-headers, even if it just makes the config command clearer. (I would expect some overlap in the file list though)

Sure, we can have an AArch64 specific section. I have no AArch64/arm background to comment on what the lists should look like. Could you provide a pointer on how to decide what should be AArch64 specific? Thank you!

Sure, we can have an AArch64 specific section. I have no AArch64/arm background to comment on what the lists should look like. Could you provide a pointer on how to decide what should be AArch64 specific? Thank you!

I looked through the list and here's what goes where:

arm_acle.h - both
arm_cmse.h - Arm only (CMSE is an M profile feature)
armintr.h - Arm only (Windows intrinsics)
arm64intr.h - AArch64 only (Windows intrinsics)

arm_neon.h - both
arm_fp16.h - both

Only includes AArch64 stuff at this time but according to the docs:

FEAT_FP16 supports:
• Half-precision data-processing instructions for Advanced SIMD and floating-point in both
AArch64 and AArch32 states.

arm_sve.h - AArch64 (SVE is AArch64 exclusive)
arm_bf16.h - AArch64 only

"FEAT_BF16 supports the BFloat16, or BF16, 16-bit floating-point storage format in AArch64 state."

arm_mve.h - Arm only (MVE is an M profile feature)
arm_cde.h - Arm only (CDE is an M profile feature)
arm_neon_sve_bridge.h - AArch64 only (SVE is AArch64 exclusive)

@momchil.velikov Please double check I got that right.

So you'd probably want to have an arm_common, like you have for the core. Arm installs arm_common and arm, AArch64 installs arm_common and aarch64.

Not sure if you'd expect the Windows intrisics files to show up in the windows headers. My guess is no because you'd configure with Windows and Arm, or Windows and AArch64 headers. windows would just be arch agnostic stuff.

This split reduces each install by 4 headers. So hardly amazing disk space wise but I think your goal is more to only have relevant files and this achieves that.

Then again a lot of Arm systems can run 32 bit code as well so there is a situation where you might include both.

I would guess that having two install targets makes it obvious that if you want 32 bit code you need to opt into both. (though I am biased since I'm already familiar with Arm)

Also, what's the feedback mechanism for issues with these listings? Say we add a new Arm header but forget to put it on these lists, who would be the first to notice? (I admit I'm not very familiar with the process of distributions)

Thanks @DavidSpickett !! The patch is updated. The arm headers are now split between arm and aarch64.

Also, what's the feedback mechanism for issues with these listings? Say we add a new Arm header but forget to put it on these lists, who would be the first to notice? (I admit I'm not very familiar with the process of distributions)

This is a good question. I don't think there are automatic tests against distribution installations. So in the worst case it could be the user of a distribution to first notice that a header is missing. Let me look into the possibilities to automatically check for the case if a header exists, but is not added to any of the target specific headers.

At the moment, adding new arm specific headers to arm_common_files, arm_only_files or aarch64_only_files lists will make sure they are included in the distribution targets. The generated ones are more problematic and may be missed.

Also, what's the feedback mechanism for issues with these listings? Say we add a new Arm header but forget to put it on these lists, who would be the first to notice? (I admit I'm not very familiar with the process of distributions)

Ok so I reworked the logic to add the generated headers and added a check. If there is a header generated, but not added to a target specific list, we have a cmake warning during configuration. The reason that I did not make it into a fatal error is that the omission does not affect building and testing clang/llvm, and it only affects a target specific distribution target. I can revise it to a fatal error if that is more desired.

Thanks again @DavidSpickett for the feedback! @chill may I get some comments from you as well? Thank you!

@DavidSpickett @chill @momchil.velikov May I get some comments on the arm/aarch64 related code changes? Thank you!

The Arm/AArch64 split and the generated files check looks good to me.

Unless I'm missing an existing check, is it possible to check for the existing files too? I guess not nicely because along with the resource headers there are lots of internal headers, so we'd have to maintain some list of "non resource" headers which means we've just created another thing to maintain.

Unless I'm missing an existing check, is it possible to check for the existing files too? I guess not nicely because along with the resource headers there are lots of internal headers, so we'd have to maintain some list of "non resource" headers which means we've just created another thing to maintain.

This is a good point. Having such checks will be beneficial, but I concur that it is not easy to check for all the existing files given what we have now (the current way headers are organized etc) and I agree that we may end up maintaining more lists. Therefore I am keeping this patch in its current shape at this stage. I can come back and revisit once I find a clean way to check for the necessity of the header file. Maybe I can ask cmake to check for architecture/targets during configuration and select the headers automatically, but that is beyond the scope of this patch.

Therefore I am keeping this patch in its current shape at this stage.

Sounds good to me.

This revision was landed with ongoing or failed builds.Apr 19 2022, 7:10 AM
This revision was automatically updated to reflect the committed changes.

Maybe I can ask cmake to check for architecture/targets during configuration and select the headers automatically, but that is beyond the scope of this patch.

I'm not familar with cmake, but I guess it might be doable. I once verified the X86 headers by command echo '#include <x86intrin.h>' | clang -x c -E - | grep '#.*clang.*h' | grep -o '[^\/]*\.h' |sort|uniq.
Notice, targets like X86 doesn't have a single entry. But it still available with a bit more work.

Maybe I can ask cmake to check for architecture/targets during configuration and select the headers automatically, but that is beyond the scope of this patch.

I'm not familar with cmake, but I guess it might be doable. I once verified the X86 headers by command echo '#include <x86intrin.h>' | clang -x c -E - | grep '#.*clang.*h' | grep -o '[^\/]*\.h' |sort|uniq.
Notice, targets like X86 doesn't have a single entry. But it still available with a bit more work.

Ah I see! Let me look into adopting something along this line. Maybe eventually we can remove all the lists (or reduce the lists to minimal) here.

Thanks for the input!

Hi, this patch causes an issue with the CMake Xcode build configuration, if I try to use xcode as the generator with CMake, using the build command:

xcrun cmake -G Xcode -DCMAKE_BUILD_TYPE:STRING=Debug -DLLVM_ENABLE_ASSERTIONS:BOOL=TRUE -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DLLVM_ENABLE_PROJECTS='clang;' -DCMAKE_IGNORE_PATH="/usr/lib;/usr/local/lib;/lib" -DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64" ../llvm

I get:

CMake Error in /Users/shubhamrastogi/Development/llvm-project-cas/llvm-project/clang/lib/Headers/CMakeLists.txt:

The custom command generating

  /Users/shubhamrastogi/Development/llvm-project-cas/llvm-project/build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/lib/clang/15.0.0/include/float.h

is attached to multiple targets:

  x86-resource-headers
  windows-resource-headers
  webassembly-resource-headers
  systemz-resource-headers
  mips-resource-headers
  arm-resource-headers
  cuda-resource-headers
  riscv-resource-headers
  ppc-resource-headers
  opencl-resource-headers
  aarch64-resource-headers
  hip-resource-headers
  ve-resource-headers
  hexagon-resource-headers
  clang-resource-headers

but none of these is a common dependency of the other(s).  This is not
allowed by the Xcode "new build system".

CMake Error in /Users/shubhamrastogi/Development/llvm-project-cas/llvm-project/third-party/benchmark/CMakeLists.txt:

The custom command generating

  /Users/shubhamrastogi/Development/llvm-project-cas/llvm-project/build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/lib/clang/15.0.0/include/float.h

is attached to multiple targets:

  x86-resource-headers
  windows-resource-headers
  webassembly-resource-headers
  systemz-resource-headers
  mips-resource-headers
  arm-resource-headers
  cuda-resource-headers
  riscv-resource-headers
  ppc-resource-headers
  opencl-resource-headers
  aarch64-resource-headers
  hip-resource-headers
  ve-resource-headers
  hexagon-resource-headers
  clang-resource-headers

but none of these is a common dependency of the other(s).  This is not
allowed by the Xcode "new build system".

I used git bisect to figure this out, is there some solution to this?

Hi, this patch causes an issue with the CMake Xcode build configuration, if I try to use xcode as the generator with CMake, using the build command:

I used git bisect to figure this out, is there some solution to this?

Hi Schubham!

I will go take a look to see how we can provide a long term solution. In the meantime, could you try the workaround here https://stackoverflow.com/questions/65473503/when-trying-to-generate-an-xcode-project-from-a-cmake-folder-i-get-an-error-rel?

Thanks!

Hi Qiongsi

Thanks for the response!

Anastasia added inline comments.Apr 26 2022, 2:08 AM
clang/lib/Headers/CMakeLists.txt
333

I feel that the above comment doesn't apply here:
# Architecture/platform specific targets

This header is not a target or platform specific so I don't imagine it can ever be optional unless we start modularization of the language support in clang parsing.

qiongsiwu1 updated this revision to Diff 425780.EditedApr 28 2022, 8:03 AM
qiongsiwu1 added reviewers: ye-luo, rastogishubham.

This patch is updated to address

@ye-luo @rastogishubham if you get a chance, could you try the patch and see if it works? Thanks!

Thanks for the comments and the issue reports!

@qiongsiwu1 Tested the updated patch. Works fine now.

Hi Qiongsi,

Thank you for your work on the patch, it seems to work now!

Shubham

craig.topper added inline comments.
clang/lib/Headers/CMakeLists.txt
336

There appear to be two installs of ppc_wrapper_files with different components. Is that intentional?

qiongsiwu1 added inline comments.May 12 2022, 5:48 AM
clang/lib/Headers/CMakeLists.txt
336

Ah yes this is indeed intentional. cuda_wrapper_files and openmp_wrapper_files have two install targets as well. The first target is part of the "catch-all" clang-resource-headers. The second targets are not installed by default (EXCLUDE_FROM_ALL). and a distribution build can opt-in the relevant set of headers.

That said, if there are better ways to implement the logic I am all ears.

craig.topper added inline comments.May 12 2022, 9:08 AM
clang/lib/Headers/CMakeLists.txt
336

As far as I know, the ppc_wrapper_files are only usable on the powerpc target so I don't think they should be treated any different than ppc_files. ppc_files only has one install target right?

qiongsiwu1 added inline comments.May 12 2022, 9:52 AM
clang/lib/Headers/CMakeLists.txt
336

As far as I know, the ppc_wrapper_files are only usable on the powerpc target

Yes that is my understanding as well.

ppc_files only has one install target right?

There is indeed one install target specifically setup to include only ppc files. Meanwhile, the ppc files are also included in the ${files} list (which is installed as as a component of the catch-all clang-resource-headers), so the ppc files are included in two different install targets.

craig.topper added inline comments.May 18 2022, 10:58 PM
clang/lib/Headers/CMakeLists.txt
336

Thanks. I was trying to resolve some merge issues in my downstream and I really should have read your changes more closely.

463

Should this be windows_only_files. I don't see a windows_files defined anywhere.

craig.topper added inline comments.May 18 2022, 11:13 PM
clang/lib/Headers/CMakeLists.txt
452

Should this be ${header_install_dir}/openmp_wrappers

qiongsiwu1 added inline comments.
clang/lib/Headers/CMakeLists.txt
336

No problem!

452

Oh good catch! Thanks! I am fixing this in https://reviews.llvm.org/D126002, together with the issue with windows only headers.