Commit 0230df80 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[turbofan] Optimize equality between fresh objects and constants

This is a workaround for not having escape analysis for wasm
(machine-level) turbofan graphs.

Additional change:
Move IsFreshObject to NodeProperties.

Bug: v8:11510
Change-Id: Ibd63f4352adaa58a25f07e025c9a2c395dc669b4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2773345Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73604}
parent afe9020f
......@@ -74,41 +74,14 @@ bool Subsumes(MachineRepresentation from, MachineRepresentation to) {
return false;
}
inline bool IsFreshObject(Node* node) {
if (node->opcode() == IrOpcode::kAllocate) return true;
#if V8_ENABLE_WEBASSEMBLY
if (node->opcode() == IrOpcode::kCall) {
NumberMatcher matcher(node->InputAt(0));
if (matcher.HasResolvedValue()) {
Builtins::Name callee =
static_cast<Builtins::Name>(matcher.ResolvedValue());
return callee == Builtins::kWasmAllocateArrayWithRtt ||
callee == Builtins::kWasmAllocatePair ||
callee == Builtins::kWasmAllocateFixedArray ||
callee == Builtins::kWasmAllocateJSArray ||
callee == Builtins::kWasmAllocateObjectWrapper ||
callee == Builtins::kWasmAllocateStructWithRtt;
}
}
#endif // V8_ENABLE_WEBASSEMBLY
return false;
}
inline bool IsPointerConstant(Node* node) {
switch (node->opcode()) {
case IrOpcode::kHeapConstant:
case IrOpcode::kParameter:
case IrOpcode::kLoadImmutable:
return true;
default:
return false;
}
}
bool ObjectMayAlias(Node* a, Node* b) {
if (a != b) {
if (IsFreshObject(b)) std::swap(a, b);
if (IsFreshObject(a) && (IsFreshObject(b) || IsPointerConstant(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;
}
}
......
......@@ -285,6 +285,22 @@ 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()) {
......@@ -340,6 +356,11 @@ 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:
......@@ -1967,6 +1988,11 @@ 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();
}
......
......@@ -581,6 +581,36 @@ 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()) {
Builtins::Name callee =
static_cast<Builtins::Name>(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, and kWasmAllocateRtt may return a cached rtt.
return callee == Builtins::kWasmAllocateArrayWithRtt ||
callee == Builtins::kWasmAllocateStructWithRtt ||
callee == Builtins::kWasmAllocateObjectWrapper ||
callee == Builtins::kWasmAllocatePair;
}
}
#endif // V8_ENABLE_WEBASSEMBLY
return false;
}
// static
bool NodeProperties::IsInputRange(Edge edge, int first, int num) {
......
......@@ -136,6 +136,10 @@ 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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment