| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 ConnectIncomingPhiMoves(block->AsJoinEntry()); | 503 ConnectIncomingPhiMoves(block->AsJoinEntry()); |
| 504 } else if (block->IsCatchBlockEntry()) { | 504 } else if (block->IsCatchBlockEntry()) { |
| 505 // Process initial definitions. | 505 // Process initial definitions. |
| 506 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); | 506 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); |
| 507 for (intptr_t i = 0; | 507 for (intptr_t i = 0; |
| 508 i < catch_entry->initial_definitions()->length(); | 508 i < catch_entry->initial_definitions()->length(); |
| 509 i++) { | 509 i++) { |
| 510 Definition* defn = (*catch_entry->initial_definitions())[i]; | 510 Definition* defn = (*catch_entry->initial_definitions())[i]; |
| 511 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); | 511 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); |
| 512 range->DefineAt(catch_entry->start_pos()); // Defined at block entry. | 512 range->DefineAt(catch_entry->start_pos()); // Defined at block entry. |
| 513 |
| 514 // Save range->End() because it may change in ProcessInitialDefinition. |
| 515 intptr_t range_end = range->End(); |
| 513 ProcessInitialDefinition(defn, range, catch_entry); | 516 ProcessInitialDefinition(defn, range, catch_entry); |
| 517 spill_slots_.Add(range_end); |
| 518 quad_spill_slots_.Add(false); |
| 519 |
| 520 if (defn->IsParameter() && range->spill_slot().stack_index() >= 0) { |
| 521 MarkAsObjectAtSafepoints(range); |
| 522 } |
| 514 } | 523 } |
| 515 } | 524 } |
| 516 } | 525 } |
| 517 | 526 |
| 518 // Process incoming parameters and constants. Do this after all other | 527 // Process incoming parameters and constants. Do this after all other |
| 519 // instructions so that safepoints for all calls have already been found. | 528 // instructions so that safepoints for all calls have already been found. |
| 520 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); | 529 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); |
| 521 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) { | 530 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) { |
| 522 Definition* defn = (*graph_entry->initial_definitions())[i]; | 531 Definition* defn = (*graph_entry->initial_definitions())[i]; |
| 523 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); | 532 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); |
| 524 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); | 533 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); |
| 525 range->DefineAt(graph_entry->start_pos()); | 534 range->DefineAt(graph_entry->start_pos()); |
| 535 |
| 536 // Save range->End() because it may change in ProcessInitialDefinition. |
| 537 intptr_t range_end = range->End(); |
| 526 ProcessInitialDefinition(defn, range, graph_entry); | 538 ProcessInitialDefinition(defn, range, graph_entry); |
| 539 if (defn->IsParameter() && flow_graph_.num_copied_params() > 0) { |
| 540 spill_slots_.Add(range_end); |
| 541 quad_spill_slots_.Add(false); |
| 542 |
| 543 MarkAsObjectAtSafepoints(range); |
| 544 } |
| 527 } | 545 } |
| 528 } | 546 } |
| 529 | 547 |
| 530 | 548 |
| 531 void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn, | 549 void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn, |
| 532 LiveRange* range, | 550 LiveRange* range, |
| 533 BlockEntryInstr* block) { | 551 BlockEntryInstr* block) { |
| 534 // Save the range end because it may change below. | |
| 535 intptr_t range_end = range->End(); | |
| 536 if (defn->IsParameter()) { | 552 if (defn->IsParameter()) { |
| 537 ParameterInstr* param = defn->AsParameter(); | 553 ParameterInstr* param = defn->AsParameter(); |
| 538 // Assert that copied and non-copied parameters are mutually exclusive. | 554 // Assert that copied and non-copied parameters are mutually exclusive. |
| 539 // This might change in the future and, if so, the index will be wrong. | 555 // This might change in the future and, if so, the index will be wrong. |
| 540 ASSERT((flow_graph_.num_copied_params() == 0) || | 556 ASSERT((flow_graph_.num_copied_params() == 0) || |
| 541 (flow_graph_.num_non_copied_params() == 0)); | 557 (flow_graph_.num_non_copied_params() == 0)); |
| 542 // Slot index for the leftmost copied parameter is 0. | 558 // Slot index for the leftmost copied parameter is 0. |
| 543 intptr_t slot_index = param->index(); | 559 intptr_t slot_index = param->index(); |
| 544 // Slot index for the rightmost fixed parameter is -1. | 560 // Slot index for the rightmost fixed parameter is -1. |
| 545 slot_index -= flow_graph_.num_non_copied_params(); | 561 slot_index -= flow_graph_.num_non_copied_params(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 556 range->finger()->Initialize(range); | 572 range->finger()->Initialize(range); |
| 557 UsePosition* use = | 573 UsePosition* use = |
| 558 range->finger()->FirstRegisterBeneficialUse(block->start_pos()); | 574 range->finger()->FirstRegisterBeneficialUse(block->start_pos()); |
| 559 if (use != NULL) { | 575 if (use != NULL) { |
| 560 LiveRange* tail = | 576 LiveRange* tail = |
| 561 SplitBetween(range, block->start_pos(), use->pos()); | 577 SplitBetween(range, block->start_pos(), use->pos()); |
| 562 // Parameters and constants are tagged, so allocated to CPU registers. | 578 // Parameters and constants are tagged, so allocated to CPU registers. |
| 563 CompleteRange(tail, Location::kRegister); | 579 CompleteRange(tail, Location::kRegister); |
| 564 } | 580 } |
| 565 ConvertAllUses(range); | 581 ConvertAllUses(range); |
| 566 if (defn->IsParameter() && (range->spill_slot().stack_index() >= 0)) { | |
| 567 // Parameters above the frame pointer consume spill slots and are marked | |
| 568 // in stack maps. | |
| 569 spill_slots_.Add(range_end); | |
| 570 quad_spill_slots_.Add(false); | |
| 571 MarkAsObjectAtSafepoints(range); | |
| 572 } else if (defn->IsConstant() && block->IsCatchBlockEntry()) { | |
| 573 // Constants at catch block entries consume spill slots. | |
| 574 spill_slots_.Add(range_end); | |
| 575 quad_spill_slots_.Add(false); | |
| 576 } | |
| 577 } | 582 } |
| 578 | 583 |
| 579 | 584 |
| 580 static Location::Kind RegisterKindFromPolicy(Location loc) { | 585 static Location::Kind RegisterKindFromPolicy(Location loc) { |
| 581 if (loc.policy() == Location::kRequiresFpuRegister) { | 586 if (loc.policy() == Location::kRequiresFpuRegister) { |
| 582 return Location::kFpuRegister; | 587 return Location::kFpuRegister; |
| 583 } else { | 588 } else { |
| 584 return Location::kRegister; | 589 return Location::kRegister; |
| 585 } | 590 } |
| 586 } | 591 } |
| (...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 if (idx == spill_slots_.length()) { | 1610 if (idx == spill_slots_.length()) { |
| 1606 // No free spill slot found. Allocate a new one. | 1611 // No free spill slot found. Allocate a new one. |
| 1607 spill_slots_.Add(0); | 1612 spill_slots_.Add(0); |
| 1608 quad_spill_slots_.Add(need_quad); | 1613 quad_spill_slots_.Add(need_quad); |
| 1609 if (need_quad) { // Allocate two double stack slots if we need quad slot. | 1614 if (need_quad) { // Allocate two double stack slots if we need quad slot. |
| 1610 spill_slots_.Add(0); | 1615 spill_slots_.Add(0); |
| 1611 quad_spill_slots_.Add(need_quad); | 1616 quad_spill_slots_.Add(need_quad); |
| 1612 } | 1617 } |
| 1613 } | 1618 } |
| 1614 | 1619 |
| 1620 |
| 1615 // Set spill slot expiration boundary to the live range's end. | 1621 // Set spill slot expiration boundary to the live range's end. |
| 1616 spill_slots_[idx] = end; | 1622 spill_slots_[idx] = end; |
| 1617 if (need_quad) { | 1623 if (need_quad) { |
| 1618 ASSERT(quad_spill_slots_[idx] && quad_spill_slots_[idx + 1]); | 1624 ASSERT(quad_spill_slots_[idx] && quad_spill_slots_[idx + 1]); |
| 1619 idx++; // Use the higher index it corresponds to the lower stack address. | 1625 idx++; // Use the higher index it corresponds to the lower stack address. |
| 1620 spill_slots_[idx] = end; | 1626 spill_slots_[idx] = end; |
| 1621 } else { | 1627 } else { |
| 1622 ASSERT(!quad_spill_slots_[idx]); | 1628 ASSERT(!quad_spill_slots_[idx]); |
| 1623 } | 1629 } |
| 1624 | 1630 |
| (...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2585 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2591 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
| 2586 function.ToFullyQualifiedCString()); | 2592 function.ToFullyQualifiedCString()); |
| 2587 FlowGraphPrinter printer(flow_graph_, true); | 2593 FlowGraphPrinter printer(flow_graph_, true); |
| 2588 printer.PrintBlocks(); | 2594 printer.PrintBlocks(); |
| 2589 OS::Print("----------------------------------------------\n"); | 2595 OS::Print("----------------------------------------------\n"); |
| 2590 } | 2596 } |
| 2591 } | 2597 } |
| 2592 | 2598 |
| 2593 | 2599 |
| 2594 } // namespace dart | 2600 } // namespace dart |
| OLD | NEW |