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

Side by Side Diff: runtime/vm/intermediate_language_x64.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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 Register result = locs()->out().reg(); 948 Register result = locs()->out().reg();
949 __ movq(result, 949 __ movq(result,
950 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress()))); 950 Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
951 __ movq(result, Address(result, 951 __ movq(result, Address(result,
952 char_code, 952 char_code,
953 TIMES_HALF_WORD_SIZE, // Char code is a smi. 953 TIMES_HALF_WORD_SIZE, // Char code is a smi.
954 Symbols::kNullCharCodeSymbolOffset * kWordSize)); 954 Symbols::kNullCharCodeSymbolOffset * kWordSize));
955 } 955 }
956 956
957 957
958 intptr_t LoadIndexedInstr::ResultCid() const {
959 switch (class_id_) {
960 case kArrayCid:
961 case kImmutableArrayCid:
962 return kDynamicCid;
963 case kFloat32ArrayCid :
964 case kFloat64ArrayCid :
965 return kDoubleCid;
966 case kInt8ArrayCid:
967 case kUint8ArrayCid:
968 case kUint8ClampedArrayCid:
969 case kExternalUint8ArrayCid:
970 case kInt16ArrayCid:
971 case kUint16ArrayCid:
972 case kOneByteStringCid:
973 case kTwoByteStringCid:
974 case kInt32ArrayCid:
975 case kUint32ArrayCid:
976 return kSmiCid;
977
978 default:
979 UNIMPLEMENTED();
980 return kSmiCid;
981 }
982 }
983
984
985 Representation LoadIndexedInstr::representation() const {
986 switch (class_id_) {
987 case kArrayCid:
988 case kImmutableArrayCid:
989 case kInt8ArrayCid:
990 case kUint8ArrayCid:
991 case kUint8ClampedArrayCid:
992 case kExternalUint8ArrayCid:
993 case kInt16ArrayCid:
994 case kUint16ArrayCid:
995 case kOneByteStringCid:
996 case kTwoByteStringCid:
997 case kInt32ArrayCid:
998 case kUint32ArrayCid:
999 return kTagged;
1000 case kFloat32ArrayCid :
1001 case kFloat64ArrayCid :
1002 return kUnboxedDouble;
1003 default:
1004 UNIMPLEMENTED();
1005 return kTagged;
1006 }
1007 }
1008
1009
958 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { 1010 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
959 const intptr_t kNumInputs = 2; 1011 const intptr_t kNumInputs = 2;
960 const intptr_t kNumTemps = 0; 1012 const intptr_t kNumTemps = 0;
961 LocationSummary* locs = 1013 LocationSummary* locs =
962 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1014 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
963 locs->set_in(0, Location::RequiresRegister()); 1015 locs->set_in(0, Location::RequiresRegister());
964 // The smi index is either untagged and tagged again at the end of the 1016 // The smi index is either untagged and tagged again at the end of the
965 // operation (element size == 1), or it is left smi tagged (for all element 1017 // operation (element size == 1), or it is left smi tagged (for all element
966 // sizes > 1). 1018 // sizes > 1).
967 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 1019 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 break; 1095 break;
1044 case kInt16ArrayCid: 1096 case kInt16ArrayCid:
1045 __ movsxw(result, element_address); 1097 __ movsxw(result, element_address);
1046 __ SmiTag(result); 1098 __ SmiTag(result);
1047 break; 1099 break;
1048 case kUint16ArrayCid: 1100 case kUint16ArrayCid:
1049 case kTwoByteStringCid: 1101 case kTwoByteStringCid:
1050 __ movzxw(result, element_address); 1102 __ movzxw(result, element_address);
1051 __ SmiTag(result); 1103 __ SmiTag(result);
1052 break; 1104 break;
1105 case kInt32ArrayCid:
1106 __ movsxl(result, element_address);
1107 __ SmiTag(result);
1108 break;
1109 case kUint32ArrayCid:
1110 __ movl(result, element_address);
1111 __ SmiTag(result);
1112 break;
1053 default: 1113 default:
1054 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1114 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1055 __ movq(result, element_address); 1115 __ movq(result, element_address);
1056 break; 1116 break;
1057 } 1117 }
1058 } 1118 }
1059 1119
1060 1120
1121 Representation StoreIndexedInstr::RequiredInputRepresentation(
1122 intptr_t idx) const {
1123 if ((idx == 0) || (idx == 1)) return kTagged;
1124 ASSERT(idx == 2);
1125 switch (class_id_) {
1126 case kArrayCid:
1127 case kInt8ArrayCid:
1128 case kUint8ArrayCid:
1129 case kUint8ClampedArrayCid:
1130 case kInt16ArrayCid:
1131 case kUint16ArrayCid:
1132 case kInt32ArrayCid:
1133 case kUint32ArrayCid:
1134 return kTagged;
1135 case kFloat32ArrayCid :
1136 case kFloat64ArrayCid :
1137 return kUnboxedDouble;
1138 default:
1139 UNIMPLEMENTED();
1140 return kTagged;
1141 }
1142 }
1143
1144
1061 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 1145 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
1062 const intptr_t kNumInputs = 3; 1146 const intptr_t kNumInputs = 3;
1063 const intptr_t kNumTemps = 0; 1147 const intptr_t kNumTemps = 0;
1064 LocationSummary* locs = 1148 LocationSummary* locs =
1065 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1149 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1066 // The smi index is either untagged and tagged again at the end of the 1150 // The smi index is either untagged and tagged again at the end of the
1067 // operation (element size == 1), or it is left smi tagged (for all element 1151 // operation (element size == 1), or it is left smi tagged (for all element
1068 // sizes > 1). 1152 // sizes > 1).
1069 locs->set_in(0, Location::RequiresRegister()); 1153 locs->set_in(0, Location::RequiresRegister());
1070 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) 1154 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
1071 ? Location::RegisterOrSmiConstant(index()) 1155 ? Location::RegisterOrSmiConstant(index())
1072 : Location::RequiresRegister()); 1156 : Location::RequiresRegister());
1073 switch (class_id()) { 1157 switch (class_id()) {
1074 case kArrayCid: 1158 case kArrayCid:
1075 locs->set_in(2, ShouldEmitStoreBarrier() 1159 locs->set_in(2, ShouldEmitStoreBarrier()
1076 ? Location::WritableRegister() 1160 ? Location::WritableRegister()
1077 : Location::RegisterOrConstant(value())); 1161 : Location::RegisterOrConstant(value()));
1078 break; 1162 break;
1079 case kInt8ArrayCid: 1163 case kInt8ArrayCid:
1080 case kUint8ArrayCid: 1164 case kUint8ArrayCid:
1081 case kUint8ClampedArrayCid: 1165 case kUint8ClampedArrayCid:
1082 // TODO(fschneider): Add location constraint for byte registers (RAX, 1166 // TODO(fschneider): Add location constraint for byte registers (RAX,
1083 // RBX, RCX, RDX) instead of using a fixed register. 1167 // RBX, RCX, RDX) instead of using a fixed register.
1084 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX)); 1168 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), RAX));
1085 break; 1169 break;
1086 case kInt16ArrayCid: 1170 case kInt16ArrayCid:
1087 case kUint16ArrayCid: 1171 case kUint16ArrayCid:
1172 case kInt32ArrayCid:
1173 case kUint32ArrayCid:
1088 // Writable register because the value must be untagged before storing. 1174 // Writable register because the value must be untagged before storing.
1089 locs->set_in(2, Location::WritableRegister()); 1175 locs->set_in(2, Location::WritableRegister());
1090 break; 1176 break;
1091 case kFloat32ArrayCid: 1177 case kFloat32ArrayCid:
1092 // Need temp register for float-to-double conversion. 1178 // Need temp register for float-to-double conversion.
1093 locs->AddTemp(Location::RequiresFpuRegister()); 1179 locs->AddTemp(Location::RequiresFpuRegister());
1094 // Fall through. 1180 // Fall through.
1095 case kFloat64ArrayCid: 1181 case kFloat64ArrayCid:
1096 // TODO(srdjan): Support Float64 constants. 1182 // TODO(srdjan): Support Float64 constants.
1097 locs->set_in(2, Location::RequiresFpuRegister()); 1183 locs->set_in(2, Location::RequiresFpuRegister());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 __ Bind(&store_value); 1261 __ Bind(&store_value);
1176 __ movb(element_address, RAX); 1262 __ movb(element_address, RAX);
1177 } 1263 }
1178 if (index.IsRegister()) { 1264 if (index.IsRegister()) {
1179 __ SmiTag(index.reg()); // Re-tag. 1265 __ SmiTag(index.reg()); // Re-tag.
1180 } 1266 }
1181 break; 1267 break;
1182 } 1268 }
1183 case kInt16ArrayCid: 1269 case kInt16ArrayCid:
1184 case kUint16ArrayCid: { 1270 case kUint16ArrayCid: {
1185 Register value = locs()->in(2).reg(); 1271 Register value = locs()->in(2).reg();
1186 __ SmiUntag(value); 1272 __ SmiUntag(value);
1187 __ movw(element_address, value); 1273 __ movw(element_address, value);
1274 break;
1275 }
1276 case kInt32ArrayCid:
1277 case kUint32ArrayCid: {
1278 Register value = locs()->in(2).reg();
1279 __ SmiUntag(value);
1280 __ movl(element_address, value);
1188 break; 1281 break;
1189 } 1282 }
1190 case kFloat32ArrayCid: 1283 case kFloat32ArrayCid:
1191 // Convert to single precision. 1284 // Convert to single precision.
1192 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg()); 1285 __ cvtsd2ss(locs()->temp(0).fpu_reg(), locs()->in(2).fpu_reg());
1193 // Store. 1286 // Store.
1194 __ movss(element_address, locs()->temp(0).fpu_reg()); 1287 __ movss(element_address, locs()->temp(0).fpu_reg());
1195 break; 1288 break;
1196 case kFloat64ArrayCid: 1289 case kFloat64ArrayCid:
1197 __ movsd(element_address, locs()->in(2).fpu_reg()); 1290 __ movsd(element_address, locs()->in(2).fpu_reg());
1198 break; 1291 break;
1199 default: 1292 default:
(...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after
2859 PcDescriptors::kOther, 2952 PcDescriptors::kOther,
2860 locs()); 2953 locs());
2861 __ Drop(2); // Discard type arguments and receiver. 2954 __ Drop(2); // Discard type arguments and receiver.
2862 } 2955 }
2863 2956
2864 } // namespace dart 2957 } // namespace dart
2865 2958
2866 #undef __ 2959 #undef __
2867 2960
2868 #endif // defined TARGET_ARCH_X64 2961 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/intermediate_language_ia32.cc ('K') | « runtime/vm/intermediate_language_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698