Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 10536145: Fuse comparisons that are used by branches together. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698