[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 <tebbi@chromium.org>
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84545}
This commit is contained in:
Maya Lekova 2022-11-28 17:06:39 +01:00 committed by V8 LUCI CQ
parent 8ca9f77d0f
commit d4e3daca25
6 changed files with 81 additions and 16 deletions

View File

@ -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:

View File

@ -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<const OpIndex> inputs, RegisterRepresentation rep) {
return stack().ReducePhi(inputs, rep);
}

View File

@ -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<bool> 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<OpIndex> 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<bool> 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<const SwitchOp::Case> 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,

View File

@ -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<const RegisterRepresentation> 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<const RegisterRepresentation> 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<OpProperties>
kOperationPropertiesTable[kNumberOfOpcodes] = {

View File

@ -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) {

View File

@ -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);