Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 998 | 998 |
| 999 void TraceGVN(const char* msg, ...) { | 999 void TraceGVN(const char* msg, ...) { |
| 1000 if (FLAG_trace_gvn) { | 1000 if (FLAG_trace_gvn) { |
| 1001 va_list arguments; | 1001 va_list arguments; |
| 1002 va_start(arguments, msg); | 1002 va_start(arguments, msg); |
| 1003 OS::VPrint(msg, arguments); | 1003 OS::VPrint(msg, arguments); |
| 1004 va_end(arguments); | 1004 va_end(arguments); |
| 1005 } | 1005 } |
| 1006 } | 1006 } |
| 1007 | 1007 |
| 1008 class HEffectSet: public ZoneObject { | |
| 1009 public: | |
| 1010 HEffectSet() : parameters_(0) { | |
|
fschneider
2011/03/16 15:43:28
Since Initialize() also initializes paramters_, th
| |
| 1011 Initialize(); | |
| 1012 } | |
| 1013 | |
| 1014 explicit HEffectSet(int flags) : parameters_(0) { | |
|
fschneider
2011/03/16 15:43:28
Same here.
| |
| 1015 Initialize(); | |
| 1016 AddFlags(flags); | |
| 1017 } | |
| 1018 | |
| 1019 void Initialize() { | |
| 1020 flags_ = 0; | |
| 1021 flags_without_parameters_ = 0; | |
| 1022 parameters_.Initialize(0); | |
| 1023 } | |
| 1024 | |
| 1025 void Add(HValue* value) { | |
| 1026 int flags = value->flags() & HValue::ChangesFlagsMask(); | |
| 1027 if (flags == 0) return; | |
| 1028 if (value->CheckFlag(HValue::kHasGVNParameter)) { | |
| 1029 AddWithParameter(flags, value->GetGVNParameter()); | |
| 1030 } else { | |
| 1031 AddWithoutParameter(flags); | |
| 1032 } | |
| 1033 } | |
| 1034 | |
| 1035 void AddAll(const HEffectSet& other) { | |
| 1036 flags_ |= other.flags_; | |
| 1037 flags_without_parameters_ |= other.flags_without_parameters_; | |
| 1038 for (int i = 0; i < other.parameters_.length(); i++) { | |
| 1039 int flag = i << 1; | |
|
fschneider
2011/03/16 15:43:28
You could move this line to after the continue.
| |
| 1040 if (other.parameters_[i] == NULL) continue; | |
| 1041 for (int j = 0; j < other.parameters_[i]->length(); j++) { | |
| 1042 InternalAddWithParameter(flag, other.parameters_[i]->at(j)); | |
| 1043 } | |
| 1044 } | |
| 1045 } | |
| 1046 | |
| 1047 bool HasEffectOnAny(int depends_flags) const { | |
| 1048 return (HValue::ConvertDependsToChangesFlags(depends_flags) & flags_) != 0; | |
| 1049 } | |
| 1050 | |
| 1051 bool HasEffectOn(HValue* value) const { | |
| 1052 ASSERT(value->CheckFlag(HValue::kUseGVN)); | |
| 1053 int affected_flags = | |
| 1054 HValue::ConvertDependsToChangesFlags(value->flags()) & flags_; | |
| 1055 if (affected_flags == 0) return false; | |
| 1056 if (!value->CheckFlag(HValue::kHasGVNParameter)) return true; | |
| 1057 if ((affected_flags & flags_without_parameters_) != 0) return true; | |
| 1058 // Only a single GVN flag can be set when we have a parameter | |
| 1059 // (with a possible exception of the special OsrEntries flag). | |
| 1060 affected_flags &= ~(1 << HValue::kChangesOsrEntries); | |
| 1061 ASSERT(IsPowerOf2(affected_flags)); | |
| 1062 for (int i = 0; i < parameters_.length(); i++) { | |
| 1063 int flag = i << 1; | |
| 1064 if (((1 << flag) & affected_flags) != 0) { | |
| 1065 if (parameters_[i] == NULL) return true; | |
| 1066 return parameters_[i]->Contains(value->GetGVNParameter()); | |
| 1067 } | |
| 1068 } | |
| 1069 return true; | |
| 1070 } | |
| 1071 | |
| 1072 int flags() const { return flags_; } | |
| 1073 | |
| 1074 private: | |
| 1075 typedef ZoneList<intptr_t> ParameterList; | |
| 1076 | |
| 1077 static const int kParameterListLengthLimit = 8; | |
| 1078 | |
| 1079 void AddWithoutParameter(int flags) { | |
| 1080 AddFlags(flags); | |
| 1081 flags_without_parameters_ |= flags; | |
| 1082 } | |
| 1083 | |
| 1084 void AddWithParameter(int flags, intptr_t parameter) { | |
| 1085 AddFlags(flags); | |
| 1086 if ((flags_without_parameters_ & flags) != 0) return; | |
| 1087 int flag = -1; | |
| 1088 for (int i = 0; i < HValue::kFirstNonGVNFlag; i += 2) { | |
| 1089 if ((flags & (1 << i)) != 0) { | |
| 1090 flag = i; | |
| 1091 break; | |
| 1092 } | |
| 1093 } | |
| 1094 ASSERT(flag != -1); | |
| 1095 ASSERT(flags == (1 << flag)); | |
| 1096 InternalAddWithParameter(flag, parameter); | |
| 1097 } | |
| 1098 | |
| 1099 void InternalAddWithParameter(int flag, intptr_t parameter) { | |
| 1100 int flag_index = flag >> 1; | |
| 1101 ASSERT(flag == (flag_index << 1)); | |
| 1102 if (parameters_.length() <= flag_index) { | |
|
fschneider
2011/03/16 15:43:28
I find (flag_index >= parameters_.length()) better
| |
| 1103 parameters_.AddBlock(NULL, flag_index - parameters_.length() + 1); | |
| 1104 } | |
| 1105 if (parameters_[flag_index] == NULL) { | |
| 1106 parameters_[flag_index] = new ParameterList(2); | |
| 1107 } else if (parameters_[flag_index]->Contains(parameter)) { | |
| 1108 return; | |
| 1109 } | |
| 1110 if (parameters_[flag_index]->length() == kParameterListLengthLimit) { | |
| 1111 // Too many parameters to track efficiently. | |
| 1112 parameters_[flag_index] = NULL; | |
| 1113 flags_without_parameters_ |= (1 << flag); | |
| 1114 return; | |
| 1115 } | |
| 1116 parameters_[flag_index]->Add(parameter); | |
| 1117 } | |
| 1118 | |
| 1119 void AddFlags(int flags) { | |
| 1120 ASSERT((flags & HValue::ChangesFlagsMask()) == flags); | |
| 1121 flags_ |= flags; | |
| 1122 } | |
| 1123 | |
| 1124 int flags_; | |
| 1125 int flags_without_parameters_; | |
| 1126 ZoneList<ParameterList*> parameters_; | |
| 1127 | |
| 1128 DISALLOW_COPY_AND_ASSIGN(HEffectSet); | |
| 1129 }; | |
| 1130 | |
| 1008 | 1131 |
| 1009 HValueMap::HValueMap(const HValueMap* other) | 1132 HValueMap::HValueMap(const HValueMap* other) |
| 1010 : array_size_(other->array_size_), | 1133 : array_size_(other->array_size_), |
| 1011 lists_size_(other->lists_size_), | 1134 lists_size_(other->lists_size_), |
| 1012 count_(other->count_), | 1135 count_(other->count_), |
| 1013 present_flags_(other->present_flags_), | 1136 present_flags_(other->present_flags_), |
| 1014 array_(Zone::NewArray<HValueMapListElement>(other->array_size_)), | 1137 array_(Zone::NewArray<HValueMapListElement>(other->array_size_)), |
| 1015 lists_(Zone::NewArray<HValueMapListElement>(other->lists_size_)), | 1138 lists_(Zone::NewArray<HValueMapListElement>(other->lists_size_)), |
| 1016 free_list_head_(other->free_list_head_) { | 1139 free_list_head_(other->free_list_head_) { |
| 1017 memcpy(array_, other->array_, array_size_ * sizeof(HValueMapListElement)); | 1140 memcpy(array_, other->array_, array_size_ * sizeof(HValueMapListElement)); |
| 1018 memcpy(lists_, other->lists_, lists_size_ * sizeof(HValueMapListElement)); | 1141 memcpy(lists_, other->lists_, lists_size_ * sizeof(HValueMapListElement)); |
| 1019 } | 1142 } |
| 1020 | 1143 |
| 1021 | 1144 |
| 1022 void HValueMap::Kill(int flags) { | 1145 void HValueMap::Kill(const HEffectSet& effects) { |
| 1023 int depends_flags = HValue::ConvertChangesToDependsFlags(flags); | 1146 if (!effects.HasEffectOnAny(present_flags_)) return; |
| 1024 if ((present_flags_ & depends_flags) == 0) return; | |
| 1025 present_flags_ = 0; | 1147 present_flags_ = 0; |
| 1026 for (int i = 0; i < array_size_; ++i) { | 1148 for (int i = 0; i < array_size_; ++i) { |
| 1027 HValue* value = array_[i].value; | 1149 HValue* value = array_[i].value; |
| 1028 if (value != NULL) { | 1150 if (value != NULL) { |
| 1029 // Clear list of collisions first, so we know if it becomes empty. | 1151 // Clear list of collisions first, so we know if it becomes empty. |
| 1030 int kept = kNil; // List of kept elements. | 1152 int kept = kNil; // List of kept elements. |
| 1031 int next; | 1153 int next; |
| 1032 for (int current = array_[i].next; current != kNil; current = next) { | 1154 for (int current = array_[i].next; current != kNil; current = next) { |
| 1033 next = lists_[current].next; | 1155 next = lists_[current].next; |
| 1034 if ((lists_[current].value->flags() & depends_flags) != 0) { | 1156 if (effects.HasEffectOn(lists_[current].value)) { |
| 1035 // Drop it. | 1157 // Drop it. |
| 1036 count_--; | 1158 count_--; |
| 1037 lists_[current].next = free_list_head_; | 1159 lists_[current].next = free_list_head_; |
| 1038 free_list_head_ = current; | 1160 free_list_head_ = current; |
| 1039 } else { | 1161 } else { |
| 1040 // Keep it. | 1162 // Keep it. |
| 1041 lists_[current].next = kept; | 1163 lists_[current].next = kept; |
| 1042 kept = current; | 1164 kept = current; |
| 1043 present_flags_ |= lists_[current].value->flags(); | 1165 present_flags_ |= lists_[current].value->flags(); |
| 1044 } | 1166 } |
| 1045 } | 1167 } |
| 1046 array_[i].next = kept; | 1168 array_[i].next = kept; |
| 1047 | 1169 |
| 1048 // Now possibly drop directly indexed element. | 1170 // Now possibly drop directly indexed element. |
| 1049 if ((array_[i].value->flags() & depends_flags) != 0) { // Drop it. | 1171 if (effects.HasEffectOn(array_[i].value)) { |
| 1050 count_--; | 1172 count_--; |
| 1051 int head = array_[i].next; | 1173 int head = array_[i].next; |
| 1052 if (head == kNil) { | 1174 if (head == kNil) { |
| 1053 array_[i].value = NULL; | 1175 array_[i].value = NULL; |
| 1054 } else { | 1176 } else { |
| 1055 array_[i].value = lists_[head].value; | 1177 array_[i].value = lists_[head].value; |
| 1056 array_[i].next = lists_[head].next; | 1178 array_[i].next = lists_[head].next; |
| 1057 lists_[head].next = free_list_head_; | 1179 lists_[head].next = free_list_head_; |
| 1058 free_list_head_ = head; | 1180 free_list_head_ = head; |
| 1059 } | 1181 } |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1220 HGoto::cast(instr)->set_include_stack_check(false); | 1342 HGoto::cast(instr)->set_include_stack_check(false); |
| 1221 return; | 1343 return; |
| 1222 } | 1344 } |
| 1223 instr = instr->next(); | 1345 instr = instr->next(); |
| 1224 } | 1346 } |
| 1225 } | 1347 } |
| 1226 | 1348 |
| 1227 | 1349 |
| 1228 class HGlobalValueNumberer BASE_EMBEDDED { | 1350 class HGlobalValueNumberer BASE_EMBEDDED { |
| 1229 public: | 1351 public: |
| 1230 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) | 1352 HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) |
| 1231 : graph_(graph), | 1353 : graph_(graph), info_(info) { |
| 1232 info_(info), | |
| 1233 block_side_effects_(graph_->blocks()->length()), | |
| 1234 loop_side_effects_(graph_->blocks()->length()) { | |
| 1235 ASSERT(Heap::allow_allocation(false)); | 1354 ASSERT(Heap::allow_allocation(false)); |
| 1236 block_side_effects_.AddBlock(0, graph_->blocks()->length()); | 1355 int length = graph_->blocks()->length(); |
| 1237 loop_side_effects_.AddBlock(0, graph_->blocks()->length()); | 1356 block_side_effects_ = Zone::NewArray<HEffectSet>(length); |
| 1357 loop_side_effects_ = Zone::NewArray<HEffectSet>(length); | |
| 1358 for (int i = 0; i < length; i++) { | |
| 1359 block_side_effects_[i].Initialize(); | |
| 1360 loop_side_effects_[i].Initialize(); | |
| 1361 } | |
| 1238 } | 1362 } |
| 1363 | |
| 1239 ~HGlobalValueNumberer() { | 1364 ~HGlobalValueNumberer() { |
| 1240 ASSERT(!Heap::allow_allocation(true)); | 1365 ASSERT(!Heap::allow_allocation(true)); |
| 1241 } | 1366 } |
| 1242 | 1367 |
| 1243 void Analyze(); | 1368 void Analyze(); |
| 1244 | 1369 |
| 1245 private: | 1370 private: |
| 1246 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); | 1371 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); |
| 1247 void ComputeBlockSideEffects(); | 1372 void ComputeBlockSideEffects(); |
| 1248 void LoopInvariantCodeMotion(); | 1373 void LoopInvariantCodeMotion(); |
| 1249 void ProcessLoopBlock(HBasicBlock* block, | 1374 void ProcessLoopBlock(HBasicBlock* block, |
| 1250 HBasicBlock* before_loop, | 1375 HBasicBlock* before_loop, |
| 1251 int loop_kills); | 1376 const HEffectSet& loop_effects); |
| 1252 bool AllowCodeMotion(); | 1377 bool AllowCodeMotion(); |
| 1253 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); | 1378 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); |
| 1254 | 1379 |
| 1255 HGraph* graph() { return graph_; } | 1380 HGraph* graph() { return graph_; } |
| 1256 CompilationInfo* info() { return info_; } | 1381 CompilationInfo* info() { return info_; } |
| 1257 | 1382 |
| 1258 HGraph* graph_; | 1383 HGraph* graph_; |
| 1259 CompilationInfo* info_; | 1384 CompilationInfo* info_; |
| 1260 | 1385 |
| 1261 // A map of block IDs to their side effects. | 1386 // An array mapping block IDs to their side effects. |
| 1262 ZoneList<int> block_side_effects_; | 1387 HEffectSet* block_side_effects_; |
| 1263 | 1388 |
| 1264 // A map of loop header block IDs to their loop's side effects. | 1389 // An array mapping loop header block IDs to their loop's side effects. |
| 1265 ZoneList<int> loop_side_effects_; | 1390 HEffectSet* loop_side_effects_; |
| 1266 }; | 1391 }; |
| 1267 | 1392 |
| 1268 | 1393 |
| 1269 void HGlobalValueNumberer::Analyze() { | 1394 void HGlobalValueNumberer::Analyze() { |
| 1270 ComputeBlockSideEffects(); | 1395 ComputeBlockSideEffects(); |
| 1271 if (FLAG_loop_invariant_code_motion) { | 1396 if (FLAG_loop_invariant_code_motion) { |
| 1272 LoopInvariantCodeMotion(); | 1397 LoopInvariantCodeMotion(); |
| 1273 } | 1398 } |
| 1274 HValueMap* map = new HValueMap(); | 1399 HValueMap* map = new HValueMap(); |
| 1275 AnalyzeBlock(graph_->blocks()->at(0), map); | 1400 AnalyzeBlock(graph_->blocks()->at(0), map); |
| 1276 } | 1401 } |
| 1277 | 1402 |
| 1278 | 1403 |
| 1279 void HGlobalValueNumberer::ComputeBlockSideEffects() { | 1404 void HGlobalValueNumberer::ComputeBlockSideEffects() { |
| 1280 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { | 1405 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { |
| 1281 // Compute side effects for the block. | 1406 // Compute side effects for the block. |
| 1282 HBasicBlock* block = graph_->blocks()->at(i); | 1407 HBasicBlock* block = graph_->blocks()->at(i); |
| 1283 HInstruction* instr = block->first(); | 1408 HInstruction* instr = block->first(); |
| 1284 int id = block->block_id(); | 1409 int id = block->block_id(); |
| 1285 int side_effects = 0; | 1410 HEffectSet* block_effects = &block_side_effects_[id]; |
| 1286 while (instr != NULL) { | |
| 1287 side_effects |= (instr->flags() & HValue::ChangesFlagsMask()); | |
| 1288 instr = instr->next(); | |
| 1289 } | |
| 1290 block_side_effects_[id] |= side_effects; | |
| 1291 | 1411 |
| 1292 // Loop headers are part of their loop. | 1412 // Loop headers are part of their loop. |
| 1293 if (block->IsLoopHeader()) { | 1413 HEffectSet* loop_effects = |
| 1294 loop_side_effects_[id] |= side_effects; | 1414 block->IsLoopHeader() ? &loop_side_effects_[id] : NULL; |
| 1415 | |
| 1416 while (instr != NULL) { | |
| 1417 block_effects->Add(instr); | |
| 1418 if (loop_effects != NULL) loop_effects->Add(instr); | |
| 1419 instr = instr->next(); | |
| 1295 } | 1420 } |
| 1296 | 1421 |
| 1297 // Propagate loop side effects upwards. | 1422 // Propagate loop side effects upwards. |
| 1298 if (block->HasParentLoopHeader()) { | 1423 if (block->HasParentLoopHeader()) { |
| 1299 int header_id = block->parent_loop_header()->block_id(); | 1424 int header_id = block->parent_loop_header()->block_id(); |
| 1300 loop_side_effects_[header_id] |= | 1425 loop_side_effects_[header_id].AddAll( |
| 1301 block->IsLoopHeader() ? loop_side_effects_[id] : side_effects; | 1426 block->IsLoopHeader() ? *loop_effects : *block_effects); |
| 1302 } | 1427 } |
| 1303 } | 1428 } |
| 1304 } | 1429 } |
| 1305 | 1430 |
| 1306 | 1431 |
| 1307 void HGlobalValueNumberer::LoopInvariantCodeMotion() { | 1432 void HGlobalValueNumberer::LoopInvariantCodeMotion() { |
| 1308 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { | 1433 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { |
| 1309 HBasicBlock* block = graph_->blocks()->at(i); | 1434 HBasicBlock* block = graph_->blocks()->at(i); |
| 1310 if (block->IsLoopHeader()) { | 1435 if (block->IsLoopHeader()) { |
| 1311 int side_effects = loop_side_effects_[block->block_id()]; | 1436 const HEffectSet& loop_effects = loop_side_effects_[block->block_id()]; |
| 1312 TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n", | 1437 TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n", |
| 1313 block->block_id(), | 1438 block->block_id(), |
| 1314 side_effects); | 1439 loop_effects.flags()); |
| 1315 | 1440 |
| 1316 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); | 1441 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); |
| 1317 for (int j = block->block_id(); j <= last->block_id(); ++j) { | 1442 for (int j = block->block_id(); j <= last->block_id(); ++j) { |
| 1318 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects); | 1443 ProcessLoopBlock(graph_->blocks()->at(j), block, loop_effects); |
| 1319 } | 1444 } |
| 1320 } | 1445 } |
| 1321 } | 1446 } |
| 1322 } | 1447 } |
| 1323 | 1448 |
| 1324 | 1449 |
| 1325 void HGlobalValueNumberer::ProcessLoopBlock(HBasicBlock* block, | 1450 void HGlobalValueNumberer::ProcessLoopBlock(HBasicBlock* block, |
| 1326 HBasicBlock* loop_header, | 1451 HBasicBlock* loop_header, |
| 1327 int loop_kills) { | 1452 const HEffectSet& loop_effects) { |
| 1328 HBasicBlock* pre_header = loop_header->predecessors()->at(0); | 1453 HBasicBlock* pre_header = loop_header->predecessors()->at(0); |
| 1329 int depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); | |
| 1330 TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n", | 1454 TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n", |
| 1331 block->block_id(), | 1455 block->block_id(), |
| 1332 depends_flags); | 1456 loop_effects.flags()); |
| 1333 HInstruction* instr = block->first(); | 1457 HInstruction* instr = block->first(); |
| 1334 while (instr != NULL) { | 1458 while (instr != NULL) { |
| 1335 HInstruction* next = instr->next(); | 1459 HInstruction* next = instr->next(); |
| 1336 if (instr->CheckFlag(HValue::kUseGVN) && | 1460 if (instr->CheckFlag(HValue::kUseGVN) && |
| 1337 (instr->flags() & depends_flags) == 0) { | 1461 !loop_effects.HasEffectOn(instr)) { |
| 1338 TraceGVN("Checking instruction %d (%s)\n", | 1462 TraceGVN("Checking instruction %d (%s)\n", |
| 1339 instr->id(), | 1463 instr->id(), |
| 1340 instr->Mnemonic()); | 1464 instr->Mnemonic()); |
| 1341 bool inputs_loop_invariant = true; | 1465 bool inputs_loop_invariant = true; |
| 1342 for (int i = 0; i < instr->OperandCount(); ++i) { | 1466 for (int i = 0; i < instr->OperandCount(); ++i) { |
| 1343 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { | 1467 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { |
| 1344 inputs_loop_invariant = false; | 1468 inputs_loop_invariant = false; |
| 1345 } | 1469 } |
| 1346 } | 1470 } |
| 1347 | 1471 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1407 } | 1531 } |
| 1408 | 1532 |
| 1409 // Go through all instructions of the current block. | 1533 // Go through all instructions of the current block. |
| 1410 HInstruction* instr = block->first(); | 1534 HInstruction* instr = block->first(); |
| 1411 while (instr != NULL) { | 1535 while (instr != NULL) { |
| 1412 HInstruction* next = instr->next(); | 1536 HInstruction* next = instr->next(); |
| 1413 int flags = (instr->flags() & HValue::ChangesFlagsMask()); | 1537 int flags = (instr->flags() & HValue::ChangesFlagsMask()); |
| 1414 if (flags != 0) { | 1538 if (flags != 0) { |
| 1415 ASSERT(!instr->CheckFlag(HValue::kUseGVN)); | 1539 ASSERT(!instr->CheckFlag(HValue::kUseGVN)); |
| 1416 // Clear all instructions in the map that are affected by side effects. | 1540 // Clear all instructions in the map that are affected by side effects. |
| 1417 map->Kill(flags); | 1541 HEffectSet effects(flags); |
| 1542 map->Kill(effects); | |
| 1418 TraceGVN("Instruction %d kills\n", instr->id()); | 1543 TraceGVN("Instruction %d kills\n", instr->id()); |
| 1419 } else if (instr->CheckFlag(HValue::kUseGVN)) { | 1544 } else if (instr->CheckFlag(HValue::kUseGVN)) { |
| 1420 HValue* other = map->Lookup(instr); | 1545 HValue* other = map->Lookup(instr); |
| 1421 if (other != NULL) { | 1546 if (other != NULL) { |
| 1422 ASSERT(instr->Equals(other) && other->Equals(instr)); | 1547 ASSERT(instr->Equals(other) && other->Equals(instr)); |
| 1423 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", | 1548 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", |
| 1424 instr->id(), | 1549 instr->id(), |
| 1425 instr->Mnemonic(), | 1550 instr->Mnemonic(), |
| 1426 other->id(), | 1551 other->id(), |
| 1427 other->Mnemonic()); | 1552 other->Mnemonic()); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1443 // If the dominated block is not a successor to this block we have to | 1568 // If the dominated block is not a successor to this block we have to |
| 1444 // kill everything killed on any path between this block and the | 1569 // kill everything killed on any path between this block and the |
| 1445 // dominated block. Note we rely on the block ordering. | 1570 // dominated block. Note we rely on the block ordering. |
| 1446 bool is_successor = false; | 1571 bool is_successor = false; |
| 1447 int predecessor_count = dominated->predecessors()->length(); | 1572 int predecessor_count = dominated->predecessors()->length(); |
| 1448 for (int j = 0; !is_successor && j < predecessor_count; ++j) { | 1573 for (int j = 0; !is_successor && j < predecessor_count; ++j) { |
| 1449 is_successor = (dominated->predecessors()->at(j) == block); | 1574 is_successor = (dominated->predecessors()->at(j) == block); |
| 1450 } | 1575 } |
| 1451 | 1576 |
| 1452 if (!is_successor) { | 1577 if (!is_successor) { |
| 1453 int side_effects = 0; | 1578 HEffectSet side_effects; |
| 1454 for (int j = block->block_id() + 1; j < dominated->block_id(); ++j) { | 1579 for (int j = block->block_id() + 1; j < dominated->block_id(); ++j) { |
| 1455 side_effects |= block_side_effects_[j]; | 1580 side_effects.AddAll(block_side_effects_[j]); |
| 1456 } | 1581 } |
| 1457 successor_map->Kill(side_effects); | 1582 successor_map->Kill(side_effects); |
| 1458 } | 1583 } |
| 1459 | 1584 |
| 1460 AnalyzeBlock(dominated, successor_map); | 1585 AnalyzeBlock(dominated, successor_map); |
| 1461 } | 1586 } |
| 1462 } | 1587 } |
| 1463 | 1588 |
| 1464 | 1589 |
| 1465 class HInferRepresentation BASE_EMBEDDED { | 1590 class HInferRepresentation BASE_EMBEDDED { |
| (...skipping 1561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3027 // Negative property indices are in-object properties, indexed | 3152 // Negative property indices are in-object properties, indexed |
| 3028 // from the end of the fixed part of the object. | 3153 // from the end of the fixed part of the object. |
| 3029 offset += type->instance_size(); | 3154 offset += type->instance_size(); |
| 3030 } else { | 3155 } else { |
| 3031 offset += FixedArray::kHeaderSize; | 3156 offset += FixedArray::kHeaderSize; |
| 3032 } | 3157 } |
| 3033 HStoreNamedField* instr = | 3158 HStoreNamedField* instr = |
| 3034 new HStoreNamedField(object, name, value, is_in_object, offset); | 3159 new HStoreNamedField(object, name, value, is_in_object, offset); |
| 3035 if (lookup->type() == MAP_TRANSITION) { | 3160 if (lookup->type() == MAP_TRANSITION) { |
| 3036 Handle<Map> transition(lookup->GetTransitionMapFromMap(*type)); | 3161 Handle<Map> transition(lookup->GetTransitionMapFromMap(*type)); |
| 3037 instr->set_transition(transition); | 3162 instr->SetTransition(transition); |
| 3038 // TODO(fschneider): Record the new map type of the object in the IR to | |
| 3039 // enable elimination of redundant checks after the transition store. | |
| 3040 instr->SetFlag(HValue::kChangesMaps); | |
| 3041 } | 3163 } |
| 3042 return instr; | 3164 return instr; |
| 3043 } | 3165 } |
| 3044 | 3166 |
| 3045 | 3167 |
| 3046 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, | 3168 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, |
| 3047 Handle<String> name, | 3169 Handle<String> name, |
| 3048 HValue* value) { | 3170 HValue* value) { |
| 3049 HContext* context = new HContext; | 3171 HContext* context = new HContext; |
| 3050 AddInstruction(context); | 3172 AddInstruction(context); |
| (...skipping 2853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5904 } | 6026 } |
| 5905 } | 6027 } |
| 5906 | 6028 |
| 5907 #ifdef DEBUG | 6029 #ifdef DEBUG |
| 5908 if (graph_ != NULL) graph_->Verify(); | 6030 if (graph_ != NULL) graph_->Verify(); |
| 5909 if (allocator_ != NULL) allocator_->Verify(); | 6031 if (allocator_ != NULL) allocator_->Verify(); |
| 5910 #endif | 6032 #endif |
| 5911 } | 6033 } |
| 5912 | 6034 |
| 5913 } } // namespace v8::internal | 6035 } } // namespace v8::internal |
| OLD | NEW |