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