| 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 |