| 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 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 } | 562 } |
| 563 } | 563 } |
| 564 | 564 |
| 565 // Process global constants. | 565 // Process global constants. |
| 566 BindInstr* null_defn = graph_entry->constant_null()->AsBind(); | 566 BindInstr* null_defn = graph_entry->constant_null()->AsBind(); |
| 567 LiveRange* range = GetLiveRange(null_defn->ssa_temp_index()); | 567 LiveRange* range = GetLiveRange(null_defn->ssa_temp_index()); |
| 568 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); | 568 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); |
| 569 range->DefineAt(graph_entry->start_pos()); | 569 range->DefineAt(graph_entry->start_pos()); |
| 570 range->set_assigned_location( | 570 range->set_assigned_location( |
| 571 Location::Constant(null_defn->computation()->AsConstant()->value())); | 571 Location::Constant(null_defn->computation()->AsConstant()->value())); |
| 572 range->set_spill_slot( |
| 573 Location::Constant(null_defn->computation()->AsConstant()->value())); |
| 572 range->finger()->Initialize(range); | 574 range->finger()->Initialize(range); |
| 573 UsePosition* use = | 575 UsePosition* use = |
| 574 range->finger()->FirstRegisterBeneficialUse(graph_entry->start_pos()); | 576 range->finger()->FirstRegisterBeneficialUse(graph_entry->start_pos()); |
| 575 if (use != NULL) { | 577 if (use != NULL) { |
| 576 LiveRange* tail = SplitBetween(range, graph_entry->start_pos(), use->pos()); | 578 LiveRange* tail = SplitBetween(range, graph_entry->start_pos(), use->pos()); |
| 577 CompleteRange(tail, Location::kRegister); | 579 CompleteRange(tail, Location::kRegister); |
| 578 } | 580 } |
| 579 ConvertAllUses(range); | 581 ConvertAllUses(range); |
| 580 } | 582 } |
| 581 | 583 |
| (...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1928 | 1930 |
| 1929 // All allocation decisions were done. | 1931 // All allocation decisions were done. |
| 1930 ASSERT(unallocated_.is_empty()); | 1932 ASSERT(unallocated_.is_empty()); |
| 1931 | 1933 |
| 1932 // Finish allocation. | 1934 // Finish allocation. |
| 1933 AdvanceActiveIntervals(kMaxPosition); | 1935 AdvanceActiveIntervals(kMaxPosition); |
| 1934 TRACE_ALLOC(OS::Print("Allocation completed\n")); | 1936 TRACE_ALLOC(OS::Print("Allocation completed\n")); |
| 1935 } | 1937 } |
| 1936 | 1938 |
| 1937 | 1939 |
| 1940 bool FlowGraphAllocator::TargetLocationIsSpillSlot(LiveRange* range, |
| 1941 Location target) { |
| 1942 if (target.IsStackSlot() || |
| 1943 target.IsDoubleStackSlot() || |
| 1944 target.IsConstant()) { |
| 1945 ASSERT(GetLiveRange(range->vreg())->spill_slot().Equals(target)); |
| 1946 return true; |
| 1947 } |
| 1948 return false; |
| 1949 } |
| 1950 |
| 1951 |
| 1938 void FlowGraphAllocator::ConnectSplitSiblings(LiveRange* parent, | 1952 void FlowGraphAllocator::ConnectSplitSiblings(LiveRange* parent, |
| 1939 BlockEntryInstr* source_block, | 1953 BlockEntryInstr* source_block, |
| 1940 BlockEntryInstr* target_block) { | 1954 BlockEntryInstr* target_block) { |
| 1941 TRACE_ALLOC(OS::Print("Connect source_block=%d, target_block=%d\n", | 1955 TRACE_ALLOC(OS::Print("Connect source_block=%d, target_block=%d\n", |
| 1942 source_block->block_id(), | 1956 source_block->block_id(), |
| 1943 target_block->block_id())); | 1957 target_block->block_id())); |
| 1944 if (parent->next_sibling() == NULL) { | 1958 if (parent->next_sibling() == NULL) { |
| 1945 // Nothing to connect. The whole range was allocated to the same location. | 1959 // Nothing to connect. The whole range was allocated to the same location. |
| 1946 TRACE_ALLOC(OS::Print("range %d has no siblings\n", parent->vreg())); | 1960 TRACE_ALLOC(OS::Print("range %d has no siblings\n", parent->vreg())); |
| 1947 return; | 1961 return; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1985 TRACE_ALLOC(source.Print()); | 1999 TRACE_ALLOC(source.Print()); |
| 1986 TRACE_ALLOC(OS::Print("] to [%d, %d) [", | 2000 TRACE_ALLOC(OS::Print("] to [%d, %d) [", |
| 1987 target_cover->Start(), target_cover->End())); | 2001 target_cover->Start(), target_cover->End())); |
| 1988 TRACE_ALLOC(target.Print()); | 2002 TRACE_ALLOC(target.Print()); |
| 1989 TRACE_ALLOC(OS::Print("]\n")); | 2003 TRACE_ALLOC(OS::Print("]\n")); |
| 1990 | 2004 |
| 1991 // Siblings were allocated to the same register. | 2005 // Siblings were allocated to the same register. |
| 1992 if (source.Equals(target)) return; | 2006 if (source.Equals(target)) return; |
| 1993 | 2007 |
| 1994 // Values are eagerly spilled. Spill slot already contains appropriate value. | 2008 // Values are eagerly spilled. Spill slot already contains appropriate value. |
| 1995 if (target.IsStackSlot() || target.IsDoubleStackSlot()) { | 2009 if (TargetLocationIsSpillSlot(parent, target)) { |
| 1996 ASSERT(parent->spill_slot().Equals(target)); | |
| 1997 return; | 2010 return; |
| 1998 } | 2011 } |
| 1999 | 2012 |
| 2000 Instruction* last = source_block->last_instruction(); | 2013 Instruction* last = source_block->last_instruction(); |
| 2001 if ((last->SuccessorCount() == 1) && !source_block->IsGraphEntry()) { | 2014 if ((last->SuccessorCount() == 1) && !source_block->IsGraphEntry()) { |
| 2002 ASSERT(last->IsGoto()); | 2015 ASSERT(last->IsGoto()); |
| 2003 last->AsGoto()->GetParallelMove()->AddMove(target, source); | 2016 last->AsGoto()->GetParallelMove()->AddMove(target, source); |
| 2004 } else { | 2017 } else { |
| 2005 target_block->GetParallelMove()->AddMove(target, source); | 2018 target_block->GetParallelMove()->AddMove(target, source); |
| 2006 } | 2019 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2017 while (range->next_sibling() != NULL) { | 2030 while (range->next_sibling() != NULL) { |
| 2018 LiveRange* sibling = range->next_sibling(); | 2031 LiveRange* sibling = range->next_sibling(); |
| 2019 TRACE_ALLOC(OS::Print("connecting [%d, %d) [", | 2032 TRACE_ALLOC(OS::Print("connecting [%d, %d) [", |
| 2020 range->Start(), range->End())); | 2033 range->Start(), range->End())); |
| 2021 TRACE_ALLOC(range->assigned_location().Print()); | 2034 TRACE_ALLOC(range->assigned_location().Print()); |
| 2022 TRACE_ALLOC(OS::Print("] to [%d, %d) [", | 2035 TRACE_ALLOC(OS::Print("] to [%d, %d) [", |
| 2023 sibling->Start(), sibling->End())); | 2036 sibling->Start(), sibling->End())); |
| 2024 TRACE_ALLOC(sibling->assigned_location().Print()); | 2037 TRACE_ALLOC(sibling->assigned_location().Print()); |
| 2025 TRACE_ALLOC(OS::Print("]\n")); | 2038 TRACE_ALLOC(OS::Print("]\n")); |
| 2026 if ((range->End() == sibling->Start()) && | 2039 if ((range->End() == sibling->Start()) && |
| 2027 !sibling->assigned_location().IsStackSlot() && | 2040 !TargetLocationIsSpillSlot(range, sibling->assigned_location()) && |
| 2028 !sibling->assigned_location().IsDoubleStackSlot() && | |
| 2029 !range->assigned_location().Equals(sibling->assigned_location()) && | 2041 !range->assigned_location().Equals(sibling->assigned_location()) && |
| 2030 !IsBlockEntry(range->End())) { | 2042 !IsBlockEntry(range->End())) { |
| 2031 AddMoveAt(sibling->Start(), | 2043 AddMoveAt(sibling->Start(), |
| 2032 sibling->assigned_location(), | 2044 sibling->assigned_location(), |
| 2033 range->assigned_location()); | 2045 range->assigned_location()); |
| 2034 } | 2046 } |
| 2035 range = sibling; | 2047 range = sibling; |
| 2036 } | 2048 } |
| 2037 } | 2049 } |
| 2038 | 2050 |
| 2039 // Resolve non-linear control flow across branches. | 2051 // Resolve non-linear control flow across branches. |
| 2040 for (intptr_t i = 1; i < block_order_.length(); i++) { | 2052 for (intptr_t i = 1; i < block_order_.length(); i++) { |
| 2041 BlockEntryInstr* block = block_order_[i]; | 2053 BlockEntryInstr* block = block_order_[i]; |
| 2042 BitVector* live = live_in_[block->postorder_number()]; | 2054 BitVector* live = live_in_[block->postorder_number()]; |
| 2043 for (BitVector::Iterator it(live); !it.Done(); it.Advance()) { | 2055 for (BitVector::Iterator it(live); !it.Done(); it.Advance()) { |
| 2044 LiveRange* range = GetLiveRange(it.Current()); | 2056 LiveRange* range = GetLiveRange(it.Current()); |
| 2045 for (intptr_t j = 0; j < block->PredecessorCount(); j++) { | 2057 for (intptr_t j = 0; j < block->PredecessorCount(); j++) { |
| 2046 ConnectSplitSiblings(range, block->PredecessorAt(j), block); | 2058 ConnectSplitSiblings(range, block->PredecessorAt(j), block); |
| 2047 } | 2059 } |
| 2048 } | 2060 } |
| 2049 } | 2061 } |
| 2050 | 2062 |
| 2051 // Eagerly spill values. | 2063 // Eagerly spill values. |
| 2052 // TODO(vegorov): if value is spilled on the cold path (e.g. by the call) | 2064 // TODO(vegorov): if value is spilled on the cold path (e.g. by the call) |
| 2053 // this will cause spilling to occur on the fast path (at the definition). | 2065 // this will cause spilling to occur on the fast path (at the definition). |
| 2054 for (intptr_t i = 0; i < spilled_.length(); i++) { | 2066 for (intptr_t i = 0; i < spilled_.length(); i++) { |
| 2055 LiveRange* range = spilled_[i]; | 2067 LiveRange* range = spilled_[i]; |
| 2056 if (range->assigned_location().IsStackSlot() || | 2068 if (range->assigned_location().IsStackSlot() || |
| 2057 range->assigned_location().IsDoubleStackSlot()) { | 2069 range->assigned_location().IsDoubleStackSlot() || |
| 2070 range->assigned_location().IsConstant()) { |
| 2058 ASSERT(range->assigned_location().Equals(range->spill_slot())); | 2071 ASSERT(range->assigned_location().Equals(range->spill_slot())); |
| 2059 } else { | 2072 } else { |
| 2060 AddMoveAt(range->Start() + 1, | 2073 AddMoveAt(range->Start() + 1, |
| 2061 range->spill_slot(), | 2074 range->spill_slot(), |
| 2062 range->assigned_location()); | 2075 range->assigned_location()); |
| 2063 } | 2076 } |
| 2064 } | 2077 } |
| 2065 } | 2078 } |
| 2066 | 2079 |
| 2067 | 2080 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2131 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2144 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
| 2132 function.ToFullyQualifiedCString()); | 2145 function.ToFullyQualifiedCString()); |
| 2133 FlowGraphPrinter printer(flow_graph_, true); | 2146 FlowGraphPrinter printer(flow_graph_, true); |
| 2134 printer.PrintBlocks(); | 2147 printer.PrintBlocks(); |
| 2135 OS::Print("----------------------------------------------\n"); | 2148 OS::Print("----------------------------------------------\n"); |
| 2136 } | 2149 } |
| 2137 } | 2150 } |
| 2138 | 2151 |
| 2139 | 2152 |
| 2140 } // namespace dart | 2153 } // namespace dart |
| OLD | NEW |