[wasm-gc] Clean up workarounds in optimizations
Earlier, we had to introduce some temporary workarounds in Turbofan to enable optimizations for common wasm-gc patterns. These are now not required, since these optimizations are applied in WasmTyper and WasmGCOperatorReducer. Bug: v8:7748 Change-Id: I3a7bc4bd2a8023a438ee4620934ff3fcb8bcfc6a Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3693999 Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Reviewed-by: Maya Lekova <mslekova@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/main@{#81011}
This commit is contained in:
parent
cd21627b16
commit
31ece3e9e4
@ -15,15 +15,12 @@ namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
BranchElimination::BranchElimination(Editor* editor, JSGraph* js_graph,
|
||||
Zone* zone,
|
||||
SourcePositionTable* source_positions,
|
||||
Phase phase)
|
||||
Zone* zone, Phase phase)
|
||||
: AdvancedReducer(editor),
|
||||
jsgraph_(js_graph),
|
||||
node_conditions_(js_graph->graph()->NodeCount(), zone),
|
||||
reduced_(js_graph->graph()->NodeCount(), zone),
|
||||
zone_(zone),
|
||||
source_positions_(source_positions),
|
||||
dead_(js_graph->Dead()),
|
||||
phase_(phase) {}
|
||||
|
||||
@ -162,72 +159,6 @@ Reduction BranchElimination::ReduceBranch(Node* node) {
|
||||
return TakeConditionsFromFirstControl(node);
|
||||
}
|
||||
|
||||
// Simplify a trap following a merge.
|
||||
// Assuming condition is in control1's path conditions, and !condition is in
|
||||
// control2's path condtions, the following transformation takes place:
|
||||
//
|
||||
// control1 control2 condition effect1
|
||||
// \ / \ / |
|
||||
// Merge X | control1
|
||||
// | / \ | /
|
||||
// effect1 effect2 | | TrapIf control2
|
||||
// \ | /| ==> | \ /
|
||||
// EffectPhi | | effect2 Merge
|
||||
// | / | | /
|
||||
// condition | / \ | /
|
||||
// \ | / EffectPhi
|
||||
// TrapIf
|
||||
// TODO(manoskouk): We require that the trap's effect input is the Merge's
|
||||
// EffectPhi, so we can ensure that the new traps' effect inputs are not
|
||||
// dominated by the Merge. Can we relax this?
|
||||
bool BranchElimination::TryPullTrapIntoMerge(Node* node) {
|
||||
DCHECK(node->opcode() == IrOpcode::kTrapIf ||
|
||||
node->opcode() == IrOpcode::kTrapUnless);
|
||||
Node* merge = NodeProperties::GetControlInput(node);
|
||||
DCHECK_EQ(merge->opcode(), IrOpcode::kMerge);
|
||||
Node* condition = NodeProperties::GetValueInput(node, 0);
|
||||
Node* effect_input = NodeProperties::GetEffectInput(node);
|
||||
if (!(effect_input->opcode() == IrOpcode::kEffectPhi &&
|
||||
NodeProperties::GetControlInput(effect_input) == merge)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool trapping_condition = node->opcode() == IrOpcode::kTrapIf;
|
||||
base::SmallVector<Node*, 8> new_merge_inputs;
|
||||
for (Edge edge : merge->input_edges()) {
|
||||
Node* input = edge.to();
|
||||
ControlPathConditions from_input = node_conditions_.Get(input);
|
||||
Node* previous_branch;
|
||||
bool condition_value;
|
||||
if (!from_input.LookupCondition(condition, &previous_branch,
|
||||
&condition_value)) {
|
||||
return false;
|
||||
}
|
||||
if (condition_value == trapping_condition) {
|
||||
Node* inputs[] = {
|
||||
condition, NodeProperties::GetEffectInput(effect_input, edge.index()),
|
||||
input};
|
||||
Node* trap_clone = graph()->NewNode(node->op(), 3, inputs);
|
||||
if (source_positions_) {
|
||||
source_positions_->SetSourcePosition(
|
||||
trap_clone, source_positions_->GetSourcePosition(node));
|
||||
}
|
||||
new_merge_inputs.emplace_back(trap_clone);
|
||||
} else {
|
||||
new_merge_inputs.emplace_back(input);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < merge->InputCount(); i++) {
|
||||
merge->ReplaceInput(i, new_merge_inputs[i]);
|
||||
}
|
||||
ReplaceWithValue(node, dead(), dead(), merge);
|
||||
node->Kill();
|
||||
Revisit(merge);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reduction BranchElimination::ReduceTrapConditional(Node* node) {
|
||||
DCHECK(node->opcode() == IrOpcode::kTrapIf ||
|
||||
node->opcode() == IrOpcode::kTrapUnless);
|
||||
@ -239,13 +170,6 @@ Reduction BranchElimination::ReduceTrapConditional(Node* node) {
|
||||
// predecessor.
|
||||
if (!reduced_.Get(control_input)) return NoChange();
|
||||
|
||||
// If the trap comes directly after a merge, pull it into the merge. This will
|
||||
// unlock other optimizations later.
|
||||
if (control_input->opcode() == IrOpcode::kMerge &&
|
||||
TryPullTrapIntoMerge(node)) {
|
||||
return Replace(dead());
|
||||
}
|
||||
|
||||
ControlPathConditions from_input = node_conditions_.Get(control_input);
|
||||
Node* previous_branch;
|
||||
bool condition_value;
|
||||
|
@ -29,7 +29,7 @@ class V8_EXPORT_PRIVATE BranchElimination final
|
||||
kLATE,
|
||||
};
|
||||
BranchElimination(Editor* editor, JSGraph* js_graph, Zone* zone,
|
||||
SourcePositionTable* sourse_positions, Phase phase = kLATE);
|
||||
Phase phase = kLATE);
|
||||
~BranchElimination() final;
|
||||
|
||||
const char* reducer_name() const override { return "BranchElimination"; }
|
||||
@ -109,7 +109,6 @@ class V8_EXPORT_PRIVATE BranchElimination final
|
||||
Reduction ReduceStart(Node* node);
|
||||
Reduction ReduceOtherControl(Node* node);
|
||||
void SimplifyBranchCondition(Node* branch);
|
||||
bool TryPullTrapIntoMerge(Node* node);
|
||||
|
||||
Reduction TakeConditionsFromFirstControl(Node* node);
|
||||
Reduction UpdateConditions(Node* node, ControlPathConditions conditions);
|
||||
@ -133,7 +132,6 @@ class V8_EXPORT_PRIVATE BranchElimination final
|
||||
node_conditions_;
|
||||
NodeAuxData<bool> reduced_;
|
||||
Zone* zone_;
|
||||
SourcePositionTable* source_positions_;
|
||||
Node* dead_;
|
||||
Phase phase_;
|
||||
};
|
||||
|
@ -84,9 +84,8 @@ bool IsConstantObject(Node* object) {
|
||||
}
|
||||
|
||||
bool IsFreshObject(Node* object) {
|
||||
DCHECK_IMPLIES(NodeProperties::IsFreshObject(object),
|
||||
!IsConstantObject(object));
|
||||
return NodeProperties::IsFreshObject(object);
|
||||
return object->opcode() == IrOpcode::kAllocate ||
|
||||
object->opcode() == IrOpcode::kAllocateRaw;
|
||||
}
|
||||
|
||||
} // namespace CsaLoadEliminationHelpers
|
||||
|
@ -289,22 +289,6 @@ Node* MachineOperatorReducer::TruncateInt64ToInt32(Node* value) {
|
||||
return reduction.Changed() ? reduction.replacement() : node;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool ObjectsMayAlias(Node* a, Node* b) {
|
||||
if (a != b) {
|
||||
if (NodeProperties::IsFreshObject(b)) std::swap(a, b);
|
||||
if (NodeProperties::IsFreshObject(a) &&
|
||||
(NodeProperties::IsFreshObject(b) ||
|
||||
b->opcode() == IrOpcode::kParameter ||
|
||||
b->opcode() == IrOpcode::kLoadImmutable ||
|
||||
IrOpcode::IsConstantOpcode(b->opcode()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// Perform constant folding and strength reduction on machine operators.
|
||||
Reduction MachineOperatorReducer::Reduce(Node* node) {
|
||||
switch (node->opcode()) {
|
||||
@ -360,11 +344,6 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
|
||||
}
|
||||
// TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares
|
||||
if (m.LeftEqualsRight()) return ReplaceBool(true); // x == x => true
|
||||
// This is a workaround for not having escape analysis for wasm
|
||||
// (machine-level) turbofan graphs.
|
||||
if (!ObjectsMayAlias(m.left().node(), m.right().node())) {
|
||||
return ReplaceBool(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IrOpcode::kInt32Add:
|
||||
@ -2080,11 +2059,6 @@ Reduction MachineOperatorReducer::ReduceWord32Equal(Node* node) {
|
||||
return Changed(node);
|
||||
}
|
||||
}
|
||||
// This is a workaround for not having escape analysis for wasm
|
||||
// (machine-level) turbofan graphs.
|
||||
if (!ObjectsMayAlias(m.left().node(), m.right().node())) {
|
||||
return ReplaceBool(false);
|
||||
}
|
||||
|
||||
return NoChange();
|
||||
}
|
||||
|
@ -601,35 +601,6 @@ bool NodeProperties::AllValueInputsAreTyped(Node* node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool NodeProperties::IsFreshObject(Node* node) {
|
||||
if (node->opcode() == IrOpcode::kAllocate ||
|
||||
node->opcode() == IrOpcode::kAllocateRaw)
|
||||
return true;
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
if (node->opcode() == IrOpcode::kCall) {
|
||||
// TODO(manoskouk): Currently, some wasm builtins are called with in
|
||||
// CallDescriptor::kCallWasmFunction mode. Make sure this is synced if the
|
||||
// calling mechanism is refactored.
|
||||
if (CallDescriptorOf(node->op())->kind() !=
|
||||
CallDescriptor::kCallBuiltinPointer) {
|
||||
return false;
|
||||
}
|
||||
NumberMatcher matcher(node->InputAt(0));
|
||||
if (matcher.HasResolvedValue()) {
|
||||
Builtin callee = static_cast<Builtin>(matcher.ResolvedValue());
|
||||
// Note: Make sure to only add builtins which are guaranteed to return a
|
||||
// fresh object. E.g. kWasmAllocateFixedArray may return the canonical
|
||||
// empty array.
|
||||
return callee == Builtin::kWasmAllocateArray_Uninitialized ||
|
||||
callee == Builtin::kWasmAllocateStructWithRtt ||
|
||||
callee == Builtin::kWasmAllocateObjectWrapper;
|
||||
}
|
||||
}
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool NodeProperties::IsInputRange(Edge edge, int first, int num) {
|
||||
if (num == 0) return false;
|
||||
|
@ -143,10 +143,6 @@ class V8_EXPORT_PRIVATE NodeProperties {
|
||||
}
|
||||
}
|
||||
|
||||
// Determines if {node} has an allocating opcode, or is a builtin known to
|
||||
// return a fresh object.
|
||||
static bool IsFreshObject(Node* node);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Miscellaneous mutators.
|
||||
|
||||
|
@ -1885,8 +1885,7 @@ struct LoadEliminationPhase {
|
||||
temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
|
||||
data->jsgraph()->Dead(), data->observe_node_manager());
|
||||
BranchElimination branch_condition_elimination(
|
||||
&graph_reducer, data->jsgraph(), temp_zone, data->source_positions(),
|
||||
BranchElimination::kEARLY);
|
||||
&graph_reducer, data->jsgraph(), temp_zone, BranchElimination::kEARLY);
|
||||
DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
|
||||
data->common(), temp_zone);
|
||||
RedundancyElimination redundancy_elimination(&graph_reducer, temp_zone);
|
||||
@ -1955,8 +1954,8 @@ struct LateOptimizationPhase {
|
||||
data->jsgraph()->Dead(), data->observe_node_manager());
|
||||
LateEscapeAnalysis escape_analysis(&graph_reducer, data->graph(),
|
||||
data->common(), temp_zone);
|
||||
BranchElimination branch_condition_elimination(
|
||||
&graph_reducer, data->jsgraph(), temp_zone, data->source_positions());
|
||||
BranchElimination branch_condition_elimination(&graph_reducer,
|
||||
data->jsgraph(), temp_zone);
|
||||
DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
|
||||
data->common(), temp_zone);
|
||||
ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
|
||||
@ -2152,7 +2151,7 @@ struct WasmOptimizationPhase {
|
||||
data->machine(), temp_zone, BranchSemantics::kMachine);
|
||||
ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
|
||||
BranchElimination branch_condition_elimination(
|
||||
&graph_reducer, data->jsgraph(), temp_zone, data->source_positions());
|
||||
&graph_reducer, data->jsgraph(), temp_zone);
|
||||
AddReducer(data, &graph_reducer, &machine_reducer);
|
||||
AddReducer(data, &graph_reducer, &dead_code_elimination);
|
||||
AddReducer(data, &graph_reducer, &common_reducer);
|
||||
@ -2207,7 +2206,7 @@ struct CsaEarlyOptimizationPhase {
|
||||
data->machine(), temp_zone, BranchSemantics::kMachine);
|
||||
ValueNumberingReducer value_numbering(temp_zone, data->graph()->zone());
|
||||
BranchElimination branch_condition_elimination(
|
||||
&graph_reducer, data->jsgraph(), temp_zone, data->source_positions());
|
||||
&graph_reducer, data->jsgraph(), temp_zone);
|
||||
AddReducer(data, &graph_reducer, &machine_reducer);
|
||||
AddReducer(data, &graph_reducer, &dead_code_elimination);
|
||||
AddReducer(data, &graph_reducer, &common_reducer);
|
||||
@ -2225,8 +2224,8 @@ struct CsaOptimizationPhase {
|
||||
GraphReducer graph_reducer(
|
||||
temp_zone, data->graph(), &data->info()->tick_counter(), data->broker(),
|
||||
data->jsgraph()->Dead(), data->observe_node_manager());
|
||||
BranchElimination branch_condition_elimination(
|
||||
&graph_reducer, data->jsgraph(), temp_zone, data->source_positions());
|
||||
BranchElimination branch_condition_elimination(&graph_reducer,
|
||||
data->jsgraph(), temp_zone);
|
||||
DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
|
||||
data->common(), temp_zone);
|
||||
MachineOperatorReducer machine_reducer(&graph_reducer, data->jsgraph(),
|
||||
|
@ -31,7 +31,7 @@ class BranchEliminationTest : public GraphTest {
|
||||
GraphReducer graph_reducer(zone(), graph(), tick_counter(), broker(),
|
||||
jsgraph.Dead());
|
||||
BranchElimination branch_condition_elimination(&graph_reducer, &jsgraph,
|
||||
zone(), nullptr);
|
||||
zone());
|
||||
graph_reducer.AddReducer(&branch_condition_elimination);
|
||||
graph_reducer.ReduceGraph();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user