Chromium Code Reviews| 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/compiler.h" | |
| 9 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| 10 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
| 11 #include "vm/exceptions.h" | 12 #include "vm/exceptions.h" |
| 12 #include "vm/flow_graph_builder.h" | 13 #include "vm/flow_graph_builder.h" |
| 13 #include "vm/flow_graph_compiler.h" | 14 #include "vm/flow_graph_compiler.h" |
| 14 #include "vm/flow_graph_range_analysis.h" | 15 #include "vm/flow_graph_range_analysis.h" |
| 15 #include "vm/hash_map.h" | 16 #include "vm/hash_map.h" |
| 16 #include "vm/il_printer.h" | 17 #include "vm/il_printer.h" |
| 17 #include "vm/intermediate_language.h" | 18 #include "vm/intermediate_language.h" |
| 18 #include "vm/object_store.h" | 19 #include "vm/object_store.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 #endif | 81 #endif |
| 81 } | 82 } |
| 82 | 83 |
| 83 | 84 |
| 84 // Optimize instance calls using ICData. | 85 // Optimize instance calls using ICData. |
| 85 void FlowGraphOptimizer::ApplyICData() { | 86 void FlowGraphOptimizer::ApplyICData() { |
| 86 VisitBlocks(); | 87 VisitBlocks(); |
| 87 } | 88 } |
| 88 | 89 |
| 89 | 90 |
| 91 void FlowGraphOptimizer::PopulateWithICData() { | |
| 92 ASSERT(current_iterator_ == NULL); | |
| 93 for (intptr_t i = 0; i < block_order_.length(); ++i) { | |
| 94 BlockEntryInstr* entry = block_order_[i]; | |
| 95 ForwardInstructionIterator it(entry); | |
| 96 current_iterator_ = ⁢ | |
|
Florian Schneider
2015/05/21 14:51:05
I don't think you need to use the current_iterator
srdjan
2015/05/21 17:27:07
Done.
| |
| 97 for (; !it.Done(); it.Advance()) { | |
| 98 Instruction* instr = it.Current(); | |
| 99 if (instr->IsInstanceCall()) { | |
| 100 InstanceCallInstr* call = instr->AsInstanceCall(); | |
| 101 if (!call->HasICData()) { | |
| 102 const Array& arguments_descriptor = | |
| 103 Array::Handle(zone(), | |
| 104 ArgumentsDescriptor::New(call->ArgumentCount(), | |
| 105 call->argument_names())); | |
| 106 const ICData& ic_data = ICData::ZoneHandle(zone(), ICData::New( | |
| 107 function(), call->function_name(), | |
| 108 arguments_descriptor, call->deopt_id(), | |
| 109 call->checked_argument_count())); | |
| 110 call->set_ic_data(&ic_data); | |
| 111 } | |
| 112 } | |
| 113 } | |
| 114 current_iterator_ = NULL; | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 | |
| 90 // Optimize instance calls using cid. This is called after optimizer | 119 // Optimize instance calls using cid. This is called after optimizer |
| 91 // converted instance calls to instructions. Any remaining | 120 // converted instance calls to instructions. Any remaining |
| 92 // instance calls are either megamorphic calls, cannot be optimized or | 121 // instance calls are either megamorphic calls, cannot be optimized or |
| 93 // have no runtime type feedback collected. | 122 // have no runtime type feedback collected. |
| 94 // Attempts to convert an instance call (IC call) using propagated class-ids, | 123 // Attempts to convert an instance call (IC call) using propagated class-ids, |
| 95 // e.g., receiver class id, guarded-cid, or by guessing cid-s. | 124 // e.g., receiver class id, guarded-cid, or by guessing cid-s. |
| 96 void FlowGraphOptimizer::ApplyClassIds() { | 125 void FlowGraphOptimizer::ApplyClassIds() { |
| 97 ASSERT(current_iterator_ == NULL); | 126 ASSERT(current_iterator_ == NULL); |
| 98 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 127 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 99 BlockEntryInstr* entry = block_order_[i]; | 128 BlockEntryInstr* entry = block_order_[i]; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 const intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid(); | 184 const intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid(); |
| 156 class_ids.Add(cid); | 185 class_ids.Add(cid); |
| 157 } | 186 } |
| 158 | 187 |
| 159 const Token::Kind op_kind = call->token_kind(); | 188 const Token::Kind op_kind = call->token_kind(); |
| 160 if (Token::IsRelationalOperator(op_kind) || | 189 if (Token::IsRelationalOperator(op_kind) || |
| 161 Token::IsEqualityOperator(op_kind) || | 190 Token::IsEqualityOperator(op_kind) || |
| 162 Token::IsBinaryOperator(op_kind)) { | 191 Token::IsBinaryOperator(op_kind)) { |
| 163 // Guess cid: if one of the inputs is a number assume that the other | 192 // Guess cid: if one of the inputs is a number assume that the other |
| 164 // is a number of same type. | 193 // is a number of same type. |
| 165 const intptr_t cid_0 = class_ids[0]; | 194 if (Compiler::guess_other_cid()) { |
| 166 const intptr_t cid_1 = class_ids[1]; | 195 const intptr_t cid_0 = class_ids[0]; |
| 167 if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) { | 196 const intptr_t cid_1 = class_ids[1]; |
| 168 class_ids[0] = cid_1; | 197 if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) { |
| 169 } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) { | 198 class_ids[0] = cid_1; |
| 170 class_ids[1] = cid_0; | 199 } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) { |
| 200 class_ids[1] = cid_0; | |
| 201 } | |
| 171 } | 202 } |
| 172 } | 203 } |
| 173 | 204 |
| 174 for (intptr_t i = 0; i < class_ids.length(); i++) { | 205 for (intptr_t i = 0; i < class_ids.length(); i++) { |
| 175 if (class_ids[i] == kDynamicCid) { | 206 if (class_ids[i] == kDynamicCid) { |
| 176 // Not all cid-s known. | 207 // Not all cid-s known. |
| 177 return false; | 208 return false; |
| 178 } | 209 } |
| 179 } | 210 } |
| 180 | 211 |
| (...skipping 3981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4162 | 4193 |
| 4163 | 4194 |
| 4164 // Tries to optimize instance call by replacing it with a faster instruction | 4195 // Tries to optimize instance call by replacing it with a faster instruction |
| 4165 // (e.g, binary op, field load, ..). | 4196 // (e.g, binary op, field load, ..). |
| 4166 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { | 4197 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| 4167 if (!instr->HasICData() || (instr->ic_data()->NumberOfUsedChecks() == 0)) { | 4198 if (!instr->HasICData() || (instr->ic_data()->NumberOfUsedChecks() == 0)) { |
| 4168 return; | 4199 return; |
| 4169 } | 4200 } |
| 4170 | 4201 |
| 4171 const Token::Kind op_kind = instr->token_kind(); | 4202 const Token::Kind op_kind = instr->token_kind(); |
| 4203 if (Compiler::always_optimize()) { | |
| 4204 // TODO(srdjan): Investigate other attempts, as they are not allowed to | |
| 4205 // deoptimize. | |
| 4206 if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) { | |
|
Florian Schneider
2015/05/21 14:51:05
How do we guarantee that TryInline... does not int
srdjan
2015/05/21 17:27:07
Every check adds a deopt stub in case of failure;
| |
| 4207 return; | |
| 4208 } | |
| 4209 return; | |
| 4210 } | |
| 4211 | |
| 4172 // Type test is special as it always gets converted into inlined code. | 4212 // Type test is special as it always gets converted into inlined code. |
| 4173 if (Token::IsTypeTestOperator(op_kind)) { | 4213 if (Token::IsTypeTestOperator(op_kind)) { |
| 4174 ReplaceWithInstanceOf(instr); | 4214 ReplaceWithInstanceOf(instr); |
| 4175 return; | 4215 return; |
| 4176 } | 4216 } |
| 4177 | 4217 |
| 4178 if (Token::IsTypeCastOperator(op_kind)) { | 4218 if (Token::IsTypeCastOperator(op_kind)) { |
| 4179 ReplaceWithTypeCast(instr); | 4219 ReplaceWithTypeCast(instr); |
| 4180 return; | 4220 return; |
| 4181 } | 4221 } |
| (...skipping 4428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8610 | 8650 |
| 8611 // Insert materializations at environment uses. | 8651 // Insert materializations at environment uses. |
| 8612 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 8652 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 8613 CreateMaterializationAt( | 8653 CreateMaterializationAt( |
| 8614 exits_collector_.exits()[i], alloc, *slots); | 8654 exits_collector_.exits()[i], alloc, *slots); |
| 8615 } | 8655 } |
| 8616 } | 8656 } |
| 8617 | 8657 |
| 8618 | 8658 |
| 8619 } // namespace dart | 8659 } // namespace dart |
| OLD | NEW |