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

Side by Side Diff: src/hydrogen.cc

Issue 6690006: Improve GVN dependency tracking by adding parameters to certain flags.
Patch Set: Created 9 years, 9 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
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698