1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___UTILITY_ASSUME_H
10#define _LIBCPP___UTILITY_ASSUME_H
11
12#include <__config>
13#include <__type_traits/is_constant_evaluated.h>
14
15#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16# pragma GCC system_header
17#endif
18
19_LIBCPP_PUSH_MACROS
20#include <__undef_macros>
21
22_LIBCPP_BEGIN_NAMESPACE_STD
23
24// WARNING: [[assume]] can currently inhibit optimizations. Only add assumptions with a clear optimization intent.
25// See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a discussion.
26
27_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 void __assume(bool __cond) { [[__assume__(__cond)]]; }
28
29// This function allows the compiler to assume that `__a` and `__b` can never alias each other, similar to `__restrict`.
30// However, this assume must also hold if the function is inlined, so effectively the two pointers must never be part of
31// the same allocation according to the LLVM semantics. This is currently only the case for stack allocated objects as
32// well as pointers returned from the `malloc`-family of functions and `::operator new` family of functions. Other
33// pointers may be considered part of the same allocation, in which case this assume could lead to incorrect
34// optimizations.
35_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 void
36__assume_separate_storage([[__maybe_unused__]] const void* __a, [[__maybe_unused__]] const void* __b) {
37#if __has_builtin(__builtin_assume_separate_storage)
38 // __builtin_assume_separate_storage claims constexpr support, but it's broken. See https://llvm.org/PR225335.
39 if (!__libcpp_is_constant_evaluated())
40 __builtin_assume_separate_storage(__a, __b);
41#endif
42}
43
44_LIBCPP_END_NAMESPACE_STD
45
46_LIBCPP_POP_MACROS
47
48#endif // _LIBCPP___UTILITY_ASSUME_H
49