Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Unified Diff: src/compiler/ast-graph-builder.cc

Issue 1128193005: [turbofan] Use FrameStatesBeforeAndAfter to simplify handling of before/after frame states in AstGr… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 9a751a0952ec115d9147ebc63a3c429601ce08f6..8bf9312aa75c25d6b34b00f6a90e3f0a5a88bfa6 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -384,6 +384,48 @@ class AstGraphBuilder::ControlScopeForFinally : public ControlScope {
};
+// Helper for generating before and after frame states.
+class AstGraphBuilder::FrameStateBeforeAndAfter {
+ public:
+ FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before)
+ : builder_(builder), frame_state_before_(nullptr) {
+ frame_state_before_ = id_before == BailoutId::None()
+ ? builder_->jsgraph()->EmptyFrameState()
+ : builder_->environment()->Checkpoint(id_before);
+ }
+
+ void AddToNode(Node* node, BailoutId id_after,
+ OutputFrameStateCombine combine) {
+ int count = OperatorProperties::GetFrameStateInputCount(node->op());
+ DCHECK_LE(count, 2);
+
+ if (count >= 1) {
+ // Add the frame state for after the operation.
+ DCHECK_EQ(IrOpcode::kDead,
+ NodeProperties::GetFrameStateInput(node, 0)->opcode());
+
+ Node* frame_state_after =
+ id_after == BailoutId::None()
+ ? builder_->jsgraph()->EmptyFrameState()
+ : builder_->environment()->Checkpoint(id_after, combine);
+
+ NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
+ }
+
+ if (count >= 2) {
+ // Add the frame state for before the operation.
+ DCHECK_EQ(IrOpcode::kDead,
+ NodeProperties::GetFrameStateInput(node, 1)->opcode());
+ NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
+ }
+ }
+
+ private:
+ AstGraphBuilder* builder_;
+ Node* frame_state_before_;
+};
+
+
AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
JSGraph* jsgraph, LoopAssignmentAnalysis* loop,
JSTypeFeedbackTable* js_type_feedback)
@@ -1304,14 +1346,15 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
is_property_missing.If(property_missing);
is_property_missing.Then();
// Inc counter and continue.
- Node* index_inc =
- NewNode(javascript()->Add(LanguageMode::SLOPPY), index,
- jsgraph()->OneConstant());
- // TODO(jarin): provide real bailout id.
- PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(),
- OutputFrameStateCombine::Ignore(),
- jsgraph()->EmptyFrameState());
- environment()->Poke(0, index_inc);
+ {
+ // TODO(jarin): provide real bailout id.
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
+ Node* index_inc = NewNode(javascript()->Add(LanguageMode::SLOPPY),
+ index, jsgraph()->OneConstant());
+ states.AddToNode(index_inc, BailoutId::None(),
+ OutputFrameStateCombine::Ignore());
+ environment()->Poke(0, index_inc);
+ }
for_loop.Continue();
is_property_missing.Else();
is_property_missing.End();
@@ -1332,10 +1375,12 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
Node* index_inc =
NewNode(javascript()->Add(LanguageMode::SLOPPY), index,
jsgraph()->OneConstant());
- // TODO(jarin): provide real bailout id.
- PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(),
- OutputFrameStateCombine::Ignore(),
- jsgraph()->EmptyFrameState());
+ {
+ // TODO(jarin): provide real bailout ids.
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
+ states.AddToNode(index_inc, BailoutId::None(),
+ OutputFrameStateCombine::Ignore());
+ }
environment()->Poke(0, index_inc);
for_loop.EndLoop();
environment()->Drop(5);
@@ -1870,15 +1915,15 @@ void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
VisitForValue(subexpr);
- Node* frame_state_before = environment()->Checkpoint(
- subexpr->id(), OutputFrameStateCombine::PokeAt(0));
- Node* value = environment()->Pop();
- Node* index = jsgraph()->Constant(i);
- Node* store =
- BuildKeyedStore(literal, index, value, TypeFeedbackId::None());
- PrepareFrameStateAfterAndBefore(store, expr->GetIdForElement(i),
- OutputFrameStateCombine::Ignore(),
- frame_state_before);
+ {
+ FrameStateBeforeAndAfter states(this, subexpr->id());
+ Node* value = environment()->Pop();
+ Node* index = jsgraph()->Constant(i);
+ Node* store =
+ BuildKeyedStore(literal, index, value, TypeFeedbackId::None());
+ states.AddToNode(store, expr->GetIdForElement(i),
+ OutputFrameStateCombine::Ignore());
+ }
}
environment()->Pop(); // Array literal index.
@@ -1916,14 +1961,16 @@ void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
environment()->Push(value);
VisitForValue(property->obj());
VisitForValue(property->key());
- Node* key = environment()->Pop();
- Node* object = environment()->Pop();
- value = environment()->Pop();
- Node* store = BuildKeyedStore(object, key, value, TypeFeedbackId::None());
- // TODO(jarin) Provide a real frame state before.
- PrepareFrameStateAfterAndBefore(store, bailout_id,
- OutputFrameStateCombine::Ignore(),
- jsgraph()->EmptyFrameState());
+ {
+ // TODO(jarin) Provide a real frame state before.
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
+ Node* key = environment()->Pop();
+ Node* object = environment()->Pop();
+ value = environment()->Pop();
+ Node* store =
+ BuildKeyedStore(object, key, value, TypeFeedbackId::None());
+ states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
+ }
break;
}
}
@@ -1936,12 +1983,19 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
// Left-hand side can only be a property, a global or a variable slot.
Property* property = expr->target()->AsProperty();
LhsKind assign_type = DetermineLhsKind(expr->target());
+ bool needs_frame_state_before = true;
// Evaluate LHS expression.
switch (assign_type) {
- case VARIABLE:
- // Nothing to do here.
+ case VARIABLE: {
+ Variable* variable = expr->target()->AsVariableProxy()->var();
+ if (variable->location() == Variable::PARAMETER ||
+ variable->location() == Variable::LOCAL ||
+ variable->location() == Variable::CONTEXT) {
+ needs_frame_state_before = false;
+ }
break;
+ }
case NAMED_PROPERTY:
VisitForValue(property->obj());
break;
@@ -1952,10 +2006,9 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
}
}
+ BailoutId before_store_id = BailoutId::None();
// Evaluate the value and potentially handle compound assignments by loading
// the left-hand side value and performing a binary operation.
- Node* frame_state_before_store = nullptr;
- bool needs_frame_state_before = (assign_type == KEYED_PROPERTY);
if (expr->is_compound()) {
Node* old_value = NULL;
switch (assign_type) {
@@ -1991,31 +2044,27 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
}
environment()->Push(old_value);
VisitForValue(expr->value());
- Node* frame_state_before = environment()->Checkpoint(expr->value()->id());
- Node* right = environment()->Pop();
- Node* left = environment()->Pop();
- Node* value = BuildBinaryOp(left, right, expr->binary_op());
- PrepareFrameStateAfterAndBefore(value, expr->binary_operation()->id(),
- OutputFrameStateCombine::Push(),
- frame_state_before);
+ Node* value;
+ {
+ FrameStateBeforeAndAfter states(this, expr->value()->id());
+ Node* right = environment()->Pop();
+ Node* left = environment()->Pop();
+ value = BuildBinaryOp(left, right, expr->binary_op());
+ states.AddToNode(value, expr->binary_operation()->id(),
+ OutputFrameStateCombine::Push());
+ }
environment()->Push(value);
if (needs_frame_state_before) {
- frame_state_before_store = environment()->Checkpoint(
- expr->binary_operation()->id(), OutputFrameStateCombine::PokeAt(0));
+ before_store_id = expr->binary_operation()->id();
}
} else {
VisitForValue(expr->value());
if (needs_frame_state_before) {
- // This frame state can be used for lazy-deopting from a to-number
- // conversion if we are storing into a typed array. It is important
- // that the frame state is usable for such lazy deopt (i.e., it has
- // to specify how to override the value before the conversion, in this
- // case, it overwrites the stack top).
- frame_state_before_store = environment()->Checkpoint(
- expr->value()->id(), OutputFrameStateCombine::PokeAt(0));
+ before_store_id = expr->value()->id();
}
}
+ FrameStateBeforeAndAfter store_states(this, before_store_id);
// Store the value.
Node* value = environment()->Pop();
switch (assign_type) {
@@ -2030,7 +2079,8 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
Node* store =
BuildNamedStore(object, name, value, expr->AssignmentFeedbackId());
- PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine());
+ store_states.AddToNode(store, expr->id(),
+ ast_context()->GetStateCombine());
break;
}
case KEYED_PROPERTY: {
@@ -2038,9 +2088,8 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
Node* object = environment()->Pop();
Node* store =
BuildKeyedStore(object, key, value, expr->AssignmentFeedbackId());
- PrepareFrameStateAfterAndBefore(store, expr->id(),
- ast_context()->GetStateCombine(),
- frame_state_before_store);
+ store_states.AddToNode(store, expr->id(),
+ ast_context()->GetStateCombine());
break;
}
}
@@ -2362,22 +2411,25 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
PrepareFrameState(old_value, expr->ToNumberId(),
OutputFrameStateCombine::Push());
- Node* frame_state_before_store =
- assign_type == KEYED_PROPERTY
- ? environment()->Checkpoint(expr->ToNumberId())
- : nullptr;
+ // TODO(titzer): combine this framestate with the above?
+ FrameStateBeforeAndAfter store_states(this, assign_type == KEYED_PROPERTY
+ ? expr->ToNumberId()
+ : BailoutId::None());
// Save result for postfix expressions at correct stack depth.
if (is_postfix) environment()->Poke(stack_depth, old_value);
// Create node to perform +1/-1 operation.
- Node* value =
- BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
- // This should never deoptimize because we have converted to number
- // before.
- PrepareFrameStateAfterAndBefore(value, BailoutId::None(),
- OutputFrameStateCombine::Ignore(),
- jsgraph()->EmptyFrameState());
+ Node* value;
+ {
+ FrameStateBeforeAndAfter states(this, BailoutId::None());
+ value =
+ BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
+ // This should never deoptimize because we have converted to number
+ // before.
+ states.AddToNode(value, BailoutId::None(),
+ OutputFrameStateCombine::Ignore());
+ }
// Store the value.
switch (assign_type) {
@@ -2405,9 +2457,8 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
Node* store =
BuildKeyedStore(object, key, value, expr->CountStoreFeedbackId());
environment()->Push(value);
- PrepareFrameStateAfterAndBefore(store, expr->AssignmentId(),
- OutputFrameStateCombine::Ignore(),
- frame_state_before_store);
+ store_states.AddToNode(store, expr->AssignmentId(),
+ OutputFrameStateCombine::Ignore());
environment()->Pop();
break;
}
@@ -2430,13 +2481,11 @@ void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
default: {
VisitForValue(expr->left());
VisitForValue(expr->right());
- Node* frame_state_before = environment()->Checkpoint(expr->right()->id());
+ FrameStateBeforeAndAfter states(this, expr->right()->id());
Node* right = environment()->Pop();
Node* left = environment()->Pop();
Node* value = BuildBinaryOp(left, right, expr->op());
- PrepareFrameStateAfterAndBefore(value, expr->id(),
- ast_context()->GetStateCombine(),
- frame_state_before);
+ states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
ast_context()->ProduceValue(value);
}
}
@@ -3297,24 +3346,6 @@ void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
}
-void AstGraphBuilder::PrepareFrameStateAfterAndBefore(
- Node* node, BailoutId ast_id, OutputFrameStateCombine combine,
- Node* frame_state_before) {
- if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
- DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op()));
-
- DCHECK_EQ(IrOpcode::kDead,
- NodeProperties::GetFrameStateInput(node, 0)->opcode());
- NodeProperties::ReplaceFrameStateInput(
- node, 0, environment()->Checkpoint(ast_id, combine));
-
- DCHECK_EQ(IrOpcode::kDead,
- NodeProperties::GetFrameStateInput(node, 1)->opcode());
- NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before);
- }
-}
-
-
BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
IterationStatement* stmt) {
if (loop_assignment_analysis_ == NULL) return NULL;
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698