| 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 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 UsePosition* use = | 573 UsePosition* use = |
| 574 range->finger()->FirstRegisterBeneficialUse(block->start_pos()); | 574 range->finger()->FirstRegisterBeneficialUse(block->start_pos()); |
| 575 if (use != NULL) { | 575 if (use != NULL) { |
| 576 LiveRange* tail = | 576 LiveRange* tail = |
| 577 SplitBetween(range, block->start_pos(), use->pos()); | 577 SplitBetween(range, block->start_pos(), use->pos()); |
| 578 // Parameters and constants are tagged, so allocated to CPU registers. | 578 // Parameters and constants are tagged, so allocated to CPU registers. |
| 579 CompleteRange(tail, Location::kRegister); | 579 CompleteRange(tail, Location::kRegister); |
| 580 } | 580 } |
| 581 ConvertAllUses(range); | 581 ConvertAllUses(range); |
| 582 if (defn->IsParameter() && (range->spill_slot().stack_index() >= 0)) { | 582 if (defn->IsParameter() && (range->spill_slot().stack_index() >= 0)) { |
| 583 // Parameters above the frame pointer occupy (allocatable) spill slots | 583 // Parameters above the frame pointer consume spill slots and are marked |
| 584 // and are marked in stack maps. There are multiple non-interfering | 584 // in stack maps. |
| 585 // live ranges occupying the same spill slot (e.g., those for different | 585 spill_slots_.Add(range_end); |
| 586 // catch blocks). Block the spill slot until the latest such live range | 586 quad_spill_slots_.Add(false); |
| 587 // endpoint. | |
| 588 intptr_t index = range->spill_slot().stack_index(); | |
| 589 while (index > (spill_slots_.length() - 1)) { | |
| 590 spill_slots_.Add(-1); | |
| 591 quad_spill_slots_.Add(false); | |
| 592 } | |
| 593 spill_slots_[index] = Utils::Maximum(spill_slots_[index], range_end); | |
| 594 ASSERT(!quad_spill_slots_[index]); | |
| 595 MarkAsObjectAtSafepoints(range); | 587 MarkAsObjectAtSafepoints(range); |
| 588 } else if (defn->IsConstant() && block->IsCatchBlockEntry()) { |
| 589 // Constants at catch block entries consume spill slots. |
| 590 spill_slots_.Add(range_end); |
| 591 quad_spill_slots_.Add(false); |
| 596 } | 592 } |
| 597 } | 593 } |
| 598 | 594 |
| 599 | 595 |
| 600 static Location::Kind RegisterKindFromPolicy(Location loc) { | 596 static Location::Kind RegisterKindFromPolicy(Location loc) { |
| 601 if (loc.policy() == Location::kRequiresFpuRegister) { | 597 if (loc.policy() == Location::kRequiresFpuRegister) { |
| 602 return Location::kFpuRegister; | 598 return Location::kFpuRegister; |
| 603 } else { | 599 } else { |
| 604 return Location::kRegister; | 600 return Location::kRegister; |
| 605 } | 601 } |
| (...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1604 // Special care is taken to never allocate the same index to both | 1600 // Special care is taken to never allocate the same index to both |
| 1605 // double and quad spill slots as it complicates disambiguation during | 1601 // double and quad spill slots as it complicates disambiguation during |
| 1606 // parallel move resolution. | 1602 // parallel move resolution. |
| 1607 const bool need_quad = (register_kind_ == Location::kFpuRegister) && | 1603 const bool need_quad = (register_kind_ == Location::kFpuRegister) && |
| 1608 ((range->representation() == kUnboxedFloat32x4) || | 1604 ((range->representation() == kUnboxedFloat32x4) || |
| 1609 (range->representation() == kUnboxedInt32x4)); | 1605 (range->representation() == kUnboxedInt32x4)); |
| 1610 | 1606 |
| 1611 // Search for a free spill slot among allocated: the value in it should be | 1607 // Search for a free spill slot among allocated: the value in it should be |
| 1612 // dead and its type should match (e.g. it should not be a part of the quad if | 1608 // dead and its type should match (e.g. it should not be a part of the quad if |
| 1613 // we are allocating normal double slot). | 1609 // we are allocating normal double slot). |
| 1614 intptr_t idx = 0; | 1610 // For CPU registers we need to take reserved slots for try-catch into |
| 1611 // account. |
| 1612 intptr_t idx = register_kind_ == Location::kRegister |
| 1613 ? flow_graph_.graph_entry()->fixed_slot_count() |
| 1614 : 0; |
| 1615 for (; idx < spill_slots_.length(); idx++) { | 1615 for (; idx < spill_slots_.length(); idx++) { |
| 1616 if ((need_quad == quad_spill_slots_[idx]) && | 1616 if ((need_quad == quad_spill_slots_[idx]) && |
| 1617 (spill_slots_[idx] <= start)) { | 1617 (spill_slots_[idx] <= start)) { |
| 1618 break; | 1618 break; |
| 1619 } | 1619 } |
| 1620 } | 1620 } |
| 1621 | 1621 |
| 1622 if (idx == spill_slots_.length()) { | 1622 if (idx == spill_slots_.length()) { |
| 1623 // No free spill slot found. Allocate a new one. | 1623 // No free spill slot found. Allocate a new one. |
| 1624 spill_slots_.Add(0); | 1624 spill_slots_.Add(0); |
| (...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2602 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2602 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
| 2603 function.ToFullyQualifiedCString()); | 2603 function.ToFullyQualifiedCString()); |
| 2604 FlowGraphPrinter printer(flow_graph_, true); | 2604 FlowGraphPrinter printer(flow_graph_, true); |
| 2605 printer.PrintBlocks(); | 2605 printer.PrintBlocks(); |
| 2606 OS::Print("----------------------------------------------\n"); | 2606 OS::Print("----------------------------------------------\n"); |
| 2607 } | 2607 } |
| 2608 } | 2608 } |
| 2609 | 2609 |
| 2610 | 2610 |
| 2611 } // namespace dart | 2611 } // namespace dart |
| OLD | NEW |