OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 frame_state, effect, control); | 1308 frame_state, effect, control); |
1309 | 1309 |
1310 return ValueEffectControl(value, effect, control); | 1310 return ValueEffectControl(value, effect, control); |
1311 } | 1311 } |
1312 | 1312 |
1313 EffectControlLinearizer::ValueEffectControl | 1313 EffectControlLinearizer::ValueEffectControl |
1314 EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state, | 1314 EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state, |
1315 Node* effect, Node* control) { | 1315 Node* effect, Node* control) { |
1316 Node* zero = jsgraph()->Int32Constant(0); | 1316 Node* zero = jsgraph()->Int32Constant(0); |
1317 Node* one = jsgraph()->Int32Constant(1); | 1317 Node* one = jsgraph()->Int32Constant(1); |
1318 Node* minusone = jsgraph()->Int32Constant(-1); | |
1319 | 1318 |
1320 // General case for signed integer modulus, with optimization for (unknown) | 1319 // General case for signed integer modulus, with optimization for (unknown) |
1321 // power of 2 right hand side. | 1320 // power of 2 right hand side. |
1322 // | 1321 // |
1323 // if 1 < rhs then | 1322 // if rhs <= 0 then |
1324 // msk = rhs - 1 | 1323 // rhs = -rhs |
| 1324 // deopt if rhs == 0 |
| 1325 // if lhs < 0 then |
| 1326 // let res = lhs % rhs in |
| 1327 // deopt if res == 0 |
| 1328 // res |
| 1329 // else |
| 1330 // let msk = rhs - 1 in |
1325 // if rhs & msk == 0 then | 1331 // if rhs & msk == 0 then |
1326 // if lhs < 0 then | 1332 // lhs & msk |
1327 // -(-lhs & msk) | |
1328 // else | |
1329 // lhs & msk | |
1330 // else | 1333 // else |
1331 // lhs % rhs | 1334 // lhs % rhs |
1332 // else | |
1333 // if rhs < -1 then | |
1334 // lhs % rhs | |
1335 // else | |
1336 // deopt if rhs == 0 | |
1337 // deopt if lhs < 0 | |
1338 // zero | |
1339 // | 1335 // |
1340 Node* lhs = node->InputAt(0); | 1336 Node* lhs = node->InputAt(0); |
1341 Node* rhs = node->InputAt(1); | 1337 Node* rhs = node->InputAt(1); |
1342 | 1338 |
1343 // Check if {rhs} is strictly greater than one. | 1339 // Check if {rhs} is not strictly positive. |
1344 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), one, rhs); | 1340 Node* check0 = graph()->NewNode(machine()->Int32LessThanOrEqual(), rhs, zero); |
1345 Node* branch0 = | 1341 Node* branch0 = |
1346 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); | 1342 graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control); |
1347 | 1343 |
1348 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1344 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
1349 Node* etrue0 = effect; | 1345 Node* etrue0 = effect; |
1350 Node* vtrue0; | 1346 Node* vtrue0; |
1351 { | 1347 { |
1352 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minusone); | 1348 // Negate {rhs}, might still produce a negative result in case of |
| 1349 // -2^31, but that is handled safely below. |
| 1350 vtrue0 = graph()->NewNode(machine()->Int32Sub(), zero, rhs); |
1353 | 1351 |
1354 // Check if {rhs} minus one is a valid mask. | 1352 // Ensure that {rhs} is not zero, otherwise we'd have to return NaN. |
1355 Node* check1 = graph()->NewNode( | 1353 Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue0, zero); |
1356 machine()->Word32Equal(), | 1354 if_true0 = etrue0 = graph()->NewNode( |
1357 graph()->NewNode(machine()->Word32And(), rhs, msk), zero); | 1355 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check, |
1358 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0); | 1356 frame_state, etrue0, if_true0); |
1359 | |
1360 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
1361 Node* vtrue1; | |
1362 { | |
1363 // Check if {lhs} is negative. | |
1364 Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero); | |
1365 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
1366 check2, if_true1); | |
1367 | |
1368 // Compute the remainder as {-(-lhs & msk)}. | |
1369 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); | |
1370 Node* vtrue2 = graph()->NewNode( | |
1371 machine()->Int32Sub(), zero, | |
1372 graph()->NewNode(machine()->Word32And(), | |
1373 graph()->NewNode(machine()->Int32Sub(), zero, lhs), | |
1374 msk)); | |
1375 | |
1376 // Compute the remainder as {lhs & msk}. | |
1377 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); | |
1378 Node* vfalse2 = graph()->NewNode(machine()->Word32And(), lhs, msk); | |
1379 | |
1380 if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); | |
1381 vtrue1 = | |
1382 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), | |
1383 vtrue2, vfalse2, if_true1); | |
1384 } | |
1385 | |
1386 // Compute the remainder using the generic {lhs % rhs}. | |
1387 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
1388 Node* vfalse1 = | |
1389 graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false1); | |
1390 | |
1391 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
1392 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), | |
1393 vtrue1, vfalse1, if_true0); | |
1394 } | 1357 } |
1395 | 1358 |
1396 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 1359 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
1397 Node* efalse0 = effect; | 1360 Node* efalse0 = effect; |
1398 Node* vfalse0; | 1361 Node* vfalse0 = rhs; |
| 1362 |
| 1363 // At this point {rhs} is either greater than zero or -2^31, both are |
| 1364 // fine for the code that follows. |
| 1365 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1366 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
| 1367 rhs = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
| 1368 vtrue0, vfalse0, control); |
| 1369 |
| 1370 // Check if {lhs} is negative. |
| 1371 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero); |
| 1372 Node* branch1 = |
| 1373 graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control); |
| 1374 |
| 1375 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 1376 Node* etrue1 = effect; |
| 1377 Node* vtrue1; |
1399 { | 1378 { |
1400 // Check if {rhs} is strictly less than -1. | 1379 // Compute the remainder using {lhs % msk}. |
1401 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minusone); | 1380 vtrue1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1); |
1402 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue), | 1381 |
1403 check1, if_false0); | 1382 // Check if we would have to return -0. |
| 1383 Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue1, zero); |
| 1384 if_true1 = etrue1 = |
| 1385 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero), |
| 1386 check, frame_state, etrue1, if_true1); |
| 1387 } |
| 1388 |
| 1389 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 1390 Node* efalse1 = effect; |
| 1391 Node* vfalse1; |
| 1392 { |
| 1393 Node* msk = graph()->NewNode(machine()->Int32Sub(), rhs, one); |
| 1394 |
| 1395 // Check if {rhs} minus one is a valid mask. |
| 1396 Node* check2 = graph()->NewNode( |
| 1397 machine()->Word32Equal(), |
| 1398 graph()->NewNode(machine()->Word32And(), rhs, msk), zero); |
| 1399 Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1); |
| 1400 |
| 1401 // Compute the remainder using {lhs & msk}. |
| 1402 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
| 1403 Node* vtrue2 = graph()->NewNode(machine()->Word32And(), lhs, msk); |
1404 | 1404 |
1405 // Compute the remainder using the generic {lhs % rhs}. | 1405 // Compute the remainder using the generic {lhs % rhs}. |
1406 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | 1406 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
1407 Node* etrue1 = efalse0; | 1407 Node* vfalse2 = |
1408 Node* vtrue1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1); | 1408 graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false2); |
1409 | 1409 |
1410 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | 1410 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
1411 Node* efalse1 = efalse0; | 1411 vfalse1 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
1412 Node* vfalse1; | 1412 vtrue2, vfalse2, if_false1); |
1413 { | |
1414 // Ensure that {rhs} is not zero. | |
1415 Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero); | |
1416 if_false1 = efalse1 = graph()->NewNode( | |
1417 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check2, | |
1418 frame_state, efalse1, if_false1); | |
1419 | |
1420 // Now we know that {rhs} is -1, so make sure {lhs} is >= 0, as we would | |
1421 // otherwise have to return -0. | |
1422 Node* check3 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero); | |
1423 if_false1 = efalse1 = | |
1424 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero), | |
1425 check3, frame_state, efalse1, if_false1); | |
1426 | |
1427 // The remainder is zero. | |
1428 vfalse1 = zero; | |
1429 } | |
1430 | |
1431 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
1432 efalse0 = | |
1433 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); | |
1434 vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), | |
1435 vtrue1, vfalse1, if_false0); | |
1436 } | 1413 } |
1437 | 1414 |
1438 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | 1415 control = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
1439 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); | 1416 effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control); |
1440 Node* value = | 1417 Node* value = |
1441 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0, | 1418 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue1, |
1442 vfalse0, control); | 1419 vfalse1, control); |
1443 | 1420 |
1444 return ValueEffectControl(value, effect, control); | 1421 return ValueEffectControl(value, effect, control); |
1445 } | 1422 } |
1446 | 1423 |
1447 EffectControlLinearizer::ValueEffectControl | 1424 EffectControlLinearizer::ValueEffectControl |
1448 EffectControlLinearizer::LowerCheckedUint32Div(Node* node, Node* frame_state, | 1425 EffectControlLinearizer::LowerCheckedUint32Div(Node* node, Node* frame_state, |
1449 Node* effect, Node* control) { | 1426 Node* effect, Node* control) { |
1450 Node* zero = jsgraph()->Int32Constant(0); | 1427 Node* zero = jsgraph()->Int32Constant(0); |
1451 | 1428 |
1452 Node* lhs = node->InputAt(0); | 1429 Node* lhs = node->InputAt(0); |
(...skipping 1856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3309 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3286 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3310 Operator::kEliminatable); | 3287 Operator::kEliminatable); |
3311 to_number_operator_.set(common()->Call(desc)); | 3288 to_number_operator_.set(common()->Call(desc)); |
3312 } | 3289 } |
3313 return to_number_operator_.get(); | 3290 return to_number_operator_.get(); |
3314 } | 3291 } |
3315 | 3292 |
3316 } // namespace compiler | 3293 } // namespace compiler |
3317 } // namespace internal | 3294 } // namespace internal |
3318 } // namespace v8 | 3295 } // namespace v8 |
OLD | NEW |