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

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

Issue 19695007: Optimize double min/max by reducing the code size (reusing left register as result removes the need… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 3075 matching lines...) Expand 10 before | Expand all | Expand 10 after
3086 3086
3087 3087
3088 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { 3088 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const {
3089 if (result_cid() == kDoubleCid) { 3089 if (result_cid() == kDoubleCid) {
3090 const intptr_t kNumInputs = 2; 3090 const intptr_t kNumInputs = 2;
3091 const intptr_t kNumTemps = 1; 3091 const intptr_t kNumTemps = 1;
3092 LocationSummary* summary = 3092 LocationSummary* summary =
3093 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3093 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3094 summary->set_in(0, Location::RequiresFpuRegister()); 3094 summary->set_in(0, Location::RequiresFpuRegister());
3095 summary->set_in(1, Location::RequiresFpuRegister()); 3095 summary->set_in(1, Location::RequiresFpuRegister());
3096 summary->set_out(Location::RequiresFpuRegister()); 3096 // Reuse the left register so that code can be made shorter.
3097 summary->set_out(Location::SameAsFirstInput());
3097 summary->set_temp(0, Location::RequiresRegister()); 3098 summary->set_temp(0, Location::RequiresRegister());
3098 return summary; 3099 return summary;
3099 } 3100 }
3100 ASSERT(result_cid() == kSmiCid); 3101 ASSERT(result_cid() == kSmiCid);
3101 UNIMPLEMENTED(); 3102 const intptr_t kNumInputs = 2;
3102 return NULL; 3103 const intptr_t kNumTemps = 0;
3104 LocationSummary* summary =
3105 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3106 summary->set_in(0, Location::RequiresRegister());
3107 summary->set_in(1, Location::RequiresRegister());
3108 // Reuse the left register so that code can be made shorter.
3109 summary->set_out(Location::SameAsFirstInput());
3110 return summary;
3103 } 3111 }
3104 3112
3105 3113
3106 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3114 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3107 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 3115 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
3108 (op_kind() == MethodRecognizer::kMathMax)); 3116 (op_kind() == MethodRecognizer::kMathMax));
3117 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3109 if (result_cid() == kDoubleCid) { 3118 if (result_cid() == kDoubleCid) {
3110 Label done, returns_nan, returns_left, are_equal; 3119 Label done, returns_nan, are_equal;
3111 DRegister left = locs()->in(0).fpu_reg(); 3120 DRegister left = locs()->in(0).fpu_reg();
3112 DRegister right = locs()->in(1).fpu_reg(); 3121 DRegister right = locs()->in(1).fpu_reg();
3113 DRegister result = locs()->out().fpu_reg(); 3122 DRegister result = locs()->out().fpu_reg();
3114 Register temp = locs()->temp(0).reg(); 3123 Register temp = locs()->temp(0).reg();
3115 __ cund(left, right); 3124 __ cund(left, right);
3116 __ bc1t(&returns_nan); 3125 __ bc1t(&returns_nan);
3117 __ ceqd(left, right); 3126 __ ceqd(left, right);
3118 __ bc1t(&are_equal); 3127 __ bc1t(&are_equal);
3119 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3120 if (is_min) { 3128 if (is_min) {
3121 __ coltd(left, right); 3129 __ coltd(left, right);
3122 } else { 3130 } else {
3123 __ coltd(right, left); 3131 __ coltd(right, left);
3124 } 3132 }
3125 // TODO(zra): Add conditional moves. 3133 // TODO(zra): Add conditional moves.
3126 __ bc1t(&returns_left); 3134 ASSERT(left == result);
3135 __ bc1t(&done);
3127 __ movd(result, right); 3136 __ movd(result, right);
3128 __ b(&done); 3137 __ b(&done);
3129 3138
3130 __ Bind(&returns_left);
3131 __ movd(result, left);
3132 __ b(&done);
3133
3134 __ Bind(&returns_nan); 3139 __ Bind(&returns_nan);
3135 __ LoadImmediate(result, NAN); 3140 __ LoadImmediate(result, NAN);
3136 __ b(&done); 3141 __ b(&done);
3137 3142
3138 __ Bind(&are_equal); 3143 __ Bind(&are_equal);
3139 Label left_is_negative; 3144 Label left_is_negative;
3140 // Check for negative zero: -0.0 is equal 0.0 but min or max must return 3145 // Check for negative zero: -0.0 is equal 0.0 but min or max must return
3141 // -0.0 or 0.0 respectively. 3146 // -0.0 or 0.0 respectively.
3142 // Check for negative left value (get the sign bit): 3147 // Check for negative left value (get the sign bit):
3143 // - min -> left is negative ? left : right. 3148 // - min -> left is negative ? left : right.
3144 // - max -> left is negative ? right : left 3149 // - max -> left is negative ? right : left
3145 // Check the sign bit. 3150 // Check the sign bit.
3146 __ mfc1(temp, OddFRegisterOf(left)); // Moves bits 32...63 of left to temp. 3151 __ mfc1(temp, OddFRegisterOf(left)); // Moves bits 32...63 of left to temp.
3147 __ bltz(temp, &left_is_negative); 3152 if (is_min) {
3148 // Left is positive. 3153 ASSERT(left == result);
3149 __ movd(result, (is_min ? right : left)); 3154 __ bltz(temp, &done); // Left is negative.
3150 __ b(&done); 3155 } else {
3151 3156 __ bgez(temp, &done); // Left is positive.
3152 __ Bind(&left_is_negative); 3157 }
3153 __ movd(result, (is_min ? left : right)); 3158 __ movd(result, right);
3154 __ Bind(&done); 3159 __ Bind(&done);
3155 return; 3160 return;
3156 } 3161 }
3162
3163 Label done;
3157 ASSERT(result_cid() == kSmiCid); 3164 ASSERT(result_cid() == kSmiCid);
3158 UNIMPLEMENTED(); 3165 Register left = locs()->in(0).reg();
3166 Register right = locs()->in(1).reg();
3167 Register result = locs()->out().reg();
3168 ASSERT(result == left);
3169 if (is_min) {
3170 __ BranchSignedLessEqual(left, right, &done);
3171 } else {
3172 __ BranchSignedGreaterEqual(left, right, &done);
3173 }
3174 __ mov(result, right);
3175 __ Bind(&done);
3159 } 3176 }
3160 3177
3161 3178
3162 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 3179 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
3163 const intptr_t kNumInputs = 1; 3180 const intptr_t kNumInputs = 1;
3164 const intptr_t kNumTemps = 0; 3181 const intptr_t kNumTemps = 0;
3165 LocationSummary* summary = 3182 LocationSummary* summary =
3166 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3183 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3167 summary->set_in(0, Location::RequiresRegister()); 3184 summary->set_in(0, Location::RequiresRegister());
3168 // We make use of 3-operand instructions by not requiring result register 3185 // We make use of 3-operand instructions by not requiring result register
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
3847 compiler->GenerateCall(token_pos(), 3864 compiler->GenerateCall(token_pos(),
3848 &label, 3865 &label,
3849 PcDescriptors::kOther, 3866 PcDescriptors::kOther,
3850 locs()); 3867 locs());
3851 __ Drop(2); // Discard type arguments and receiver. 3868 __ Drop(2); // Discard type arguments and receiver.
3852 } 3869 }
3853 3870
3854 } // namespace dart 3871 } // namespace dart
3855 3872
3856 #endif // defined TARGET_ARCH_MIPS 3873 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698