summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/turboshaft/typed-optimizations-reducer.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/turboshaft/typed-optimizations-reducer.h')
-rw-r--r--deps/v8/src/compiler/turboshaft/typed-optimizations-reducer.h129
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_