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

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

Issue 23757016: Simplify compilation of relational operators. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 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) 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/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 locs->set_out(Location::RequiresRegister()); 916 locs->set_out(Location::RequiresRegister());
917 return locs; 917 return locs;
918 } 918 }
919 if (operation_cid() == kDoubleCid) { 919 if (operation_cid() == kDoubleCid) {
920 LocationSummary* summary = 920 LocationSummary* summary =
921 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 921 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
922 summary->set_in(0, Location::RequiresFpuRegister()); 922 summary->set_in(0, Location::RequiresFpuRegister());
923 summary->set_in(1, Location::RequiresFpuRegister()); 923 summary->set_in(1, Location::RequiresFpuRegister());
924 summary->set_out(Location::RequiresRegister()); 924 summary->set_out(Location::RequiresRegister());
925 return summary; 925 return summary;
926 } else if (operation_cid() == kSmiCid) {
927 LocationSummary* summary =
928 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
929 summary->set_in(0, Location::RegisterOrConstant(left()));
930 // Only one input can be a constant operand. The case of two constant
931 // operands should be handled by constant propagation.
932 summary->set_in(1, summary->in(0).IsConstant()
933 ? Location::RequiresRegister()
934 : Location::RegisterOrConstant(right()));
935 summary->set_out(Location::RequiresRegister());
936 return summary;
937 } 926 }
938 LocationSummary* locs = 927 ASSERT(operation_cid() == kSmiCid);
939 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 928 LocationSummary* summary =
940 // Pick arbitrary fixed input registers because this is a call. 929 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
941 locs->set_in(0, Location::RegisterLocation(EAX)); 930 summary->set_in(0, Location::RegisterOrConstant(left()));
942 locs->set_in(1, Location::RegisterLocation(ECX)); 931 // Only one input can be a constant operand. The case of two constant
943 locs->set_out(Location::RegisterLocation(EAX)); 932 // operands should be handled by constant propagation.
944 return locs; 933 summary->set_in(1, summary->in(0).IsConstant()
934 ? Location::RequiresRegister()
935 : Location::RegisterOrConstant(right()));
936 summary->set_out(Location::RequiresRegister());
937 return summary;
945 } 938 }
946 939
947 940
948 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 941 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
949 if (operation_cid() == kSmiCid) { 942 if (operation_cid() == kSmiCid) {
950 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); 943 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
951 return; 944 return;
952 } 945 }
953 if (operation_cid() == kMintCid) { 946 if (operation_cid() == kMintCid) {
954 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL); 947 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
955 return; 948 return;
956 } 949 }
957 if (operation_cid() == kDoubleCid) { 950 ASSERT(operation_cid() == kDoubleCid);
958 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); 951 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
959 return;
960 }
961
962 // Push arguments for the call.
963 // TODO(fschneider): Split this instruction into different types to avoid
964 // explicitly pushing arguments to the call here.
965 Register left = locs()->in(0).reg();
966 Register right = locs()->in(1).reg();
967 __ pushl(left);
968 __ pushl(right);
969 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
970 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp);
971 // Load class into EDI. Since this is a call, any register except
972 // the fixed input registers would be ok.
973 ASSERT((left != EDI) && (right != EDI));
974 const intptr_t kNumArguments = 2;
975 LoadValueCid(compiler, EDI, left);
976 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
977 EDI, // Class id register.
978 kNumArguments,
979 Object::null_array(), // No named arguments.
980 deopt, // Deoptimize target.
981 deopt_id(),
982 token_pos(),
983 locs());
984 return;
985 }
986 const String& function_name =
987 String::ZoneHandle(Symbols::New(Token::Str(kind())));
988 if (!compiler->is_optimizing()) {
989 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
990 deopt_id(),
991 token_pos());
992 }
993 const intptr_t kNumArguments = 2;
994 const intptr_t kNumArgsChecked = 2; // Type-feedback.
995 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw());
996 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
997 ASSERT(!ic_data()->IsNull());
998 if (ic_data()->NumberOfChecks() == 0) {
999 // IC call for reoptimization populates original ICData.
1000 relational_ic_data = ic_data()->raw();
1001 } else {
1002 // Megamorphic call.
1003 relational_ic_data = ic_data()->AsUnaryClassChecks();
1004 }
1005 } else {
1006 const Array& arguments_descriptor =
1007 Array::Handle(ArgumentsDescriptor::New(kNumArguments,
1008 Object::null_array()));
1009 relational_ic_data = ICData::New(compiler->parsed_function().function(),
1010 function_name,
1011 arguments_descriptor,
1012 deopt_id(),
1013 kNumArgsChecked);
1014 }
1015 compiler->GenerateInstanceCall(deopt_id(),
1016 token_pos(),
1017 kNumArguments,
1018 Object::null_array(), // No optional args.
1019 locs(),
1020 relational_ic_data);
1021 } 952 }
1022 953
1023 954
1024 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 955 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
1025 BranchInstr* branch) { 956 BranchInstr* branch) {
1026 if (operation_cid() == kSmiCid) { 957 if (operation_cid() == kSmiCid) {
1027 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 958 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
1028 return; 959 return;
1029 } 960 }
1030 if (operation_cid() == kMintCid) { 961 if (operation_cid() == kMintCid) {
1031 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); 962 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
1032 return; 963 return;
1033 } 964 }
1034 if (operation_cid() == kDoubleCid) { 965 ASSERT(operation_cid() == kDoubleCid);
1035 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 966 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
1036 return;
1037 }
1038 EmitNativeCode(compiler);
1039 __ CompareObject(EAX, Bool::True());
1040 branch->EmitBranchOnCondition(compiler, EQUAL);
1041 } 967 }
1042 968
1043 969
1044 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 970 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
1045 const intptr_t kNumInputs = 0; 971 const intptr_t kNumInputs = 0;
1046 const intptr_t kNumTemps = 3; 972 const intptr_t kNumTemps = 3;
1047 LocationSummary* locs = 973 LocationSummary* locs =
1048 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 974 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1049 locs->set_temp(0, Location::RegisterLocation(EAX)); 975 locs->set_temp(0, Location::RegisterLocation(EAX));
1050 locs->set_temp(1, Location::RegisterLocation(ECX)); 976 locs->set_temp(1, Location::RegisterLocation(ECX));
(...skipping 4214 matching lines...) Expand 10 before | Expand all | Expand 10 after
5265 PcDescriptors::kOther, 5191 PcDescriptors::kOther,
5266 locs()); 5192 locs());
5267 __ Drop(2); // Discard type arguments and receiver. 5193 __ Drop(2); // Discard type arguments and receiver.
5268 } 5194 }
5269 5195
5270 } // namespace dart 5196 } // namespace dart
5271 5197
5272 #undef __ 5198 #undef __
5273 5199
5274 #endif // defined TARGET_ARCH_IA32 5200 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698