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

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

Issue 12041005: Optimize loads and stores to Int32Array and Uint32Array. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 Register result = locs()->out().reg(); 1084 Register result = locs()->out().reg();
1085 __ movl(result, 1085 __ movl(result,
1086 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); 1086 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
1087 __ movl(result, Address(result, 1087 __ movl(result, Address(result,
1088 char_code, 1088 char_code,
1089 TIMES_HALF_WORD_SIZE, // Char code is a smi. 1089 TIMES_HALF_WORD_SIZE, // Char code is a smi.
1090 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 1090 Symbols::kNullCharCodeSymbolOffset * kWordSize));
1091 } 1091 }
1092 1092
1093 1093
1094 intptr_t LoadIndexedInstr::ResultCid() const {
1095 switch (class_id_) {
1096 case kArrayCid:
1097 case kImmutableArrayCid:
1098 return kDynamicCid;
1099 case kFloat32ArrayCid :
1100 case kFloat64ArrayCid :
1101 return kDoubleCid;
1102 case kInt8ArrayCid:
1103 case kUint8ArrayCid:
1104 case kUint8ClampedArrayCid:
1105 case kExternalUint8ArrayCid:
1106 case kInt16ArrayCid:
1107 case kUint16ArrayCid:
1108 case kOneByteStringCid:
1109 case kTwoByteStringCid:
1110 return kSmiCid;
1111 case kInt32ArrayCid:
1112 case kUint32ArrayCid:
1113 // Result can be smi or mint when boxed.
1114 return kDynamicCid;
1115 default:
1116 UNIMPLEMENTED();
1117 return kDynamicCid;
1118 }
1119 }
1120
1121
1122 Representation LoadIndexedInstr::representation() const {
1123 switch (class_id_) {
1124 case kArrayCid:
1125 case kImmutableArrayCid:
1126 case kInt8ArrayCid:
1127 case kUint8ArrayCid:
1128 case kUint8ClampedArrayCid:
1129 case kExternalUint8ArrayCid:
1130 case kInt16ArrayCid:
1131 case kUint16ArrayCid:
1132 case kOneByteStringCid:
1133 case kTwoByteStringCid:
1134 return kTagged;
1135 case kInt32ArrayCid:
1136 case kUint32ArrayCid:
1137 return kUnboxedMint;
1138 case kFloat32ArrayCid :
1139 case kFloat64ArrayCid :
1140 return kUnboxedDouble;
1141 default:
1142 UNIMPLEMENTED();
1143 return kTagged;
1144 }
1145 }
1146
1147
1094 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { 1148 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
1095 const intptr_t kNumInputs = 2; 1149 const intptr_t kNumInputs = 2;
1096 const intptr_t kNumTemps = 0; 1150 const intptr_t kNumTemps = 0;
1097 LocationSummary* locs = 1151 LocationSummary* locs =
1098 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1152 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1099 locs->set_in(0, Location::RequiresRegister()); 1153 locs->set_in(0, Location::RequiresRegister());
1100 // The smi index is either untagged and tagged again at the end of the 1154 // The smi index is either untagged and tagged again at the end of the
1101 // operation (element size == 1), or it is left smi tagged (for all element 1155 // operation (element size == 1), or it is left smi tagged (for all element
1102 // sizes > 1). 1156 // sizes > 1).
1103 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 1157 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 } 1191 }
1138 return; 1192 return;
1139 } 1193 }
1140 1194
1141 FieldAddress element_address = index.IsRegister() 1195 FieldAddress element_address = index.IsRegister()
1142 ? FlowGraphCompiler::ElementAddressForRegIndex( 1196 ? FlowGraphCompiler::ElementAddressForRegIndex(
1143 class_id(), array, index.reg()) 1197 class_id(), array, index.reg())
1144 : FlowGraphCompiler::ElementAddressForIntIndex( 1198 : FlowGraphCompiler::ElementAddressForIntIndex(
1145 class_id(), array, Smi::Cast(index.constant()).Value()); 1199 class_id(), array, Smi::Cast(index.constant()).Value());
1146 1200
1147 if (representation() == kUnboxedDouble) { 1201 if (representation() == kUnboxedDouble ||
Kevin Millikin (Google) 2013/01/21 15:16:01 I guess you need more parens.
Florian Schneider 2013/01/21 16:03:25 Done.
1202 representation() == kUnboxedMint) {
1148 XmmRegister result = locs()->out().fpu_reg(); 1203 XmmRegister result = locs()->out().fpu_reg();
1149 if (class_id() == kFloat32ArrayCid) { 1204 switch (class_id()) {
1150 // Load single precision float. 1205 case kInt32ArrayCid:
1151 __ movss(result, element_address); 1206 __ movss(result, element_address);
1152 // Promote to double. 1207 __ pmovsxdq(result, result);
1153 __ cvtss2sd(result, locs()->out().fpu_reg()); 1208 break;
1154 } else { 1209 case kUint32ArrayCid:
1155 ASSERT(class_id() == kFloat64ArrayCid); 1210 __ xorpd(result, result);
1156 __ movsd(result, element_address); 1211 __ movss(result, element_address);
1212 break;
1213 case kFloat32ArrayCid:
1214 // Load single precision float and promote to double.
1215 __ movss(result, element_address);
1216 __ cvtss2sd(result, locs()->out().fpu_reg());
1217 break;
1218 case kFloat64ArrayCid:
1219 __ movsd(result, element_address);
1220 break;
1157 } 1221 }
1158 return; 1222 return;
1159 } 1223 }
1160 1224
1161 Register result = locs()->out().reg(); 1225 Register result = locs()->out().reg();
1162 switch (class_id()) { 1226 switch (class_id()) {
1163 case kInt8ArrayCid: 1227 case kInt8ArrayCid:
1164 case kUint8ArrayCid: 1228 case kUint8ArrayCid:
1165 case kUint8ClampedArrayCid: 1229 case kUint8ClampedArrayCid:
1166 case kOneByteStringCid: 1230 case kOneByteStringCid:
(...skipping 20 matching lines...) Expand all
1187 __ SmiTag(result); 1251 __ SmiTag(result);
1188 break; 1252 break;
1189 default: 1253 default:
1190 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1254 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1191 __ movl(result, element_address); 1255 __ movl(result, element_address);
1192 break; 1256 break;
1193 } 1257 }
1194 } 1258 }
1195 1259
1196 1260
1261 Representation StoreIndexedInstr::RequiredInputRepresentation(
1262 intptr_t idx) const {
1263 if ((idx == 0) || (idx == 1)) return kTagged;
1264 ASSERT(idx == 2);
1265 switch (class_id_) {
1266 case kArrayCid:
1267 case kInt8ArrayCid:
1268 case kUint8ArrayCid:
1269 case kUint8ClampedArrayCid:
1270 case kInt16ArrayCid:
1271 case kUint16ArrayCid:
1272 return kTagged;
1273 case kInt32ArrayCid:
1274 case kUint32ArrayCid:
1275 return kUnboxedMint;
1276 case kFloat32ArrayCid :
1277 case kFloat64ArrayCid :
1278 return kUnboxedDouble;
1279 default:
1280 UNIMPLEMENTED();
1281 return kTagged;
1282 }
1283 }
1284
1285
1197 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 1286 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
1198 const intptr_t kNumInputs = 3; 1287 const intptr_t kNumInputs = 3;
1199 const intptr_t kNumTemps = 0; 1288 const intptr_t kNumTemps = 0;
1200 LocationSummary* locs = 1289 LocationSummary* locs =
1201 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1290 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1202 locs->set_in(0, Location::RequiresRegister()); 1291 locs->set_in(0, Location::RequiresRegister());
1203 // The smi index is either untagged and tagged again at the end of the 1292 // The smi index is either untagged and tagged again at the end of the
1204 // operation (element size == 1), or it is left smi tagged (for all element 1293 // operation (element size == 1), or it is left smi tagged (for all element
1205 // sizes > 1). 1294 // sizes > 1).
1206 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 1295 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
(...skipping 14 matching lines...) Expand all
1221 break; 1310 break;
1222 case kInt16ArrayCid: 1311 case kInt16ArrayCid:
1223 case kUint16ArrayCid: 1312 case kUint16ArrayCid:
1224 // Writable register because the value must be untagged before storing. 1313 // Writable register because the value must be untagged before storing.
1225 locs->set_in(2, Location::WritableRegister()); 1314 locs->set_in(2, Location::WritableRegister());
1226 break; 1315 break;
1227 case kFloat32ArrayCid: 1316 case kFloat32ArrayCid:
1228 // Need temp register for float-to-double conversion. 1317 // Need temp register for float-to-double conversion.
1229 locs->AddTemp(Location::RequiresFpuRegister()); 1318 locs->AddTemp(Location::RequiresFpuRegister());
1230 // Fall through. 1319 // Fall through.
1320 case kInt32ArrayCid:
1321 case kUint32ArrayCid:
1231 case kFloat64ArrayCid: 1322 case kFloat64ArrayCid:
1232 // TODO(srdjan): Support Float64 constants. 1323 // TODO(srdjan): Support Float64 constants.
1233 locs->set_in(2, Location::RequiresFpuRegister()); 1324 locs->set_in(2, Location::RequiresFpuRegister());
1234 break; 1325 break;
1235 default: 1326 default:
1236 UNREACHABLE(); 1327 UNREACHABLE();
1237 return NULL; 1328 return NULL;
1238 } 1329 }
1239 return locs; 1330 return locs;
1240 } 1331 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 __ Bind(&store_value); 1402 __ Bind(&store_value);
1312 __ movb(element_address, AL); 1403 __ movb(element_address, AL);
1313 } 1404 }
1314 if (index.IsRegister()) { 1405 if (index.IsRegister()) {
1315 __ SmiTag(index.reg()); // Re-tag. 1406 __ SmiTag(index.reg()); // Re-tag.
1316 } 1407 }
1317 break; 1408 break;
1318 } 1409 }
1319 case kInt16ArrayCid: 1410 case kInt16ArrayCid:
1320 case kUint16ArrayCid: { 1411 case kUint16ArrayCid: {
1321 Register value = locs()->in(2).reg(); 1412 Register value = locs()->in(2).reg();
1322 __ SmiUntag(value); 1413 __ SmiUntag(value);
1323 __ movw(element_address, value); 1414 __ movw(element_address, value);
1324 break; 1415 break;
1325 } 1416 }
1417 case kInt32ArrayCid:
1418 case kUint32ArrayCid:
1419 __ movss(element_address, locs()->in(2).fpu_reg());
1420 break;
1326 case kFloat32ArrayCid: 1421 case kFloat32ArrayCid:
1327 // Convert to single precision. 1422 // Convert to single precision.
1328 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); 1423 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
1329 // Store. 1424 // Store.
1330 __ movss(element_address, locs()->temp(0).fpu_reg()); 1425 __ movss(element_address, locs()->temp(0).fpu_reg());
1331 break; 1426 break;
1332 case kFloat64ArrayCid: 1427 case kFloat64ArrayCid:
1333 __ movsd(element_address, locs()->in(2).fpu_reg()); 1428 __ movsd(element_address, locs()->in(2).fpu_reg());
1334 break; 1429 break;
1335 default: 1430 default:
(...skipping 1879 matching lines...) Expand 10 before | Expand all | Expand 10 after
3215 PcDescriptors::kOther, 3310 PcDescriptors::kOther,
3216 locs()); 3311 locs());
3217 __ Drop(2); // Discard type arguments and receiver. 3312 __ Drop(2); // Discard type arguments and receiver.
3218 } 3313 }
3219 3314
3220 } // namespace dart 3315 } // namespace dart
3221 3316
3222 #undef __ 3317 #undef __
3223 3318
3224 #endif // defined TARGET_ARCH_IA32 3319 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698