folly/folly/lang/Hint-inl.h

/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

namespace folly {

FOLLY_ALWAYS_INLINE void compiler_may_unsafely_assume(bool cond) {}

[[noreturn]] FOLLY_ALWAYS_INLINE void
compiler_may_unsafely_assume_unreachable() {}

FOLLY_ALWAYS_INLINE void compiler_may_unsafely_assume_separate_storage(
    void const* const a, void const* const b) {}

#if defined(_MSC_VER) && !defined(__clang__)

namespace detail {

#pragma optimize("", off)

inline void compiler_must_force_sink(void const*) {}

#pragma optimize("", on)

} // namespace detail

template <typename T>
FOLLY_ALWAYS_INLINE void compiler_must_not_elide_fn::operator()(
    T const& t) const noexcept {
  detail::compiler_must_force_sink(&t);
}

template <typename T>
FOLLY_ALWAYS_INLINE void compiler_must_not_predict_fn::operator()(
    T& t) const noexcept {
  detail::compiler_must_force_sink(&t);
}

#else

namespace detail {

compiler_must_force_indirect;

template <typename T>
FOLLY_ALWAYS_INLINE void compiler_must_not_elide(T const& t, std::false_type) {}

template <typename T>
FOLLY_ALWAYS_INLINE void compiler_must_not_elide(T const& t, std::true_type) {}

template <typename T>
FOLLY_ALWAYS_INLINE void compiler_must_not_predict(T& t, std::false_type) {}

template <typename T>
FOLLY_ALWAYS_INLINE void compiler_must_not_predict(T& t, std::true_type) {}

} // namespace detail

template <typename T>
FOLLY_ALWAYS_INLINE void compiler_must_not_elide_fn::operator()(
    T const& t) const noexcept {}

template <typename T>
FOLLY_ALWAYS_INLINE void compiler_must_not_predict_fn::operator()(
    T& t) const noexcept {}

#endif

} // namespace folly