[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:
parent
8ca9f77d0f
commit
d4e3daca25
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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] = {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user