| 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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 class_ids.Add(kMintCid); | 238 class_ids.Add(kMintCid); |
| 239 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids); | 239 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids); |
| 240 } | 240 } |
| 241 | 241 |
| 242 | 242 |
| 243 static bool HasOneDouble(const ICData& ic_data) { | 243 static bool HasOneDouble(const ICData& ic_data) { |
| 244 return ICDataHasReceiverClassId(ic_data, kDoubleCid); | 244 return ICDataHasReceiverClassId(ic_data, kDoubleCid); |
| 245 } | 245 } |
| 246 | 246 |
| 247 | 247 |
| 248 static bool HasOnlyTwoDouble(const ICData& ic_data) { | 248 static bool ShouldSpecializeForDouble(const ICData& ic_data) { |
| 249 return (ic_data.NumberOfChecks() == 1) && | 249 if (ic_data.NumberOfChecks() != 1) return false; |
| 250 ICDataHasReceiverArgumentClassIds(ic_data, kDoubleCid, kDoubleCid); | 250 if (ic_data.num_args_tested() != 2) return false; |
| 251 |
| 252 Function& target = Function::Handle(); |
| 253 GrowableArray<intptr_t> class_ids; |
| 254 ic_data.GetCheckAt(0, &class_ids, &target); |
| 255 ASSERT(class_ids.length() == 2); |
| 256 |
| 257 const bool seen_double = |
| 258 (class_ids[0] == kDoubleCid) || (class_ids[1] == kDoubleCid); |
| 259 |
| 260 const bool seen_only_smi_or_double = |
| 261 ((class_ids[0] == kDoubleCid) || (class_ids[0] == kSmiCid)) && |
| 262 ((class_ids[1] == kDoubleCid) || (class_ids[1] == kSmiCid)); |
| 263 |
| 264 return seen_double && seen_only_smi_or_double; |
| 251 } | 265 } |
| 252 | 266 |
| 253 | 267 |
| 254 static void RemovePushArguments(InstanceCallComp* comp) { | 268 static void RemovePushArguments(InstanceCallComp* comp) { |
| 255 // Remove original push arguments. | 269 // Remove original push arguments. |
| 256 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { | 270 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { |
| 257 PushArgumentInstr* push = comp->ArgumentAt(i); | 271 PushArgumentInstr* push = comp->ArgumentAt(i); |
| 258 push->ReplaceUsesWith(push->value()->definition()); | 272 push->ReplaceUsesWith(push->value()->definition()); |
| 259 push->RemoveFromGraph(); | 273 push->RemoveFromGraph(); |
| 260 } | 274 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 Token::Kind op_kind) { | 403 Token::Kind op_kind) { |
| 390 intptr_t operands_type = kIllegalCid; | 404 intptr_t operands_type = kIllegalCid; |
| 391 ASSERT(comp->HasICData()); | 405 ASSERT(comp->HasICData()); |
| 392 const ICData& ic_data = *comp->ic_data(); | 406 const ICData& ic_data = *comp->ic_data(); |
| 393 switch (op_kind) { | 407 switch (op_kind) { |
| 394 case Token::kADD: | 408 case Token::kADD: |
| 395 case Token::kSUB: | 409 case Token::kSUB: |
| 396 case Token::kMUL: | 410 case Token::kMUL: |
| 397 if (HasOnlyTwoSmi(ic_data)) { | 411 if (HasOnlyTwoSmi(ic_data)) { |
| 398 operands_type = kSmiCid; | 412 operands_type = kSmiCid; |
| 399 } else if (HasOnlyTwoDouble(ic_data)) { | 413 } else if (ShouldSpecializeForDouble(ic_data)) { |
| 400 operands_type = kDoubleCid; | 414 operands_type = kDoubleCid; |
| 401 } else { | 415 } else { |
| 402 return false; | 416 return false; |
| 403 } | 417 } |
| 404 break; | 418 break; |
| 405 case Token::kDIV: | 419 case Token::kDIV: |
| 406 case Token::kMOD: | 420 if (ShouldSpecializeForDouble(ic_data)) { |
| 407 if (HasOnlyTwoDouble(ic_data)) { | |
| 408 operands_type = kDoubleCid; | 421 operands_type = kDoubleCid; |
| 409 } else { | 422 } else { |
| 410 return false; | 423 return false; |
| 411 } | 424 } |
| 425 break; |
| 426 case Token::kMOD: |
| 427 // TODO(vegorov): implement fast path code for modulo. |
| 428 return false; |
| 412 case Token::kBIT_AND: | 429 case Token::kBIT_AND: |
| 413 if (HasOnlyTwoSmi(ic_data)) { | 430 if (HasOnlyTwoSmi(ic_data)) { |
| 414 operands_type = kSmiCid; | 431 operands_type = kSmiCid; |
| 415 } else if (HasTwoMintOrSmi(ic_data)) { | 432 } else if (HasTwoMintOrSmi(ic_data)) { |
| 416 operands_type = kMintCid; | 433 operands_type = kMintCid; |
| 417 } else { | 434 } else { |
| 418 return false; | 435 return false; |
| 419 } | 436 } |
| 420 break; | 437 break; |
| 421 case Token::kBIT_OR: | 438 case Token::kBIT_OR: |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 if (!comp->HasICData()) return; | 800 if (!comp->HasICData()) return; |
| 784 | 801 |
| 785 const ICData& ic_data = *comp->ic_data(); | 802 const ICData& ic_data = *comp->ic_data(); |
| 786 if (ic_data.NumberOfChecks() == 0) return; | 803 if (ic_data.NumberOfChecks() == 0) return; |
| 787 // TODO(srdjan): Add multiple receiver type support. | 804 // TODO(srdjan): Add multiple receiver type support. |
| 788 if (ic_data.NumberOfChecks() != 1) return; | 805 if (ic_data.NumberOfChecks() != 1) return; |
| 789 ASSERT(HasOneTarget(ic_data)); | 806 ASSERT(HasOneTarget(ic_data)); |
| 790 | 807 |
| 791 if (HasOnlyTwoSmi(ic_data)) { | 808 if (HasOnlyTwoSmi(ic_data)) { |
| 792 comp->set_operands_class_id(kSmiCid); | 809 comp->set_operands_class_id(kSmiCid); |
| 793 } else if (HasOnlyTwoDouble(ic_data)) { | 810 } else if (ShouldSpecializeForDouble(ic_data)) { |
| 794 comp->set_operands_class_id(kDoubleCid); | 811 comp->set_operands_class_id(kDoubleCid); |
| 795 } else if (comp->ic_data()->AllReceiversAreNumbers()) { | 812 } else if (comp->ic_data()->AllReceiversAreNumbers()) { |
| 796 comp->set_operands_class_id(kNumberCid); | 813 comp->set_operands_class_id(kNumberCid); |
| 797 } | 814 } |
| 798 } | 815 } |
| 799 | 816 |
| 800 | 817 |
| 801 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareComp* comp, | 818 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareComp* comp, |
| 802 BindInstr* instr) { | 819 BindInstr* instr) { |
| 803 // If one of the inputs is null, no ICdata will be collected. | 820 // If one of the inputs is null, no ICdata will be collected. |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1148 DirectChainedHashMap<BindInstr*> child_map(*map); // Copy map. | 1165 DirectChainedHashMap<BindInstr*> child_map(*map); // Copy map. |
| 1149 OptimizeRecursive(child, &child_map); | 1166 OptimizeRecursive(child, &child_map); |
| 1150 } else { | 1167 } else { |
| 1151 OptimizeRecursive(child, map); // Reuse map for the last child. | 1168 OptimizeRecursive(child, map); // Reuse map for the last child. |
| 1152 } | 1169 } |
| 1153 } | 1170 } |
| 1154 } | 1171 } |
| 1155 | 1172 |
| 1156 | 1173 |
| 1157 } // namespace dart | 1174 } // namespace dart |
| OLD | NEW |