Skip to content

[libc++][RFC] Only include what is required by-version in the umbrella headers #83740

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
merged 1 commit into from
Apr 14, 2024

Conversation

philnik777
Copy link
Contributor

@philnik777 philnik777 commented Mar 3, 2024

This is a relatively low cost way of reducing the include sizes in older language modes compared to the effect. For example, in C++14 mode the include time of <algorithm> is reduced from 198ms to 127ms.

@philnik777 philnik777 marked this pull request as ready for review March 3, 2024 19:43
@philnik777 philnik777 requested a review from a team as a code owner March 3, 2024 19:43
@philnik777
Copy link
Contributor Author

@mordante @ldionne What are your thoughts on this?

@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Mar 3, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 3, 2024

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

This is a relatively low cost way of reducing the include sizes in older language modes compared to the effect. For example, in C++14 mode the include time of &lt;algorithm&gt; is reduced from 198ms to 127ms.


Patch is 28.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/83740.diff

14 Files Affected:

  • (modified) libcxx/include/algorithm (+213-207)
  • (modified) libcxx/include/bit (+18-13)
  • (modified) libcxx/include/charconv (+13-11)
  • (modified) libcxx/include/chrono (+24-20)
  • (modified) libcxx/include/compare (+16-13)
  • (modified) libcxx/include/concepts (+25-22)
  • (modified) libcxx/include/coroutine (+4)
  • (modified) libcxx/include/module.modulemap.in (+4-1)
  • (modified) libcxx/include/streambuf (+1)
  • (modified) libcxx/test/libcxx/algorithms/half_positive.pass.cpp (+2-2)
  • (modified) libcxx/test/libcxx/time/convert_to_tm.pass.cpp (+1)
  • (modified) libcxx/test/libcxx/transitive_includes/cxx03.csv (-1)
  • (modified) libcxx/test/libcxx/transitive_includes/cxx11.csv (-1)
  • (modified) libcxx/test/tools/clang_tidy_checks/CMakeLists.txt (+1-1)
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 0f62de7fa83f98..39f24efafe0755 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -1796,213 +1796,219 @@ template <class BidirectionalIterator, class Compare>
 #include <__config>
 #include <version>
 
