Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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/globals.h" // Needed here to get TARGET_ARCH_DBC. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC. |
| 6 #if defined(TARGET_ARCH_DBC) | 6 #if defined(TARGET_ARCH_DBC) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 // to be in the subsequent instruction, which it skips if the test fails. | 447 // to be in the subsequent instruction, which it skips if the test fails. |
| 448 __ Jump(labels.true_label); | 448 __ Jump(labels.true_label); |
| 449 if (labels.fall_through != labels.false_label) { | 449 if (labels.fall_through != labels.false_label) { |
| 450 // The preceeding Jump instruction will be skipped if the test fails. | 450 // The preceeding Jump instruction will be skipped if the test fails. |
| 451 // If we aren't falling through to the false case, then we have to do | 451 // If we aren't falling through to the false case, then we have to do |
| 452 // a Jump to it here. | 452 // a Jump to it here. |
| 453 __ Jump(labels.false_label); | 453 __ Jump(labels.false_label); |
| 454 } | 454 } |
| 455 } else { | 455 } else { |
| 456 ASSERT(true_condition == NEXT_IS_FALSE); | 456 ASSERT(true_condition == NEXT_IS_FALSE); |
| 457 // NEXT_IS_FALSE indicates that the preceeing test has been flipped and | 457 // NEXT_IS_FALSE indicates that the preceeding test has been flipped and |
| 458 // expects the false case to be in the subsequent instruction, which it | 458 // expects the false case to be in the subsequent instruction, which it |
| 459 // skips if the test succeeds. | 459 // skips if the test succeeds. |
| 460 __ Jump(labels.false_label); | 460 __ Jump(labels.false_label); |
| 461 if (labels.fall_through != labels.true_label) { | 461 if (labels.fall_through != labels.true_label) { |
| 462 // The preceeding Jump instruction will be skipped if the test succeeds. | 462 // The preceeding Jump instruction will be skipped if the test succeeds. |
| 463 // If we aren't falling through to the true case, then we have to do | 463 // If we aren't falling through to the true case, then we have to do |
| 464 // a Jump to it here. | 464 // a Jump to it here. |
| 465 __ Jump(labels.true_label); | 465 __ Jump(labels.true_label); |
| 466 } | 466 } |
| 467 } | 467 } |
| 468 } | 468 } |
| 469 | 469 |
| 470 | 470 |
| 471 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 471 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 472 BranchLabels labels) { | 472 BranchLabels labels) { |
| 473 ASSERT((kind() == Token::kNE_STRICT) || | 473 ASSERT((kind() == Token::kNE_STRICT) || |
| 474 (kind() == Token::kEQ_STRICT)); | 474 (kind() == Token::kEQ_STRICT)); |
| 475 | 475 |
| 476 Token::Kind comparison; | 476 Token::Kind comparison; |
| 477 Condition condition; | 477 Condition condition; |
| 478 if (labels.fall_through == labels.false_label) { | 478 if (labels.fall_through == labels.false_label) { |
| 479 condition = NEXT_IS_TRUE; | 479 condition = NEXT_IS_TRUE; |
| 480 comparison = kind(); | 480 comparison = kind(); |
| 481 } else { | 481 } else { |
| 482 // Flip comparision to save a jump. | 482 // Flip comparison to save a jump. |
| 483 condition = NEXT_IS_FALSE; | 483 condition = NEXT_IS_FALSE; |
| 484 comparison = (kind() == Token::kEQ_STRICT) ? Token::kNE_STRICT | 484 comparison = (kind() == Token::kEQ_STRICT) ? Token::kNE_STRICT |
| 485 : Token::kEQ_STRICT; | 485 : Token::kEQ_STRICT; |
| 486 } | 486 } |
| 487 | 487 |
| 488 if (!compiler->is_optimizing()) { | 488 if (!compiler->is_optimizing()) { |
| 489 const Bytecode::Opcode eq_op = needs_number_check() ? | 489 const Bytecode::Opcode eq_op = needs_number_check() ? |
| 490 Bytecode::kIfEqStrictNumTOS : Bytecode::kIfEqStrictTOS; | 490 Bytecode::kIfEqStrictNumTOS : Bytecode::kIfEqStrictTOS; |
| 491 const Bytecode::Opcode ne_op = needs_number_check() ? | 491 const Bytecode::Opcode ne_op = needs_number_check() ? |
| 492 Bytecode::kIfNeStrictNumTOS : Bytecode::kIfNeStrictTOS; | 492 Bytecode::kIfNeStrictNumTOS : Bytecode::kIfNeStrictTOS; |
| (...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1781 } | 1781 } |
| 1782 | 1782 |
| 1783 | 1783 |
| 1784 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler, | 1784 static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler, |
| 1785 LocationSummary* locs, | 1785 LocationSummary* locs, |
| 1786 Token::Kind kind, | 1786 Token::Kind kind, |
| 1787 BranchLabels labels) { | 1787 BranchLabels labels) { |
| 1788 const Register left = locs->in(0).reg(); | 1788 const Register left = locs->in(0).reg(); |
| 1789 const Register right = locs->in(1).reg(); | 1789 const Register right = locs->in(1).reg(); |
| 1790 Token::Kind comparison = kind; | 1790 Token::Kind comparison = kind; |
| 1791 // For double comparisons we can't flip the condition like with smi | |
|
zra
2016/10/07 02:14:43
Can we flip for all but == and/or != ?
Florian Schneider
2016/10/07 16:49:33
As discussed offline, we could do inline assembly
| |
| 1792 // comparisons because of NaN which will compare false for all except != | |
| 1793 // operations. | |
| 1794 // TODO(fschneider): Change the block order instead in DBC so that the | |
| 1795 // false block in always the fall-through block. | |
| 1791 Condition condition = NEXT_IS_TRUE; | 1796 Condition condition = NEXT_IS_TRUE; |
| 1792 if (labels.fall_through != labels.false_label) { | |
| 1793 // If we aren't falling through to the false label, we can save a Jump | |
| 1794 // instruction in the case that the true case is the fall through by | |
| 1795 // flipping the sense of the test such that the instruction following the | |
| 1796 // test is the Jump to the false label. | |
| 1797 condition = NEXT_IS_FALSE; | |
| 1798 comparison = FlipCondition(kind); | |
| 1799 } | |
| 1800 __ Emit(Bytecode::Encode(OpcodeForDoubleCondition(comparison), left, right)); | 1797 __ Emit(Bytecode::Encode(OpcodeForDoubleCondition(comparison), left, right)); |
| 1801 return condition; | 1798 return condition; |
| 1802 } | 1799 } |
| 1803 | 1800 |
| 1804 | 1801 |
| 1805 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, | 1802 Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
| 1806 BranchLabels labels) { | 1803 BranchLabels labels) { |
| 1807 if (operation_cid() == kSmiCid) { | 1804 if (operation_cid() == kSmiCid) { |
| 1808 return EmitSmiComparisonOp(compiler, locs(), kind(), labels); | 1805 return EmitSmiComparisonOp(compiler, locs(), kind(), labels); |
| 1809 } else { | 1806 } else { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1883 __ IfULe(length, index); | 1880 __ IfULe(length, index); |
| 1884 compiler->EmitDeopt(deopt_id(), | 1881 compiler->EmitDeopt(deopt_id(), |
| 1885 ICData::kDeoptCheckArrayBound, | 1882 ICData::kDeoptCheckArrayBound, |
| 1886 (generalized_ ? ICData::kGeneralized : 0) | | 1883 (generalized_ ? ICData::kGeneralized : 0) | |
| 1887 (licm_hoisted_ ? ICData::kHoisted : 0)); | 1884 (licm_hoisted_ ? ICData::kHoisted : 0)); |
| 1888 } | 1885 } |
| 1889 | 1886 |
| 1890 } // namespace dart | 1887 } // namespace dart |
| 1891 | 1888 |
| 1892 #endif // defined TARGET_ARCH_DBC | 1889 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |