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

Side by Side Diff: src/hydrogen.cc

Issue 10031031: Remove write-barriers for stores to new-space objects. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Erik Corry. Created 8 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698