-#include <__algorithm/adjacent_find.h>
-#include <__algorithm/all_of.h>
-#include <__algorithm/any_of.h>
-#include <__algorithm/binary_search.h>
-#include <__algorithm/clamp.h>
-#include <__algorithm/comp.h>
-#include <__algorithm/comp_ref_type.h>
-#include <__algorithm/copy.h>
-#include <__algorithm/copy_backward.h>
-#include <__algorithm/copy_if.h>
-#include <__algorithm/copy_n.h>
-#include <__algorithm/count.h>
-#include <__algorithm/count_if.h>
-#include <__algorithm/equal.h>
-#include <__algorithm/equal_range.h>
-#include <__algorithm/fill.h>
-#include <__algorithm/fill_n.h>
-#include <__algorithm/find.h>
-#include <__algorithm/find_end.h>
-#include <__algorithm/find_first_of.h>
-#include <__algorithm/find_if.h>
-#include <__algorithm/find_if_not.h>
-#include <__algorithm/fold.h>
-#include <__algorithm/for_each.h>
-#include <__algorithm/for_each_n.h>
-#include <__algorithm/generate.h>
-#include <__algorithm/generate_n.h>
-#include <__algorithm/half_positive.h>
-#include <__algorithm/in_found_result.h>
-#include <__algorithm/in_fun_result.h>
-#include <__algorithm/in_in_out_result.h>
-#include <__algorithm/in_in_result.h>
-#include <__algorithm/in_out_out_result.h>
-#include <__algorithm/in_out_result.h>
-#include <__algorithm/includes.h>
-#include <__algorithm/inplace_merge.h>
-#include <__algorithm/is_heap.h>
-#include <__algorithm/is_heap_until.h>
-#include <__algorithm/is_partitioned.h>
-#include <__algorithm/is_permutation.h>
-#include <__algorithm/is_sorted.h>
-#include <__algorithm/is_sorted_until.h>
-#include <__algorithm/iter_swap.h>
-#include <__algorithm/lexicographical_compare.h>
-#include <__algorithm/lexicographical_compare_three_way.h>
-#include <__algorithm/lower_bound.h>
-#include <__algorithm/make_heap.h>
-#include <__algorithm/max.h>
-#include <__algorithm/max_element.h>
-#include <__algorithm/merge.h>
-#include <__algorithm/min.h>
-#include <__algorithm/min_element.h>
-#include <__algorithm/min_max_result.h>
-#include <__algorithm/minmax.h>
-#include <__algorithm/minmax_element.h>
-#include <__algorithm/mismatch.h>
-#include <__algorithm/move.h>
-#include <__algorithm/move_backward.h>
-#include <__algorithm/next_permutation.h>
-#include <__algorithm/none_of.h>
-#include <__algorithm/nth_element.h>
-#include <__algorithm/partial_sort.h>
-#include <__algorithm/partial_sort_copy.h>
-#include <__algorithm/partition.h>
-#include <__algorithm/partition_copy.h>
-#include <__algorithm/partition_point.h>
-#include <__algorithm/pop_heap.h>
-#include <__algorithm/prev_permutation.h>
-#include <__algorithm/pstl_any_all_none_of.h>
-#include <__algorithm/pstl_copy.h>
-#include <__algorithm/pstl_count.h>
-#include <__algorithm/pstl_equal.h>
-#include <__algorithm/pstl_fill.h>
-#include <__algorithm/pstl_find.h>
-#include <__algorithm/pstl_for_each.h>
-#include <__algorithm/pstl_generate.h>
-#include <__algorithm/pstl_is_partitioned.h>
-#include <__algorithm/pstl_merge.h>
-#include <__algorithm/pstl_move.h>
-#include <__algorithm/pstl_replace.h>
-#include <__algorithm/pstl_rotate_copy.h>
-#include <__algorithm/pstl_sort.h>
-#include <__algorithm/pstl_stable_sort.h>
-#include <__algorithm/pstl_transform.h>
-#include <__algorithm/push_heap.h>
-#include <__algorithm/ranges_adjacent_find.h>
-#include <__algorithm/ranges_all_of.h>
-#include <__algorithm/ranges_any_of.h>
-#include <__algorithm/ranges_binary_search.h>
-#include <__algorithm/ranges_clamp.h>
-#include <__algorithm/ranges_contains.h>
-#include <__algorithm/ranges_contains_subrange.h>
-#include <__algorithm/ranges_copy.h>
-#include <__algorithm/ranges_copy_backward.h>
-#include <__algorithm/ranges_copy_if.h>
-#include <__algorithm/ranges_copy_n.h>
-#include <__algorithm/ranges_count.h>
-#include <__algorithm/ranges_count_if.h>
-#include <__algorithm/ranges_ends_with.h>
-#include <__algorithm/ranges_equal.h>
-#include <__algorithm/ranges_equal_range.h>
-#include <__algorithm/ranges_fill.h>
-#include <__algorithm/ranges_fill_n.h>
-#include <__algorithm/ranges_find.h>
-#include <__algorithm/ranges_find_end.h>
-#include <__algorithm/ranges_find_first_of.h>
-#include <__algorithm/ranges_find_if.h>
-#include <__algorithm/ranges_find_if_not.h>
-#include <__algorithm/ranges_for_each.h>
-#include <__algorithm/ranges_for_each_n.h>
-#include <__algorithm/ranges_generate.h>
-#include <__algorithm/ranges_generate_n.h>
-#include <__algorithm/ranges_includes.h>
-#include <__algorithm/ranges_inplace_merge.h>
-#include <__algorithm/ranges_is_heap.h>
-#include <__algorithm/ranges_is_heap_until.h>
-#include <__algorithm/ranges_is_partitioned.h>
-#include <__algorithm/ranges_is_permutation.h>
-#include <__algorithm/ranges_is_sorted.h>
-#include <__algorithm/ranges_is_sorted_until.h>
-#include <__algorithm/ranges_lexicographical_compare.h>
-#include <__algorithm/ranges_lower_bound.h>
-#include <__algorithm/ranges_make_heap.h>
-#include <__algorithm/ranges_max.h>
-#include <__algorithm/ranges_max_element.h>
-#include <__algorithm/ranges_merge.h>
-#include <__algorithm/ranges_min.h>
-#include <__algorithm/ranges_min_element.h>
-#include <__algorithm/ranges_minmax.h>
-#include <__algorithm/ranges_minmax_element.h>
-#include <__algorithm/ranges_mismatch.h>
-#include <__algorithm/ranges_move.h>
-#include <__algorithm/ranges_move_backward.h>
-#include <__algorithm/ranges_next_permutation.h>
-#include <__algorithm/ranges_none_of.h>
-#include <__algorithm/ranges_nth_element.h>
-#include <__algorithm/ranges_partial_sort.h>
-#include <__algorithm/ranges_partial_sort_copy.h>
-#include <__algorithm/ranges_partition.h>
-#include <__algorithm/ranges_partition_copy.h>
-#include <__algorithm/ranges_partition_point.h>
-#include <__algorithm/ranges_pop_heap.h>
-#include <__algorithm/ranges_prev_permutation.h>
-#include <__algorithm/ranges_push_heap.h>
-#include <__algorithm/ranges_remove.h>
-#include <__algorithm/ranges_remove_copy.h>
-#include <__algorithm/ranges_remove_copy_if.h>
-#include <__algorithm/ranges_remove_if.h>
-#include <__algorithm/ranges_replace.h>
-#include <__algorithm/ranges_replace_copy.h>
-#include <__algorithm/ranges_replace_copy_if.h>
-#include <__algorithm/ranges_replace_if.h>
-#include <__algorithm/ranges_reverse.h>
-#include <__algorithm/ranges_reverse_copy.h>
-#include <__algorithm/ranges_rotate.h>
-#include <__algorithm/ranges_rotate_copy.h>
-#include <__algorithm/ranges_sample.h>
-#include <__algorithm/ranges_search.h>
-#include <__algorithm/ranges_search_n.h>
-#include <__algorithm/ranges_set_difference.h>
-#include <__algorithm/ranges_set_intersection.h>
-#include <__algorithm/ranges_set_symmetric_difference.h>
-#include <__algorithm/ranges_set_union.h>
-#include <__algorithm/ranges_shuffle.h>
-#include <__algorithm/ranges_sort.h>
-#include <__algorithm/ranges_sort_heap.h>
-#include <__algorithm/ranges_stable_partition.h>
-#include <__algorithm/ranges_stable_sort.h>
-#include <__algorithm/ranges_starts_with.h>
-#include <__algorithm/ranges_swap_ranges.h>
-#include <__algorithm/ranges_transform.h>
-#include <__algorithm/ranges_unique.h>
-#include <__algorithm/ranges_unique_copy.h>
-#include <__algorithm/ranges_upper_bound.h>
-#include <__algorithm/remove.h>
-#include <__algorithm/remove_copy.h>
-#include <__algorithm/remove_copy_if.h>
-#include <__algorithm/remove_if.h>
-#include <__algorithm/replace.h>
-#include <__algorithm/replace_copy.h>
-#include <__algorithm/replace_copy_if.h>
-#include <__algorithm/replace_if.h>
-#include <__algorithm/reverse.h>
-#include <__algorithm/reverse_copy.h>
-#include <__algorithm/rotate.h>
-#include <__algorithm/rotate_copy.h>
-#include <__algorithm/sample.h>
-#include <__algorithm/search.h>
-#include <__algorithm/search_n.h>
-#include <__algorithm/set_difference.h>
-#include <__algorithm/set_intersection.h>
-#include <__algorithm/set_symmetric_difference.h>
-#include <__algorithm/set_union.h>
-#include <__algorithm/shift_left.h>
-#include <__algorithm/shift_right.h>
-#include <__algorithm/shuffle.h>
-#include <__algorithm/sift_down.h>
-#include <__algorithm/sort.h>
-#include <__algorithm/sort_heap.h>
-#include <__algorithm/stable_partition.h>
-#include <__algorithm/stable_sort.h>
-#include <__algorithm/swap_ranges.h>
-#include <__algorithm/transform.h>
-#include <__algorithm/unique.h>
-#include <__algorithm/unique_copy.h>
-#include <__algorithm/unwrap_iter.h>
-#include <__algorithm/upper_bound.h>
+#if 1 // C++03/11
+#  include <__algorithm/adjacent_find.h>
+#  include <__algorithm/all_of.h>
+#  include <__algorithm/any_of.h>
+#  include <__algorithm/binary_search.h>
+#  include <__algorithm/copy.h>
+#  include <__algorithm/copy_backward.h>
+#  include <__algorithm/copy_if.h>
+#  include <__algorithm/copy_n.h>
+#  include <__algorithm/count.h>
+#  include <__algorithm/count_if.h>
+#  include <__algorithm/equal.h>
+#  include <__algorithm/equal_range.h>
+#  include <__algorithm/fill.h>
+#  include <__algorithm/fill_n.h>
+#  include <__algorithm/find.h>
+#  include <__algorithm/find_end.h>
+#  include <__algorithm/find_first_of.h>
+#  include <__algorithm/find_if.h>
+#  include <__algorithm/find_if_not.h>
+#  include <__algorithm/for_each.h>
+#  include <__algorithm/generate.h>
+#  include <__algorithm/generate_n.h>
+#  include <__algorithm/includes.h>
+#  include <__algorithm/inplace_merge.h>
+#  include <__algorithm/is_heap.h>
+#  include <__algorithm/is_heap_until.h>
+#  include <__algorithm/is_partitioned.h>
+#  include <__algorithm/is_permutation.h>
+#  include <__algorithm/is_sorted.h>
+#  include <__algorithm/is_sorted_until.h>
+#  include <__algorithm/iter_swap.h>
+#  include <__algorithm/lexicographical_compare.h>
+#  include <__algorithm/lower_bound.h>
+#  include <__algorithm/make_heap.h>
+#  include <__algorithm/max.h>
+#  include <__algorithm/max_element.h>
+#  include <__algorithm/merge.h>
+#  include <__algorithm/min.h>
+#  include <__algorithm/min_element.h>
+#  include <__algorithm/minmax.h>
+#  include <__algorithm/minmax_element.h>
+#  include <__algorithm/mismatch.h>
+#  include <__algorithm/move.h>
+#  include <__algorithm/move_backward.h>
+#  include <__algorithm/next_permutation.h>
+#  include <__algorithm/none_of.h>
+#  include <__algorithm/nth_element.h>
+#  include <__algorithm/partial_sort.h>
+#  include <__algorithm/partial_sort_copy.h>
+#  include <__algorithm/partition.h>
+#  include <__algorithm/partition_copy.h>
+#  include <__algorithm/partition_point.h>
+#  include <__algorithm/pop_heap.h>
+#  include <__algorithm/prev_permutation.h>
+#  include <__algorithm/push_heap.h>
+#  include <__algorithm/remove.h>
+#  include <__algorithm/remove_copy.h>
+#  include <__algorithm/remove_copy_if.h>
+#  include <__algorithm/remove_if.h>
+#  include <__algorithm/replace.h>
+#  include <__algorithm/replace_copy.h>
+#  include <__algorithm/replace_copy_if.h>
+#  include <__algorithm/replace_if.h>
+#  include <__algorithm/reverse.h>
+#  include <__algorithm/reverse_copy.h>
+#  include <__algorithm/rotate.h>
+#  include <__algorithm/rotate_copy.h>
+#  include <__algorithm/search.h>
+#  include <__algorithm/search_n.h>
+#  include <__algorithm/set_difference.h>
+#  include <__algorithm/set_intersection.h>
+#  include <__algorithm/set_symmetric_difference.h>
+#  include <__algorithm/set_union.h>
+#  include <__algorithm/shuffle.h>
+#  include <__algorithm/sort.h>
+#  include <__algorithm/sort_heap.h>
+#  include <__algorithm/stable_partition.h>
+#  include <__algorithm/stable_sort.h>
+#  include <__algorithm/swap_ranges.h>
+#  include <__algorithm/transform.h>
+#  include <__algorithm/unique.h>
+#  include <__algorithm/unique_copy.h>
+#  include <__algorithm/upper_bound.h>
+#endif // 1 // C++03/11
+
+#if _LIBCPP_STD_VER >= 17
+#  include <__algorithm/clamp.h>
+#  include <__algorithm/for_each_n.h>
+#  include <__algorithm/pstl_any_all_none_of.h>
+#  include <__algorithm/pstl_copy.h>
+#  include <__algorithm/pstl_count.h>
+#  include <__algorithm/pstl_equal.h>
+#  include <__algorithm/pstl_fill.h>
+#  include <__algorithm/pstl_find.h>
+#  include <__algorithm/pstl_for_each.h>
+#  include <__algorithm/pstl_generate.h>
+#  include <__algorithm/pstl_is_partitioned.h>
+#  include <__algorithm/pstl_merge.h>
+#  include <__algorithm/pstl_move.h>
+#  include <__algorithm/pstl_replace.h>
+#  include <__algorithm/pstl_rotate_copy.h>
+#  include <__algorithm/pstl_sort.h>
+#  include <__algorithm/pstl_stable_sort.h>
+#  include <__algorithm/pstl_transform.h>
+#  include <__algorithm/sample.h>
+#endif // _LIBCPP_STD_VER >= 17
+
+#if _LIBCPP_STD_VER >= 20
+#  include <__algorithm/in_found_result.h>
+#  include <__algorithm/in_fun_result.h>
+#  include <__algorithm/in_in_out_result.h>
+#  include <__algorithm/in_in_result.h>
+#  include <__algorithm/in_out_out_result.h>
+#  include <__algorithm/in_out_result.h>
+#  include <__algorithm/lexicographical_compare_three_way.h>
+#  include <__algorithm/min_max_result.h>
+#  include <__algorithm/ranges_adjacent_find.h>
+#  include <__algorithm/ranges_all_of.h>
+#  include <__algorithm/ranges_any_of.h>
+#  include <__algorithm/ranges_binary_search.h>
+#  include <__algorithm/ranges_clamp.h>
+#  include <__algorithm/ranges_contains.h>
+#  include <__algorithm/ranges_copy.h>
+#  include <__algorithm/ranges_copy_backward.h>
+#  include <__algorithm/ranges_copy_if.h>
+#  include <__algorithm/ranges_copy_n.h>
+#  include <__algorithm/ranges_count.h>
+#  include <__algorithm/ranges_count_if.h>
+#  include <__algorithm/ranges_equal.h>
+#  include <__algorithm/ranges_equal_range.h>
+#  include <__algorithm/ranges_fill.h>
+#  include <__algorithm/ranges_fill_n.h>
+#  include <__algorithm/ranges_find.h>
+#  include <__algorithm/ranges_find_end.h>
+#  include <__algorithm/ranges_find_first_of.h>
+#  include <__algorithm/ranges_find_if.h>
+#  include <__algorithm/ranges_find_if_not.h>
+#  include <__algorithm/ranges_for_each.h>
+#  include <__algorithm/ranges_for_each_n.h>
+#  include <__algorithm/ranges_generate.h>
+#  include <__algorithm/ranges_generate_n.h>
+#  include <__algorithm/ranges_includes.h>
+#  include <__algorithm/ranges_inplace_merge.h>
+#  include <__algorithm/ranges_is_heap.h>
+#  include <__algorithm/ranges_is_heap_until.h>
+#  include <__algorithm/ranges_is_partitioned.h>
+#  include <__algorithm/ranges_is_permutation.h>
+#  include <__algorithm/ranges_is_sorted.h>
+#  include <__algorithm/ranges_is_sorted_until.h>
+#  include <__algorithm/ranges_lexicographical_compare.h>
+#  include <__algorithm/ranges_lower_bound.h>
+#  include <__algorithm/ranges_make_heap.h>
+#  include <__algorithm/ranges_max.h>
+#  include <__algorithm/ranges_max_element.h>
+#  include <__algorithm/ranges_merge.h>
+#  include <__algorithm/ranges_min.h>
+#  include <__algorithm/ranges_min_element.h>
+#  include <__algorithm/ranges_minmax.h>
+#  include <__algorithm/ranges_minmax_element.h>
+#  include <__algorithm/ranges_mismatch.h>
+#  include <__algorithm/ranges_move.h>
+#  include <__algorithm/ranges_move_backward.h>
+#  include <__algorithm/ranges_next_permutation.h>
+#  include <__algorithm/ranges_none_of.h>
+#  include <__algorithm/ranges_nth_element.h>
+#  include <__algorithm/ranges_partial_sort.h>
+#  include <__algorithm/ranges_partial_sort_copy.h>
+#  include <__algorithm/ranges_partition.h>
+#  include <__algorithm/ranges_partition_copy.h>
+#  include <__algorithm/ranges_partition_point.h>
+#  include <__algorithm/ranges_pop_heap.h>
+#  include <__algorithm/ranges_prev_permutation.h>
+#  include <__algorithm/ranges_push_heap.h>
+#  include <__algorithm/ranges_remove.h>
+#  include <__algorithm/ranges_remove_copy.h>
+#  include <__algorithm/ranges_remove_copy_if.h>
+#  include <__algorithm/ranges_remove_if.h>
+#  include <__algorithm/ranges_replace.h>
+#  include <__algorithm/ranges_replace_copy.h>
+#  include <__algorithm/ranges_replace_copy_if.h>
+#  include <__algorithm/ranges_replace_if.h>
+#  include <__algorithm/ranges_reverse.h>
+#  include <__algorithm/ranges_reverse_copy.h>
+#  include <__algorithm/ranges_rotate.h>
+#  include <__algorithm/ranges_rotate_copy.h>
+#  include <__algorithm/ranges_sample.h>
+#  include <__algorithm/ranges_search.h>
+#  include <__algorithm/ranges_search_n.h>
+#  include <__algorithm/ranges_set_difference.h>
+#  include <__algorithm/ranges_set_intersection.h>
+#  include <__algorithm/ranges_set_symmetric_difference.h>
+#  include <__algorithm/ranges_set_union.h>
+#  include <__algorithm/ranges_shuffle.h>
+#  include <__algorithm/ranges_sort.h>
+#  include <__algorithm/ranges_sort_heap.h>
+#  include <__algorithm/ranges_stable_partition.h>
+#  include <__algorithm/ranges_stable_sort.h>
+#  include <__algorithm/ranges_swap_ranges.h>
+#  include <__algorithm/ranges_transform.h>
+#  include <__algorithm/ranges_unique.h>
+#  include <__algorithm/ranges_unique_copy.h>
+#  include <__algorithm/ranges_upper_bound.h>
+#  include <__algorithm/shift_left.h>
+#  include <__algorithm/shift_right.h>
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+#  include <__algorithm/fold.h>
+#  include <__algorithm/ranges_contains_subrange.h>
+#  include <__algorithm/ranges_ends_with.h>
+#  include <__algorithm/ranges_starts_with.h>
+#endif // _LIBCPP_STD_VER >= 23
 
 // standard-mandated includes
 
