Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: runtime/vm/flow_graph_allocator.cc

Issue 10918006: Rematerialize constants instead of spilling them. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_allocator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698