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

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

Issue 220723017: Add optimization for pow(base, 0.5) to the other architectures as well. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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 | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 4912 matching lines...) Expand 10 before | Expand all | Expand 10 after
4923 } 4923 }
4924 result->AddTemp(Location::RegisterLocation(R3)); 4924 result->AddTemp(Location::RegisterLocation(R3));
4925 #endif 4925 #endif
4926 result->set_out(0, Location::FpuRegisterLocation(Q0)); 4926 result->set_out(0, Location::FpuRegisterLocation(Q0));
4927 return result; 4927 return result;
4928 } 4928 }
4929 4929
4930 4930
4931 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4931 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4932 // For pow-function return NaN if exponent is NaN. 4932 // For pow-function return NaN if exponent is NaN.
4933 Label do_call, skip_call; 4933 Label skip_call;
4934 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4934 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4935 // Pseudo code: 4935 // Pseudo code:
4936 // if (exponent == 0.0) return 0.0; 4936 // if (exponent == 0.0) return 1.0;
4937 // if (base == 1.0) return 1.0; 4937 // if (base == 1.0) return 1.0;
4938 // if (base.isNaN || exponent.isNaN) { 4938 // if (base.isNaN || exponent.isNaN) {
4939 // return double.NAN; 4939 // return double.NAN;
4940 // } 4940 // }
4941 // if (base != -Infinity && exponent == 0.5) {
4942 // if (base == 0.0) return 0.0;
4943 // return sqrt(value);
4944 // }
4941 DRegister base = EvenDRegisterOf(locs()->in(0).fpu_reg()); 4945 DRegister base = EvenDRegisterOf(locs()->in(0).fpu_reg());
4942 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg()); 4946 DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg());
4943 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); 4947 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
4944 Register temp = locs()->temp(0).reg(); 4948 Register temp = locs()->temp(0).reg();
4945 DRegister saved_base = EvenDRegisterOf(locs()->temp(1).fpu_reg()); 4949 DRegister saved_base = EvenDRegisterOf(locs()->temp(1).fpu_reg());
4946 ASSERT((base == result) && (result != saved_base)); 4950 ASSERT((base == result) && (result != saved_base));
4947 Label check_base_is_one; 4951
4948 // Check if exponent is 0.0 -> return 1.0; 4952 Label try_sqrt, check_base, return_nan;
4949 __ vmovd(saved_base, base); 4953 __ vmovd(saved_base, base);
4950 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); 4954 __ LoadDImmediate(DTMP, 0.0, temp);
4951 __ LoadDFromOffset(DTMP, temp, Double::value_offset() - kHeapObjectTag); 4955 __ LoadDImmediate(result, 1.0, temp);
4952 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); 4956 // exponent == 0.0 -> return 1.0;
4953 __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag);
4954 __ vcmpd(exp, DTMP); 4957 __ vcmpd(exp, DTMP);
4955 __ vmstat(); 4958 __ vmstat();
4956 __ b(&check_base_is_one, VS); // NaN -> not zero. 4959 __ b(&check_base, VS); // NaN -> check base.
4957 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0. 4960 __ b(&skip_call, EQ); // exp is 0.0, result is 1.0.
4958 4961
4959 __ Bind(&check_base_is_one); 4962 __ Bind(&check_base);
4963 // Note: 'exp' could be NaN.
4964 // base == 1.0 -> return 1.0;
4960 __ vcmpd(saved_base, result); 4965 __ vcmpd(saved_base, result);
4961 __ vmstat(); 4966 __ vmstat();
4962 __ vmovd(result, saved_base, VS); // base is NaN, return NaN. 4967 __ b(&return_nan, VS);
4963 __ b(&skip_call, VS); 4968 __ b(&skip_call, EQ); // base is 1.0, result is 1.0.
4964 __ b(&skip_call, EQ); // base and result are 1.0. 4969
4970 __ vcmpd(saved_base, exp);
4971 __ b(&try_sqrt, VC); // // Neither 'exp' nor 'base' is NaN.
4972
4973 __ Bind(&return_nan);
4974 __ LoadDImmediate(result, NAN, temp);
4975 __ b(&skip_call);
4976
4977 Label do_pow, return_zero;
4978 __ Bind(&try_sqrt);
4979
4980 // Before calling pow, check if we could use sqrt instead of pow.
4981 __ LoadDImmediate(result, -INFINITY, temp);
4982
4983 // base == -Infinity -> call pow;
4984 __ vcmpd(saved_base, result);
4985 __ b(&do_pow, EQ);
4986
4987 // exponent == 0.5 ?
4988 __ LoadDImmediate(result, 0.5, temp);
4989 __ vcmpd(exp, result);
4990 __ b(&do_pow, NE);
4991
4992 // base == 0 -> return 0;
4993 __ vcmpd(base, DTMP);
4994 __ b(&return_zero, EQ);
4995
4996 __ vsqrtd(result, saved_base);
4997 __ b(&skip_call);
4998
4999 __ Bind(&return_zero);
5000 __ vmovd(result, DTMP);
5001 __ b(&skip_call);
5002
5003 __ Bind(&do_pow);
4965 __ vmovd(base, saved_base); // Restore base. 5004 __ vmovd(base, saved_base); // Restore base.
4966 } 5005 }
4967 __ Bind(&do_call); 5006
4968 if (InputCount() == 2) { 5007 if (InputCount() == 2) {
4969 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. 5008 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1.
4970 __ vmovd(D1, D2); 5009 __ vmovd(D1, D2);
4971 } 5010 }
4972 #if defined(ARM_FLOAT_ABI_HARD) 5011 #if defined(ARM_FLOAT_ABI_HARD)
4973 __ CallRuntime(TargetFunction(), InputCount()); 5012 __ CallRuntime(TargetFunction(), InputCount());
4974 #else 5013 #else
4975 // If the ABI is not "hardfp", then we have to move the double arguments 5014 // If the ABI is not "hardfp", then we have to move the double arguments
4976 // to the integer registers, and take the results from the integer 5015 // to the integer registers, and take the results from the integer
4977 // registers. 5016 // registers.
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
5823 compiler->GenerateCall(token_pos(), 5862 compiler->GenerateCall(token_pos(),
5824 &label, 5863 &label,
5825 PcDescriptors::kOther, 5864 PcDescriptors::kOther,
5826 locs()); 5865 locs());
5827 __ Drop(ArgumentCount()); // Discard arguments. 5866 __ Drop(ArgumentCount()); // Discard arguments.
5828 } 5867 }
5829 5868
5830 } // namespace dart 5869 } // namespace dart
5831 5870
5832 #endif // defined TARGET_ARCH_ARM 5871 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698