OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 ASSERT(new_element_pos != kNil); | 1314 ASSERT(new_element_pos != kNil); |
1315 free_list_head_ = lists_[free_list_head_].next; | 1315 free_list_head_ = lists_[free_list_head_].next; |
1316 lists_[new_element_pos].value = value; | 1316 lists_[new_element_pos].value = value; |
1317 lists_[new_element_pos].next = array_[pos].next; | 1317 lists_[new_element_pos].next = array_[pos].next; |
1318 ASSERT(array_[pos].next == kNil || lists_[array_[pos].next].value != NULL); | 1318 ASSERT(array_[pos].next == kNil || lists_[array_[pos].next].value != NULL); |
1319 array_[pos].next = new_element_pos; | 1319 array_[pos].next = new_element_pos; |
1320 } | 1320 } |
1321 } | 1321 } |
1322 | 1322 |
1323 | 1323 |
| 1324 HSideEffectMap::HSideEffectMap() : count_(0) { |
| 1325 memset(data_, 0, kNumberOfTrackedSideEffects * kPointerSize); |
| 1326 } |
| 1327 |
| 1328 |
| 1329 HSideEffectMap::HSideEffectMap(HSideEffectMap* other) : count_(other->count_) { |
| 1330 memcpy(data_, other->data_, kNumberOfTrackedSideEffects * kPointerSize); |
| 1331 } |
| 1332 |
| 1333 |
| 1334 void HSideEffectMap::Kill(GVNFlagSet flags) { |
| 1335 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { |
| 1336 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); |
| 1337 if (flags.Contains(changes_flag)) { |
| 1338 if (data_[i] != NULL) count_--; |
| 1339 data_[i] = NULL; |
| 1340 } |
| 1341 } |
| 1342 } |
| 1343 |
| 1344 |
| 1345 void HSideEffectMap::Store(GVNFlagSet flags, HInstruction* instr) { |
| 1346 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { |
| 1347 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); |
| 1348 if (flags.Contains(changes_flag)) { |
| 1349 if (data_[i] == NULL) count_++; |
| 1350 data_[i] = instr; |
| 1351 } |
| 1352 } |
| 1353 } |
| 1354 |
| 1355 |
1324 class HStackCheckEliminator BASE_EMBEDDED { | 1356 class HStackCheckEliminator BASE_EMBEDDED { |
1325 public: | 1357 public: |
1326 explicit HStackCheckEliminator(HGraph* graph) : graph_(graph) { } | 1358 explicit HStackCheckEliminator(HGraph* graph) : graph_(graph) { } |
1327 | 1359 |
1328 void Process(); | 1360 void Process(); |
1329 | 1361 |
1330 private: | 1362 private: |
1331 HGraph* graph_; | 1363 HGraph* graph_; |
1332 }; | 1364 }; |
1333 | 1365 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); | 1452 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); |
1421 } | 1453 } |
1422 | 1454 |
1423 // Returns true if values with side effects are removed. | 1455 // Returns true if values with side effects are removed. |
1424 bool Analyze(); | 1456 bool Analyze(); |
1425 | 1457 |
1426 private: | 1458 private: |
1427 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( | 1459 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( |
1428 HBasicBlock* dominator, | 1460 HBasicBlock* dominator, |
1429 HBasicBlock* dominated); | 1461 HBasicBlock* dominated); |
1430 void AnalyzeBlock(HBasicBlock* block, HValueMap* map); | 1462 void AnalyzeBlock(HBasicBlock* block, |
| 1463 HValueMap* map, |
| 1464 HSideEffectMap* dominators); |
1431 void ComputeBlockSideEffects(); | 1465 void ComputeBlockSideEffects(); |
1432 void LoopInvariantCodeMotion(); | 1466 void LoopInvariantCodeMotion(); |
1433 void ProcessLoopBlock(HBasicBlock* block, | 1467 void ProcessLoopBlock(HBasicBlock* block, |
1434 HBasicBlock* before_loop, | 1468 HBasicBlock* before_loop, |
1435 GVNFlagSet loop_kills, | 1469 GVNFlagSet loop_kills, |
1436 GVNFlagSet* accumulated_first_time_depends, | 1470 GVNFlagSet* accumulated_first_time_depends, |
1437 GVNFlagSet* accumulated_first_time_changes); | 1471 GVNFlagSet* accumulated_first_time_changes); |
1438 bool AllowCodeMotion(); | 1472 bool AllowCodeMotion(); |
1439 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); | 1473 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); |
1440 | 1474 |
(...skipping 17 matching lines...) Expand all Loading... |
1458 }; | 1492 }; |
1459 | 1493 |
1460 | 1494 |
1461 bool HGlobalValueNumberer::Analyze() { | 1495 bool HGlobalValueNumberer::Analyze() { |
1462 removed_side_effects_ = false; | 1496 removed_side_effects_ = false; |
1463 ComputeBlockSideEffects(); | 1497 ComputeBlockSideEffects(); |
1464 if (FLAG_loop_invariant_code_motion) { | 1498 if (FLAG_loop_invariant_code_motion) { |
1465 LoopInvariantCodeMotion(); | 1499 LoopInvariantCodeMotion(); |
1466 } | 1500 } |
1467 HValueMap* map = new(zone()) HValueMap(); | 1501 HValueMap* map = new(zone()) HValueMap(); |
1468 AnalyzeBlock(graph_->entry_block(), map); | 1502 HSideEffectMap side_effect_dominators; |
| 1503 AnalyzeBlock(graph_->entry_block(), map, &side_effect_dominators); |
1469 return removed_side_effects_; | 1504 return removed_side_effects_; |
1470 } | 1505 } |
1471 | 1506 |
1472 | 1507 |
1473 void HGlobalValueNumberer::ComputeBlockSideEffects() { | 1508 void HGlobalValueNumberer::ComputeBlockSideEffects() { |
1474 // The Analyze phase of GVN can be called multiple times. Clear loop side | 1509 // The Analyze phase of GVN can be called multiple times. Clear loop side |
1475 // effects before computing them to erase the contents from previous Analyze | 1510 // effects before computing them to erase the contents from previous Analyze |
1476 // passes. | 1511 // passes. |
1477 for (int i = 0; i < loop_side_effects_.length(); ++i) { | 1512 for (int i = 0; i < loop_side_effects_.length(); ++i) { |
1478 loop_side_effects_[i].RemoveAll(); | 1513 loop_side_effects_[i].RemoveAll(); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1653 side_effects.Add(loop_side_effects_[block->block_id()]); | 1688 side_effects.Add(loop_side_effects_[block->block_id()]); |
1654 } | 1689 } |
1655 side_effects.Add(CollectSideEffectsOnPathsToDominatedBlock( | 1690 side_effects.Add(CollectSideEffectsOnPathsToDominatedBlock( |
1656 dominator, block)); | 1691 dominator, block)); |
1657 } | 1692 } |
1658 } | 1693 } |
1659 return side_effects; | 1694 return side_effects; |
1660 } | 1695 } |
1661 | 1696 |
1662 | 1697 |
1663 void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { | 1698 void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, |
| 1699 HValueMap* map, |
| 1700 HSideEffectMap* dominators) { |
1664 TraceGVN("Analyzing block B%d%s\n", | 1701 TraceGVN("Analyzing block B%d%s\n", |
1665 block->block_id(), | 1702 block->block_id(), |
1666 block->IsLoopHeader() ? " (loop header)" : ""); | 1703 block->IsLoopHeader() ? " (loop header)" : ""); |
1667 | 1704 |
1668 // If this is a loop header kill everything killed by the loop. | 1705 // If this is a loop header kill everything killed by the loop. |
1669 if (block->IsLoopHeader()) { | 1706 if (block->IsLoopHeader()) { |
1670 map->Kill(loop_side_effects_[block->block_id()]); | 1707 map->Kill(loop_side_effects_[block->block_id()]); |
1671 } | 1708 } |
1672 | 1709 |
1673 // Go through all instructions of the current block. | 1710 // Go through all instructions of the current block. |
1674 HInstruction* instr = block->first(); | 1711 HInstruction* instr = block->first(); |
1675 while (instr != NULL) { | 1712 while (instr != NULL) { |
1676 HInstruction* next = instr->next(); | 1713 HInstruction* next = instr->next(); |
1677 GVNFlagSet flags = instr->ChangesFlags(); | 1714 GVNFlagSet flags = instr->ChangesFlags(); |
1678 if (!flags.IsEmpty()) { | 1715 if (!flags.IsEmpty()) { |
1679 // Clear all instructions in the map that are affected by side effects. | 1716 // Clear all instructions in the map that are affected by side effects. |
| 1717 // Store instruction as the dominating one for tracked side effects. |
1680 map->Kill(flags); | 1718 map->Kill(flags); |
| 1719 dominators->Store(flags, instr); |
1681 TraceGVN("Instruction %d kills\n", instr->id()); | 1720 TraceGVN("Instruction %d kills\n", instr->id()); |
1682 } | 1721 } |
1683 if (instr->CheckFlag(HValue::kUseGVN)) { | 1722 if (instr->CheckFlag(HValue::kUseGVN)) { |
1684 ASSERT(!instr->HasObservableSideEffects()); | 1723 ASSERT(!instr->HasObservableSideEffects()); |
1685 HValue* other = map->Lookup(instr); | 1724 HValue* other = map->Lookup(instr); |
1686 if (other != NULL) { | 1725 if (other != NULL) { |
1687 ASSERT(instr->Equals(other) && other->Equals(instr)); | 1726 ASSERT(instr->Equals(other) && other->Equals(instr)); |
1688 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", | 1727 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", |
1689 instr->id(), | 1728 instr->id(), |
1690 instr->Mnemonic(), | 1729 instr->Mnemonic(), |
1691 other->id(), | 1730 other->id(), |
1692 other->Mnemonic()); | 1731 other->Mnemonic()); |
1693 if (instr->HasSideEffects()) removed_side_effects_ = true; | 1732 if (instr->HasSideEffects()) removed_side_effects_ = true; |
1694 instr->DeleteAndReplaceWith(other); | 1733 instr->DeleteAndReplaceWith(other); |
1695 } else { | 1734 } else { |
1696 map->Add(instr); | 1735 map->Add(instr); |
1697 } | 1736 } |
1698 } | 1737 } |
| 1738 if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) { |
| 1739 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { |
| 1740 HValue* other = dominators->at(i); |
| 1741 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); |
| 1742 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); |
| 1743 if (instr->DependsOnFlags().Contains(depends_on_flag) && |
| 1744 (other != NULL)) { |
| 1745 TraceGVN("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", |
| 1746 i, |
| 1747 instr->id(), |
| 1748 instr->Mnemonic(), |
| 1749 other->id(), |
| 1750 other->Mnemonic()); |
| 1751 instr->SetSideEffectDominator(changes_flag, other); |
| 1752 } |
| 1753 } |
| 1754 } |
1699 instr = next; | 1755 instr = next; |
1700 } | 1756 } |
1701 | 1757 |
1702 // Recursively continue analysis for all immediately dominated blocks. | 1758 // Recursively continue analysis for all immediately dominated blocks. |
1703 int length = block->dominated_blocks()->length(); | 1759 int length = block->dominated_blocks()->length(); |
1704 for (int i = 0; i < length; ++i) { | 1760 for (int i = 0; i < length; ++i) { |
1705 HBasicBlock* dominated = block->dominated_blocks()->at(i); | 1761 HBasicBlock* dominated = block->dominated_blocks()->at(i); |
1706 // No need to copy the map for the last child in the dominator tree. | 1762 // No need to copy the map for the last child in the dominator tree. |
1707 HValueMap* successor_map = (i == length - 1) ? map : map->Copy(zone()); | 1763 HValueMap* successor_map = (i == length - 1) ? map : map->Copy(zone()); |
| 1764 HSideEffectMap successor_dominators(dominators); |
1708 | 1765 |
1709 // Kill everything killed on any path between this block and the | 1766 // Kill everything killed on any path between this block and the |
1710 // dominated block. | 1767 // dominated block. We don't have to traverse these paths if the |
1711 // We don't have to traverse these paths if the value map is | 1768 // value map and the dominators list is already empty. If the range |
1712 // already empty. | 1769 // of block ids (block_id, dominated_id) is empty there are no such |
1713 // If the range of block ids (block_id, dominated_id) is empty | 1770 // paths. |
1714 // there are no such paths. | 1771 if ((!successor_map->IsEmpty() || !successor_dominators.IsEmpty()) && |
1715 if (!successor_map->IsEmpty() && | |
1716 block->block_id() + 1 < dominated->block_id()) { | 1772 block->block_id() + 1 < dominated->block_id()) { |
1717 visited_on_paths_.Clear(); | 1773 visited_on_paths_.Clear(); |
1718 successor_map->Kill(CollectSideEffectsOnPathsToDominatedBlock(block, | 1774 GVNFlagSet side_effects_on_all_paths = |
1719 dominated)); | 1775 CollectSideEffectsOnPathsToDominatedBlock(block, dominated); |
| 1776 successor_map->Kill(side_effects_on_all_paths); |
| 1777 successor_dominators.Kill(side_effects_on_all_paths); |
1720 } | 1778 } |
1721 AnalyzeBlock(dominated, successor_map); | 1779 AnalyzeBlock(dominated, successor_map, &successor_dominators); |
1722 } | 1780 } |
1723 } | 1781 } |
1724 | 1782 |
1725 | 1783 |
1726 class HInferRepresentation BASE_EMBEDDED { | 1784 class HInferRepresentation BASE_EMBEDDED { |
1727 public: | 1785 public: |
1728 explicit HInferRepresentation(HGraph* graph) | 1786 explicit HInferRepresentation(HGraph* graph) |
1729 : graph_(graph), | 1787 : graph_(graph), |
1730 worklist_(8), | 1788 worklist_(8), |
1731 in_worklist_(graph->GetMaximumValueID(), graph->zone()) { } | 1789 in_worklist_(graph->GetMaximumValueID(), graph->zone()) { } |
(...skipping 6499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8231 } | 8289 } |
8232 } | 8290 } |
8233 | 8291 |
8234 #ifdef DEBUG | 8292 #ifdef DEBUG |
8235 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 8293 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
8236 if (allocator_ != NULL) allocator_->Verify(); | 8294 if (allocator_ != NULL) allocator_->Verify(); |
8237 #endif | 8295 #endif |
8238 } | 8296 } |
8239 | 8297 |
8240 } } // namespace v8::internal | 8298 } } // namespace v8::internal |
OLD | NEW |