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 |