| 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/block_scheduler.h" | 7 #include "vm/block_scheduler.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/flow_graph.h" | 10 #include "vm/flow_graph.h" |
| (...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 | 1312 |
| 1313 // Replace parameter stubs and constants. Replace the receiver argument | 1313 // Replace parameter stubs and constants. Replace the receiver argument |
| 1314 // with a redefinition to prevent code from the inlined body from being | 1314 // with a redefinition to prevent code from the inlined body from being |
| 1315 // hoisted above the inlined entry. | 1315 // hoisted above the inlined entry. |
| 1316 ASSERT(arguments.length() > 0); | 1316 ASSERT(arguments.length() > 0); |
| 1317 Value* actual = arguments[0]; | 1317 Value* actual = arguments[0]; |
| 1318 RedefinitionInstr* redefinition = new(isolate()) | 1318 RedefinitionInstr* redefinition = new(isolate()) |
| 1319 RedefinitionInstr(actual->Copy(isolate())); | 1319 RedefinitionInstr(actual->Copy(isolate())); |
| 1320 redefinition->set_ssa_temp_index( | 1320 redefinition->set_ssa_temp_index( |
| 1321 owner_->caller_graph()->alloc_ssa_temp_index()); | 1321 owner_->caller_graph()->alloc_ssa_temp_index()); |
| 1322 redefinition->UpdateType(CompileType::FromCid(receiver_cid)); |
| 1322 redefinition->InsertAfter(callee_graph->graph_entry()->normal_entry()); | 1323 redefinition->InsertAfter(callee_graph->graph_entry()->normal_entry()); |
| 1323 Definition* stub = (*call_data.parameter_stubs)[0]; | 1324 Definition* stub = (*call_data.parameter_stubs)[0]; |
| 1324 stub->ReplaceUsesWith(redefinition); | 1325 stub->ReplaceUsesWith(redefinition); |
| 1325 | 1326 |
| 1326 for (intptr_t i = 1; i < arguments.length(); ++i) { | 1327 for (intptr_t i = 1; i < arguments.length(); ++i) { |
| 1327 actual = arguments[i]; | 1328 actual = arguments[i]; |
| 1328 if (actual != NULL) { | 1329 if (actual != NULL) { |
| 1329 stub = (*call_data.parameter_stubs)[i]; | 1330 stub = (*call_data.parameter_stubs)[i]; |
| 1330 stub->ReplaceUsesWith(actual->definition()); | 1331 stub->ReplaceUsesWith(actual->definition()); |
| 1331 } | 1332 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1426 // There are at least two variants including non-inlined ones, so we have | 1427 // There are at least two variants including non-inlined ones, so we have |
| 1427 // at least one branch on the class id. | 1428 // at least one branch on the class id. |
| 1428 LoadClassIdInstr* load_cid = | 1429 LoadClassIdInstr* load_cid = |
| 1429 new(isolate()) LoadClassIdInstr(new(isolate()) Value(receiver)); | 1430 new(isolate()) LoadClassIdInstr(new(isolate()) Value(receiver)); |
| 1430 load_cid->set_ssa_temp_index(owner_->caller_graph()->alloc_ssa_temp_index()); | 1431 load_cid->set_ssa_temp_index(owner_->caller_graph()->alloc_ssa_temp_index()); |
| 1431 cursor = AppendInstruction(cursor, load_cid); | 1432 cursor = AppendInstruction(cursor, load_cid); |
| 1432 for (intptr_t i = 0; i < inlined_variants_.length(); ++i) { | 1433 for (intptr_t i = 0; i < inlined_variants_.length(); ++i) { |
| 1433 // 1. Guard the body with a class id check. | 1434 // 1. Guard the body with a class id check. |
| 1434 if ((i == (inlined_variants_.length() - 1)) && | 1435 if ((i == (inlined_variants_.length() - 1)) && |
| 1435 non_inlined_variants_.is_empty()) { | 1436 non_inlined_variants_.is_empty()) { |
| 1436 // If it is the last variant use a check class or check smi | 1437 // If it is the last variant use a check class id instruction which can |
| 1437 // instruction which can deoptimize, followed unconditionally by the | 1438 // deoptimize, followed unconditionally by the body. |
| 1438 // body. Check a redefinition of the receiver, to prevent the check | 1439 const Smi& cid = Smi::ZoneHandle(Smi::New(inlined_variants_[i].cid)); |
| 1439 // from being hoisted. | 1440 ConstantInstr* cid_constant = new(isolate()) ConstantInstr(cid); |
| 1440 RedefinitionInstr* redefinition = | 1441 cid_constant->set_ssa_temp_index( |
| 1441 new(isolate()) RedefinitionInstr(new(isolate()) Value(receiver)); | |
| 1442 redefinition->set_ssa_temp_index( | |
| 1443 owner_->caller_graph()->alloc_ssa_temp_index()); | 1442 owner_->caller_graph()->alloc_ssa_temp_index()); |
| 1444 cursor = AppendInstruction(cursor, redefinition); | 1443 cursor = AppendInstruction(cursor, cid_constant); |
| 1445 if (inlined_variants_[i].cid == kSmiCid) { | 1444 |
| 1446 CheckSmiInstr* check_smi = | 1445 CheckClassIdInstr* check_class_id = |
| 1447 new CheckSmiInstr(new Value(redefinition), | 1446 new(isolate()) CheckClassIdInstr(new(isolate()) Value(load_cid), |
| 1448 call_->deopt_id(), | 1447 new(isolate()) Value(cid_constant), |
| 1449 call_->token_pos()); | 1448 call_->deopt_id()); |
| 1450 check_smi->InheritDeoptTarget(isolate(), call_); | 1449 check_class_id->InheritDeoptTarget(isolate(), call_); |
| 1451 cursor = AppendInstruction(cursor, check_smi); | 1450 cursor = AppendInstruction(cursor, check_class_id); |
| 1452 } else { | 1451 |
| 1453 const ICData& old_checks = call_->ic_data(); | |
| 1454 const ICData& new_checks = ICData::ZoneHandle( | |
| 1455 ICData::New(Function::Handle(old_checks.owner()), | |
| 1456 String::Handle(old_checks.target_name()), | |
| 1457 Array::Handle(old_checks.arguments_descriptor()), | |
| 1458 old_checks.deopt_id(), | |
| 1459 1)); // Number of args tested. | |
| 1460 new_checks.AddReceiverCheck(inlined_variants_[i].cid, | |
| 1461 *inlined_variants_[i].target); | |
| 1462 CheckClassInstr* check_class = | |
| 1463 new CheckClassInstr(new Value(redefinition), | |
| 1464 call_->deopt_id(), | |
| 1465 new_checks, | |
| 1466 call_->token_pos()); | |
| 1467 check_class->InheritDeoptTarget(isolate(), call_); | |
| 1468 cursor = AppendInstruction(cursor, check_class); | |
| 1469 } | |
| 1470 // The next instruction is the first instruction of the inlined body. | 1452 // The next instruction is the first instruction of the inlined body. |
| 1471 // Handle the two possible cases (unshared and shared subsequent | 1453 // Handle the two possible cases (unshared and shared subsequent |
| 1472 // predecessors) separately. | 1454 // predecessors) separately. |
| 1473 BlockEntryInstr* callee_entry = inlined_entries_[i]; | 1455 BlockEntryInstr* callee_entry = inlined_entries_[i]; |
| 1474 if (callee_entry->IsGraphEntry()) { | 1456 if (callee_entry->IsGraphEntry()) { |
| 1475 // Unshared. Graft the normal entry on after the check class | 1457 // Unshared. Graft the normal entry on after the check class |
| 1476 // instruction. | 1458 // instruction. |
| 1477 TargetEntryInstr* target = | 1459 TargetEntryInstr* target = |
| 1478 callee_entry->AsGraphEntry()->normal_entry(); | 1460 callee_entry->AsGraphEntry()->normal_entry(); |
| 1479 cursor->LinkTo(target->next()); | 1461 cursor->LinkTo(target->next()); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1726 OS::Print("After Inlining of %s\n", flow_graph_-> | 1708 OS::Print("After Inlining of %s\n", flow_graph_-> |
| 1727 parsed_function().function().ToFullyQualifiedCString()); | 1709 parsed_function().function().ToFullyQualifiedCString()); |
| 1728 FlowGraphPrinter printer(*flow_graph_); | 1710 FlowGraphPrinter printer(*flow_graph_); |
| 1729 printer.PrintBlocks(); | 1711 printer.PrintBlocks(); |
| 1730 } | 1712 } |
| 1731 } | 1713 } |
| 1732 } | 1714 } |
| 1733 } | 1715 } |
| 1734 | 1716 |
| 1735 } // namespace dart | 1717 } // namespace dart |
| OLD | NEW |