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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 10949019: Turn definitions that do not produce results (e.g. Checks) into instructions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/hash_map.h" 10 #include "vm/hash_map.h"
(...skipping 15 matching lines...) Expand all
26 void FlowGraphOptimizer::ApplyICData() { 26 void FlowGraphOptimizer::ApplyICData() {
27 VisitBlocks(); 27 VisitBlocks();
28 } 28 }
29 29
30 30
31 void FlowGraphOptimizer::OptimizeComputations() { 31 void FlowGraphOptimizer::OptimizeComputations() {
32 for (intptr_t i = 0; i < block_order_.length(); ++i) { 32 for (intptr_t i = 0; i < block_order_.length(); ++i) {
33 BlockEntryInstr* entry = block_order_[i]; 33 BlockEntryInstr* entry = block_order_[i];
34 entry->Accept(this); 34 entry->Accept(this);
35 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 35 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
36 Definition* defn = it.Current()->AsDefinition(); 36 Instruction* current = it.Current();
37 if (defn != NULL) { 37 Instruction* replacement = current->Canonicalize();
38 Definition* result = defn->Canonicalize(); 38 if (replacement != current) {
Florian Schneider 2012/09/19 13:24:49 Maybe assert that Canonicalize for Instructions re
Vyacheslav Egorov (Google) 2012/09/21 12:51:40 Done.
39 if (result != defn) { 39 if ((replacement != NULL) && current->IsDefinition()) {
40 if (result != NULL) { 40 Definition* current_defn = current->AsDefinition();
41 defn->ReplaceUsesWith(result); 41 Definition* replacement_defn = replacement->AsDefinition();
42 if (FLAG_trace_optimization) { 42 ASSERT(replacement_defn != NULL);
43 OS::Print("Replacing v%"Pd" with v%"Pd"\n", 43 current_defn->ReplaceUsesWith(replacement_defn);
44 defn->ssa_temp_index(), 44 if (FLAG_trace_optimization) {
45 result->ssa_temp_index()); 45 OS::Print("Replacing v%"Pd" with v%"Pd"\n",
46 } 46 current_defn->ssa_temp_index(),
47 } else if (FLAG_trace_optimization) { 47 replacement_defn->ssa_temp_index());
48 OS::Print("Removing v%"Pd".\n", defn->ssa_temp_index());
49 } 48 }
50 it.RemoveCurrentFromGraph(); 49 } else if (FLAG_trace_optimization) {
50 ASSERT(!current->IsDefinition() ||
51 ((current->AsDefinition()->input_use_list() == NULL) &&
52 (current->AsDefinition()->env_use_list() == NULL)));
53 if (current->IsDefinition()) {
54 OS::Print("Removing v%"Pd".\n",
55 current->AsDefinition()->ssa_temp_index());
56 } else {
57 OS::Print("Removing %s\n", current->DebugName());
58 }
51 } 59 }
60 it.RemoveCurrentFromGraph();
52 } 61 }
53 } 62 }
54 } 63 }
55 } 64 }
56 65
57 66
58 static Definition* CreateConversion(Representation from, 67 static Definition* CreateConversion(Representation from,
59 Representation to, 68 Representation to,
60 Definition* def, 69 Definition* def,
61 Instruction* deopt_target) { 70 Instruction* deopt_target) {
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 call->ReplaceWith(array_op, current_iterator()); 416 call->ReplaceWith(array_op, current_iterator());
408 RemovePushArguments(call); 417 RemovePushArguments(call);
409 return true; 418 return true;
410 } 419 }
411 default: 420 default:
412 return false; 421 return false;
413 } 422 }
414 } 423 }
415 424
416 425
417 void FlowGraphOptimizer::InsertBefore(Instruction* instr, 426 void FlowGraphOptimizer::InsertBefore(Instruction* next,
418 Definition* defn, 427 Instruction* instr,
419 Environment* env, 428 Environment* env,
420 Definition::UseKind use_kind) { 429 Definition::UseKind use_kind) {
421 if (env != NULL) env->DeepCopyTo(defn); 430 if (env != NULL) env->DeepCopyTo(instr);
422 if (use_kind == Definition::kValue) { 431 if (use_kind == Definition::kValue) {
423 defn->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); 432 ASSERT(instr->IsDefinition());
433 instr->AsDefinition()->set_ssa_temp_index(
434 flow_graph_->alloc_ssa_temp_index());
424 } 435 }
425 defn->InsertBefore(instr); 436 instr->InsertBefore(next);
426 } 437 }
427 438
428 439
429 void FlowGraphOptimizer::InsertAfter(Instruction* instr, 440 void FlowGraphOptimizer::InsertAfter(Instruction* prev,
430 Definition* defn, 441 Instruction* instr,
431 Environment* env, 442 Environment* env,
432 Definition::UseKind use_kind) { 443 Definition::UseKind use_kind) {
433 if (env != NULL) env->DeepCopyTo(defn); 444 if (env != NULL) env->DeepCopyTo(instr);
434 if (use_kind == Definition::kValue) { 445 if (use_kind == Definition::kValue) {
435 defn->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); 446 ASSERT(instr->IsDefinition());
447 instr->AsDefinition()->set_ssa_temp_index(
448 flow_graph_->alloc_ssa_temp_index());
436 } 449 }
437 defn->InsertAfter(instr); 450 instr->InsertAfter(prev);
438 } 451 }
439 452
440 453
441 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call, 454 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call,
442 Token::Kind op_kind) { 455 Token::Kind op_kind) {
443 intptr_t operands_type = kIllegalCid; 456 intptr_t operands_type = kIllegalCid;
444 ASSERT(call->HasICData()); 457 ASSERT(call->HasICData());
445 const ICData& ic_data = *call->ic_data(); 458 const ICData& ic_data = *call->ic_data();
446 switch (op_kind) { 459 switch (op_kind) {
447 case Token::kADD: 460 case Token::kADD:
(...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 if (header->dominator() == candidate) { 1437 if (header->dominator() == candidate) {
1425 return candidate; 1438 return candidate;
1426 } 1439 }
1427 } 1440 }
1428 return NULL; 1441 return NULL;
1429 } 1442 }
1430 1443
1431 1444
1432 void LICM::Hoist(ForwardInstructionIterator* it, 1445 void LICM::Hoist(ForwardInstructionIterator* it,
1433 BlockEntryInstr* pre_header, 1446 BlockEntryInstr* pre_header,
1434 Definition* current) { 1447 Instruction* current) {
1435 // TODO(fschneider): Avoid repeated deoptimization when 1448 // TODO(fschneider): Avoid repeated deoptimization when
1436 // speculatively hoisting checks. 1449 // speculatively hoisting checks.
1437 if (FLAG_trace_optimization) { 1450 if (FLAG_trace_optimization) {
1438 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n", 1451 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n",
1439 current->DebugName(), 1452 current->DebugName(),
1440 current->deopt_id(), 1453 current->deopt_id(),
1441 current->GetBlock()->block_id(), 1454 current->GetBlock()->block_id(),
1442 pre_header->block_id()); 1455 pre_header->block_id());
1443 } 1456 }
1444 // Move the instruction out of the loop. 1457 // Move the instruction out of the loop.
1445 it->RemoveCurrentFromGraph(); 1458 it->RemoveCurrentFromGraph();
1446 GotoInstr* last = pre_header->last_instruction()->AsGoto(); 1459 GotoInstr* last = pre_header->last_instruction()->AsGoto();
1447 current->InsertBefore(last); 1460 current->InsertBefore(last);
1448 // Attach the environment of the Goto instruction to the hoisted 1461 // Attach the environment of the Goto instruction to the hoisted
1449 // instruction and set the correct deopt_id. 1462 // instruction and set the correct deopt_id.
1450 ASSERT(last->env() != NULL); 1463 ASSERT(last->env() != NULL);
1451 last->env()->DeepCopyTo(current); 1464 last->env()->DeepCopyTo(current);
1452 current->deopt_id_ = last->GetDeoptId(); 1465 current->deopt_id_ = last->GetDeoptId();
1453 } 1466 }
1454 1467
1455 1468
1456 void LICM::TryHoistCheckSmiThroughPhi(ForwardInstructionIterator* it, 1469 void LICM::TryHoistCheckSmiThroughPhi(ForwardInstructionIterator* it,
1457 BlockEntryInstr* header, 1470 BlockEntryInstr* header,
1458 BlockEntryInstr* pre_header, 1471 BlockEntryInstr* pre_header,
1459 Definition* current) { 1472 Instruction* current) {
1460 PhiInstr* phi = current->InputAt(0)->definition()->AsPhi(); 1473 PhiInstr* phi = current->InputAt(0)->definition()->AsPhi();
1461 if (!header->loop_info()->Contains(phi->block()->preorder_number())) { 1474 if (!header->loop_info()->Contains(phi->block()->preorder_number())) {
1462 return; 1475 return;
1463 } 1476 }
1464 1477
1465 if (phi->GetPropagatedCid() == kSmiCid) { 1478 if (phi->GetPropagatedCid() == kSmiCid) {
1466 it->RemoveCurrentFromGraph(); 1479 it->RemoveCurrentFromGraph();
1467 return; 1480 return;
1468 } 1481 }
1469 1482
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 BlockEntryInstr* pre_header = FindPreHeader(header); 1519 BlockEntryInstr* pre_header = FindPreHeader(header);
1507 if (pre_header == NULL) continue; 1520 if (pre_header == NULL) continue;
1508 1521
1509 for (BitVector::Iterator loop_it(header->loop_info()); 1522 for (BitVector::Iterator loop_it(header->loop_info());
1510 !loop_it.Done(); 1523 !loop_it.Done();
1511 loop_it.Advance()) { 1524 loop_it.Advance()) {
1512 BlockEntryInstr* block = flow_graph->preorder()[loop_it.Current()]; 1525 BlockEntryInstr* block = flow_graph->preorder()[loop_it.Current()];
1513 for (ForwardInstructionIterator it(block); 1526 for (ForwardInstructionIterator it(block);
1514 !it.Done(); 1527 !it.Done();
1515 it.Advance()) { 1528 it.Advance()) {
1516 Definition* current = it.Current()->AsDefinition(); 1529 Instruction* current = it.Current();
1517 if (current != NULL && 1530 if (!current->IsPushArgument() && !current->AffectedBySideEffect()) {
1518 !current->IsPushArgument() &&
1519 !current->AffectedBySideEffect()) {
1520 bool inputs_loop_invariant = true; 1531 bool inputs_loop_invariant = true;
1521 for (int i = 0; i < current->InputCount(); ++i) { 1532 for (int i = 0; i < current->InputCount(); ++i) {
1522 Definition* input_def = current->InputAt(i)->definition(); 1533 Definition* input_def = current->InputAt(i)->definition();
1523 if (!input_def->GetBlock()->Dominates(pre_header)) { 1534 if (!input_def->GetBlock()->Dominates(pre_header)) {
1524 inputs_loop_invariant = false; 1535 inputs_loop_invariant = false;
1525 break; 1536 break;
1526 } 1537 }
1527 } 1538 }
1528 if (inputs_loop_invariant) { 1539 if (inputs_loop_invariant) {
1529 Hoist(&it, pre_header, current); 1540 Hoist(&it, pre_header, current);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 1740
1730 GrowableArray<Definition*> definitions(max_expr_id); 1741 GrowableArray<Definition*> definitions(max_expr_id);
1731 for (intptr_t j = 0; j < max_expr_id ; j++) { 1742 for (intptr_t j = 0; j < max_expr_id ; j++) {
1732 definitions.Add(NULL); 1743 definitions.Add(NULL);
1733 } 1744 }
1734 1745
1735 OptimizeLoads(graph->graph_entry(), &definitions, avail_in); 1746 OptimizeLoads(graph->graph_entry(), &definitions, avail_in);
1736 } 1747 }
1737 } 1748 }
1738 1749
1739 DirectChainedHashMap<Definition*> map; 1750 DirectChainedHashMap<Instruction*> map;
1740 OptimizeRecursive(graph->graph_entry(), &map); 1751 OptimizeRecursive(graph->graph_entry(), &map);
1741 } 1752 }
1742 1753
1743 1754
1744 void DominatorBasedCSE::OptimizeRecursive( 1755 void DominatorBasedCSE::OptimizeRecursive(
1745 BlockEntryInstr* block, 1756 BlockEntryInstr* block,
1746 DirectChainedHashMap<Definition*>* map) { 1757 DirectChainedHashMap<Instruction*>* map) {
1747 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 1758 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
1748 Definition* defn = it.Current()->AsDefinition(); 1759 Instruction* current = it.Current();
1749 if ((defn == NULL) || defn->AffectedBySideEffect()) continue; 1760 if (current->AffectedBySideEffect()) continue;
1750 Definition* result = map->Lookup(defn); 1761 Instruction* replacement = map->Lookup(current);
1751 if (result == NULL) { 1762 if (replacement == NULL) {
1752 map->Insert(defn); 1763 map->Insert(current);
1753 continue; 1764 continue;
1754 } 1765 }
1755 // Replace current with lookup result. 1766 // Replace current with lookup result.
1756 defn->ReplaceUsesWith(result); 1767 if (current->IsDefinition()) {
1768 ASSERT(replacement->IsDefinition());
1769 current->AsDefinition()->ReplaceUsesWith(replacement->AsDefinition());
1770 if (FLAG_trace_optimization) {
1771 OS::Print("Replacing v%"Pd" with v%"Pd"\n",
1772 current->AsDefinition()->ssa_temp_index(),
1773 replacement->AsDefinition()->ssa_temp_index());
1774 }
1775 }
Florian Schneider 2012/09/19 13:24:49 Maybe add the same debug output as in the Canonica
Vyacheslav Egorov (Google) 2012/09/21 12:51:40 Done.
1757 it.RemoveCurrentFromGraph(); 1776 it.RemoveCurrentFromGraph();
1758 if (FLAG_trace_optimization) {
1759 OS::Print("Replacing v%"Pd" with v%"Pd"\n",
1760 defn->ssa_temp_index(),
1761 result->ssa_temp_index());
1762 }
1763 } 1777 }
1764 1778
1765 // Process children in the dominator tree recursively. 1779 // Process children in the dominator tree recursively.
1766 intptr_t num_children = block->dominated_blocks().length(); 1780 intptr_t num_children = block->dominated_blocks().length();
1767 for (intptr_t i = 0; i < num_children; ++i) { 1781 for (intptr_t i = 0; i < num_children; ++i) {
1768 BlockEntryInstr* child = block->dominated_blocks()[i]; 1782 BlockEntryInstr* child = block->dominated_blocks()[i];
1769 if (i < num_children - 1) { 1783 if (i < num_children - 1) {
1770 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. 1784 DirectChainedHashMap<Instruction*> child_map(*map); // Copy map.
1771 OptimizeRecursive(child, &child_map); 1785 OptimizeRecursive(child, &child_map);
1772 } else { 1786 } else {
1773 OptimizeRecursive(child, map); // Reuse map for the last child. 1787 OptimizeRecursive(child, map); // Reuse map for the last child.
1774 } 1788 }
1775 } 1789 }
1776 } 1790 }
1777 1791
1778 1792
1779 } // namespace dart 1793 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698