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

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
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // TODO(regis): Range analysis may eliminate the deopt check.
5925 Register temp = locs()->temp(0).reg();
5926 __ movl(temp, left_lo);
5927 __ sarl(temp, Immediate(31));
5928 __ cmpl(temp, left_hi);
5929 __ j(NOT_EQUAL, deopt);
5930 __ movl(temp, right_lo);
5931 __ sarl(temp, Immediate(31));
5932 __ cmpl(temp, right_hi);
5933 __ j(NOT_EQUAL, deopt);
5934 ASSERT(left_lo == EAX);
5935 __ imull(right_lo); // Result in EDX:EAX.
5936 ASSERT(out_lo == EAX);
5937 ASSERT(out_hi == EDX);
5938 break;
5939 }
5940 default:
5941 UNREACHABLE();
5924 } 5942 }
5925 if (FLAG_throw_on_javascript_int_overflow) { 5943 if (FLAG_throw_on_javascript_int_overflow) {
5926 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 5944 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi);
5927 } 5945 }
5928 } 5946 }
5929 5947
5930 5948
5931 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 5949 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
5932 bool opt) const { 5950 bool opt) const {
5933 const intptr_t kNumInputs = 2; 5951 const intptr_t kNumInputs = 2;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
6106 __ Bind(&large_shift); 6124 __ Bind(&large_shift);
6107 // No need to subtract 32 from CL, only 5 bits used by shll. 6125 // No need to subtract 32 from CL, only 5 bits used by shll.
6108 __ movl(left_hi, left_lo); // Shift by 32. 6126 __ movl(left_hi, left_lo); // Shift by 32.
6109 __ xorl(left_lo, left_lo); // Zero left_lo. 6127 __ xorl(left_lo, left_lo); // Zero left_lo.
6110 __ shll(left_hi, ECX); // Shift count: CL % 32. 6128 __ shll(left_hi, ECX); // Shift count: CL % 32.
6111 } 6129 }
6112 break; 6130 break;
6113 } 6131 }
6114 default: 6132 default:
6115 UNREACHABLE(); 6133 UNREACHABLE();
6116 break;
6117 } 6134 }
6118 __ Bind(&done); 6135 __ Bind(&done);
6119 } 6136 }
6120 if (FLAG_throw_on_javascript_int_overflow) { 6137 if (FLAG_throw_on_javascript_int_overflow) {
6121 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 6138 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi);
6122 } 6139 }
6123 } 6140 }
6124 6141
6125 6142
6126 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, 6143 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
6185 6202
6186 6203
6187 CompileType UnboxUint32Instr::ComputeType() const { 6204 CompileType UnboxUint32Instr::ComputeType() const {
6188 return CompileType::Int(); 6205 return CompileType::Int();
6189 } 6206 }
6190 6207
6191 6208
6192 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6209 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6193 bool opt) const { 6210 bool opt) const {
6194 const intptr_t kNumInputs = 2; 6211 const intptr_t kNumInputs = 2;
6195 const intptr_t kNumTemps = 0; 6212 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0;
6196 LocationSummary* summary = new(isolate) LocationSummary( 6213 LocationSummary* summary = new(isolate) LocationSummary(
6197 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6214 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6198 summary->set_in(0, Location::RequiresRegister()); 6215 if (op_kind() == Token::kMUL) {
6216 summary->set_in(0, Location::RegisterLocation(EAX));
6217 summary->set_temp(0, Location::RegisterLocation(EDX));
6218 } else {
6219 summary->set_in(0, Location::RequiresRegister());
6220 }
6199 summary->set_in(1, Location::RequiresRegister()); 6221 summary->set_in(1, Location::RequiresRegister());
6200 summary->set_out(0, Location::SameAsFirstInput()); 6222 summary->set_out(0, Location::SameAsFirstInput());
6201 return summary; 6223 return summary;
6202 } 6224 }
6203 6225
6204 6226
6205 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6227 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6206 Register left = locs()->in(0).reg(); 6228 Register left = locs()->in(0).reg();
6207 Register right = locs()->in(1).reg(); 6229 Register right = locs()->in(1).reg();
6208 Register out = locs()->out(0).reg(); 6230 Register out = locs()->out(0).reg();
6209 ASSERT(out == left); 6231 ASSERT(out == left);
6210 switch (op_kind()) { 6232 switch (op_kind()) {
6211 case Token::kBIT_AND: 6233 case Token::kBIT_AND:
6212 __ andl(out, right); 6234 __ andl(out, right);
6213 break; 6235 break;
6214 case Token::kBIT_OR: 6236 case Token::kBIT_OR:
6215 __ orl(out, right); 6237 __ orl(out, right);
6216 break; 6238 break;
6217 case Token::kBIT_XOR: 6239 case Token::kBIT_XOR:
6218 __ xorl(out, right); 6240 __ xorl(out, right);
6219 break; 6241 break;
6220 case Token::kADD: 6242 case Token::kADD:
6221 __ addl(out, right); 6243 __ addl(out, right);
6222 break; 6244 break;
6223 case Token::kSUB: 6245 case Token::kSUB:
6224 __ subl(out, right); 6246 __ subl(out, right);
6225 break; 6247 break;
6248 case Token::kMUL:
6249 __ mull(right); // Result in EDX:EAX.
6250 ASSERT(out == EAX);
6251 ASSERT(locs()->temp(0).reg() == EDX);
6252 break;
6226 default: 6253 default:
6227 UNREACHABLE(); 6254 UNREACHABLE();
6228 } 6255 }
6229 } 6256 }
6230 6257
6231 6258
6232 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6259 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6233 bool opt) const { 6260 bool opt) const {
6234 const intptr_t kNumInputs = 2; 6261 const intptr_t kNumInputs = 2;
6235 const intptr_t kNumTemps = 0; 6262 const intptr_t kNumTemps = 0;
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
6830 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6857 __ movl(EDX, Immediate(kInvalidObjectPointer));
6831 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6858 __ movl(EDX, Immediate(kInvalidObjectPointer));
6832 #endif 6859 #endif
6833 } 6860 }
6834 6861
6835 } // namespace dart 6862 } // namespace dart
6836 6863
6837 #undef __ 6864 #undef __
6838 6865
6839 #endif // defined TARGET_ARCH_IA32 6866 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698