// Copyright 2023 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD // This file defines Turboshaft's assembler macros. Include this file before // your reducers and don't forget to include 'undef-assembler-macros.inc' // afterwards. #ifdef V8_COMPILER_TURBOSHAFT_ASSEMBLER_MACROS_DEFINED #error \ "Assembler macros already defined. Did you forget to #include \"undef-assembler-macros.inc\" in a previous file?" #endif #define V8_COMPILER_TURBOSHAFT_ASSEMBLER_MACROS_DEFINED … #define TSA_DCHECK … #define LIKELY(...) … #define UNLIKELY … #define BIND … #define BIND_LOOP … #define WHILE … #define FOREACH_IMPL_2 … #define FOREACH_IMPL_3 … // TODO(nicohartmann): Add more `FOREACH_IMPL_N` versions when we see need. #define FOREACH … #define BREAK … // TODO(nicohartmann): CONTINUE currently doesn't work for FOREACH. #define CONTINUE … #define GOTO … #define GOTO_IF … #define GOTO_IF_NOT … // Clang/GCC helpfully warn us about dangling else in nested if statements. This // dangling is intentional for the way these macros work, so suppress the // warning with Pragmas. Clang and GCC helpfully disagree on where the warning // is (on the if or the else), so they need separate macros. #if defined(__clang__) #if defined(DEBUG) || defined(GOOGLE3) // TODO(dmercadier,leszeks): re-enable forced unrolling in DEBUG build. This // requires figuring out why Clang doesn't manage to unroll the loop in DEBUG // builds. In google3, forced unrolling also caused problems. Disable it there // for now as well. // TODO(349411321): re-enable forced unrolling in google3 again. #define FORCE_UNROLL_LOOP #else #define FORCE_UNROLL_LOOP … #endif #define SUPPRESSED_DANGLING_ELSE_WARNING_IF(...) … #define SUPPRESSED_DANGLING_ELSE_WARNING_ELSE … #elif defined(__GNUC__) #define FORCE_UNROLL_LOOP #define SUPPRESSED_DANGLING_ELSE_WARNING_IF … #define SUPPRESSED_DANGLING_ELSE_WARNING_ELSE … #else #define FORCE_UNROLL_LOOP #define SUPPRESSED_DANGLING_ELSE_WARNING_IF … #define SUPPRESSED_DANGLING_ELSE_WARNING_ELSE … #endif // IF/ELSE macros. These expand to a real C++ if-else, so that we can get // similar block syntax behaviour (with an optional `ELSE`). Since C++ will only // evaluate one side of the if-else, wrap it in a for loop that executes the // if-else three times: once for each side of the branch, and once to close the // if. Each iteration also emits a goto-end if the corresponding branch target // was bound. An if around the for loop encapsulates the state -- this is // outside the for loop to make it easier for the compiler to unroll the three // loop iterations. #define IF … #define IF_NOT … #define ELSE … #define Assert … #ifdef DEBUG // In debug builds, `REDUCE(operation)` makes sure that `operation##Op` exists // by using this name in an expression. This will detect typos in the name which // would otherwise stay unnoticed potentially. #define REDUCE … #define REDUCE_INPUT_GRAPH … #else #define REDUCE … #define REDUCE_INPUT_GRAPH … #endif // DEBUG #define __ …