Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
| 6 | 6 |
| 7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/flow_graph.h" | 9 #include "vm/flow_graph.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 callee_graph->graph_entry()->normal_entry(); | 674 callee_graph->graph_entry()->normal_entry(); |
| 675 ClosureCallInstr* closure_call = call_data->call->AsClosureCall(); | 675 ClosureCallInstr* closure_call = call_data->call->AsClosureCall(); |
| 676 if (closure_call != NULL) { | 676 if (closure_call != NULL) { |
| 677 // TODO(fschneider): Avoid setting the context, if not needed. | 677 // TODO(fschneider): Avoid setting the context, if not needed. |
| 678 Definition* closure = | 678 Definition* closure = |
| 679 closure_call->PushArgumentAt(0)->value()->definition(); | 679 closure_call->PushArgumentAt(0)->value()->definition(); |
| 680 LoadFieldInstr* context = | 680 LoadFieldInstr* context = |
| 681 new LoadFieldInstr(new Value(closure), | 681 new LoadFieldInstr(new Value(closure), |
| 682 Closure::context_offset(), | 682 Closure::context_offset(), |
| 683 Type::ZoneHandle()); | 683 Type::ZoneHandle()); |
| 684 AllocateObjectInstr* alloc = | |
| 685 closure_call->ArgumentAt(0)->AsAllocateObject(); | |
| 686 if (alloc != NULL && !alloc->closure_function().IsNull()) { | |
|
srdjan
2013/08/01 00:54:47
Add ()
Florian Schneider
2013/08/05 14:41:55
Done.
| |
| 687 ASSERT(!alloc->context_field().IsNull()); | |
| 688 context->set_field(&alloc->context_field()); | |
| 689 } | |
| 690 | |
| 684 context->set_ssa_temp_index(caller_graph()->alloc_ssa_temp_index()); | 691 context->set_ssa_temp_index(caller_graph()->alloc_ssa_temp_index()); |
| 685 context->InsertAfter(callee_entry); | 692 context->InsertAfter(callee_entry); |
| 686 StoreContextInstr* set_context = | 693 StoreContextInstr* set_context = |
| 687 new StoreContextInstr(new Value(context)); | 694 new StoreContextInstr(new Value(context)); |
| 688 set_context->InsertAfter(context); | 695 set_context->InsertAfter(context); |
| 689 } | 696 } |
| 690 | 697 |
| 691 // Plug result in the caller graph. | 698 // Plug result in the caller graph. |
| 692 InlineExitCollector* exit_collector = call_data->exit_collector; | 699 InlineExitCollector* exit_collector = call_data->exit_collector; |
| 693 exit_collector->PrepareGraphs(callee_graph); | 700 exit_collector->PrepareGraphs(callee_graph); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 } | 803 } |
| 797 | 804 |
| 798 void InlineClosureCalls() { | 805 void InlineClosureCalls() { |
| 799 const GrowableArray<ClosureCallInstr*>& calls = | 806 const GrowableArray<ClosureCallInstr*>& calls = |
| 800 inlining_call_sites_->closure_calls(); | 807 inlining_call_sites_->closure_calls(); |
| 801 TRACE_INLINING(OS::Print(" Closure Calls (%d)\n", calls.length())); | 808 TRACE_INLINING(OS::Print(" Closure Calls (%d)\n", calls.length())); |
| 802 for (intptr_t i = 0; i < calls.length(); ++i) { | 809 for (intptr_t i = 0; i < calls.length(); ++i) { |
| 803 ClosureCallInstr* call = calls[i]; | 810 ClosureCallInstr* call = calls[i]; |
| 804 // Find the closure of the callee. | 811 // Find the closure of the callee. |
| 805 ASSERT(call->ArgumentCount() > 0); | 812 ASSERT(call->ArgumentCount() > 0); |
| 806 const CreateClosureInstr* closure = | 813 Function& target = Function::ZoneHandle(); |
| 814 CreateClosureInstr* closure = | |
| 807 call->ArgumentAt(0)->AsCreateClosure(); | 815 call->ArgumentAt(0)->AsCreateClosure(); |
| 808 if (closure == NULL) { | 816 if (closure != NULL) { |
| 817 target ^= closure->function().raw(); | |
| 818 } | |
| 819 AllocateObjectInstr* alloc = | |
| 820 call->ArgumentAt(0)->AsAllocateObject(); | |
| 821 if (alloc != NULL && !alloc->closure_function().IsNull()) { | |
|
srdjan
2013/08/01 00:54:47
add parentheses
Florian Schneider
2013/08/05 14:41:55
Done.
| |
| 822 target ^= alloc->closure_function().raw(); | |
| 823 ASSERT(target.signature_class() == alloc->cls().raw()); | |
| 824 } | |
| 825 if (target.IsNull()) { | |
| 809 TRACE_INLINING(OS::Print(" Bailout: non-closure operator\n")); | 826 TRACE_INLINING(OS::Print(" Bailout: non-closure operator\n")); |
| 810 continue; | 827 continue; |
| 811 } | 828 } |
| 812 GrowableArray<Value*> arguments(call->ArgumentCount()); | 829 GrowableArray<Value*> arguments(call->ArgumentCount()); |
| 813 for (int i = 0; i < call->ArgumentCount(); ++i) { | 830 for (int i = 0; i < call->ArgumentCount(); ++i) { |
| 814 arguments.Add(call->PushArgumentAt(i)->value()); | 831 arguments.Add(call->PushArgumentAt(i)->value()); |
| 815 } | 832 } |
| 816 InlinedCallData call_data(call, &arguments); | 833 InlinedCallData call_data(call, &arguments); |
| 817 if (TryInlining(closure->function(), | 834 if (TryInlining(target, |
| 818 call->argument_names(), | 835 call->argument_names(), |
| 819 &call_data)) { | 836 &call_data)) { |
| 820 InlineCall(&call_data); | 837 InlineCall(&call_data); |
| 821 } | 838 } |
| 822 } | 839 } |
| 823 } | 840 } |
| 824 | 841 |
| 825 void InlineInstanceCalls() { | 842 void InlineInstanceCalls() { |
| 826 const GrowableArray<CallSites::InstanceCallInfo>& call_info = | 843 const GrowableArray<CallSites::InstanceCallInfo>& call_info = |
| 827 inlining_call_sites_->instance_calls(); | 844 inlining_call_sites_->instance_calls(); |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1173 // Handle the two possible cases (unshared and shared subsequent | 1190 // Handle the two possible cases (unshared and shared subsequent |
| 1174 // predecessors) separately. | 1191 // predecessors) separately. |
| 1175 BlockEntryInstr* callee_entry = inlined_entries_[i]; | 1192 BlockEntryInstr* callee_entry = inlined_entries_[i]; |
| 1176 if (callee_entry->IsGraphEntry()) { | 1193 if (callee_entry->IsGraphEntry()) { |
| 1177 // Unshared. Graft the normal entry on after the check class | 1194 // Unshared. Graft the normal entry on after the check class |
| 1178 // instruction. | 1195 // instruction. |
| 1179 TargetEntryInstr* target = | 1196 TargetEntryInstr* target = |
| 1180 callee_entry->AsGraphEntry()->normal_entry(); | 1197 callee_entry->AsGraphEntry()->normal_entry(); |
| 1181 cursor->LinkTo(target->next()); | 1198 cursor->LinkTo(target->next()); |
| 1182 target->ReplaceAsPredecessorWith(current_block); | 1199 target->ReplaceAsPredecessorWith(current_block); |
| 1200 | |
| 1201 // Unuse the graph entry. It is not in the graph anymore. | |
| 1202 callee_entry->UnuseAllInputs(); | |
|
Florian Schneider
2013/07/31 13:52:28
I created a separate CL with a regression test for
| |
| 1203 | |
| 1183 // All blocks that were dominated by the normal entry are now | 1204 // All blocks that were dominated by the normal entry are now |
| 1184 // dominated by the current block. | 1205 // dominated by the current block. |
| 1185 for (intptr_t j = 0; | 1206 for (intptr_t j = 0; |
| 1186 j < target->dominated_blocks().length(); | 1207 j < target->dominated_blocks().length(); |
| 1187 ++j) { | 1208 ++j) { |
| 1188 BlockEntryInstr* block = target->dominated_blocks()[j]; | 1209 BlockEntryInstr* block = target->dominated_blocks()[j]; |
| 1189 current_block->AddDominatedBlock(block); | 1210 current_block->AddDominatedBlock(block); |
| 1190 } | 1211 } |
| 1191 } else if (callee_entry->IsJoinEntry()) { | 1212 } else if (callee_entry->IsJoinEntry()) { |
| 1192 // Shared inlined body and this is a subsequent entry. We have | 1213 // Shared inlined body and this is a subsequent entry. We have |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1223 cursor = NULL; | 1244 cursor = NULL; |
| 1224 | 1245 |
| 1225 // 2. Handle a match by linking to the inlined body. There are three | 1246 // 2. Handle a match by linking to the inlined body. There are three |
| 1226 // cases (unshared, shared first predecessor, and shared subsequent | 1247 // cases (unshared, shared first predecessor, and shared subsequent |
| 1227 // predecessors). | 1248 // predecessors). |
| 1228 BlockEntryInstr* callee_entry = inlined_entries_[i]; | 1249 BlockEntryInstr* callee_entry = inlined_entries_[i]; |
| 1229 TargetEntryInstr* true_target = NULL; | 1250 TargetEntryInstr* true_target = NULL; |
| 1230 if (callee_entry->IsGraphEntry()) { | 1251 if (callee_entry->IsGraphEntry()) { |
| 1231 // Unshared. | 1252 // Unshared. |
| 1232 true_target = callee_entry->AsGraphEntry()->normal_entry(); | 1253 true_target = callee_entry->AsGraphEntry()->normal_entry(); |
| 1254 | |
| 1255 // Unuse the graph entry. It is not in the graph anymore. | |
| 1256 callee_entry->UnuseAllInputs(); | |
| 1257 | |
| 1233 } else if (callee_entry->IsTargetEntry()) { | 1258 } else if (callee_entry->IsTargetEntry()) { |
| 1234 // Shared inlined body and this is the first entry. We have already | 1259 // Shared inlined body and this is the first entry. We have already |
| 1235 // constructed a join and this target jumps to it. | 1260 // constructed a join and this target jumps to it. |
| 1236 true_target = callee_entry->AsTargetEntry(); | 1261 true_target = callee_entry->AsTargetEntry(); |
| 1237 BlockEntryInstr* join = | 1262 BlockEntryInstr* join = |
| 1238 true_target->last_instruction()->SuccessorAt(0); | 1263 true_target->last_instruction()->SuccessorAt(0); |
| 1239 current_block->AddDominatedBlock(join); | 1264 current_block->AddDominatedBlock(join); |
| 1240 } else { | 1265 } else { |
| 1241 // Shared inlined body and this is a subsequent entry. We have | 1266 // Shared inlined body and this is a subsequent entry. We have |
| 1242 // already constructed a join. We need a fresh target that jumps to | 1267 // already constructed a join. We need a fresh target that jumps to |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1401 OS::Print("After Inlining of %s\n", flow_graph_-> | 1426 OS::Print("After Inlining of %s\n", flow_graph_-> |
| 1402 parsed_function().function().ToFullyQualifiedCString()); | 1427 parsed_function().function().ToFullyQualifiedCString()); |
| 1403 FlowGraphPrinter printer(*flow_graph_); | 1428 FlowGraphPrinter printer(*flow_graph_); |
| 1404 printer.PrintBlocks(); | 1429 printer.PrintBlocks(); |
| 1405 } | 1430 } |
| 1406 } | 1431 } |
| 1407 } | 1432 } |
| 1408 } | 1433 } |
| 1409 | 1434 |
| 1410 } // namespace dart | 1435 } // namespace dart |
| OLD | NEW |