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