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

Unified Diff: runtime/vm/parser.cc

Issue 10272031: Merge two functions that create sideffect free compound load nodes. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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 | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 7191)
+++ runtime/vm/parser.cc (working copy)
@@ -5902,58 +5902,6 @@
}
-// If 'node' can create side effects, store its result in a temporary variable
-// and return a LoadLocalNode instead.
-// Side effect free nodes are LoadLocalNode and LiteralNode.
-AstNode* Parser::AsSideEffectFreeNode(AstNode* node) {
- if (node->IsLoadIndexedNode()) {
- LoadIndexedNode* load_indexed = node->AsLoadIndexedNode();
- intptr_t token_id = node->id();
- intptr_t token_index = node->token_index();
- node = NULL; // Do not use it.
- // The array object access may not have side effects.
- // First, evaluate the array object expression if it might have side
- // effects.
- if (!IsLocalOrLiteralNode(load_indexed->array())) {
- LocalVariable* temp =
- CreateTempConstVariable(token_index, token_id, "lia");
- AstNode* save =
- new StoreLocalNode(token_index, *temp, load_indexed->array());
- load_indexed = new LoadIndexedNode(token_index,
- save,
- load_indexed->index_expr());
- }
- // Second, evaluate the index expression and store in a temporary
- // variable if it might have side effects.
- if (!IsLocalOrLiteralNode(load_indexed->index_expr())) {
- LocalVariable* temp =
- CreateTempConstVariable(token_index, token_id, "lix");
- AstNode* save =
- new StoreLocalNode(token_index, *temp, load_indexed->index_expr());
- load_indexed = new LoadIndexedNode(token_index,
- load_indexed->array(),
- save);
- }
- return load_indexed;
- }
- if (node->IsInstanceGetterNode()) {
- InstanceGetterNode* getter = node->AsInstanceGetterNode();
- intptr_t token_index = node->token_index();
- intptr_t token_id = node->id();
- node = NULL; // Do not use it.
- if (!IsLocalOrLiteralNode(getter->receiver())) {
- LocalVariable* temp =
- CreateTempConstVariable(token_index, token_id, "igr");
- AstNode* save =
- new StoreLocalNode(token_index, *temp, getter->receiver());
- getter = new InstanceGetterNode(token_index, save, getter->field_name());
- }
- return getter;
- }
- return node;
-}
-
-
// TODO(srdjan): Implement other optimizations.
AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos,
Token::Kind binary_op,
@@ -6033,43 +5981,66 @@
// A compound assignment consists of a store and a load part. In order
// to control inputs with potential side effects, the store part stores any
-// side effect creating inputs into locals.
-// Here we convert the inputs if the load local from the StoreLocals to
-// LoadLocals.
-static AstNode* ModifyCompoundAssignmentLoad(AstNode* node) {
+// side effect creating inputs into locals. The load part reads then from
+// those locals. If expr may have side effects, it will be split into two new
+// left and right nodes. 'expr' becomes the right node, left node is returned as
+// result.
+AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) {
+ AstNode* node = *expr;
if (node->IsLoadIndexedNode()) {
- LoadIndexedNode* load_indexed = node->AsLoadIndexedNode();
- if (load_indexed->array()->IsStoreLocalNode()) {
- StoreLocalNode* store = load_indexed->array()->AsStoreLocalNode();
- LoadLocalNode* load = new LoadLocalNode(store->token_index(),
- store->local());
- load_indexed = new LoadIndexedNode(load_indexed->token_index(),
- load,
- load_indexed->index_expr());
+ LoadIndexedNode* left_node = node->AsLoadIndexedNode();
+ LoadIndexedNode* right_node = left_node;
+ intptr_t node_id = node->id();
+ intptr_t token_index = node->token_index();
+ node = NULL; // Do not use it.
+ if (!IsLocalOrLiteralNode(left_node->array())) {
+ LocalVariable* temp =
+ CreateTempConstVariable(token_index, node_id, "lia");
+ StoreLocalNode* save =
+ new StoreLocalNode(token_index, *temp, left_node->array());
+ left_node =
+ new LoadIndexedNode(token_index, save, left_node->index_expr());
+ right_node = new LoadIndexedNode(token_index,
+ new LoadLocalNode(token_index, *temp),
+ right_node->index_expr());
}
- if (load_indexed->index_expr()->IsStoreLocalNode()) {
- StoreLocalNode* store = load_indexed->index_expr()->AsStoreLocalNode();
- LoadLocalNode* load = new LoadLocalNode(store->token_index(),
- store->local());
- load_indexed = new LoadIndexedNode(load_indexed->token_index(),
- load_indexed->array(),
- load);
+ if (!IsLocalOrLiteralNode(left_node->index_expr())) {
+ LocalVariable* temp =
+ CreateTempConstVariable(token_index, node_id, "lix");
+ StoreLocalNode* save =
+ new StoreLocalNode(token_index, *temp, left_node->index_expr());
+ left_node = new LoadIndexedNode(token_index,
+ left_node->array(),
+ save);
+ right_node = new LoadIndexedNode(token_index,
+ right_node->array(),
+ new LoadLocalNode(token_index, *temp));
}
- return load_indexed;
+ *expr = right_node;
+ return left_node;
}
if (node->IsInstanceGetterNode()) {
- InstanceGetterNode* getter = node->AsInstanceGetterNode();
- if (getter->receiver()->IsStoreLocalNode()) {
- StoreLocalNode* store = getter->receiver()->AsStoreLocalNode();
- LoadLocalNode* load = new LoadLocalNode(store->token_index(),
- store->local());
- getter = new InstanceGetterNode(getter->token_index(),
- load,
- getter->field_name());
+ InstanceGetterNode* left_node = node->AsInstanceGetterNode();
+ InstanceGetterNode* right_node = left_node;
+ intptr_t node_id = node->id();
+ intptr_t token_index = node->token_index();
+ node = NULL; // Do not use it.
+ if (!IsLocalOrLiteralNode(left_node->receiver())) {
+ LocalVariable* temp =
+ CreateTempConstVariable(token_index, node_id, "igr");
+ StoreLocalNode* save =
+ new StoreLocalNode(token_index, *temp, left_node->receiver());
+ left_node = new InstanceGetterNode(token_index,
+ save,
+ left_node->field_name());
+ right_node = new InstanceGetterNode(token_index,
+ new LoadLocalNode(token_index, *temp),
+ right_node->field_name());
}
- return getter;
+ *expr = right_node;
+ return left_node;
}
- return node;
+ return *expr;
}
@@ -6095,8 +6066,7 @@
AstNode* left_expr = expr;
if (assignment_op != Token::kASSIGN) {
// Compound assignment: store inputs with side effects into temp. locals.
- left_expr = AsSideEffectFreeNode(expr);
- expr = ModifyCompoundAssignmentLoad(left_expr);
+ left_expr = PrepareCompoundAssignmentNodes(&expr);
}
right_expr =
ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
@@ -6333,8 +6303,7 @@
AstNode* left_load_access = load_access;
if (assignment_op != Token::kASSIGN) {
// Compound assignment: store inputs with side effects into temp. locals.
- left_load_access = AsSideEffectFreeNode(load_access);
- load_access = ModifyCompoundAssignmentLoad(left_load_access);
+ left_load_access = PrepareCompoundAssignmentNodes(&load_access);
}
value = ExpandAssignableOp(call_pos, assignment_op, load_access, value);
access = left_load_access->MakeAssignmentNode(value);
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698