| 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_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/cha.h" | 7 #include "vm/cha.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/hash_map.h" | 9 #include "vm/hash_map.h" |
| 10 #include "vm/il_printer.h" | 10 #include "vm/il_printer.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 static bool HasOnlyTwoDouble(const ICData& ic_data) { | 146 static bool HasOnlyTwoDouble(const ICData& ic_data) { |
| 147 return (ic_data.NumberOfChecks() == 1) && | 147 return (ic_data.NumberOfChecks() == 1) && |
| 148 ICDataHasReceiverArgumentClassIds(ic_data, kDoubleCid, kDoubleCid); | 148 ICDataHasReceiverArgumentClassIds(ic_data, kDoubleCid, kDoubleCid); |
| 149 } | 149 } |
| 150 | 150 |
| 151 | 151 |
| 152 static void RemovePushArguments(InstanceCallComp* comp) { | 152 static void RemovePushArguments(InstanceCallComp* comp) { |
| 153 // Remove original push arguments. | 153 // Remove original push arguments. |
| 154 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { | 154 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { |
| 155 PushArgumentInstr* push = comp->ArgumentAt(i); | 155 PushArgumentInstr* push = comp->ArgumentAt(i); |
| 156 // TODO(zerny): Currently the register allocator replaces unused pushes with | |
| 157 // their definitions. To do so here, we need first to link uses to their | |
| 158 // instructions and input index. Here push->ReplaceUsesWith requires that | |
| 159 // push->value() is a UseVal. | |
| 160 // (See FlowGraphAllocator::EliminateEnvironmentUses). | |
| 161 push->set_use_list(NULL); | |
| 162 push->RemoveFromGraph(); | 156 push->RemoveFromGraph(); |
| 163 } | 157 } |
| 164 } | 158 } |
| 165 | 159 |
| 166 | 160 |
| 167 // Returns true if all targets are the same. | 161 // Returns true if all targets are the same. |
| 168 // TODO(srdjan): if targets are native use their C_function to compare. | 162 // TODO(srdjan): if targets are native use their C_function to compare. |
| 169 static bool HasOneTarget(const ICData& ic_data) { | 163 static bool HasOneTarget(const ICData& ic_data) { |
| 170 ASSERT(ic_data.NumberOfChecks() > 0); | 164 ASSERT(ic_data.NumberOfChecks() > 0); |
| 171 const Function& first_target = Function::Handle(ic_data.GetTargetAt(0)); | 165 const Function& first_target = Function::Handle(ic_data.GetTargetAt(0)); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 bin_op->set_ic_data(comp->ic_data()); | 322 bin_op->set_ic_data(comp->ic_data()); |
| 329 instr->set_computation(bin_op); | 323 instr->set_computation(bin_op); |
| 330 RemovePushArguments(comp); | 324 RemovePushArguments(comp); |
| 331 } else { | 325 } else { |
| 332 ASSERT(operands_type == kSmiCid); | 326 ASSERT(operands_type == kSmiCid); |
| 333 Value* left = comp->ArgumentAt(0)->value(); | 327 Value* left = comp->ArgumentAt(0)->value(); |
| 334 Value* right = comp->ArgumentAt(1)->value(); | 328 Value* right = comp->ArgumentAt(1)->value(); |
| 335 // Insert two smi checks and attach a copy of the original | 329 // Insert two smi checks and attach a copy of the original |
| 336 // environment because the smi operation can still deoptimize. | 330 // environment because the smi operation can still deoptimize. |
| 337 InsertCheckBefore(instr, | 331 InsertCheckBefore(instr, |
| 338 new CheckSmiComp(left, comp), | 332 new CheckSmiComp(left->CopyValue(), comp), |
| 339 instr->env()->Copy()); | 333 instr->env()->Copy()); |
| 340 InsertCheckBefore(instr, | 334 InsertCheckBefore(instr, |
| 341 new CheckSmiComp(right, comp), | 335 new CheckSmiComp(right->CopyValue(), comp), |
| 342 instr->env()->Copy()); | 336 instr->env()->Copy()); |
| 343 BinarySmiOpComp* bin_op = new BinarySmiOpComp(op_kind, | 337 BinarySmiOpComp* bin_op = new BinarySmiOpComp(op_kind, |
| 344 comp, | 338 comp, |
| 345 left, | 339 left, |
| 346 right); | 340 right); |
| 347 bin_op->set_ic_data(comp->ic_data()); | 341 bin_op->set_ic_data(comp->ic_data()); |
| 348 instr->set_computation(bin_op); | 342 instr->set_computation(bin_op); |
| 349 RemovePushArguments(comp); | 343 RemovePushArguments(comp); |
| 350 } | 344 } |
| 351 return true; | 345 return true; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 if (!HasOneTarget(ic_data)) { | 402 if (!HasOneTarget(ic_data)) { |
| 409 // TODO(srdjan): Implement for mutiple targets. | 403 // TODO(srdjan): Implement for mutiple targets. |
| 410 return false; | 404 return false; |
| 411 } | 405 } |
| 412 // Inline implicit instance getter. | 406 // Inline implicit instance getter. |
| 413 const String& field_name = | 407 const String& field_name = |
| 414 String::Handle(Field::NameFromGetter(comp->function_name())); | 408 String::Handle(Field::NameFromGetter(comp->function_name())); |
| 415 const Field& field = Field::Handle(GetField(class_ids[0], field_name)); | 409 const Field& field = Field::Handle(GetField(class_ids[0], field_name)); |
| 416 ASSERT(!field.IsNull()); | 410 ASSERT(!field.IsNull()); |
| 417 | 411 |
| 418 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()); | 412 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()->CopyValue()); |
| 419 LoadInstanceFieldComp* load = | 413 LoadInstanceFieldComp* load = |
| 420 new LoadInstanceFieldComp(field, | 414 new LoadInstanceFieldComp(field, |
| 421 comp->ArgumentAt(0)->value(), | 415 comp->ArgumentAt(0)->value(), |
| 422 NULL); // Can not deoptimize. | 416 NULL); // Can not deoptimize. |
| 423 instr->set_computation(load); | 417 instr->set_computation(load); |
| 424 RemovePushArguments(comp); | 418 RemovePushArguments(comp); |
| 425 return true; | 419 return true; |
| 426 } | 420 } |
| 427 | 421 |
| 428 // Not an implicit getter. | 422 // Not an implicit getter. |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 // Not an implicit setter. | 582 // Not an implicit setter. |
| 589 // TODO(srdjan): Inline special setters. | 583 // TODO(srdjan): Inline special setters. |
| 590 return false; | 584 return false; |
| 591 } | 585 } |
| 592 // Inline implicit instance setter. | 586 // Inline implicit instance setter. |
| 593 const String& field_name = | 587 const String& field_name = |
| 594 String::Handle(Field::NameFromSetter(comp->function_name())); | 588 String::Handle(Field::NameFromSetter(comp->function_name())); |
| 595 const Field& field = Field::Handle(GetField(class_id, field_name)); | 589 const Field& field = Field::Handle(GetField(class_id, field_name)); |
| 596 ASSERT(!field.IsNull()); | 590 ASSERT(!field.IsNull()); |
| 597 | 591 |
| 598 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()); | 592 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()->CopyValue()); |
| 599 StoreInstanceFieldComp* store = new StoreInstanceFieldComp( | 593 StoreInstanceFieldComp* store = new StoreInstanceFieldComp( |
| 600 field, | 594 field, |
| 601 comp->ArgumentAt(0)->value(), | 595 comp->ArgumentAt(0)->value(), |
| 602 comp->ArgumentAt(1)->value(), | 596 comp->ArgumentAt(1)->value(), |
| 603 NULL); // Can not deoptimize. | 597 NULL); // Can not deoptimize. |
| 604 instr->set_computation(store); | 598 instr->set_computation(store); |
| 605 RemovePushArguments(comp); | 599 RemovePushArguments(comp); |
| 606 return true; | 600 return true; |
| 607 } | 601 } |
| 608 | 602 |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 OS::Print("Replacing v%d with v%d\n", | 969 OS::Print("Replacing v%d with v%d\n", |
| 976 instr->ssa_temp_index(), | 970 instr->ssa_temp_index(), |
| 977 result->ssa_temp_index()); | 971 result->ssa_temp_index()); |
| 978 } | 972 } |
| 979 } | 973 } |
| 980 } | 974 } |
| 981 } | 975 } |
| 982 | 976 |
| 983 | 977 |
| 984 } // namespace dart | 978 } // namespace dart |
| OLD | NEW |