| 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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 // Only one merge possible. Because canonicalization happens later, | 388 // Only one merge possible. Because canonicalization happens later, |
| 389 // more candidates are possible. | 389 // more candidates are possible. |
| 390 // TODO(srdjan): Allow merging of trunc-div/mod into truncDivMod. | 390 // TODO(srdjan): Allow merging of trunc-div/mod into truncDivMod. |
| 391 break; | 391 break; |
| 392 } | 392 } |
| 393 } | 393 } |
| 394 } | 394 } |
| 395 } | 395 } |
| 396 | 396 |
| 397 | 397 |
| 398 // Tries to merge MathUnary operations, in this case sinus and cosinus. |
| 398 void FlowGraphOptimizer::TryMergeMathUnary( | 399 void FlowGraphOptimizer::TryMergeMathUnary( |
| 399 GrowableArray<MathUnaryInstr*>* merge_candidates) { | 400 GrowableArray<MathUnaryInstr*>* merge_candidates) { |
| 400 if (!FlowGraphCompiler::SupportsSinCos()) { | 401 if (!FlowGraphCompiler::SupportsSinCos()) { |
| 401 return; | 402 return; |
| 402 } | 403 } |
| 403 if (merge_candidates->length() < 2) { | 404 if (merge_candidates->length() < 2) { |
| 404 // Need at least a SIN and a COS. | 405 // Need at least a SIN and a COS. |
| 405 return; | 406 return; |
| 406 } | 407 } |
| 407 for (intptr_t i = 0; i < merge_candidates->length(); i++) { | 408 for (intptr_t i = 0; i < merge_candidates->length(); i++) { |
| 408 MathUnaryInstr* curr_instr = (*merge_candidates)[i]; | 409 MathUnaryInstr* curr_instr = (*merge_candidates)[i]; |
| 409 if (curr_instr == NULL) { | 410 if (curr_instr == NULL) { |
| 410 // Instruction was merged already. | 411 // Instruction was merged already. |
| 411 continue; | 412 continue; |
| 412 } | 413 } |
| 413 const intptr_t kind = curr_instr->kind(); | 414 const intptr_t kind = curr_instr->kind(); |
| 414 ASSERT((kind == MethodRecognizer::kMathSin) || | 415 ASSERT((kind == MathUnaryInstr::kSin) || |
| 415 (kind == MethodRecognizer::kMathCos)); | 416 (kind == MathUnaryInstr::kCos)); |
| 416 // Check if there is sin/cos binop with same inputs. | 417 // Check if there is sin/cos binop with same inputs. |
| 417 const intptr_t other_kind = (kind == MethodRecognizer::kMathSin) ? | 418 const intptr_t other_kind = (kind == MethodRecognizer::kMathSin) ? |
| 418 MethodRecognizer::kMathCos : MethodRecognizer::kMathSin; | 419 MethodRecognizer::kMathCos : MethodRecognizer::kMathSin; |
| 419 Definition* def = curr_instr->value()->definition(); | 420 Definition* def = curr_instr->value()->definition(); |
| 420 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) { | 421 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) { |
| 421 MathUnaryInstr* other_op = (*merge_candidates)[k]; | 422 MathUnaryInstr* other_op = (*merge_candidates)[k]; |
| 422 // 'other_op' can be NULL if it was already merged. | 423 // 'other_op' can be NULL if it was already merged. |
| 423 if ((other_op != NULL) && (other_op->kind() == other_kind) && | 424 if ((other_op != NULL) && (other_op->kind() == other_kind) && |
| 424 (other_op->value()->definition() == def)) { | 425 (other_op->value()->definition() == def)) { |
| 425 (*merge_candidates)[k] = NULL; // Clear it. | 426 (*merge_candidates)[k] = NULL; // Clear it. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 } | 482 } |
| 482 } else if (it.Current()->IsBinaryMintOp()) { | 483 } else if (it.Current()->IsBinaryMintOp()) { |
| 483 BinaryMintOpInstr* mintop = it.Current()->AsBinaryMintOp(); | 484 BinaryMintOpInstr* mintop = it.Current()->AsBinaryMintOp(); |
| 484 if (mintop->op_kind() == Token::kBIT_AND) { | 485 if (mintop->op_kind() == Token::kBIT_AND) { |
| 485 OptimizeLeftShiftBitAndSmiOp(mintop, | 486 OptimizeLeftShiftBitAndSmiOp(mintop, |
| 486 mintop->left()->definition(), | 487 mintop->left()->definition(), |
| 487 mintop->right()->definition()); | 488 mintop->right()->definition()); |
| 488 } | 489 } |
| 489 } else if (it.Current()->IsMathUnary()) { | 490 } else if (it.Current()->IsMathUnary()) { |
| 490 MathUnaryInstr* math_unary = it.Current()->AsMathUnary(); | 491 MathUnaryInstr* math_unary = it.Current()->AsMathUnary(); |
| 491 if ((math_unary->kind() == MethodRecognizer::kMathSin) || | 492 if ((math_unary->kind() == MathUnaryInstr::kSin) || |
| 492 (math_unary->kind() == MethodRecognizer::kMathCos)) { | 493 (math_unary->kind() == MathUnaryInstr::kCos)) { |
| 493 if (math_unary->HasUses()) { | 494 if (math_unary->HasUses()) { |
| 494 sin_cos_merge.Add(math_unary); | 495 sin_cos_merge.Add(math_unary); |
| 495 } | 496 } |
| 496 } | 497 } |
| 497 } | 498 } |
| 498 } | 499 } |
| 499 TryMergeTruncDivMod(&div_mod_merge); | 500 TryMergeTruncDivMod(&div_mod_merge); |
| 500 TryMergeMathUnary(&sin_cos_merge); | 501 TryMergeMathUnary(&sin_cos_merge); |
| 501 current_iterator_ = NULL; | 502 current_iterator_ = NULL; |
| 502 } | 503 } |
| (...skipping 3590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4093 PolymorphicInstanceCallInstr* call = | 4094 PolymorphicInstanceCallInstr* call = |
| 4094 new PolymorphicInstanceCallInstr(instr, unary_checks, | 4095 new PolymorphicInstanceCallInstr(instr, unary_checks, |
| 4095 call_with_checks); | 4096 call_with_checks); |
| 4096 instr->ReplaceWith(call, current_iterator()); | 4097 instr->ReplaceWith(call, current_iterator()); |
| 4097 } | 4098 } |
| 4098 } | 4099 } |
| 4099 | 4100 |
| 4100 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) { | 4101 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) { |
| 4101 MethodRecognizer::Kind recognized_kind = | 4102 MethodRecognizer::Kind recognized_kind = |
| 4102 MethodRecognizer::RecognizeKind(call->function()); | 4103 MethodRecognizer::RecognizeKind(call->function()); |
| 4103 if ((recognized_kind == MethodRecognizer::kMathSqrt) || | 4104 MathUnaryInstr::MathUnaryKind unary_kind; |
| 4104 (recognized_kind == MethodRecognizer::kMathSin) || | 4105 switch (recognized_kind) { |
| 4105 (recognized_kind == MethodRecognizer::kMathCos)) { | 4106 case MethodRecognizer::kMathSqrt: |
| 4107 unary_kind = MathUnaryInstr::kSqrt; |
| 4108 break; |
| 4109 case MethodRecognizer::kMathSin: |
| 4110 unary_kind = MathUnaryInstr::kSin; |
| 4111 break; |
| 4112 case MethodRecognizer::kMathCos: |
| 4113 unary_kind = MathUnaryInstr::kCos; |
| 4114 break; |
| 4115 default: |
| 4116 unary_kind = MathUnaryInstr::kIllegal; |
| 4117 break; |
| 4118 } |
| 4119 if (unary_kind != MathUnaryInstr::kIllegal) { |
| 4106 MathUnaryInstr* math_unary = | 4120 MathUnaryInstr* math_unary = |
| 4107 new MathUnaryInstr(recognized_kind, | 4121 new MathUnaryInstr(unary_kind, |
| 4108 new Value(call->ArgumentAt(0)), | 4122 new Value(call->ArgumentAt(0)), |
| 4109 call->deopt_id()); | 4123 call->deopt_id()); |
| 4110 ReplaceCall(call, math_unary); | 4124 ReplaceCall(call, math_unary); |
| 4111 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) || | 4125 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) || |
| 4112 (recognized_kind == MethodRecognizer::kFloat32x4Splat) || | 4126 (recognized_kind == MethodRecognizer::kFloat32x4Splat) || |
| 4113 (recognized_kind == MethodRecognizer::kFloat32x4Constructor) || | 4127 (recognized_kind == MethodRecognizer::kFloat32x4Constructor) || |
| 4114 (recognized_kind == MethodRecognizer::kFloat32x4FromFloat64x2)) { | 4128 (recognized_kind == MethodRecognizer::kFloat32x4FromFloat64x2)) { |
| 4115 TryInlineFloat32x4Constructor(call, recognized_kind); | 4129 TryInlineFloat32x4Constructor(call, recognized_kind); |
| 4116 } else if ((recognized_kind == MethodRecognizer::kFloat64x2Constructor) || | 4130 } else if ((recognized_kind == MethodRecognizer::kFloat64x2Constructor) || |
| 4117 (recognized_kind == MethodRecognizer::kFloat64x2Zero) || | 4131 (recognized_kind == MethodRecognizer::kFloat64x2Zero) || |
| (...skipping 5166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9284 } | 9298 } |
| 9285 | 9299 |
| 9286 // Insert materializations at environment uses. | 9300 // Insert materializations at environment uses. |
| 9287 for (intptr_t i = 0; i < exits.length(); i++) { | 9301 for (intptr_t i = 0; i < exits.length(); i++) { |
| 9288 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); | 9302 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); |
| 9289 } | 9303 } |
| 9290 } | 9304 } |
| 9291 | 9305 |
| 9292 | 9306 |
| 9293 } // namespace dart | 9307 } // namespace dart |
| OLD | NEW |