| 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 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) { | 1383 static bool ToIntegerConstant(Value* value, intptr_t* result) { |
| 1384 if (!value->BindsToConstant()) { | 1384 if (!value->BindsToConstant()) { |
| 1385 if (value->definition()->IsUnboxDouble()) { |
| 1386 return ToIntegerConstant(value->definition()->AsUnboxDouble()->value(), |
| 1387 result); |
| 1388 } |
| 1389 |
| 1385 return false; | 1390 return false; |
| 1386 } | 1391 } |
| 1387 | 1392 |
| 1388 const Object& constant = value->BoundConstant(); | 1393 const Object& constant = value->BoundConstant(); |
| 1389 if (constant.IsDouble()) { | 1394 if (constant.IsDouble()) { |
| 1390 const Double& double_constant = Double::Cast(constant); | 1395 const Double& double_constant = Double::Cast(constant); |
| 1391 *result = static_cast<intptr_t>(double_constant.value()); | 1396 *result = static_cast<intptr_t>(double_constant.value()); |
| 1392 return (static_cast<double>(*result) == double_constant.value()); | 1397 return (static_cast<double>(*result) == double_constant.value()); |
| 1393 } else if (constant.IsSmi()) { | 1398 } else if (constant.IsSmi()) { |
| 1394 *result = Smi::Cast(constant).Value(); | 1399 *result = Smi::Cast(constant).Value(); |
| 1395 return true; | 1400 return true; |
| 1396 } | 1401 } |
| 1397 | 1402 |
| 1398 return false; | 1403 return false; |
| 1399 } | 1404 } |
| 1400 | 1405 |
| 1401 | 1406 |
| 1402 static Definition* CanonicalizeCommutativeArithmetic( | 1407 static Definition* CanonicalizeCommutativeArithmetic(Token::Kind op, |
| 1403 FlowGraphOptimizer* optimizer, | 1408 intptr_t cid, |
| 1404 Definition* defn, | 1409 Value* left, |
| 1405 Token::Kind op, | 1410 Value* right) { |
| 1406 intptr_t cid, | |
| 1407 Value* left, | |
| 1408 Value* right) { | |
| 1409 ASSERT((cid == kSmiCid) || (cid == kDoubleCid) || (cid == kMintCid)); | 1411 ASSERT((cid == kSmiCid) || (cid == kDoubleCid) || (cid == kMintCid)); |
| 1410 | 1412 |
| 1411 intptr_t left_value; | 1413 intptr_t left_value; |
| 1412 if (!ToIntegerConstant(left, &left_value)) { | 1414 if (!ToIntegerConstant(left, &left_value)) { |
| 1413 return NULL; | 1415 return NULL; |
| 1414 } | 1416 } |
| 1415 | 1417 |
| 1416 switch (op) { | 1418 switch (op) { |
| 1417 case Token::kMUL: | 1419 case Token::kMUL: |
| 1418 if (left_value == 1) { | 1420 if (left_value == 1) { |
| 1419 if ((cid == kDoubleCid) && | 1421 if ((cid == kDoubleCid) && |
| 1420 (right->definition()->representation() != kUnboxedDouble)) { | 1422 (right->definition()->representation() != kUnboxedDouble)) { |
| 1421 // Ensure that the result of the operation (right value) is coerced | 1423 // Can't yet apply the equivalence because representation selection |
| 1422 // to double. | 1424 // did not run yet. We need it to guarantee that right value is |
| 1423 UnboxDoubleInstr* unbox = | 1425 // correctly coerced to double. The second canonicalization pass |
| 1424 new UnboxDoubleInstr(right->Copy(), | 1426 // will apply this equivalence. |
| 1425 defn->DeoptimizationTarget()); | 1427 return NULL; |
| 1426 optimizer->InsertBefore(defn, | |
| 1427 unbox, | |
| 1428 defn->env(), | |
| 1429 Definition::kValue); | |
| 1430 return unbox; | |
| 1431 } else { | 1428 } else { |
| 1432 return right->definition(); | 1429 return right->definition(); |
| 1433 } | 1430 } |
| 1434 } else if ((left_value == 0) && (cid != kDoubleCid)) { | 1431 } else if ((left_value == 0) && (cid != kDoubleCid)) { |
| 1435 // Can't apply this equivalence to double operation because | 1432 // Can't apply this equivalence to double operation because |
| 1436 // 0.0 * NaN is NaN not 0.0. | 1433 // 0.0 * NaN is NaN not 0.0. |
| 1437 return left->definition(); | 1434 return left->definition(); |
| 1438 } | 1435 } |
| 1439 break; | 1436 break; |
| 1440 case Token::kADD: | 1437 case Token::kADD: |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1470 break; | 1467 break; |
| 1471 } | 1468 } |
| 1472 | 1469 |
| 1473 return NULL; | 1470 return NULL; |
| 1474 } | 1471 } |
| 1475 | 1472 |
| 1476 | 1473 |
| 1477 Definition* BinaryDoubleOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) { | 1474 Definition* BinaryDoubleOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| 1478 Definition* result = NULL; | 1475 Definition* result = NULL; |
| 1479 | 1476 |
| 1480 result = CanonicalizeCommutativeArithmetic(optimizer, | 1477 result = CanonicalizeCommutativeArithmetic(op_kind(), |
| 1481 this, | |
| 1482 op_kind(), | |
| 1483 kDoubleCid, | 1478 kDoubleCid, |
| 1484 left(), | 1479 left(), |
| 1485 right()); | 1480 right()); |
| 1486 if (result != NULL) { | 1481 if (result != NULL) { |
| 1487 return result; | 1482 return result; |
| 1488 } | 1483 } |
| 1489 | 1484 |
| 1490 result = CanonicalizeCommutativeArithmetic(optimizer, | 1485 result = CanonicalizeCommutativeArithmetic(op_kind(), |
| 1491 this, | |
| 1492 op_kind(), | |
| 1493 kDoubleCid, | 1486 kDoubleCid, |
| 1494 right(), | 1487 right(), |
| 1495 left()); | 1488 left()); |
| 1496 if (result != NULL) { | 1489 if (result != NULL) { |
| 1497 return result; | 1490 return result; |
| 1498 } | 1491 } |
| 1499 | 1492 |
| 1500 return this; | 1493 return this; |
| 1501 } | 1494 } |
| 1502 | 1495 |
| 1503 | 1496 |
| 1504 Definition* BinarySmiOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) { | 1497 Definition* BinarySmiOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| 1505 Definition* result = NULL; | 1498 Definition* result = NULL; |
| 1506 | 1499 |
| 1507 result = CanonicalizeCommutativeArithmetic(optimizer, | 1500 result = CanonicalizeCommutativeArithmetic(op_kind(), |
| 1508 this, | |
| 1509 op_kind(), | |
| 1510 kSmiCid, | 1501 kSmiCid, |
| 1511 left(), | 1502 left(), |
| 1512 right()); | 1503 right()); |
| 1513 if (result != NULL) { | 1504 if (result != NULL) { |
| 1514 return result; | 1505 return result; |
| 1515 } | 1506 } |
| 1516 | 1507 |
| 1517 result = CanonicalizeCommutativeArithmetic(optimizer, | 1508 result = CanonicalizeCommutativeArithmetic(op_kind(), |
| 1518 this, | |
| 1519 op_kind(), | |
| 1520 kSmiCid, | 1509 kSmiCid, |
| 1521 right(), | 1510 right(), |
| 1522 left()); | 1511 left()); |
| 1523 if (result != NULL) { | 1512 if (result != NULL) { |
| 1524 return result; | 1513 return result; |
| 1525 } | 1514 } |
| 1526 | 1515 |
| 1527 return this; | 1516 return this; |
| 1528 } | 1517 } |
| 1529 | 1518 |
| 1530 | 1519 |
| 1531 Definition* BinaryMintOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) { | 1520 Definition* BinaryMintOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| 1532 Definition* result = NULL; | 1521 Definition* result = NULL; |
| 1533 | 1522 |
| 1534 result = CanonicalizeCommutativeArithmetic(optimizer, | 1523 result = CanonicalizeCommutativeArithmetic(op_kind(), |
| 1535 this, | |
| 1536 op_kind(), | |
| 1537 kMintCid, | 1524 kMintCid, |
| 1538 left(), | 1525 left(), |
| 1539 right()); | 1526 right()); |
| 1540 if (result != NULL) { | 1527 if (result != NULL) { |
| 1541 return result; | 1528 return result; |
| 1542 } | 1529 } |
| 1543 | 1530 |
| 1544 result = CanonicalizeCommutativeArithmetic(optimizer, | 1531 result = CanonicalizeCommutativeArithmetic(op_kind(), |
| 1545 this, | |
| 1546 op_kind(), | |
| 1547 kMintCid, | 1532 kMintCid, |
| 1548 right(), | 1533 right(), |
| 1549 left()); | 1534 left()); |
| 1550 if (result != NULL) { | 1535 if (result != NULL) { |
| 1551 return result; | 1536 return result; |
| 1552 } | 1537 } |
| 1553 | 1538 |
| 1554 return this; | 1539 return this; |
| 1555 } | 1540 } |
| 1556 | 1541 |
| (...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2954 default: | 2939 default: |
| 2955 UNREACHABLE(); | 2940 UNREACHABLE(); |
| 2956 return -1; | 2941 return -1; |
| 2957 } | 2942 } |
| 2958 } | 2943 } |
| 2959 | 2944 |
| 2960 | 2945 |
| 2961 #undef __ | 2946 #undef __ |
| 2962 | 2947 |
| 2963 } // namespace dart | 2948 } // namespace dart |
| OLD | NEW |