Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/address-map.h" | 9 #include "src/address-map.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1117 | 1117 |
| 1118 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, | 1118 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, |
| 1119 SimplifiedLowering* lowering) { | 1119 SimplifiedLowering* lowering) { |
| 1120 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can | 1120 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can |
| 1121 // only eliminate an unused speculative number operation if we know that | 1121 // only eliminate an unused speculative number operation if we know that |
| 1122 // the inputs are PlainPrimitive, which excludes everything that's might | 1122 // the inputs are PlainPrimitive, which excludes everything that's might |
| 1123 // have side effects or throws during a ToNumber conversion. | 1123 // have side effects or throws during a ToNumber conversion. |
| 1124 if (BothInputsAre(node, Type::PlainPrimitive())) { | 1124 if (BothInputsAre(node, Type::PlainPrimitive())) { |
| 1125 if (truncation.IsUnused()) return VisitUnused(node); | 1125 if (truncation.IsUnused()) return VisitUnused(node); |
| 1126 } | 1126 } |
| 1127 if (BothInputsAre(node, Type::Signed32OrMinusZero()) && | 1127 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) && |
| 1128 NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1128 (GetUpperBound(node)->Is(Type::Signed32()) || |
| 1129 // int32 + int32 = int32 ==> signed Int32Add/Sub | 1129 GetUpperBound(node)->Is(Type::Unsigned32()) || |
| 1130 truncation.IsUsedAsWord32())) { | |
| 1131 // => Int32Add/Sub | |
| 1130 VisitInt32Binop(node); | 1132 VisitInt32Binop(node); |
|
Jarin
2016/08/19 08:41:07
Use VisitWord32TuncatingBinop here, please.
(Even
Benedikt Meurer
2016/08/19 09:16:02
Done.
| |
| 1131 if (lower()) ChangeToPureOp(node, Int32Op(node)); | 1133 if (lower()) ChangeToPureOp(node, Int32Op(node)); |
| 1132 return; | 1134 return; |
| 1133 } | 1135 } |
| 1134 | |
| 1135 // Use truncation if available. | |
| 1136 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) && | |
| 1137 truncation.IsUsedAsWord32()) { | |
| 1138 // safe-int + safe-int = x (truncated to int32) | |
| 1139 // => signed Int32Add/Sub (truncated) | |
| 1140 VisitWord32TruncatingBinop(node); | |
| 1141 if (lower()) ChangeToPureOp(node, Int32Op(node)); | |
| 1142 return; | |
| 1143 } | |
| 1144 | 1136 |
| 1145 // Try to use type feedback. | 1137 // Try to use type feedback. |
| 1146 NumberOperationHint hint = NumberOperationHintOf(node->op()); | 1138 NumberOperationHint hint = NumberOperationHintOf(node->op()); |
| 1147 | 1139 |
| 1148 // Handle the case when no int32 checks on inputs are necessary | 1140 // Handle the case when no int32 checks on inputs are necessary |
| 1149 // (but an overflow check is needed on the output). | 1141 // (but an overflow check is needed on the output). |
| 1150 if (BothInputsAre(node, Type::Signed32()) || | 1142 if (BothInputsAre(node, Type::Signed32()) || |
| 1151 (BothInputsAre(node, Type::Signed32OrMinusZero()) && | 1143 (BothInputsAre(node, Type::Signed32OrMinusZero()) && |
| 1152 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) { | 1144 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) { |
| 1153 // If both the inputs the feedback are int32, use the overflow op. | 1145 // If both the inputs the feedback are int32, use the overflow op. |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1380 MachineRepresentation::kBit); | 1372 MachineRepresentation::kBit); |
| 1381 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1373 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
| 1382 return; | 1374 return; |
| 1383 } | 1375 } |
| 1384 UNREACHABLE(); | 1376 UNREACHABLE(); |
| 1385 return; | 1377 return; |
| 1386 } | 1378 } |
| 1387 | 1379 |
| 1388 case IrOpcode::kNumberAdd: | 1380 case IrOpcode::kNumberAdd: |
| 1389 case IrOpcode::kNumberSubtract: { | 1381 case IrOpcode::kNumberSubtract: { |
| 1390 if (BothInputsAre(node, Type::Signed32()) && | 1382 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) && |
| 1391 NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1383 (GetUpperBound(node)->Is(Type::Signed32()) || |
| 1392 // int32 + int32 = int32 | 1384 GetUpperBound(node)->Is(Type::Unsigned32()) || |
| 1393 // => signed Int32Add/Sub | 1385 truncation.IsUsedAsWord32())) { |
| 1386 // => Int32Add/Sub | |
| 1394 VisitInt32Binop(node); | 1387 VisitInt32Binop(node); |
| 1395 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 1388 if (lower()) ChangeToPureOp(node, Int32Op(node)); |
| 1396 } else if (BothInputsAre(node, | |
| 1397 type_cache_.kAdditiveSafeIntegerOrMinusZero) && | |
| 1398 truncation.IsUsedAsWord32()) { | |
| 1399 // safe-int + safe-int = x (truncated to int32) | |
| 1400 // => signed Int32Add/Sub (truncated) | |
| 1401 VisitWord32TruncatingBinop(node); | |
| 1402 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | |
| 1403 } else { | 1389 } else { |
| 1404 // => Float64Add/Sub | 1390 // => Float64Add/Sub |
| 1405 VisitFloat64Binop(node); | 1391 VisitFloat64Binop(node); |
| 1406 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 1392 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
| 1407 } | 1393 } |
| 1408 return; | 1394 return; |
| 1409 } | 1395 } |
| 1410 case IrOpcode::kSpeculativeNumberMultiply: { | 1396 case IrOpcode::kSpeculativeNumberMultiply: { |
| 1411 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we | 1397 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we |
| 1412 // can only eliminate an unused speculative number operation if we know | 1398 // can only eliminate an unused speculative number operation if we know |
| 1413 // that the inputs are PlainPrimitive, which excludes everything that's | 1399 // that the inputs are PlainPrimitive, which excludes everything that's |
| 1414 // might have side effects or throws during a ToNumber conversion. | 1400 // might have side effects or throws during a ToNumber conversion. |
| 1415 if (BothInputsAre(node, Type::PlainPrimitive())) { | 1401 if (BothInputsAre(node, Type::PlainPrimitive())) { |
| 1416 if (truncation.IsUnused()) return VisitUnused(node); | 1402 if (truncation.IsUnused()) return VisitUnused(node); |
| (...skipping 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3337 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3323 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 3338 Operator::kNoProperties); | 3324 Operator::kNoProperties); |
| 3339 to_number_operator_.set(common()->Call(desc)); | 3325 to_number_operator_.set(common()->Call(desc)); |
| 3340 } | 3326 } |
| 3341 return to_number_operator_.get(); | 3327 return to_number_operator_.get(); |
| 3342 } | 3328 } |
| 3343 | 3329 |
| 3344 } // namespace compiler | 3330 } // namespace compiler |
| 3345 } // namespace internal | 3331 } // namespace internal |
| 3346 } // namespace v8 | 3332 } // namespace v8 |
| OLD | NEW |