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 |