| 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_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 // Insert the callee graph into the caller graph. First sort the list of | 129 // Insert the callee graph into the caller graph. First sort the list of |
| 130 // exits by block id (recording block entries as a side effect). | 130 // exits by block id (recording block entries as a side effect). |
| 131 SortExits(); | 131 SortExits(); |
| 132 intptr_t num_exits = exits_.length(); | 132 intptr_t num_exits = exits_.length(); |
| 133 if (num_exits == 0) { | 133 if (num_exits == 0) { |
| 134 // TODO(zerny): Add support for non-local exits, such as throw. | 134 // TODO(zerny): Add support for non-local exits, such as throw. |
| 135 UNREACHABLE(); | 135 UNREACHABLE(); |
| 136 } else if (num_exits == 1) { | 136 } else if (num_exits == 1) { |
| 137 // For just one exit, replace the uses and remove the call from the graph. | 137 // For just one exit, replace the uses and remove the call from the graph. |
| 138 call->ReplaceUsesWith(ValueAt(0)->definition()); | 138 call->ReplaceUsesWith(ValueAt(0)->definition()); |
| 139 ValueAt(0)->RemoveFromUseList(); |
| 139 call->previous()->LinkTo(callee_entry->next()); | 140 call->previous()->LinkTo(callee_entry->next()); |
| 140 LastInstructionAt(0)->LinkTo(call->next()); | 141 LastInstructionAt(0)->LinkTo(call->next()); |
| 141 // In case of control flow, locally update the predecessors, phis and | 142 // In case of control flow, locally update the predecessors, phis and |
| 142 // dominator tree. | 143 // dominator tree. |
| 143 // TODO(zerny): should we leave the dominator tree since we recompute it | 144 // TODO(zerny): should we leave the dominator tree since we recompute it |
| 144 // after a full inlining pass? | 145 // after a full inlining pass? |
| 145 if (callee_graph->preorder().length() > 2) { | 146 if (callee_graph->preorder().length() > 2) { |
| 146 BlockEntryInstr* exit_block = ExitBlockAt(0); | 147 BlockEntryInstr* exit_block = ExitBlockAt(0); |
| 147 // Pictorially, the graph structure is: | 148 // Pictorially, the graph structure is: |
| 148 // | 149 // |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 phi->set_ssa_temp_index(caller_graph->alloc_ssa_temp_index()); | 204 phi->set_ssa_temp_index(caller_graph->alloc_ssa_temp_index()); |
| 204 phi->mark_alive(); | 205 phi->mark_alive(); |
| 205 for (intptr_t i = 0; i < num_exits; ++i) { | 206 for (intptr_t i = 0; i < num_exits; ++i) { |
| 206 Value* value = ValueAt(i); | 207 Value* value = ValueAt(i); |
| 207 phi->SetInputAt(i, value); | 208 phi->SetInputAt(i, value); |
| 208 value->set_instruction(phi); | 209 value->set_instruction(phi); |
| 209 value->set_use_index(i); | 210 value->set_use_index(i); |
| 210 } | 211 } |
| 211 // Replace uses of the call with the phi. | 212 // Replace uses of the call with the phi. |
| 212 call->ReplaceUsesWith(phi); | 213 call->ReplaceUsesWith(phi); |
| 214 } else { |
| 215 // In the case that the result is unused, remove the return value uses |
| 216 // from their definition's use list. |
| 217 for (intptr_t i = 0; i < num_exits; ++i) { |
| 218 ValueAt(i)->RemoveFromUseList(); |
| 219 } |
| 213 } | 220 } |
| 214 // Remove the call from the graph. | 221 // Remove the call from the graph. |
| 215 call->previous()->LinkTo(callee_entry->next()); | 222 call->previous()->LinkTo(callee_entry->next()); |
| 216 join->LinkTo(call->next()); | 223 join->LinkTo(call->next()); |
| 217 // Replace the blocks after splitting (see comment in the len=1 case above). | 224 // Replace the blocks after splitting (see comment in the len=1 case above). |
| 218 caller_entry->ReplaceAsPredecessorWith(join); | 225 caller_entry->ReplaceAsPredecessorWith(join); |
| 219 callee_entry->ReplaceAsPredecessorWith(caller_entry); | 226 callee_entry->ReplaceAsPredecessorWith(caller_entry); |
| 220 // Update the last instruction pointers on each exit block to the new goto. | 227 // Update the last instruction pointers on each exit block to the new goto. |
| 221 for (intptr_t i = 0; i < num_exits; ++i) { | 228 for (intptr_t i = 0; i < num_exits; ++i) { |
| 222 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next()); | 229 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next()); |
| (...skipping 3019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3242 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3249 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3243 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3250 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3244 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3251 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3245 const Error& error = Error::Handle( | 3252 const Error& error = Error::Handle( |
| 3246 LanguageError::New(String::Handle(String::New(chars)))); | 3253 LanguageError::New(String::Handle(String::New(chars)))); |
| 3247 Isolate::Current()->long_jump_base()->Jump(1, error); | 3254 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3248 } | 3255 } |
| 3249 | 3256 |
| 3250 | 3257 |
| 3251 } // namespace dart | 3258 } // namespace dart |
| OLD | NEW |