| 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_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 return FLAG_enable_simd_inline; | 55 return FLAG_enable_simd_inline; |
| 56 } | 56 } |
| 57 | 57 |
| 58 | 58 |
| 59 // Optimize instance calls using ICData. | 59 // Optimize instance calls using ICData. |
| 60 void FlowGraphOptimizer::ApplyICData() { | 60 void FlowGraphOptimizer::ApplyICData() { |
| 61 VisitBlocks(); | 61 VisitBlocks(); |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 // Optimize instance calls using cid. | 65 // Optimize instance calls using cid. This is called after optimizer |
| 66 // converted instance calls to instructions. Any remaining |
| 67 // instance calls are either megamorphic calls, cannot be optimized or |
| 68 // have no runtime type feedback collected. |
| 66 // Attempts to convert an instance call (IC call) using propagated class-ids, | 69 // Attempts to convert an instance call (IC call) using propagated class-ids, |
| 67 // e.g., receiver class id, guarded-cid. | 70 // e.g., receiver class id, guarded-cid, or by guessing cid-s. |
| 68 void FlowGraphOptimizer::ApplyClassIds() { | 71 void FlowGraphOptimizer::ApplyClassIds() { |
| 69 ASSERT(current_iterator_ == NULL); | 72 ASSERT(current_iterator_ == NULL); |
| 70 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 73 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 71 BlockEntryInstr* entry = block_order_[i]; | 74 BlockEntryInstr* entry = block_order_[i]; |
| 72 ForwardInstructionIterator it(entry); | 75 ForwardInstructionIterator it(entry); |
| 73 current_iterator_ = ⁢ | 76 current_iterator_ = ⁢ |
| 74 for (; !it.Done(); it.Advance()) { | 77 for (; !it.Done(); it.Advance()) { |
| 75 Instruction* instr = it.Current(); | 78 Instruction* instr = it.Current(); |
| 76 if (instr->IsInstanceCall()) { | 79 if (instr->IsInstanceCall()) { |
| 77 InstanceCallInstr* call = instr->AsInstanceCall(); | 80 InstanceCallInstr* call = instr->AsInstanceCall(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 89 if (compare->IsStrictCompare()) { | 92 if (compare->IsStrictCompare()) { |
| 90 VisitStrictCompare(compare->AsStrictCompare()); | 93 VisitStrictCompare(compare->AsStrictCompare()); |
| 91 } | 94 } |
| 92 } | 95 } |
| 93 } | 96 } |
| 94 current_iterator_ = NULL; | 97 current_iterator_ = NULL; |
| 95 } | 98 } |
| 96 } | 99 } |
| 97 | 100 |
| 98 | 101 |
| 102 // TODO(srdjan): Test/support other number types as well. |
| 103 static bool IsNumberCid(intptr_t cid) { |
| 104 return (cid == kSmiCid) || (cid == kDoubleCid); |
| 105 } |
| 106 |
| 107 |
| 99 // Attempt to build ICData for call using propagated class-ids. | 108 // Attempt to build ICData for call using propagated class-ids. |
| 100 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) { | 109 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) { |
| 101 ASSERT(call->HasICData()); | 110 ASSERT(call->HasICData()); |
| 102 if (call->ic_data()->NumberOfChecks() > 0) { | 111 if (call->ic_data()->NumberOfChecks() > 0) { |
| 103 // This occurs when an instance call has too many checks. | 112 // This occurs when an instance call has too many checks, will be converted |
| 113 // to megamorphic call. |
| 104 return false; | 114 return false; |
| 105 } | 115 } |
| 106 GrowableArray<intptr_t> class_ids(call->ic_data()->num_args_tested()); | 116 GrowableArray<intptr_t> class_ids(call->ic_data()->num_args_tested()); |
| 107 ASSERT(call->ic_data()->num_args_tested() <= call->ArgumentCount()); | 117 ASSERT(call->ic_data()->num_args_tested() <= call->ArgumentCount()); |
| 108 for (intptr_t i = 0; i < call->ic_data()->num_args_tested(); i++) { | 118 for (intptr_t i = 0; i < call->ic_data()->num_args_tested(); i++) { |
| 109 intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid(); | 119 const intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid(); |
| 110 class_ids.Add(cid); | 120 class_ids.Add(cid); |
| 111 } | 121 } |
| 112 | 122 |
| 123 const Token::Kind op_kind = call->token_kind(); |
| 124 if (Token::IsRelationalOperator(op_kind) || |
| 125 Token::IsRelationalOperator(op_kind) || |
| 126 Token::IsBinaryOperator(op_kind)) { |
| 127 // Guess cid: if one of the inputs is a number assume that the other |
| 128 // is a number of same type. |
| 129 const intptr_t cid_0 = class_ids[0]; |
| 130 const intptr_t cid_1 = class_ids[1]; |
| 131 if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) { |
| 132 class_ids[0] = cid_1; |
| 133 } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) { |
| 134 class_ids[1] = cid_0; |
| 135 } |
| 136 } |
| 137 |
| 113 for (intptr_t i = 0; i < class_ids.length(); i++) { | 138 for (intptr_t i = 0; i < class_ids.length(); i++) { |
| 114 if (class_ids[i] == kDynamicCid) { | 139 if (class_ids[i] == kDynamicCid) { |
| 115 // Not all cid-s known. | 140 // Not all cid-s known. |
| 116 return false; | 141 return false; |
| 117 } | 142 } |
| 118 } | 143 } |
| 119 | 144 |
| 120 ArgumentsDescriptor args_desc( | 145 ArgumentsDescriptor args_desc( |
| 121 Array::Handle(ArgumentsDescriptor::New(call->ArgumentCount(), | 146 Array::Handle(ArgumentsDescriptor::New(call->ArgumentCount(), |
| 122 call->argument_names()))); | 147 call->argument_names()))); |
| (...skipping 7924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8047 } | 8072 } |
| 8048 | 8073 |
| 8049 // Insert materializations at environment uses. | 8074 // Insert materializations at environment uses. |
| 8050 for (intptr_t i = 0; i < exits.length(); i++) { | 8075 for (intptr_t i = 0; i < exits.length(); i++) { |
| 8051 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 8076 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
| 8052 } | 8077 } |
| 8053 } | 8078 } |
| 8054 | 8079 |
| 8055 | 8080 |
| 8056 } // namespace dart | 8081 } // namespace dart |
| OLD | NEW |