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