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 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1014 void TraceGVN(const char* msg, ...) { | 1014 void TraceGVN(const char* msg, ...) { |
| 1015 if (FLAG_trace_gvn) { | 1015 if (FLAG_trace_gvn) { |
| 1016 va_list arguments; | 1016 va_list arguments; |
| 1017 va_start(arguments, msg); | 1017 va_start(arguments, msg); |
| 1018 OS::VPrint(msg, arguments); | 1018 OS::VPrint(msg, arguments); |
| 1019 va_end(arguments); | 1019 va_end(arguments); |
| 1020 } | 1020 } |
| 1021 } | 1021 } |
| 1022 | 1022 |
| 1023 | 1023 |
| 1024 HValueMap::HValueMap(const HValueMap* other) | 1024 HValueMap::HValueMap(Zone* zone, const HValueMap* other) |
| 1025 : array_size_(other->array_size_), | 1025 : array_size_(other->array_size_), |
| 1026 lists_size_(other->lists_size_), | 1026 lists_size_(other->lists_size_), |
| 1027 count_(other->count_), | 1027 count_(other->count_), |
| 1028 present_flags_(other->present_flags_), | 1028 present_flags_(other->present_flags_), |
| 1029 array_(ZONE->NewArray<HValueMapListElement>(other->array_size_)), | 1029 array_(zone->NewArray<HValueMapListElement>(other->array_size_)), |
| 1030 lists_(ZONE->NewArray<HValueMapListElement>(other->lists_size_)), | 1030 lists_(zone->NewArray<HValueMapListElement>(other->lists_size_)), |
| 1031 free_list_head_(other->free_list_head_) { | 1031 free_list_head_(other->free_list_head_) { |
| 1032 memcpy(array_, other->array_, array_size_ * sizeof(HValueMapListElement)); | 1032 memcpy(array_, other->array_, array_size_ * sizeof(HValueMapListElement)); |
| 1033 memcpy(lists_, other->lists_, lists_size_ * sizeof(HValueMapListElement)); | 1033 memcpy(lists_, other->lists_, lists_size_ * sizeof(HValueMapListElement)); |
| 1034 } | 1034 } |
| 1035 | 1035 |
| 1036 | 1036 |
| 1037 void HValueMap::Kill(int flags) { | 1037 void HValueMap::Kill(int flags) { |
| 1038 int depends_flags = HValue::ConvertChangesToDependsFlags(flags); | 1038 int depends_flags = HValue::ConvertChangesToDependsFlags(flags); |
| 1039 if ((present_flags_ & depends_flags) == 0) return; | 1039 if ((present_flags_ & depends_flags) == 0) return; |
| 1040 present_flags_ = 0; | 1040 present_flags_ = 0; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1233 while (instr != NULL) { | 1233 while (instr != NULL) { |
| 1234 if (instr->IsGoto()) { | 1234 if (instr->IsGoto()) { |
| 1235 HGoto::cast(instr)->set_include_stack_check(false); | 1235 HGoto::cast(instr)->set_include_stack_check(false); |
| 1236 return; | 1236 return; |
| 1237 } | 1237 } |
| 1238 instr = instr->next(); | 1238 instr = instr->next(); |
| 1239 } | 1239 } |
| 1240 } | 1240 } |
| 1241 | 1241 |
| 1242 | 1242 |
| 1243 // Simple sparse set with O(1) add, contains, and clear. | |
| 1244 class SparseSet { | |
| 1245 public: | |
| 1246 SparseSet(Zone* zone, int capacity) | |
| 1247 : capacity_(capacity), | |
| 1248 length_(0), | |
| 1249 dense_(zone->NewArray<int>(capacity)), | |
| 1250 sparse_(zone->NewArray<int>(capacity)) {} | |
| 1251 | |
| 1252 bool Contains(int n) const { | |
| 1253 ASSERT(0 <= n && n < capacity_); | |
| 1254 int d = sparse_[n]; | |
| 1255 return 0 <= d && d < length_ && dense_[d] == n; | |
| 1256 } | |
| 1257 | |
| 1258 bool Add(int n) { | |
| 1259 if (Contains(n)) return false; | |
| 1260 dense_[length_] = n; | |
| 1261 sparse_[n] = length_; | |
| 1262 ++length_; | |
| 1263 return true; | |
| 1264 } | |
| 1265 | |
| 1266 void Clear() { length_ = 0; } | |
| 1267 | |
| 1268 private: | |
| 1269 int capacity_; | |
| 1270 int length_; | |
| 1271 int* dense_; | |
| 1272 int* sparse_; | |
| 1273 | |
| 1274 DISALLOW_COPY_AND_ASSIGN(SparseSet); | |
| 1275 }; | |
| 1276 | |
| 1277 | |
| 1243 class HGlobalValueNumberer BASE_EMBEDDED { | 1278 class HGlobalValueNumberer BASE_EMBEDDED { |
| 1244 public: | 1279 public: |
| 1245 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) | 1280 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) |
| 1246 : graph_(graph), | 1281 : graph_(graph), |
| 1247 info_(info), | 1282 info_(info), |
| 1248 block_side_effects_(graph_->blocks()->length()), | 1283 block_side_effects_(graph->blocks()->length()), |
| 1249 loop_side_effects_(graph_->blocks()->length()) { | 1284 loop_side_effects_(graph->blocks()->length()), |
| 1285 visited_on_paths_(graph->zone(), graph->blocks()->length()) { | |
| 1250 ASSERT(info->isolate()->heap()->allow_allocation(false)); | 1286 ASSERT(info->isolate()->heap()->allow_allocation(false)); |
| 1251 block_side_effects_.AddBlock(0, graph_->blocks()->length()); | 1287 block_side_effects_.AddBlock(0, graph_->blocks()->length()); |
| 1252 loop_side_effects_.AddBlock(0, graph_->blocks()->length()); | 1288 loop_side_effects_.AddBlock(0, graph_->blocks()->length()); |
| 1253 } | 1289 } |
| 1254 ~HGlobalValueNumberer() { | 1290 ~HGlobalValueNumberer() { |
| 1255 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); | 1291 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); |
| 1256 } | 1292 } |
| 1257 | 1293 |
| 1258 void Analyze(); | 1294 void Analyze(); |
| 1259 | 1295 |
| 1260 private: | 1296 private: |
| 1297 int CollectSideEffectsOnPathsToDominatedBlock(HBasicBlock* dominator, | |
| 1298 HBasicBlock* dominated); | |
| 1261 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); | 1299 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); |
| 1262 void ComputeBlockSideEffects(); | 1300 void ComputeBlockSideEffects(); |
| 1263 void LoopInvariantCodeMotion(); | 1301 void LoopInvariantCodeMotion(); |
| 1264 void ProcessLoopBlock(HBasicBlock* block, | 1302 void ProcessLoopBlock(HBasicBlock* block, |
| 1265 HBasicBlock* before_loop, | 1303 HBasicBlock* before_loop, |
| 1266 int loop_kills); | 1304 int loop_kills); |
| 1267 bool AllowCodeMotion(); | 1305 bool AllowCodeMotion(); |
| 1268 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); | 1306 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); |
| 1269 | 1307 |
| 1270 HGraph* graph() { return graph_; } | 1308 HGraph* graph() { return graph_; } |
| 1271 CompilationInfo* info() { return info_; } | 1309 CompilationInfo* info() { return info_; } |
| 1272 Zone* zone() { return graph_->zone(); } | 1310 Zone* zone() { return graph_->zone(); } |
| 1273 | 1311 |
| 1274 HGraph* graph_; | 1312 HGraph* graph_; |
| 1275 CompilationInfo* info_; | 1313 CompilationInfo* info_; |
| 1276 | 1314 |
| 1277 // A map of block IDs to their side effects. | 1315 // A map of block IDs to their side effects. |
| 1278 ZoneList<int> block_side_effects_; | 1316 ZoneList<int> block_side_effects_; |
| 1279 | 1317 |
| 1280 // A map of loop header block IDs to their loop's side effects. | 1318 // A map of loop header block IDs to their loop's side effects. |
| 1281 ZoneList<int> loop_side_effects_; | 1319 ZoneList<int> loop_side_effects_; |
| 1320 | |
| 1321 // Used when collecting side effects on paths from dominator to | |
| 1322 // dominated. | |
| 1323 SparseSet visited_on_paths_; | |
| 1282 }; | 1324 }; |
| 1283 | 1325 |
| 1284 | 1326 |
| 1285 void HGlobalValueNumberer::Analyze() { | 1327 void HGlobalValueNumberer::Analyze() { |
| 1286 ComputeBlockSideEffects(); | 1328 ComputeBlockSideEffects(); |
| 1287 if (FLAG_loop_invariant_code_motion) { | 1329 if (FLAG_loop_invariant_code_motion) { |
| 1288 LoopInvariantCodeMotion(); | 1330 LoopInvariantCodeMotion(); |
| 1289 } | 1331 } |
| 1290 HValueMap* map = new(zone()) HValueMap(); | 1332 HValueMap* map = new(zone()) HValueMap(); |
| 1291 AnalyzeBlock(graph_->blocks()->at(0), map); | 1333 AnalyzeBlock(graph_->blocks()->at(0), map); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1407 if (!found) { | 1449 if (!found) { |
| 1408 result = false; | 1450 result = false; |
| 1409 break; | 1451 break; |
| 1410 } | 1452 } |
| 1411 } | 1453 } |
| 1412 } | 1454 } |
| 1413 return result; | 1455 return result; |
| 1414 } | 1456 } |
| 1415 | 1457 |
| 1416 | 1458 |
| 1459 int HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock( | |
| 1460 HBasicBlock* dominator, HBasicBlock* dominated) { | |
| 1461 int side_effects = 0; | |
| 1462 for (int i = 0; i < dominated->predecessors()->length(); ++i) { | |
| 1463 HBasicBlock* block = dominated->predecessors()->at(i); | |
| 1464 if (dominator->block_id() < block->block_id() && | |
| 1465 block->block_id() < dominated->block_id() && | |
| 1466 visited_on_paths_.Add(block->block_id())) { | |
| 1467 side_effects |= block_side_effects_[block->block_id()]; | |
| 1468 side_effects |= CollectSideEffectsOnPathsToDominatedBlock( | |
| 1469 dominator, block); | |
| 1470 } | |
| 1471 } | |
| 1472 return side_effects; | |
| 1473 } | |
| 1474 | |
| 1475 | |
| 1417 void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { | 1476 void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { |
| 1418 TraceGVN("Analyzing block B%d\n", block->block_id()); | 1477 TraceGVN("Analyzing block B%d%s\n", |
| 1478 block->block_id(), | |
| 1479 block->IsLoopHeader() ? " (loop header)" : ""); | |
| 1419 | 1480 |
| 1420 // If this is a loop header kill everything killed by the loop. | 1481 // If this is a loop header kill everything killed by the loop. |
| 1421 if (block->IsLoopHeader()) { | 1482 if (block->IsLoopHeader()) { |
| 1422 map->Kill(loop_side_effects_[block->block_id()]); | 1483 map->Kill(loop_side_effects_[block->block_id()]); |
| 1423 } | 1484 } |
| 1424 | 1485 |
| 1425 // Go through all instructions of the current block. | 1486 // Go through all instructions of the current block. |
| 1426 HInstruction* instr = block->first(); | 1487 HInstruction* instr = block->first(); |
| 1427 while (instr != NULL) { | 1488 while (instr != NULL) { |
| 1428 HInstruction* next = instr->next(); | 1489 HInstruction* next = instr->next(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1441 instr->Mnemonic(), | 1502 instr->Mnemonic(), |
| 1442 other->id(), | 1503 other->id(), |
| 1443 other->Mnemonic()); | 1504 other->Mnemonic()); |
| 1444 instr->DeleteAndReplaceWith(other); | 1505 instr->DeleteAndReplaceWith(other); |
| 1445 } else { | 1506 } else { |
| 1446 map->Add(instr); | 1507 map->Add(instr); |
| 1447 } | 1508 } |
| 1448 } | 1509 } |
| 1449 instr = next; | 1510 instr = next; |
| 1450 } | 1511 } |
| 1451 | 1512 |
|
fschneider
2011/05/18 16:25:02
Remove extra new-line.
| |
| 1513 | |
| 1452 // Recursively continue analysis for all immediately dominated blocks. | 1514 // Recursively continue analysis for all immediately dominated blocks. |
| 1453 int length = block->dominated_blocks()->length(); | 1515 int length = block->dominated_blocks()->length(); |
| 1454 for (int i = 0; i < length; ++i) { | 1516 for (int i = 0; i < length; ++i) { |
| 1455 HBasicBlock* dominated = block->dominated_blocks()->at(i); | 1517 HBasicBlock* dominated = block->dominated_blocks()->at(i); |
| 1456 // No need to copy the map for the last child in the dominator tree. | 1518 // No need to copy the map for the last child in the dominator tree. |
| 1457 HValueMap* successor_map = (i == length - 1) ? map : map->Copy(zone()); | 1519 HValueMap* successor_map = (i == length - 1) ? map : map->Copy(zone()); |
| 1458 | 1520 |
| 1459 // If the dominated block is not a successor to this block we have to | 1521 // Kill everything killed on any path between this block and the |
| 1460 // kill everything killed on any path between this block and the | 1522 // dominated block. |
| 1461 // dominated block. Note we rely on the block ordering. | 1523 if (!successor_map->IsEmpty() && |
| 1462 bool is_successor = false; | 1524 block->block_id() + 1 < dominated->block_id()) { |
|
fschneider
2011/05/18 16:25:02
Maybe assert that (block->block_id() + 1) is alway
| |
| 1463 int predecessor_count = dominated->predecessors()->length(); | 1525 visited_on_paths_.Clear(); |
| 1464 for (int j = 0; !is_successor && j < predecessor_count; ++j) { | 1526 successor_map->Kill(CollectSideEffectsOnPathsToDominatedBlock(block, |
| 1465 is_successor = (dominated->predecessors()->at(j) == block); | 1527 dominated)); |
| 1466 } | 1528 } |
| 1467 | |
| 1468 if (!is_successor) { | |
| 1469 int side_effects = 0; | |
| 1470 for (int j = block->block_id() + 1; j < dominated->block_id(); ++j) { | |
| 1471 side_effects |= block_side_effects_[j]; | |
| 1472 } | |
| 1473 successor_map->Kill(side_effects); | |
| 1474 } | |
| 1475 | |
| 1476 AnalyzeBlock(dominated, successor_map); | 1529 AnalyzeBlock(dominated, successor_map); |
| 1477 } | 1530 } |
| 1478 } | 1531 } |
| 1479 | 1532 |
| 1480 | 1533 |
| 1481 class HInferRepresentation BASE_EMBEDDED { | 1534 class HInferRepresentation BASE_EMBEDDED { |
| 1482 public: | 1535 public: |
| 1483 explicit HInferRepresentation(HGraph* graph) | 1536 explicit HInferRepresentation(HGraph* graph) |
| 1484 : graph_(graph), worklist_(8), in_worklist_(graph->GetMaximumValueID()) {} | 1537 : graph_(graph), worklist_(8), in_worklist_(graph->GetMaximumValueID()) {} |
| 1485 | 1538 |
| (...skipping 4656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6142 } | 6195 } |
| 6143 } | 6196 } |
| 6144 | 6197 |
| 6145 #ifdef DEBUG | 6198 #ifdef DEBUG |
| 6146 if (graph_ != NULL) graph_->Verify(); | 6199 if (graph_ != NULL) graph_->Verify(); |
| 6147 if (allocator_ != NULL) allocator_->Verify(); | 6200 if (allocator_ != NULL) allocator_->Verify(); |
| 6148 #endif | 6201 #endif |
| 6149 } | 6202 } |
| 6150 | 6203 |
| 6151 } } // namespace v8::internal | 6204 } } // namespace v8::internal |
| OLD | NEW |