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

Side by Side Diff: src/arm64/lithium-arm64.cc

Issue 257203002: ARM64: Use the shifter operand to merge in previous shift instructions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "v8.h" 5 #include "v8.h"
6 6
7 #include "lithium-allocator-inl.h" 7 #include "lithium-allocator-inl.h"
8 #include "arm64/lithium-arm64.h" 8 #include "arm64/lithium-arm64.h"
9 #include "arm64/lithium-codegen-arm64.h" 9 #include "arm64/lithium-codegen-arm64.h"
10 #include "hydrogen-osr.h" 10 #include "hydrogen-osr.h"
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 } 818 }
819 819
820 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index)); 820 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
821 } 821 }
822 822
823 823
824 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { 824 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
825 if (instr->representation().IsSmiOrInteger32()) { 825 if (instr->representation().IsSmiOrInteger32()) {
826 ASSERT(instr->left()->representation().Equals(instr->representation())); 826 ASSERT(instr->left()->representation().Equals(instr->representation()));
827 ASSERT(instr->right()->representation().Equals(instr->representation())); 827 ASSERT(instr->right()->representation().Equals(instr->representation()));
828
829 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
830 if (shifted_operation != NULL) {
831 return shifted_operation;
832 }
833
828 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); 834 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
829 LOperand* right = 835 LOperand* right =
830 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); 836 UseRegisterOrConstantAtStart(instr->BetterRightOperand());
831 LInstruction* result = instr->representation().IsSmi() ? 837 LInstruction* result = instr->representation().IsSmi() ?
832 DefineAsRegister(new(zone()) LAddS(left, right)) : 838 DefineAsRegister(new(zone()) LAddS(left, right)) :
833 DefineAsRegister(new(zone()) LAddI(left, right)); 839 DefineAsRegister(new(zone()) LAddI(left, right));
834 if (instr->CheckFlag(HValue::kCanOverflow)) { 840 if (instr->CheckFlag(HValue::kCanOverflow)) {
835 result = AssignEnvironment(result); 841 result = AssignEnvironment(result);
836 } 842 }
837 return result; 843 return result;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 return NULL; 904 return NULL;
899 } 905 }
900 906
901 907
902 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { 908 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
903 if (instr->representation().IsSmiOrInteger32()) { 909 if (instr->representation().IsSmiOrInteger32()) {
904 ASSERT(instr->left()->representation().Equals(instr->representation())); 910 ASSERT(instr->left()->representation().Equals(instr->representation()));
905 ASSERT(instr->right()->representation().Equals(instr->representation())); 911 ASSERT(instr->right()->representation().Equals(instr->representation()));
906 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32)); 912 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
907 913
914 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
915 if (shifted_operation != NULL) {
916 return shifted_operation;
917 }
918
908 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); 919 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
909 LOperand* right = 920 LOperand* right =
910 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); 921 UseRegisterOrConstantAtStart(instr->BetterRightOperand());
911 return instr->representation().IsSmi() ? 922 return instr->representation().IsSmi() ?
912 DefineAsRegister(new(zone()) LBitS(left, right)) : 923 DefineAsRegister(new(zone()) LBitS(left, right)) :
913 DefineAsRegister(new(zone()) LBitI(left, right)); 924 DefineAsRegister(new(zone()) LBitI(left, right));
914 } else { 925 } else {
915 return DoArithmeticT(instr->op(), instr); 926 return DoArithmeticT(instr->op(), instr);
916 } 927 }
917 } 928 }
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2023 : UseRegisterOrConstant(instr->index()); 2034 : UseRegisterOrConstant(instr->index());
2024 LOperand* value = UseRegister(instr->value()); 2035 LOperand* value = UseRegister(instr->value());
2025 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL; 2036 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL;
2026 LOperand* temp = TempRegister(); 2037 LOperand* temp = TempRegister();
2027 LSeqStringSetChar* result = 2038 LSeqStringSetChar* result =
2028 new(zone()) LSeqStringSetChar(context, string, index, value, temp); 2039 new(zone()) LSeqStringSetChar(context, string, index, value, temp);
2029 return DefineAsRegister(result); 2040 return DefineAsRegister(result);
2030 } 2041 }
2031 2042
2032 2043
2044 HBitwiseBinaryOperation* LChunkBuilder::CanTransformToShiftedOp(HValue* val,
2045 HValue** left) {
2046 if (!val->representation().IsInteger32()) return NULL;
2047 if (!val->IsBitwise() && !(val->IsAdd() || val->IsSub())) return NULL;
ulan 2014/05/02 10:01:18 Simpler condition: !(val->IsBitwise() || val->IsAd
Alexandre Rames 2014/05/02 13:51:44 Done.
2048
2049 HBinaryOperation* hinstr = HBinaryOperation::cast(val);
2050 HValue* hleft = hinstr->left();
2051 HValue* hright = hinstr->right();
2052 ASSERT(hleft->representation().Equals(hinstr->representation()));
2053 ASSERT(hright->representation().Equals(hinstr->representation()));
2054
2055 if ((hright->IsConstant() &&
2056 LikelyFitsImmField(hinstr, HConstant::cast(hright)->Integer32Value())) ||
2057 (hinstr->IsCommutative() && hleft->IsConstant() &&
2058 LikelyFitsImmField(hinstr, HConstant::cast(hleft)->Integer32Value()))) {
2059 // The constant operand will likely fit in the immediate field. We are
2060 // better off with
2061 // lsl x8, x9, #imm
2062 // add x0, x8, #imm2
2063 // than with
2064 // mov x16, #imm2
2065 // add x0, x16, x9 LSL #imm
2066 return NULL;
2067 }
2068
2069 HBitwiseBinaryOperation* shift = NULL;
2070 // TODO(aleram): We will miss situations where a shift operation is used by
2071 // different instructions both as a left and right operands.
2072 if (hright->IsBitwiseBinaryShift() &&
2073 HBitwiseBinaryOperation::cast(hright)->right()->IsConstant()) {
2074 shift = HBitwiseBinaryOperation::cast(hright);
2075 if (left != NULL) {
2076 *left = hleft;
2077 }
2078 } else if (hinstr->IsCommutative() &&
2079 hleft->IsBitwiseBinaryShift() &&
2080 HBitwiseBinaryOperation::cast(hleft)->right()->IsConstant()) {
2081 shift = HBitwiseBinaryOperation::cast(hleft);
2082 if (left != NULL) {
2083 *left = hright;
2084 }
2085 } else {
2086 return NULL;
2087 }
2088
2089 if ((ShiftAmountFromHConstant(shift->right()) == 0) && shift->IsShr()) {
2090 // Shifts right by zero can deoptimize.
2091 return NULL;
2092 }
2093
2094 return shift;
2095 }
2096
2097
2098 bool LChunkBuilder::ShiftCanBeOptimizedAway(HBitwiseBinaryOperation* shift) {
2099 if (!shift->representation().IsInteger32()) {
2100 return false;
2101 }
2102 for (HUseIterator it(shift->uses()); !it.Done(); it.Advance()) {
2103 if (shift != CanTransformToShiftedOp(it.value())) {
2104 return false;
2105 }
2106 }
2107 return true;
2108 }
2109
2110
2111 LInstruction* LChunkBuilder::TryDoOpWithShiftedRightOperand(
2112 HBinaryOperation* instr) {
2113 HValue* left;
2114 HBitwiseBinaryOperation* shift = CanTransformToShiftedOp(instr, &left);
2115
2116 if ((shift != NULL) && ShiftCanBeOptimizedAway(shift)) {
2117 return DoShiftedBinaryOp(instr, left, shift);
2118 }
2119 return NULL;
2120 }
2121
2122
2123 LInstruction* LChunkBuilder::DoShiftedBinaryOp(
2124 HBinaryOperation* hinstr, HValue* hleft, HBitwiseBinaryOperation* hshift) {
2125 ASSERT(hshift->IsBitwiseBinaryShift());
2126 ASSERT(!hshift->IsShr() || (ShiftAmountFromHConstant(hshift->right()) > 0));
2127
2128 LTemplateResultInstruction<1>* res;
2129 LOperand* left = UseRegisterAtStart(hleft);
2130 LOperand* right = UseRegisterAtStart(hshift->left());
2131 LOperand* shift_amount = UseConstant(hshift->right());
2132 Shift shift_op;
2133 switch (hshift->opcode()) {
2134 case HValue::kShl: shift_op = LSL; break;
2135 case HValue::kShr: shift_op = LSR; break;
2136 case HValue::kSar: shift_op = ASR; break;
2137 default: UNREACHABLE(); shift_op = NO_SHIFT;
2138 }
2139 bool can_overflow = hinstr->CheckFlag(HValue::kCanOverflow);
ulan 2014/05/02 10:01:18 You can inline hinstr->CheckFlag(HValue::kCanOverf
Alexandre Rames 2014/05/02 13:51:44 Done.
2140
2141 if (hinstr->IsBitwise()) {
2142 res = new(zone()) LBitI(left, right, shift_op, shift_amount);
2143 } else if (hinstr->IsAdd()) {
2144 res = new(zone()) LAddI(left, right, shift_op, shift_amount);
2145 } else if (hinstr->IsSub()) {
2146 res = new(zone()) LSubI(left, right, shift_op, shift_amount);
2147 } else {
2148 UNREACHABLE();
ulan 2014/05/02 10:01:18 nit: I'd ASSERT(hinstr->IsSub()) above.
Alexandre Rames 2014/05/02 13:51:44 Done.
2149 res = NULL;
2150 }
2151 if (can_overflow) {
2152 AssignEnvironment(res);
2153 }
2154 return DefineAsRegister(res);
2155 }
2156
2157
2033 LInstruction* LChunkBuilder::DoShift(Token::Value op, 2158 LInstruction* LChunkBuilder::DoShift(Token::Value op,
2034 HBitwiseBinaryOperation* instr) { 2159 HBitwiseBinaryOperation* instr) {
2035 if (instr->representation().IsTagged()) { 2160 if (instr->representation().IsTagged()) {
2036 return DoArithmeticT(op, instr); 2161 return DoArithmeticT(op, instr);
2037 } 2162 }
2038 2163
2039 ASSERT(instr->representation().IsInteger32() || 2164 ASSERT(instr->representation().IsInteger32() ||
2040 instr->representation().IsSmi()); 2165 instr->representation().IsSmi());
2041 ASSERT(instr->left()->representation().Equals(instr->representation())); 2166 ASSERT(instr->left()->representation().Equals(instr->representation()));
2042 ASSERT(instr->right()->representation().Equals(instr->representation())); 2167 ASSERT(instr->right()->representation().Equals(instr->representation()));
2043 2168
2169 if (ShiftCanBeOptimizedAway(instr)) {
2170 return NULL;
2171 }
2172
2044 LOperand* left = instr->representation().IsSmi() 2173 LOperand* left = instr->representation().IsSmi()
2045 ? UseRegister(instr->left()) 2174 ? UseRegister(instr->left())
2046 : UseRegisterAtStart(instr->left()); 2175 : UseRegisterAtStart(instr->left());
2047 2176
2048 HValue* right_value = instr->right(); 2177 HValue* right_value = instr->right();
2049 LOperand* right = NULL; 2178 LOperand* right = NULL;
2050 LOperand* temp = NULL; 2179 LOperand* temp = NULL;
2051 int constant_value = 0; 2180 int constant_value = 0;
2052 if (right_value->IsConstant()) { 2181 if (right_value->IsConstant()) {
2053 right = UseConstant(right_value); 2182 right = UseConstant(right_value);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2307 LStringCompareAndBranch* result = 2436 LStringCompareAndBranch* result =
2308 new(zone()) LStringCompareAndBranch(context, left, right); 2437 new(zone()) LStringCompareAndBranch(context, left, right);
2309 return MarkAsCall(result, instr); 2438 return MarkAsCall(result, instr);
2310 } 2439 }
2311 2440
2312 2441
2313 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 2442 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
2314 if (instr->representation().IsSmiOrInteger32()) { 2443 if (instr->representation().IsSmiOrInteger32()) {
2315 ASSERT(instr->left()->representation().Equals(instr->representation())); 2444 ASSERT(instr->left()->representation().Equals(instr->representation()));
2316 ASSERT(instr->right()->representation().Equals(instr->representation())); 2445 ASSERT(instr->right()->representation().Equals(instr->representation()));
2446
2447 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
2448 if (shifted_operation != NULL) {
2449 return shifted_operation;
2450 }
2451
2317 LOperand *left; 2452 LOperand *left;
2318 if (instr->left()->IsConstant() && 2453 if (instr->left()->IsConstant() &&
2319 (HConstant::cast(instr->left())->Integer32Value() == 0)) { 2454 (HConstant::cast(instr->left())->Integer32Value() == 0)) {
2320 left = UseConstant(instr->left()); 2455 left = UseConstant(instr->left());
2321 } else { 2456 } else {
2322 left = UseRegisterAtStart(instr->left()); 2457 left = UseRegisterAtStart(instr->left());
2323 } 2458 }
2324 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); 2459 LOperand* right = UseRegisterOrConstantAtStart(instr->right());
2325 LInstruction* result = instr->representation().IsSmi() ? 2460 LInstruction* result = instr->representation().IsSmi() ?
2326 DefineAsRegister(new(zone()) LSubS(left, right)) : 2461 DefineAsRegister(new(zone()) LSubS(left, right)) :
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2553 2688
2554 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { 2689 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
2555 LOperand* receiver = UseRegister(instr->receiver()); 2690 LOperand* receiver = UseRegister(instr->receiver());
2556 LOperand* function = UseRegister(instr->function()); 2691 LOperand* function = UseRegister(instr->function());
2557 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); 2692 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function);
2558 return AssignEnvironment(DefineAsRegister(result)); 2693 return AssignEnvironment(DefineAsRegister(result));
2559 } 2694 }
2560 2695
2561 2696
2562 } } // namespace v8::internal 2697 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698