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/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 if (lower()) node->set_op(Int32Op(node)); | 598 if (lower()) node->set_op(Int32Op(node)); |
599 break; | 599 break; |
600 } | 600 } |
601 } | 601 } |
602 // => Float64Mul | 602 // => Float64Mul |
603 VisitFloat64Binop(node); | 603 VisitFloat64Binop(node); |
604 if (lower()) node->set_op(Float64Op(node)); | 604 if (lower()) node->set_op(Float64Op(node)); |
605 break; | 605 break; |
606 } | 606 } |
607 case IrOpcode::kNumberDivide: { | 607 case IrOpcode::kNumberDivide: { |
608 NumberMatcher right(node->InputAt(1)); | 608 if (CanLowerToInt32Binop(node, use)) { |
609 if (right.HasValue() && !right.Is(0) && !right.Is(-1)) { | 609 // => signed Int32Div |
610 if (CanLowerToInt32Binop(node, use)) { | 610 VisitInt32Binop(node); |
611 // => signed Int32Div | 611 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
612 VisitInt32Binop(node); | 612 break; |
613 if (lower()) node->set_op(Int32Op(node)); | 613 } |
614 break; | 614 if (CanLowerToUint32Binop(node, use)) { |
615 } else if (CanLowerToUint32Binop(node, use)) { | 615 // => unsigned Uint32Div |
616 // => unsigned Uint32Div | 616 VisitUint32Binop(node); |
617 VisitUint32Binop(node); | 617 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); |
618 if (lower()) node->set_op(Uint32Op(node)); | 618 break; |
619 break; | |
620 } | |
621 } | 619 } |
622 // => Float64Div | 620 // => Float64Div |
623 VisitFloat64Binop(node); | 621 VisitFloat64Binop(node); |
624 if (lower()) node->set_op(Float64Op(node)); | 622 if (lower()) node->set_op(Float64Op(node)); |
625 break; | 623 break; |
626 } | 624 } |
627 case IrOpcode::kNumberModulus: { | 625 case IrOpcode::kNumberModulus: { |
628 NumberMatcher right(node->InputAt(1)); | 626 if (CanLowerToInt32Binop(node, use)) { |
629 if (right.HasValue() && !right.Is(0) && !right.Is(-1)) { | 627 // => signed Int32Mod |
630 if (BothInputsAre(node, Type::Signed32()) && | 628 VisitInt32Binop(node); |
631 !CanObserveMinusZero(use)) { | 629 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
632 // => signed Int32Mod | 630 break; |
633 VisitInt32Binop(node); | 631 } |
634 if (lower()) node->set_op(Int32Op(node)); | 632 if (CanLowerToUint32Binop(node, use)) { |
635 break; | 633 // => unsigned Uint32Mod |
636 } else if (BothInputsAre(node, Type::Unsigned32())) { | 634 VisitUint32Binop(node); |
637 // => unsigned Uint32Mod | 635 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
638 VisitUint32Binop(node); | 636 break; |
639 if (lower()) node->set_op(Uint32Op(node)); | |
640 break; | |
641 } | |
642 } | 637 } |
643 // => Float64Mod | 638 // => Float64Mod |
644 VisitFloat64Binop(node); | 639 VisitFloat64Binop(node); |
645 if (lower()) node->set_op(Float64Op(node)); | 640 if (lower()) node->set_op(Float64Op(node)); |
646 break; | 641 break; |
647 } | 642 } |
648 case IrOpcode::kNumberToInt32: { | 643 case IrOpcode::kNumberToInt32: { |
649 MachineTypeUnion use_rep = use & kRepMask; | 644 MachineTypeUnion use_rep = use & kRepMask; |
650 Node* input = node->InputAt(0); | 645 Node* input = node->InputAt(0); |
651 MachineTypeUnion in = GetInfo(input)->output; | 646 MachineTypeUnion in = GetInfo(input)->output; |
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 return graph()->NewNode(common()->Call(desc), | 1206 return graph()->NewNode(common()->Call(desc), |
1212 jsgraph()->HeapConstant(stub.GetCode()), | 1207 jsgraph()->HeapConstant(stub.GetCode()), |
1213 NodeProperties::GetValueInput(node, 0), | 1208 NodeProperties::GetValueInput(node, 0), |
1214 NodeProperties::GetValueInput(node, 1), | 1209 NodeProperties::GetValueInput(node, 1), |
1215 jsgraph()->ExternalConstant(ref), | 1210 jsgraph()->ExternalConstant(ref), |
1216 jsgraph()->Int32Constant(2), | 1211 jsgraph()->Int32Constant(2), |
1217 jsgraph()->UndefinedConstant()); | 1212 jsgraph()->UndefinedConstant()); |
1218 } | 1213 } |
1219 | 1214 |
1220 | 1215 |
| 1216 Node* SimplifiedLowering::Int32Div(Node* const node) { |
| 1217 Int32BinopMatcher m(node); |
| 1218 Node* const zero = jsgraph()->Int32Constant(0); |
| 1219 Node* const lhs = m.left().node(); |
| 1220 Node* const rhs = m.right().node(); |
| 1221 |
| 1222 if (m.right().Is(-1)) { |
| 1223 return graph()->NewNode(machine()->Int32Sub(), zero, lhs); |
| 1224 } else if (m.right().Is(0)) { |
| 1225 return rhs; |
| 1226 } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) { |
| 1227 return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start()); |
| 1228 } |
| 1229 |
| 1230 Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
| 1231 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, |
| 1232 graph()->start()); |
| 1233 |
| 1234 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1235 Node* true0 = zero; |
| 1236 |
| 1237 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 1238 Node* false0 = nullptr; |
| 1239 { |
| 1240 Node* check1 = graph()->NewNode(machine()->Word32Equal(), rhs, |
| 1241 jsgraph()->Int32Constant(-1)); |
| 1242 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 1243 check1, if_false0); |
| 1244 |
| 1245 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 1246 Node* true1 = graph()->NewNode(machine()->Int32Sub(), zero, lhs); |
| 1247 |
| 1248 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 1249 Node* false1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_false1); |
| 1250 |
| 1251 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 1252 false0 = graph()->NewNode(common()->Phi(kMachInt32, 2), true1, false1, |
| 1253 if_false0); |
| 1254 } |
| 1255 |
| 1256 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1257 return graph()->NewNode(common()->Phi(kMachInt32, 2), true0, false0, merge0); |
| 1258 } |
| 1259 |
| 1260 |
| 1261 Node* SimplifiedLowering::Int32Mod(Node* const node) { |
| 1262 Int32BinopMatcher m(node); |
| 1263 Node* const zero = jsgraph()->Int32Constant(0); |
| 1264 Node* const lhs = m.left().node(); |
| 1265 Node* const rhs = m.right().node(); |
| 1266 |
| 1267 if (m.right().Is(-1) || m.right().Is(0)) { |
| 1268 return zero; |
| 1269 } else if (machine()->Int32ModIsSafe() || m.right().HasValue()) { |
| 1270 return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start()); |
| 1271 } |
| 1272 |
| 1273 Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
| 1274 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, |
| 1275 graph()->start()); |
| 1276 |
| 1277 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1278 Node* true0 = zero; |
| 1279 |
| 1280 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 1281 Node* false0 = nullptr; |
| 1282 { |
| 1283 Node* check1 = graph()->NewNode(machine()->Word32Equal(), rhs, |
| 1284 jsgraph()->Int32Constant(-1)); |
| 1285 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 1286 check1, if_false0); |
| 1287 |
| 1288 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 1289 Node* true1 = zero; |
| 1290 |
| 1291 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 1292 Node* false1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false1); |
| 1293 |
| 1294 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 1295 false0 = graph()->NewNode(common()->Phi(kMachInt32, 2), true1, false1, |
| 1296 if_false0); |
| 1297 } |
| 1298 |
| 1299 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1300 return graph()->NewNode(common()->Phi(kMachInt32, 2), true0, false0, merge0); |
| 1301 } |
| 1302 |
| 1303 |
| 1304 Node* SimplifiedLowering::Uint32Div(Node* const node) { |
| 1305 Uint32BinopMatcher m(node); |
| 1306 Node* const zero = jsgraph()->Uint32Constant(0); |
| 1307 Node* const lhs = m.left().node(); |
| 1308 Node* const rhs = m.right().node(); |
| 1309 |
| 1310 if (m.right().Is(0)) { |
| 1311 return zero; |
| 1312 } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) { |
| 1313 return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start()); |
| 1314 } |
| 1315 |
| 1316 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
| 1317 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), check, |
| 1318 graph()->start()); |
| 1319 |
| 1320 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 1321 Node* vtrue = zero; |
| 1322 |
| 1323 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 1324 Node* vfalse = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, if_false); |
| 1325 |
| 1326 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 1327 return graph()->NewNode(common()->Phi(kMachUint32, 2), vtrue, vfalse, merge); |
| 1328 } |
| 1329 |
| 1330 |
| 1331 Node* SimplifiedLowering::Uint32Mod(Node* const node) { |
| 1332 Uint32BinopMatcher m(node); |
| 1333 Node* const zero = jsgraph()->Uint32Constant(0); |
| 1334 Node* const lhs = m.left().node(); |
| 1335 Node* const rhs = m.right().node(); |
| 1336 |
| 1337 if (m.right().Is(0)) { |
| 1338 return zero; |
| 1339 } else if (machine()->Uint32ModIsSafe() || m.right().HasValue()) { |
| 1340 return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start()); |
| 1341 } |
| 1342 |
| 1343 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
| 1344 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), check, |
| 1345 graph()->start()); |
| 1346 |
| 1347 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 1348 Node* vtrue = zero; |
| 1349 |
| 1350 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 1351 Node* vfalse = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_false); |
| 1352 |
| 1353 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 1354 return graph()->NewNode(common()->Phi(kMachUint32, 2), vtrue, vfalse, merge); |
| 1355 } |
| 1356 |
| 1357 |
1221 void SimplifiedLowering::DoStringEqual(Node* node) { | 1358 void SimplifiedLowering::DoStringEqual(Node* node) { |
1222 node->set_op(machine()->WordEqual()); | 1359 node->set_op(machine()->WordEqual()); |
1223 node->ReplaceInput(0, StringComparison(node, false)); | 1360 node->ReplaceInput(0, StringComparison(node, false)); |
1224 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1361 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1225 } | 1362 } |
1226 | 1363 |
1227 | 1364 |
1228 void SimplifiedLowering::DoStringLessThan(Node* node) { | 1365 void SimplifiedLowering::DoStringLessThan(Node* node) { |
1229 node->set_op(machine()->IntLessThan()); | 1366 node->set_op(machine()->IntLessThan()); |
1230 node->ReplaceInput(0, StringComparison(node, true)); | 1367 node->ReplaceInput(0, StringComparison(node, true)); |
1231 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1368 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1232 } | 1369 } |
1233 | 1370 |
1234 | 1371 |
1235 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1372 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
1236 node->set_op(machine()->IntLessThanOrEqual()); | 1373 node->set_op(machine()->IntLessThanOrEqual()); |
1237 node->ReplaceInput(0, StringComparison(node, true)); | 1374 node->ReplaceInput(0, StringComparison(node, true)); |
1238 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1375 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1239 } | 1376 } |
1240 | 1377 |
1241 | 1378 |
1242 } // namespace compiler | 1379 } // namespace compiler |
1243 } // namespace internal | 1380 } // namespace internal |
1244 } // namespace v8 | 1381 } // namespace v8 |
OLD | NEW |