diff options
Diffstat (limited to 'deps/v8/src/compiler/turboshaft/typed-optimizations-reducer.h')
-rw-r--r-- | deps/v8/src/compiler/turboshaft/typed-optimizations-reducer.h | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/deps/v8/src/compiler/turboshaft/typed-optimizations-reducer.h b/deps/v8/src/compiler/turboshaft/typed-optimizations-reducer.h new file mode 100644 index 0000000000..be62b77f20 --- /dev/null +++ b/deps/v8/src/compiler/turboshaft/typed-optimizations-reducer.h @@ -0,0 +1,129 @@ +// Copyright 2022 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. + +#ifndef V8_COMPILER_TURBOSHAFT_TYPED_OPTIMIZATIONS_REDUCER_H_ +#define V8_COMPILER_TURBOSHAFT_TYPED_OPTIMIZATIONS_REDUCER_H_ + +#include "src/compiler/turboshaft/assembler.h" +#include "src/compiler/turboshaft/index.h" +#include "src/compiler/turboshaft/operations.h" +#include "src/compiler/turboshaft/typer.h" +#include "src/compiler/turboshaft/uniform-reducer-adapter.h" + +namespace v8::internal::compiler::turboshaft { + +template <typename> +class TypeInferenceReducer; + +template <typename Next> +class TypedOptimizationsReducer + : public UniformReducerAdapter<TypedOptimizationsReducer, Next> { + // Typed optimizations require a typed graph. + // TODO(nicohartmann@): Reenable this in a way that compiles with msvc light. + // static_assert(next_contains_reducer<Next, TypeInferenceReducer>::value); + + public: + TURBOSHAFT_REDUCER_BOILERPLATE() + + using Adapter = UniformReducerAdapter<TypedOptimizationsReducer, Next>; + + template <typename... Args> + explicit TypedOptimizationsReducer(const std::tuple<Args...>& args) + : Adapter(args) {} + + OpIndex ReduceInputGraphBranch(OpIndex ig_index, const BranchOp& operation) { + Type condition_type = GetType(operation.condition()); + if (!condition_type.IsInvalid()) { + if (condition_type.IsNone()) { + Asm().Unreachable(); + return OpIndex::Invalid(); + } + condition_type = + Typer::TruncateWord32Input(condition_type, true, Asm().graph_zone()); + DCHECK(condition_type.IsWord32()); + if (auto c = condition_type.AsWord32().try_get_constant()) { + Block* goto_target = *c == 0 ? operation.if_false : operation.if_true; + Asm().Goto(goto_target->MapToNextGraph()); + return OpIndex::Invalid(); + } + } + return Adapter::ReduceInputGraphBranch(ig_index, operation); + } + + template <typename Op, typename Continuation> + OpIndex ReduceInputGraphOperation(OpIndex ig_index, const Op& operation) { + Type type = GetType(ig_index); + if (type.IsNone()) { + // This operation is dead. Remove it. + DCHECK(CanBeTyped(operation)); + return OpIndex::Invalid(); + } else if (!type.IsInvalid()) { + // See if we can replace the operation by a constant. + if (OpIndex constant = TryAssembleConstantForType(type); + constant.valid()) { + return constant; + } + } + + // Otherwise just continue with reduction. + return Continuation{this}.ReduceInputGraph(ig_index, operation); + } + + private: + // If {type} is a single value that can be respresented by a constant, this + // function returns the index for a corresponding ConstantOp. It returns + // OpIndex::Invalid otherwise. + OpIndex TryAssembleConstantForType(const Type& type) { + switch (type.kind()) { + case Type::Kind::kWord32: { + auto w32 = type.AsWord32(); + if (auto c = w32.try_get_constant()) { + return Asm().Word32Constant(*c); + } + break; + } + case Type::Kind::kWord64: { + auto w64 = type.AsWord64(); + if (auto c = w64.try_get_constant()) { + return Asm().Word64Constant(*c); + } + break; + } + case Type::Kind::kFloat32: { + auto f32 = type.AsFloat32(); + if (f32.is_only_nan()) { + return Asm().Float32Constant(nan_v<32>); + } else if (f32.is_only_minus_zero()) { + return Asm().Float32Constant(-0.0f); + } else if (auto c = f32.try_get_constant()) { + return Asm().Float32Constant(*c); + } + break; + } + case Type::Kind::kFloat64: { + auto f64 = type.AsFloat64(); + if (f64.is_only_nan()) { + return Asm().Float64Constant(nan_v<64>); + } else if (f64.is_only_minus_zero()) { + return Asm().Float64Constant(-0.0); + } else if (auto c = f64.try_get_constant()) { + return Asm().Float64Constant(*c); + } + break; + } + default: + break; + } + return OpIndex::Invalid(); + } + + Type GetType(const OpIndex index) { + // Typed optimizations use the types of the input graph. + return Asm().GetInputGraphType(index); + } +}; + +} // namespace v8::internal::compiler::turboshaft + +#endif // V8_COMPILER_TURBOSHAFT_TYPED_OPTIMIZATIONS_REDUCER_H_ |