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 |