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

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: Address first round of review comments 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
« no previous file with comments | « src/arm64/lithium-arm64.h ('k') | src/arm64/lithium-codegen-arm64.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 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 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 } 819 }
820 820
821 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index)); 821 return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
822 } 822 }
823 823
824 824
825 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { 825 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
826 if (instr->representation().IsSmiOrInteger32()) { 826 if (instr->representation().IsSmiOrInteger32()) {
827 ASSERT(instr->left()->representation().Equals(instr->representation())); 827 ASSERT(instr->left()->representation().Equals(instr->representation()));
828 ASSERT(instr->right()->representation().Equals(instr->representation())); 828 ASSERT(instr->right()->representation().Equals(instr->representation()));
829
830 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
831 if (shifted_operation != NULL) {
832 return shifted_operation;
833 }
834
829 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); 835 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
830 LOperand* right = 836 LOperand* right =
831 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); 837 UseRegisterOrConstantAtStart(instr->BetterRightOperand());
832 LInstruction* result = instr->representation().IsSmi() ? 838 LInstruction* result = instr->representation().IsSmi() ?
833 DefineAsRegister(new(zone()) LAddS(left, right)) : 839 DefineAsRegister(new(zone()) LAddS(left, right)) :
834 DefineAsRegister(new(zone()) LAddI(left, right)); 840 DefineAsRegister(new(zone()) LAddI(left, right));
835 if (instr->CheckFlag(HValue::kCanOverflow)) { 841 if (instr->CheckFlag(HValue::kCanOverflow)) {
836 result = AssignEnvironment(result); 842 result = AssignEnvironment(result);
837 } 843 }
838 return result; 844 return result;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 return NULL; 905 return NULL;
900 } 906 }
901 907
902 908
903 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { 909 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
904 if (instr->representation().IsSmiOrInteger32()) { 910 if (instr->representation().IsSmiOrInteger32()) {
905 ASSERT(instr->left()->representation().Equals(instr->representation())); 911 ASSERT(instr->left()->representation().Equals(instr->representation()));
906 ASSERT(instr->right()->representation().Equals(instr->representation())); 912 ASSERT(instr->right()->representation().Equals(instr->representation()));
907 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32)); 913 ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
908 914
915 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
916 if (shifted_operation != NULL) {
917 return shifted_operation;
918 }
919
909 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); 920 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
910 LOperand* right = 921 LOperand* right =
911 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); 922 UseRegisterOrConstantAtStart(instr->BetterRightOperand());
912 return instr->representation().IsSmi() ? 923 return instr->representation().IsSmi() ?
913 DefineAsRegister(new(zone()) LBitS(left, right)) : 924 DefineAsRegister(new(zone()) LBitS(left, right)) :
914 DefineAsRegister(new(zone()) LBitI(left, right)); 925 DefineAsRegister(new(zone()) LBitI(left, right));
915 } else { 926 } else {
916 return DoArithmeticT(instr->op(), instr); 927 return DoArithmeticT(instr->op(), instr);
917 } 928 }
918 } 929 }
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2024 : UseRegisterOrConstant(instr->index()); 2035 : UseRegisterOrConstant(instr->index());
2025 LOperand* value = UseRegister(instr->value()); 2036 LOperand* value = UseRegister(instr->value());
2026 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL; 2037 LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL;
2027 LOperand* temp = TempRegister(); 2038 LOperand* temp = TempRegister();
2028 LSeqStringSetChar* result = 2039 LSeqStringSetChar* result =
2029 new(zone()) LSeqStringSetChar(context, string, index, value, temp); 2040 new(zone()) LSeqStringSetChar(context, string, index, value, temp);
2030 return DefineAsRegister(result); 2041 return DefineAsRegister(result);
2031 } 2042 }
2032 2043
2033 2044
2045 HBitwiseBinaryOperation* LChunkBuilder::CanTransformToShiftedOp(HValue* val,
2046 HValue** left) {
2047 if (!val->representation().IsInteger32()) return NULL;
2048 if (!(val->IsBitwise() || val->IsAdd() || val->IsSub())) return NULL;
2049
2050 HBinaryOperation* hinstr = HBinaryOperation::cast(val);
2051 HValue* hleft = hinstr->left();
2052 HValue* hright = hinstr->right();
2053 ASSERT(hleft->representation().Equals(hinstr->representation()));
2054 ASSERT(hright->representation().Equals(hinstr->representation()));
2055
2056 if ((hright->IsConstant() &&
2057 LikelyFitsImmField(hinstr, HConstant::cast(hright)->Integer32Value())) ||
2058 (hinstr->IsCommutative() && hleft->IsConstant() &&
2059 LikelyFitsImmField(hinstr, HConstant::cast(hleft)->Integer32Value()))) {
2060 // The constant operand will likely fit in the immediate field. We are
2061 // better off with
2062 // lsl x8, x9, #imm
2063 // add x0, x8, #imm2
2064 // than with
2065 // mov x16, #imm2
2066 // add x0, x16, x9 LSL #imm
2067 return NULL;
2068 }
2069
2070 HBitwiseBinaryOperation* shift = NULL;
2071 // TODO(aleram): We will miss situations where a shift operation is used by
2072 // different instructions both as a left and right operands.
2073 if (hright->IsBitwiseBinaryShift() &&
2074 HBitwiseBinaryOperation::cast(hright)->right()->IsConstant()) {
2075 shift = HBitwiseBinaryOperation::cast(hright);
2076 if (left != NULL) {
2077 *left = hleft;
2078 }
2079 } else if (hinstr->IsCommutative() &&
2080 hleft->IsBitwiseBinaryShift() &&
2081 HBitwiseBinaryOperation::cast(hleft)->right()->IsConstant()) {
2082 shift = HBitwiseBinaryOperation::cast(hleft);
2083 if (left != NULL) {
2084 *left = hright;
2085 }
2086 } else {
2087 return NULL;
2088 }
2089
2090 if ((JSShiftAmountFromHConstant(shift->right()) == 0) && shift->IsShr()) {
2091 // Shifts right by zero can deoptimize.
2092 return NULL;
2093 }
2094
2095 return shift;
2096 }
2097
2098
2099 bool LChunkBuilder::ShiftCanBeOptimizedAway(HBitwiseBinaryOperation* shift) {
2100 if (!shift->representation().IsInteger32()) {
2101 return false;
2102 }
2103 for (HUseIterator it(shift->uses()); !it.Done(); it.Advance()) {
2104 if (shift != CanTransformToShiftedOp(it.value())) {
2105 return false;
2106 }
2107 }
2108 return true;
2109 }
2110
2111
2112 LInstruction* LChunkBuilder::TryDoOpWithShiftedRightOperand(
2113 HBinaryOperation* instr) {
2114 HValue* left;
2115 HBitwiseBinaryOperation* shift = CanTransformToShiftedOp(instr, &left);
2116
2117 if ((shift != NULL) && ShiftCanBeOptimizedAway(shift)) {
2118 return DoShiftedBinaryOp(instr, left, shift);
2119 }
2120 return NULL;
2121 }
2122
2123
2124 LInstruction* LChunkBuilder::DoShiftedBinaryOp(
2125 HBinaryOperation* hinstr, HValue* hleft, HBitwiseBinaryOperation* hshift) {
2126 ASSERT(hshift->IsBitwiseBinaryShift());
2127 ASSERT(!hshift->IsShr() || (JSShiftAmountFromHConstant(hshift->right()) > 0));
2128
2129 LTemplateResultInstruction<1>* res;
2130 LOperand* left = UseRegisterAtStart(hleft);
2131 LOperand* right = UseRegisterAtStart(hshift->left());
2132 LOperand* shift_amount = UseConstant(hshift->right());
2133 Shift shift_op;
2134 switch (hshift->opcode()) {
2135 case HValue::kShl: shift_op = LSL; break;
2136 case HValue::kShr: shift_op = LSR; break;
2137 case HValue::kSar: shift_op = ASR; break;
2138 default: UNREACHABLE(); shift_op = NO_SHIFT;
2139 }
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 {
2146 ASSERT(hinstr->IsSub());
2147 res = new(zone()) LSubI(left, right, shift_op, shift_amount);
2148 }
2149 if (hinstr->CheckFlag(HValue::kCanOverflow)) {
2150 AssignEnvironment(res);
2151 }
2152 return DefineAsRegister(res);
2153 }
2154
2155
2034 LInstruction* LChunkBuilder::DoShift(Token::Value op, 2156 LInstruction* LChunkBuilder::DoShift(Token::Value op,
2035 HBitwiseBinaryOperation* instr) { 2157 HBitwiseBinaryOperation* instr) {
2036 if (instr->representation().IsTagged()) { 2158 if (instr->representation().IsTagged()) {
2037 return DoArithmeticT(op, instr); 2159 return DoArithmeticT(op, instr);
2038 } 2160 }
2039 2161
2040 ASSERT(instr->representation().IsInteger32() || 2162 ASSERT(instr->representation().IsInteger32() ||
2041 instr->representation().IsSmi()); 2163 instr->representation().IsSmi());
2042 ASSERT(instr->left()->representation().Equals(instr->representation())); 2164 ASSERT(instr->left()->representation().Equals(instr->representation()));
2043 ASSERT(instr->right()->representation().Equals(instr->representation())); 2165 ASSERT(instr->right()->representation().Equals(instr->representation()));
2044 2166
2167 if (ShiftCanBeOptimizedAway(instr)) {
2168 return NULL;
2169 }
2170
2045 LOperand* left = instr->representation().IsSmi() 2171 LOperand* left = instr->representation().IsSmi()
2046 ? UseRegister(instr->left()) 2172 ? UseRegister(instr->left())
2047 : UseRegisterAtStart(instr->left()); 2173 : UseRegisterAtStart(instr->left());
2048 2174
2049 HValue* right_value = instr->right(); 2175 HValue* right_value = instr->right();
2050 LOperand* right = NULL; 2176 LOperand* right = NULL;
2051 LOperand* temp = NULL; 2177 LOperand* temp = NULL;
2052 int constant_value = 0; 2178 int constant_value = 0;
2053 if (right_value->IsConstant()) { 2179 if (right_value->IsConstant()) {
2054 right = UseConstant(right_value); 2180 right = UseConstant(right_value);
2055 HConstant* constant = HConstant::cast(right_value); 2181 constant_value = JSShiftAmountFromHConstant(right_value);
2056 constant_value = constant->Integer32Value() & 0x1f;
2057 } else { 2182 } else {
2058 right = UseRegisterAtStart(right_value); 2183 right = UseRegisterAtStart(right_value);
2059 if (op == Token::ROR) { 2184 if (op == Token::ROR) {
2060 temp = TempRegister(); 2185 temp = TempRegister();
2061 } 2186 }
2062 } 2187 }
2063 2188
2064 // Shift operations can only deoptimize if we do a logical shift by 0 and the 2189 // Shift operations can only deoptimize if we do a logical shift by 0 and the
2065 // result cannot be truncated to int32. 2190 // result cannot be truncated to int32.
2066 bool does_deopt = false; 2191 bool does_deopt = false;
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 LStringCompareAndBranch* result = 2433 LStringCompareAndBranch* result =
2309 new(zone()) LStringCompareAndBranch(context, left, right); 2434 new(zone()) LStringCompareAndBranch(context, left, right);
2310 return MarkAsCall(result, instr); 2435 return MarkAsCall(result, instr);
2311 } 2436 }
2312 2437
2313 2438
2314 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 2439 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
2315 if (instr->representation().IsSmiOrInteger32()) { 2440 if (instr->representation().IsSmiOrInteger32()) {
2316 ASSERT(instr->left()->representation().Equals(instr->representation())); 2441 ASSERT(instr->left()->representation().Equals(instr->representation()));
2317 ASSERT(instr->right()->representation().Equals(instr->representation())); 2442 ASSERT(instr->right()->representation().Equals(instr->representation()));
2443
2444 LInstruction* shifted_operation = TryDoOpWithShiftedRightOperand(instr);
2445 if (shifted_operation != NULL) {
2446 return shifted_operation;
2447 }
2448
2318 LOperand *left; 2449 LOperand *left;
2319 if (instr->left()->IsConstant() && 2450 if (instr->left()->IsConstant() &&
2320 (HConstant::cast(instr->left())->Integer32Value() == 0)) { 2451 (HConstant::cast(instr->left())->Integer32Value() == 0)) {
2321 left = UseConstant(instr->left()); 2452 left = UseConstant(instr->left());
2322 } else { 2453 } else {
2323 left = UseRegisterAtStart(instr->left()); 2454 left = UseRegisterAtStart(instr->left());
2324 } 2455 }
2325 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); 2456 LOperand* right = UseRegisterOrConstantAtStart(instr->right());
2326 LInstruction* result = instr->representation().IsSmi() ? 2457 LInstruction* result = instr->representation().IsSmi() ?
2327 DefineAsRegister(new(zone()) LSubS(left, right)) : 2458 DefineAsRegister(new(zone()) LSubS(left, right)) :
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 2689
2559 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { 2690 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
2560 LOperand* receiver = UseRegister(instr->receiver()); 2691 LOperand* receiver = UseRegister(instr->receiver());
2561 LOperand* function = UseRegister(instr->function()); 2692 LOperand* function = UseRegister(instr->function());
2562 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); 2693 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function);
2563 return AssignEnvironment(DefineAsRegister(result)); 2694 return AssignEnvironment(DefineAsRegister(result));
2564 } 2695 }
2565 2696
2566 2697
2567 } } // namespace v8::internal 2698 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm64/lithium-arm64.h ('k') | src/arm64/lithium-codegen-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698