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