Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: src/compiler/effect-control-linearizer.cc

Issue 2200453002: [turbofan] Optimize CheckedInt32Mod with unknown power of 2 right hand side. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 return ValueEffectControl(value, effect, control); 1278 return ValueEffectControl(value, effect, control);
1279 } 1279 }
1280 1280
1281 EffectControlLinearizer::ValueEffectControl 1281 EffectControlLinearizer::ValueEffectControl
1282 EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state, 1282 EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state,
1283 Node* effect, Node* control) { 1283 Node* effect, Node* control) {
1284 Node* zero = jsgraph()->Int32Constant(0); 1284 Node* zero = jsgraph()->Int32Constant(0);
1285 Node* minusone = jsgraph()->Int32Constant(-1); 1285 Node* minusone = jsgraph()->Int32Constant(-1);
1286 Node* minint = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::min()); 1286 Node* minint = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::min());
1287 1287
1288 // General case for signed integer modulus, with optimization for (unknown)
1289 // power of 2 right hand side.
1290 //
1291 // if 0 < rhs then
1292 // msk = rhs - 1
1293 // if rhs & msk == 0 then
1294 // if lhs < 0 then
1295 // -(-lhs & msk)
1296 // else
1297 // lhs & msk
1298 // else
1299 // lhs % rhs
1300 // else
1301 // if rhs < -1 then
1302 // lhs % rhs
1303 // else
1304 // deopt if rhs == 0
1305 // deopt if lhs == minint
1306 // zero
1307 //
1288 Node* lhs = node->InputAt(0); 1308 Node* lhs = node->InputAt(0);
1289 Node* rhs = node->InputAt(1); 1309 Node* rhs = node->InputAt(1);
1290 1310
1291 // Ensure that {rhs} is not zero, otherwise we'd have to return NaN. 1311 // Check if {rhs} is strictly positive.
1292 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); 1312 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
1293 control = effect = graph()->NewNode(
1294 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check,
1295 frame_state, effect, control);
1296
1297 // Check if {lhs} is positive or zero.
1298 Node* check0 = graph()->NewNode(machine()->Int32LessThanOrEqual(), zero, lhs);
1299 Node* branch0 = 1313 Node* branch0 =
1300 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); 1314 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
1301 1315
1302 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); 1316 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1303 Node* etrue0 = effect; 1317 Node* etrue0 = effect;
1304 Node* vtrue0; 1318 Node* vtrue0;
1305 { 1319 {
1306 // Fast case, no additional checking required. 1320 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minusone);
1307 vtrue0 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true0); 1321
1322 // Check if {rhs} minus one is a valid mask.
1323 Node* check1 = graph()->NewNode(
1324 machine()->Word32Equal(),
1325 graph()->NewNode(machine()->Word32And(), rhs, msk), zero);
1326 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
1327
1328 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1329 Node* vtrue1;
1330 {
1331 // Check if {lhs} is negative.
1332 Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
1333 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1334 check2, if_true1);
1335
1336 // Compute the remainder as {-(-lhs & msk)}.
1337 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1338 Node* vtrue2 = graph()->NewNode(
1339 machine()->Int32Sub(), zero,
1340 graph()->NewNode(machine()->Word32And(),
1341 graph()->NewNode(machine()->Int32Sub(), zero, lhs),
1342 msk));
1343
1344 // Compute the remainder as {lhs & msk}.
1345 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1346 Node* vfalse2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
1347
1348 if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
1349 vtrue1 =
1350 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1351 vtrue2, vfalse2, if_true1);
1352 }
1353
1354 // Compute the remainder using the generic {lhs % rhs}.
1355 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1356 Node* vfalse1 =
1357 graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false1);
1358
1359 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1360 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1361 vtrue1, vfalse1, if_true0);
1308 } 1362 }
1309 1363
1310 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); 1364 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1311 Node* efalse0 = effect; 1365 Node* efalse0 = effect;
1312 Node* vfalse0; 1366 Node* vfalse0;
1313 { 1367 {
1314 // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have 1368 // Check if {rhs} is strictly less than -1.
1315 // to return -0. 1369 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minusone);
1316 Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint); 1370 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
1317 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1318 check1, if_false0); 1371 check1, if_false0);
1319 1372
1373 // Compute the remainder using the generic {lhs % rhs}.
1320 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); 1374 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1321 Node* etrue1 = efalse0; 1375 Node* etrue1 = efalse0;
1322 { 1376 Node* vtrue1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
1323 // Check if {rhs} is -1.
1324 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, minusone);
1325 if_true1 = etrue1 =
1326 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1327 check, frame_state, etrue1, if_true1);
1328 }
1329 1377
1330 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); 1378 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1331 Node* efalse1 = efalse0; 1379 Node* efalse1 = efalse0;
1380 Node* vfalse1;
1381 {
1382 // Ensure that {rhs} is not zero.
1383 Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
1384 if_false1 = efalse1 = graph()->NewNode(
1385 common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check2,
1386 frame_state, efalse1, if_false1);
1387
1388 // Now we know that {rhs} is -1, so make sure {lhs} is not kMinInt, as
1389 // we would otherwise have to return -0.
1390 Node* check3 = graph()->NewNode(machine()->Word32Equal(), lhs, minint);
1391 if_false1 = efalse1 =
1392 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1393 check3, frame_state, efalse1, if_false1);
1394
1395 // The remainder is zero.
1396 vfalse1 = zero;
1397 }
1332 1398
1333 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); 1399 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1334 efalse0 = 1400 efalse0 =
1335 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); 1401 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
1336 1402 vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
1337 // Perform the actual integer modulos. 1403 vtrue1, vfalse1, if_false0);
1338 vfalse0 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false0);
1339
1340 // Check if the result is zero, because in that case we'd have to return
1341 // -0 here since we always take the signe of the {lhs} which is negative.
1342 Node* check = graph()->NewNode(machine()->Word32Equal(), vfalse0, zero);
1343 if_false0 = efalse0 =
1344 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero),
1345 check, frame_state, efalse0, if_false0);
1346 } 1404 }
1347 1405
1348 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 1406 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1349 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); 1407 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
1350 Node* value = 1408 Node* value =
1351 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0, 1409 graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0,
1352 vfalse0, control); 1410 vfalse0, control);
1353 1411
1354 return ValueEffectControl(value, effect, control); 1412 return ValueEffectControl(value, effect, control);
1355 } 1413 }
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 2635 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
2578 Operator::kNoThrow); 2636 Operator::kNoThrow);
2579 to_number_operator_.set(common()->Call(desc)); 2637 to_number_operator_.set(common()->Call(desc));
2580 } 2638 }
2581 return to_number_operator_.get(); 2639 return to_number_operator_.get();
2582 } 2640 }
2583 2641
2584 } // namespace compiler 2642 } // namespace compiler
2585 } // namespace internal 2643 } // namespace internal
2586 } // namespace v8 2644 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698