Chromium Code Reviews| 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/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/flow_graph_compiler.h" | 9 #include "vm/flow_graph_compiler.h" |
| 10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 733 ASSERT(stack_trace()->IsUse()); | 733 ASSERT(stack_trace()->IsUse()); |
| 734 compiler->GenerateCallRuntime(cid(), | 734 compiler->GenerateCallRuntime(cid(), |
| 735 token_index(), | 735 token_index(), |
| 736 try_index(), | 736 try_index(), |
| 737 kReThrowRuntimeEntry); | 737 kReThrowRuntimeEntry); |
| 738 __ int3(); | 738 __ int3(); |
| 739 } | 739 } |
| 740 | 740 |
| 741 | 741 |
| 742 LocationSummary* BranchInstr::MakeLocationSummary() const { | 742 LocationSummary* BranchInstr::MakeLocationSummary() const { |
| 743 const int kNumInputs = 1; | 743 if (is_fused_with_comparison()) { |
|
srdjan
2012/06/13 15:29:35
Add comment: no code needs to be emitted.
Vyacheslav Egorov (Google)
2012/06/13 16:23:43
Done.
| |
| 744 const int kNumTemps = 0; | 744 return LocationSummary::Make(0, Location::NoLocation()); |
| 745 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 745 } else { |
| 746 locs->set_in(0, Location::RequiresRegister()); | 746 const int kNumInputs = 1; |
| 747 return locs; | 747 const int kNumTemps = 0; |
| 748 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | |
| 749 locs->set_in(0, Location::RequiresRegister()); | |
| 750 return locs; | |
| 751 } | |
| 748 } | 752 } |
| 749 | 753 |
| 750 | 754 |
| 751 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 755 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 752 Register value = locs()->in(0).reg(); | 756 if (!is_fused_with_comparison()) { |
| 753 __ CompareObject(value, Bool::ZoneHandle(Bool::True())); | 757 Register value = locs()->in(0).reg(); |
| 754 if (compiler->IsNextBlock(false_successor())) { | 758 __ CompareObject(value, compiler->true_value()); |
| 755 // If the next block is the false successor we will fall through to it if | 759 EmitBranchOnCondition(compiler, EQUAL); |
| 756 // comparison with true fails. | |
| 757 __ j(EQUAL, compiler->GetBlockLabel(true_successor())); | |
| 758 } else { | |
| 759 ASSERT(compiler->IsNextBlock(true_successor())); | |
| 760 // If the next block is the true successor we negate comparison and fall | |
| 761 // through to it. | |
| 762 __ j(NOT_EQUAL, compiler->GetBlockLabel(false_successor())); | |
| 763 } | 760 } |
| 764 } | 761 } |
| 765 | 762 |
| 763 | |
| 764 static Condition NegateCondition(Condition condition) { | |
| 765 switch (condition) { | |
| 766 case EQUAL: return NOT_EQUAL; | |
| 767 case NOT_EQUAL: return EQUAL; | |
| 768 case LESS: return GREATER_EQUAL; | |
| 769 case LESS_EQUAL: return GREATER; | |
| 770 case GREATER: return LESS_EQUAL; | |
| 771 case GREATER_EQUAL: return LESS; | |
| 772 case BELOW: return ABOVE_EQUAL; | |
| 773 case BELOW_EQUAL: return ABOVE; | |
| 774 case ABOVE: return BELOW_EQUAL; | |
| 775 case ABOVE_EQUAL: return BELOW; | |
| 776 default: | |
| 777 OS::Print("Error %d\n", condition); | |
|
srdjan
2012/06/13 15:29:35
Remove Print
| |
| 778 UNIMPLEMENTED(); | |
| 779 return EQUAL; | |
| 780 } | |
| 781 } | |
| 782 | |
| 783 | |
| 784 void BranchInstr::EmitBranchOnCondition(FlowGraphCompiler* compiler, | |
| 785 Condition true_condition) { | |
| 786 if (compiler->IsNextBlock(false_successor())) { | |
| 787 // If the next block is the false successor we will fall through to it. | |
| 788 __ j(true_condition, compiler->GetBlockLabel(true_successor())); | |
| 789 } else { | |
| 790 // If the next block is the true successor we negate comparison and fall | |
| 791 // through to it. | |
| 792 ASSERT(compiler->IsNextBlock(true_successor())); | |
| 793 Condition false_condition = NegateCondition(true_condition); | |
| 794 __ j(false_condition, compiler->GetBlockLabel(false_successor())); | |
| 795 } | |
| 796 } | |
| 797 | |
| 766 | 798 |
| 767 LocationSummary* CurrentContextComp::MakeLocationSummary() const { | 799 LocationSummary* CurrentContextComp::MakeLocationSummary() const { |
| 768 return LocationSummary::Make(0, Location::RequiresRegister()); | 800 return LocationSummary::Make(0, Location::RequiresRegister()); |
| 769 } | 801 } |
| 770 | 802 |
| 771 | 803 |
| 772 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 804 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 773 __ MoveRegister(locs()->out().reg(), CTX); | 805 __ MoveRegister(locs()->out().reg(), CTX); |
| 774 } | 806 } |
| 775 | 807 |
| 776 | 808 |
| 777 LocationSummary* StoreContextComp::MakeLocationSummary() const { | 809 LocationSummary* StoreContextComp::MakeLocationSummary() const { |
| 778 const intptr_t kNumInputs = 1; | 810 const intptr_t kNumInputs = 1; |
| 779 const intptr_t kNumTemps = 0; | 811 const intptr_t kNumTemps = 0; |
| 780 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 812 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 781 summary->set_in(0, Location::RegisterLocation(CTX)); | 813 summary->set_in(0, Location::RegisterLocation(CTX)); |
| 782 return summary; | 814 return summary; |
| 783 } | 815 } |
| 784 | 816 |
| 785 | 817 |
| 786 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 818 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 787 // Nothing to do. Context register were loaded by register allocator. | 819 // Nothing to do. Context register were loaded by register allocator. |
| 788 ASSERT(locs()->in(0).reg() == CTX); | 820 ASSERT(locs()->in(0).reg() == CTX); |
| 789 } | 821 } |
| 790 | 822 |
| 791 | 823 |
| 792 LocationSummary* StrictCompareComp::MakeLocationSummary() const { | 824 LocationSummary* StrictCompareComp::MakeLocationSummary() const { |
| 793 return LocationSummary::Make(2, Location::SameAsFirstInput()); | 825 if (fused_with_branch() == NULL) { |
| 826 return LocationSummary::Make(2, Location::SameAsFirstInput()); | |
| 827 } else { | |
| 828 return LocationSummary::Make(2, Location::NoLocation()); | |
| 829 } | |
| 794 } | 830 } |
| 795 | 831 |
| 796 | 832 |
| 797 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 833 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 798 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 799 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 800 | |
| 801 Register left = locs()->in(0).reg(); | 834 Register left = locs()->in(0).reg(); |
| 802 Register right = locs()->in(1).reg(); | 835 Register right = locs()->in(1).reg(); |
| 803 Register result = locs()->out().reg(); | |
| 804 | 836 |
| 837 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | |
| 838 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; | |
| 805 __ CompareRegisters(left, right); | 839 __ CompareRegisters(left, right); |
| 806 Label load_true, done; | 840 |
| 807 if (kind() == Token::kEQ_STRICT) { | 841 if (fused_with_branch() == NULL) { |
|
srdjan
2012/06/13 15:29:35
!is_fused_with_branch() or revert the if clauses t
Vyacheslav Egorov (Google)
2012/06/13 16:23:43
Done.
| |
| 808 __ j(EQUAL, &load_true, Assembler::kNearJump); | 842 Register result = locs()->out().reg(); |
| 843 Label load_true, done; | |
| 844 __ j(true_condition, &load_true, Assembler::kNearJump); | |
| 845 __ LoadObject(result, compiler->false_value()); | |
| 846 __ jmp(&done, Assembler::kNearJump); | |
| 847 __ Bind(&load_true); | |
| 848 __ LoadObject(result, compiler->true_value()); | |
| 849 __ Bind(&done); | |
| 809 } else { | 850 } else { |
| 810 ASSERT(kind() == Token::kNE_STRICT); | 851 fused_with_branch()->EmitBranchOnCondition(compiler, true_condition); |
| 811 __ j(NOT_EQUAL, &load_true, Assembler::kNearJump); | |
| 812 } | 852 } |
| 813 __ LoadObject(result, bool_false); | |
| 814 __ jmp(&done, Assembler::kNearJump); | |
| 815 __ Bind(&load_true); | |
| 816 __ LoadObject(result, bool_true); | |
| 817 __ Bind(&done); | |
| 818 } | 853 } |
| 819 | 854 |
| 820 | 855 |
| 821 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 856 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 822 ASSERT(VerifyCallComputation(this)); | 857 ASSERT(VerifyCallComputation(this)); |
| 823 // The arguments to the stub include the closure. The arguments | 858 // The arguments to the stub include the closure. The arguments |
| 824 // descriptor describes the closure's arguments (and so does not include | 859 // descriptor describes the closure's arguments (and so does not include |
| 825 // the closure). | 860 // the closure). |
| 826 Register temp_reg = locs()->temp(0).reg(); | 861 Register temp_reg = locs()->temp(0).reg(); |
| 827 int argument_count = ArgumentCount(); | 862 int argument_count = ArgumentCount(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 921 | 956 |
| 922 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { | 957 LocationSummary* BooleanNegateComp::MakeLocationSummary() const { |
| 923 return LocationSummary::Make(1, Location::RequiresRegister()); | 958 return LocationSummary::Make(1, Location::RequiresRegister()); |
| 924 } | 959 } |
| 925 | 960 |
| 926 | 961 |
| 927 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 962 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 928 Register value = locs()->in(0).reg(); | 963 Register value = locs()->in(0).reg(); |
| 929 Register result = locs()->out().reg(); | 964 Register result = locs()->out().reg(); |
| 930 | 965 |
| 931 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 932 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 933 Label done; | 966 Label done; |
| 934 __ LoadObject(result, bool_true); | 967 __ LoadObject(result, compiler->true_value()); |
| 935 __ CompareRegisters(result, value); | 968 __ CompareRegisters(result, value); |
| 936 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 969 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 937 __ LoadObject(result, bool_false); | 970 __ LoadObject(result, compiler->false_value()); |
| 938 __ Bind(&done); | 971 __ Bind(&done); |
| 939 } | 972 } |
| 940 | 973 |
| 941 | 974 |
| 942 LocationSummary* ChainContextComp::MakeLocationSummary() const { | 975 LocationSummary* ChainContextComp::MakeLocationSummary() const { |
| 943 return LocationSummary::Make(1, Location::NoLocation()); | 976 return LocationSummary::Make(1, Location::NoLocation()); |
| 944 } | 977 } |
| 945 | 978 |
| 946 | 979 |
| 947 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 980 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 999 StubCode::GetAllocationStubForClosure(closure_function)); | 1032 StubCode::GetAllocationStubForClosure(closure_function)); |
| 1000 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 1033 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 1001 compiler->GenerateCall(token_index(), try_index(), &label, | 1034 compiler->GenerateCall(token_index(), try_index(), &label, |
| 1002 PcDescriptors::kOther); | 1035 PcDescriptors::kOther); |
| 1003 __ Drop(2); // Discard type arguments and receiver. | 1036 __ Drop(2); // Discard type arguments and receiver. |
| 1004 } | 1037 } |
| 1005 | 1038 |
| 1006 #undef __ | 1039 #undef __ |
| 1007 | 1040 |
| 1008 } // namespace dart | 1041 } // namespace dart |
| OLD | NEW |