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 1780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1791 friend class AstContext; // Pushes and pops the AST context stack. | 1791 friend class AstContext; // Pushes and pops the AST context stack. |
1792 friend class KeyedLoadFastElementStub; | 1792 friend class KeyedLoadFastElementStub; |
1793 | 1793 |
1794 DISALLOW_COPY_AND_ASSIGN(HOptimizedGraphBuilder); | 1794 DISALLOW_COPY_AND_ASSIGN(HOptimizedGraphBuilder); |
1795 }; | 1795 }; |
1796 | 1796 |
1797 | 1797 |
1798 Zone* AstContext::zone() const { return owner_->zone(); } | 1798 Zone* AstContext::zone() const { return owner_->zone(); } |
1799 | 1799 |
1800 | 1800 |
1801 class HValueMap: public ZoneObject { | |
1802 public: | |
1803 explicit HValueMap(Zone* zone) | |
1804 : array_size_(0), | |
1805 lists_size_(0), | |
1806 count_(0), | |
1807 present_flags_(0), | |
1808 array_(NULL), | |
1809 lists_(NULL), | |
1810 free_list_head_(kNil) { | |
1811 ResizeLists(kInitialSize, zone); | |
1812 Resize(kInitialSize, zone); | |
1813 } | |
1814 | |
1815 void Kill(GVNFlagSet flags); | |
1816 | |
1817 void Add(HValue* value, Zone* zone) { | |
1818 present_flags_.Add(value->gvn_flags()); | |
1819 Insert(value, zone); | |
1820 } | |
1821 | |
1822 HValue* Lookup(HValue* value) const; | |
1823 | |
1824 HValueMap* Copy(Zone* zone) const { | |
1825 return new(zone) HValueMap(zone, this); | |
1826 } | |
1827 | |
1828 bool IsEmpty() const { return count_ == 0; } | |
1829 | |
1830 private: | |
1831 // A linked list of HValue* values. Stored in arrays. | |
1832 struct HValueMapListElement { | |
1833 HValue* value; | |
1834 int next; // Index in the array of the next list element. | |
1835 }; | |
1836 static const int kNil = -1; // The end of a linked list | |
1837 | |
1838 // Must be a power of 2. | |
1839 static const int kInitialSize = 16; | |
1840 | |
1841 HValueMap(Zone* zone, const HValueMap* other); | |
1842 | |
1843 void Resize(int new_size, Zone* zone); | |
1844 void ResizeLists(int new_size, Zone* zone); | |
1845 void Insert(HValue* value, Zone* zone); | |
1846 uint32_t Bound(uint32_t value) const { return value & (array_size_ - 1); } | |
1847 | |
1848 int array_size_; | |
1849 int lists_size_; | |
1850 int count_; // The number of values stored in the HValueMap. | |
1851 GVNFlagSet present_flags_; // All flags that are in any value in the | |
1852 // HValueMap. | |
1853 HValueMapListElement* array_; // Primary store - contains the first value | |
1854 // with a given hash. Colliding elements are stored in linked lists. | |
1855 HValueMapListElement* lists_; // The linked lists containing hash collisions. | |
1856 int free_list_head_; // Unused elements in lists_ are on the free list. | |
1857 }; | |
1858 | |
1859 | |
1860 class HSideEffectMap BASE_EMBEDDED { | |
1861 public: | |
1862 HSideEffectMap(); | |
1863 explicit HSideEffectMap(HSideEffectMap* other); | |
1864 HSideEffectMap& operator= (const HSideEffectMap& other); | |
1865 | |
1866 void Kill(GVNFlagSet flags); | |
1867 | |
1868 void Store(GVNFlagSet flags, HInstruction* instr); | |
1869 | |
1870 bool IsEmpty() const { return count_ == 0; } | |
1871 | |
1872 inline HInstruction* operator[](int i) const { | |
1873 ASSERT(0 <= i); | |
1874 ASSERT(i < kNumberOfTrackedSideEffects); | |
1875 return data_[i]; | |
1876 } | |
1877 inline HInstruction* at(int i) const { return operator[](i); } | |
1878 | |
1879 private: | |
1880 int count_; | |
1881 HInstruction* data_[kNumberOfTrackedSideEffects]; | |
1882 }; | |
1883 | |
1884 | |
1885 class HStatistics: public Malloced { | 1801 class HStatistics: public Malloced { |
1886 public: | 1802 public: |
1887 HStatistics() | 1803 HStatistics() |
1888 : timing_(5), | 1804 : timing_(5), |
1889 names_(5), | 1805 names_(5), |
1890 sizes_(5), | 1806 sizes_(5), |
1891 create_graph_(0), | 1807 create_graph_(0), |
1892 optimize_graph_(0), | 1808 optimize_graph_(0), |
1893 generate_code_(0), | 1809 generate_code_(0), |
1894 total_size_(0), | 1810 total_size_(0), |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2022 } | 1938 } |
2023 } | 1939 } |
2024 | 1940 |
2025 EmbeddedVector<char, 64> filename_; | 1941 EmbeddedVector<char, 64> filename_; |
2026 HeapStringAllocator string_allocator_; | 1942 HeapStringAllocator string_allocator_; |
2027 StringStream trace_; | 1943 StringStream trace_; |
2028 int indent_; | 1944 int indent_; |
2029 }; | 1945 }; |
2030 | 1946 |
2031 | 1947 |
1948 // Simple sparse set with O(1) add, contains, and clear. | |
1949 class SparseSet { | |
Sven Panne
2013/05/27 11:41:23
I think it makes sense to move this to a separate
titzer
2013/05/27 12:22:09
As discussed in-person, we can move this datastruc
| |
1950 public: | |
1951 SparseSet(Zone* zone, int capacity) | |
1952 : capacity_(capacity), | |
1953 length_(0), | |
1954 dense_(zone->NewArray<int>(capacity)), | |
1955 sparse_(zone->NewArray<int>(capacity)) { | |
1956 #ifndef NVALGRIND | |
1957 // Initialize the sparse array to make valgrind happy. | |
1958 memset(sparse_, 0, sizeof(sparse_[0]) * capacity); | |
1959 #endif | |
1960 } | |
1961 | |
1962 bool Contains(int n) const { | |
1963 ASSERT(0 <= n && n < capacity_); | |
1964 int d = sparse_[n]; | |
1965 return 0 <= d && d < length_ && dense_[d] == n; | |
1966 } | |
1967 | |
1968 bool Add(int n) { | |
1969 if (Contains(n)) return false; | |
1970 dense_[length_] = n; | |
1971 sparse_[n] = length_; | |
1972 ++length_; | |
1973 return true; | |
1974 } | |
1975 | |
1976 void Clear() { length_ = 0; } | |
1977 | |
1978 private: | |
1979 int capacity_; | |
1980 int length_; | |
1981 int* dense_; | |
1982 int* sparse_; | |
1983 | |
1984 DISALLOW_COPY_AND_ASSIGN(SparseSet); | |
1985 }; | |
1986 | |
1987 | |
1988 class HGlobalValueNumberer BASE_EMBEDDED { | |
Sven Panne
2013/05/27 11:41:23
To be consistent, this should really live in a new
titzer
2013/05/27 12:22:09
Done.
| |
1989 public: | |
1990 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) | |
1991 : graph_(graph), | |
1992 info_(info), | |
1993 removed_side_effects_(false), | |
1994 block_side_effects_(graph->blocks()->length(), graph->zone()), | |
1995 loop_side_effects_(graph->blocks()->length(), graph->zone()), | |
1996 visited_on_paths_(graph->zone(), graph->blocks()->length()) { | |
1997 #ifdef DEBUG | |
1998 ASSERT(info->isolate()->optimizing_compiler_thread()->IsOptimizerThread() || | |
1999 !info->isolate()->heap()->IsAllocationAllowed()); | |
2000 #endif | |
2001 block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(), | |
2002 graph_->zone()); | |
2003 loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(), | |
2004 graph_->zone()); | |
2005 } | |
2006 | |
2007 // Returns true if values with side effects are removed. | |
2008 bool Analyze(); | |
2009 | |
2010 private: | |
2011 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( | |
2012 HBasicBlock* dominator, | |
2013 HBasicBlock* dominated); | |
2014 void AnalyzeGraph(); | |
2015 void ComputeBlockSideEffects(); | |
2016 void LoopInvariantCodeMotion(); | |
2017 void ProcessLoopBlock(HBasicBlock* block, | |
2018 HBasicBlock* before_loop, | |
2019 GVNFlagSet loop_kills, | |
2020 GVNFlagSet* accumulated_first_time_depends, | |
2021 GVNFlagSet* accumulated_first_time_changes); | |
2022 bool AllowCodeMotion(); | |
2023 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); | |
2024 | |
2025 HGraph* graph() { return graph_; } | |
2026 CompilationInfo* info() { return info_; } | |
2027 Zone* zone() const { return graph_->zone(); } | |
2028 | |
2029 HGraph* graph_; | |
2030 CompilationInfo* info_; | |
2031 bool removed_side_effects_; | |
2032 | |
2033 // A map of block IDs to their side effects. | |
2034 ZoneList<GVNFlagSet> block_side_effects_; | |
2035 | |
2036 // A map of loop header block IDs to their loop's side effects. | |
2037 ZoneList<GVNFlagSet> loop_side_effects_; | |
2038 | |
2039 // Used when collecting side effects on paths from dominator to | |
2040 // dominated. | |
2041 SparseSet visited_on_paths_; | |
2042 }; | |
2043 | |
2044 | |
2032 } } // namespace v8::internal | 2045 } } // namespace v8::internal |
2033 | 2046 |
2034 #endif // V8_HYDROGEN_H_ | 2047 #endif // V8_HYDROGEN_H_ |
OLD | NEW |