| 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.h" | 10 #include "vm/flow_graph.h" |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 const intptr_t use = val->definition()->ssa_temp_index(); | 180 const intptr_t use = val->definition()->ssa_temp_index(); |
| 181 if (!kill_[pred->postorder_number()]->Contains(use)) { | 181 if (!kill_[pred->postorder_number()]->Contains(use)) { |
| 182 live_in_[pred->postorder_number()]->Add(use); | 182 live_in_[pred->postorder_number()]->Add(use); |
| 183 } | 183 } |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 } | 186 } |
| 187 } | 187 } |
| 188 } | 188 } |
| 189 | 189 |
| 190 // Process incoming parameters. | 190 // Process initial definitions, ie, constants and incoming parameters. |
| 191 GraphEntryInstr* graph_entry = postorder_.Last()->AsGraphEntry(); | 191 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); |
| 192 for (intptr_t i = 0; i < graph_entry->start_env()->Length(); i++) { | 192 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) { |
| 193 Value* val = graph_entry->start_env()->ValueAt(i); | 193 intptr_t vreg = (*graph_entry->initial_definitions())[i]->ssa_temp_index(); |
| 194 intptr_t vreg = val->definition()->ssa_temp_index(); | |
| 195 kill_[graph_entry->postorder_number()]->Add(vreg); | 194 kill_[graph_entry->postorder_number()]->Add(vreg); |
| 196 live_in_[graph_entry->postorder_number()]->Remove(vreg); | 195 live_in_[graph_entry->postorder_number()]->Remove(vreg); |
| 197 } | 196 } |
| 198 | 197 |
| 199 // Process global constants. | |
| 200 intptr_t vreg = graph_entry->constant_null()->ssa_temp_index(); | |
| 201 kill_[graph_entry->postorder_number()]->Add(vreg); | |
| 202 live_in_[graph_entry->postorder_number()]->Remove(vreg); | |
| 203 | |
| 204 // Update initial live_in sets to match live_out sets. Has to be | 198 // Update initial live_in sets to match live_out sets. Has to be |
| 205 // done in a separate path because of backwards branches. | 199 // done in a separate path because of backwards branches. |
| 206 for (intptr_t i = 0; i < block_count; i++) { | 200 for (intptr_t i = 0; i < block_count; i++) { |
| 207 UpdateLiveIn(*postorder_[i]); | 201 UpdateLiveIn(*postorder_[i]); |
| 208 } | 202 } |
| 209 } | 203 } |
| 210 | 204 |
| 211 | 205 |
| 212 bool FlowGraphAllocator::UpdateLiveOut(const BlockEntryInstr& instr) { | 206 bool FlowGraphAllocator::UpdateLiveOut(const BlockEntryInstr& instr) { |
| 213 BitVector* live_out = live_out_[instr.postorder_number()]; | 207 BitVector* live_out = live_out_[instr.postorder_number()]; |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 // Skip parallel moves that we insert while processing instructions. | 507 // Skip parallel moves that we insert while processing instructions. |
| 514 if (!current->IsParallelMove()) { | 508 if (!current->IsParallelMove()) { |
| 515 ProcessOneInstruction(block, current); | 509 ProcessOneInstruction(block, current); |
| 516 } | 510 } |
| 517 current = current->previous(); | 511 current = current->previous(); |
| 518 } | 512 } |
| 519 | 513 |
| 520 ConnectIncomingPhiMoves(block); | 514 ConnectIncomingPhiMoves(block); |
| 521 } | 515 } |
| 522 | 516 |
| 523 // Process incoming parameters. Do this after all other instructions so | 517 // Process incoming parameters and constants. Do this after all other |
| 524 // that safepoints for all calls have already been found. | 518 // instructions so that safepoints for all calls have already been found. |
| 525 GraphEntryInstr* graph_entry = postorder_.Last()->AsGraphEntry(); | 519 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); |
| 526 for (intptr_t i = 0; i < graph_entry->start_env()->Length(); i++) { | 520 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) { |
| 527 Value* val = graph_entry->start_env()->ValueAt(i); | 521 Definition* defn = (*graph_entry->initial_definitions())[i]; |
| 528 ParameterInstr* param = val->definition()->AsParameter(); | 522 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); |
| 529 if (param == NULL) continue; | |
| 530 | |
| 531 // Handle the parameters specially. They are spilled on entry. | |
| 532 LiveRange* range = GetLiveRange(param->ssa_temp_index()); | |
| 533 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); | 523 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); |
| 534 range->DefineAt(graph_entry->start_pos()); | 524 range->DefineAt(graph_entry->start_pos()); |
| 525 if (defn->IsParameter()) { |
| 526 ParameterInstr* param = defn->AsParameter(); |
| 527 // Assert that copied and non-copied parameters are mutually exclusive. |
| 528 // This might change in the future and, if so, the index will be wrong. |
| 529 ASSERT((flow_graph_.num_copied_params() == 0) || |
| 530 (flow_graph_.num_non_copied_params() == 0)); |
| 531 // Slot index for the leftmost copied parameter is 0. |
| 532 intptr_t slot_index = param->index(); |
| 533 // Slot index for the rightmost fixed parameter is -1. |
| 534 slot_index -= flow_graph_.num_non_copied_params(); |
| 535 | 535 |
| 536 // Assert that copied and non-copied parameters are mutually exclusive. | 536 range->set_assigned_location(Location::StackSlot(slot_index)); |
| 537 // This might change in the future and, if so, the index will be wrong. | 537 range->set_spill_slot(Location::StackSlot(slot_index)); |
| 538 ASSERT((flow_graph_.num_copied_params() == 0) || | 538 if (flow_graph_.num_copied_params() > 0) { |
| 539 (flow_graph_.num_non_copied_params() == 0)); | 539 ASSERT(spill_slots_.length() == slot_index); |
| 540 // Slot index for the leftmost copied parameter is 0. | 540 spill_slots_.Add(range->End()); |
| 541 intptr_t slot_index = param->index(); | 541 } |
| 542 // Slot index for the rightmost fixed parameter is -1. | 542 AssignSafepoints(range); |
| 543 slot_index -= flow_graph_.num_non_copied_params(); | 543 } else { |
| 544 | 544 ConstantInstr* constant = defn->AsConstant(); |
| 545 range->set_assigned_location(Location::StackSlot(slot_index)); | 545 ASSERT(constant != NULL); |
| 546 range->set_spill_slot(Location::StackSlot(slot_index)); | 546 range->set_assigned_location(Location::Constant(constant->value())); |
| 547 if (flow_graph_.num_copied_params() > 0) { | 547 range->set_spill_slot(Location::Constant(constant->value())); |
| 548 ASSERT(spill_slots_.length() == slot_index); | |
| 549 spill_slots_.Add(range->End()); | |
| 550 } | 548 } |
| 551 | |
| 552 AssignSafepoints(range); | |
| 553 | |
| 554 range->finger()->Initialize(range); | 549 range->finger()->Initialize(range); |
| 555 UsePosition* use = | 550 UsePosition* use = |
| 556 range->finger()->FirstRegisterBeneficialUse(graph_entry->start_pos()); | 551 range->finger()->FirstRegisterBeneficialUse(graph_entry->start_pos()); |
| 557 if (use != NULL) { | 552 if (use != NULL) { |
| 558 LiveRange* tail = | 553 LiveRange* tail = |
| 559 SplitBetween(range, graph_entry->start_pos(), use->pos()); | 554 SplitBetween(range, graph_entry->start_pos(), use->pos()); |
| 560 // All incoming parameters are tagged. | 555 // Parameters and constants are tagged, so allocated to CPU registers. |
| 561 CompleteRange(tail, Location::kRegister); | 556 CompleteRange(tail, Location::kRegister); |
| 562 } | 557 } |
| 563 ConvertAllUses(range); | 558 ConvertAllUses(range); |
| 564 if (flow_graph_.num_copied_params() > 0) { | 559 |
| 560 if (defn->IsParameter() && flow_graph_.num_copied_params() > 0) { |
| 565 MarkAsObjectAtSafepoints(range); | 561 MarkAsObjectAtSafepoints(range); |
| 566 } | 562 } |
| 567 } | 563 } |
| 568 | |
| 569 // Process global constants. | |
| 570 ConstantInstr* null_defn = graph_entry->constant_null(); | |
| 571 LiveRange* range = GetLiveRange(null_defn->ssa_temp_index()); | |
| 572 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); | |
| 573 range->DefineAt(graph_entry->start_pos()); | |
| 574 range->set_assigned_location(Location::Constant(null_defn->value())); | |
| 575 range->set_spill_slot(Location::Constant(null_defn->value())); | |
| 576 range->finger()->Initialize(range); | |
| 577 UsePosition* use = | |
| 578 range->finger()->FirstRegisterBeneficialUse(graph_entry->start_pos()); | |
| 579 if (use != NULL) { | |
| 580 LiveRange* tail = SplitBetween(range, graph_entry->start_pos(), use->pos()); | |
| 581 CompleteRange(tail, Location::kRegister); | |
| 582 } | |
| 583 ConvertAllUses(range); | |
| 584 } | 564 } |
| 585 | 565 |
| 586 | 566 |
| 587 static Location::Kind RegisterKindFromPolicy(Location loc) { | 567 static Location::Kind RegisterKindFromPolicy(Location loc) { |
| 588 if (loc.policy() == Location::kRequiresXmmRegister) { | 568 if (loc.policy() == Location::kRequiresXmmRegister) { |
| 589 return Location::kXmmRegister; | 569 return Location::kXmmRegister; |
| 590 } else { | 570 } else { |
| 591 return Location::kRegister; | 571 return Location::kRegister; |
| 592 } | 572 } |
| 593 } | 573 } |
| (...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2214 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2194 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
| 2215 function.ToFullyQualifiedCString()); | 2195 function.ToFullyQualifiedCString()); |
| 2216 FlowGraphPrinter printer(flow_graph_, true); | 2196 FlowGraphPrinter printer(flow_graph_, true); |
| 2217 printer.PrintBlocks(); | 2197 printer.PrintBlocks(); |
| 2218 OS::Print("----------------------------------------------\n"); | 2198 OS::Print("----------------------------------------------\n"); |
| 2219 } | 2199 } |
| 2220 } | 2200 } |
| 2221 | 2201 |
| 2222 | 2202 |
| 2223 } // namespace dart | 2203 } // namespace dart |
| OLD | NEW |