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

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') | runtime/vm/object.h » ('j') | 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 case Token::kADD:
5851 case Token::kSUB: {
5850 const intptr_t kNumTemps = 0; 5852 const intptr_t kNumTemps = 0;
5851 LocationSummary* summary = new(isolate) LocationSummary( 5853 LocationSummary* summary = new(isolate) LocationSummary(
5852 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5854 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5853 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5855 summary->set_in(0, Location::Pair(Location::RequiresRegister(),
5854 Location::RequiresRegister())); 5856 Location::RequiresRegister()));
5855 summary->set_in(1, Location::Pair(Location::RequiresRegister(), 5857 summary->set_in(1, Location::Pair(Location::RequiresRegister(),
5856 Location::RequiresRegister())); 5858 Location::RequiresRegister()));
5857 summary->set_out(0, Location::SameAsFirstInput()); 5859 summary->set_out(0, Location::SameAsFirstInput());
5858 return summary; 5860 return summary;
5859 } 5861 }
5860 case Token::kADD: 5862 case Token::kMUL: {
5861 case Token::kSUB: {
5862 const intptr_t kNumTemps = 0; 5863 const intptr_t kNumTemps = 0;
5863 LocationSummary* summary = new(isolate) LocationSummary( 5864 LocationSummary* summary = new(isolate) LocationSummary(
5864 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5865 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5865 summary->set_in(0, Location::Pair(Location::RequiresRegister(), 5866 summary->set_in(0, Location::Pair(Location::RegisterLocation(EAX),
5866 Location::RequiresRegister())); 5867 Location::RegisterLocation(EDX)));
5867 summary->set_in(1, Location::Pair(Location::RequiresRegister(), 5868 summary->set_in(1, Location::Pair(Location::RequiresRegister(),
5868 Location::RequiresRegister())); 5869 Location::RequiresRegister()));
5869 summary->set_out(0, Location::SameAsFirstInput()); 5870 summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX),
5871 Location::RegisterLocation(EDX)));
5870 return summary; 5872 return summary;
5871 } 5873 }
5872 default: 5874 default:
5873 UNREACHABLE(); 5875 UNREACHABLE();
5874 return NULL; 5876 return NULL;
5875 } 5877 }
5876 } 5878 }
5877 5879
5878 5880
5879 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5881 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5913 __ adcl(left_hi, right_hi); 5915 __ adcl(left_hi, right_hi);
5914 } else { 5916 } else {
5915 __ subl(left_lo, right_lo); 5917 __ subl(left_lo, right_lo);
5916 __ sbbl(left_hi, right_hi); 5918 __ sbbl(left_hi, right_hi);
5917 } 5919 }
5918 if (can_overflow()) { 5920 if (can_overflow()) {
5919 __ j(OVERFLOW, deopt); 5921 __ j(OVERFLOW, deopt);
5920 } 5922 }
5921 break; 5923 break;
5922 } 5924 }
5925 case Token::kMUL: {
5926 // We only support the multiplication of two positive 32-bit integers
5927 // resulting in a positive 64-bit integer fitting in a mint.
5928 // We deopt in all other cases.
5929 // This guarantees that the multiplication of 16-bit unsigned integers,
5930 // as used in bignum arithmetic, will always succeed.
5931 __ orl(left_hi, right_hi);
5932 __ j(NOT_ZERO, deopt);
5933 ASSERT(left_lo == EAX);
5934 __ mull(right_lo); // Result in EDX:EAX.
5935 if (can_overflow()) {
5936 __ testl(right_hi, Immediate(0xc0000000));
5937 __ shrl(right_hi, Immediate(30));
sra1 2014/07/16 00:58:27 Maybe I misunderstand, but... Why test right_hi?
regis 2014/07/16 02:23:22 Oops, the shrl is left over from a previous versio
5938 __ j(NOT_ZERO, deopt);
5939 }
5940 break;
5941 }
5923 default: UNREACHABLE(); 5942 default: UNREACHABLE();
5924 } 5943 }
5925 if (FLAG_throw_on_javascript_int_overflow) { 5944 if (FLAG_throw_on_javascript_int_overflow) {
5926 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); 5945 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi);
5927 } 5946 }
5928 } 5947 }
5929 5948
5930 5949
5931 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, 5950 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
5932 bool opt) const { 5951 bool opt) const {
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
6186 6205
6187 6206
6188 CompileType UnboxUint32Instr::ComputeType() const { 6207 CompileType UnboxUint32Instr::ComputeType() const {
6189 return CompileType::Int(); 6208 return CompileType::Int();
6190 } 6209 }
6191 6210
6192 6211
6193 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6212 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6194 bool opt) const { 6213 bool opt) const {
6195 const intptr_t kNumInputs = 2; 6214 const intptr_t kNumInputs = 2;
6196 const intptr_t kNumTemps = 0; 6215 const intptr_t kNumTemps = (op_kind() == Token::kMUL) ? 1 : 0;
6197 LocationSummary* summary = new(isolate) LocationSummary( 6216 LocationSummary* summary = new(isolate) LocationSummary(
6198 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6217 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6199 summary->set_in(0, Location::RequiresRegister()); 6218 if (op_kind() == Token::kMUL) {
6219 summary->set_in(0, Location::RegisterLocation(EAX));
6220 summary->set_temp(0, Location::RegisterLocation(EDX));
6221 } else {
6222 summary->set_in(0, Location::RequiresRegister());
6223 }
6200 summary->set_in(1, Location::RequiresRegister()); 6224 summary->set_in(1, Location::RequiresRegister());
6201 summary->set_out(0, Location::SameAsFirstInput()); 6225 summary->set_out(0, Location::SameAsFirstInput());
6202 return summary; 6226 return summary;
6203 } 6227 }
6204 6228
6205 6229
6206 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6230 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6207 Register left = locs()->in(0).reg(); 6231 Register left = locs()->in(0).reg();
6208 Register right = locs()->in(1).reg(); 6232 Register right = locs()->in(1).reg();
6209 Register out = locs()->out(0).reg(); 6233 Register out = locs()->out(0).reg();
6210 ASSERT(out == left); 6234 ASSERT(out == left);
6235 Label* deopt = CanDeoptimize() ?
6236 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryUint32Op) : NULL;
6211 switch (op_kind()) { 6237 switch (op_kind()) {
6212 case Token::kBIT_AND: 6238 case Token::kBIT_AND:
6213 __ andl(out, right); 6239 __ andl(out, right);
6214 break; 6240 break;
6215 case Token::kBIT_OR: 6241 case Token::kBIT_OR:
6216 __ orl(out, right); 6242 __ orl(out, right);
6217 break; 6243 break;
6218 case Token::kBIT_XOR: 6244 case Token::kBIT_XOR:
6219 __ xorl(out, right); 6245 __ xorl(out, right);
6220 break; 6246 break;
6221 case Token::kADD: 6247 case Token::kADD:
6222 __ addl(out, right); 6248 __ addl(out, right);
6223 break; 6249 break;
6224 case Token::kSUB: 6250 case Token::kSUB:
6225 __ subl(out, right); 6251 __ subl(out, right);
6226 break; 6252 break;
6253 case Token::kMUL:
6254 __ mull(right); // Result in EDX:EAX, CF set if EDX != 0.
6255 __ j(OVERFLOW, deopt);
6256 break;
6227 default: 6257 default:
6228 UNREACHABLE(); 6258 UNREACHABLE();
6229 } 6259 }
6230 } 6260 }
6231 6261
6232 6262
6233 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, 6263 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate,
6234 bool opt) const { 6264 bool opt) const {
6235 const intptr_t kNumInputs = 2; 6265 const intptr_t kNumInputs = 2;
6236 const intptr_t kNumTemps = 0; 6266 const intptr_t kNumTemps = 0;
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
6831 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6861 __ movl(EDX, Immediate(kInvalidObjectPointer));
6832 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6862 __ movl(EDX, Immediate(kInvalidObjectPointer));
6833 #endif 6863 #endif
6834 } 6864 }
6835 6865
6836 } // namespace dart 6866 } // namespace dart
6837 6867
6838 #undef __ 6868 #undef __
6839 6869
6840 #endif // defined TARGET_ARCH_IA32 6870 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698