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

Side by Side Diff: src/hydrogen.cc

Issue 10233004: Reduce expense of TraceGVN when --trace-gvn is off (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback 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 | « no previous file | no next file » | 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 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 original_range->lower(), 1143 original_range->lower(),
1144 original_range->upper()); 1144 original_range->upper());
1145 } 1145 }
1146 TraceRange("New information was [%d,%d]\n", 1146 TraceRange("New information was [%d,%d]\n",
1147 range->lower(), 1147 range->lower(),
1148 range->upper()); 1148 range->upper());
1149 } 1149 }
1150 1150
1151 1151
1152 void TraceGVN(const char* msg, ...) { 1152 void TraceGVN(const char* msg, ...) {
1153 if (FLAG_trace_gvn) { 1153 va_list arguments;
1154 va_list arguments; 1154 va_start(arguments, msg);
1155 va_start(arguments, msg); 1155 OS::VPrint(msg, arguments);
1156 OS::VPrint(msg, arguments); 1156 va_end(arguments);
1157 va_end(arguments); 1157 }
1158
1159 // Wrap TraceGVN in macros to avoid the expense of evaluating its arguments when
1160 // --trace-gvn is off.
1161 #define TRACE_GVN_1(msg, a1) \
1162 if (FLAG_trace_gvn) { \
1163 TraceGVN(msg, a1); \
1158 } 1164 }
1159 } 1165
1166 #define TRACE_GVN_2(msg, a1, a2) \
1167 if (FLAG_trace_gvn) { \
1168 TraceGVN(msg, a1, a2); \
1169 }
1170
1171 #define TRACE_GVN_3(msg, a1, a2, a3) \
1172 if (FLAG_trace_gvn) { \
1173 TraceGVN(msg, a1, a2, a3); \
1174 }
1175
1176 #define TRACE_GVN_4(msg, a1, a2, a3, a4) \
1177 if (FLAG_trace_gvn) { \
1178 TraceGVN(msg, a1, a2, a3, a4); \
1179 }
1180
1181 #define TRACE_GVN_5(msg, a1, a2, a3, a4, a5) \
1182 if (FLAG_trace_gvn) { \
1183 TraceGVN(msg, a1, a2, a3, a4, a5); \
1184 }
1160 1185
1161 1186
1162 HValueMap::HValueMap(Zone* zone, const HValueMap* other) 1187 HValueMap::HValueMap(Zone* zone, const HValueMap* other)
1163 : array_size_(other->array_size_), 1188 : array_size_(other->array_size_),
1164 lists_size_(other->lists_size_), 1189 lists_size_(other->lists_size_),
1165 count_(other->count_), 1190 count_(other->count_),
1166 present_flags_(other->present_flags_), 1191 present_flags_(other->present_flags_),
1167 array_(zone->NewArray<HValueMapListElement>(other->array_size_)), 1192 array_(zone->NewArray<HValueMapListElement>(other->array_size_)),
1168 lists_(zone->NewArray<HValueMapListElement>(other->lists_size_)), 1193 lists_(zone->NewArray<HValueMapListElement>(other->lists_size_)),
1169 free_list_head_(other->free_list_head_) { 1194 free_list_head_(other->free_list_head_) {
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 memcpy(result, underlying_buffer, string_len); 1661 memcpy(result, underlying_buffer, string_len);
1637 return SmartArrayPointer<char>(result); 1662 return SmartArrayPointer<char>(result);
1638 } 1663 }
1639 1664
1640 1665
1641 void HGlobalValueNumberer::LoopInvariantCodeMotion() { 1666 void HGlobalValueNumberer::LoopInvariantCodeMotion() {
1642 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { 1667 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
1643 HBasicBlock* block = graph_->blocks()->at(i); 1668 HBasicBlock* block = graph_->blocks()->at(i);
1644 if (block->IsLoopHeader()) { 1669 if (block->IsLoopHeader()) {
1645 GVNFlagSet side_effects = loop_side_effects_[block->block_id()]; 1670 GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
1646 TraceGVN("Try loop invariant motion for block B%d %s\n", 1671 TRACE_GVN_2("Try loop invariant motion for block B%d %s\n",
1647 block->block_id(), 1672 block->block_id(),
1648 *GetGVNFlagsString(side_effects)); 1673 *GetGVNFlagsString(side_effects));
1649 1674
1650 GVNFlagSet accumulated_first_time_depends; 1675 GVNFlagSet accumulated_first_time_depends;
1651 GVNFlagSet accumulated_first_time_changes; 1676 GVNFlagSet accumulated_first_time_changes;
1652 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); 1677 HBasicBlock* last = block->loop_information()->GetLastBackEdge();
1653 for (int j = block->block_id(); j <= last->block_id(); ++j) { 1678 for (int j = block->block_id(); j <= last->block_id(); ++j) {
1654 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects, 1679 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects,
1655 &accumulated_first_time_depends, 1680 &accumulated_first_time_depends,
1656 &accumulated_first_time_changes); 1681 &accumulated_first_time_changes);
1657 } 1682 }
1658 } 1683 }
1659 } 1684 }
1660 } 1685 }
1661 1686
1662 1687
1663 void HGlobalValueNumberer::ProcessLoopBlock( 1688 void HGlobalValueNumberer::ProcessLoopBlock(
1664 HBasicBlock* block, 1689 HBasicBlock* block,
1665 HBasicBlock* loop_header, 1690 HBasicBlock* loop_header,
1666 GVNFlagSet loop_kills, 1691 GVNFlagSet loop_kills,
1667 GVNFlagSet* first_time_depends, 1692 GVNFlagSet* first_time_depends,
1668 GVNFlagSet* first_time_changes) { 1693 GVNFlagSet* first_time_changes) {
1669 HBasicBlock* pre_header = loop_header->predecessors()->at(0); 1694 HBasicBlock* pre_header = loop_header->predecessors()->at(0);
1670 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); 1695 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
1671 TraceGVN("Loop invariant motion for B%d %s\n", 1696 TRACE_GVN_2("Loop invariant motion for B%d %s\n",
1672 block->block_id(), 1697 block->block_id(),
1673 *GetGVNFlagsString(depends_flags)); 1698 *GetGVNFlagsString(depends_flags));
1674 HInstruction* instr = block->first(); 1699 HInstruction* instr = block->first();
1675 while (instr != NULL) { 1700 while (instr != NULL) {
1676 HInstruction* next = instr->next(); 1701 HInstruction* next = instr->next();
1677 bool hoisted = false; 1702 bool hoisted = false;
1678 if (instr->CheckFlag(HValue::kUseGVN)) { 1703 if (instr->CheckFlag(HValue::kUseGVN)) {
1679 TraceGVN("Checking instruction %d (%s) %s. Loop %s\n", 1704 TRACE_GVN_4("Checking instruction %d (%s) %s. Loop %s\n",
1680 instr->id(), 1705 instr->id(),
1681 instr->Mnemonic(), 1706 instr->Mnemonic(),
1682 *GetGVNFlagsString(instr->gvn_flags()), 1707 *GetGVNFlagsString(instr->gvn_flags()),
1683 *GetGVNFlagsString(loop_kills)); 1708 *GetGVNFlagsString(loop_kills));
1684 bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags); 1709 bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags);
1685 if (instr->IsTransitionElementsKind()) { 1710 if (instr->IsTransitionElementsKind()) {
1686 // It's possible to hoist transitions out of a loop as long as the 1711 // It's possible to hoist transitions out of a loop as long as the
1687 // hoisting wouldn't move the transition past a DependsOn of one of it's 1712 // hoisting wouldn't move the transition past a DependsOn of one of it's
1688 // changes or any instructions that might change an objects map or 1713 // changes or any instructions that might change an objects map or
1689 // elements contents. 1714 // elements contents.
1690 GVNFlagSet changes = instr->ChangesFlags(); 1715 GVNFlagSet changes = instr->ChangesFlags();
1691 GVNFlagSet hoist_depends_blockers = 1716 GVNFlagSet hoist_depends_blockers =
1692 HValue::ConvertChangesToDependsFlags(changes); 1717 HValue::ConvertChangesToDependsFlags(changes);
1693 // In addition to not hoisting transitions above other instructions that 1718 // In addition to not hoisting transitions above other instructions that
1694 // change dependencies that the transition changes, it must not be 1719 // change dependencies that the transition changes, it must not be
1695 // hoisted above map changes and stores to an elements backing store 1720 // hoisted above map changes and stores to an elements backing store
1696 // that the transition might change. 1721 // that the transition might change.
1697 GVNFlagSet hoist_change_blockers = changes; 1722 GVNFlagSet hoist_change_blockers = changes;
1698 hoist_change_blockers.Add(kChangesMaps); 1723 hoist_change_blockers.Add(kChangesMaps);
1699 HTransitionElementsKind* trans = HTransitionElementsKind::cast(instr); 1724 HTransitionElementsKind* trans = HTransitionElementsKind::cast(instr);
1700 if (trans->original_map()->has_fast_double_elements()) { 1725 if (trans->original_map()->has_fast_double_elements()) {
1701 hoist_change_blockers.Add(kChangesDoubleArrayElements); 1726 hoist_change_blockers.Add(kChangesDoubleArrayElements);
1702 } 1727 }
1703 if (trans->transitioned_map()->has_fast_double_elements()) { 1728 if (trans->transitioned_map()->has_fast_double_elements()) {
1704 hoist_change_blockers.Add(kChangesArrayElements); 1729 hoist_change_blockers.Add(kChangesArrayElements);
1705 } 1730 }
1706 TraceGVN("Checking dependencies on HTransitionElementsKind %d (%s) " 1731 if (FLAG_trace_gvn) {
1707 "hoist blockers: %s %s; " 1732 GVNFlagSet hoist_blockers = hoist_depends_blockers;
1708 "first-time accumulated: %s %s\n", 1733 hoist_blockers.Add(hoist_change_blockers);
1709 instr->id(), 1734 GVNFlagSet first_time = *first_time_changes;
1710 instr->Mnemonic(), 1735 first_time.Add(*first_time_depends);
1711 *GetGVNFlagsString(hoist_depends_blockers), 1736 TRACE_GVN_4("Checking dependencies on HTransitionElementsKind "
1712 *GetGVNFlagsString(hoist_change_blockers), 1737 "%d (%s) hoist blockers: %s; "
1713 *GetGVNFlagsString(*first_time_depends), 1738 "first-time accumulated: %s\n",
1714 *GetGVNFlagsString(*first_time_changes)); 1739 instr->id(),
1740 instr->Mnemonic(),
1741 *GetGVNFlagsString(hoist_blockers),
1742 *GetGVNFlagsString(first_time));
1743 }
1715 // It's possible to hoist transition from the current loop loop only if 1744 // It's possible to hoist transition from the current loop loop only if
1716 // they dominate all of the successor blocks in the same loop and there 1745 // they dominate all of the successor blocks in the same loop and there
1717 // are not any instructions that have Changes/DependsOn that intervene 1746 // are not any instructions that have Changes/DependsOn that intervene
1718 // between it and the beginning of the loop header. 1747 // between it and the beginning of the loop header.
1719 bool in_nested_loop = block != loop_header && 1748 bool in_nested_loop = block != loop_header &&
1720 ((block->parent_loop_header() != loop_header) || 1749 ((block->parent_loop_header() != loop_header) ||
1721 block->IsLoopHeader()); 1750 block->IsLoopHeader());
1722 can_hoist = !in_nested_loop && 1751 can_hoist = !in_nested_loop &&
1723 block->IsLoopSuccessorDominator() && 1752 block->IsLoopSuccessorDominator() &&
1724 !first_time_depends->ContainsAnyOf(hoist_depends_blockers) && 1753 !first_time_depends->ContainsAnyOf(hoist_depends_blockers) &&
1725 !first_time_changes->ContainsAnyOf(hoist_change_blockers); 1754 !first_time_changes->ContainsAnyOf(hoist_change_blockers);
1726 } 1755 }
1727 1756
1728 if (can_hoist) { 1757 if (can_hoist) {
1729 bool inputs_loop_invariant = true; 1758 bool inputs_loop_invariant = true;
1730 for (int i = 0; i < instr->OperandCount(); ++i) { 1759 for (int i = 0; i < instr->OperandCount(); ++i) {
1731 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { 1760 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) {
1732 inputs_loop_invariant = false; 1761 inputs_loop_invariant = false;
1733 } 1762 }
1734 } 1763 }
1735 1764
1736 if (inputs_loop_invariant && ShouldMove(instr, loop_header)) { 1765 if (inputs_loop_invariant && ShouldMove(instr, loop_header)) {
1737 TraceGVN("Hoisting loop invariant instruction %d\n", instr->id()); 1766 TRACE_GVN_1("Hoisting loop invariant instruction %d\n", instr->id());
1738 // Move the instruction out of the loop. 1767 // Move the instruction out of the loop.
1739 instr->Unlink(); 1768 instr->Unlink();
1740 instr->InsertBefore(pre_header->end()); 1769 instr->InsertBefore(pre_header->end());
1741 if (instr->HasSideEffects()) removed_side_effects_ = true; 1770 if (instr->HasSideEffects()) removed_side_effects_ = true;
1742 hoisted = true; 1771 hoisted = true;
1743 } 1772 }
1744 } 1773 }
1745 } 1774 }
1746 if (!hoisted) { 1775 if (!hoisted) {
1747 // If an instruction is not hoisted, we have to account for its side 1776 // If an instruction is not hoisted, we have to account for its side
1748 // effects when hoisting later HTransitionElementsKind instructions. 1777 // effects when hoisting later HTransitionElementsKind instructions.
1749 GVNFlagSet previous_depends = *first_time_depends; 1778 GVNFlagSet previous_depends = *first_time_depends;
1750 GVNFlagSet previous_changes = *first_time_changes; 1779 GVNFlagSet previous_changes = *first_time_changes;
1751 first_time_depends->Add(instr->DependsOnFlags()); 1780 first_time_depends->Add(instr->DependsOnFlags());
1752 first_time_changes->Add(instr->ChangesFlags()); 1781 first_time_changes->Add(instr->ChangesFlags());
1753 if (!(previous_depends == *first_time_depends)) { 1782 if (!(previous_depends == *first_time_depends)) {
1754 TraceGVN("Updated first-time accumulated %s\n", 1783 TRACE_GVN_1("Updated first-time accumulated %s\n",
1755 *GetGVNFlagsString(*first_time_depends)); 1784 *GetGVNFlagsString(*first_time_depends));
1756 } 1785 }
1757 if (!(previous_changes == *first_time_changes)) { 1786 if (!(previous_changes == *first_time_changes)) {
1758 TraceGVN("Updated first-time accumulated %s\n", 1787 TRACE_GVN_1("Updated first-time accumulated %s\n",
1759 *GetGVNFlagsString(*first_time_changes)); 1788 *GetGVNFlagsString(*first_time_changes));
1760 } 1789 }
1761 } 1790 }
1762 instr = next; 1791 instr = next;
1763 } 1792 }
1764 } 1793 }
1765 1794
1766 1795
1767 bool HGlobalValueNumberer::AllowCodeMotion() { 1796 bool HGlobalValueNumberer::AllowCodeMotion() {
1768 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount; 1797 return info()->shared_info()->opt_count() + 1 < Compiler::kDefaultMaxOptCount;
1769 } 1798 }
(...skipping 23 matching lines...) Expand all
1793 dominator, block)); 1822 dominator, block));
1794 } 1823 }
1795 } 1824 }
1796 return side_effects; 1825 return side_effects;
1797 } 1826 }
1798 1827
1799 1828
1800 void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, 1829 void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block,
1801 HValueMap* map, 1830 HValueMap* map,
1802 HSideEffectMap* dominators) { 1831 HSideEffectMap* dominators) {
1803 TraceGVN("Analyzing block B%d%s\n", 1832 TRACE_GVN_2("Analyzing block B%d%s\n",
1804 block->block_id(), 1833 block->block_id(),
1805 block->IsLoopHeader() ? " (loop header)" : ""); 1834 block->IsLoopHeader() ? " (loop header)" : "");
1806 1835
1807 // If this is a loop header kill everything killed by the loop. 1836 // If this is a loop header kill everything killed by the loop.
1808 if (block->IsLoopHeader()) { 1837 if (block->IsLoopHeader()) {
1809 map->Kill(loop_side_effects_[block->block_id()]); 1838 map->Kill(loop_side_effects_[block->block_id()]);
1810 } 1839 }
1811 1840
1812 // Go through all instructions of the current block. 1841 // Go through all instructions of the current block.
1813 HInstruction* instr = block->first(); 1842 HInstruction* instr = block->first();
1814 while (instr != NULL) { 1843 while (instr != NULL) {
1815 HInstruction* next = instr->next(); 1844 HInstruction* next = instr->next();
1816 GVNFlagSet flags = instr->ChangesFlags(); 1845 GVNFlagSet flags = instr->ChangesFlags();
1817 if (!flags.IsEmpty()) { 1846 if (!flags.IsEmpty()) {
1818 // Clear all instructions in the map that are affected by side effects. 1847 // Clear all instructions in the map that are affected by side effects.
1819 // Store instruction as the dominating one for tracked side effects. 1848 // Store instruction as the dominating one for tracked side effects.
1820 map->Kill(flags); 1849 map->Kill(flags);
1821 dominators->Store(flags, instr); 1850 dominators->Store(flags, instr);
1822 TraceGVN("Instruction %d kills\n", instr->id()); 1851 TRACE_GVN_2("Instruction %d %s\n", instr->id(),
1852 *GetGVNFlagsString(flags));
1823 } 1853 }
1824 if (instr->CheckFlag(HValue::kUseGVN)) { 1854 if (instr->CheckFlag(HValue::kUseGVN)) {
1825 ASSERT(!instr->HasObservableSideEffects()); 1855 ASSERT(!instr->HasObservableSideEffects());
1826 HValue* other = map->Lookup(instr); 1856 HValue* other = map->Lookup(instr);
1827 if (other != NULL) { 1857 if (other != NULL) {
1828 ASSERT(instr->Equals(other) && other->Equals(instr)); 1858 ASSERT(instr->Equals(other) && other->Equals(instr));
1829 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", 1859 TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n",
1830 instr->id(), 1860 instr->id(),
1831 instr->Mnemonic(), 1861 instr->Mnemonic(),
1832 other->id(), 1862 other->id(),
1833 other->Mnemonic()); 1863 other->Mnemonic());
1834 if (instr->HasSideEffects()) removed_side_effects_ = true; 1864 if (instr->HasSideEffects()) removed_side_effects_ = true;
1835 instr->DeleteAndReplaceWith(other); 1865 instr->DeleteAndReplaceWith(other);
1836 } else { 1866 } else {
1837 map->Add(instr); 1867 map->Add(instr);
1838 } 1868 }
1839 } 1869 }
1840 if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) { 1870 if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) {
1841 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { 1871 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) {
1842 HValue* other = dominators->at(i); 1872 HValue* other = dominators->at(i);
1843 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); 1873 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i);
1844 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); 1874 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i);
1845 if (instr->DependsOnFlags().Contains(depends_on_flag) && 1875 if (instr->DependsOnFlags().Contains(depends_on_flag) &&
1846 (other != NULL)) { 1876 (other != NULL)) {
1847 TraceGVN("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", 1877 TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n",
1848 i, 1878 i,
1849 instr->id(), 1879 instr->id(),
1850 instr->Mnemonic(), 1880 instr->Mnemonic(),
1851 other->id(), 1881 other->id(),
1852 other->Mnemonic()); 1882 other->Mnemonic());
1853 instr->SetSideEffectDominator(changes_flag, other); 1883 instr->SetSideEffectDominator(changes_flag, other);
1854 } 1884 }
1855 } 1885 }
1856 } 1886 }
1857 instr = next; 1887 instr = next;
1858 } 1888 }
1859 1889
1860 // Recursively continue analysis for all immediately dominated blocks. 1890 // Recursively continue analysis for all immediately dominated blocks.
1861 int length = block->dominated_blocks()->length(); 1891 int length = block->dominated_blocks()->length();
1862 for (int i = 0; i < length; ++i) { 1892 for (int i = 0; i < length; ++i) {
(...skipping 6897 matching lines...) Expand 10 before | Expand all | Expand 10 after
8760 } 8790 }
8761 } 8791 }
8762 8792
8763 #ifdef DEBUG 8793 #ifdef DEBUG
8764 if (graph_ != NULL) graph_->Verify(false); // No full verify. 8794 if (graph_ != NULL) graph_->Verify(false); // No full verify.
8765 if (allocator_ != NULL) allocator_->Verify(); 8795 if (allocator_ != NULL) allocator_->Verify();
8766 #endif 8796 #endif
8767 } 8797 }
8768 8798
8769 } } // namespace v8::internal 8799 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698