From d4e3daca25655d1052cfba7de8c0a72ff43f5a92 Mon Sep 17 00:00:00 2001 From: Maya Lekova Date: Mon, 28 Nov 2022 17:06:39 +0100 Subject: [PATCH] [turboshaft] Port basic lowerings of CommonOperatorReducer The following operations are reduced in MachineOptimizationReducer: - TrapIf/TrapUnless - Switch - StaticAssert Bug: v8:12783 Change-Id: I9afbf83b6fab4c1ffc346ffcfa1e80770387e133 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4016818 Reviewed-by: Tobias Tebbi Commit-Queue: Maya Lekova Cr-Commit-Position: refs/heads/main@{#84545} --- src/compiler/common-operator-reducer.cc | 9 ++- src/compiler/turboshaft/assembler.h | 4 ++ .../turboshaft/machine-optimization-reducer.h | 56 +++++++++++++++++++ src/compiler/turboshaft/operations.h | 24 ++++---- src/compiler/turboshaft/optimization-phase.h | 2 +- src/compiler/turboshaft/recreate-schedule.cc | 2 +- 6 files changed, 81 insertions(+), 16 deletions(-) diff --git a/src/compiler/common-operator-reducer.cc b/src/compiler/common-operator-reducer.cc index 0e34933c66..c7157d5620 100644 --- a/src/compiler/common-operator-reducer.cc +++ b/src/compiler/common-operator-reducer.cc @@ -49,9 +49,14 @@ Reduction CommonOperatorReducer::Reduce(Node* node) { case IrOpcode::kEffectPhi: return ReduceEffectPhi(node); case IrOpcode::kPhi: - return ReducePhi(node); + return ReducePhi(node); // TODO(mslekova): + // 1. Reduce a Phi whose all inputs are the same, replace + // it with its input; + // 2. Reduce a Loop Phi which points to itself, replace it + // with it's 0'th input. case IrOpcode::kReturn: - return ReduceReturn(node); + return ReduceReturn(node); // TODO(mslekova): + // Add to Branch Elimination. case IrOpcode::kSelect: return ReduceSelect(node); case IrOpcode::kSwitch: diff --git a/src/compiler/turboshaft/assembler.h b/src/compiler/turboshaft/assembler.h index 09839d42a7..6a201bbb32 100644 --- a/src/compiler/turboshaft/assembler.h +++ b/src/compiler/turboshaft/assembler.h @@ -840,6 +840,10 @@ class AssemblerOpInterface { stack().ReduceTrapIf(condition, true, trap_id); } + void StaticAssert(OpIndex condition, const char* source) { + stack().ReduceStaticAssert(condition, source); + } + OpIndex Phi(base::Vector inputs, RegisterRepresentation rep) { return stack().ReducePhi(inputs, rep); } diff --git a/src/compiler/turboshaft/machine-optimization-reducer.h b/src/compiler/turboshaft/machine-optimization-reducer.h index e9218f5c41..326b937c8e 100644 --- a/src/compiler/turboshaft/machine-optimization-reducer.h +++ b/src/compiler/turboshaft/machine-optimization-reducer.h @@ -1532,6 +1532,62 @@ class MachineOptimizationReducer : public Next { } } + OpIndex ReduceTrapIf(OpIndex condition, bool negated, TrapId trap_id) { + LABEL_BLOCK(no_change) { + return Next::ReduceTrapIf(condition, negated, trap_id); + } + if (ShouldSkipOptimizationStep()) goto no_change; + if (base::Optional decision = DecideBranchCondition(condition)) { + if (*decision != negated) { + Next::ReduceTrapIf(condition, negated, trap_id); + Asm().Unreachable(); + } + // `TrapIf` doesn't produce a value. + return OpIndex::Invalid(); + } + if (base::Optional new_condition = + ReduceBranchCondition(condition, &negated)) { + return Asm().ReduceTrapIf(new_condition.value(), negated, trap_id); + } else { + goto no_change; + } + } + + OpIndex ReduceStaticAssert(OpIndex condition, const char* source) { + LABEL_BLOCK(no_change) { + return Next::ReduceStaticAssert(condition, source); + } + if (base::Optional decision = DecideBranchCondition(condition)) { + if (decision) { + // Drop the assert, the condition holds true. + return OpIndex::Invalid(); + } else { + // Leave the assert, as the condition is not true. + goto no_change; + } + } + goto no_change; + } + + OpIndex ReduceSwitch(OpIndex input, base::Vector cases, + Block* default_case) { + LABEL_BLOCK(no_change) { + return Next::ReduceSwitch(input, cases, default_case); + } + if (ShouldSkipOptimizationStep()) goto no_change; + if (int32_t value; Asm().MatchWord32Constant(input, &value)) { + for (const SwitchOp::Case& if_value : cases) { + if (if_value.value == value) { + Asm().Goto(if_value.destination); + return OpIndex::Invalid(); + } + } + Asm().Goto(default_case); + return OpIndex::Invalid(); + } + goto no_change; + } + OpIndex ReduceStore(OpIndex base, OpIndex index, OpIndex value, StoreOp::Kind kind, MemoryRepresentation stored_rep, WriteBarrierKind write_barrier, int32_t offset, diff --git a/src/compiler/turboshaft/operations.h b/src/compiler/turboshaft/operations.h index 4cdb06f8b0..dba8c715e3 100644 --- a/src/compiler/turboshaft/operations.h +++ b/src/compiler/turboshaft/operations.h @@ -1661,6 +1661,18 @@ struct TrapIfOp : FixedArityOperationT<1, TrapIfOp> { auto options() const { return std::tuple{negated, trap_id}; } }; +struct StaticAssertOp : FixedArityOperationT<1, StaticAssertOp> { + static constexpr OpProperties properties = OpProperties::CanAbort(); + base::Vector outputs_rep() const { return {}; } + const char* source; + + OpIndex condition() const { return Base::input(0); } + + StaticAssertOp(OpIndex condition, const char* source) + : Base(condition), source(source) {} + auto options() const { return std::tuple{source}; } +}; + struct ParameterOp : FixedArityOperationT<0, ParameterOp> { int32_t parameter_index; RegisterRepresentation rep; @@ -1958,18 +1970,6 @@ struct ProjectionOp : FixedArityOperationT<1, ProjectionOp> { auto options() const { return std::tuple{index}; } }; -struct StaticAssertOp : FixedArityOperationT<1, StaticAssertOp> { - static constexpr OpProperties properties = OpProperties::CanAbort(); - base::Vector outputs_rep() const { return {}; } - const char* source; - - OpIndex input() const { return Base::input(0); } - - explicit StaticAssertOp(OpIndex input, const char* source) - : Base(input), source(source) {} - auto options() const { return std::tuple{}; } -}; - #define OPERATION_PROPERTIES_CASE(Name) Name##Op::PropertiesIfStatic(), static constexpr base::Optional kOperationPropertiesTable[kNumberOfOpcodes] = { diff --git a/src/compiler/turboshaft/optimization-phase.h b/src/compiler/turboshaft/optimization-phase.h index 1d8f6a7d20..58f5ed0b63 100644 --- a/src/compiler/turboshaft/optimization-phase.h +++ b/src/compiler/turboshaft/optimization-phase.h @@ -650,7 +650,7 @@ class GraphVisitor { return assembler().ReduceUnreachable(); } OpIndex VisitStaticAssert(const StaticAssertOp& op) { - return assembler().ReduceStaticAssert(op.input(), op.source); + return assembler().ReduceStaticAssert(op.condition(), op.source); } void CreateOldToNewMapping(OpIndex old_index, OpIndex new_index) { diff --git a/src/compiler/turboshaft/recreate-schedule.cc b/src/compiler/turboshaft/recreate-schedule.cc index 641c5d3c7b..ad03daf8b0 100644 --- a/src/compiler/turboshaft/recreate-schedule.cc +++ b/src/compiler/turboshaft/recreate-schedule.cc @@ -1069,7 +1069,7 @@ Node* ScheduleBuilder::ProcessOperation(const StaticAssertOp& op) { // Static asserts should be (statically asserted and) removed by turboshaft. UnparkedScopeIfNeeded scope(broker); AllowHandleDereference allow_handle_dereference; - std::cout << input_graph.Get(op.input()); + std::cout << input_graph.Get(op.condition()); FATAL( "Expected Turbofan static assert to hold, but got non-true input:\n %s", op.source);