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

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

Issue 10909168: Introduce nested deoptimization environments. (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
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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 void FlowGraphAllocator::EliminateEnvironmentUses() { 88 void FlowGraphAllocator::EliminateEnvironmentUses() {
89 ConstantInstr* constant_null = 89 ConstantInstr* constant_null =
90 postorder_.Last()->AsGraphEntry()->constant_null(); 90 postorder_.Last()->AsGraphEntry()->constant_null();
91 for (intptr_t i = 0; i < block_order_.length(); ++i) { 91 for (intptr_t i = 0; i < block_order_.length(); ++i) {
92 BlockEntryInstr* block = block_order_[i]; 92 BlockEntryInstr* block = block_order_[i];
93 if (block->IsJoinEntry()) block->AsJoinEntry()->RemoveDeadPhis(); 93 if (block->IsJoinEntry()) block->AsJoinEntry()->RemoveDeadPhis();
94 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 94 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
95 Instruction* current = it.Current(); 95 Instruction* current = it.Current();
96 if (current->CanDeoptimize()) { 96 if (current->CanDeoptimize()) {
97 ASSERT(current->env() != NULL); 97 ASSERT(current->env() != NULL);
98 GrowableArray<Value*>* values = current->env()->values_ptr(); 98 for (Environment::DeepIterator it(current->env());
99 for (intptr_t i = 0; i < values->length(); i++) { 99 !it.Done();
100 Value* use = (*values)[i]; 100 it.Advance()) {
101 Value* use = it.CurrentValue();
101 Definition* def = use->definition(); 102 Definition* def = use->definition();
102 PushArgumentInstr* push_argument = def->AsPushArgument(); 103 PushArgumentInstr* push_argument = def->AsPushArgument();
103 if ((push_argument != NULL) && push_argument->WasEliminated()) { 104 if ((push_argument != NULL) && push_argument->WasEliminated()) {
104 (*values)[i] = push_argument->value()->Copy(); 105 it.SetCurrentValue(push_argument->value()->Copy());
105 continue; 106 continue;
106 } 107 }
107 108
108 PhiInstr* phi = def->AsPhi(); 109 PhiInstr* phi = def->AsPhi();
109 if ((phi != NULL) && !phi->is_alive()) { 110 if ((phi != NULL) && !phi->is_alive()) {
110 (*values)[i] = new Value(constant_null); 111 it.SetCurrentValue(new Value(constant_null));
111 continue; 112 continue;
112 } 113 }
113 } 114 }
114 } else { 115 } else {
115 current->set_env(NULL); 116 current->set_env(NULL);
116 } 117 }
117 } 118 }
118 } 119 }
119 } 120 }
120 121
(...skipping 17 matching lines...) Expand all
138 live_in->Remove(current_def->ssa_temp_index()); 139 live_in->Remove(current_def->ssa_temp_index());
139 } 140 }
140 141
141 // Handle uses. 142 // Handle uses.
142 for (intptr_t j = 0; j < current->InputCount(); j++) { 143 for (intptr_t j = 0; j < current->InputCount(); j++) {
143 Value* input = current->InputAt(j); 144 Value* input = current->InputAt(j);
144 const intptr_t use = input->definition()->ssa_temp_index(); 145 const intptr_t use = input->definition()->ssa_temp_index();
145 live_in->Add(use); 146 live_in->Add(use);
146 } 147 }
147 148
148 // Add uses from the deoptimization environment. 149 // Add non-argument uses from the deoptimization environment (pushed
150 // arguments are not allocated by the register allocator).
149 if (current->env() != NULL) { 151 if (current->env() != NULL) {
150 const GrowableArray<Value*>& values = current->env()->values(); 152 for (intptr_t i = 0; i < current->env()->Length(); ++i) {
151 for (intptr_t j = 0; j < values.length(); j++) { 153 Value* value = current->env()->ValueAt(i);
152 Value* value = values[j];
153 if (!value->definition()->IsPushArgument()) { 154 if (!value->definition()->IsPushArgument()) {
154 live_in->Add(value->definition()->ssa_temp_index()); 155 live_in->Add(value->definition()->ssa_temp_index());
155 } 156 }
156 } 157 }
157 } 158 }
158 } 159 }
159 160
160 // Handle phis. 161 // Handle phis.
161 if (block->IsJoinEntry()) { 162 if (block->IsJoinEntry()) {
162 JoinEntryInstr* join = block->AsJoinEntry(); 163 JoinEntryInstr* join = block->AsJoinEntry();
(...skipping 15 matching lines...) Expand all
178 live_in_[pred->postorder_number()]->Add(use); 179 live_in_[pred->postorder_number()]->Add(use);
179 } 180 }
180 } 181 }
181 } 182 }
182 } 183 }
183 } 184 }
184 } 185 }
185 186
186 // Process incoming parameters. 187 // Process incoming parameters.
187 GraphEntryInstr* graph_entry = postorder_.Last()->AsGraphEntry(); 188 GraphEntryInstr* graph_entry = postorder_.Last()->AsGraphEntry();
188 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) { 189 for (intptr_t i = 0; i < graph_entry->start_env()->Length(); i++) {
189 Value* val = graph_entry->start_env()->values()[i]; 190 Value* val = graph_entry->start_env()->ValueAt(i);
190 intptr_t vreg = val->definition()->ssa_temp_index(); 191 intptr_t vreg = val->definition()->ssa_temp_index();
191 kill_[graph_entry->postorder_number()]->Add(vreg); 192 kill_[graph_entry->postorder_number()]->Add(vreg);
192 live_in_[graph_entry->postorder_number()]->Remove(vreg); 193 live_in_[graph_entry->postorder_number()]->Remove(vreg);
193 } 194 }
194 195
195 // Process global constants. 196 // Process global constants.
196 intptr_t vreg = graph_entry->constant_null()->ssa_temp_index(); 197 intptr_t vreg = graph_entry->constant_null()->ssa_temp_index();
197 kill_[graph_entry->postorder_number()]->Add(vreg); 198 kill_[graph_entry->postorder_number()]->Add(vreg);
198 live_in_[graph_entry->postorder_number()]->Remove(vreg); 199 live_in_[graph_entry->postorder_number()]->Remove(vreg);
199 200
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 } 513 }
513 current = current->previous(); 514 current = current->previous();
514 } 515 }
515 516
516 ConnectIncomingPhiMoves(block); 517 ConnectIncomingPhiMoves(block);
517 } 518 }
518 519
519 // Process incoming parameters. Do this after all other instructions so 520 // Process incoming parameters. Do this after all other instructions so
520 // that safepoints for all calls have already been found. 521 // that safepoints for all calls have already been found.
521 GraphEntryInstr* graph_entry = postorder_.Last()->AsGraphEntry(); 522 GraphEntryInstr* graph_entry = postorder_.Last()->AsGraphEntry();
522 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) { 523 for (intptr_t i = 0; i < graph_entry->start_env()->Length(); i++) {
523 Value* val = graph_entry->start_env()->values()[i]; 524 Value* val = graph_entry->start_env()->ValueAt(i);
524 ParameterInstr* param = val->definition()->AsParameter(); 525 ParameterInstr* param = val->definition()->AsParameter();
525 if (param == NULL) continue; 526 if (param == NULL) continue;
526 527
527 // Handle the parameters specially. They are spilled on entry. 528 // Handle the parameters specially. They are spilled on entry.
528 LiveRange* range = GetLiveRange(param->ssa_temp_index()); 529 LiveRange* range = GetLiveRange(param->ssa_temp_index());
529 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); 530 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos());
530 range->DefineAt(graph_entry->start_pos()); 531 range->DefineAt(graph_entry->start_pos());
531 532
532 // Assert that copied and non-copied parameters are mutually exclusive. 533 // Assert that copied and non-copied parameters are mutually exclusive.
533 // This might change in the future and, if so, the index will be wrong. 534 // This might change in the future and, if so, the index will be wrong.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 Environment* env = current->env(); 742 Environment* env = current->env();
742 743
743 // Any value mentioned in the deoptimization environment should survive 744 // Any value mentioned in the deoptimization environment should survive
744 // until the end of instruction but it does not need to be in the register. 745 // until the end of instruction but it does not need to be in the register.
745 // Expected shape of live range: 746 // Expected shape of live range:
746 // 747 //
747 // i i' 748 // i i'
748 // value -----* 749 // value -----*
749 // 750 //
750 751
751 const GrowableArray<Value*>& values = env->values(); 752 if (env->Length() == 0) return;
752 if (values.length() == 0) return;
753 753
754 const intptr_t block_start_pos = block->start_pos(); 754 const intptr_t block_start_pos = block->start_pos();
755 const intptr_t use_pos = current->lifetime_position() + 1; 755 const intptr_t use_pos = current->lifetime_position() + 1;
756 756
757 Location* locations = 757 Location* locations =
758 Isolate::Current()->current_zone()->Alloc<Location>(values.length()); 758 Isolate::Current()->current_zone()->Alloc<Location>(env->Length());
759 759
760 for (intptr_t i = 0; i < values.length(); ++i) { 760 for (intptr_t i = 0; i < env->Length(); ++i) {
761 Value* value = values[i]; 761 Value* value = env->ValueAt(i);
762 locations[i] = Location::Any(); 762 locations[i] = Location::Any();
763 Definition* def = value->definition(); 763 Definition* def = value->definition();
764 764
765 if (def->IsPushArgument()) { 765 if (def->IsPushArgument()) {
766 // Frame size is unknown until after allocation. 766 // Frame size is unknown until after allocation.
767 locations[i] = Location::NoLocation(); 767 locations[i] = Location::NoLocation();
768 continue; 768 continue;
769 } 769 }
770 770
771 ConstantInstr* constant = def->AsConstant(); 771 ConstantInstr* constant = def->AsConstant();
(...skipping 1411 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", 2183 OS::Print("-- [after ssa allocator] ir [%s] -------------\n",
2184 function.ToFullyQualifiedCString()); 2184 function.ToFullyQualifiedCString());
2185 FlowGraphPrinter printer(flow_graph_, true); 2185 FlowGraphPrinter printer(flow_graph_, true);
2186 printer.PrintBlocks(); 2186 printer.PrintBlocks();
2187 OS::Print("----------------------------------------------\n"); 2187 OS::Print("----------------------------------------------\n");
2188 } 2188 }
2189 } 2189 }
2190 2190
2191 2191
2192 } // namespace dart 2192 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698