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

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

Issue 396733006: Optimize the multiplication of two 32-bit unsigned integers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 5 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 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 } 644 }
645 645
646 646
647 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 647 Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
648 BranchLabels labels) { 648 BranchLabels labels) {
649 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT)); 649 ASSERT((kind() == Token::kIS) || (kind() == Token::kISNOT));
650 Register val_reg = locs()->in(0).reg(); 650 Register val_reg = locs()->in(0).reg();
651 Register cid_reg = locs()->temp(0).reg(); 651 Register cid_reg = locs()->temp(0).reg();
652 652
653 Label* deopt = CanDeoptimize() ? 653 Label* deopt = CanDeoptimize() ?
654 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL; 654 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL;
655 655
656 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0; 656 const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
657 const ZoneGrowableArray<intptr_t>& data = cid_results(); 657 const ZoneGrowableArray<intptr_t>& data = cid_results();
658 ASSERT(data[0] == kSmiCid); 658 ASSERT(data[0] == kSmiCid);
659 bool result = data[1] == true_result; 659 bool result = data[1] == true_result;
660 __ testl(val_reg, Immediate(kSmiTagMask)); 660 __ testl(val_reg, Immediate(kSmiTagMask));
661 __ j(ZERO, result ? labels.true_label : labels.false_label); 661 __ j(ZERO, result ? labels.true_label : labels.false_label);
662 __ LoadClassId(cid_reg, val_reg); 662 __ LoadClassId(cid_reg, val_reg);
663 for (intptr_t i = 2; i < data.length(); i += 2) { 663 for (intptr_t i = 2; i < data.length(); i += 2) {
664 const intptr_t test_cid = data[i]; 664 const intptr_t test_cid = data[i];
(...skipping 5174 matching lines...) Expand 10 before | Expand all | Expand 10 after
5839 __ Bind(&done); 5839 __ Bind(&done);
5840 } 5840 }
5841 5841
5842 5842
5843 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 5843 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
5844 bool opt) const { 5844 bool opt) const {
5845 const intptr_t kNumInputs = 2; 5845 const intptr_t kNumInputs = 2;
5846 switch (op_kind()) { 5846 switch (op_kind()) {
5847 case Token::kBIT_AND: 5847 case Token::kBIT_AND:
5848 case Token::kBIT_OR: 5848 case Token::kBIT_OR:
5849 case Token::kBIT_XOR: { 5849 case Token::kBIT_XOR:
5850 const intptr_t kNumTemps = 0; 5850 case Token::kADD:
5851 case Token::kSUB:
5852 case Token::kMUL: {
5853 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0;
5851 LocationSummary* summary = new(isolate) LocationSummary( 5854 LocationSummary* summary = new(isolate) LocationSummary(
5852 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5855 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5853 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5856 summary->set_in(0, (op_kind() == Token::kMUL)
5854 Location::RequiresRegister())); 5857 ? Location::Pair(Location::RegisterLocation(EAX),
5858 Location::RegisterLocation(EDX))
5859 : Location::Pair(Location::RequiresRegister(),
5860 Location::RequiresRegister()));
5855 summary->set_in(1, Location::Pair(Location::RequiresRegister(), 5861 summary->set_in(1, Location::Pair(Location::RequiresRegister(),
5856 Location::RequiresRegister())); 5862 Location::RequiresRegister()));
5857 summary->set_out(0, Location::SameAsFirstInput()); 5863 summary->set_out(0, Location::SameAsFirstInput());
5858 return summary; 5864 if (kNumTemps > 0) {
5859 } 5865 summary->set_temp(0, Location::RequiresRegister());
5860 case Token::kADD: 5866 }
5861 case Token::kSUB: {
5862 const intptr_t kNumTemps = 0;
5863 LocationSummary* summary = new(isolate) LocationSummary(
5864 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5865 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
5866 Location::RequiresRegister()));
5867 summary->set_in(1, Location::Pair(Location::RequiresRegister(),
5868 Location::RequiresRegister()));
5869 summary->set_out(0, Location::SameAsFirstInput());
5870 return summary; 5867 return summary;
5871 } 5868 }
5872 default: 5869 default:
5873 UNREACHABLE(); 5870 UNREACHABLE();
5874 return NULL; 5871 return NULL;
5875 } 5872 }
5876 } 5873 }
5877 5874
5878 5875
5879 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5876 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5913 __ adcl(left_hi, right_hi); 5910 __ adcl(left_hi, right_hi);
5914 } else { 5911 } else {
5915 __ subl(left_lo, right_lo); 5912 __ subl(left_lo, right_lo);
5916 __ sbbl(left_hi, right_hi); 5913 __ sbbl(left_hi, right_hi);
5917 } 5914 }
5918 if (can_overflow()) { 5915 if (can_overflow()) {
5919 __ j(OVERFLOW, deopt); 5916 __ j(OVERFLOW, deopt);
5920 } 5917 }
5921 break; 5918 break;
5922 } 5919 }
5923 default: UNREACHABLE(); 5920 case Token::kMUL: {
5921 // The product of two signed 32-bit integers fits in a signed 64-bit
5922 // result without causing overflow.
5923 // We deopt on larger inputs.
5924 Register temp = locs()->temp(0).reg();
Vyacheslav Egorov (Google) 2014/07/18 11:15:35 Please add TODO here and in another place use rang
regis 2014/07/18 17:59:43 Done.
5925 __ movl(temp, left_lo);
5926 __ sarl(temp, Immediate(31));
5927 __ cmpl(temp, left_hi);
5928 __ j(NOT_EQUAL, deopt);
5929 __ movl(temp, right_lo);
5930 __ sarl(temp, Immediate(31));
5931 __ cmpl(temp, right_hi);
5932 __ j(NOT_EQUAL, deopt);
5933 ASSERT(left_lo == EAX);
5934 __ imull(right_lo); // Result in EDX:EAX.
5935 ASSERT(out_lo == EAX);
5936 ASSERT(out_hi == EDX);
5937 break;
5938 }
5939 default:
5940 UNREACHABLE();
5924 } 5941 }
5925 if (FLAG_throw_on_javascript_int_overflow) { 5942 if (FLAG_throw_on_javascript_int_overflow) {
5926 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 5943 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi);
5927 } 5944 }
5928 } 5945 }
5929 5946
5930 5947
5931 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 5948 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
5932 bool opt) const { 5949 bool opt) const {
5933 const intptr_t kNumInputs = 2; 5950 const intptr_t kNumInputs = 2;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
6106 __ Bind(&large_shift); 6123 __ Bind(&large_shift);
6107 // No need to subtract 32 from CL, only 5 bits used by shll. 6124 // No need to subtract 32 from CL, only 5 bits used by shll.
6108 __ movl(left_hi, left_lo); // Shift by 32. 6125 __ movl(left_hi, left_lo); // Shift by 32.
6109 __ xorl(left_lo, left_lo); // Zero left_lo. 6126 __ xorl(left_lo, left_lo); // Zero left_lo.
6110 __ shll(left_hi, ECX); // Shift count: CL % 32. 6127 __ shll(left_hi, ECX); // Shift count: CL % 32.
6111 } 6128 }
6112 break; 6129 break;
6113 } 6130 }
6114 default: 6131 default:
6115 UNREACHABLE(); 6132 UNREACHABLE();
6116 break;
6117 } 6133 }
6118 __ Bind(&done); 6134 __ Bind(&done);
6119 } 6135 }
6120 if (FLAG_throw_on_javascript_int_overflow) { 6136 if (FLAG_throw_on_javascript_int_overflow) {
6121 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 6137 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi);
6122 } 6138 }
6123 } 6139 }
6124 6140
6125 6141
6126 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 6142 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
6185 6201
6186 6202
6187 CompileType UnboxUint32Instr::ComputeType() const { 6203 CompileType UnboxUint32Instr::ComputeType() const {
6188 return CompileType::Int(); 6204 return CompileType::Int();
6189 } 6205 }
6190 6206
6191 6207
6192 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6208 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6193 bool opt) const { 6209 bool opt) const {
6194 const intptr_t kNumInputs = 2; 6210 const intptr_t kNumInputs = 2;
6195 const intptr_t kNumTemps = 0; 6211 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0;
6196 LocationSummary* summary = new(isolate) LocationSummary( 6212 LocationSummary* summary = new(isolate) LocationSummary(
6197 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6213 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6198 summary->set_in(0, Location::RequiresRegister()); 6214 if (op_kind() == Token::kMUL) {
6215 summary->set_in(0, Location::RegisterLocation(EAX));
6216 summary->set_temp(0, Location::RegisterLocation(EDX));
6217 } else {
6218 summary->set_in(0, Location::RequiresRegister());
6219 }
6199 summary->set_in(1, Location::RequiresRegister()); 6220 summary->set_in(1, Location::RequiresRegister());
6200 summary->set_out(0, Location::SameAsFirstInput()); 6221 summary->set_out(0, Location::SameAsFirstInput());
6201 return summary; 6222 return summary;
6202 } 6223 }
6203 6224
6204 6225
6205 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6226 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6206 Register left = locs()->in(0).reg(); 6227 Register left = locs()->in(0).reg();
6207 Register right = locs()->in(1).reg(); 6228 Register right = locs()->in(1).reg();
6208 Register out = locs()->out(0).reg(); 6229 Register out = locs()->out(0).reg();
6209 ASSERT(out == left); 6230 ASSERT(out == left);
6210 switch (op_kind()) { 6231 switch (op_kind()) {
6211 case Token::kBIT_AND: 6232 case Token::kBIT_AND:
6212 __ andl(out, right); 6233 __ andl(out, right);
6213 break; 6234 break;
6214 case Token::kBIT_OR: 6235 case Token::kBIT_OR:
6215 __ orl(out, right); 6236 __ orl(out, right);
6216 break; 6237 break;
6217 case Token::kBIT_XOR: 6238 case Token::kBIT_XOR:
6218 __ xorl(out, right); 6239 __ xorl(out, right);
6219 break; 6240 break;
6220 case Token::kADD: 6241 case Token::kADD:
6221 __ addl(out, right); 6242 __ addl(out, right);
6222 break; 6243 break;
6223 case Token::kSUB: 6244 case Token::kSUB:
6224 __ subl(out, right); 6245 __ subl(out, right);
6225 break; 6246 break;
6247 case Token::kMUL:
6248 __ mull(right); // Result in EDX:EAX.
6249 ASSERT(out == EAX);
6250 ASSERT(locs()->temp(0).reg() == EDX);
6251 break;
6226 default: 6252 default:
6227 UNREACHABLE(); 6253 UNREACHABLE();
6228 } 6254 }
6229 } 6255 }
6230 6256
6231 6257
6232 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6258 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6233 bool opt) const { 6259 bool opt) const {
6234 const intptr_t kNumInputs = 2; 6260 const intptr_t kNumInputs = 2;
6235 const intptr_t kNumTemps = 0; 6261 const intptr_t kNumTemps = 0;
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
6830 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6856 __ movl(EDX, Immediate(kInvalidObjectPointer));
6831 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6857 __ movl(EDX, Immediate(kInvalidObjectPointer));
6832 #endif 6858 #endif
6833 } 6859 }
6834 6860
6835 } // namespace dart 6861 } // namespace dart
6836 6862
6837 #undef __ 6863 #undef __
6838 6864
6839 #endif // defined TARGET_ARCH_IA32 6865 #endif // defined TARGET_ARCH_IA32
OLDNEW
« runtime/vm/flow_graph_optimizer.cc ('K') | « runtime/vm/intermediate_language_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698