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

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

Issue 12457034: Ensure that all goto instructions have deoptimization target. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Delete UNREACHABLE Created 7 years, 8 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_builder.h ('k') | runtime/vm/flow_graph_compiler.h » ('j') | 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_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 // Insert the callee graph into the caller graph. First sort the list of 126 // Insert the callee graph into the caller graph. First sort the list of
127 // exits by block id (recording block entries as a side effect). 127 // exits by block id (recording block entries as a side effect).
128 SortExits(); 128 SortExits();
129 intptr_t num_exits = exits_.length(); 129 intptr_t num_exits = exits_.length();
130 if (num_exits == 0) { 130 if (num_exits == 0) {
131 // TODO(zerny): Add support for non-local exits, such as throw. 131 // TODO(zerny): Add support for non-local exits, such as throw.
132 UNREACHABLE(); 132 UNREACHABLE();
133 } else if (num_exits == 1) { 133 } else if (num_exits == 1) {
134 // For just one exit, replace the uses and remove the call from the graph. 134 // For just one exit, replace the uses and remove the call from the graph.
135 call->ReplaceUsesWith(ValueAt(0)->definition()); 135 call->ReplaceUsesWith(ValueAt(0)->definition());
136 ValueAt(0)->RemoveFromUseList(); 136 ReturnAt(0)->UnuseAllInputs();
137 call->previous()->LinkTo(callee_entry->next()); 137 call->previous()->LinkTo(callee_entry->next());
138 LastInstructionAt(0)->LinkTo(call->next()); 138 LastInstructionAt(0)->LinkTo(call->next());
139 // In case of control flow, locally update the predecessors, phis and 139 // In case of control flow, locally update the predecessors, phis and
140 // dominator tree. 140 // dominator tree.
141 // TODO(zerny): should we leave the dominator tree since we recompute it 141 // TODO(zerny): should we leave the dominator tree since we recompute it
142 // after a full inlining pass? 142 // after a full inlining pass?
143 if (callee_graph->preorder().length() > 2) { 143 if (callee_graph->preorder().length() > 2) {
144 BlockEntryInstr* exit_block = ExitBlockAt(0); 144 BlockEntryInstr* exit_block = ExitBlockAt(0);
145 // Pictorially, the graph structure is: 145 // Pictorially, the graph structure is:
146 // 146 //
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 block->set_dominator(caller_entry); 179 block->set_dominator(caller_entry);
180 caller_entry->AddDominatedBlock(block); 180 caller_entry->AddDominatedBlock(block);
181 } 181 }
182 } 182 }
183 } else { 183 } else {
184 // Create a join of the returns. 184 // Create a join of the returns.
185 intptr_t join_id = caller_graph->max_block_id() + 1; 185 intptr_t join_id = caller_graph->max_block_id() + 1;
186 caller_graph->set_max_block_id(join_id); 186 caller_graph->set_max_block_id(join_id);
187 JoinEntryInstr* join = 187 JoinEntryInstr* join =
188 new JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex); 188 new JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex);
189 join->InheritDeoptTarget(call);
189 for (intptr_t i = 0; i < num_exits; ++i) { 190 for (intptr_t i = 0; i < num_exits; ++i) {
190 LastInstructionAt(i)->Goto(join); 191 GotoInstr* goto_instr = new GotoInstr(join);
192 goto_instr->InheritDeoptTarget(ReturnAt(i));
193 LastInstructionAt(i)->LinkTo(goto_instr);
191 // Directly add the predecessors of the join in ascending block id order. 194 // Directly add the predecessors of the join in ascending block id order.
192 join->predecessors_.Add(ExitBlockAt(i)); 195 join->predecessors_.Add(ExitBlockAt(i));
193 } 196 }
194 // If the call has uses, create a phi of the returns. 197 // If the call has uses, create a phi of the returns.
195 if (call->HasUses()) { 198 if (call->HasUses()) {
196 // Add a phi of the return values. 199 // Add a phi of the return values.
197 PhiInstr* phi = new PhiInstr(join, num_exits); 200 PhiInstr* phi = new PhiInstr(join, num_exits);
198 phi->set_ssa_temp_index(caller_graph->alloc_ssa_temp_index()); 201 phi->set_ssa_temp_index(caller_graph->alloc_ssa_temp_index());
199 phi->mark_alive(); 202 phi->mark_alive();
200 for (intptr_t i = 0; i < num_exits; ++i) { 203 for (intptr_t i = 0; i < num_exits; ++i) {
204 ReturnAt(i)->RemoveEnvironment();
201 phi->SetInputAt(i, ValueAt(i)); 205 phi->SetInputAt(i, ValueAt(i));
202 } 206 }
203 join->InsertPhi(phi); 207 join->InsertPhi(phi);
204 // Replace uses of the call with the phi. 208 // Replace uses of the call with the phi.
205 call->ReplaceUsesWith(phi); 209 call->ReplaceUsesWith(phi);
206 } else { 210 } else {
207 // In the case that the result is unused, remove the return value uses 211 // In the case that the result is unused, remove the return value uses
208 // from their definition's use list. 212 // from their definition's use list.
209 for (intptr_t i = 0; i < num_exits; ++i) { 213 for (intptr_t i = 0; i < num_exits; ++i) {
210 ValueAt(i)->RemoveFromUseList(); 214 ReturnAt(i)->UnuseAllInputs();
211 } 215 }
212 } 216 }
213 // Remove the call from the graph. 217 // Remove the call from the graph.
214 call->previous()->LinkTo(callee_entry->next()); 218 call->previous()->LinkTo(callee_entry->next());
215 join->LinkTo(call->next()); 219 join->LinkTo(call->next());
216 // Replace the blocks after splitting (see comment in the len=1 case above). 220 // Replace the blocks after splitting (see comment in the len=1 case above).
217 caller_entry->ReplaceAsPredecessorWith(join); 221 caller_entry->ReplaceAsPredecessorWith(join);
218 callee_entry->ReplaceAsPredecessorWith(caller_entry); 222 callee_entry->ReplaceAsPredecessorWith(caller_entry);
219 // Update the last instruction pointers on each exit block to the new goto. 223 // Update the last instruction pointers on each exit block to the new goto.
220 for (intptr_t i = 0; i < num_exits; ++i) { 224 for (intptr_t i = 0; i < num_exits; ++i) {
(...skipping 3123 matching lines...) Expand 10 before | Expand all | Expand 10 after
3344 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 3348 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
3345 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 3349 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
3346 OS::SNPrint(chars, len, kFormat, function_name, reason); 3350 OS::SNPrint(chars, len, kFormat, function_name, reason);
3347 const Error& error = Error::Handle( 3351 const Error& error = Error::Handle(
3348 LanguageError::New(String::Handle(String::New(chars)))); 3352 LanguageError::New(String::Handle(String::New(chars))));
3349 Isolate::Current()->long_jump_base()->Jump(1, error); 3353 Isolate::Current()->long_jump_base()->Jump(1, error);
3350 } 3354 }
3351 3355
3352 3356
3353 } // namespace dart 3357 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698