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

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: Address Florian's comments 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 10 matching lines...) Expand all
21 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); 21 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details.");
22 DECLARE_FLAG(bool, trace_type_check_elimination); 22 DECLARE_FLAG(bool, trace_type_check_elimination);
23 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis."); 23 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis.");
24 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination."); 24 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
25 25
26 void FlowGraphOptimizer::ApplyICData() { 26 void FlowGraphOptimizer::ApplyICData() {
27 VisitBlocks(); 27 VisitBlocks();
28 } 28 }
29 29
30 30
31 static void ReplaceCurrentInstruction(ForwardInstructionIterator* it,
32 Instruction* current,
33 Instruction* replacement) {
34 if ((replacement != NULL) && current->IsDefinition()) {
35 Definition* current_defn = current->AsDefinition();
36 Definition* replacement_defn = replacement->AsDefinition();
37 ASSERT(replacement_defn != NULL);
38 current_defn->ReplaceUsesWith(replacement_defn);
39
40 if (FLAG_trace_optimization) {
41 OS::Print("Replacing v%"Pd" with v%"Pd"\n",
42 current_defn->ssa_temp_index(),
43 replacement_defn->ssa_temp_index());
44 }
45 } else if (FLAG_trace_optimization) {
46 ASSERT(!current->IsDefinition() ||
47 ((current->AsDefinition()->input_use_list() == NULL) &&
48 (current->AsDefinition()->env_use_list() == NULL)));
49 if (current->IsDefinition()) {
50 OS::Print("Removing v%"Pd".\n",
51 current->AsDefinition()->ssa_temp_index());
52 } else {
53 OS::Print("Removing %s\n", current->DebugName());
54 }
55 }
56 it->RemoveCurrentFromGraph();
57 }
58
59
31 void FlowGraphOptimizer::OptimizeComputations() { 60 void FlowGraphOptimizer::OptimizeComputations() {
32 for (intptr_t i = 0; i < block_order_.length(); ++i) { 61 for (intptr_t i = 0; i < block_order_.length(); ++i) {
33 BlockEntryInstr* entry = block_order_[i]; 62 BlockEntryInstr* entry = block_order_[i];
34 entry->Accept(this); 63 entry->Accept(this);
35 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 64 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
36 Definition* defn = it.Current()->AsDefinition(); 65 Instruction* current = it.Current();
37 if (defn != NULL) { 66 Instruction* replacement = current->Canonicalize();
38 Definition* result = defn->Canonicalize(); 67 if (replacement != current) {
39 if (result != defn) { 68 // For non-definitions Canonicalize should return either NULL or
40 if (result != NULL) { 69 // this.
41 defn->ReplaceUsesWith(result); 70 ASSERT((replacement == NULL) || current->IsDefinition());
42 if (FLAG_trace_optimization) { 71 ReplaceCurrentInstruction(&it, current, replacement);
43 OS::Print("Replacing v%"Pd" with v%"Pd"\n",
44 defn->ssa_temp_index(),
45 result->ssa_temp_index());
46 }
47 } else if (FLAG_trace_optimization) {
48 OS::Print("Removing v%"Pd".\n", defn->ssa_temp_index());
49 }
50 it.RemoveCurrentFromGraph();
51 }
52 } 72 }
53 } 73 }
54 } 74 }
55 } 75 }
56 76
57 77
58 static Definition* CreateConversion(Representation from, 78 static Definition* CreateConversion(Representation from,
59 Representation to, 79 Representation to,
60 Definition* def, 80 Definition* def,
61 Instruction* deopt_target) { 81 Instruction* deopt_target) {
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 call->ReplaceWith(array_op, current_iterator()); 427 call->ReplaceWith(array_op, current_iterator());
408 RemovePushArguments(call); 428 RemovePushArguments(call);
409 return true; 429 return true;
410 } 430 }
411 default: 431 default:
412 return false; 432 return false;
413 } 433 }
414 } 434 }
415 435
416 436
417 void FlowGraphOptimizer::InsertBefore(Instruction* instr, 437 void FlowGraphOptimizer::InsertBefore(Instruction* next,
418 Definition* defn, 438 Instruction* instr,
419 Environment* env, 439 Environment* env,
420 Definition::UseKind use_kind) { 440 Definition::UseKind use_kind) {
421 if (env != NULL) env->DeepCopyTo(defn); 441 if (env != NULL) env->DeepCopyTo(instr);
422 if (use_kind == Definition::kValue) { 442 if (use_kind == Definition::kValue) {
423 defn->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); 443 ASSERT(instr->IsDefinition());
444 instr->AsDefinition()->set_ssa_temp_index(
445 flow_graph_->alloc_ssa_temp_index());
424 } 446 }
425 defn->InsertBefore(instr); 447 instr->InsertBefore(next);
426 } 448 }
427 449
428 450
429 void FlowGraphOptimizer::InsertAfter(Instruction* instr, 451 void FlowGraphOptimizer::InsertAfter(Instruction* prev,
430 Definition* defn, 452 Instruction* instr,
431 Environment* env, 453 Environment* env,
432 Definition::UseKind use_kind) { 454 Definition::UseKind use_kind) {
433 if (env != NULL) env->DeepCopyTo(defn); 455 if (env != NULL) env->DeepCopyTo(instr);
434 if (use_kind == Definition::kValue) { 456 if (use_kind == Definition::kValue) {
435 defn->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); 457 ASSERT(instr->IsDefinition());
458 instr->AsDefinition()->set_ssa_temp_index(
459 flow_graph_->alloc_ssa_temp_index());
436 } 460 }
437 defn->InsertAfter(instr); 461 instr->InsertAfter(prev);
438 } 462 }
439 463
440 464
441 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call, 465 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call,
442 Token::Kind op_kind) { 466 Token::Kind op_kind) {
443 intptr_t operands_type = kIllegalCid; 467 intptr_t operands_type = kIllegalCid;
444 ASSERT(call->HasICData()); 468 ASSERT(call->HasICData());
445 const ICData& ic_data = *call->ic_data(); 469 const ICData& ic_data = *call->ic_data();
446 switch (op_kind) { 470 switch (op_kind) {
447 case Token::kADD: 471 case Token::kADD:
(...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 if (header->dominator() == candidate) { 1448 if (header->dominator() == candidate) {
1425 return candidate; 1449 return candidate;
1426 } 1450 }
1427 } 1451 }
1428 return NULL; 1452 return NULL;
1429 } 1453 }
1430 1454
1431 1455
1432 void LICM::Hoist(ForwardInstructionIterator* it, 1456 void LICM::Hoist(ForwardInstructionIterator* it,
1433 BlockEntryInstr* pre_header, 1457 BlockEntryInstr* pre_header,
1434 Definition* current) { 1458 Instruction* current) {
1435 // TODO(fschneider): Avoid repeated deoptimization when 1459 // TODO(fschneider): Avoid repeated deoptimization when
1436 // speculatively hoisting checks. 1460 // speculatively hoisting checks.
1437 if (FLAG_trace_optimization) { 1461 if (FLAG_trace_optimization) {
1438 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n", 1462 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n",
1439 current->DebugName(), 1463 current->DebugName(),
1440 current->deopt_id(), 1464 current->deopt_id(),
1441 current->GetBlock()->block_id(), 1465 current->GetBlock()->block_id(),
1442 pre_header->block_id()); 1466 pre_header->block_id());
1443 } 1467 }
1444 // Move the instruction out of the loop. 1468 // Move the instruction out of the loop.
1445 it->RemoveCurrentFromGraph(); 1469 it->RemoveCurrentFromGraph();
1446 GotoInstr* last = pre_header->last_instruction()->AsGoto(); 1470 GotoInstr* last = pre_header->last_instruction()->AsGoto();
1447 current->InsertBefore(last); 1471 current->InsertBefore(last);
1448 // Attach the environment of the Goto instruction to the hoisted 1472 // Attach the environment of the Goto instruction to the hoisted
1449 // instruction and set the correct deopt_id. 1473 // instruction and set the correct deopt_id.
1450 ASSERT(last->env() != NULL); 1474 ASSERT(last->env() != NULL);
1451 last->env()->DeepCopyTo(current); 1475 last->env()->DeepCopyTo(current);
1452 current->deopt_id_ = last->GetDeoptId(); 1476 current->deopt_id_ = last->GetDeoptId();
1453 } 1477 }
1454 1478
1455 1479
1456 void LICM::TryHoistCheckSmiThroughPhi(ForwardInstructionIterator* it, 1480 void LICM::TryHoistCheckSmiThroughPhi(ForwardInstructionIterator* it,
1457 BlockEntryInstr* header, 1481 BlockEntryInstr* header,
1458 BlockEntryInstr* pre_header, 1482 BlockEntryInstr* pre_header,
1459 Definition* current) { 1483 Instruction* current) {
1460 PhiInstr* phi = current->InputAt(0)->definition()->AsPhi(); 1484 PhiInstr* phi = current->InputAt(0)->definition()->AsPhi();
1461 if (!header->loop_info()->Contains(phi->block()->preorder_number())) { 1485 if (!header->loop_info()->Contains(phi->block()->preorder_number())) {
1462 return; 1486 return;
1463 } 1487 }
1464 1488
1465 if (phi->GetPropagatedCid() == kSmiCid) { 1489 if (phi->GetPropagatedCid() == kSmiCid) {
1466 it->RemoveCurrentFromGraph(); 1490 it->RemoveCurrentFromGraph();
1467 return; 1491 return;
1468 } 1492 }
1469 1493
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 BlockEntryInstr* pre_header = FindPreHeader(header); 1530 BlockEntryInstr* pre_header = FindPreHeader(header);
1507 if (pre_header == NULL) continue; 1531 if (pre_header == NULL) continue;
1508 1532
1509 for (BitVector::Iterator loop_it(header->loop_info()); 1533 for (BitVector::Iterator loop_it(header->loop_info());
1510 !loop_it.Done(); 1534 !loop_it.Done();
1511 loop_it.Advance()) { 1535 loop_it.Advance()) {
1512 BlockEntryInstr* block = flow_graph->preorder()[loop_it.Current()]; 1536 BlockEntryInstr* block = flow_graph->preorder()[loop_it.Current()];
1513 for (ForwardInstructionIterator it(block); 1537 for (ForwardInstructionIterator it(block);
1514 !it.Done(); 1538 !it.Done();
1515 it.Advance()) { 1539 it.Advance()) {
1516 Definition* current = it.Current()->AsDefinition(); 1540 Instruction* current = it.Current();
1517 if (current != NULL && 1541 if (!current->IsPushArgument() && !current->AffectedBySideEffect()) {
1518 !current->IsPushArgument() &&
1519 !current->AffectedBySideEffect()) {
1520 bool inputs_loop_invariant = true; 1542 bool inputs_loop_invariant = true;
1521 for (int i = 0; i < current->InputCount(); ++i) { 1543 for (int i = 0; i < current->InputCount(); ++i) {
1522 Definition* input_def = current->InputAt(i)->definition(); 1544 Definition* input_def = current->InputAt(i)->definition();
1523 if (!input_def->GetBlock()->Dominates(pre_header)) { 1545 if (!input_def->GetBlock()->Dominates(pre_header)) {
1524 inputs_loop_invariant = false; 1546 inputs_loop_invariant = false;
1525 break; 1547 break;
1526 } 1548 }
1527 } 1549 }
1528 if (inputs_loop_invariant) { 1550 if (inputs_loop_invariant) {
1529 Hoist(&it, pre_header, current); 1551 Hoist(&it, pre_header, current);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 1751
1730 GrowableArray<Definition*> definitions(max_expr_id); 1752 GrowableArray<Definition*> definitions(max_expr_id);
1731 for (intptr_t j = 0; j < max_expr_id ; j++) { 1753 for (intptr_t j = 0; j < max_expr_id ; j++) {
1732 definitions.Add(NULL); 1754 definitions.Add(NULL);
1733 } 1755 }
1734 1756
1735 OptimizeLoads(graph->graph_entry(), &definitions, avail_in); 1757 OptimizeLoads(graph->graph_entry(), &definitions, avail_in);
1736 } 1758 }
1737 } 1759 }
1738 1760
1739 DirectChainedHashMap<Definition*> map; 1761 DirectChainedHashMap<Instruction*> map;
1740 OptimizeRecursive(graph->graph_entry(), &map); 1762 OptimizeRecursive(graph->graph_entry(), &map);
1741 } 1763 }
1742 1764
1743 1765
1744 void DominatorBasedCSE::OptimizeRecursive( 1766 void DominatorBasedCSE::OptimizeRecursive(
1745 BlockEntryInstr* block, 1767 BlockEntryInstr* block,
1746 DirectChainedHashMap<Definition*>* map) { 1768 DirectChainedHashMap<Instruction*>* map) {
1747 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 1769 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
1748 Definition* defn = it.Current()->AsDefinition(); 1770 Instruction* current = it.Current();
1749 if ((defn == NULL) || defn->AffectedBySideEffect()) continue; 1771 if (current->AffectedBySideEffect()) continue;
1750 Definition* result = map->Lookup(defn); 1772 Instruction* replacement = map->Lookup(current);
1751 if (result == NULL) { 1773 if (replacement == NULL) {
1752 map->Insert(defn); 1774 map->Insert(current);
1753 continue; 1775 continue;
1754 } 1776 }
1755 // Replace current with lookup result. 1777 // Replace current with lookup result.
1756 defn->ReplaceUsesWith(result); 1778 ReplaceCurrentInstruction(&it, current, replacement);
1757 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 } 1779 }
1764 1780
1765 // Process children in the dominator tree recursively. 1781 // Process children in the dominator tree recursively.
1766 intptr_t num_children = block->dominated_blocks().length(); 1782 intptr_t num_children = block->dominated_blocks().length();
1767 for (intptr_t i = 0; i < num_children; ++i) { 1783 for (intptr_t i = 0; i < num_children; ++i) {
1768 BlockEntryInstr* child = block->dominated_blocks()[i]; 1784 BlockEntryInstr* child = block->dominated_blocks()[i];
1769 if (i < num_children - 1) { 1785 if (i < num_children - 1) {
1770 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. 1786 DirectChainedHashMap<Instruction*> child_map(*map); // Copy map.
1771 OptimizeRecursive(child, &child_map); 1787 OptimizeRecursive(child, &child_map);
1772 } else { 1788 } else {
1773 OptimizeRecursive(child, map); // Reuse map for the last child. 1789 OptimizeRecursive(child, map); // Reuse map for the last child.
1774 } 1790 }
1775 } 1791 }
1776 } 1792 }
1777 1793
1778 1794
1779 } // namespace dart 1795 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698