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

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

Issue 330263002: Eliminate overflow check for non-overflowing smi << operations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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
« no previous file with comments | « runtime/vm/intermediate_language_test.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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 2555 matching lines...) Expand 10 before | Expand all | Expand 10 after
2566 __ CompareImmediate(result, Immediate(-0x20000000000000LL), PP); 2566 __ CompareImmediate(result, Immediate(-0x20000000000000LL), PP);
2567 __ j(LESS, overflow); 2567 __ j(LESS, overflow);
2568 __ CompareImmediate(result, Immediate(0x20000000000000LL), PP); 2568 __ CompareImmediate(result, Immediate(0x20000000000000LL), PP);
2569 __ j(GREATER, overflow); 2569 __ j(GREATER, overflow);
2570 } 2570 }
2571 } 2571 }
2572 2572
2573 2573
2574 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, 2574 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
2575 BinarySmiOpInstr* shift_left) { 2575 BinarySmiOpInstr* shift_left) {
2576 const bool is_truncating = shift_left->is_truncating(); 2576 const bool is_truncating = shift_left->IsTruncating();
2577 const LocationSummary& locs = *shift_left->locs(); 2577 const LocationSummary& locs = *shift_left->locs();
2578 Register left = locs.in(0).reg(); 2578 Register left = locs.in(0).reg();
2579 Register result = locs.out(0).reg(); 2579 Register result = locs.out(0).reg();
2580 ASSERT(left == result); 2580 ASSERT(left == result);
2581 Label* deopt = shift_left->CanDeoptimize() ? 2581 Label* deopt = shift_left->CanDeoptimize() ?
2582 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) 2582 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp)
2583 : NULL; 2583 : NULL;
2584 if (locs.in(1).IsConstant()) { 2584 if (locs.in(1).IsConstant()) {
2585 const Object& constant = locs.in(1).constant(); 2585 const Object& constant = locs.in(1).constant();
2586 ASSERT(constant.IsSmi()); 2586 ASSERT(constant.IsSmi());
2587 // shlq operation masks the count to 6 bits. 2587 // shlq operation masks the count to 6 bits.
2588 const intptr_t kCountLimit = 0x3F; 2588 const intptr_t kCountLimit = 0x3F;
2589 const intptr_t value = Smi::Cast(constant).Value(); 2589 const intptr_t value = Smi::Cast(constant).Value();
2590 if (value == 0) { 2590 if (value == 0) {
2591 // No code needed. 2591 // No code needed.
2592 } else if ((value < 0) || (value >= kCountLimit)) { 2592 } else if ((value < 0) || (value >= kCountLimit)) {
2593 // This condition may not be known earlier in some cases because 2593 // This condition may not be known earlier in some cases because
2594 // of constant propagation, inlining, etc. 2594 // of constant propagation, inlining, etc.
2595 if ((value >=kCountLimit) && is_truncating) { 2595 if ((value >= kCountLimit) && is_truncating) {
2596 __ xorq(result, result); 2596 __ xorq(result, result);
2597 } else { 2597 } else {
2598 // Result is Mint or exception. 2598 // Result is Mint or exception.
2599 __ jmp(deopt); 2599 __ jmp(deopt);
2600 } 2600 }
2601 } else { 2601 } else {
2602 if (!is_truncating) { 2602 if (!is_truncating) {
2603 // Check for overflow. 2603 // Check for overflow.
2604 Register temp = locs.temp(0).reg(); 2604 Register temp = locs.temp(0).reg();
2605 __ movq(temp, left); 2605 __ movq(temp, left);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
2759 return summary; 2759 return summary;
2760 } else if (op_kind() == Token::kSHR) { 2760 } else if (op_kind() == Token::kSHR) {
2761 const intptr_t kNumTemps = 0; 2761 const intptr_t kNumTemps = 0;
2762 LocationSummary* summary = new(isolate) LocationSummary( 2762 LocationSummary* summary = new(isolate) LocationSummary(
2763 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 2763 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
2764 summary->set_in(0, Location::RequiresRegister()); 2764 summary->set_in(0, Location::RequiresRegister());
2765 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX)); 2765 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
2766 summary->set_out(0, Location::SameAsFirstInput()); 2766 summary->set_out(0, Location::SameAsFirstInput());
2767 return summary; 2767 return summary;
2768 } else if (op_kind() == Token::kSHL) { 2768 } else if (op_kind() == Token::kSHL) {
2769 const intptr_t kNumTemps = !is_truncating() ? 1 : 0; 2769 const intptr_t kNumTemps = !IsTruncating() ? 1 : 0;
2770 LocationSummary* summary = new(isolate) LocationSummary( 2770 LocationSummary* summary = new(isolate) LocationSummary(
2771 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 2771 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
2772 summary->set_in(0, Location::RequiresRegister()); 2772 summary->set_in(0, Location::RequiresRegister());
2773 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX)); 2773 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
2774 if (!is_truncating()) { 2774 if (!IsTruncating()) {
2775 summary->set_temp(0, Location::RequiresRegister()); 2775 summary->set_temp(0, Location::RequiresRegister());
2776 } 2776 }
2777 summary->set_out(0, Location::SameAsFirstInput()); 2777 summary->set_out(0, Location::SameAsFirstInput());
2778 return summary; 2778 return summary;
2779 } else { 2779 } else {
2780 const intptr_t kNumTemps = 0; 2780 const intptr_t kNumTemps = 0;
2781 LocationSummary* summary = new(isolate) LocationSummary( 2781 LocationSummary* summary = new(isolate) LocationSummary(
2782 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 2782 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
2783 summary->set_in(0, Location::RequiresRegister()); 2783 summary->set_in(0, Location::RequiresRegister());
2784 ConstantInstr* constant = right()->definition()->AsConstant(); 2784 ConstantInstr* constant = right()->definition()->AsConstant();
2785 if (constant != NULL) { 2785 if (constant != NULL) {
2786 summary->set_in(1, Location::RegisterOrSmiConstant(right())); 2786 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
2787 } else { 2787 } else {
2788 summary->set_in(1, Location::PrefersRegister()); 2788 summary->set_in(1, Location::PrefersRegister());
2789 } 2789 }
2790 summary->set_out(0, Location::SameAsFirstInput()); 2790 summary->set_out(0, Location::SameAsFirstInput());
2791 return summary; 2791 return summary;
2792 } 2792 }
2793 } 2793 }
2794 2794
2795 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2795 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2796 if (op_kind() == Token::kSHL) { 2796 if (op_kind() == Token::kSHL) {
2797 EmitSmiShiftLeft(compiler, this); 2797 EmitSmiShiftLeft(compiler, this);
2798 return; 2798 return;
2799 } 2799 }
2800 2800
2801 ASSERT(!is_truncating());
2802 Register left = locs()->in(0).reg(); 2801 Register left = locs()->in(0).reg();
2803 Register result = locs()->out(0).reg(); 2802 Register result = locs()->out(0).reg();
2804 ASSERT(left == result); 2803 ASSERT(left == result);
2805 Label* deopt = NULL; 2804 Label* deopt = NULL;
2806 if (CanDeoptimize()) { 2805 if (CanDeoptimize()) {
2807 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); 2806 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp);
2808 } 2807 }
2809 2808
2810 if (locs()->in(1).IsConstant()) { 2809 if (locs()->in(1).IsConstant()) {
2811 const Object& constant = locs()->in(1).constant(); 2810 const Object& constant = locs()->in(1).constant();
(...skipping 3024 matching lines...) Expand 10 before | Expand all | Expand 10 after
5836 __ movq(R10, Immediate(kInvalidObjectPointer)); 5835 __ movq(R10, Immediate(kInvalidObjectPointer));
5837 __ movq(RBX, Immediate(kInvalidObjectPointer)); 5836 __ movq(RBX, Immediate(kInvalidObjectPointer));
5838 #endif 5837 #endif
5839 } 5838 }
5840 5839
5841 } // namespace dart 5840 } // namespace dart
5842 5841
5843 #undef __ 5842 #undef __
5844 5843
5845 #endif // defined TARGET_ARCH_X64 5844 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_test.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698