| 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 |