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

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

Issue 214613004: Only assign environments when they are actually needed. (ARM and ARM64 only) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased. 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 | « src/arm64/lithium-arm64.h ('k') | src/ia32/lithium-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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 instr->ReplayEnvironment(current_block_->last_environment()); 1067 instr->ReplayEnvironment(current_block_->last_environment());
1068 1068
1069 // There are no real uses of a captured object. 1069 // There are no real uses of a captured object.
1070 return NULL; 1070 return NULL;
1071 } 1071 }
1072 1072
1073 1073
1074 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1074 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1075 Representation from = instr->from(); 1075 Representation from = instr->from();
1076 Representation to = instr->to(); 1076 Representation to = instr->to();
1077 1077 HValue* val = instr->value();
1078 if (from.IsSmi()) { 1078 if (from.IsSmi()) {
1079 if (to.IsTagged()) { 1079 if (to.IsTagged()) {
1080 LOperand* value = UseRegister(instr->value()); 1080 LOperand* value = UseRegister(val);
1081 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1081 return DefineSameAsFirst(new(zone()) LDummyUse(value));
1082 } 1082 }
1083 from = Representation::Tagged(); 1083 from = Representation::Tagged();
1084 } 1084 }
1085
1086 if (from.IsTagged()) { 1085 if (from.IsTagged()) {
1087 if (to.IsDouble()) { 1086 if (to.IsDouble()) {
1088 LOperand* value = UseRegister(instr->value()); 1087 LOperand* value = UseRegister(val);
1089 LOperand* temp = TempRegister(); 1088 LOperand* temp = TempRegister();
1090 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); 1089 LInstruction* result =
1091 return AssignEnvironment(DefineAsRegister(res)); 1090 DefineAsRegister(new(zone()) LNumberUntagD(value, temp));
1091 if (!val->representation().IsSmi()) result = AssignEnvironment(result);
1092 return result;
1092 } else if (to.IsSmi()) { 1093 } else if (to.IsSmi()) {
1093 LOperand* value = UseRegister(instr->value()); 1094 LOperand* value = UseRegister(val);
1094 if (instr->value()->type().IsSmi()) { 1095 if (val->type().IsSmi()) {
1095 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1096 return DefineSameAsFirst(new(zone()) LDummyUse(value));
1096 } 1097 }
1097 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); 1098 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
1098 } else { 1099 } else {
1099 ASSERT(to.IsInteger32()); 1100 ASSERT(to.IsInteger32());
1100 LInstruction* res = NULL; 1101 if (val->type().IsSmi() || val->representation().IsSmi()) {
1101 1102 LOperand* value = UseRegisterAtStart(val);
1102 if (instr->value()->type().IsSmi() || 1103 return DefineAsRegister(new(zone()) LSmiUntag(value, false));
1103 instr->value()->representation().IsSmi()) {
1104 LOperand* value = UseRegisterAtStart(instr->value());
1105 res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
1106 } else { 1104 } else {
1107 LOperand* value = UseRegister(instr->value()); 1105 LOperand* value = UseRegister(val);
1108 LOperand* temp1 = TempRegister(); 1106 LOperand* temp1 = TempRegister();
1109 LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24); 1107 LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24);
1110 res = DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2)); 1108 LInstruction* result =
1111 res = AssignEnvironment(res); 1109 DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2));
1110 if (!val->representation().IsSmi()) {
1111 // Note: Only deopts in deferred code.
1112 result = AssignEnvironment(result);
1113 }
1114 return result;
1112 } 1115 }
1113
1114 return res;
1115 } 1116 }
1116 } else if (from.IsDouble()) { 1117 } else if (from.IsDouble()) {
1117 if (to.IsTagged()) { 1118 if (to.IsTagged()) {
1118 info()->MarkAsDeferredCalling(); 1119 info()->MarkAsDeferredCalling();
1119 LOperand* value = UseRegister(instr->value()); 1120 LOperand* value = UseRegister(val);
1120 LOperand* temp1 = TempRegister(); 1121 LOperand* temp1 = TempRegister();
1121 LOperand* temp2 = TempRegister(); 1122 LOperand* temp2 = TempRegister();
1122
1123 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); 1123 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
1124 return AssignPointerMap(DefineAsRegister(result)); 1124 return AssignPointerMap(DefineAsRegister(result));
1125 } else { 1125 } else {
1126 ASSERT(to.IsSmi() || to.IsInteger32()); 1126 ASSERT(to.IsSmi() || to.IsInteger32());
1127 LOperand* value = UseRegister(instr->value());
1128
1129 if (instr->CanTruncateToInt32()) { 1127 if (instr->CanTruncateToInt32()) {
1130 LTruncateDoubleToIntOrSmi* result = 1128 LOperand* value = UseRegister(val);
1131 new(zone()) LTruncateDoubleToIntOrSmi(value); 1129 return DefineAsRegister(new(zone()) LTruncateDoubleToIntOrSmi(value));
1132 return DefineAsRegister(result);
1133 } else { 1130 } else {
1131 LOperand* value = UseRegister(val);
1134 LDoubleToIntOrSmi* result = new(zone()) LDoubleToIntOrSmi(value); 1132 LDoubleToIntOrSmi* result = new(zone()) LDoubleToIntOrSmi(value);
1135 return AssignEnvironment(DefineAsRegister(result)); 1133 return AssignEnvironment(DefineAsRegister(result));
1136 } 1134 }
1137 } 1135 }
1138 } else if (from.IsInteger32()) { 1136 } else if (from.IsInteger32()) {
1139 info()->MarkAsDeferredCalling(); 1137 info()->MarkAsDeferredCalling();
1140 if (to.IsTagged()) { 1138 if (to.IsTagged()) {
1141 if (instr->value()->CheckFlag(HInstruction::kUint32)) { 1139 if (val->CheckFlag(HInstruction::kUint32)) {
1142 LOperand* value = UseRegister(instr->value()); 1140 LOperand* value = UseRegister(val);
1143 LNumberTagU* result = new(zone()) LNumberTagU(value, 1141 LNumberTagU* result =
1144 TempRegister(), 1142 new(zone()) LNumberTagU(value, TempRegister(), TempRegister());
1145 TempRegister()); 1143 return AssignPointerMap(DefineAsRegister(result));
1146 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1147 } else { 1144 } else {
1148 STATIC_ASSERT((kMinInt == Smi::kMinValue) && 1145 STATIC_ASSERT((kMinInt == Smi::kMinValue) &&
1149 (kMaxInt == Smi::kMaxValue)); 1146 (kMaxInt == Smi::kMaxValue));
1150 LOperand* value = UseRegisterAtStart(instr->value()); 1147 LOperand* value = UseRegisterAtStart(val);
1151 return DefineAsRegister(new(zone()) LSmiTag(value)); 1148 return DefineAsRegister(new(zone()) LSmiTag(value));
1152 } 1149 }
1153 } else if (to.IsSmi()) { 1150 } else if (to.IsSmi()) {
1154 LOperand* value = UseRegisterAtStart(instr->value()); 1151 LOperand* value = UseRegisterAtStart(val);
1155 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); 1152 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
1156 if (instr->value()->CheckFlag(HInstruction::kUint32)) { 1153 if (val->CheckFlag(HInstruction::kUint32)) {
1157 result = AssignEnvironment(result); 1154 result = AssignEnvironment(result);
1158 } 1155 }
1159 return result; 1156 return result;
1160 } else { 1157 } else {
1161 ASSERT(to.IsDouble()); 1158 ASSERT(to.IsDouble());
1162 if (instr->value()->CheckFlag(HInstruction::kUint32)) { 1159 if (val->CheckFlag(HInstruction::kUint32)) {
1163 return DefineAsRegister( 1160 return DefineAsRegister(
1164 new(zone()) LUint32ToDouble(UseRegisterAtStart(instr->value()))); 1161 new(zone()) LUint32ToDouble(UseRegisterAtStart(val)));
1165 } else { 1162 } else {
1166 return DefineAsRegister( 1163 return DefineAsRegister(
1167 new(zone()) LInteger32ToDouble(UseRegisterAtStart(instr->value()))); 1164 new(zone()) LInteger32ToDouble(UseRegisterAtStart(val)));
1168 } 1165 }
1169 } 1166 }
1170 } 1167 }
1171
1172 UNREACHABLE(); 1168 UNREACHABLE();
1173 return NULL; 1169 return NULL;
1174 } 1170 }
1175 1171
1176 1172
1177 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) { 1173 LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
1178 LOperand* value = UseRegisterAtStart(instr->value()); 1174 LOperand* value = UseRegisterAtStart(instr->value());
1179 return AssignEnvironment(new(zone()) LCheckValue(value)); 1175 return AssignEnvironment(new(zone()) LCheckValue(value));
1180 } 1176 }
1181 1177
1182 1178
1183 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { 1179 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1184 LOperand* value = UseRegisterAtStart(instr->value()); 1180 LOperand* value = UseRegisterAtStart(instr->value());
1185 LOperand* temp = TempRegister(); 1181 LOperand* temp = TempRegister();
1186 LInstruction* result = new(zone()) LCheckInstanceType(value, temp); 1182 LInstruction* result = new(zone()) LCheckInstanceType(value, temp);
1187 return AssignEnvironment(result); 1183 return AssignEnvironment(result);
1188 } 1184 }
1189 1185
1190 1186
1191 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { 1187 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
1192 if (instr->CanOmitMapChecks()) { 1188 LOperand* value = NULL;
1193 // LCheckMaps does nothing in this case. 1189 LOperand* temp = NULL;
1194 return new(zone()) LCheckMaps(NULL); 1190 if (!instr->CanOmitMapChecks()) {
1195 } else { 1191 value = UseRegisterAtStart(instr->value());
1196 LOperand* value = UseRegisterAtStart(instr->value()); 1192 temp = TempRegister();
1197 LOperand* temp = TempRegister(); 1193 if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
1198
1199 if (instr->has_migration_target()) {
1200 info()->MarkAsDeferredCalling();
1201 LInstruction* result = new(zone()) LCheckMaps(value, temp);
1202 return AssignPointerMap(AssignEnvironment(result));
1203 } else {
1204 return AssignEnvironment(new(zone()) LCheckMaps(value, temp));
1205 }
1206 } 1194 }
1195 LInstruction* result = new(zone()) LCheckMaps(value, temp);
1196 if (!instr->CanOmitMapChecks()) {
1197 // Note: Only deopts in deferred code.
1198 result = AssignEnvironment(result);
1199 if (instr->has_migration_target()) return AssignPointerMap(result);
1200 }
1201 return result;
1207 } 1202 }
1208 1203
1209 1204
1210 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { 1205 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
1211 LOperand* value = UseRegisterAtStart(instr->value()); 1206 LOperand* value = UseRegisterAtStart(instr->value());
1212 return AssignEnvironment(new(zone()) LCheckNonSmi(value)); 1207 return AssignEnvironment(new(zone()) LCheckNonSmi(value));
1213 } 1208 }
1214 1209
1215 1210
1216 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { 1211 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 1406
1412 1407
1413 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { 1408 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
1414 ASSERT(instr->representation().IsSmiOrInteger32()); 1409 ASSERT(instr->representation().IsSmiOrInteger32());
1415 ASSERT(instr->left()->representation().Equals(instr->representation())); 1410 ASSERT(instr->left()->representation().Equals(instr->representation()));
1416 ASSERT(instr->right()->representation().Equals(instr->representation())); 1411 ASSERT(instr->right()->representation().Equals(instr->representation()));
1417 LOperand* dividend = UseRegister(instr->left()); 1412 LOperand* dividend = UseRegister(instr->left());
1418 LOperand* divisor = UseRegister(instr->right()); 1413 LOperand* divisor = UseRegister(instr->right());
1419 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) 1414 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)
1420 ? NULL : TempRegister(); 1415 ? NULL : TempRegister();
1421 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); 1416 LInstruction* result =
1422 return AssignEnvironment(DefineAsRegister(div)); 1417 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp));
1418 if (!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1419 result = AssignEnvironment(result);
1420 }
1421 return result;
1423 } 1422 }
1424 1423
1425 1424
1426 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1425 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1427 if (instr->representation().IsSmiOrInteger32()) { 1426 if (instr->representation().IsSmiOrInteger32()) {
1428 if (instr->RightIsPowerOf2()) { 1427 if (instr->RightIsPowerOf2()) {
1429 return DoDivByPowerOf2I(instr); 1428 return DoDivByPowerOf2I(instr);
1430 } else if (instr->right()->IsConstant()) { 1429 } else if (instr->right()->IsConstant()) {
1431 return DoDivByConstI(instr); 1430 return DoDivByConstI(instr);
1432 } else { 1431 } else {
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 current_block_->UpdateEnvironment(outer); 1614 current_block_->UpdateEnvironment(outer);
1616 1615
1617 return pop; 1616 return pop;
1618 } 1617 }
1619 1618
1620 1619
1621 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 1620 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1622 LOperand* context = UseRegisterAtStart(instr->value()); 1621 LOperand* context = UseRegisterAtStart(instr->value());
1623 LInstruction* result = 1622 LInstruction* result =
1624 DefineAsRegister(new(zone()) LLoadContextSlot(context)); 1623 DefineAsRegister(new(zone()) LLoadContextSlot(context));
1625 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; 1624 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
1625 result = AssignEnvironment(result);
1626 }
1627 return result;
1626 } 1628 }
1627 1629
1628 1630
1629 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( 1631 LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
1630 HLoadFunctionPrototype* instr) { 1632 HLoadFunctionPrototype* instr) {
1631 LOperand* function = UseRegister(instr->function()); 1633 LOperand* function = UseRegister(instr->function());
1632 LOperand* temp = TempRegister(); 1634 LOperand* temp = TempRegister();
1633 return AssignEnvironment(DefineAsRegister( 1635 return AssignEnvironment(DefineAsRegister(
1634 new(zone()) LLoadFunctionPrototype(function, temp))); 1636 new(zone()) LLoadFunctionPrototype(function, temp)));
1635 } 1637 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 ? AssignEnvironment(DefineAsRegister(result)) 1682 ? AssignEnvironment(DefineAsRegister(result))
1681 : DefineAsRegister(result); 1683 : DefineAsRegister(result);
1682 } 1684 }
1683 } else { 1685 } else {
1684 ASSERT((instr->representation().IsInteger32() && 1686 ASSERT((instr->representation().IsInteger32() &&
1685 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || 1687 !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
1686 (instr->representation().IsDouble() && 1688 (instr->representation().IsDouble() &&
1687 IsDoubleOrFloatElementsKind(instr->elements_kind()))); 1689 IsDoubleOrFloatElementsKind(instr->elements_kind())));
1688 1690
1689 LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister(); 1691 LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister();
1690 LLoadKeyedExternal* result = 1692 LInstruction* result = DefineAsRegister(
1691 new(zone()) LLoadKeyedExternal(elements, key, temp); 1693 new(zone()) LLoadKeyedExternal(elements, key, temp));
1692 // An unsigned int array load might overflow and cause a deopt. Make sure it 1694 if ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
1693 // has an environment. 1695 elements_kind == UINT32_ELEMENTS) &&
1694 if (instr->RequiresHoleCheck() || 1696 !instr->CheckFlag(HInstruction::kUint32)) {
1695 elements_kind == EXTERNAL_UINT32_ELEMENTS || 1697 result = AssignEnvironment(result);
1696 elements_kind == UINT32_ELEMENTS) {
1697 return AssignEnvironment(DefineAsRegister(result));
1698 } else {
1699 return DefineAsRegister(result);
1700 } 1698 }
1699 return result;
1701 } 1700 }
1702 } 1701 }
1703 1702
1704 1703
1705 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1704 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1706 LOperand* context = UseFixed(instr->context(), cp); 1705 LOperand* context = UseFixed(instr->context(), cp);
1707 LOperand* object = UseFixed(instr->object(), x1); 1706 LOperand* object = UseFixed(instr->object(), x1);
1708 LOperand* key = UseFixed(instr->key(), x0); 1707 LOperand* key = UseFixed(instr->key(), x0);
1709 1708
1710 LInstruction* result = 1709 LInstruction* result =
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 } 1877 }
1879 1878
1880 1879
1881 LInstruction* LChunkBuilder::DoMul(HMul* instr) { 1880 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1882 if (instr->representation().IsSmiOrInteger32()) { 1881 if (instr->representation().IsSmiOrInteger32()) {
1883 ASSERT(instr->left()->representation().Equals(instr->representation())); 1882 ASSERT(instr->left()->representation().Equals(instr->representation()));
1884 ASSERT(instr->right()->representation().Equals(instr->representation())); 1883 ASSERT(instr->right()->representation().Equals(instr->representation()));
1885 1884
1886 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); 1885 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
1887 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); 1886 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
1888 bool needs_environment = can_overflow || bailout_on_minus_zero;
1889 1887
1890 HValue* least_const = instr->BetterLeftOperand(); 1888 HValue* least_const = instr->BetterLeftOperand();
1891 HValue* most_const = instr->BetterRightOperand(); 1889 HValue* most_const = instr->BetterRightOperand();
1892 1890
1893 LOperand* left;
1894
1895 // LMulConstI can handle a subset of constants: 1891 // LMulConstI can handle a subset of constants:
1896 // With support for overflow detection: 1892 // With support for overflow detection:
1897 // -1, 0, 1, 2 1893 // -1, 0, 1, 2
1898 // 2^n, -(2^n) 1894 // 2^n, -(2^n)
1899 // Without support for overflow detection: 1895 // Without support for overflow detection:
1900 // 2^n + 1, -(2^n - 1) 1896 // 2^n + 1, -(2^n - 1)
1901 if (most_const->IsConstant()) { 1897 if (most_const->IsConstant()) {
1902 int32_t constant = HConstant::cast(most_const)->Integer32Value(); 1898 int32_t constant = HConstant::cast(most_const)->Integer32Value();
1903 bool small_constant = (constant >= -1) && (constant <= 2); 1899 bool small_constant = (constant >= -1) && (constant <= 2);
1904 bool end_range_constant = (constant <= -kMaxInt) || (constant == kMaxInt); 1900 bool end_range_constant = (constant <= -kMaxInt) || (constant == kMaxInt);
1905 int32_t constant_abs = Abs(constant); 1901 int32_t constant_abs = Abs(constant);
1906 1902
1907 if (!end_range_constant && 1903 if (!end_range_constant &&
1908 (small_constant || 1904 (small_constant ||
1909 (IsPowerOf2(constant_abs)) || 1905 (IsPowerOf2(constant_abs)) ||
1910 (!can_overflow && (IsPowerOf2(constant_abs + 1) || 1906 (!can_overflow && (IsPowerOf2(constant_abs + 1) ||
1911 IsPowerOf2(constant_abs - 1))))) { 1907 IsPowerOf2(constant_abs - 1))))) {
1912 LConstantOperand* right = UseConstant(most_const); 1908 LConstantOperand* right = UseConstant(most_const);
1913 bool need_register = IsPowerOf2(constant_abs) && !small_constant; 1909 bool need_register = IsPowerOf2(constant_abs) && !small_constant;
1914 left = need_register ? UseRegister(least_const) 1910 LOperand* left = need_register ? UseRegister(least_const)
1915 : UseRegisterAtStart(least_const); 1911 : UseRegisterAtStart(least_const);
1916 LMulConstIS* mul = new(zone()) LMulConstIS(left, right); 1912 LInstruction* result =
1917 if (needs_environment) AssignEnvironment(mul); 1913 DefineAsRegister(new(zone()) LMulConstIS(left, right));
1918 return DefineAsRegister(mul); 1914 if ((bailout_on_minus_zero && constant <= 0) || can_overflow) {
1915 result = AssignEnvironment(result);
1916 }
1917 return result;
1919 } 1918 }
1920 } 1919 }
1921 1920
1922 left = UseRegisterAtStart(least_const);
1923 // LMulI/S can handle all cases, but it requires that a register is 1921 // LMulI/S can handle all cases, but it requires that a register is
1924 // allocated for the second operand. 1922 // allocated for the second operand.
1925 LInstruction* result; 1923 LOperand* left = UseRegisterAtStart(least_const);
1926 if (instr->representation().IsSmi()) { 1924 LOperand* right = UseRegisterAtStart(most_const);
1927 LOperand* right = UseRegisterAtStart(most_const); 1925 LInstruction* result = instr->representation().IsSmi()
1928 result = DefineAsRegister(new(zone()) LMulS(left, right)); 1926 ? DefineAsRegister(new(zone()) LMulS(left, right))
1929 } else { 1927 : DefineAsRegister(new(zone()) LMulI(left, right));
1930 LOperand* right = UseRegisterAtStart(most_const); 1928 if ((bailout_on_minus_zero && least_const != most_const) || can_overflow) {
1931 result = DefineAsRegister(new(zone()) LMulI(left, right)); 1929 result = AssignEnvironment(result);
1932 } 1930 }
1933 if (needs_environment) AssignEnvironment(result);
1934 return result; 1931 return result;
1935 } else if (instr->representation().IsDouble()) { 1932 } else if (instr->representation().IsDouble()) {
1936 return DoArithmeticD(Token::MUL, instr); 1933 return DoArithmeticD(Token::MUL, instr);
1937 } else { 1934 } else {
1938 return DoArithmeticT(Token::MUL, instr); 1935 return DoArithmeticT(Token::MUL, instr);
1939 } 1936 }
1940 } 1937 }
1941 1938
1942 1939
1943 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { 1940 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
2153 if (instr->NeedsWriteBarrier()) { 2150 if (instr->NeedsWriteBarrier()) {
2154 // TODO(all): Replace these constraints when RecordWriteStub has been 2151 // TODO(all): Replace these constraints when RecordWriteStub has been
2155 // rewritten. 2152 // rewritten.
2156 context = UseRegisterAndClobber(instr->context()); 2153 context = UseRegisterAndClobber(instr->context());
2157 value = UseRegisterAndClobber(instr->value()); 2154 value = UseRegisterAndClobber(instr->value());
2158 } else { 2155 } else {
2159 context = UseRegister(instr->context()); 2156 context = UseRegister(instr->context());
2160 value = UseRegister(instr->value()); 2157 value = UseRegister(instr->value());
2161 } 2158 }
2162 LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp); 2159 LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp);
2163 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; 2160 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2161 result = AssignEnvironment(result);
2162 }
2163 return result;
2164 } 2164 }
2165 2165
2166 2166
2167 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { 2167 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
2168 LOperand* value = UseRegister(instr->value()); 2168 LOperand* value = UseRegister(instr->value());
2169 if (instr->RequiresHoleCheck()) { 2169 if (instr->RequiresHoleCheck()) {
2170 return AssignEnvironment(new(zone()) LStoreGlobalCell(value, 2170 return AssignEnvironment(new(zone()) LStoreGlobalCell(value,
2171 TempRegister(), 2171 TempRegister(),
2172 TempRegister())); 2172 TempRegister()));
2173 } else { 2173 } else {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 return MarkAsCall(DefineFixed(result, x0), instr); 2287 return MarkAsCall(DefineFixed(result, x0), instr);
2288 } 2288 }
2289 2289
2290 2290
2291 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { 2291 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2292 LOperand* string = UseRegisterAndClobber(instr->string()); 2292 LOperand* string = UseRegisterAndClobber(instr->string());
2293 LOperand* index = UseRegisterAndClobber(instr->index()); 2293 LOperand* index = UseRegisterAndClobber(instr->index());
2294 LOperand* context = UseAny(instr->context()); 2294 LOperand* context = UseAny(instr->context());
2295 LStringCharCodeAt* result = 2295 LStringCharCodeAt* result =
2296 new(zone()) LStringCharCodeAt(context, string, index); 2296 new(zone()) LStringCharCodeAt(context, string, index);
2297 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 2297 return AssignPointerMap(DefineAsRegister(result));
2298 } 2298 }
2299 2299
2300 2300
2301 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { 2301 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2302 LOperand* char_code = UseRegister(instr->value()); 2302 LOperand* char_code = UseRegister(instr->value());
2303 LOperand* context = UseAny(instr->context()); 2303 LOperand* context = UseAny(instr->context());
2304 LStringCharFromCode* result = 2304 LStringCharFromCode* result =
2305 new(zone()) LStringCharFromCode(context, char_code); 2305 new(zone()) LStringCharFromCode(context, char_code);
2306 return AssignPointerMap(DefineAsRegister(result)); 2306 return AssignPointerMap(DefineAsRegister(result));
2307 } 2307 }
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2423 case kMathAbs: { 2423 case kMathAbs: {
2424 Representation r = instr->representation(); 2424 Representation r = instr->representation();
2425 if (r.IsTagged()) { 2425 if (r.IsTagged()) {
2426 // The tagged case might need to allocate a HeapNumber for the result, 2426 // The tagged case might need to allocate a HeapNumber for the result,
2427 // so it is handled by a separate LInstruction. 2427 // so it is handled by a separate LInstruction.
2428 LOperand* context = UseFixed(instr->context(), cp); 2428 LOperand* context = UseFixed(instr->context(), cp);
2429 LOperand* input = UseRegister(instr->value()); 2429 LOperand* input = UseRegister(instr->value());
2430 LOperand* temp1 = TempRegister(); 2430 LOperand* temp1 = TempRegister();
2431 LOperand* temp2 = TempRegister(); 2431 LOperand* temp2 = TempRegister();
2432 LOperand* temp3 = TempRegister(); 2432 LOperand* temp3 = TempRegister();
2433 LMathAbsTagged* result = 2433 LInstruction* result = DefineAsRegister(
2434 new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3); 2434 new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3));
2435 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 2435 // Note: Only deopts in deferred code.
2436 return AssignEnvironment(AssignPointerMap(result));
2436 } else { 2437 } else {
2437 LOperand* input = UseRegisterAtStart(instr->value()); 2438 LOperand* input = UseRegisterAtStart(instr->value());
2438 LMathAbs* result = new(zone()) LMathAbs(input); 2439 LInstruction* result = DefineAsRegister(new(zone()) LMathAbs(input));
2439 if (r.IsDouble()) { 2440 if (!r.IsDouble()) result = AssignEnvironment(result);
2440 // The Double case can never fail so it doesn't need an environment. 2441 return result;
2441 return DefineAsRegister(result);
2442 } else {
2443 ASSERT(r.IsInteger32() || r.IsSmi());
2444 // The Integer32 and Smi cases need an environment because they can
2445 // deoptimize on minimum representable number.
2446 return AssignEnvironment(DefineAsRegister(result));
2447 }
2448 } 2442 }
2449 } 2443 }
2450 case kMathExp: { 2444 case kMathExp: {
2451 ASSERT(instr->representation().IsDouble()); 2445 ASSERT(instr->representation().IsDouble());
2452 ASSERT(instr->value()->representation().IsDouble()); 2446 ASSERT(instr->value()->representation().IsDouble());
2453 LOperand* input = UseRegister(instr->value()); 2447 LOperand* input = UseRegister(instr->value());
2454 // TODO(all): Implement TempFPRegister. 2448 // TODO(all): Implement TempFPRegister.
2455 LOperand* double_temp1 = FixedTemp(d24); // This was chosen arbitrarily. 2449 LOperand* double_temp1 = FixedTemp(d24); // This was chosen arbitrarily.
2456 LOperand* temp1 = TempRegister(); 2450 LOperand* temp1 = TempRegister();
2457 LOperand* temp2 = TempRegister(); 2451 LOperand* temp2 = TempRegister();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2570 2564
2571 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { 2565 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
2572 LOperand* receiver = UseRegister(instr->receiver()); 2566 LOperand* receiver = UseRegister(instr->receiver());
2573 LOperand* function = UseRegister(instr->function()); 2567 LOperand* function = UseRegister(instr->function());
2574 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); 2568 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function);
2575 return AssignEnvironment(DefineAsRegister(result)); 2569 return AssignEnvironment(DefineAsRegister(result));
2576 } 2570 }
2577 2571
2578 2572
2579 } } // namespace v8::internal 2573 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm64/lithium-arm64.h ('k') | src/ia32/lithium-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698