annotate src/share/vm/opto/indexSet.hpp @ 1941:79d04223b8a5

Added caching for resolved types and resolved fields. This is crucial, because the local load elimination will lead to wrong results, if field equality (of two RiField objects with the same object and the same RiType) is not given. The caching makes sure that the default equals implementation is sufficient.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 28 Dec 2010 18:33:26 +0100
parents c18cbe5936b8
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
2 * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // This file defines the IndexSet class, a set of sparse integer indices.
a61af66fc99e Initial load
duke
parents:
diff changeset
26 // This data structure is used by the compiler in its liveness analysis and
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // during register allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 //-------------------------------- class IndexSet ----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // An IndexSet is a piece-wise bitvector. At the top level, we have an array
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // of pointers to bitvector chunks called BitBlocks. Each BitBlock has a fixed
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // size and is allocated from a shared free list. The bits which are set in
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // each BitBlock correspond to the elements of the set.
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 class IndexSet : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
36 friend class IndexSetIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // When we allocate an IndexSet, it starts off with an array of top level block
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // pointers of a set length. This size is intended to be large enough for the
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // majority of IndexSets. In the cases when this size is not large enough,
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // a separately allocated array is used.
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // The length of the preallocated top level block array
a61af66fc99e Initial load
duke
parents:
diff changeset
45 enum { preallocated_block_list_size = 16 };
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // Elements of a IndexSet get decomposed into three fields. The highest order
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // bits are the block index, which tell which high level block holds the element.
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // Within that block, the word index indicates which word holds the element.
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Finally, the bit index determines which single bit within that word indicates
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // membership of the element in the set.
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // The lengths of the index bitfields
a61af66fc99e Initial load
duke
parents:
diff changeset
54 enum { bit_index_length = 5,
a61af66fc99e Initial load
duke
parents:
diff changeset
55 word_index_length = 3,
a61af66fc99e Initial load
duke
parents:
diff changeset
56 block_index_length = 8 // not used
a61af66fc99e Initial load
duke
parents:
diff changeset
57 };
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // Derived constants used for manipulating the index bitfields
a61af66fc99e Initial load
duke
parents:
diff changeset
60 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 bit_index_offset = 0, // not used
a61af66fc99e Initial load
duke
parents:
diff changeset
62 word_index_offset = bit_index_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
63 block_index_offset = bit_index_length + word_index_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 bits_per_word = 1 << bit_index_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
66 words_per_block = 1 << word_index_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
67 bits_per_block = bits_per_word * words_per_block,
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 bit_index_mask = right_n_bits(bit_index_length),
a61af66fc99e Initial load
duke
parents:
diff changeset
70 word_index_mask = right_n_bits(word_index_length)
a61af66fc99e Initial load
duke
parents:
diff changeset
71 };
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // These routines are used for extracting the block, word, and bit index
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // from an element.
a61af66fc99e Initial load
duke
parents:
diff changeset
75 static uint get_block_index(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 return element >> block_index_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78 static uint get_word_index(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 return mask_bits(element >> word_index_offset,word_index_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81 static uint get_bit_index(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 return mask_bits(element,bit_index_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 //------------------------------ class BitBlock ----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // The BitBlock class is a segment of a bitvector set.
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 class BitBlock : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 friend class IndexSetIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 friend class IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // All of BitBlocks fields and methods are declared private. We limit
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // access to IndexSet and IndexSetIterator.
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // A BitBlock is composed of some number of 32 bit words. When a BitBlock
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // is not in use by any IndexSet, it is stored on a free list. The next field
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // is used by IndexSet to mainting this free list.
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 union {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 uint32 _words[words_per_block];
a61af66fc99e Initial load
duke
parents:
diff changeset
102 BitBlock *_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 } _data;
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
106 uint32 *words() { return _data._words; }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 void set_next(BitBlock *next) { _data._next = next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
108 BitBlock *next() { return _data._next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // Operations. A BitBlock supports four simple operations,
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // clear(), member(), insert(), and remove(). These methods do
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // not assume that the block index has been masked out.
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 memset(words(), 0, sizeof(uint32) * words_per_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 bool member(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 uint word_index = IndexSet::get_word_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 uint bit_index = IndexSet::get_bit_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 return ((words()[word_index] & (uint32)(0x1 << bit_index)) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 bool insert(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 uint word_index = IndexSet::get_word_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
127 uint bit_index = IndexSet::get_bit_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 uint32 bit = (0x1 << bit_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
130 uint32 before = words()[word_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
131 words()[word_index] = before | bit;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 return ((before & bit) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 bool remove(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 uint word_index = IndexSet::get_word_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 uint bit_index = IndexSet::get_bit_index(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 uint32 bit = (0x1 << bit_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
140 uint32 before = words()[word_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
141 words()[word_index] = before & ~bit;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 return ((before & bit) != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144 };
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 //-------------------------- BitBlock allocation ---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
147 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // All IndexSets share an arena from which they allocate BitBlocks. Unused
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // BitBlocks are placed on a free list.
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // The number of BitBlocks to allocate at a time
a61af66fc99e Initial load
duke
parents:
diff changeset
153 enum { bitblock_alloc_chunk_size = 50 };
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 static Arena *arena() { return Compile::current()->indexSet_arena(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 static void populate_free_list();
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // Invalidate the current free BitBlock list and begin allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // from a new arena. It is essential that this method is called whenever
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // the Arena being used for BitBlock allocation is reset.
a61af66fc99e Initial load
duke
parents:
diff changeset
164 static void reset_memory(Compile* compile, Arena *arena) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 compile->set_indexSet_free_block_list(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 compile->set_indexSet_arena(arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // This should probably be done in a static initializer
a61af66fc99e Initial load
duke
parents:
diff changeset
169 _empty_block.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
173 friend class BitBlock;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // A distinguished BitBlock which always remains empty. When a new IndexSet is
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // created, all of its top level BitBlock pointers are initialized to point to
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // this.
a61af66fc99e Initial load
duke
parents:
diff changeset
177 static BitBlock _empty_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 //-------------------------- Members ------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // The number of elements in the set
a61af66fc99e Initial load
duke
parents:
diff changeset
182 uint _count;
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Our top level array of bitvector segments
a61af66fc99e Initial load
duke
parents:
diff changeset
185 BitBlock **_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 BitBlock *_preallocated_block_list[preallocated_block_list_size];
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // The number of top level array entries in use
a61af66fc99e Initial load
duke
parents:
diff changeset
190 uint _max_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // Our assertions need to know the maximum number allowed in the set
a61af66fc99e Initial load
duke
parents:
diff changeset
193 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
194 uint _max_elements;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // The next IndexSet on the free list (not used at same time as count)
a61af66fc99e Initial load
duke
parents:
diff changeset
198 IndexSet *_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
201 //-------------------------- Free list operations ------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // Individual IndexSets can be placed on a free list. This is done in PhaseLive.
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 IndexSet *next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
206 if( VerifyOpto ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
207 check_watch("removed from free list?", ((_next == NULL) ? 0 : _next->_serial_number));
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
210 return _next;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 void set_next(IndexSet *next) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
215 if( VerifyOpto ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 check_watch("put on free list?", ((next == NULL) ? 0 : next->_serial_number));
a61af66fc99e Initial load
duke
parents:
diff changeset
217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
218 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
219 _next = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
223 //-------------------------- Utility methods -----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // Get the block which holds element
a61af66fc99e Initial load
duke
parents:
diff changeset
226 BitBlock *get_block_containing(uint element) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 assert(element < _max_elements, "element out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 return _blocks[get_block_index(element)];
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // Set a block in the top level array
a61af66fc99e Initial load
duke
parents:
diff changeset
232 void set_block(uint index, BitBlock *block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
234 if( VerifyOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
235 check_watch("set block", index);
a61af66fc99e Initial load
duke
parents:
diff changeset
236 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
237 _blocks[index] = block;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // Get a BitBlock from the free list
a61af66fc99e Initial load
duke
parents:
diff changeset
241 BitBlock *alloc_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // Get a BitBlock from the free list and place it in the top level array
a61af66fc99e Initial load
duke
parents:
diff changeset
244 BitBlock *alloc_block_containing(uint element);
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // Free a block from the top level array, placing it on the free BitBlock list
a61af66fc99e Initial load
duke
parents:
diff changeset
247 void free_block(uint i);
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
250 //-------------------------- Primitive set operations --------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
254 if( VerifyOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
255 check_watch("clear");
a61af66fc99e Initial load
duke
parents:
diff changeset
256 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
257 _count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
258 for (uint i = 0; i < _max_blocks; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 BitBlock *block = _blocks[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (block != &_empty_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 free_block(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 uint count() const { return _count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 bool is_empty() const { return _count == 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 bool member(uint element) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 return get_block_containing(element)->member(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
273
a61af66fc99e Initial load
duke
parents:
diff changeset
274 bool insert(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
275 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
276 if( VerifyOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
277 check_watch("insert", element);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
279 if (element == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
280 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 BitBlock *block = get_block_containing(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
283 if (block == &_empty_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 block = alloc_block_containing(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 bool present = block->insert(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (!present) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 _count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 return !present;
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 bool remove(uint element) {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
295 if( VerifyOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
296 check_watch("remove", element);
a61af66fc99e Initial load
duke
parents:
diff changeset
297 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 BitBlock *block = get_block_containing(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 bool present = block->remove(element);
a61af66fc99e Initial load
duke
parents:
diff changeset
301 if (present) {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 _count--;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
304 return present;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307 //-------------------------- Compound set operations ------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // Compute the union of all elements of one and two which interfere
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // with the RegMask mask. If the degree of the union becomes
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // exceeds fail_degree, the union bails out. The underlying set is
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // cleared before the union is performed.
a61af66fc99e Initial load
duke
parents:
diff changeset
312 uint lrg_union(uint lr1, uint lr2,
a61af66fc99e Initial load
duke
parents:
diff changeset
313 const uint fail_degree,
a61af66fc99e Initial load
duke
parents:
diff changeset
314 const class PhaseIFG *ifg,
a61af66fc99e Initial load
duke
parents:
diff changeset
315 const RegMask &mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317
a61af66fc99e Initial load
duke
parents:
diff changeset
318 //------------------------- Construction, initialization -----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 IndexSet() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
321
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // This constructor is used for making a deep copy of a IndexSet.
a61af66fc99e Initial load
duke
parents:
diff changeset
323 IndexSet(IndexSet *set);
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // Perform initialization on a IndexSet
a61af66fc99e Initial load
duke
parents:
diff changeset
326 void initialize(uint max_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // Initialize a IndexSet. If the top level BitBlock array needs to be
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // allocated, do it from the proffered arena. BitBlocks are still allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // from the static Arena member.
a61af66fc99e Initial load
duke
parents:
diff changeset
331 void initialize(uint max_element, Arena *arena);
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // Exchange two sets
a61af66fc99e Initial load
duke
parents:
diff changeset
334 void swap(IndexSet *set);
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 //-------------------------- Debugging and statistics --------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // Output a IndexSet for debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
340 void dump() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
341 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
344 void tally_iteration_statistics() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // BitBlock allocation statistics
a61af66fc99e Initial load
duke
parents:
diff changeset
347 static uint _alloc_new;
a61af66fc99e Initial load
duke
parents:
diff changeset
348 static uint _alloc_total;
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // Block density statistics
a61af66fc99e Initial load
duke
parents:
diff changeset
351 static long _total_bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 static long _total_used_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
353 static long _total_unused_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // Sanity tests
a61af66fc99e Initial load
duke
parents:
diff changeset
356 void verify() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 static int _serial_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
359 int _serial_number;
a61af66fc99e Initial load
duke
parents:
diff changeset
360
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // Check to see if the serial number of the current set is the one we're tracing.
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // If it is, print a message.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 void check_watch(const char *operation, uint operand) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
364 if (IndexSetWatch != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
365 if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 tty->print_cr("IndexSet %d : %s ( %d )", _serial_number, operation, operand);
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369 }
a61af66fc99e Initial load
duke
parents:
diff changeset
370 void check_watch(const char *operation) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 if (IndexSetWatch != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 tty->print_cr("IndexSet %d : %s", _serial_number, operation);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
379 static void print_statistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
382 };
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384
a61af66fc99e Initial load
duke
parents:
diff changeset
385 //-------------------------------- class IndexSetIterator --------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // An iterator for IndexSets.
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 class IndexSetIterator VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
389 friend class IndexSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // We walk over the bits in a word in chunks of size window_size.
a61af66fc99e Initial load
duke
parents:
diff changeset
394 enum { window_size = 5,
a61af66fc99e Initial load
duke
parents:
diff changeset
395 window_mask = right_n_bits(window_size),
a61af66fc99e Initial load
duke
parents:
diff changeset
396 table_size = (1 << window_size) };
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // For an integer of length window_size, what is the first set bit?
a61af66fc99e Initial load
duke
parents:
diff changeset
399 static const byte _first_bit[table_size];
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // For an integer of length window_size, what is the second set bit?
a61af66fc99e Initial load
duke
parents:
diff changeset
402 static const byte _second_bit[table_size];
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // The current word we are inspecting
a61af66fc99e Initial load
duke
parents:
diff changeset
406 uint32 _current;
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // What element number are we currently on?
a61af66fc99e Initial load
duke
parents:
diff changeset
409 uint _value;
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // The index of the next word we will inspect
a61af66fc99e Initial load
duke
parents:
diff changeset
412 uint _next_word;
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // A pointer to the contents of the current block
a61af66fc99e Initial load
duke
parents:
diff changeset
415 uint32 *_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // The index of the next block we will inspect
a61af66fc99e Initial load
duke
parents:
diff changeset
418 uint _next_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // A pointer to the blocks in our set
a61af66fc99e Initial load
duke
parents:
diff changeset
421 IndexSet::BitBlock **_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // The number of blocks in the set
a61af66fc99e Initial load
duke
parents:
diff changeset
424 uint _max_blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // If the iterator was created from a non-const set, we replace
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // non-canonical empty blocks with the _empty_block pointer. If
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // _set is NULL, we do no replacement.
a61af66fc99e Initial load
duke
parents:
diff changeset
429 IndexSet *_set;
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // Advance to the next non-empty word and return the next
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // element in the set.
a61af66fc99e Initial load
duke
parents:
diff changeset
433 uint advance_and_next();
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // If an iterator is built from a constant set then empty blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // are not canonicalized.
a61af66fc99e Initial load
duke
parents:
diff changeset
440 IndexSetIterator(IndexSet *set);
a61af66fc99e Initial load
duke
parents:
diff changeset
441 IndexSetIterator(const IndexSet *set);
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // Return the next element of the set. Return 0 when done.
a61af66fc99e Initial load
duke
parents:
diff changeset
444 uint next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
445 uint current = _current;
a61af66fc99e Initial load
duke
parents:
diff changeset
446 if (current != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
447 uint value = _value;
a61af66fc99e Initial load
duke
parents:
diff changeset
448 while (mask_bits(current,window_mask) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 current >>= window_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
450 value += window_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
452
a61af66fc99e Initial load
duke
parents:
diff changeset
453 uint advance = _second_bit[mask_bits(current,window_mask)];
a61af66fc99e Initial load
duke
parents:
diff changeset
454 _current = current >> advance;
a61af66fc99e Initial load
duke
parents:
diff changeset
455 _value = value + advance;
a61af66fc99e Initial load
duke
parents:
diff changeset
456 return value + _first_bit[mask_bits(current,window_mask)];
a61af66fc99e Initial load
duke
parents:
diff changeset
457 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 return advance_and_next();
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461 };