| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/branch_optimizer.h" | 8 #include "vm/branch_optimizer.h" |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 DEFINE_FLAG(bool, truncating_left_shift, true, | 42 DEFINE_FLAG(bool, truncating_left_shift, true, |
| 43 "Optimize left shift to truncate if possible"); | 43 "Optimize left shift to truncate if possible"); |
| 44 DEFINE_FLAG(bool, use_cha_deopt, true, | 44 DEFINE_FLAG(bool, use_cha_deopt, true, |
| 45 "Use class hierarchy analysis even if it can cause deoptimization."); | 45 "Use class hierarchy analysis even if it can cause deoptimization."); |
| 46 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32) | 46 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32) |
| 47 DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass."); | 47 DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass."); |
| 48 #endif | 48 #endif |
| 49 | 49 |
| 50 DECLARE_FLAG(bool, precompilation); | 50 DECLARE_FLAG(bool, precompilation); |
| 51 DECLARE_FLAG(bool, polymorphic_with_deopt); | 51 DECLARE_FLAG(bool, polymorphic_with_deopt); |
| 52 DECLARE_FLAG(bool, source_lines); | |
| 53 DECLARE_FLAG(bool, trace_cha); | 52 DECLARE_FLAG(bool, trace_cha); |
| 54 DECLARE_FLAG(bool, trace_field_guards); | 53 DECLARE_FLAG(bool, trace_field_guards); |
| 55 DECLARE_FLAG(bool, trace_type_check_elimination); | |
| 56 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 54 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 57 | 55 |
| 58 // Quick access to the current isolate and zone. | 56 // Quick access to the current isolate and zone. |
| 59 #define I (isolate()) | 57 #define I (isolate()) |
| 60 #define Z (zone()) | 58 #define Z (zone()) |
| 61 | 59 |
| 62 static bool ShouldInlineSimd() { | 60 static bool ShouldInlineSimd() { |
| 63 return FlowGraphCompiler::SupportsUnboxedSimd128(); | 61 return FlowGraphCompiler::SupportsUnboxedSimd128(); |
| 64 } | 62 } |
| 65 | 63 |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 BinarySmiOpInstr* smi_op = new(Z) BinarySmiOpInstr( | 409 BinarySmiOpInstr* smi_op = new(Z) BinarySmiOpInstr( |
| 412 Token::kBIT_AND, | 410 Token::kBIT_AND, |
| 413 new(Z) Value(left_instr), | 411 new(Z) Value(left_instr), |
| 414 new(Z) Value(right_instr), | 412 new(Z) Value(right_instr), |
| 415 Thread::kNoDeoptId); // BIT_AND cannot deoptimize. | 413 Thread::kNoDeoptId); // BIT_AND cannot deoptimize. |
| 416 bit_and_instr->ReplaceWith(smi_op, current_iterator()); | 414 bit_and_instr->ReplaceWith(smi_op, current_iterator()); |
| 417 } | 415 } |
| 418 } | 416 } |
| 419 | 417 |
| 420 | 418 |
| 421 | |
| 422 // Used by TryMergeDivMod. | |
| 423 // Inserts a load-indexed instruction between a TRUNCDIV or MOD instruction, | |
| 424 // and the using instruction. This is an intermediate step before merging. | |
| 425 void FlowGraphOptimizer::AppendLoadIndexedForMerged(Definition* instr, | |
| 426 intptr_t ix, | |
| 427 intptr_t cid) { | |
| 428 const intptr_t index_scale = Instance::ElementSizeFor(cid); | |
| 429 ConstantInstr* index_instr = | |
| 430 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(ix))); | |
| 431 LoadIndexedInstr* load = | |
| 432 new(Z) LoadIndexedInstr(new(Z) Value(instr), | |
| 433 new(Z) Value(index_instr), | |
| 434 index_scale, | |
| 435 cid, | |
| 436 Thread::kNoDeoptId, | |
| 437 instr->token_pos()); | |
| 438 instr->ReplaceUsesWith(load); | |
| 439 flow_graph()->InsertAfter(instr, load, NULL, FlowGraph::kValue); | |
| 440 } | |
| 441 | |
| 442 | |
| 443 void FlowGraphOptimizer::AppendExtractNthOutputForMerged(Definition* instr, | 419 void FlowGraphOptimizer::AppendExtractNthOutputForMerged(Definition* instr, |
| 444 intptr_t index, | 420 intptr_t index, |
| 445 Representation rep, | 421 Representation rep, |
| 446 intptr_t cid) { | 422 intptr_t cid) { |
| 447 ExtractNthOutputInstr* extract = | 423 ExtractNthOutputInstr* extract = |
| 448 new(Z) ExtractNthOutputInstr(new(Z) Value(instr), index, rep, cid); | 424 new(Z) ExtractNthOutputInstr(new(Z) Value(instr), index, rep, cid); |
| 449 instr->ReplaceUsesWith(extract); | 425 instr->ReplaceUsesWith(extract); |
| 450 flow_graph()->InsertAfter(instr, extract, NULL, FlowGraph::kValue); | 426 flow_graph()->InsertAfter(instr, extract, NULL, FlowGraph::kValue); |
| 451 } | 427 } |
| 452 | 428 |
| (...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1507 case MethodRecognizer::kFloat64x2ArraySetIndexed: | 1483 case MethodRecognizer::kFloat64x2ArraySetIndexed: |
| 1508 if (!ShouldInlineSimd()) { | 1484 if (!ShouldInlineSimd()) { |
| 1509 return false; | 1485 return false; |
| 1510 } | 1486 } |
| 1511 value_check = ic_data.AsUnaryClassChecksForCid(kFloat64x2Cid, target); | 1487 value_check = ic_data.AsUnaryClassChecksForCid(kFloat64x2Cid, target); |
| 1512 return InlineSetIndexed(kind, target, call, receiver, token_pos, | 1488 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
| 1513 value_check, entry, last); | 1489 value_check, entry, last); |
| 1514 case MethodRecognizer::kByteArrayBaseGetInt8: | 1490 case MethodRecognizer::kByteArrayBaseGetInt8: |
| 1515 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1491 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1516 kTypedDataInt8ArrayCid, | 1492 kTypedDataInt8ArrayCid, |
| 1517 ic_data, entry, last); | 1493 entry, last); |
| 1518 case MethodRecognizer::kByteArrayBaseGetUint8: | 1494 case MethodRecognizer::kByteArrayBaseGetUint8: |
| 1519 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1495 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1520 kTypedDataUint8ArrayCid, | 1496 kTypedDataUint8ArrayCid, |
| 1521 ic_data, entry, last); | 1497 entry, last); |
| 1522 case MethodRecognizer::kByteArrayBaseGetInt16: | 1498 case MethodRecognizer::kByteArrayBaseGetInt16: |
| 1523 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1499 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1524 kTypedDataInt16ArrayCid, | 1500 kTypedDataInt16ArrayCid, |
| 1525 ic_data, entry, last); | 1501 entry, last); |
| 1526 case MethodRecognizer::kByteArrayBaseGetUint16: | 1502 case MethodRecognizer::kByteArrayBaseGetUint16: |
| 1527 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1503 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1528 kTypedDataUint16ArrayCid, | 1504 kTypedDataUint16ArrayCid, |
| 1529 ic_data, entry, last); | 1505 entry, last); |
| 1530 case MethodRecognizer::kByteArrayBaseGetInt32: | 1506 case MethodRecognizer::kByteArrayBaseGetInt32: |
| 1531 if (!CanUnboxInt32()) { | 1507 if (!CanUnboxInt32()) { |
| 1532 return false; | 1508 return false; |
| 1533 } | 1509 } |
| 1534 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1510 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1535 kTypedDataInt32ArrayCid, | 1511 kTypedDataInt32ArrayCid, |
| 1536 ic_data, entry, last); | 1512 entry, last); |
| 1537 case MethodRecognizer::kByteArrayBaseGetUint32: | 1513 case MethodRecognizer::kByteArrayBaseGetUint32: |
| 1538 if (!CanUnboxInt32()) { | 1514 if (!CanUnboxInt32()) { |
| 1539 return false; | 1515 return false; |
| 1540 } | 1516 } |
| 1541 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1517 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1542 kTypedDataUint32ArrayCid, | 1518 kTypedDataUint32ArrayCid, |
| 1543 ic_data, entry, last); | 1519 entry, last); |
| 1544 case MethodRecognizer::kByteArrayBaseGetFloat32: | 1520 case MethodRecognizer::kByteArrayBaseGetFloat32: |
| 1545 if (!CanUnboxDouble()) { | 1521 if (!CanUnboxDouble()) { |
| 1546 return false; | 1522 return false; |
| 1547 } | 1523 } |
| 1548 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1524 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1549 kTypedDataFloat32ArrayCid, | 1525 kTypedDataFloat32ArrayCid, |
| 1550 ic_data, entry, last); | 1526 entry, last); |
| 1551 case MethodRecognizer::kByteArrayBaseGetFloat64: | 1527 case MethodRecognizer::kByteArrayBaseGetFloat64: |
| 1552 if (!CanUnboxDouble()) { | 1528 if (!CanUnboxDouble()) { |
| 1553 return false; | 1529 return false; |
| 1554 } | 1530 } |
| 1555 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1531 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1556 kTypedDataFloat64ArrayCid, | 1532 kTypedDataFloat64ArrayCid, |
| 1557 ic_data, entry, last); | 1533 entry, last); |
| 1558 case MethodRecognizer::kByteArrayBaseGetFloat32x4: | 1534 case MethodRecognizer::kByteArrayBaseGetFloat32x4: |
| 1559 if (!ShouldInlineSimd()) { | 1535 if (!ShouldInlineSimd()) { |
| 1560 return false; | 1536 return false; |
| 1561 } | 1537 } |
| 1562 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1538 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1563 kTypedDataFloat32x4ArrayCid, | 1539 kTypedDataFloat32x4ArrayCid, |
| 1564 ic_data, entry, last); | 1540 entry, last); |
| 1565 case MethodRecognizer::kByteArrayBaseGetInt32x4: | 1541 case MethodRecognizer::kByteArrayBaseGetInt32x4: |
| 1566 if (!ShouldInlineSimd()) { | 1542 if (!ShouldInlineSimd()) { |
| 1567 return false; | 1543 return false; |
| 1568 } | 1544 } |
| 1569 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, | 1545 return InlineByteArrayBaseLoad(call, receiver, receiver_cid, |
| 1570 kTypedDataInt32x4ArrayCid, | 1546 kTypedDataInt32x4ArrayCid, |
| 1571 ic_data, entry, last); | 1547 entry, last); |
| 1572 case MethodRecognizer::kByteArrayBaseSetInt8: | 1548 case MethodRecognizer::kByteArrayBaseSetInt8: |
| 1573 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1549 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1574 kTypedDataInt8ArrayCid, | 1550 kTypedDataInt8ArrayCid, |
| 1575 ic_data, entry, last); | 1551 entry, last); |
| 1576 case MethodRecognizer::kByteArrayBaseSetUint8: | 1552 case MethodRecognizer::kByteArrayBaseSetUint8: |
| 1577 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1553 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1578 kTypedDataUint8ArrayCid, | 1554 kTypedDataUint8ArrayCid, |
| 1579 ic_data, entry, last); | 1555 entry, last); |
| 1580 case MethodRecognizer::kByteArrayBaseSetInt16: | 1556 case MethodRecognizer::kByteArrayBaseSetInt16: |
| 1581 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1557 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1582 kTypedDataInt16ArrayCid, | 1558 kTypedDataInt16ArrayCid, |
| 1583 ic_data, entry, last); | 1559 entry, last); |
| 1584 case MethodRecognizer::kByteArrayBaseSetUint16: | 1560 case MethodRecognizer::kByteArrayBaseSetUint16: |
| 1585 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1561 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1586 kTypedDataUint16ArrayCid, | 1562 kTypedDataUint16ArrayCid, |
| 1587 ic_data, entry, last); | 1563 entry, last); |
| 1588 case MethodRecognizer::kByteArrayBaseSetInt32: | 1564 case MethodRecognizer::kByteArrayBaseSetInt32: |
| 1589 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1565 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1590 kTypedDataInt32ArrayCid, | 1566 kTypedDataInt32ArrayCid, |
| 1591 ic_data, entry, last); | 1567 entry, last); |
| 1592 case MethodRecognizer::kByteArrayBaseSetUint32: | 1568 case MethodRecognizer::kByteArrayBaseSetUint32: |
| 1593 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1569 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1594 kTypedDataUint32ArrayCid, | 1570 kTypedDataUint32ArrayCid, |
| 1595 ic_data, entry, last); | 1571 entry, last); |
| 1596 case MethodRecognizer::kByteArrayBaseSetFloat32: | 1572 case MethodRecognizer::kByteArrayBaseSetFloat32: |
| 1597 if (!CanUnboxDouble()) { | 1573 if (!CanUnboxDouble()) { |
| 1598 return false; | 1574 return false; |
| 1599 } | 1575 } |
| 1600 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1576 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1601 kTypedDataFloat32ArrayCid, | 1577 kTypedDataFloat32ArrayCid, |
| 1602 ic_data, entry, last); | 1578 entry, last); |
| 1603 case MethodRecognizer::kByteArrayBaseSetFloat64: | 1579 case MethodRecognizer::kByteArrayBaseSetFloat64: |
| 1604 if (!CanUnboxDouble()) { | 1580 if (!CanUnboxDouble()) { |
| 1605 return false; | 1581 return false; |
| 1606 } | 1582 } |
| 1607 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1583 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1608 kTypedDataFloat64ArrayCid, | 1584 kTypedDataFloat64ArrayCid, |
| 1609 ic_data, entry, last); | 1585 entry, last); |
| 1610 case MethodRecognizer::kByteArrayBaseSetFloat32x4: | 1586 case MethodRecognizer::kByteArrayBaseSetFloat32x4: |
| 1611 if (!ShouldInlineSimd()) { | 1587 if (!ShouldInlineSimd()) { |
| 1612 return false; | 1588 return false; |
| 1613 } | 1589 } |
| 1614 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1590 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1615 kTypedDataFloat32x4ArrayCid, | 1591 kTypedDataFloat32x4ArrayCid, |
| 1616 ic_data, entry, last); | 1592 entry, last); |
| 1617 case MethodRecognizer::kByteArrayBaseSetInt32x4: | 1593 case MethodRecognizer::kByteArrayBaseSetInt32x4: |
| 1618 if (!ShouldInlineSimd()) { | 1594 if (!ShouldInlineSimd()) { |
| 1619 return false; | 1595 return false; |
| 1620 } | 1596 } |
| 1621 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, | 1597 return InlineByteArrayBaseStore(target, call, receiver, receiver_cid, |
| 1622 kTypedDataInt32x4ArrayCid, | 1598 kTypedDataInt32x4ArrayCid, |
| 1623 ic_data, entry, last); | 1599 entry, last); |
| 1624 case MethodRecognizer::kStringBaseCodeUnitAt: | 1600 case MethodRecognizer::kStringBaseCodeUnitAt: |
| 1625 return InlineStringCodeUnitAt(call, receiver_cid, entry, last); | 1601 return InlineStringCodeUnitAt(call, receiver_cid, entry, last); |
| 1626 case MethodRecognizer::kStringBaseCharAt: | 1602 case MethodRecognizer::kStringBaseCharAt: |
| 1627 return InlineStringBaseCharAt(call, receiver_cid, entry, last); | 1603 return InlineStringBaseCharAt(call, receiver_cid, entry, last); |
| 1628 case MethodRecognizer::kDoubleAdd: | 1604 case MethodRecognizer::kDoubleAdd: |
| 1629 return InlineDoubleOp(Token::kADD, call, entry, last); | 1605 return InlineDoubleOp(Token::kADD, call, entry, last); |
| 1630 case MethodRecognizer::kDoubleSub: | 1606 case MethodRecognizer::kDoubleSub: |
| 1631 return InlineDoubleOp(Token::kSUB, call, entry, last); | 1607 return InlineDoubleOp(Token::kSUB, call, entry, last); |
| 1632 case MethodRecognizer::kDoubleMul: | 1608 case MethodRecognizer::kDoubleMul: |
| 1633 return InlineDoubleOp(Token::kMUL, call, entry, last); | 1609 return InlineDoubleOp(Token::kMUL, call, entry, last); |
| (...skipping 1908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3542 default: | 3518 default: |
| 3543 return false; | 3519 return false; |
| 3544 } | 3520 } |
| 3545 } | 3521 } |
| 3546 | 3522 |
| 3547 | 3523 |
| 3548 bool FlowGraphOptimizer::InlineByteArrayBaseLoad(Instruction* call, | 3524 bool FlowGraphOptimizer::InlineByteArrayBaseLoad(Instruction* call, |
| 3549 Definition* receiver, | 3525 Definition* receiver, |
| 3550 intptr_t array_cid, | 3526 intptr_t array_cid, |
| 3551 intptr_t view_cid, | 3527 intptr_t view_cid, |
| 3552 const ICData& ic_data, | |
| 3553 TargetEntryInstr** entry, | 3528 TargetEntryInstr** entry, |
| 3554 Definition** last) { | 3529 Definition** last) { |
| 3555 ASSERT(array_cid != kIllegalCid); | 3530 ASSERT(array_cid != kIllegalCid); |
| 3556 Definition* array = receiver; | 3531 Definition* array = receiver; |
| 3557 Definition* index = call->ArgumentAt(1); | 3532 Definition* index = call->ArgumentAt(1); |
| 3558 *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(), | 3533 *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(), |
| 3559 call->GetBlock()->try_index()); | 3534 call->GetBlock()->try_index()); |
| 3560 (*entry)->InheritDeoptTarget(Z, call); | 3535 (*entry)->InheritDeoptTarget(Z, call); |
| 3561 Instruction* cursor = *entry; | 3536 Instruction* cursor = *entry; |
| 3562 | 3537 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3595 } | 3570 } |
| 3596 return true; | 3571 return true; |
| 3597 } | 3572 } |
| 3598 | 3573 |
| 3599 | 3574 |
| 3600 bool FlowGraphOptimizer::InlineByteArrayBaseStore(const Function& target, | 3575 bool FlowGraphOptimizer::InlineByteArrayBaseStore(const Function& target, |
| 3601 Instruction* call, | 3576 Instruction* call, |
| 3602 Definition* receiver, | 3577 Definition* receiver, |
| 3603 intptr_t array_cid, | 3578 intptr_t array_cid, |
| 3604 intptr_t view_cid, | 3579 intptr_t view_cid, |
| 3605 const ICData& ic_data, | |
| 3606 TargetEntryInstr** entry, | 3580 TargetEntryInstr** entry, |
| 3607 Definition** last) { | 3581 Definition** last) { |
| 3608 ASSERT(array_cid != kIllegalCid); | 3582 ASSERT(array_cid != kIllegalCid); |
| 3609 Definition* array = receiver; | 3583 Definition* array = receiver; |
| 3610 Definition* index = call->ArgumentAt(1); | 3584 Definition* index = call->ArgumentAt(1); |
| 3611 *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(), | 3585 *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(), |
| 3612 call->GetBlock()->try_index()); | 3586 call->GetBlock()->try_index()); |
| 3613 (*entry)->InheritDeoptTarget(Z, call); | 3587 (*entry)->InheritDeoptTarget(Z, call); |
| 3614 Instruction* cursor = *entry; | 3588 Instruction* cursor = *entry; |
| 3615 | 3589 |
| (...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5025 } | 4999 } |
| 5026 #else | 5000 #else |
| 5027 void FlowGraphOptimizer::WidenSmiToInt32() { | 5001 void FlowGraphOptimizer::WidenSmiToInt32() { |
| 5028 // TODO(vegorov) ideally on 64-bit platforms we would like to narrow smi | 5002 // TODO(vegorov) ideally on 64-bit platforms we would like to narrow smi |
| 5029 // operations to 32-bit where it saves tagging and untagging and allows | 5003 // operations to 32-bit where it saves tagging and untagging and allows |
| 5030 // to use shorted (and faster) instructions. But we currently don't | 5004 // to use shorted (and faster) instructions. But we currently don't |
| 5031 // save enough range information in the ICData to drive this decision. | 5005 // save enough range information in the ICData to drive this decision. |
| 5032 } | 5006 } |
| 5033 #endif | 5007 #endif |
| 5034 | 5008 |
| 5035 void FlowGraphOptimizer::InferIntRanges() { | |
| 5036 RangeAnalysis range_analysis(flow_graph_); | |
| 5037 range_analysis.Analyze(); | |
| 5038 } | |
| 5039 | |
| 5040 | 5009 |
| 5041 void FlowGraphOptimizer::EliminateEnvironments() { | 5010 void FlowGraphOptimizer::EliminateEnvironments() { |
| 5042 // After this pass we can no longer perform LICM and hoist instructions | 5011 // After this pass we can no longer perform LICM and hoist instructions |
| 5043 // that can deoptimize. | 5012 // that can deoptimize. |
| 5044 | 5013 |
| 5045 flow_graph_->disallow_licm(); | 5014 flow_graph_->disallow_licm(); |
| 5046 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 5015 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 5047 BlockEntryInstr* block = block_order_[i]; | 5016 BlockEntryInstr* block = block_order_[i]; |
| 5048 block->RemoveEnvironment(); | 5017 block->RemoveEnvironment(); |
| 5049 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 5018 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 5050 Instruction* current = it.Current(); | 5019 Instruction* current = it.Current(); |
| 5051 if (!current->CanDeoptimize()) { | 5020 if (!current->CanDeoptimize()) { |
| 5052 // TODO(srdjan): --source-lines needs deopt environments to get at | 5021 // TODO(srdjan): --source-lines needs deopt environments to get at |
| 5053 // the code for this instruction, however, leaving the environment | 5022 // the code for this instruction, however, leaving the environment |
| 5054 // changes code. | 5023 // changes code. |
| 5055 current->RemoveEnvironment(); | 5024 current->RemoveEnvironment(); |
| 5056 } | 5025 } |
| 5057 } | 5026 } |
| 5058 } | 5027 } |
| 5059 } | 5028 } |
| 5060 | 5029 |
| 5061 | 5030 |
| 5062 } // namespace dart | 5031 } // namespace dart |
| OLD | NEW |