Chromium Code Reviews| 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 |