| 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/compiler.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 4184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4195 new(Z) Value(left), | 4195 new(Z) Value(left), |
| 4196 new(Z) Value(instantiator), | 4196 new(Z) Value(instantiator), |
| 4197 new(Z) Value(type_args), | 4197 new(Z) Value(type_args), |
| 4198 type, | 4198 type, |
| 4199 dst_name, | 4199 dst_name, |
| 4200 call->deopt_id()); | 4200 call->deopt_id()); |
| 4201 ReplaceCall(call, assert_as); | 4201 ReplaceCall(call, assert_as); |
| 4202 } | 4202 } |
| 4203 | 4203 |
| 4204 | 4204 |
| 4205 bool FlowGraphOptimizer::IsBlackListedForInlining(intptr_t call_deopt_id) { |
| 4206 for (intptr_t i = 0; i < inlining_black_list_->length(); ++i) { |
| 4207 if ((*inlining_black_list_)[i] == call_deopt_id) return true; |
| 4208 } |
| 4209 return false; |
| 4210 } |
| 4211 |
| 4205 // Special optimizations when running in --noopt mode. | 4212 // Special optimizations when running in --noopt mode. |
| 4206 void FlowGraphOptimizer::InstanceCallNoopt(InstanceCallInstr* instr) { | 4213 void FlowGraphOptimizer::InstanceCallNoopt(InstanceCallInstr* instr) { |
| 4207 // TODO(srdjan): Investigate other attempts, as they are not allowed to | 4214 // TODO(srdjan): Investigate other attempts, as they are not allowed to |
| 4208 // deoptimize. | 4215 // deoptimize. |
| 4209 | 4216 |
| 4210 // Type test is special as it always gets converted into inlined code. | 4217 // Type test is special as it always gets converted into inlined code. |
| 4211 const Token::Kind op_kind = instr->token_kind(); | 4218 const Token::Kind op_kind = instr->token_kind(); |
| 4212 if (Token::IsTypeTestOperator(op_kind)) { | 4219 if (Token::IsTypeTestOperator(op_kind)) { |
| 4213 ReplaceWithInstanceOf(instr); | 4220 ReplaceWithInstanceOf(instr); |
| 4214 return; | 4221 return; |
| 4215 } | 4222 } |
| 4216 if (Token::IsTypeCastOperator(op_kind)) { | 4223 if (Token::IsTypeCastOperator(op_kind)) { |
| 4217 ReplaceWithTypeCast(instr); | 4224 ReplaceWithTypeCast(instr); |
| 4218 return; | 4225 return; |
| 4219 } | 4226 } |
| 4220 | 4227 |
| 4221 if ((op_kind == Token::kGET) && | 4228 if ((op_kind == Token::kGET) && |
| 4222 TryInlineInstanceGetter(instr, false /* no checks allowed */)) { | 4229 TryInlineInstanceGetter(instr, false /* no checks allowed */)) { |
| 4223 return; | 4230 return; |
| 4224 } | 4231 } |
| 4225 const ICData& unary_checks = | 4232 const ICData& unary_checks = |
| 4226 ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks()); | 4233 ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks()); |
| 4227 if ((unary_checks.NumberOfChecks() > 0) && | 4234 if ((unary_checks.NumberOfChecks() > 0) && |
| 4228 (op_kind == Token::kSET) && | 4235 (op_kind == Token::kSET) && |
| 4229 TryInlineInstanceSetter(instr, unary_checks, false /* no checks */)) { | 4236 TryInlineInstanceSetter(instr, unary_checks, false /* no checks */)) { |
| 4230 return; | 4237 return; |
| 4231 } | 4238 } |
| 4232 | 4239 |
| 4240 if (use_speculative_inlining_ && |
| 4241 !IsBlackListedForInlining(instr->deopt_id()) && |
| 4242 (unary_checks.NumberOfChecks() > 0)) { |
| 4243 if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) { |
| 4244 return; |
| 4245 } |
| 4246 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) { |
| 4247 return; |
| 4248 } |
| 4249 if ((op_kind == Token::kEQ) && TryReplaceWithEqualityOp(instr, op_kind)) { |
| 4250 return; |
| 4251 } |
| 4252 |
| 4253 if (Token::IsRelationalOperator(op_kind) && |
| 4254 TryReplaceWithRelationalOp(instr, op_kind)) { |
| 4255 return; |
| 4256 } |
| 4257 |
| 4258 if (Token::IsBinaryOperator(op_kind) && |
| 4259 TryReplaceWithBinaryOp(instr, op_kind)) { |
| 4260 return; |
| 4261 } |
| 4262 if (Token::IsUnaryOperator(op_kind) && |
| 4263 TryReplaceWithUnaryOp(instr, op_kind)) { |
| 4264 return; |
| 4265 } |
| 4266 } |
| 4267 |
| 4233 bool has_one_target = | 4268 bool has_one_target = |
| 4234 (unary_checks.NumberOfChecks() > 0) && unary_checks.HasOneTarget(); | 4269 (unary_checks.NumberOfChecks() > 0) && unary_checks.HasOneTarget(); |
| 4235 if (has_one_target) { | 4270 if (has_one_target) { |
| 4236 // Check if the single target is a polymorphic target, if it is, | 4271 // Check if the single target is a polymorphic target, if it is, |
| 4237 // we don't have one target. | 4272 // we don't have one target. |
| 4238 const Function& target = | 4273 const Function& target = |
| 4239 Function::Handle(Z, unary_checks.GetTargetAt(0)); | 4274 Function::Handle(Z, unary_checks.GetTargetAt(0)); |
| 4240 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); | 4275 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); |
| 4241 has_one_target = !polymorphic_target; | 4276 has_one_target = !polymorphic_target; |
| 4242 } | 4277 } |
| (...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5169 Instruction* instr) { | 5204 Instruction* instr) { |
| 5170 return IsLoadEliminationCandidate(instr) && | 5205 return IsLoadEliminationCandidate(instr) && |
| 5171 (sets != NULL) && | 5206 (sets != NULL) && |
| 5172 instr->HasPlaceId() && | 5207 instr->HasPlaceId() && |
| 5173 ((*sets)[loop_header_index] != NULL) && | 5208 ((*sets)[loop_header_index] != NULL) && |
| 5174 (*sets)[loop_header_index]->Contains(instr->place_id()); | 5209 (*sets)[loop_header_index]->Contains(instr->place_id()); |
| 5175 } | 5210 } |
| 5176 | 5211 |
| 5177 | 5212 |
| 5178 void LICM::OptimisticallySpecializeSmiPhis() { | 5213 void LICM::OptimisticallySpecializeSmiPhis() { |
| 5179 if (!flow_graph()->function().allows_hoisting_check_class()) { | 5214 if (!flow_graph()->function().allows_hoisting_check_class() || |
| 5180 // Do not hoist any. | 5215 Compiler::always_optimize()) { |
| 5216 // Do not hoist any: Either deoptimized on a hoisted check, |
| 5217 // or compiling precompiled code where we can't do optimistic |
| 5218 // hoisting of checks. |
| 5181 return; | 5219 return; |
| 5182 } | 5220 } |
| 5183 | 5221 |
| 5184 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = | 5222 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = |
| 5185 flow_graph()->LoopHeaders(); | 5223 flow_graph()->LoopHeaders(); |
| 5186 | 5224 |
| 5187 for (intptr_t i = 0; i < loop_headers.length(); ++i) { | 5225 for (intptr_t i = 0; i < loop_headers.length(); ++i) { |
| 5188 JoinEntryInstr* header = loop_headers[i]->AsJoinEntry(); | 5226 JoinEntryInstr* header = loop_headers[i]->AsJoinEntry(); |
| 5189 // Skip loop that don't have a pre-header block. | 5227 // Skip loop that don't have a pre-header block. |
| 5190 BlockEntryInstr* pre_header = header->ImmediateDominator(); | 5228 BlockEntryInstr* pre_header = header->ImmediateDominator(); |
| (...skipping 3598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8789 | 8827 |
| 8790 // Insert materializations at environment uses. | 8828 // Insert materializations at environment uses. |
| 8791 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 8829 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 8792 CreateMaterializationAt( | 8830 CreateMaterializationAt( |
| 8793 exits_collector_.exits()[i], alloc, *slots); | 8831 exits_collector_.exits()[i], alloc, *slots); |
| 8794 } | 8832 } |
| 8795 } | 8833 } |
| 8796 | 8834 |
| 8797 | 8835 |
| 8798 } // namespace dart | 8836 } // namespace dart |
| OLD | NEW |