| 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 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 if (HasOnlyTwoOf(ic_data, kSmiCid)) { | 762 if (HasOnlyTwoOf(ic_data, kSmiCid)) { |
| 763 // Don't generate smi code if the IC data is marked because | 763 // Don't generate smi code if the IC data is marked because |
| 764 // of an overflow. | 764 // of an overflow. |
| 765 operands_type = ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp) | 765 operands_type = ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp) |
| 766 ? kMintCid | 766 ? kMintCid |
| 767 : kSmiCid; | 767 : kSmiCid; |
| 768 } else if (HasTwoMintOrSmi(ic_data) && | 768 } else if (HasTwoMintOrSmi(ic_data) && |
| 769 FlowGraphCompiler::SupportsUnboxedMints()) { | 769 FlowGraphCompiler::SupportsUnboxedMints()) { |
| 770 // Don't generate mint code if the IC data is marked because of an | 770 // Don't generate mint code if the IC data is marked because of an |
| 771 // overflow. | 771 // overflow. |
| 772 if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) return false; | 772 if (ic_data.HasDeoptReason(ICData::kDeoptBinaryInt64Op)) return false; |
| 773 operands_type = kMintCid; | 773 operands_type = kMintCid; |
| 774 } else if (ShouldSpecializeForDouble(ic_data)) { | 774 } else if (ShouldSpecializeForDouble(ic_data)) { |
| 775 operands_type = kDoubleCid; | 775 operands_type = kDoubleCid; |
| 776 } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) { | 776 } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) { |
| 777 operands_type = kFloat32x4Cid; | 777 operands_type = kFloat32x4Cid; |
| 778 } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) { | 778 } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) { |
| 779 ASSERT(op_kind != Token::kMUL); // Int32x4 doesn't have a multiply op. | 779 ASSERT(op_kind != Token::kMUL); // Int32x4 doesn't have a multiply op. |
| 780 operands_type = kInt32x4Cid; | 780 operands_type = kInt32x4Cid; |
| 781 } else if (HasOnlyTwoOf(ic_data, kFloat64x2Cid)) { | 781 } else if (HasOnlyTwoOf(ic_data, kFloat64x2Cid)) { |
| 782 operands_type = kFloat64x2Cid; | 782 operands_type = kFloat64x2Cid; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 809 } else { | 809 } else { |
| 810 return false; | 810 return false; |
| 811 } | 811 } |
| 812 break; | 812 break; |
| 813 case Token::kSHR: | 813 case Token::kSHR: |
| 814 case Token::kSHL: | 814 case Token::kSHL: |
| 815 if (HasOnlyTwoOf(ic_data, kSmiCid)) { | 815 if (HasOnlyTwoOf(ic_data, kSmiCid)) { |
| 816 // Left shift may overflow from smi into mint or big ints. | 816 // Left shift may overflow from smi into mint or big ints. |
| 817 // Don't generate smi code if the IC data is marked because | 817 // Don't generate smi code if the IC data is marked because |
| 818 // of an overflow. | 818 // of an overflow. |
| 819 if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) { | 819 if (ic_data.HasDeoptReason(ICData::kDeoptBinaryInt64Op)) { |
| 820 return false; | 820 return false; |
| 821 } | 821 } |
| 822 operands_type = ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp) | 822 operands_type = ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp) |
| 823 ? kMintCid | 823 ? kMintCid |
| 824 : kSmiCid; | 824 : kSmiCid; |
| 825 } else if (HasTwoMintOrSmi(ic_data) && | 825 } else if (HasTwoMintOrSmi(ic_data) && |
| 826 HasOnlyOneSmi(ICData::Handle( | 826 HasOnlyOneSmi(ICData::Handle( |
| 827 Z, ic_data.AsUnaryClassChecksForArgNr(1)))) { | 827 Z, ic_data.AsUnaryClassChecksForArgNr(1)))) { |
| 828 // Don't generate mint code if the IC data is marked because of an | 828 // Don't generate mint code if the IC data is marked because of an |
| 829 // overflow. | 829 // overflow. |
| 830 if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) { | 830 if (ic_data.HasDeoptReason(ICData::kDeoptBinaryInt64Op)) { |
| 831 return false; | 831 return false; |
| 832 } | 832 } |
| 833 // Check for smi/mint << smi or smi/mint >> smi. | 833 // Check for smi/mint << smi or smi/mint >> smi. |
| 834 operands_type = kMintCid; | 834 operands_type = kMintCid; |
| 835 } else { | 835 } else { |
| 836 return false; | 836 return false; |
| 837 } | 837 } |
| 838 break; | 838 break; |
| 839 case Token::kMOD: | 839 case Token::kMOD: |
| 840 case Token::kTRUNCDIV: | 840 case Token::kTRUNCDIV: |
| (...skipping 30 matching lines...) Expand all Loading... |
| 871 call->env(), FlowGraph::kEffect); | 871 call->env(), FlowGraph::kEffect); |
| 872 } | 872 } |
| 873 | 873 |
| 874 BinaryDoubleOpInstr* double_bin_op = new (Z) | 874 BinaryDoubleOpInstr* double_bin_op = new (Z) |
| 875 BinaryDoubleOpInstr(op_kind, new (Z) Value(left), new (Z) Value(right), | 875 BinaryDoubleOpInstr(op_kind, new (Z) Value(left), new (Z) Value(right), |
| 876 call->deopt_id(), call->token_pos()); | 876 call->deopt_id(), call->token_pos()); |
| 877 ReplaceCall(call, double_bin_op); | 877 ReplaceCall(call, double_bin_op); |
| 878 } else if (operands_type == kMintCid) { | 878 } else if (operands_type == kMintCid) { |
| 879 if (!FlowGraphCompiler::SupportsUnboxedMints()) return false; | 879 if (!FlowGraphCompiler::SupportsUnboxedMints()) return false; |
| 880 if ((op_kind == Token::kSHR) || (op_kind == Token::kSHL)) { | 880 if ((op_kind == Token::kSHR) || (op_kind == Token::kSHL)) { |
| 881 ShiftMintOpInstr* shift_op = new (Z) ShiftMintOpInstr( | 881 ShiftInt64OpInstr* shift_op = new (Z) ShiftInt64OpInstr( |
| 882 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); | 882 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); |
| 883 ReplaceCall(call, shift_op); | 883 ReplaceCall(call, shift_op); |
| 884 } else { | 884 } else { |
| 885 BinaryMintOpInstr* bin_op = new (Z) BinaryMintOpInstr( | 885 BinaryInt64OpInstr* bin_op = new (Z) BinaryInt64OpInstr( |
| 886 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); | 886 op_kind, new (Z) Value(left), new (Z) Value(right), call->deopt_id()); |
| 887 ReplaceCall(call, bin_op); | 887 ReplaceCall(call, bin_op); |
| 888 } | 888 } |
| 889 } else if (operands_type == kFloat32x4Cid) { | 889 } else if (operands_type == kFloat32x4Cid) { |
| 890 return InlineFloat32x4BinaryOp(call, op_kind); | 890 return InlineFloat32x4BinaryOp(call, op_kind); |
| 891 } else if (operands_type == kInt32x4Cid) { | 891 } else if (operands_type == kInt32x4Cid) { |
| 892 return InlineInt32x4BinaryOp(call, op_kind); | 892 return InlineInt32x4BinaryOp(call, op_kind); |
| 893 } else if (operands_type == kFloat64x2Cid) { | 893 } else if (operands_type == kFloat64x2Cid) { |
| 894 return InlineFloat64x2BinaryOp(call, op_kind); | 894 return InlineFloat64x2BinaryOp(call, op_kind); |
| 895 } else if (op_kind == Token::kMOD) { | 895 } else if (op_kind == Token::kMOD) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 InsertBefore(call, | 949 InsertBefore(call, |
| 950 new (Z) CheckSmiInstr(new (Z) Value(input), call->deopt_id(), | 950 new (Z) CheckSmiInstr(new (Z) Value(input), call->deopt_id(), |
| 951 call->token_pos()), | 951 call->token_pos()), |
| 952 call->env(), FlowGraph::kEffect); | 952 call->env(), FlowGraph::kEffect); |
| 953 unary_op = new (Z) | 953 unary_op = new (Z) |
| 954 UnarySmiOpInstr(op_kind, new (Z) Value(input), call->deopt_id()); | 954 UnarySmiOpInstr(op_kind, new (Z) Value(input), call->deopt_id()); |
| 955 } else if ((op_kind == Token::kBIT_NOT) && | 955 } else if ((op_kind == Token::kBIT_NOT) && |
| 956 HasOnlySmiOrMint(*call->ic_data()) && | 956 HasOnlySmiOrMint(*call->ic_data()) && |
| 957 FlowGraphCompiler::SupportsUnboxedMints()) { | 957 FlowGraphCompiler::SupportsUnboxedMints()) { |
| 958 unary_op = new (Z) | 958 unary_op = new (Z) |
| 959 UnaryMintOpInstr(op_kind, new (Z) Value(input), call->deopt_id()); | 959 UnaryInt64OpInstr(op_kind, new (Z) Value(input), call->deopt_id()); |
| 960 } else if (HasOnlyOneDouble(*call->ic_data()) && | 960 } else if (HasOnlyOneDouble(*call->ic_data()) && |
| 961 (op_kind == Token::kNEGATE) && CanUnboxDouble()) { | 961 (op_kind == Token::kNEGATE) && CanUnboxDouble()) { |
| 962 AddReceiverCheck(call); | 962 AddReceiverCheck(call); |
| 963 unary_op = new (Z) UnaryDoubleOpInstr(Token::kNEGATE, new (Z) Value(input), | 963 unary_op = new (Z) UnaryDoubleOpInstr(Token::kNEGATE, new (Z) Value(input), |
| 964 call->deopt_id()); | 964 call->deopt_id()); |
| 965 } else { | 965 } else { |
| 966 return false; | 966 return false; |
| 967 } | 967 } |
| 968 ASSERT(unary_op != NULL); | 968 ASSERT(unary_op != NULL); |
| 969 ReplaceCall(call, unary_op); | 969 ReplaceCall(call, unary_op); |
| (...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2007 break; | 2007 break; |
| 2008 } | 2008 } |
| 2009 default: | 2009 default: |
| 2010 break; | 2010 break; |
| 2011 } | 2011 } |
| 2012 } | 2012 } |
| 2013 | 2013 |
| 2014 void AotOptimizer::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { | 2014 void AotOptimizer::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { |
| 2015 // TODO(zerny): Use kUnboxedUint32 once it is fully supported/optimized. | 2015 // TODO(zerny): Use kUnboxedUint32 once it is fully supported/optimized. |
| 2016 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) | 2016 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) |
| 2017 if (!instr->can_pack_into_smi()) instr->set_representation(kUnboxedMint); | 2017 if (!instr->can_pack_into_smi()) instr->set_representation(kUnboxedInt64); |
| 2018 #endif | 2018 #endif |
| 2019 } | 2019 } |
| 2020 | 2020 |
| 2021 bool AotOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, | 2021 bool AotOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, |
| 2022 const ICData& unary_ic_data) { | 2022 const ICData& unary_ic_data) { |
| 2023 ASSERT((unary_ic_data.NumberOfChecks() > 0) && | 2023 ASSERT((unary_ic_data.NumberOfChecks() > 0) && |
| 2024 (unary_ic_data.NumArgsTested() == 1)); | 2024 (unary_ic_data.NumArgsTested() == 1)); |
| 2025 if (I->type_checks()) { | 2025 if (I->type_checks()) { |
| 2026 // Checked mode setters are inlined like normal methods by conventional | 2026 // Checked mode setters are inlined like normal methods by conventional |
| 2027 // inlining. | 2027 // inlining. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 FlowGraph::kEffect); | 2088 FlowGraph::kEffect); |
| 2089 current_iterator()->RemoveCurrentFromGraph(); | 2089 current_iterator()->RemoveCurrentFromGraph(); |
| 2090 } | 2090 } |
| 2091 } | 2091 } |
| 2092 } | 2092 } |
| 2093 } | 2093 } |
| 2094 | 2094 |
| 2095 #endif // DART_PRECOMPILER | 2095 #endif // DART_PRECOMPILER |
| 2096 | 2096 |
| 2097 } // namespace dart | 2097 } // namespace dart |
| OLD | NEW |