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/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 return FlowGraphCompiler::SupportsUnboxedSimd128(); | 54 return FlowGraphCompiler::SupportsUnboxedSimd128(); |
| 55 } | 55 } |
| 56 | 56 |
| 57 | 57 |
| 58 // Optimize instance calls using ICData. | 58 // Optimize instance calls using ICData. |
| 59 void FlowGraphOptimizer::ApplyICData() { | 59 void FlowGraphOptimizer::ApplyICData() { |
| 60 VisitBlocks(); | 60 VisitBlocks(); |
| 61 } | 61 } |
| 62 | 62 |
| 63 | 63 |
| 64 // Optimize instructions that rely on constants. | |
| 65 void FlowGraphOptimizer::ApplyConstants() { | |
| 66 ASSERT(current_iterator_ == NULL); | |
| 67 for (intptr_t i = 0; i < block_order_.length(); ++i) { | |
| 68 BlockEntryInstr* entry = block_order_[i]; | |
| 69 ForwardInstructionIterator it(entry); | |
| 70 current_iterator_ = ⁢ | |
| 71 for (; !it.Done(); it.Advance()) { | |
| 72 Instruction* instr = it.Current(); | |
| 73 if (instr->IsStaticCall()) { | |
| 74 VisitStaticCall(instr->AsStaticCall()); | |
| 75 } | |
| 76 } | |
| 77 current_iterator_ = NULL; | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 | |
| 64 // Optimize instance calls using cid. This is called after optimizer | 82 // Optimize instance calls using cid. This is called after optimizer |
| 65 // converted instance calls to instructions. Any remaining | 83 // converted instance calls to instructions. Any remaining |
| 66 // instance calls are either megamorphic calls, cannot be optimized or | 84 // instance calls are either megamorphic calls, cannot be optimized or |
| 67 // have no runtime type feedback collected. | 85 // have no runtime type feedback collected. |
| 68 // Attempts to convert an instance call (IC call) using propagated class-ids, | 86 // Attempts to convert an instance call (IC call) using propagated class-ids, |
| 69 // e.g., receiver class id, guarded-cid, or by guessing cid-s. | 87 // e.g., receiver class id, guarded-cid, or by guessing cid-s. |
| 70 void FlowGraphOptimizer::ApplyClassIds() { | 88 void FlowGraphOptimizer::ApplyClassIds() { |
| 71 ASSERT(current_iterator_ == NULL); | 89 ASSERT(current_iterator_ == NULL); |
| 72 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 90 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 73 BlockEntryInstr* entry = block_order_[i]; | 91 BlockEntryInstr* entry = block_order_[i]; |
| (...skipping 4147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4221 new ZoneGrowableArray<Value*>(call->ArgumentCount()); | 4239 new ZoneGrowableArray<Value*>(call->ArgumentCount()); |
| 4222 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { | 4240 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { |
| 4223 args->Add(new Value(call->ArgumentAt(i))); | 4241 args->Add(new Value(call->ArgumentAt(i))); |
| 4224 } | 4242 } |
| 4225 InvokeMathCFunctionInstr* invoke = | 4243 InvokeMathCFunctionInstr* invoke = |
| 4226 new InvokeMathCFunctionInstr(args, | 4244 new InvokeMathCFunctionInstr(args, |
| 4227 call->deopt_id(), | 4245 call->deopt_id(), |
| 4228 recognized_kind, | 4246 recognized_kind, |
| 4229 call->token_pos()); | 4247 call->token_pos()); |
| 4230 ReplaceCall(call, invoke); | 4248 ReplaceCall(call, invoke); |
| 4249 } else if (recognized_kind == MethodRecognizer::kObjectArrayConstructor) { | |
| 4250 Value* type = new Value(call->ArgumentAt(0)); | |
| 4251 Value* num_elements = new Value(call->ArgumentAt(1)); | |
| 4252 if (num_elements->BindsToConstant() && | |
| 4253 num_elements->BoundConstant().IsSmi()) { | |
|
Florian Schneider
2014/05/13 11:17:32
Why does num_elements need to be constant? CreateA
srdjan
2014/05/13 18:07:18
CreateArrayInstr expects a positive integer. Added
Florian Schneider
2014/05/14 08:23:28
Sorry to be not precise enough: I meant checking f
srdjan
2014/05/14 15:21:02
This code is just the first step for optimized all
| |
| 4254 const intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); | |
| 4255 if (length >= 0 && length <= Array::kMaxElements) { | |
| 4256 CreateArrayInstr* create_array = | |
|
Florian Schneider
2014/05/13 11:17:32
How about doing this in the flow graph builder ins
srdjan
2014/05/13 18:07:18
Done.
srdjan
2014/05/13 18:24:44
Actually not done. FlowGraphBuilder is run in unop
| |
| 4257 new CreateArrayInstr(call->token_pos(), type, num_elements); | |
| 4258 ReplaceCall(call, create_array); | |
| 4259 } | |
| 4260 } | |
| 4231 } else if (Library::PrivateCoreLibName(Symbols::ClassId()).Equals( | 4261 } else if (Library::PrivateCoreLibName(Symbols::ClassId()).Equals( |
| 4232 String::Handle(call->function().name()))) { | 4262 String::Handle(call->function().name()))) { |
| 4233 // Check for core library get:_classId. | 4263 // Check for core library get:_classId. |
| 4234 intptr_t cid = Class::Handle(call->function().Owner()).id(); | 4264 intptr_t cid = Class::Handle(call->function().Owner()).id(); |
| 4235 // Currently only implemented for a subset of classes. | 4265 // Currently only implemented for a subset of classes. |
| 4236 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) || | 4266 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) || |
| 4237 (cid == kExternalOneByteStringCid) || | 4267 (cid == kExternalOneByteStringCid) || |
| 4238 (cid == kGrowableObjectArrayCid) || | 4268 (cid == kGrowableObjectArrayCid) || |
| 4239 (cid == kImmutableArrayCid) || (cid == kArrayCid)); | 4269 (cid == kImmutableArrayCid) || (cid == kArrayCid)); |
| 4240 ConstantInstr* cid_instr = new ConstantInstr(Smi::Handle(Smi::New(cid))); | 4270 ConstantInstr* cid_instr = new ConstantInstr(Smi::Handle(Smi::New(cid))); |
| 4241 ReplaceCall(call, cid_instr); | 4271 ReplaceCall(call, cid_instr); |
| 4242 } | 4272 } else if (call->function().IsFactory()) { |
| 4243 | |
| 4244 if (call->function().IsFactory()) { | |
| 4245 const Class& function_class = Class::Handle(call->function().Owner()); | 4273 const Class& function_class = Class::Handle(call->function().Owner()); |
| 4246 if ((function_class.library() == Library::CoreLibrary()) || | 4274 if ((function_class.library() == Library::CoreLibrary()) || |
| 4247 (function_class.library() == Library::TypedDataLibrary())) { | 4275 (function_class.library() == Library::TypedDataLibrary())) { |
| 4248 intptr_t cid = FactoryRecognizer::ResultCid(call->function()); | 4276 intptr_t cid = FactoryRecognizer::ResultCid(call->function()); |
| 4249 switch (cid) { | 4277 switch (cid) { |
| 4250 case kArrayCid: { | 4278 case kArrayCid: { |
| 4251 Value* type = new Value(call->ArgumentAt(0)); | 4279 Value* type = new Value(call->ArgumentAt(0)); |
| 4252 Value* num_elements = new Value(call->ArgumentAt(1)); | 4280 Value* num_elements = new Value(call->ArgumentAt(1)); |
| 4253 if (num_elements->BindsToConstant() && | 4281 if (num_elements->BindsToConstant() && |
| 4254 num_elements->BoundConstant().IsSmi()) { | 4282 num_elements->BoundConstant().IsSmi()) { |
| (...skipping 5294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9549 } | 9577 } |
| 9550 | 9578 |
| 9551 // Insert materializations at environment uses. | 9579 // Insert materializations at environment uses. |
| 9552 for (intptr_t i = 0; i < exits.length(); i++) { | 9580 for (intptr_t i = 0; i < exits.length(); i++) { |
| 9553 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); | 9581 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); |
| 9554 } | 9582 } |
| 9555 } | 9583 } |
| 9556 | 9584 |
| 9557 | 9585 |
| 9558 } // namespace dart | 9586 } // namespace dart |
| OLD | NEW |