| 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/aot_optimizer.h" | 5 #include "vm/aot_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/branch_optimizer.h" | 8 #include "vm/branch_optimizer.h" |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "vm/object_store.h" | 22 #include "vm/object_store.h" |
| 23 #include "vm/parser.h" | 23 #include "vm/parser.h" |
| 24 #include "vm/precompiler.h" | 24 #include "vm/precompiler.h" |
| 25 #include "vm/resolver.h" | 25 #include "vm/resolver.h" |
| 26 #include "vm/scopes.h" | 26 #include "vm/scopes.h" |
| 27 #include "vm/stack_frame.h" | 27 #include "vm/stack_frame.h" |
| 28 #include "vm/symbols.h" | 28 #include "vm/symbols.h" |
| 29 | 29 |
| 30 namespace dart { | 30 namespace dart { |
| 31 | 31 |
| 32 DECLARE_FLAG(bool, precompilation); | |
| 33 | |
| 34 // Quick access to the current isolate and zone. | 32 // Quick access to the current isolate and zone. |
| 35 #define I (isolate()) | 33 #define I (isolate()) |
| 36 #define Z (zone()) | 34 #define Z (zone()) |
| 37 | 35 |
| 38 static bool ShouldInlineSimd() { | 36 static bool ShouldInlineSimd() { |
| 39 return FlowGraphCompiler::SupportsUnboxedSimd128(); | 37 return FlowGraphCompiler::SupportsUnboxedSimd128(); |
| 40 } | 38 } |
| 41 | 39 |
| 42 | 40 |
| 43 static bool CanUnboxDouble() { | 41 static bool CanUnboxDouble() { |
| (...skipping 1983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2027 } | 2025 } |
| 2028 } | 2026 } |
| 2029 return false; | 2027 return false; |
| 2030 } | 2028 } |
| 2031 | 2029 |
| 2032 | 2030 |
| 2033 bool AotOptimizer::TryInlineFloat32x4Constructor( | 2031 bool AotOptimizer::TryInlineFloat32x4Constructor( |
| 2034 StaticCallInstr* call, | 2032 StaticCallInstr* call, |
| 2035 MethodRecognizer::Kind recognized_kind) { | 2033 MethodRecognizer::Kind recognized_kind) { |
| 2036 // Cannot handle unboxed instructions. | 2034 // Cannot handle unboxed instructions. |
| 2037 ASSERT(FLAG_precompilation); | 2035 ASSERT(FLAG_precompiled_mode); |
| 2038 return false; | 2036 return false; |
| 2039 } | 2037 } |
| 2040 | 2038 |
| 2041 | 2039 |
| 2042 bool AotOptimizer::TryInlineFloat64x2Constructor( | 2040 bool AotOptimizer::TryInlineFloat64x2Constructor( |
| 2043 StaticCallInstr* call, | 2041 StaticCallInstr* call, |
| 2044 MethodRecognizer::Kind recognized_kind) { | 2042 MethodRecognizer::Kind recognized_kind) { |
| 2045 // Cannot handle unboxed instructions. | 2043 // Cannot handle unboxed instructions. |
| 2046 ASSERT(FLAG_precompilation); | 2044 ASSERT(FLAG_precompiled_mode); |
| 2047 return false; | 2045 return false; |
| 2048 } | 2046 } |
| 2049 | 2047 |
| 2050 | 2048 |
| 2051 bool AotOptimizer::TryInlineInt32x4Constructor( | 2049 bool AotOptimizer::TryInlineInt32x4Constructor( |
| 2052 StaticCallInstr* call, | 2050 StaticCallInstr* call, |
| 2053 MethodRecognizer::Kind recognized_kind) { | 2051 MethodRecognizer::Kind recognized_kind) { |
| 2054 // Cannot handle unboxed instructions. | 2052 // Cannot handle unboxed instructions. |
| 2055 ASSERT(FLAG_precompilation); | 2053 ASSERT(FLAG_precompiled_mode); |
| 2056 return false; | 2054 return false; |
| 2057 } | 2055 } |
| 2058 | 2056 |
| 2059 | 2057 |
| 2060 bool AotOptimizer::TryInlineFloat32x4Method( | 2058 bool AotOptimizer::TryInlineFloat32x4Method( |
| 2061 InstanceCallInstr* call, | 2059 InstanceCallInstr* call, |
| 2062 MethodRecognizer::Kind recognized_kind) { | 2060 MethodRecognizer::Kind recognized_kind) { |
| 2063 // Cannot handle unboxed instructions. | 2061 // Cannot handle unboxed instructions. |
| 2064 return false; | 2062 return false; |
| 2065 } | 2063 } |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2542 /* with_checks = */ false); | 2540 /* with_checks = */ false); |
| 2543 instr->ReplaceWith(call, current_iterator()); | 2541 instr->ReplaceWith(call, current_iterator()); |
| 2544 return; | 2542 return; |
| 2545 } | 2543 } |
| 2546 } | 2544 } |
| 2547 | 2545 |
| 2548 | 2546 |
| 2549 // Tries to optimize instance call by replacing it with a faster instruction | 2547 // Tries to optimize instance call by replacing it with a faster instruction |
| 2550 // (e.g, binary op, field load, ..). | 2548 // (e.g, binary op, field load, ..). |
| 2551 void AotOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { | 2549 void AotOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| 2552 ASSERT(FLAG_precompilation); | 2550 ASSERT(FLAG_precompiled_mode); |
| 2553 InstanceCallNoopt(instr); | 2551 InstanceCallNoopt(instr); |
| 2554 } | 2552 } |
| 2555 | 2553 |
| 2556 | 2554 |
| 2557 void AotOptimizer::VisitStaticCall(StaticCallInstr* call) { | 2555 void AotOptimizer::VisitStaticCall(StaticCallInstr* call) { |
| 2558 if (!CanUnboxDouble()) { | 2556 if (!CanUnboxDouble()) { |
| 2559 return; | 2557 return; |
| 2560 } | 2558 } |
| 2561 MethodRecognizer::Kind recognized_kind = | 2559 MethodRecognizer::Kind recognized_kind = |
| 2562 MethodRecognizer::RecognizeKind(call->function()); | 2560 MethodRecognizer::RecognizeKind(call->function()); |
| 2563 MathUnaryInstr::MathUnaryKind unary_kind; | 2561 MathUnaryInstr::MathUnaryKind unary_kind; |
| 2564 switch (recognized_kind) { | 2562 switch (recognized_kind) { |
| 2565 case MethodRecognizer::kMathSqrt: | 2563 case MethodRecognizer::kMathSqrt: |
| 2566 unary_kind = MathUnaryInstr::kSqrt; | 2564 unary_kind = MathUnaryInstr::kSqrt; |
| 2567 break; | 2565 break; |
| 2568 case MethodRecognizer::kMathSin: | 2566 case MethodRecognizer::kMathSin: |
| 2569 unary_kind = MathUnaryInstr::kSin; | 2567 unary_kind = MathUnaryInstr::kSin; |
| 2570 break; | 2568 break; |
| 2571 case MethodRecognizer::kMathCos: | 2569 case MethodRecognizer::kMathCos: |
| 2572 unary_kind = MathUnaryInstr::kCos; | 2570 unary_kind = MathUnaryInstr::kCos; |
| 2573 break; | 2571 break; |
| 2574 default: | 2572 default: |
| 2575 unary_kind = MathUnaryInstr::kIllegal; | 2573 unary_kind = MathUnaryInstr::kIllegal; |
| 2576 break; | 2574 break; |
| 2577 } | 2575 } |
| 2578 if (unary_kind != MathUnaryInstr::kIllegal) { | 2576 if (unary_kind != MathUnaryInstr::kIllegal) { |
| 2579 ASSERT(FLAG_precompilation); | 2577 ASSERT(FLAG_precompiled_mode); |
| 2580 // TODO(srdjan): Adapt MathUnaryInstr to allow tagged inputs as well. | 2578 // TODO(srdjan): Adapt MathUnaryInstr to allow tagged inputs as well. |
| 2581 return; | 2579 return; |
| 2582 } | 2580 } |
| 2583 | 2581 |
| 2584 switch (recognized_kind) { | 2582 switch (recognized_kind) { |
| 2585 case MethodRecognizer::kFloat32x4Zero: | 2583 case MethodRecognizer::kFloat32x4Zero: |
| 2586 case MethodRecognizer::kFloat32x4Splat: | 2584 case MethodRecognizer::kFloat32x4Splat: |
| 2587 case MethodRecognizer::kFloat32x4Constructor: | 2585 case MethodRecognizer::kFloat32x4Constructor: |
| 2588 case MethodRecognizer::kFloat32x4FromFloat64x2: | 2586 case MethodRecognizer::kFloat32x4FromFloat64x2: |
| 2589 TryInlineFloat32x4Constructor(call, recognized_kind); | 2587 TryInlineFloat32x4Constructor(call, recognized_kind); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2649 } | 2647 } |
| 2650 } | 2648 } |
| 2651 break; | 2649 break; |
| 2652 } | 2650 } |
| 2653 case MethodRecognizer::kMathDoublePow: | 2651 case MethodRecognizer::kMathDoublePow: |
| 2654 case MethodRecognizer::kMathTan: | 2652 case MethodRecognizer::kMathTan: |
| 2655 case MethodRecognizer::kMathAsin: | 2653 case MethodRecognizer::kMathAsin: |
| 2656 case MethodRecognizer::kMathAcos: | 2654 case MethodRecognizer::kMathAcos: |
| 2657 case MethodRecognizer::kMathAtan: | 2655 case MethodRecognizer::kMathAtan: |
| 2658 case MethodRecognizer::kMathAtan2: { | 2656 case MethodRecognizer::kMathAtan2: { |
| 2659 ASSERT(FLAG_precompilation); | 2657 ASSERT(FLAG_precompiled_mode); |
| 2660 // No UnboxDouble instructions allowed. | 2658 // No UnboxDouble instructions allowed. |
| 2661 return; | 2659 return; |
| 2662 } | 2660 } |
| 2663 case MethodRecognizer::kDoubleFromInteger: { | 2661 case MethodRecognizer::kDoubleFromInteger: { |
| 2664 if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) { | 2662 if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) { |
| 2665 const ICData& ic_data = *call->ic_data(); | 2663 const ICData& ic_data = *call->ic_data(); |
| 2666 if (CanUnboxDouble()) { | 2664 if (CanUnboxDouble()) { |
| 2667 if (ArgIsAlways(kSmiCid, ic_data, 1)) { | 2665 if (ArgIsAlways(kSmiCid, ic_data, 1)) { |
| 2668 Definition* arg = call->ArgumentAt(1); | 2666 Definition* arg = call->ArgumentAt(1); |
| 2669 AddCheckSmi(arg, call->deopt_id(), call->env(), call); | 2667 AddCheckSmi(arg, call->deopt_id(), call->env(), call); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2809 | 2807 |
| 2810 // Discard the environment from the original instruction because the store | 2808 // Discard the environment from the original instruction because the store |
| 2811 // can't deoptimize. | 2809 // can't deoptimize. |
| 2812 instr->RemoveEnvironment(); | 2810 instr->RemoveEnvironment(); |
| 2813 ReplaceCall(instr, store); | 2811 ReplaceCall(instr, store); |
| 2814 return true; | 2812 return true; |
| 2815 } | 2813 } |
| 2816 | 2814 |
| 2817 | 2815 |
| 2818 } // namespace dart | 2816 } // namespace dart |
| OLD | NEW |