Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_allocator.h" | 5 #include "vm/flow_graph_allocator.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 #include "vm/il_printer.h" | 9 #include "vm/il_printer.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 | 73 |
| 74 blocked_cpu_regs_[CTX] = true; | 74 blocked_cpu_regs_[CTX] = true; |
| 75 if (TMP != kNoRegister) { | 75 if (TMP != kNoRegister) { |
| 76 blocked_cpu_regs_[TMP] = true; | 76 blocked_cpu_regs_[TMP] = true; |
| 77 } | 77 } |
| 78 blocked_cpu_regs_[SPREG] = true; | 78 blocked_cpu_regs_[SPREG] = true; |
| 79 blocked_cpu_regs_[FPREG] = true; | 79 blocked_cpu_regs_[FPREG] = true; |
| 80 } | 80 } |
| 81 | 81 |
| 82 | 82 |
| 83 // Remove environments from the instructions which can't deoptimize. | |
| 84 // Replace dead phis uses with null values in environments. | |
| 83 void FlowGraphAllocator::EliminateEnvironmentUses() { | 85 void FlowGraphAllocator::EliminateEnvironmentUses() { |
| 86 ConstantVal* null_value = new ConstantVal(Object::ZoneHandle()); | |
| 87 | |
| 84 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 88 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 85 BlockEntryInstr* block = block_order_[i]; | 89 BlockEntryInstr* block = block_order_[i]; |
| 86 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 90 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 87 Instruction* current = it.Current(); | 91 Instruction* current = it.Current(); |
| 88 if (!current->CanDeoptimize()) current->set_env(NULL); | 92 if (current->CanDeoptimize()) { |
| 93 ASSERT(current->env() != NULL); | |
| 94 GrowableArray<Value*>* values = current->env()->values_ptr(); | |
| 95 | |
| 96 for (intptr_t i = 0; i < values->length(); i++) { | |
| 97 UseVal* use = (*values)[i]->AsUse(); | |
| 98 if (use == NULL) continue; | |
| 99 | |
| 100 PhiInstr* phi = use->definition()->AsPhi(); | |
| 101 if (phi == NULL) continue; | |
| 102 | |
| 103 if (!phi->is_alive()) (*values)[i] = null_value; | |
| 104 } | |
| 105 } else { | |
| 106 current->set_env(NULL); | |
| 107 } | |
| 89 } | 108 } |
| 90 } | 109 } |
| 91 } | 110 } |
| 92 | 111 |
| 93 | 112 |
| 94 void FlowGraphAllocator::ComputeInitialSets() { | 113 void FlowGraphAllocator::ComputeInitialSets() { |
| 95 const intptr_t block_count = postorder_.length(); | 114 const intptr_t block_count = postorder_.length(); |
| 96 for (intptr_t i = 0; i < block_count; i++) { | 115 for (intptr_t i = 0; i < block_count; i++) { |
| 97 BlockEntryInstr* block = postorder_[i]; | 116 BlockEntryInstr* block = postorder_[i]; |
| 98 | 117 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 } | 150 } |
| 132 } | 151 } |
| 133 } | 152 } |
| 134 | 153 |
| 135 // Handle phis. | 154 // Handle phis. |
| 136 if (block->IsJoinEntry()) { | 155 if (block->IsJoinEntry()) { |
| 137 JoinEntryInstr* join = block->AsJoinEntry(); | 156 JoinEntryInstr* join = block->AsJoinEntry(); |
| 138 if (join->phis() != NULL) { | 157 if (join->phis() != NULL) { |
| 139 for (intptr_t j = 0; j < join->phis()->length(); j++) { | 158 for (intptr_t j = 0; j < join->phis()->length(); j++) { |
| 140 PhiInstr* phi = (*join->phis())[j]; | 159 PhiInstr* phi = (*join->phis())[j]; |
| 141 if (phi == NULL) continue; | 160 if ((phi == NULL) || !phi->is_alive()) continue; |
|
Kevin Millikin (Google)
2012/08/08 11:07:43
It doesn't work to set (*join->phis())[j] = NULL w
| |
| 161 | |
| 142 kill->Add(phi->ssa_temp_index()); | 162 kill->Add(phi->ssa_temp_index()); |
| 143 live_in->Remove(phi->ssa_temp_index()); | 163 live_in->Remove(phi->ssa_temp_index()); |
| 144 | 164 |
| 145 // If phi-operand is not defined by a predecessor it must be marked | 165 // If phi-operand is not defined by a predecessor it must be marked |
| 146 // live-in for a predecessor. | 166 // live-in for a predecessor. |
| 147 for (intptr_t k = 0; k < phi->InputCount(); k++) { | 167 for (intptr_t k = 0; k < phi->InputCount(); k++) { |
| 148 Value* val = phi->InputAt(k); | 168 Value* val = phi->InputAt(k); |
| 149 if (val->IsUse()) { | 169 if (val->IsUse()) { |
| 150 BlockEntryInstr* pred = block->PredecessorAt(k); | 170 BlockEntryInstr* pred = block->PredecessorAt(k); |
| 151 const intptr_t use = val->AsUse()->definition()->ssa_temp_index(); | 171 const intptr_t use = val->AsUse()->definition()->ssa_temp_index(); |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 // the join. | 569 // the join. |
| 550 const intptr_t pred_idx = join->IndexOfPredecessor(block); | 570 const intptr_t pred_idx = join->IndexOfPredecessor(block); |
| 551 | 571 |
| 552 // Record the corresponding phi input use for each phi. | 572 // Record the corresponding phi input use for each phi. |
| 553 ZoneGrowableArray<PhiInstr*>* phis = join->phis(); | 573 ZoneGrowableArray<PhiInstr*>* phis = join->phis(); |
| 554 intptr_t move_idx = 0; | 574 intptr_t move_idx = 0; |
| 555 for (intptr_t phi_idx = 0; phi_idx < phis->length(); phi_idx++) { | 575 for (intptr_t phi_idx = 0; phi_idx < phis->length(); phi_idx++) { |
| 556 PhiInstr* phi = (*phis)[phi_idx]; | 576 PhiInstr* phi = (*phis)[phi_idx]; |
| 557 if (phi == NULL) continue; | 577 if (phi == NULL) continue; |
| 558 | 578 |
| 579 if (!phi->is_alive()) { | |
| 580 move_idx++; | |
| 581 continue; | |
| 582 } | |
| 583 | |
| 559 Value* val = phi->InputAt(pred_idx); | 584 Value* val = phi->InputAt(pred_idx); |
| 560 MoveOperands* move = parallel_move->MoveOperandsAt(move_idx); | 585 MoveOperands* move = parallel_move->MoveOperandsAt(move_idx); |
| 561 if (val->IsUse()) { | 586 if (val->IsUse()) { |
| 562 // Expected shape of live ranges: | 587 // Expected shape of live ranges: |
| 563 // | 588 // |
| 564 // g g' | 589 // g g' |
| 565 // value --* | 590 // value --* |
| 566 // | 591 // |
| 567 | 592 |
| 568 LiveRange* range = GetLiveRange( | 593 LiveRange* range = GetLiveRange( |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 595 // All uses are recorded at the start position in the block. | 620 // All uses are recorded at the start position in the block. |
| 596 const intptr_t pos = join->start_pos(); | 621 const intptr_t pos = join->start_pos(); |
| 597 | 622 |
| 598 ZoneGrowableArray<PhiInstr*>* phis = join->phis(); | 623 ZoneGrowableArray<PhiInstr*>* phis = join->phis(); |
| 599 if (phis != NULL) { | 624 if (phis != NULL) { |
| 600 intptr_t move_idx = 0; | 625 intptr_t move_idx = 0; |
| 601 for (intptr_t phi_idx = 0; phi_idx < phis->length(); phi_idx++) { | 626 for (intptr_t phi_idx = 0; phi_idx < phis->length(); phi_idx++) { |
| 602 PhiInstr* phi = (*phis)[phi_idx]; | 627 PhiInstr* phi = (*phis)[phi_idx]; |
| 603 if (phi == NULL) continue; | 628 if (phi == NULL) continue; |
| 604 | 629 |
| 630 if (!phi->is_alive()) { | |
| 631 move_idx++; | |
| 632 continue; | |
| 633 } | |
| 634 | |
| 605 const intptr_t vreg = phi->ssa_temp_index(); | 635 const intptr_t vreg = phi->ssa_temp_index(); |
| 606 ASSERT(vreg != -1); | 636 ASSERT(vreg != -1); |
| 607 | 637 |
| 608 // Expected shape of live range: | 638 // Expected shape of live range: |
| 609 // | 639 // |
| 610 // B | 640 // B |
| 611 // phi [-------- | 641 // phi [-------- |
| 612 // | 642 // |
| 613 LiveRange* range = GetLiveRange(vreg); | 643 LiveRange* range = GetLiveRange(vreg); |
| 614 range->DefineAt(pos); // Shorten live range. | 644 range->DefineAt(pos); // Shorten live range. |
| (...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1888 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 1918 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
| 1889 function.ToFullyQualifiedCString()); | 1919 function.ToFullyQualifiedCString()); |
| 1890 FlowGraphPrinter printer(Function::Handle(), block_order_, true); | 1920 FlowGraphPrinter printer(Function::Handle(), block_order_, true); |
| 1891 printer.PrintBlocks(); | 1921 printer.PrintBlocks(); |
| 1892 OS::Print("----------------------------------------------\n"); | 1922 OS::Print("----------------------------------------------\n"); |
| 1893 } | 1923 } |
| 1894 } | 1924 } |
| 1895 | 1925 |
| 1896 | 1926 |
| 1897 } // namespace dart | 1927 } // namespace dart |
| OLD | NEW |