Mercurial > hg > graal-compiler
annotate src/share/vm/ci/ciTypeFlow.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 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
380
diff
changeset
|
2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
380
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
380
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:
380
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 | |
26 class ciTypeFlow : public ResourceObj { | |
27 private: | |
28 ciEnv* _env; | |
29 ciMethod* _method; | |
30 ciMethodBlocks* _methodBlocks; | |
31 int _osr_bci; | |
32 | |
33 // information cached from the method: | |
34 int _max_locals; | |
35 int _max_stack; | |
36 int _code_size; | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
37 bool _has_irreducible_entry; |
0 | 38 |
39 const char* _failure_reason; | |
40 | |
41 public: | |
42 class StateVector; | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
43 class Loop; |
0 | 44 class Block; |
45 | |
46 // Build a type flow analyzer | |
47 // Do an OSR analysis if osr_bci >= 0. | |
48 ciTypeFlow(ciEnv* env, ciMethod* method, int osr_bci = InvocationEntryBci); | |
49 | |
50 // Accessors | |
51 ciMethod* method() const { return _method; } | |
52 ciEnv* env() { return _env; } | |
53 Arena* arena() { return _env->arena(); } | |
54 bool is_osr_flow() const{ return _osr_bci != InvocationEntryBci; } | |
55 int start_bci() const { return is_osr_flow()? _osr_bci: 0; } | |
56 int max_locals() const { return _max_locals; } | |
57 int max_stack() const { return _max_stack; } | |
58 int max_cells() const { return _max_locals + _max_stack; } | |
59 int code_size() const { return _code_size; } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
60 bool has_irreducible_entry() const { return _has_irreducible_entry; } |
0 | 61 |
62 // Represents information about an "active" jsr call. This | |
63 // class represents a call to the routine at some entry address | |
64 // with some distinct return address. | |
65 class JsrRecord : public ResourceObj { | |
66 private: | |
67 int _entry_address; | |
68 int _return_address; | |
69 public: | |
70 JsrRecord(int entry_address, int return_address) { | |
71 _entry_address = entry_address; | |
72 _return_address = return_address; | |
73 } | |
74 | |
75 int entry_address() const { return _entry_address; } | |
76 int return_address() const { return _return_address; } | |
77 | |
78 void print_on(outputStream* st) const { | |
79 #ifndef PRODUCT | |
80 st->print("%d->%d", entry_address(), return_address()); | |
81 #endif | |
82 } | |
83 }; | |
84 | |
85 // A JsrSet represents some set of JsrRecords. This class | |
86 // is used to record a set of all jsr routines which we permit | |
87 // execution to return (ret) from. | |
88 // | |
89 // During abstract interpretation, JsrSets are used to determine | |
90 // whether two paths which reach a given block are unique, and | |
91 // should be cloned apart, or are compatible, and should merge | |
92 // together. | |
93 // | |
94 // Note that different amounts of effort can be expended determining | |
95 // if paths are compatible. <DISCUSSION> | |
96 class JsrSet : public ResourceObj { | |
97 private: | |
98 GrowableArray<JsrRecord*>* _set; | |
99 | |
100 JsrRecord* record_at(int i) { | |
101 return _set->at(i); | |
102 } | |
103 | |
104 // Insert the given JsrRecord into the JsrSet, maintaining the order | |
105 // of the set and replacing any element with the same entry address. | |
106 void insert_jsr_record(JsrRecord* record); | |
107 | |
108 // Remove the JsrRecord with the given return address from the JsrSet. | |
109 void remove_jsr_record(int return_address); | |
110 | |
111 public: | |
112 JsrSet(Arena* arena, int default_len = 4); | |
113 | |
114 // Copy this JsrSet. | |
115 void copy_into(JsrSet* jsrs); | |
116 | |
117 // Is this JsrSet compatible with some other JsrSet? | |
118 bool is_compatible_with(JsrSet* other); | |
119 | |
120 // Apply the effect of a single bytecode to the JsrSet. | |
121 void apply_control(ciTypeFlow* analyzer, | |
122 ciBytecodeStream* str, | |
123 StateVector* state); | |
124 | |
125 // What is the cardinality of this set? | |
126 int size() const { return _set->length(); } | |
127 | |
128 void print_on(outputStream* st) const PRODUCT_RETURN; | |
129 }; | |
130 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
131 class LocalSet VALUE_OBJ_CLASS_SPEC { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
132 private: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
133 enum Constants { max = 63 }; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
134 uint64_t _bits; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
135 public: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
136 LocalSet() : _bits(0) {} |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
137 void add(uint32_t i) { if (i < (uint32_t)max) _bits |= (1LL << i); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
138 void add(LocalSet* ls) { _bits |= ls->_bits; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
139 bool test(uint32_t i) const { return i < (uint32_t)max ? (_bits>>i)&1U : true; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
140 void clear() { _bits = 0; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
141 void print_on(outputStream* st, int limit) const PRODUCT_RETURN; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
142 }; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
143 |
0 | 144 // Used as a combined index for locals and temps |
145 enum Cell { | |
303 | 146 Cell_0, Cell_max = INT_MAX |
0 | 147 }; |
148 | |
149 // A StateVector summarizes the type information at some | |
150 // point in the program | |
151 class StateVector : public ResourceObj { | |
152 private: | |
153 ciType** _types; | |
154 int _stack_size; | |
155 int _monitor_count; | |
156 ciTypeFlow* _outer; | |
157 | |
158 int _trap_bci; | |
159 int _trap_index; | |
160 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
161 LocalSet _def_locals; // For entire block |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
162 |
0 | 163 static ciType* type_meet_internal(ciType* t1, ciType* t2, ciTypeFlow* analyzer); |
164 | |
165 public: | |
166 // Special elements in our type lattice. | |
167 enum { | |
168 T_TOP = T_VOID, // why not? | |
169 T_BOTTOM = T_CONFLICT, | |
170 T_LONG2 = T_SHORT, // 2nd word of T_LONG | |
171 T_DOUBLE2 = T_CHAR, // 2nd word of T_DOUBLE | |
172 T_NULL = T_BYTE // for now. | |
173 }; | |
174 static ciType* top_type() { return ciType::make((BasicType)T_TOP); } | |
175 static ciType* bottom_type() { return ciType::make((BasicType)T_BOTTOM); } | |
176 static ciType* long2_type() { return ciType::make((BasicType)T_LONG2); } | |
177 static ciType* double2_type(){ return ciType::make((BasicType)T_DOUBLE2); } | |
178 static ciType* null_type() { return ciType::make((BasicType)T_NULL); } | |
179 | |
180 static ciType* half_type(ciType* t) { | |
181 switch (t->basic_type()) { | |
182 case T_LONG: return long2_type(); | |
183 case T_DOUBLE: return double2_type(); | |
184 default: ShouldNotReachHere(); return NULL; | |
185 } | |
186 } | |
187 | |
188 // The meet operation for our type lattice. | |
189 ciType* type_meet(ciType* t1, ciType* t2) { | |
190 return type_meet_internal(t1, t2, outer()); | |
191 } | |
192 | |
193 // Accessors | |
194 ciTypeFlow* outer() const { return _outer; } | |
195 | |
196 int stack_size() const { return _stack_size; } | |
197 void set_stack_size(int ss) { _stack_size = ss; } | |
198 | |
199 int monitor_count() const { return _monitor_count; } | |
200 void set_monitor_count(int mc) { _monitor_count = mc; } | |
201 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
202 LocalSet* def_locals() { return &_def_locals; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
203 const LocalSet* def_locals() const { return &_def_locals; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
204 |
0 | 205 static Cell start_cell() { return (Cell)0; } |
206 static Cell next_cell(Cell c) { return (Cell)(((int)c) + 1); } | |
207 Cell limit_cell() const { | |
208 return (Cell)(outer()->max_locals() + stack_size()); | |
209 } | |
210 | |
211 // Cell creation | |
212 Cell local(int lnum) const { | |
213 assert(lnum < outer()->max_locals(), "index check"); | |
214 return (Cell)(lnum); | |
215 } | |
216 | |
217 Cell stack(int snum) const { | |
218 assert(snum < stack_size(), "index check"); | |
219 return (Cell)(outer()->max_locals() + snum); | |
220 } | |
221 | |
222 Cell tos() const { return stack(stack_size()-1); } | |
223 | |
224 // For external use only: | |
225 ciType* local_type_at(int i) const { return type_at(local(i)); } | |
226 ciType* stack_type_at(int i) const { return type_at(stack(i)); } | |
227 | |
228 // Accessors for the type of some Cell c | |
229 ciType* type_at(Cell c) const { | |
230 assert(start_cell() <= c && c < limit_cell(), "out of bounds"); | |
231 return _types[c]; | |
232 } | |
233 | |
234 void set_type_at(Cell c, ciType* type) { | |
235 assert(start_cell() <= c && c < limit_cell(), "out of bounds"); | |
236 _types[c] = type; | |
237 } | |
238 | |
239 // Top-of-stack operations. | |
240 void set_type_at_tos(ciType* type) { set_type_at(tos(), type); } | |
241 ciType* type_at_tos() const { return type_at(tos()); } | |
242 | |
243 void push(ciType* type) { | |
244 _stack_size++; | |
245 set_type_at_tos(type); | |
246 } | |
247 void pop() { | |
248 debug_only(set_type_at_tos(bottom_type())); | |
249 _stack_size--; | |
250 } | |
251 ciType* pop_value() { | |
252 ciType* t = type_at_tos(); | |
253 pop(); | |
254 return t; | |
255 } | |
256 | |
257 // Convenience operations. | |
258 bool is_reference(ciType* type) const { | |
259 return type == null_type() || !type->is_primitive_type(); | |
260 } | |
261 bool is_int(ciType* type) const { | |
262 return type->basic_type() == T_INT; | |
263 } | |
264 bool is_long(ciType* type) const { | |
265 return type->basic_type() == T_LONG; | |
266 } | |
267 bool is_float(ciType* type) const { | |
268 return type->basic_type() == T_FLOAT; | |
269 } | |
270 bool is_double(ciType* type) const { | |
271 return type->basic_type() == T_DOUBLE; | |
272 } | |
273 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
274 void store_to_local(int lnum) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
275 _def_locals.add((uint) lnum); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
276 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
277 |
0 | 278 void push_translate(ciType* type); |
279 | |
280 void push_int() { | |
281 push(ciType::make(T_INT)); | |
282 } | |
283 void pop_int() { | |
284 assert(is_int(type_at_tos()), "must be integer"); | |
285 pop(); | |
286 } | |
287 void check_int(Cell c) { | |
288 assert(is_int(type_at(c)), "must be integer"); | |
289 } | |
290 void push_double() { | |
291 push(ciType::make(T_DOUBLE)); | |
292 push(double2_type()); | |
293 } | |
294 void pop_double() { | |
295 assert(type_at_tos() == double2_type(), "must be 2nd half"); | |
296 pop(); | |
297 assert(is_double(type_at_tos()), "must be double"); | |
298 pop(); | |
299 } | |
300 void push_float() { | |
301 push(ciType::make(T_FLOAT)); | |
302 } | |
303 void pop_float() { | |
304 assert(is_float(type_at_tos()), "must be float"); | |
305 pop(); | |
306 } | |
307 void push_long() { | |
308 push(ciType::make(T_LONG)); | |
309 push(long2_type()); | |
310 } | |
311 void pop_long() { | |
312 assert(type_at_tos() == long2_type(), "must be 2nd half"); | |
313 pop(); | |
314 assert(is_long(type_at_tos()), "must be long"); | |
315 pop(); | |
316 } | |
317 void push_object(ciKlass* klass) { | |
318 push(klass); | |
319 } | |
320 void pop_object() { | |
321 assert(is_reference(type_at_tos()), "must be reference type"); | |
322 pop(); | |
323 } | |
324 void pop_array() { | |
325 assert(type_at_tos() == null_type() || | |
326 type_at_tos()->is_array_klass(), "must be array type"); | |
327 pop(); | |
328 } | |
329 // pop_objArray and pop_typeArray narrow the tos to ciObjArrayKlass | |
330 // or ciTypeArrayKlass (resp.). In the rare case that an explicit | |
331 // null is popped from the stack, we return NULL. Caller beware. | |
332 ciObjArrayKlass* pop_objArray() { | |
333 ciType* array = pop_value(); | |
334 if (array == null_type()) return NULL; | |
335 assert(array->is_obj_array_klass(), "must be object array type"); | |
336 return array->as_obj_array_klass(); | |
337 } | |
338 ciTypeArrayKlass* pop_typeArray() { | |
339 ciType* array = pop_value(); | |
340 if (array == null_type()) return NULL; | |
341 assert(array->is_type_array_klass(), "must be prim array type"); | |
342 return array->as_type_array_klass(); | |
343 } | |
344 void push_null() { | |
345 push(null_type()); | |
346 } | |
347 void do_null_assert(ciKlass* unloaded_klass); | |
348 | |
349 // Helper convenience routines. | |
350 void do_aaload(ciBytecodeStream* str); | |
351 void do_checkcast(ciBytecodeStream* str); | |
352 void do_getfield(ciBytecodeStream* str); | |
353 void do_getstatic(ciBytecodeStream* str); | |
354 void do_invoke(ciBytecodeStream* str, bool has_receiver); | |
355 void do_jsr(ciBytecodeStream* str); | |
356 void do_ldc(ciBytecodeStream* str); | |
357 void do_multianewarray(ciBytecodeStream* str); | |
358 void do_new(ciBytecodeStream* str); | |
359 void do_newarray(ciBytecodeStream* str); | |
360 void do_putfield(ciBytecodeStream* str); | |
361 void do_putstatic(ciBytecodeStream* str); | |
362 void do_ret(ciBytecodeStream* str); | |
363 | |
364 void overwrite_local_double_long(int index) { | |
365 // Invalidate the previous local if it contains first half of | |
366 // a double or long value since it's seconf half is being overwritten. | |
367 int prev_index = index - 1; | |
368 if (prev_index >= 0 && | |
369 (is_double(type_at(local(prev_index))) || | |
370 is_long(type_at(local(prev_index))))) { | |
371 set_type_at(local(prev_index), bottom_type()); | |
372 } | |
373 } | |
374 | |
375 void load_local_object(int index) { | |
376 ciType* type = type_at(local(index)); | |
377 assert(is_reference(type), "must be reference type"); | |
378 push(type); | |
379 } | |
380 void store_local_object(int index) { | |
381 ciType* type = pop_value(); | |
382 assert(is_reference(type) || type->is_return_address(), | |
383 "must be reference type or return address"); | |
384 overwrite_local_double_long(index); | |
385 set_type_at(local(index), type); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
386 store_to_local(index); |
0 | 387 } |
388 | |
389 void load_local_double(int index) { | |
390 ciType* type = type_at(local(index)); | |
391 ciType* type2 = type_at(local(index+1)); | |
392 assert(is_double(type), "must be double type"); | |
393 assert(type2 == double2_type(), "must be 2nd half"); | |
394 push(type); | |
395 push(double2_type()); | |
396 } | |
397 void store_local_double(int index) { | |
398 ciType* type2 = pop_value(); | |
399 ciType* type = pop_value(); | |
400 assert(is_double(type), "must be double"); | |
401 assert(type2 == double2_type(), "must be 2nd half"); | |
402 overwrite_local_double_long(index); | |
403 set_type_at(local(index), type); | |
404 set_type_at(local(index+1), type2); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
405 store_to_local(index); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
406 store_to_local(index+1); |
0 | 407 } |
408 | |
409 void load_local_float(int index) { | |
410 ciType* type = type_at(local(index)); | |
411 assert(is_float(type), "must be float type"); | |
412 push(type); | |
413 } | |
414 void store_local_float(int index) { | |
415 ciType* type = pop_value(); | |
416 assert(is_float(type), "must be float type"); | |
417 overwrite_local_double_long(index); | |
418 set_type_at(local(index), type); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
419 store_to_local(index); |
0 | 420 } |
421 | |
422 void load_local_int(int index) { | |
423 ciType* type = type_at(local(index)); | |
424 assert(is_int(type), "must be int type"); | |
425 push(type); | |
426 } | |
427 void store_local_int(int index) { | |
428 ciType* type = pop_value(); | |
429 assert(is_int(type), "must be int type"); | |
430 overwrite_local_double_long(index); | |
431 set_type_at(local(index), type); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
432 store_to_local(index); |
0 | 433 } |
434 | |
435 void load_local_long(int index) { | |
436 ciType* type = type_at(local(index)); | |
437 ciType* type2 = type_at(local(index+1)); | |
438 assert(is_long(type), "must be long type"); | |
439 assert(type2 == long2_type(), "must be 2nd half"); | |
440 push(type); | |
441 push(long2_type()); | |
442 } | |
443 void store_local_long(int index) { | |
444 ciType* type2 = pop_value(); | |
445 ciType* type = pop_value(); | |
446 assert(is_long(type), "must be long"); | |
447 assert(type2 == long2_type(), "must be 2nd half"); | |
448 overwrite_local_double_long(index); | |
449 set_type_at(local(index), type); | |
450 set_type_at(local(index+1), type2); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
451 store_to_local(index); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
452 store_to_local(index+1); |
0 | 453 } |
454 | |
455 // Stop interpretation of this path with a trap. | |
456 void trap(ciBytecodeStream* str, ciKlass* klass, int index); | |
457 | |
458 public: | |
459 StateVector(ciTypeFlow* outer); | |
460 | |
461 // Copy our value into some other StateVector | |
462 void copy_into(StateVector* copy) const; | |
463 | |
464 // Meets this StateVector with another, destructively modifying this | |
465 // one. Returns true if any modification takes place. | |
466 bool meet(const StateVector* incoming); | |
467 | |
468 // Ditto, except that the incoming state is coming from an exception. | |
469 bool meet_exception(ciInstanceKlass* exc, const StateVector* incoming); | |
470 | |
471 // Apply the effect of one bytecode to this StateVector | |
472 bool apply_one_bytecode(ciBytecodeStream* stream); | |
473 | |
474 // What is the bci of the trap? | |
475 int trap_bci() { return _trap_bci; } | |
476 | |
477 // What is the index associated with the trap? | |
478 int trap_index() { return _trap_index; } | |
479 | |
480 void print_cell_on(outputStream* st, Cell c) const PRODUCT_RETURN; | |
481 void print_on(outputStream* st) const PRODUCT_RETURN; | |
482 }; | |
483 | |
484 // Parameter for "find_block" calls: | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
485 // Describes the difference between a public and backedge copy. |
0 | 486 enum CreateOption { |
487 create_public_copy, | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
488 create_backedge_copy, |
0 | 489 no_create |
490 }; | |
491 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
492 // Successor iterator |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
493 class SuccIter : public StackObj { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
494 private: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
495 Block* _pred; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
496 int _index; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
497 Block* _succ; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
498 public: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
499 SuccIter() : _pred(NULL), _index(-1), _succ(NULL) {} |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
500 SuccIter(Block* pred) : _pred(pred), _index(-1), _succ(NULL) { next(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
501 int index() { return _index; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
502 Block* pred() { return _pred; } // Return predecessor |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
503 bool done() { return _index < 0; } // Finished? |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
504 Block* succ() { return _succ; } // Return current successor |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
505 void next(); // Advance |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
506 void set_succ(Block* succ); // Update current successor |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
507 bool is_normal_ctrl() { return index() < _pred->successors()->length(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
508 }; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
509 |
0 | 510 // A basic block |
511 class Block : public ResourceObj { | |
512 private: | |
513 ciBlock* _ciblock; | |
514 GrowableArray<Block*>* _exceptions; | |
515 GrowableArray<ciInstanceKlass*>* _exc_klasses; | |
516 GrowableArray<Block*>* _successors; | |
517 StateVector* _state; | |
518 JsrSet* _jsrs; | |
519 | |
520 int _trap_bci; | |
521 int _trap_index; | |
522 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
523 // pre_order, assigned at first visit. Used as block ID and "visited" tag |
0 | 524 int _pre_order; |
525 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
526 // A post-order, used to compute the reverse post order (RPO) provided to the client |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
527 int _post_order; // used to compute rpo |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
528 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
529 // Has this block been cloned for a loop backedge? |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
530 bool _backedge_copy; |
0 | 531 |
532 // A pointer used for our internal work list | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
533 Block* _next; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
534 bool _on_work_list; // on the work list |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
535 Block* _rpo_next; // Reverse post order list |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
536 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
537 // Loop info |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
538 Loop* _loop; // nearest loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
539 bool _irreducible_entry; // entry to irreducible loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
540 bool _exception_entry; // entry to exception handler |
0 | 541 |
542 ciBlock* ciblock() const { return _ciblock; } | |
543 StateVector* state() const { return _state; } | |
544 | |
545 // Compute the exceptional successors and types for this Block. | |
546 void compute_exceptions(); | |
547 | |
548 public: | |
549 // constructors | |
550 Block(ciTypeFlow* outer, ciBlock* ciblk, JsrSet* jsrs); | |
551 | |
552 void set_trap(int trap_bci, int trap_index) { | |
553 _trap_bci = trap_bci; | |
554 _trap_index = trap_index; | |
555 assert(has_trap(), ""); | |
556 } | |
557 bool has_trap() const { return _trap_bci != -1; } | |
558 int trap_bci() const { assert(has_trap(), ""); return _trap_bci; } | |
559 int trap_index() const { assert(has_trap(), ""); return _trap_index; } | |
560 | |
561 // accessors | |
562 ciTypeFlow* outer() const { return state()->outer(); } | |
563 int start() const { return _ciblock->start_bci(); } | |
564 int limit() const { return _ciblock->limit_bci(); } | |
565 int control() const { return _ciblock->control_bci(); } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
566 JsrSet* jsrs() const { return _jsrs; } |
0 | 567 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
568 bool is_backedge_copy() const { return _backedge_copy; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
569 void set_backedge_copy(bool z); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
570 int backedge_copy_count() const { return outer()->backedge_copy_count(ciblock()->index(), _jsrs); } |
0 | 571 |
572 // access to entry state | |
573 int stack_size() const { return _state->stack_size(); } | |
574 int monitor_count() const { return _state->monitor_count(); } | |
575 ciType* local_type_at(int i) const { return _state->local_type_at(i); } | |
576 ciType* stack_type_at(int i) const { return _state->stack_type_at(i); } | |
577 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
578 // Data flow on locals |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
579 bool is_invariant_local(uint v) const { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
580 assert(is_loop_head(), "only loop heads"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
581 // Find outermost loop with same loop head |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
582 Loop* lp = loop(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
583 while (lp->parent() != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
584 if (lp->parent()->head() != lp->head()) break; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
585 lp = lp->parent(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
586 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
587 return !lp->def_locals()->test(v); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
588 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
589 LocalSet* def_locals() { return _state->def_locals(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
590 const LocalSet* def_locals() const { return _state->def_locals(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
591 |
0 | 592 // Get the successors for this Block. |
593 GrowableArray<Block*>* successors(ciBytecodeStream* str, | |
594 StateVector* state, | |
595 JsrSet* jsrs); | |
596 GrowableArray<Block*>* successors() { | |
597 assert(_successors != NULL, "must be filled in"); | |
598 return _successors; | |
599 } | |
600 | |
601 // Get the exceptional successors for this Block. | |
602 GrowableArray<Block*>* exceptions() { | |
603 if (_exceptions == NULL) { | |
604 compute_exceptions(); | |
605 } | |
606 return _exceptions; | |
607 } | |
608 | |
609 // Get the exception klasses corresponding to the | |
610 // exceptional successors for this Block. | |
611 GrowableArray<ciInstanceKlass*>* exc_klasses() { | |
612 if (_exc_klasses == NULL) { | |
613 compute_exceptions(); | |
614 } | |
615 return _exc_klasses; | |
616 } | |
617 | |
618 // Is this Block compatible with a given JsrSet? | |
619 bool is_compatible_with(JsrSet* other) { | |
620 return _jsrs->is_compatible_with(other); | |
621 } | |
622 | |
623 // Copy the value of our state vector into another. | |
624 void copy_state_into(StateVector* copy) const { | |
625 _state->copy_into(copy); | |
626 } | |
627 | |
628 // Copy the value of our JsrSet into another | |
629 void copy_jsrs_into(JsrSet* copy) const { | |
630 _jsrs->copy_into(copy); | |
631 } | |
632 | |
633 // Meets the start state of this block with another state, destructively | |
634 // modifying this one. Returns true if any modification takes place. | |
635 bool meet(const StateVector* incoming) { | |
636 return state()->meet(incoming); | |
637 } | |
638 | |
639 // Ditto, except that the incoming state is coming from an | |
640 // exception path. This means the stack is replaced by the | |
641 // appropriate exception type. | |
642 bool meet_exception(ciInstanceKlass* exc, const StateVector* incoming) { | |
643 return state()->meet_exception(exc, incoming); | |
644 } | |
645 | |
646 // Work list manipulation | |
647 void set_next(Block* block) { _next = block; } | |
648 Block* next() const { return _next; } | |
649 | |
650 void set_on_work_list(bool c) { _on_work_list = c; } | |
651 bool is_on_work_list() const { return _on_work_list; } | |
652 | |
653 bool has_pre_order() const { return _pre_order >= 0; } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
654 void set_pre_order(int po) { assert(!has_pre_order(), ""); _pre_order = po; } |
0 | 655 int pre_order() const { assert(has_pre_order(), ""); return _pre_order; } |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
656 void set_next_pre_order() { set_pre_order(outer()->inc_next_pre_order()); } |
0 | 657 bool is_start() const { return _pre_order == outer()->start_block_num(); } |
658 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
659 // Reverse post order |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
660 void df_init(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
661 bool has_post_order() const { return _post_order >= 0; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
662 void set_post_order(int po) { assert(!has_post_order() && po >= 0, ""); _post_order = po; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
663 void reset_post_order(int o){ _post_order = o; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
664 int post_order() const { assert(has_post_order(), ""); return _post_order; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
665 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
666 bool has_rpo() const { return has_post_order() && outer()->have_block_count(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
667 int rpo() const { assert(has_rpo(), ""); return outer()->block_count() - post_order() - 1; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
668 void set_rpo_next(Block* b) { _rpo_next = b; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
669 Block* rpo_next() { return _rpo_next; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
670 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
671 // Loops |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
672 Loop* loop() const { return _loop; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
673 void set_loop(Loop* lp) { _loop = lp; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
674 bool is_loop_head() const { return _loop && _loop->head() == this; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
675 void set_irreducible_entry(bool c) { _irreducible_entry = c; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
676 bool is_irreducible_entry() const { return _irreducible_entry; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
677 bool is_visited() const { return has_pre_order(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
678 bool is_post_visited() const { return has_post_order(); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
679 bool is_clonable_exit(Loop* lp); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
680 Block* looping_succ(Loop* lp); // Successor inside of loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
681 bool is_single_entry_loop_head() const { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
682 if (!is_loop_head()) return false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
683 for (Loop* lp = loop(); lp != NULL && lp->head() == this; lp = lp->parent()) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
684 if (lp->is_irreducible()) return false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
685 return true; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
686 } |
0 | 687 |
688 void print_value_on(outputStream* st) const PRODUCT_RETURN; | |
689 void print_on(outputStream* st) const PRODUCT_RETURN; | |
690 }; | |
691 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
692 // Loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
693 class Loop : public ResourceObj { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
694 private: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
695 Loop* _parent; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
696 Loop* _sibling; // List of siblings, null terminated |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
697 Loop* _child; // Head of child list threaded thru sibling pointer |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
698 Block* _head; // Head of loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
699 Block* _tail; // Tail of loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
700 bool _irreducible; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
701 LocalSet _def_locals; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
702 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
703 public: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
704 Loop(Block* head, Block* tail) : |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
705 _head(head), _tail(tail), |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
706 _parent(NULL), _sibling(NULL), _child(NULL), |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
707 _irreducible(false), _def_locals() {} |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
708 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
709 Loop* parent() const { return _parent; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
710 Loop* sibling() const { return _sibling; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
711 Loop* child() const { return _child; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
712 Block* head() const { return _head; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
713 Block* tail() const { return _tail; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
714 void set_parent(Loop* p) { _parent = p; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
715 void set_sibling(Loop* s) { _sibling = s; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
716 void set_child(Loop* c) { _child = c; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
717 void set_head(Block* hd) { _head = hd; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
718 void set_tail(Block* tl) { _tail = tl; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
719 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
720 int depth() const; // nesting depth |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
721 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
722 // Returns true if lp is a nested loop or us. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
723 bool contains(Loop* lp) const; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
724 bool contains(Block* blk) const { return contains(blk->loop()); } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
725 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
726 // Data flow on locals |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
727 LocalSet* def_locals() { return &_def_locals; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
728 const LocalSet* def_locals() const { return &_def_locals; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
729 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
730 // Merge the branch lp into this branch, sorting on the loop head |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
731 // pre_orders. Returns the new branch. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
732 Loop* sorted_merge(Loop* lp); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
733 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
734 // Mark non-single entry to loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
735 void set_irreducible(Block* entry) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
736 _irreducible = true; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
737 entry->set_irreducible_entry(true); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
738 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
739 bool is_irreducible() const { return _irreducible; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
740 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
741 bool is_root() const { return _tail->pre_order() == max_jint; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
742 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
743 void print(outputStream* st = tty, int indent = 0) const PRODUCT_RETURN; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
744 }; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
745 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
746 // Postorder iteration over the loop tree. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
747 class PostorderLoops : public StackObj { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
748 private: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
749 Loop* _root; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
750 Loop* _current; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
751 public: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
752 PostorderLoops(Loop* root) : _root(root), _current(root) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
753 while (_current->child() != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
754 _current = _current->child(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
755 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
756 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
757 bool done() { return _current == NULL; } // Finished iterating? |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
758 void next(); // Advance to next loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
759 Loop* current() { return _current; } // Return current loop. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
760 }; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
761 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
762 // Preorder iteration over the loop tree. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
763 class PreorderLoops : public StackObj { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
764 private: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
765 Loop* _root; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
766 Loop* _current; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
767 public: |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
768 PreorderLoops(Loop* root) : _root(root), _current(root) {} |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
769 bool done() { return _current == NULL; } // Finished iterating? |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
770 void next(); // Advance to next loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
771 Loop* current() { return _current; } // Return current loop. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
772 }; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
773 |
0 | 774 // Standard indexes of successors, for various bytecodes. |
775 enum { | |
776 FALL_THROUGH = 0, // normal control | |
777 IF_NOT_TAKEN = 0, // the not-taken branch of an if (i.e., fall-through) | |
778 IF_TAKEN = 1, // the taken branch of an if | |
779 GOTO_TARGET = 0, // unique successor for goto, jsr, or ret | |
780 SWITCH_DEFAULT = 0, // default branch of a switch | |
781 SWITCH_CASES = 1 // first index for any non-default switch branches | |
782 // Unlike in other blocks, the successors of a switch are listed uniquely. | |
783 }; | |
784 | |
785 private: | |
786 // A mapping from pre_order to Blocks. This array is created | |
787 // only at the end of the flow. | |
788 Block** _block_map; | |
789 | |
790 // For each ciBlock index, a list of Blocks which share this ciBlock. | |
791 GrowableArray<Block*>** _idx_to_blocklist; | |
792 // count of ciBlocks | |
793 int _ciblock_count; | |
794 | |
795 // Tells if a given instruction is able to generate an exception edge. | |
796 bool can_trap(ciBytecodeStream& str); | |
797 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
798 // Clone the loop heads. Returns true if any cloning occurred. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
799 bool clone_loop_heads(Loop* lp, StateVector* temp_vector, JsrSet* temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
800 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
801 // Clone lp's head and replace tail's successors with clone. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
802 Block* clone_loop_head(Loop* lp, StateVector* temp_vector, JsrSet* temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
803 |
0 | 804 public: |
805 // Return the block beginning at bci which has a JsrSet compatible | |
806 // with jsrs. | |
807 Block* block_at(int bci, JsrSet* set, CreateOption option = create_public_copy); | |
808 | |
809 // block factory | |
810 Block* get_block_for(int ciBlockIndex, JsrSet* jsrs, CreateOption option = create_public_copy); | |
811 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
812 // How many of the blocks have the backedge_copy bit set? |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
813 int backedge_copy_count(int ciBlockIndex, JsrSet* jsrs) const; |
0 | 814 |
815 // Return an existing block containing bci which has a JsrSet compatible | |
816 // with jsrs, or NULL if there is none. | |
817 Block* existing_block_at(int bci, JsrSet* set) { return block_at(bci, set, no_create); } | |
818 | |
819 // Tell whether the flow analysis has encountered an error of some sort. | |
820 bool failing() { return env()->failing() || _failure_reason != NULL; } | |
821 | |
822 // Reason this compilation is failing, such as "too many basic blocks". | |
823 const char* failure_reason() { return _failure_reason; } | |
824 | |
825 // Note a failure. | |
826 void record_failure(const char* reason); | |
827 | |
828 // Return the block of a given pre-order number. | |
829 int have_block_count() const { return _block_map != NULL; } | |
830 int block_count() const { assert(have_block_count(), ""); | |
831 return _next_pre_order; } | |
832 Block* pre_order_at(int po) const { assert(0 <= po && po < block_count(), "out of bounds"); | |
833 return _block_map[po]; } | |
834 Block* start_block() const { return pre_order_at(start_block_num()); } | |
835 int start_block_num() const { return 0; } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
836 Block* rpo_at(int rpo) const { assert(0 <= rpo && rpo < block_count(), "out of bounds"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
837 return _block_map[rpo]; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
838 int next_pre_order() { return _next_pre_order; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
839 int inc_next_pre_order() { return _next_pre_order++; } |
0 | 840 |
841 private: | |
842 // A work list used during flow analysis. | |
843 Block* _work_list; | |
844 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
845 // List of blocks in reverse post order |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
846 Block* _rpo_list; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
847 |
0 | 848 // Next Block::_pre_order. After mapping, doubles as block_count. |
849 int _next_pre_order; | |
850 | |
851 // Are there more blocks on the work list? | |
852 bool work_list_empty() { return _work_list == NULL; } | |
853 | |
854 // Get the next basic block from our work list. | |
855 Block* work_list_next(); | |
856 | |
857 // Add a basic block to our work list. | |
858 void add_to_work_list(Block* block); | |
859 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
860 // Prepend a basic block to rpo list. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
861 void prepend_to_rpo_list(Block* blk) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
862 blk->set_rpo_next(_rpo_list); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
863 _rpo_list = blk; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
864 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
865 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
866 // Root of the loop tree |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
867 Loop* _loop_tree_root; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
868 |
0 | 869 // State used for make_jsr_record |
870 int _jsr_count; | |
871 GrowableArray<JsrRecord*>* _jsr_records; | |
872 | |
873 public: | |
874 // Make a JsrRecord for a given (entry, return) pair, if such a record | |
875 // does not already exist. | |
876 JsrRecord* make_jsr_record(int entry_address, int return_address); | |
877 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
878 void set_loop_tree_root(Loop* ltr) { _loop_tree_root = ltr; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
879 Loop* loop_tree_root() { return _loop_tree_root; } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
880 |
0 | 881 private: |
882 // Get the initial state for start_bci: | |
883 const StateVector* get_start_state(); | |
884 | |
885 // Merge the current state into all exceptional successors at the | |
886 // current point in the code. | |
887 void flow_exceptions(GrowableArray<Block*>* exceptions, | |
888 GrowableArray<ciInstanceKlass*>* exc_klasses, | |
889 StateVector* state); | |
890 | |
891 // Merge the current state into all successors at the current point | |
892 // in the code. | |
893 void flow_successors(GrowableArray<Block*>* successors, | |
894 StateVector* state); | |
895 | |
896 // Interpret the effects of the bytecodes on the incoming state | |
897 // vector of a basic block. Push the changed state to succeeding | |
898 // basic blocks. | |
899 void flow_block(Block* block, | |
900 StateVector* scratch_state, | |
901 JsrSet* scratch_jsrs); | |
902 | |
903 // Perform the type flow analysis, creating and cloning Blocks as | |
904 // necessary. | |
905 void flow_types(); | |
906 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
907 // Perform the depth first type flow analysis. Helper for flow_types. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
908 void df_flow_types(Block* start, |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
909 bool do_flow, |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
910 StateVector* temp_vector, |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
911 JsrSet* temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
912 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
913 // Incrementally build loop tree. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
914 void build_loop_tree(Block* blk); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
915 |
0 | 916 // Create the block map, which indexes blocks in pre_order. |
917 void map_blocks(); | |
918 | |
919 public: | |
920 // Perform type inference flow analysis. | |
921 void do_flow(); | |
922 | |
923 void print_on(outputStream* st) const PRODUCT_RETURN; | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
924 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
303
diff
changeset
|
925 void rpo_print_on(outputStream* st) const PRODUCT_RETURN; |
0 | 926 }; |