| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |