[turbofan] Move global constant optimization to AstGraphBuilder.
Optimizing global constants such as "NaN", "Infinity" and "undefined" is best performed during graph building. Then the optimization and lowering passes only need to deal with real loads in case of JSLoadGlobal. R=mstarzinger@chromium.org BUG=v8:4470 LOG=n Review URL: https://codereview.chromium.org/1384953002 Cr-Commit-Position: refs/heads/master@{#31135}
This commit is contained in:
parent
785516821d
commit
74ae226b94
@ -3289,6 +3289,13 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
|
||||
case VariableLocation::GLOBAL:
|
||||
case VariableLocation::UNALLOCATED: {
|
||||
// Global var, const, or let variable.
|
||||
Handle<Name> name = variable->name();
|
||||
Handle<Object> constant_value =
|
||||
jsgraph()->isolate()->factory()->GlobalConstantFor(name);
|
||||
if (!constant_value.is_null()) {
|
||||
// Optimize global constants like "undefined", "Infinity", and "NaN".
|
||||
return jsgraph()->Constant(constant_value);
|
||||
}
|
||||
Node* script_context = current_context();
|
||||
int slot_index = -1;
|
||||
if (variable->index() > 0) {
|
||||
@ -3302,7 +3309,6 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
|
||||
}
|
||||
}
|
||||
Node* global = BuildLoadGlobalObject();
|
||||
Handle<Name> name = variable->name();
|
||||
Node* value = BuildGlobalLoad(script_context, global, name, feedback,
|
||||
typeof_mode, slot_index);
|
||||
states.AddToNode(value, bailout_id, combine);
|
||||
|
@ -191,16 +191,6 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadGlobal(Node* node) {
|
||||
DCHECK(node->opcode() == IrOpcode::kJSLoadGlobal);
|
||||
Handle<String> name =
|
||||
Handle<String>::cast(LoadGlobalParametersOf(node->op()).name());
|
||||
// Try to optimize loads from the global object.
|
||||
Handle<Object> constant_value =
|
||||
jsgraph()->isolate()->factory()->GlobalConstantFor(name);
|
||||
if (!constant_value.is_null()) {
|
||||
// Always optimize global constants.
|
||||
Node* constant = jsgraph()->Constant(constant_value);
|
||||
ReplaceWithValue(node, constant);
|
||||
return Replace(constant);
|
||||
}
|
||||
|
||||
if (global_object_.is_null()) {
|
||||
// Nothing else can be done if we don't have a global object.
|
||||
return NoChange();
|
||||
|
@ -815,19 +815,6 @@ Reduction JSTypedLowering::ReduceJSToString(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSLoadGlobal(Node* node) {
|
||||
// Optimize global constants like "undefined", "Infinity", and "NaN".
|
||||
Handle<Name> name = LoadGlobalParametersOf(node->op()).name();
|
||||
Handle<Object> constant_value = factory()->GlobalConstantFor(name);
|
||||
if (!constant_value.is_null()) {
|
||||
Node* constant = jsgraph()->Constant(constant_value);
|
||||
ReplaceWithValue(node, constant);
|
||||
return Replace(constant);
|
||||
}
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) {
|
||||
DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
|
||||
Node* receiver = NodeProperties::GetValueInput(node, 0);
|
||||
@ -1772,8 +1759,6 @@ Reduction JSTypedLowering::Reduce(Node* node) {
|
||||
return ReduceJSToNumber(node);
|
||||
case IrOpcode::kJSToString:
|
||||
return ReduceJSToString(node);
|
||||
case IrOpcode::kJSLoadGlobal:
|
||||
return ReduceJSLoadGlobal(node);
|
||||
case IrOpcode::kJSLoadNamed:
|
||||
return ReduceJSLoadNamed(node);
|
||||
case IrOpcode::kJSLoadProperty:
|
||||
|
@ -41,7 +41,6 @@ class JSTypedLowering final : public AdvancedReducer {
|
||||
Reduction ReduceJSBitwiseOr(Node* node);
|
||||
Reduction ReduceJSMultiply(Node* node);
|
||||
Reduction ReduceJSComparison(Node* node);
|
||||
Reduction ReduceJSLoadGlobal(Node* node);
|
||||
Reduction ReduceJSLoadNamed(Node* node);
|
||||
Reduction ReduceJSLoadProperty(Node* node);
|
||||
Reduction ReduceJSStoreProperty(Node* node);
|
||||
|
@ -861,41 +861,6 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// JSLoadGlobal
|
||||
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSLoadGlobalConstants) {
|
||||
Handle<String> names[] = {
|
||||
Handle<String>(isolate()->heap()->undefined_string(), isolate()),
|
||||
Handle<String>(isolate()->heap()->infinity_string(), isolate()),
|
||||
Handle<String>(isolate()->heap()->nan_string(), isolate()) // --
|
||||
};
|
||||
Matcher<Node*> matches[] = {
|
||||
IsHeapConstant(
|
||||
Handle<HeapObject>(isolate()->heap()->undefined_value(), isolate())),
|
||||
IsNumberConstant(std::numeric_limits<double>::infinity()),
|
||||
IsNumberConstant(IsNaN()) // --
|
||||
};
|
||||
|
||||
VectorSlotPair feedback;
|
||||
Node* global = UndefinedConstant();
|
||||
Node* vector = UndefinedConstant();
|
||||
Node* context = UndefinedConstant();
|
||||
Node* effect = graph()->start();
|
||||
Node* control = graph()->start();
|
||||
|
||||
for (size_t i = 0; i < arraysize(names); i++) {
|
||||
Reduction r = Reduce(graph()->NewNode(
|
||||
javascript()->LoadGlobal(names[i], feedback), context, global, vector,
|
||||
context, EmptyFrameState(), EmptyFrameState(), effect, control));
|
||||
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), matches[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// JSLoadNamed
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user