diff --git a/libcxx/include/bit b/libcxx/include/bit
index b8e4bdc2dfe202..a40c44a3d4a8b6 100644
--- a/libcxx/include/bit
+++ b/libcxx/include/bit
@@ -61,19 +61,24 @@ namespace std {
 
 */
 
-#include <__bit/bit_cast.h>
-#include <__bit/bit_ceil.h>
-#include <__bit/bit_floor.h>
-#include <__bit/bit_log2.h>
-#include <__bit/bit_width.h>
-#include <__bit/blsr.h>
-#include <__bit/byteswap.h>
-#include <__bit/countl.h>
-#include <__bit/countr.h>
-#include <__bit/endian.h>
-#include <__bit/has_single_bit.h>
-#include <__bit/popcount.h>
-#include <__bit/rotate.h>
+#if _LIBCPP_STD_VER >= 20
+#  include <__bit/bit_cast.h>
+#  include <__bit/bit_ceil.h>
+#  include <__bit/bit_floor.h>
+#  include <__bit/bit_log2.h>
+#  include <__bit/bit_width.h>
+#  include <__bit/countl.h>
+#  include <__bit/countr.h>
+#  include <__bit/endian.h>
+#  include <__bit/has_single_bit.h>
+#  include <__bit/popcount.h>
+#  include <__bit/rotate.h>
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+#  include <__bit/byteswap.h>
+#endif
+
 #include <__config>
 #include <version>
 
diff --git a/libcxx/include/charconv b/libcxx/include/charconv
index 5bc7b9011be024..5840f412bad89a 100644
--- a/libcxx/include/charconv
+++ b/libcxx/include/charconv
@@ -69,18 +69,20 @@ namespace std {
 
 */
 
-#include <__charconv/chars_format.h>
-#include <__charconv/from_chars_integral.h>
-#include <__charconv/from_chars_result.h>
-#include <__charconv/tables.h>
-#include <__charconv/to_chars.h>
-#include <__charconv/to_chars_base_10.h>
-#include <__charconv/to_chars_floating_point.h>
-#include <__charconv/to_chars_integral.h>
-#include <__charconv/to_chars_result.h>
-#include <__charconv/traits.h>
+#if _LIBCPP_STD_VER >= 17
+#  include <__charconv/chars_format.h>
+#  include <__charconv/from_chars_integral.h>
+#  include <__charconv/from_chars_result.h>
+#  include <__charconv/tables.h>
+#  include <__charconv/to_chars.h>
+#  include <__charconv/to_chars_base_10.h>
+#  include <__charconv/to_chars_floating_point.h>
+#  include <__charconv/to_chars_integral.h>
+#  include <__charconv/to_chars_result.h>
+#  include <__charconv/traits.h>
+#endif // _LIBCPP_STD_VER >= 17
+
 #include <__config>
-#include <__system_error/errc.h>
 #include <version>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index b3b260c2a998e6..888499c22216de 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -825,26 +825,30 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 
 // clang-format on
 
-#include <__chrono/calendar.h>
-#include <__chrono/convert_to_timespec.h>
-#include <__chrono/convert_to_tm.h>
-#include <__chrono/day.h>
-#include <__chrono/duration.h>
-#include <__chrono/file_clock.h>
-#include <__chrono/hh_mm_ss.h>
-#include <__chrono/high_resolution_clock.h>
-#include <__chrono/literals.h>
-#include <__chrono/month.h>
-#include <__chrono/month_weekday.h>
-#include <__chrono/monthday.h>
-#include <__chrono/steady_clock.h>
-#include <__chrono/system_cl...
[truncated]

@philnik777 philnik777 changed the title [libc++] Only include what is required by-version in the umbrella headers [libc++][RFC] Only include what is required by-version in the umbrella headers Mar 3, 2024
Copy link
Member

@mordante mordante left a comment

Choose a reason for hiding this comment

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

As mentioned earlier I had a patch on Phab with a slightly different approach. So yes in general I like the idea of reducing the size of the includes.

I wonder about the approach you take; your examples only show how to handle granularized headers. I wonder what do you propose for non-granularized headers?

For example, <ostream> includes <print> the <print> header has been introduced in C++23. This header has some includes not used in <ostream>.

Do you propose to keep the <ostream> header unchanged or do you want to guard the include of <print> with C++23?

@philnik777
Copy link
Contributor Author

As mentioned earlier I had a patch on Phab with a slightly different approach. So yes in general I like the idea of reducing the size of the includes.

I wonder about the approach you take; your examples only show how to handle granularized headers. I wonder what do you propose for non-granularized headers?

For example, <ostream> includes <print> the <print> header has been introduced in C++23. This header has some includes not used in <ostream>.

Do you propose to keep the <ostream> header unchanged or do you want to guard the include of <print> with C++23?

I propose to either keep them unchanged, or to granularize it if we think it's worth the reduced include size. IIUC the main problem we have is <format> and the different formatter specializations that have to be provided through different headers resulting in huge amounts of transitive includes. Since they can be implemented separately from the rest of the files, we can simply move them into new detail headers and include these detail headers conditionally in the umbrella header.
In essence, I want the only place where we conditionally include headers to be the umbrella headers.

@mordante
Copy link
Member

mordante commented Mar 9, 2024

As mentioned earlier I had a patch on Phab with a slightly different approach. So yes in general I like the idea of reducing the size of the includes.
I wonder about the approach you take; your examples only show how to handle granularized headers. I wonder what do you propose for non-granularized headers?
For example, <ostream> includes <print> the <print> header has been introduced in C++23. This header has some includes not used in <ostream>.
Do you propose to keep the <ostream> header unchanged or do you want to guard the include of <print> with C++23?

I propose to either keep them unchanged, or to granularize it if we think it's worth the reduced include size. IIUC the main problem we have is <format> and the different formatter specializations that have to be provided through different headers resulting in huge amounts of transitive includes. Since they can be implemented separately from the rest of the files, we can simply move them into new detail headers and include these detail headers conditionally in the umbrella header. In essence, I want the only place where we conditionally include headers to be the umbrella headers.

I'm not sure how feasible splitting-off format would be. For example the formatter for vector needs to know about vector. IMO that is something we can look into for a separate patch if we want to solve these includes.

I think the approach you suggest is simple and easy to maintain. I think we could do more, but that might have an different maintenance trade-off. Taking this approach does not block other optimizations. So I'm happy to move forward with this direction.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

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

This direction LGTM. There are a few bugs as pointed out by Mark, but with those fixed I think this patch makes a lot of sense.

@philnik777 philnik777 force-pushed the reduce_include_size branch 2 times, most recently from acf7ea0 to a0cec7f Compare April 13, 2024 16:53
@philnik777 philnik777 force-pushed the reduce_include_size branch from a0cec7f to 74c6a48 Compare April 14, 2024 06:55
@philnik777 philnik777 merged commit d5c654b into llvm:main Apr 14, 2024
@philnik777 philnik777 deleted the reduce_include_size branch April 14, 2024 13:53
bazuzi pushed a commit to bazuzi/llvm-project that referenced this pull request Apr 15, 2024
…a headers (llvm#83740)

This is a relatively low cost way of reducing the include sizes in older
language modes compared to the effect. For example, in C++14 mode the
include time of `<algorithm>` is reduced from 198ms to 127ms.
philnik777 added a commit that referenced this pull request Jul 18, 2024
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
…rella headers (#96032)

Summary: This is a follow-up to #83740.

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60250970
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants