| 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 2132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2143 } else { | 2143 } else { |
| 2144 return false; | 2144 return false; |
| 2145 } | 2145 } |
| 2146 break; | 2146 break; |
| 2147 case Token::kSHR: | 2147 case Token::kSHR: |
| 2148 case Token::kSHL: | 2148 case Token::kSHL: |
| 2149 if (HasOnlyTwoOf(ic_data, kSmiCid)) { | 2149 if (HasOnlyTwoOf(ic_data, kSmiCid)) { |
| 2150 // Left shift may overflow from smi into mint or big ints. | 2150 // Left shift may overflow from smi into mint or big ints. |
| 2151 // Don't generate smi code if the IC data is marked because | 2151 // Don't generate smi code if the IC data is marked because |
| 2152 // of an overflow. | 2152 // of an overflow. |
| 2153 if (ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) { | 2153 if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) { |
| 2154 return false; | 2154 return false; |
| 2155 } | 2155 } |
| 2156 operands_type = ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp) | 2156 operands_type = ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp) |
| 2157 ? kMintCid | 2157 ? kMintCid |
| 2158 : kSmiCid; | 2158 : kSmiCid; |
| 2159 } else if (HasTwoMintOrSmi(ic_data) && | 2159 } else if (HasTwoMintOrSmi(ic_data) && |
| 2160 HasOnlyOneSmi(ICData::Handle(I, | 2160 HasOnlyOneSmi(ICData::Handle(I, |
| 2161 ic_data.AsUnaryClassChecksForArgNr(1)))) { | 2161 ic_data.AsUnaryClassChecksForArgNr(1)))) { |
| 2162 // Don't generate mint code if the IC data is marked because of an | 2162 // Don't generate mint code if the IC data is marked because of an |
| 2163 // overflow. | 2163 // overflow. |
| 2164 if (ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) { | 2164 if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) { |
| 2165 return false; | 2165 return false; |
| 2166 } | 2166 } |
| 2167 // Check for smi/mint << smi or smi/mint >> smi. | 2167 // Check for smi/mint << smi or smi/mint >> smi. |
| 2168 operands_type = kMintCid; | 2168 operands_type = kMintCid; |
| 2169 } else { | 2169 } else { |
| 2170 return false; | 2170 return false; |
| 2171 } | 2171 } |
| 2172 break; | 2172 break; |
| 2173 case Token::kMOD: | 2173 case Token::kMOD: |
| 2174 case Token::kTRUNCDIV: | 2174 case Token::kTRUNCDIV: |
| (...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3156 return TryInlineFloat64x2Method(call, recognized_kind); | 3156 return TryInlineFloat64x2Method(call, recognized_kind); |
| 3157 } | 3157 } |
| 3158 | 3158 |
| 3159 if (recognized_kind == MethodRecognizer::kIntegerLeftShiftWithMask32) { | 3159 if (recognized_kind == MethodRecognizer::kIntegerLeftShiftWithMask32) { |
| 3160 ASSERT(call->ArgumentCount() == 3); | 3160 ASSERT(call->ArgumentCount() == 3); |
| 3161 ASSERT(ic_data.NumArgsTested() == 2); | 3161 ASSERT(ic_data.NumArgsTested() == 2); |
| 3162 Definition* value = call->ArgumentAt(0); | 3162 Definition* value = call->ArgumentAt(0); |
| 3163 Definition* count = call->ArgumentAt(1); | 3163 Definition* count = call->ArgumentAt(1); |
| 3164 Definition* int32_mask = call->ArgumentAt(2); | 3164 Definition* int32_mask = call->ArgumentAt(2); |
| 3165 if (HasOnlyTwoOf(ic_data, kSmiCid)) { | 3165 if (HasOnlyTwoOf(ic_data, kSmiCid)) { |
| 3166 if (ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) { | 3166 if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) { |
| 3167 return false; | 3167 return false; |
| 3168 } | 3168 } |
| 3169 // We cannot overflow. The input value must be a Smi | 3169 // We cannot overflow. The input value must be a Smi |
| 3170 AddCheckSmi(value, call->deopt_id(), call->env(), call); | 3170 AddCheckSmi(value, call->deopt_id(), call->env(), call); |
| 3171 AddCheckSmi(count, call->deopt_id(), call->env(), call); | 3171 AddCheckSmi(count, call->deopt_id(), call->env(), call); |
| 3172 ASSERT(int32_mask->IsConstant()); | 3172 ASSERT(int32_mask->IsConstant()); |
| 3173 const Integer& mask_literal = Integer::Cast( | 3173 const Integer& mask_literal = Integer::Cast( |
| 3174 int32_mask->AsConstant()->value()); | 3174 int32_mask->AsConstant()->value()); |
| 3175 const int64_t mask_value = mask_literal.AsInt64Value(); | 3175 const int64_t mask_value = mask_literal.AsInt64Value(); |
| 3176 ASSERT(mask_value >= 0); | 3176 ASSERT(mask_value >= 0); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3196 call->deopt_id()); | 3196 call->deopt_id()); |
| 3197 ReplaceCall(call, bit_and); | 3197 ReplaceCall(call, bit_and); |
| 3198 } | 3198 } |
| 3199 return true; | 3199 return true; |
| 3200 } | 3200 } |
| 3201 | 3201 |
| 3202 if (HasTwoMintOrSmi(ic_data) && | 3202 if (HasTwoMintOrSmi(ic_data) && |
| 3203 HasOnlyOneSmi(ICData::Handle(I, | 3203 HasOnlyOneSmi(ICData::Handle(I, |
| 3204 ic_data.AsUnaryClassChecksForArgNr(1)))) { | 3204 ic_data.AsUnaryClassChecksForArgNr(1)))) { |
| 3205 if (!FlowGraphCompiler::SupportsUnboxedMints() || | 3205 if (!FlowGraphCompiler::SupportsUnboxedMints() || |
| 3206 ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) { | 3206 ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) { |
| 3207 return false; | 3207 return false; |
| 3208 } | 3208 } |
| 3209 ShiftMintOpInstr* left_shift = | 3209 ShiftMintOpInstr* left_shift = |
| 3210 new(I) ShiftMintOpInstr(Token::kSHL, | 3210 new(I) ShiftMintOpInstr(Token::kSHL, |
| 3211 new(I) Value(value), | 3211 new(I) Value(value), |
| 3212 new(I) Value(count), | 3212 new(I) Value(count), |
| 3213 call->deopt_id()); | 3213 call->deopt_id()); |
| 3214 InsertBefore(call, left_shift, call->env(), FlowGraph::kValue); | 3214 InsertBefore(call, left_shift, call->env(), FlowGraph::kValue); |
| 3215 BinaryMintOpInstr* bit_and = | 3215 BinaryMintOpInstr* bit_and = |
| 3216 new(I) BinaryMintOpInstr(Token::kBIT_AND, | 3216 new(I) BinaryMintOpInstr(Token::kBIT_AND, |
| (...skipping 6861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10078 | 10078 |
| 10079 // Insert materializations at environment uses. | 10079 // Insert materializations at environment uses. |
| 10080 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 10080 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 10081 CreateMaterializationAt( | 10081 CreateMaterializationAt( |
| 10082 exits_collector_.exits()[i], alloc, *slots); | 10082 exits_collector_.exits()[i], alloc, *slots); |
| 10083 } | 10083 } |
| 10084 } | 10084 } |
| 10085 | 10085 |
| 10086 | 10086 |
| 10087 } // namespace dart | 10087 } // namespace dart |
| OLD | NEW |