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

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 11773040: Canonicalize away simple arithmetic equivalences. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add test, address comments Created 7 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_allocator.h" 9 #include "vm/flow_graph_allocator.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 return Type::Double(); 1373 return Type::Double();
1374 } 1374 }
1375 1375
1376 1376
1377 intptr_t BinaryDoubleOpInstr::ResultCid() const { 1377 intptr_t BinaryDoubleOpInstr::ResultCid() const {
1378 // The output is not an instance but when it is boxed it becomes double. 1378 // The output is not an instance but when it is boxed it becomes double.
1379 return kDoubleCid; 1379 return kDoubleCid;
1380 } 1380 }
1381 1381
1382 1382
1383 static bool ToIntegerConstant(Value* value, intptr_t* result) {
1384 if (!value->BindsToConstant()) {
1385 return false;
1386 }
1387
1388 const Object& constant = value->BoundConstant();
1389 if (constant.IsDouble()) {
1390 const Double& double_constant = Double::Cast(constant);
1391 *result = static_cast<intptr_t>(double_constant.value());
1392 return (static_cast<double>(*result) == double_constant.value());
1393 } else if (constant.IsSmi()) {
1394 *result = Smi::Cast(constant).Value();
1395 return true;
1396 }
1397
1398 return false;
1399 }
1400
1401
1402 static Definition* CanonicalizeCommutativeArithmetic(
1403 FlowGraphOptimizer* optimizer,
1404 Definition* defn,
1405 Token::Kind op,
1406 intptr_t cid,
1407 Value* left,
1408 Value* right) {
1409 ASSERT((cid == kSmiCid) || (cid == kDoubleCid) || (cid == kMintCid));
1410
1411 intptr_t left_value;
1412 if (!ToIntegerConstant(left, &left_value)) {
1413 return NULL;
1414 }
1415
1416 switch (op) {
1417 case Token::kMUL:
1418 if (left_value == 1) {
1419 if ((cid == kDoubleCid) &&
1420 (right->definition()->representation() != kUnboxedDouble)) {
1421 // Ensure that the result of the operation (right value) is coerced
1422 // to double.
1423 UnboxDoubleInstr* unbox =
1424 new UnboxDoubleInstr(right->Copy(),
1425 defn->DeoptimizationTarget());
1426 optimizer->InsertBefore(defn,
1427 unbox,
1428 defn->env(),
1429 Definition::kValue);
1430 return unbox;
1431 } else {
1432 return right->definition();
1433 }
1434 } else if ((left_value == 0) && (cid != kDoubleCid)) {
1435 // Can't apply this equivalence to double operation because
1436 // 0.0 * NaN is NaN not 0.0.
1437 return left->definition();
1438 }
1439 break;
1440 case Token::kADD:
1441 if ((left_value == 0) && (cid != kDoubleCid)) {
1442 // Can't apply this equivalence to double operations because
1443 // 0.0 + (-0.0) is 0.0 not -0.0.
1444 return right->definition();
1445 }
1446 break;
1447 case Token::kBIT_AND:
1448 ASSERT(cid != kDoubleCid);
1449 if (left_value == 0) {
1450 return left->definition();
1451 } else if (left_value == -1) {
1452 return right->definition();
1453 }
1454 break;
1455 case Token::kBIT_OR:
1456 ASSERT(cid != kDoubleCid);
1457 if (left_value == 0) {
1458 return right->definition();
1459 } else if (left_value == -1) {
1460 return left->definition();
1461 }
1462 break;
1463 case Token::kBIT_XOR:
1464 ASSERT(cid != kDoubleCid);
1465 if (left_value == 0) {
1466 return right->definition();
1467 }
1468 break;
1469 default:
1470 break;
1471 }
1472
1473 return NULL;
1474 }
1475
1476
1477 Definition* BinaryDoubleOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1478 Definition* result = NULL;
1479
1480 result = CanonicalizeCommutativeArithmetic(optimizer,
1481 this,
1482 op_kind(),
1483 kDoubleCid,
1484 left(),
1485 right());
1486 if (result != NULL) {
1487 return result;
1488 }
1489
1490 result = CanonicalizeCommutativeArithmetic(optimizer,
1491 this,
1492 op_kind(),
1493 kDoubleCid,
1494 right(),
1495 left());
1496 if (result != NULL) {
1497 return result;
1498 }
1499
1500 return this;
1501 }
1502
1503
1504 Definition* BinarySmiOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1505 Definition* result = NULL;
1506
1507 result = CanonicalizeCommutativeArithmetic(optimizer,
1508 this,
1509 op_kind(),
1510 kSmiCid,
1511 left(),
1512 right());
1513 if (result != NULL) {
1514 return result;
1515 }
1516
1517 result = CanonicalizeCommutativeArithmetic(optimizer,
1518 this,
1519 op_kind(),
1520 kSmiCid,
1521 right(),
1522 left());
1523 if (result != NULL) {
1524 return result;
1525 }
1526
1527 return this;
1528 }
1529
1530
1531 Definition* BinaryMintOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
1532 Definition* result = NULL;
1533
1534 result = CanonicalizeCommutativeArithmetic(optimizer,
1535 this,
1536 op_kind(),
1537 kMintCid,
1538 left(),
1539 right());
1540 if (result != NULL) {
1541 return result;
1542 }
1543
1544 result = CanonicalizeCommutativeArithmetic(optimizer,
1545 this,
1546 op_kind(),
1547 kMintCid,
1548 right(),
1549 left());
1550 if (result != NULL) {
1551 return result;
1552 }
1553
1554 return this;
1555 }
1556
1557
1383 RawAbstractType* MathSqrtInstr::CompileType() const { 1558 RawAbstractType* MathSqrtInstr::CompileType() const {
1384 return Type::Double(); 1559 return Type::Double();
1385 } 1560 }
1386 1561
1387 1562
1388 RawAbstractType* UnboxDoubleInstr::CompileType() const { 1563 RawAbstractType* UnboxDoubleInstr::CompileType() const {
1389 return Type::null(); 1564 return Type::null();
1390 } 1565 }
1391 1566
1392 1567
(...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after
2779 default: 2954 default:
2780 UNREACHABLE(); 2955 UNREACHABLE();
2781 return -1; 2956 return -1;
2782 } 2957 }
2783 } 2958 }
2784 2959
2785 2960
2786 #undef __ 2961 #undef __
2787 2962
2788 } // namespace dart 2963 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | tests/language/arithmetic_canonicalization_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698