Mercurial > hg > truffle
annotate src/share/vm/ci/ciTypeFlow.cpp @ 1145:e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking.
Reviewed-by: jmasa
author | ysr |
---|---|
date | Wed, 23 Dec 2009 09:23:54 -0800 |
parents | 3a2aa26bdc58 |
children | 97125851f396 |
rev | line source |
---|---|
0 | 1 /* |
844 | 2 * Copyright 2000-2009 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_ciTypeFlow.cpp.incl" | |
27 | |
28 // ciTypeFlow::JsrSet | |
29 // | |
30 // A JsrSet represents some set of JsrRecords. This class | |
31 // is used to record a set of all jsr routines which we permit | |
32 // execution to return (ret) from. | |
33 // | |
34 // During abstract interpretation, JsrSets are used to determine | |
35 // whether two paths which reach a given block are unique, and | |
36 // should be cloned apart, or are compatible, and should merge | |
37 // together. | |
38 | |
39 // ------------------------------------------------------------------ | |
40 // ciTypeFlow::JsrSet::JsrSet | |
41 ciTypeFlow::JsrSet::JsrSet(Arena* arena, int default_len) { | |
42 if (arena != NULL) { | |
43 // Allocate growable array in Arena. | |
44 _set = new (arena) GrowableArray<JsrRecord*>(arena, default_len, 0, NULL); | |
45 } else { | |
46 // Allocate growable array in current ResourceArea. | |
47 _set = new GrowableArray<JsrRecord*>(4, 0, NULL, false); | |
48 } | |
49 } | |
50 | |
51 // ------------------------------------------------------------------ | |
52 // ciTypeFlow::JsrSet::copy_into | |
53 void ciTypeFlow::JsrSet::copy_into(JsrSet* jsrs) { | |
54 int len = size(); | |
55 jsrs->_set->clear(); | |
56 for (int i = 0; i < len; i++) { | |
57 jsrs->_set->append(_set->at(i)); | |
58 } | |
59 } | |
60 | |
61 // ------------------------------------------------------------------ | |
62 // ciTypeFlow::JsrSet::is_compatible_with | |
63 // | |
64 // !!!! MISGIVINGS ABOUT THIS... disregard | |
65 // | |
66 // Is this JsrSet compatible with some other JsrSet? | |
67 // | |
68 // In set-theoretic terms, a JsrSet can be viewed as a partial function | |
69 // from entry addresses to return addresses. Two JsrSets A and B are | |
70 // compatible iff | |
71 // | |
72 // For any x, | |
73 // A(x) defined and B(x) defined implies A(x) == B(x) | |
74 // | |
75 // Less formally, two JsrSets are compatible when they have identical | |
76 // return addresses for any entry addresses they share in common. | |
77 bool ciTypeFlow::JsrSet::is_compatible_with(JsrSet* other) { | |
78 // Walk through both sets in parallel. If the same entry address | |
79 // appears in both sets, then the return address must match for | |
80 // the sets to be compatible. | |
81 int size1 = size(); | |
82 int size2 = other->size(); | |
83 | |
84 // Special case. If nothing is on the jsr stack, then there can | |
85 // be no ret. | |
86 if (size2 == 0) { | |
87 return true; | |
88 } else if (size1 != size2) { | |
89 return false; | |
90 } else { | |
91 for (int i = 0; i < size1; i++) { | |
92 JsrRecord* record1 = record_at(i); | |
93 JsrRecord* record2 = other->record_at(i); | |
94 if (record1->entry_address() != record2->entry_address() || | |
95 record1->return_address() != record2->return_address()) { | |
96 return false; | |
97 } | |
98 } | |
99 return true; | |
100 } | |
101 | |
102 #if 0 | |
103 int pos1 = 0; | |
104 int pos2 = 0; | |
105 int size1 = size(); | |
106 int size2 = other->size(); | |
107 while (pos1 < size1 && pos2 < size2) { | |
108 JsrRecord* record1 = record_at(pos1); | |
109 JsrRecord* record2 = other->record_at(pos2); | |
110 int entry1 = record1->entry_address(); | |
111 int entry2 = record2->entry_address(); | |
112 if (entry1 < entry2) { | |
113 pos1++; | |
114 } else if (entry1 > entry2) { | |
115 pos2++; | |
116 } else { | |
117 if (record1->return_address() == record2->return_address()) { | |
118 pos1++; | |
119 pos2++; | |
120 } else { | |
121 // These two JsrSets are incompatible. | |
122 return false; | |
123 } | |
124 } | |
125 } | |
126 // The two JsrSets agree. | |
127 return true; | |
128 #endif | |
129 } | |
130 | |
131 // ------------------------------------------------------------------ | |
132 // ciTypeFlow::JsrSet::insert_jsr_record | |
133 // | |
134 // Insert the given JsrRecord into the JsrSet, maintaining the order | |
135 // of the set and replacing any element with the same entry address. | |
136 void ciTypeFlow::JsrSet::insert_jsr_record(JsrRecord* record) { | |
137 int len = size(); | |
138 int entry = record->entry_address(); | |
139 int pos = 0; | |
140 for ( ; pos < len; pos++) { | |
141 JsrRecord* current = record_at(pos); | |
142 if (entry == current->entry_address()) { | |
143 // Stomp over this entry. | |
144 _set->at_put(pos, record); | |
145 assert(size() == len, "must be same size"); | |
146 return; | |
147 } else if (entry < current->entry_address()) { | |
148 break; | |
149 } | |
150 } | |
151 | |
152 // Insert the record into the list. | |
153 JsrRecord* swap = record; | |
154 JsrRecord* temp = NULL; | |
155 for ( ; pos < len; pos++) { | |
156 temp = _set->at(pos); | |
157 _set->at_put(pos, swap); | |
158 swap = temp; | |
159 } | |
160 _set->append(swap); | |
161 assert(size() == len+1, "must be larger"); | |
162 } | |
163 | |
164 // ------------------------------------------------------------------ | |
165 // ciTypeFlow::JsrSet::remove_jsr_record | |
166 // | |
167 // Remove the JsrRecord with the given return address from the JsrSet. | |
168 void ciTypeFlow::JsrSet::remove_jsr_record(int return_address) { | |
169 int len = size(); | |
170 for (int i = 0; i < len; i++) { | |
171 if (record_at(i)->return_address() == return_address) { | |
172 // We have found the proper entry. Remove it from the | |
173 // JsrSet and exit. | |
174 for (int j = i+1; j < len ; j++) { | |
175 _set->at_put(j-1, _set->at(j)); | |
176 } | |
177 _set->trunc_to(len-1); | |
178 assert(size() == len-1, "must be smaller"); | |
179 return; | |
180 } | |
181 } | |
182 assert(false, "verify: returning from invalid subroutine"); | |
183 } | |
184 | |
185 // ------------------------------------------------------------------ | |
186 // ciTypeFlow::JsrSet::apply_control | |
187 // | |
188 // Apply the effect of a control-flow bytecode on the JsrSet. The | |
189 // only bytecodes that modify the JsrSet are jsr and ret. | |
190 void ciTypeFlow::JsrSet::apply_control(ciTypeFlow* analyzer, | |
191 ciBytecodeStream* str, | |
192 ciTypeFlow::StateVector* state) { | |
193 Bytecodes::Code code = str->cur_bc(); | |
194 if (code == Bytecodes::_jsr) { | |
195 JsrRecord* record = | |
196 analyzer->make_jsr_record(str->get_dest(), str->next_bci()); | |
197 insert_jsr_record(record); | |
198 } else if (code == Bytecodes::_jsr_w) { | |
199 JsrRecord* record = | |
200 analyzer->make_jsr_record(str->get_far_dest(), str->next_bci()); | |
201 insert_jsr_record(record); | |
202 } else if (code == Bytecodes::_ret) { | |
203 Cell local = state->local(str->get_index()); | |
204 ciType* return_address = state->type_at(local); | |
205 assert(return_address->is_return_address(), "verify: wrong type"); | |
206 if (size() == 0) { | |
207 // Ret-state underflow: Hit a ret w/o any previous jsrs. Bail out. | |
208 // This can happen when a loop is inside a finally clause (4614060). | |
209 analyzer->record_failure("OSR in finally clause"); | |
210 return; | |
211 } | |
212 remove_jsr_record(return_address->as_return_address()->bci()); | |
213 } | |
214 } | |
215 | |
216 #ifndef PRODUCT | |
217 // ------------------------------------------------------------------ | |
218 // ciTypeFlow::JsrSet::print_on | |
219 void ciTypeFlow::JsrSet::print_on(outputStream* st) const { | |
220 st->print("{ "); | |
221 int num_elements = size(); | |
222 if (num_elements > 0) { | |
223 int i = 0; | |
224 for( ; i < num_elements - 1; i++) { | |
225 _set->at(i)->print_on(st); | |
226 st->print(", "); | |
227 } | |
228 _set->at(i)->print_on(st); | |
229 st->print(" "); | |
230 } | |
231 st->print("}"); | |
232 } | |
233 #endif | |
234 | |
235 // ciTypeFlow::StateVector | |
236 // | |
237 // A StateVector summarizes the type information at some point in | |
238 // the program. | |
239 | |
240 // ------------------------------------------------------------------ | |
241 // ciTypeFlow::StateVector::type_meet | |
242 // | |
243 // Meet two types. | |
244 // | |
245 // The semi-lattice of types use by this analysis are modeled on those | |
246 // of the verifier. The lattice is as follows: | |
247 // | |
248 // top_type() >= all non-extremal types >= bottom_type | |
249 // and | |
250 // Every primitive type is comparable only with itself. The meet of | |
251 // reference types is determined by their kind: instance class, | |
252 // interface, or array class. The meet of two types of the same | |
253 // kind is their least common ancestor. The meet of two types of | |
254 // different kinds is always java.lang.Object. | |
255 ciType* ciTypeFlow::StateVector::type_meet_internal(ciType* t1, ciType* t2, ciTypeFlow* analyzer) { | |
256 assert(t1 != t2, "checked in caller"); | |
257 if (t1->equals(top_type())) { | |
258 return t2; | |
259 } else if (t2->equals(top_type())) { | |
260 return t1; | |
261 } else if (t1->is_primitive_type() || t2->is_primitive_type()) { | |
262 // Special case null_type. null_type meet any reference type T | |
263 // is T. null_type meet null_type is null_type. | |
264 if (t1->equals(null_type())) { | |
265 if (!t2->is_primitive_type() || t2->equals(null_type())) { | |
266 return t2; | |
267 } | |
268 } else if (t2->equals(null_type())) { | |
269 if (!t1->is_primitive_type()) { | |
270 return t1; | |
271 } | |
272 } | |
273 | |
274 // At least one of the two types is a non-top primitive type. | |
275 // The other type is not equal to it. Fall to bottom. | |
276 return bottom_type(); | |
277 } else { | |
278 // Both types are non-top non-primitive types. That is, | |
279 // both types are either instanceKlasses or arrayKlasses. | |
280 ciKlass* object_klass = analyzer->env()->Object_klass(); | |
281 ciKlass* k1 = t1->as_klass(); | |
282 ciKlass* k2 = t2->as_klass(); | |
283 if (k1->equals(object_klass) || k2->equals(object_klass)) { | |
284 return object_klass; | |
285 } else if (!k1->is_loaded() || !k2->is_loaded()) { | |
286 // Unloaded classes fall to java.lang.Object at a merge. | |
287 return object_klass; | |
288 } else if (k1->is_interface() != k2->is_interface()) { | |
289 // When an interface meets a non-interface, we get Object; | |
290 // This is what the verifier does. | |
291 return object_klass; | |
292 } else if (k1->is_array_klass() || k2->is_array_klass()) { | |
293 // When an array meets a non-array, we get Object. | |
294 // When objArray meets typeArray, we also get Object. | |
295 // And when typeArray meets different typeArray, we again get Object. | |
296 // But when objArray meets objArray, we look carefully at element types. | |
297 if (k1->is_obj_array_klass() && k2->is_obj_array_klass()) { | |
298 // Meet the element types, then construct the corresponding array type. | |
299 ciKlass* elem1 = k1->as_obj_array_klass()->element_klass(); | |
300 ciKlass* elem2 = k2->as_obj_array_klass()->element_klass(); | |
301 ciKlass* elem = type_meet_internal(elem1, elem2, analyzer)->as_klass(); | |
302 // Do an easy shortcut if one type is a super of the other. | |
303 if (elem == elem1) { | |
304 assert(k1 == ciObjArrayKlass::make(elem), "shortcut is OK"); | |
305 return k1; | |
306 } else if (elem == elem2) { | |
307 assert(k2 == ciObjArrayKlass::make(elem), "shortcut is OK"); | |
308 return k2; | |
309 } else { | |
310 return ciObjArrayKlass::make(elem); | |
311 } | |
312 } else { | |
313 return object_klass; | |
314 } | |
315 } else { | |
316 // Must be two plain old instance klasses. | |
317 assert(k1->is_instance_klass(), "previous cases handle non-instances"); | |
318 assert(k2->is_instance_klass(), "previous cases handle non-instances"); | |
319 return k1->least_common_ancestor(k2); | |
320 } | |
321 } | |
322 } | |
323 | |
324 | |
325 // ------------------------------------------------------------------ | |
326 // ciTypeFlow::StateVector::StateVector | |
327 // | |
328 // Build a new state vector | |
329 ciTypeFlow::StateVector::StateVector(ciTypeFlow* analyzer) { | |
330 _outer = analyzer; | |
331 _stack_size = -1; | |
332 _monitor_count = -1; | |
333 // Allocate the _types array | |
334 int max_cells = analyzer->max_cells(); | |
335 _types = (ciType**)analyzer->arena()->Amalloc(sizeof(ciType*) * max_cells); | |
336 for (int i=0; i<max_cells; i++) { | |
337 _types[i] = top_type(); | |
338 } | |
339 _trap_bci = -1; | |
340 _trap_index = 0; | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
341 _def_locals.clear(); |
0 | 342 } |
343 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
344 |
0 | 345 // ------------------------------------------------------------------ |
346 // ciTypeFlow::get_start_state | |
347 // | |
348 // Set this vector to the method entry state. | |
349 const ciTypeFlow::StateVector* ciTypeFlow::get_start_state() { | |
350 StateVector* state = new StateVector(this); | |
351 if (is_osr_flow()) { | |
352 ciTypeFlow* non_osr_flow = method()->get_flow_analysis(); | |
353 if (non_osr_flow->failing()) { | |
354 record_failure(non_osr_flow->failure_reason()); | |
355 return NULL; | |
356 } | |
357 JsrSet* jsrs = new JsrSet(NULL, 16); | |
358 Block* non_osr_block = non_osr_flow->existing_block_at(start_bci(), jsrs); | |
359 if (non_osr_block == NULL) { | |
360 record_failure("cannot reach OSR point"); | |
361 return NULL; | |
362 } | |
363 // load up the non-OSR state at this point | |
364 non_osr_block->copy_state_into(state); | |
365 int non_osr_start = non_osr_block->start(); | |
366 if (non_osr_start != start_bci()) { | |
367 // must flow forward from it | |
368 if (CITraceTypeFlow) { | |
369 tty->print_cr(">> Interpreting pre-OSR block %d:", non_osr_start); | |
370 } | |
371 Block* block = block_at(non_osr_start, jsrs); | |
372 assert(block->limit() == start_bci(), "must flow forward to start"); | |
373 flow_block(block, state, jsrs); | |
374 } | |
375 return state; | |
376 // Note: The code below would be an incorrect for an OSR flow, | |
377 // even if it were possible for an OSR entry point to be at bci zero. | |
378 } | |
379 // "Push" the method signature into the first few locals. | |
380 state->set_stack_size(-max_locals()); | |
381 if (!method()->is_static()) { | |
382 state->push(method()->holder()); | |
383 assert(state->tos() == state->local(0), ""); | |
384 } | |
385 for (ciSignatureStream str(method()->signature()); | |
386 !str.at_return_type(); | |
387 str.next()) { | |
388 state->push_translate(str.type()); | |
389 } | |
390 // Set the rest of the locals to bottom. | |
391 Cell cell = state->next_cell(state->tos()); | |
392 state->set_stack_size(0); | |
393 int limit = state->limit_cell(); | |
394 for (; cell < limit; cell = state->next_cell(cell)) { | |
395 state->set_type_at(cell, state->bottom_type()); | |
396 } | |
397 // Lock an object, if necessary. | |
398 state->set_monitor_count(method()->is_synchronized() ? 1 : 0); | |
399 return state; | |
400 } | |
401 | |
402 // ------------------------------------------------------------------ | |
403 // ciTypeFlow::StateVector::copy_into | |
404 // | |
405 // Copy our value into some other StateVector | |
406 void ciTypeFlow::StateVector::copy_into(ciTypeFlow::StateVector* copy) | |
407 const { | |
408 copy->set_stack_size(stack_size()); | |
409 copy->set_monitor_count(monitor_count()); | |
410 Cell limit = limit_cell(); | |
411 for (Cell c = start_cell(); c < limit; c = next_cell(c)) { | |
412 copy->set_type_at(c, type_at(c)); | |
413 } | |
414 } | |
415 | |
416 // ------------------------------------------------------------------ | |
417 // ciTypeFlow::StateVector::meet | |
418 // | |
419 // Meets this StateVector with another, destructively modifying this | |
420 // one. Returns true if any modification takes place. | |
421 bool ciTypeFlow::StateVector::meet(const ciTypeFlow::StateVector* incoming) { | |
422 if (monitor_count() == -1) { | |
423 set_monitor_count(incoming->monitor_count()); | |
424 } | |
425 assert(monitor_count() == incoming->monitor_count(), "monitors must match"); | |
426 | |
427 if (stack_size() == -1) { | |
428 set_stack_size(incoming->stack_size()); | |
429 Cell limit = limit_cell(); | |
430 #ifdef ASSERT | |
431 { for (Cell c = start_cell(); c < limit; c = next_cell(c)) { | |
432 assert(type_at(c) == top_type(), ""); | |
433 } } | |
434 #endif | |
435 // Make a simple copy of the incoming state. | |
436 for (Cell c = start_cell(); c < limit; c = next_cell(c)) { | |
437 set_type_at(c, incoming->type_at(c)); | |
438 } | |
439 return true; // it is always different the first time | |
440 } | |
441 #ifdef ASSERT | |
442 if (stack_size() != incoming->stack_size()) { | |
443 _outer->method()->print_codes(); | |
444 tty->print_cr("!!!! Stack size conflict"); | |
445 tty->print_cr("Current state:"); | |
446 print_on(tty); | |
447 tty->print_cr("Incoming state:"); | |
448 ((StateVector*)incoming)->print_on(tty); | |
449 } | |
450 #endif | |
451 assert(stack_size() == incoming->stack_size(), "sanity"); | |
452 | |
453 bool different = false; | |
454 Cell limit = limit_cell(); | |
455 for (Cell c = start_cell(); c < limit; c = next_cell(c)) { | |
456 ciType* t1 = type_at(c); | |
457 ciType* t2 = incoming->type_at(c); | |
458 if (!t1->equals(t2)) { | |
459 ciType* new_type = type_meet(t1, t2); | |
460 if (!t1->equals(new_type)) { | |
461 set_type_at(c, new_type); | |
462 different = true; | |
463 } | |
464 } | |
465 } | |
466 return different; | |
467 } | |
468 | |
469 // ------------------------------------------------------------------ | |
470 // ciTypeFlow::StateVector::meet_exception | |
471 // | |
472 // Meets this StateVector with another, destructively modifying this | |
473 // one. The incoming state is coming via an exception. Returns true | |
474 // if any modification takes place. | |
475 bool ciTypeFlow::StateVector::meet_exception(ciInstanceKlass* exc, | |
476 const ciTypeFlow::StateVector* incoming) { | |
477 if (monitor_count() == -1) { | |
478 set_monitor_count(incoming->monitor_count()); | |
479 } | |
480 assert(monitor_count() == incoming->monitor_count(), "monitors must match"); | |
481 | |
482 if (stack_size() == -1) { | |
483 set_stack_size(1); | |
484 } | |
485 | |
486 assert(stack_size() == 1, "must have one-element stack"); | |
487 | |
488 bool different = false; | |
489 | |
490 // Meet locals from incoming array. | |
491 Cell limit = local(_outer->max_locals()-1); | |
492 for (Cell c = start_cell(); c <= limit; c = next_cell(c)) { | |
493 ciType* t1 = type_at(c); | |
494 ciType* t2 = incoming->type_at(c); | |
495 if (!t1->equals(t2)) { | |
496 ciType* new_type = type_meet(t1, t2); | |
497 if (!t1->equals(new_type)) { | |
498 set_type_at(c, new_type); | |
499 different = true; | |
500 } | |
501 } | |
502 } | |
503 | |
504 // Handle stack separately. When an exception occurs, the | |
505 // only stack entry is the exception instance. | |
506 ciType* tos_type = type_at_tos(); | |
507 if (!tos_type->equals(exc)) { | |
508 ciType* new_type = type_meet(tos_type, exc); | |
509 if (!tos_type->equals(new_type)) { | |
510 set_type_at_tos(new_type); | |
511 different = true; | |
512 } | |
513 } | |
514 | |
515 return different; | |
516 } | |
517 | |
518 // ------------------------------------------------------------------ | |
519 // ciTypeFlow::StateVector::push_translate | |
520 void ciTypeFlow::StateVector::push_translate(ciType* type) { | |
521 BasicType basic_type = type->basic_type(); | |
522 if (basic_type == T_BOOLEAN || basic_type == T_CHAR || | |
523 basic_type == T_BYTE || basic_type == T_SHORT) { | |
524 push_int(); | |
525 } else { | |
526 push(type); | |
527 if (type->is_two_word()) { | |
528 push(half_type(type)); | |
529 } | |
530 } | |
531 } | |
532 | |
533 // ------------------------------------------------------------------ | |
534 // ciTypeFlow::StateVector::do_aaload | |
535 void ciTypeFlow::StateVector::do_aaload(ciBytecodeStream* str) { | |
536 pop_int(); | |
537 ciObjArrayKlass* array_klass = pop_objArray(); | |
538 if (array_klass == NULL) { | |
539 // Did aaload on a null reference; push a null and ignore the exception. | |
540 // This instruction will never continue normally. All we have to do | |
541 // is report a value that will meet correctly with any downstream | |
542 // reference types on paths that will truly be executed. This null type | |
543 // meets with any reference type to yield that same reference type. | |
605 | 544 // (The compiler will generate an unconditional exception here.) |
0 | 545 push(null_type()); |
546 return; | |
547 } | |
548 if (!array_klass->is_loaded()) { | |
549 // Only fails for some -Xcomp runs | |
550 trap(str, array_klass, | |
551 Deoptimization::make_trap_request | |
552 (Deoptimization::Reason_unloaded, | |
553 Deoptimization::Action_reinterpret)); | |
554 return; | |
555 } | |
556 ciKlass* element_klass = array_klass->element_klass(); | |
557 if (!element_klass->is_loaded() && element_klass->is_instance_klass()) { | |
558 Untested("unloaded array element class in ciTypeFlow"); | |
559 trap(str, element_klass, | |
560 Deoptimization::make_trap_request | |
561 (Deoptimization::Reason_unloaded, | |
562 Deoptimization::Action_reinterpret)); | |
563 } else { | |
564 push_object(element_klass); | |
565 } | |
566 } | |
567 | |
568 | |
569 // ------------------------------------------------------------------ | |
570 // ciTypeFlow::StateVector::do_checkcast | |
571 void ciTypeFlow::StateVector::do_checkcast(ciBytecodeStream* str) { | |
572 bool will_link; | |
573 ciKlass* klass = str->get_klass(will_link); | |
574 if (!will_link) { | |
575 // VM's interpreter will not load 'klass' if object is NULL. | |
576 // Type flow after this block may still be needed in two situations: | |
577 // 1) C2 uses do_null_assert() and continues compilation for later blocks | |
578 // 2) C2 does an OSR compile in a later block (see bug 4778368). | |
579 pop_object(); | |
580 do_null_assert(klass); | |
581 } else { | |
582 pop_object(); | |
583 push_object(klass); | |
584 } | |
585 } | |
586 | |
587 // ------------------------------------------------------------------ | |
588 // ciTypeFlow::StateVector::do_getfield | |
589 void ciTypeFlow::StateVector::do_getfield(ciBytecodeStream* str) { | |
590 // could add assert here for type of object. | |
591 pop_object(); | |
592 do_getstatic(str); | |
593 } | |
594 | |
595 // ------------------------------------------------------------------ | |
596 // ciTypeFlow::StateVector::do_getstatic | |
597 void ciTypeFlow::StateVector::do_getstatic(ciBytecodeStream* str) { | |
598 bool will_link; | |
599 ciField* field = str->get_field(will_link); | |
600 if (!will_link) { | |
601 trap(str, field->holder(), str->get_field_holder_index()); | |
602 } else { | |
603 ciType* field_type = field->type(); | |
604 if (!field_type->is_loaded()) { | |
605 // Normally, we need the field's type to be loaded if we are to | |
606 // do anything interesting with its value. | |
607 // We used to do this: trap(str, str->get_field_signature_index()); | |
608 // | |
609 // There is one good reason not to trap here. Execution can | |
610 // get past this "getfield" or "getstatic" if the value of | |
611 // the field is null. As long as the value is null, the class | |
612 // does not need to be loaded! The compiler must assume that | |
613 // the value of the unloaded class reference is null; if the code | |
614 // ever sees a non-null value, loading has occurred. | |
615 // | |
616 // This actually happens often enough to be annoying. If the | |
617 // compiler throws an uncommon trap at this bytecode, you can | |
618 // get an endless loop of recompilations, when all the code | |
619 // needs to do is load a series of null values. Also, a trap | |
620 // here can make an OSR entry point unreachable, triggering the | |
621 // assert on non_osr_block in ciTypeFlow::get_start_state. | |
622 // (See bug 4379915.) | |
623 do_null_assert(field_type->as_klass()); | |
624 } else { | |
625 push_translate(field_type); | |
626 } | |
627 } | |
628 } | |
629 | |
630 // ------------------------------------------------------------------ | |
631 // ciTypeFlow::StateVector::do_invoke | |
632 void ciTypeFlow::StateVector::do_invoke(ciBytecodeStream* str, | |
633 bool has_receiver) { | |
634 bool will_link; | |
635 ciMethod* method = str->get_method(will_link); | |
636 if (!will_link) { | |
637 // We weren't able to find the method. | |
638 ciKlass* unloaded_holder = method->holder(); | |
639 trap(str, unloaded_holder, str->get_method_holder_index()); | |
640 } else { | |
641 ciSignature* signature = method->signature(); | |
642 ciSignatureStream sigstr(signature); | |
643 int arg_size = signature->size(); | |
644 int stack_base = stack_size() - arg_size; | |
645 int i = 0; | |
646 for( ; !sigstr.at_return_type(); sigstr.next()) { | |
647 ciType* type = sigstr.type(); | |
648 ciType* stack_type = type_at(stack(stack_base + i++)); | |
649 // Do I want to check this type? | |
650 // assert(stack_type->is_subtype_of(type), "bad type for field value"); | |
651 if (type->is_two_word()) { | |
652 ciType* stack_type2 = type_at(stack(stack_base + i++)); | |
653 assert(stack_type2->equals(half_type(type)), "must be 2nd half"); | |
654 } | |
655 } | |
656 assert(arg_size == i, "must match"); | |
657 for (int j = 0; j < arg_size; j++) { | |
658 pop(); | |
659 } | |
660 if (has_receiver) { | |
661 // Check this? | |
662 pop_object(); | |
663 } | |
664 assert(!sigstr.is_done(), "must have return type"); | |
665 ciType* return_type = sigstr.type(); | |
666 if (!return_type->is_void()) { | |
667 if (!return_type->is_loaded()) { | |
668 // As in do_getstatic(), generally speaking, we need the return type to | |
669 // be loaded if we are to do anything interesting with its value. | |
670 // We used to do this: trap(str, str->get_method_signature_index()); | |
671 // | |
672 // We do not trap here since execution can get past this invoke if | |
673 // the return value is null. As long as the value is null, the class | |
674 // does not need to be loaded! The compiler must assume that | |
675 // the value of the unloaded class reference is null; if the code | |
676 // ever sees a non-null value, loading has occurred. | |
677 // | |
678 // See do_getstatic() for similar explanation, as well as bug 4684993. | |
679 do_null_assert(return_type->as_klass()); | |
680 } else { | |
681 push_translate(return_type); | |
682 } | |
683 } | |
684 } | |
685 } | |
686 | |
687 // ------------------------------------------------------------------ | |
688 // ciTypeFlow::StateVector::do_jsr | |
689 void ciTypeFlow::StateVector::do_jsr(ciBytecodeStream* str) { | |
690 push(ciReturnAddress::make(str->next_bci())); | |
691 } | |
692 | |
693 // ------------------------------------------------------------------ | |
694 // ciTypeFlow::StateVector::do_ldc | |
695 void ciTypeFlow::StateVector::do_ldc(ciBytecodeStream* str) { | |
696 ciConstant con = str->get_constant(); | |
697 BasicType basic_type = con.basic_type(); | |
698 if (basic_type == T_ILLEGAL) { | |
699 // OutOfMemoryError in the CI while loading constant | |
700 push_null(); | |
701 outer()->record_failure("ldc did not link"); | |
702 return; | |
703 } | |
704 if (basic_type == T_OBJECT || basic_type == T_ARRAY) { | |
705 ciObject* obj = con.as_object(); | |
706 if (obj->is_null_object()) { | |
707 push_null(); | |
708 } else if (obj->is_klass()) { | |
709 // The type of ldc <class> is java.lang.Class | |
710 push_object(outer()->env()->Class_klass()); | |
711 } else { | |
712 push_object(obj->klass()); | |
713 } | |
714 } else { | |
715 push_translate(ciType::make(basic_type)); | |
716 } | |
717 } | |
718 | |
719 // ------------------------------------------------------------------ | |
720 // ciTypeFlow::StateVector::do_multianewarray | |
721 void ciTypeFlow::StateVector::do_multianewarray(ciBytecodeStream* str) { | |
722 int dimensions = str->get_dimensions(); | |
723 bool will_link; | |
724 ciArrayKlass* array_klass = str->get_klass(will_link)->as_array_klass(); | |
725 if (!will_link) { | |
726 trap(str, array_klass, str->get_klass_index()); | |
727 } else { | |
728 for (int i = 0; i < dimensions; i++) { | |
729 pop_int(); | |
730 } | |
731 push_object(array_klass); | |
732 } | |
733 } | |
734 | |
735 // ------------------------------------------------------------------ | |
736 // ciTypeFlow::StateVector::do_new | |
737 void ciTypeFlow::StateVector::do_new(ciBytecodeStream* str) { | |
738 bool will_link; | |
739 ciKlass* klass = str->get_klass(will_link); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
740 if (!will_link || str->is_unresolved_klass()) { |
0 | 741 trap(str, klass, str->get_klass_index()); |
742 } else { | |
743 push_object(klass); | |
744 } | |
745 } | |
746 | |
747 // ------------------------------------------------------------------ | |
748 // ciTypeFlow::StateVector::do_newarray | |
749 void ciTypeFlow::StateVector::do_newarray(ciBytecodeStream* str) { | |
750 pop_int(); | |
751 ciKlass* klass = ciTypeArrayKlass::make((BasicType)str->get_index()); | |
752 push_object(klass); | |
753 } | |
754 | |
755 // ------------------------------------------------------------------ | |
756 // ciTypeFlow::StateVector::do_putfield | |
757 void ciTypeFlow::StateVector::do_putfield(ciBytecodeStream* str) { | |
758 do_putstatic(str); | |
759 if (_trap_bci != -1) return; // unloaded field holder, etc. | |
760 // could add assert here for type of object. | |
761 pop_object(); | |
762 } | |
763 | |
764 // ------------------------------------------------------------------ | |
765 // ciTypeFlow::StateVector::do_putstatic | |
766 void ciTypeFlow::StateVector::do_putstatic(ciBytecodeStream* str) { | |
767 bool will_link; | |
768 ciField* field = str->get_field(will_link); | |
769 if (!will_link) { | |
770 trap(str, field->holder(), str->get_field_holder_index()); | |
771 } else { | |
772 ciType* field_type = field->type(); | |
773 ciType* type = pop_value(); | |
774 // Do I want to check this type? | |
775 // assert(type->is_subtype_of(field_type), "bad type for field value"); | |
776 if (field_type->is_two_word()) { | |
777 ciType* type2 = pop_value(); | |
778 assert(type2->is_two_word(), "must be 2nd half"); | |
779 assert(type == half_type(type2), "must be 2nd half"); | |
780 } | |
781 } | |
782 } | |
783 | |
784 // ------------------------------------------------------------------ | |
785 // ciTypeFlow::StateVector::do_ret | |
786 void ciTypeFlow::StateVector::do_ret(ciBytecodeStream* str) { | |
787 Cell index = local(str->get_index()); | |
788 | |
789 ciType* address = type_at(index); | |
790 assert(address->is_return_address(), "bad return address"); | |
791 set_type_at(index, bottom_type()); | |
792 } | |
793 | |
794 // ------------------------------------------------------------------ | |
795 // ciTypeFlow::StateVector::trap | |
796 // | |
797 // Stop interpretation of this path with a trap. | |
798 void ciTypeFlow::StateVector::trap(ciBytecodeStream* str, ciKlass* klass, int index) { | |
799 _trap_bci = str->cur_bci(); | |
800 _trap_index = index; | |
801 | |
802 // Log information about this trap: | |
803 CompileLog* log = outer()->env()->log(); | |
804 if (log != NULL) { | |
805 int mid = log->identify(outer()->method()); | |
806 int kid = (klass == NULL)? -1: log->identify(klass); | |
807 log->begin_elem("uncommon_trap method='%d' bci='%d'", mid, str->cur_bci()); | |
808 char buf[100]; | |
809 log->print(" %s", Deoptimization::format_trap_request(buf, sizeof(buf), | |
810 index)); | |
811 if (kid >= 0) | |
812 log->print(" klass='%d'", kid); | |
813 log->end_elem(); | |
814 } | |
815 } | |
816 | |
817 // ------------------------------------------------------------------ | |
818 // ciTypeFlow::StateVector::do_null_assert | |
819 // Corresponds to graphKit::do_null_assert. | |
820 void ciTypeFlow::StateVector::do_null_assert(ciKlass* unloaded_klass) { | |
821 if (unloaded_klass->is_loaded()) { | |
822 // We failed to link, but we can still compute with this class, | |
823 // since it is loaded somewhere. The compiler will uncommon_trap | |
824 // if the object is not null, but the typeflow pass can not assume | |
825 // that the object will be null, otherwise it may incorrectly tell | |
826 // the parser that an object is known to be null. 4761344, 4807707 | |
827 push_object(unloaded_klass); | |
828 } else { | |
829 // The class is not loaded anywhere. It is safe to model the | |
830 // null in the typestates, because we can compile in a null check | |
831 // which will deoptimize us if someone manages to load the | |
832 // class later. | |
833 push_null(); | |
834 } | |
835 } | |
836 | |
837 | |
838 // ------------------------------------------------------------------ | |
839 // ciTypeFlow::StateVector::apply_one_bytecode | |
840 // | |
841 // Apply the effect of one bytecode to this StateVector | |
842 bool ciTypeFlow::StateVector::apply_one_bytecode(ciBytecodeStream* str) { | |
843 _trap_bci = -1; | |
844 _trap_index = 0; | |
845 | |
846 if (CITraceTypeFlow) { | |
847 tty->print_cr(">> Interpreting bytecode %d:%s", str->cur_bci(), | |
848 Bytecodes::name(str->cur_bc())); | |
849 } | |
850 | |
851 switch(str->cur_bc()) { | |
852 case Bytecodes::_aaload: do_aaload(str); break; | |
853 | |
854 case Bytecodes::_aastore: | |
855 { | |
856 pop_object(); | |
857 pop_int(); | |
858 pop_objArray(); | |
859 break; | |
860 } | |
861 case Bytecodes::_aconst_null: | |
862 { | |
863 push_null(); | |
864 break; | |
865 } | |
866 case Bytecodes::_aload: load_local_object(str->get_index()); break; | |
867 case Bytecodes::_aload_0: load_local_object(0); break; | |
868 case Bytecodes::_aload_1: load_local_object(1); break; | |
869 case Bytecodes::_aload_2: load_local_object(2); break; | |
870 case Bytecodes::_aload_3: load_local_object(3); break; | |
871 | |
872 case Bytecodes::_anewarray: | |
873 { | |
874 pop_int(); | |
875 bool will_link; | |
876 ciKlass* element_klass = str->get_klass(will_link); | |
877 if (!will_link) { | |
878 trap(str, element_klass, str->get_klass_index()); | |
879 } else { | |
880 push_object(ciObjArrayKlass::make(element_klass)); | |
881 } | |
882 break; | |
883 } | |
884 case Bytecodes::_areturn: | |
885 case Bytecodes::_ifnonnull: | |
886 case Bytecodes::_ifnull: | |
887 { | |
888 pop_object(); | |
889 break; | |
890 } | |
891 case Bytecodes::_monitorenter: | |
892 { | |
893 pop_object(); | |
894 set_monitor_count(monitor_count() + 1); | |
895 break; | |
896 } | |
897 case Bytecodes::_monitorexit: | |
898 { | |
899 pop_object(); | |
900 assert(monitor_count() > 0, "must be a monitor to exit from"); | |
901 set_monitor_count(monitor_count() - 1); | |
902 break; | |
903 } | |
904 case Bytecodes::_arraylength: | |
905 { | |
906 pop_array(); | |
907 push_int(); | |
908 break; | |
909 } | |
910 case Bytecodes::_astore: store_local_object(str->get_index()); break; | |
911 case Bytecodes::_astore_0: store_local_object(0); break; | |
912 case Bytecodes::_astore_1: store_local_object(1); break; | |
913 case Bytecodes::_astore_2: store_local_object(2); break; | |
914 case Bytecodes::_astore_3: store_local_object(3); break; | |
915 | |
916 case Bytecodes::_athrow: | |
917 { | |
918 NEEDS_CLEANUP; | |
919 pop_object(); | |
920 break; | |
921 } | |
922 case Bytecodes::_baload: | |
923 case Bytecodes::_caload: | |
924 case Bytecodes::_iaload: | |
925 case Bytecodes::_saload: | |
926 { | |
927 pop_int(); | |
928 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
929 // Put assert here for right type? | |
930 push_int(); | |
931 break; | |
932 } | |
933 case Bytecodes::_bastore: | |
934 case Bytecodes::_castore: | |
935 case Bytecodes::_iastore: | |
936 case Bytecodes::_sastore: | |
937 { | |
938 pop_int(); | |
939 pop_int(); | |
940 pop_typeArray(); | |
941 // assert here? | |
942 break; | |
943 } | |
944 case Bytecodes::_bipush: | |
945 case Bytecodes::_iconst_m1: | |
946 case Bytecodes::_iconst_0: | |
947 case Bytecodes::_iconst_1: | |
948 case Bytecodes::_iconst_2: | |
949 case Bytecodes::_iconst_3: | |
950 case Bytecodes::_iconst_4: | |
951 case Bytecodes::_iconst_5: | |
952 case Bytecodes::_sipush: | |
953 { | |
954 push_int(); | |
955 break; | |
956 } | |
957 case Bytecodes::_checkcast: do_checkcast(str); break; | |
958 | |
959 case Bytecodes::_d2f: | |
960 { | |
961 pop_double(); | |
962 push_float(); | |
963 break; | |
964 } | |
965 case Bytecodes::_d2i: | |
966 { | |
967 pop_double(); | |
968 push_int(); | |
969 break; | |
970 } | |
971 case Bytecodes::_d2l: | |
972 { | |
973 pop_double(); | |
974 push_long(); | |
975 break; | |
976 } | |
977 case Bytecodes::_dadd: | |
978 case Bytecodes::_ddiv: | |
979 case Bytecodes::_dmul: | |
980 case Bytecodes::_drem: | |
981 case Bytecodes::_dsub: | |
982 { | |
983 pop_double(); | |
984 pop_double(); | |
985 push_double(); | |
986 break; | |
987 } | |
988 case Bytecodes::_daload: | |
989 { | |
990 pop_int(); | |
991 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
992 // Put assert here for right type? | |
993 push_double(); | |
994 break; | |
995 } | |
996 case Bytecodes::_dastore: | |
997 { | |
998 pop_double(); | |
999 pop_int(); | |
1000 pop_typeArray(); | |
1001 // assert here? | |
1002 break; | |
1003 } | |
1004 case Bytecodes::_dcmpg: | |
1005 case Bytecodes::_dcmpl: | |
1006 { | |
1007 pop_double(); | |
1008 pop_double(); | |
1009 push_int(); | |
1010 break; | |
1011 } | |
1012 case Bytecodes::_dconst_0: | |
1013 case Bytecodes::_dconst_1: | |
1014 { | |
1015 push_double(); | |
1016 break; | |
1017 } | |
1018 case Bytecodes::_dload: load_local_double(str->get_index()); break; | |
1019 case Bytecodes::_dload_0: load_local_double(0); break; | |
1020 case Bytecodes::_dload_1: load_local_double(1); break; | |
1021 case Bytecodes::_dload_2: load_local_double(2); break; | |
1022 case Bytecodes::_dload_3: load_local_double(3); break; | |
1023 | |
1024 case Bytecodes::_dneg: | |
1025 { | |
1026 pop_double(); | |
1027 push_double(); | |
1028 break; | |
1029 } | |
1030 case Bytecodes::_dreturn: | |
1031 { | |
1032 pop_double(); | |
1033 break; | |
1034 } | |
1035 case Bytecodes::_dstore: store_local_double(str->get_index()); break; | |
1036 case Bytecodes::_dstore_0: store_local_double(0); break; | |
1037 case Bytecodes::_dstore_1: store_local_double(1); break; | |
1038 case Bytecodes::_dstore_2: store_local_double(2); break; | |
1039 case Bytecodes::_dstore_3: store_local_double(3); break; | |
1040 | |
1041 case Bytecodes::_dup: | |
1042 { | |
1043 push(type_at_tos()); | |
1044 break; | |
1045 } | |
1046 case Bytecodes::_dup_x1: | |
1047 { | |
1048 ciType* value1 = pop_value(); | |
1049 ciType* value2 = pop_value(); | |
1050 push(value1); | |
1051 push(value2); | |
1052 push(value1); | |
1053 break; | |
1054 } | |
1055 case Bytecodes::_dup_x2: | |
1056 { | |
1057 ciType* value1 = pop_value(); | |
1058 ciType* value2 = pop_value(); | |
1059 ciType* value3 = pop_value(); | |
1060 push(value1); | |
1061 push(value3); | |
1062 push(value2); | |
1063 push(value1); | |
1064 break; | |
1065 } | |
1066 case Bytecodes::_dup2: | |
1067 { | |
1068 ciType* value1 = pop_value(); | |
1069 ciType* value2 = pop_value(); | |
1070 push(value2); | |
1071 push(value1); | |
1072 push(value2); | |
1073 push(value1); | |
1074 break; | |
1075 } | |
1076 case Bytecodes::_dup2_x1: | |
1077 { | |
1078 ciType* value1 = pop_value(); | |
1079 ciType* value2 = pop_value(); | |
1080 ciType* value3 = pop_value(); | |
1081 push(value2); | |
1082 push(value1); | |
1083 push(value3); | |
1084 push(value2); | |
1085 push(value1); | |
1086 break; | |
1087 } | |
1088 case Bytecodes::_dup2_x2: | |
1089 { | |
1090 ciType* value1 = pop_value(); | |
1091 ciType* value2 = pop_value(); | |
1092 ciType* value3 = pop_value(); | |
1093 ciType* value4 = pop_value(); | |
1094 push(value2); | |
1095 push(value1); | |
1096 push(value4); | |
1097 push(value3); | |
1098 push(value2); | |
1099 push(value1); | |
1100 break; | |
1101 } | |
1102 case Bytecodes::_f2d: | |
1103 { | |
1104 pop_float(); | |
1105 push_double(); | |
1106 break; | |
1107 } | |
1108 case Bytecodes::_f2i: | |
1109 { | |
1110 pop_float(); | |
1111 push_int(); | |
1112 break; | |
1113 } | |
1114 case Bytecodes::_f2l: | |
1115 { | |
1116 pop_float(); | |
1117 push_long(); | |
1118 break; | |
1119 } | |
1120 case Bytecodes::_fadd: | |
1121 case Bytecodes::_fdiv: | |
1122 case Bytecodes::_fmul: | |
1123 case Bytecodes::_frem: | |
1124 case Bytecodes::_fsub: | |
1125 { | |
1126 pop_float(); | |
1127 pop_float(); | |
1128 push_float(); | |
1129 break; | |
1130 } | |
1131 case Bytecodes::_faload: | |
1132 { | |
1133 pop_int(); | |
1134 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
1135 // Put assert here. | |
1136 push_float(); | |
1137 break; | |
1138 } | |
1139 case Bytecodes::_fastore: | |
1140 { | |
1141 pop_float(); | |
1142 pop_int(); | |
1143 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
1144 // Put assert here. | |
1145 break; | |
1146 } | |
1147 case Bytecodes::_fcmpg: | |
1148 case Bytecodes::_fcmpl: | |
1149 { | |
1150 pop_float(); | |
1151 pop_float(); | |
1152 push_int(); | |
1153 break; | |
1154 } | |
1155 case Bytecodes::_fconst_0: | |
1156 case Bytecodes::_fconst_1: | |
1157 case Bytecodes::_fconst_2: | |
1158 { | |
1159 push_float(); | |
1160 break; | |
1161 } | |
1162 case Bytecodes::_fload: load_local_float(str->get_index()); break; | |
1163 case Bytecodes::_fload_0: load_local_float(0); break; | |
1164 case Bytecodes::_fload_1: load_local_float(1); break; | |
1165 case Bytecodes::_fload_2: load_local_float(2); break; | |
1166 case Bytecodes::_fload_3: load_local_float(3); break; | |
1167 | |
1168 case Bytecodes::_fneg: | |
1169 { | |
1170 pop_float(); | |
1171 push_float(); | |
1172 break; | |
1173 } | |
1174 case Bytecodes::_freturn: | |
1175 { | |
1176 pop_float(); | |
1177 break; | |
1178 } | |
1179 case Bytecodes::_fstore: store_local_float(str->get_index()); break; | |
1180 case Bytecodes::_fstore_0: store_local_float(0); break; | |
1181 case Bytecodes::_fstore_1: store_local_float(1); break; | |
1182 case Bytecodes::_fstore_2: store_local_float(2); break; | |
1183 case Bytecodes::_fstore_3: store_local_float(3); break; | |
1184 | |
1185 case Bytecodes::_getfield: do_getfield(str); break; | |
1186 case Bytecodes::_getstatic: do_getstatic(str); break; | |
1187 | |
1188 case Bytecodes::_goto: | |
1189 case Bytecodes::_goto_w: | |
1190 case Bytecodes::_nop: | |
1191 case Bytecodes::_return: | |
1192 { | |
1193 // do nothing. | |
1194 break; | |
1195 } | |
1196 case Bytecodes::_i2b: | |
1197 case Bytecodes::_i2c: | |
1198 case Bytecodes::_i2s: | |
1199 case Bytecodes::_ineg: | |
1200 { | |
1201 pop_int(); | |
1202 push_int(); | |
1203 break; | |
1204 } | |
1205 case Bytecodes::_i2d: | |
1206 { | |
1207 pop_int(); | |
1208 push_double(); | |
1209 break; | |
1210 } | |
1211 case Bytecodes::_i2f: | |
1212 { | |
1213 pop_int(); | |
1214 push_float(); | |
1215 break; | |
1216 } | |
1217 case Bytecodes::_i2l: | |
1218 { | |
1219 pop_int(); | |
1220 push_long(); | |
1221 break; | |
1222 } | |
1223 case Bytecodes::_iadd: | |
1224 case Bytecodes::_iand: | |
1225 case Bytecodes::_idiv: | |
1226 case Bytecodes::_imul: | |
1227 case Bytecodes::_ior: | |
1228 case Bytecodes::_irem: | |
1229 case Bytecodes::_ishl: | |
1230 case Bytecodes::_ishr: | |
1231 case Bytecodes::_isub: | |
1232 case Bytecodes::_iushr: | |
1233 case Bytecodes::_ixor: | |
1234 { | |
1235 pop_int(); | |
1236 pop_int(); | |
1237 push_int(); | |
1238 break; | |
1239 } | |
1240 case Bytecodes::_if_acmpeq: | |
1241 case Bytecodes::_if_acmpne: | |
1242 { | |
1243 pop_object(); | |
1244 pop_object(); | |
1245 break; | |
1246 } | |
1247 case Bytecodes::_if_icmpeq: | |
1248 case Bytecodes::_if_icmpge: | |
1249 case Bytecodes::_if_icmpgt: | |
1250 case Bytecodes::_if_icmple: | |
1251 case Bytecodes::_if_icmplt: | |
1252 case Bytecodes::_if_icmpne: | |
1253 { | |
1254 pop_int(); | |
1255 pop_int(); | |
1256 break; | |
1257 } | |
1258 case Bytecodes::_ifeq: | |
1259 case Bytecodes::_ifle: | |
1260 case Bytecodes::_iflt: | |
1261 case Bytecodes::_ifge: | |
1262 case Bytecodes::_ifgt: | |
1263 case Bytecodes::_ifne: | |
1264 case Bytecodes::_ireturn: | |
1265 case Bytecodes::_lookupswitch: | |
1266 case Bytecodes::_tableswitch: | |
1267 { | |
1268 pop_int(); | |
1269 break; | |
1270 } | |
1271 case Bytecodes::_iinc: | |
1272 { | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1273 int lnum = str->get_index(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1274 check_int(local(lnum)); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1275 store_to_local(lnum); |
0 | 1276 break; |
1277 } | |
1278 case Bytecodes::_iload: load_local_int(str->get_index()); break; | |
1279 case Bytecodes::_iload_0: load_local_int(0); break; | |
1280 case Bytecodes::_iload_1: load_local_int(1); break; | |
1281 case Bytecodes::_iload_2: load_local_int(2); break; | |
1282 case Bytecodes::_iload_3: load_local_int(3); break; | |
1283 | |
1284 case Bytecodes::_instanceof: | |
1285 { | |
1286 // Check for uncommon trap: | |
1287 do_checkcast(str); | |
1288 pop_object(); | |
1289 push_int(); | |
1290 break; | |
1291 } | |
1292 case Bytecodes::_invokeinterface: do_invoke(str, true); break; | |
1293 case Bytecodes::_invokespecial: do_invoke(str, true); break; | |
1294 case Bytecodes::_invokestatic: do_invoke(str, false); break; | |
1295 | |
1296 case Bytecodes::_invokevirtual: do_invoke(str, true); break; | |
1297 | |
1298 case Bytecodes::_istore: store_local_int(str->get_index()); break; | |
1299 case Bytecodes::_istore_0: store_local_int(0); break; | |
1300 case Bytecodes::_istore_1: store_local_int(1); break; | |
1301 case Bytecodes::_istore_2: store_local_int(2); break; | |
1302 case Bytecodes::_istore_3: store_local_int(3); break; | |
1303 | |
1304 case Bytecodes::_jsr: | |
1305 case Bytecodes::_jsr_w: do_jsr(str); break; | |
1306 | |
1307 case Bytecodes::_l2d: | |
1308 { | |
1309 pop_long(); | |
1310 push_double(); | |
1311 break; | |
1312 } | |
1313 case Bytecodes::_l2f: | |
1314 { | |
1315 pop_long(); | |
1316 push_float(); | |
1317 break; | |
1318 } | |
1319 case Bytecodes::_l2i: | |
1320 { | |
1321 pop_long(); | |
1322 push_int(); | |
1323 break; | |
1324 } | |
1325 case Bytecodes::_ladd: | |
1326 case Bytecodes::_land: | |
1327 case Bytecodes::_ldiv: | |
1328 case Bytecodes::_lmul: | |
1329 case Bytecodes::_lor: | |
1330 case Bytecodes::_lrem: | |
1331 case Bytecodes::_lsub: | |
1332 case Bytecodes::_lxor: | |
1333 { | |
1334 pop_long(); | |
1335 pop_long(); | |
1336 push_long(); | |
1337 break; | |
1338 } | |
1339 case Bytecodes::_laload: | |
1340 { | |
1341 pop_int(); | |
1342 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
1343 // Put assert here for right type? | |
1344 push_long(); | |
1345 break; | |
1346 } | |
1347 case Bytecodes::_lastore: | |
1348 { | |
1349 pop_long(); | |
1350 pop_int(); | |
1351 pop_typeArray(); | |
1352 // assert here? | |
1353 break; | |
1354 } | |
1355 case Bytecodes::_lcmp: | |
1356 { | |
1357 pop_long(); | |
1358 pop_long(); | |
1359 push_int(); | |
1360 break; | |
1361 } | |
1362 case Bytecodes::_lconst_0: | |
1363 case Bytecodes::_lconst_1: | |
1364 { | |
1365 push_long(); | |
1366 break; | |
1367 } | |
1368 case Bytecodes::_ldc: | |
1369 case Bytecodes::_ldc_w: | |
1370 case Bytecodes::_ldc2_w: | |
1371 { | |
1372 do_ldc(str); | |
1373 break; | |
1374 } | |
1375 | |
1376 case Bytecodes::_lload: load_local_long(str->get_index()); break; | |
1377 case Bytecodes::_lload_0: load_local_long(0); break; | |
1378 case Bytecodes::_lload_1: load_local_long(1); break; | |
1379 case Bytecodes::_lload_2: load_local_long(2); break; | |
1380 case Bytecodes::_lload_3: load_local_long(3); break; | |
1381 | |
1382 case Bytecodes::_lneg: | |
1383 { | |
1384 pop_long(); | |
1385 push_long(); | |
1386 break; | |
1387 } | |
1388 case Bytecodes::_lreturn: | |
1389 { | |
1390 pop_long(); | |
1391 break; | |
1392 } | |
1393 case Bytecodes::_lshl: | |
1394 case Bytecodes::_lshr: | |
1395 case Bytecodes::_lushr: | |
1396 { | |
1397 pop_int(); | |
1398 pop_long(); | |
1399 push_long(); | |
1400 break; | |
1401 } | |
1402 case Bytecodes::_lstore: store_local_long(str->get_index()); break; | |
1403 case Bytecodes::_lstore_0: store_local_long(0); break; | |
1404 case Bytecodes::_lstore_1: store_local_long(1); break; | |
1405 case Bytecodes::_lstore_2: store_local_long(2); break; | |
1406 case Bytecodes::_lstore_3: store_local_long(3); break; | |
1407 | |
1408 case Bytecodes::_multianewarray: do_multianewarray(str); break; | |
1409 | |
1410 case Bytecodes::_new: do_new(str); break; | |
1411 | |
1412 case Bytecodes::_newarray: do_newarray(str); break; | |
1413 | |
1414 case Bytecodes::_pop: | |
1415 { | |
1416 pop(); | |
1417 break; | |
1418 } | |
1419 case Bytecodes::_pop2: | |
1420 { | |
1421 pop(); | |
1422 pop(); | |
1423 break; | |
1424 } | |
1425 | |
1426 case Bytecodes::_putfield: do_putfield(str); break; | |
1427 case Bytecodes::_putstatic: do_putstatic(str); break; | |
1428 | |
1429 case Bytecodes::_ret: do_ret(str); break; | |
1430 | |
1431 case Bytecodes::_swap: | |
1432 { | |
1433 ciType* value1 = pop_value(); | |
1434 ciType* value2 = pop_value(); | |
1435 push(value1); | |
1436 push(value2); | |
1437 break; | |
1438 } | |
1439 case Bytecodes::_wide: | |
1440 default: | |
1441 { | |
1442 // The iterator should skip this. | |
1443 ShouldNotReachHere(); | |
1444 break; | |
1445 } | |
1446 } | |
1447 | |
1448 if (CITraceTypeFlow) { | |
1449 print_on(tty); | |
1450 } | |
1451 | |
1452 return (_trap_bci != -1); | |
1453 } | |
1454 | |
1455 #ifndef PRODUCT | |
1456 // ------------------------------------------------------------------ | |
1457 // ciTypeFlow::StateVector::print_cell_on | |
1458 void ciTypeFlow::StateVector::print_cell_on(outputStream* st, Cell c) const { | |
1459 ciType* type = type_at(c); | |
1460 if (type == top_type()) { | |
1461 st->print("top"); | |
1462 } else if (type == bottom_type()) { | |
1463 st->print("bottom"); | |
1464 } else if (type == null_type()) { | |
1465 st->print("null"); | |
1466 } else if (type == long2_type()) { | |
1467 st->print("long2"); | |
1468 } else if (type == double2_type()) { | |
1469 st->print("double2"); | |
1470 } else if (is_int(type)) { | |
1471 st->print("int"); | |
1472 } else if (is_long(type)) { | |
1473 st->print("long"); | |
1474 } else if (is_float(type)) { | |
1475 st->print("float"); | |
1476 } else if (is_double(type)) { | |
1477 st->print("double"); | |
1478 } else if (type->is_return_address()) { | |
1479 st->print("address(%d)", type->as_return_address()->bci()); | |
1480 } else { | |
1481 if (type->is_klass()) { | |
1482 type->as_klass()->name()->print_symbol_on(st); | |
1483 } else { | |
1484 st->print("UNEXPECTED TYPE"); | |
1485 type->print(); | |
1486 } | |
1487 } | |
1488 } | |
1489 | |
1490 // ------------------------------------------------------------------ | |
1491 // ciTypeFlow::StateVector::print_on | |
1492 void ciTypeFlow::StateVector::print_on(outputStream* st) const { | |
1493 int num_locals = _outer->max_locals(); | |
1494 int num_stack = stack_size(); | |
1495 int num_monitors = monitor_count(); | |
1496 st->print_cr(" State : locals %d, stack %d, monitors %d", num_locals, num_stack, num_monitors); | |
1497 if (num_stack >= 0) { | |
1498 int i; | |
1499 for (i = 0; i < num_locals; i++) { | |
1500 st->print(" local %2d : ", i); | |
1501 print_cell_on(st, local(i)); | |
1502 st->cr(); | |
1503 } | |
1504 for (i = 0; i < num_stack; i++) { | |
1505 st->print(" stack %2d : ", i); | |
1506 print_cell_on(st, stack(i)); | |
1507 st->cr(); | |
1508 } | |
1509 } | |
1510 } | |
1511 #endif | |
1512 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1513 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1514 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1515 // ciTypeFlow::SuccIter::next |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1516 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1517 void ciTypeFlow::SuccIter::next() { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1518 int succ_ct = _pred->successors()->length(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1519 int next = _index + 1; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1520 if (next < succ_ct) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1521 _index = next; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1522 _succ = _pred->successors()->at(next); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1523 return; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1524 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1525 for (int i = next - succ_ct; i < _pred->exceptions()->length(); i++) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1526 // Do not compile any code for unloaded exception types. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1527 // Following compiler passes are responsible for doing this also. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1528 ciInstanceKlass* exception_klass = _pred->exc_klasses()->at(i); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1529 if (exception_klass->is_loaded()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1530 _index = next; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1531 _succ = _pred->exceptions()->at(i); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1532 return; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1533 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1534 next++; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1535 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1536 _index = -1; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1537 _succ = NULL; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1538 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1539 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1540 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1541 // ciTypeFlow::SuccIter::set_succ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1542 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1543 void ciTypeFlow::SuccIter::set_succ(Block* succ) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1544 int succ_ct = _pred->successors()->length(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1545 if (_index < succ_ct) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1546 _pred->successors()->at_put(_index, succ); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1547 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1548 int idx = _index - succ_ct; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1549 _pred->exceptions()->at_put(idx, succ); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1550 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1551 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1552 |
0 | 1553 // ciTypeFlow::Block |
1554 // | |
1555 // A basic block. | |
1556 | |
1557 // ------------------------------------------------------------------ | |
1558 // ciTypeFlow::Block::Block | |
1559 ciTypeFlow::Block::Block(ciTypeFlow* outer, | |
1560 ciBlock *ciblk, | |
1561 ciTypeFlow::JsrSet* jsrs) { | |
1562 _ciblock = ciblk; | |
1563 _exceptions = NULL; | |
1564 _exc_klasses = NULL; | |
1565 _successors = NULL; | |
1566 _state = new (outer->arena()) StateVector(outer); | |
1567 JsrSet* new_jsrs = | |
1568 new (outer->arena()) JsrSet(outer->arena(), jsrs->size()); | |
1569 jsrs->copy_into(new_jsrs); | |
1570 _jsrs = new_jsrs; | |
1571 _next = NULL; | |
1572 _on_work_list = false; | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1573 _backedge_copy = false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1574 _exception_entry = false; |
0 | 1575 _trap_bci = -1; |
1576 _trap_index = 0; | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1577 df_init(); |
0 | 1578 |
1579 if (CITraceTypeFlow) { | |
1580 tty->print_cr(">> Created new block"); | |
1581 print_on(tty); | |
1582 } | |
1583 | |
1584 assert(this->outer() == outer, "outer link set up"); | |
1585 assert(!outer->have_block_count(), "must not have mapped blocks yet"); | |
1586 } | |
1587 | |
1588 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1589 // ciTypeFlow::Block::df_init |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1590 void ciTypeFlow::Block::df_init() { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1591 _pre_order = -1; assert(!has_pre_order(), ""); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1592 _post_order = -1; assert(!has_post_order(), ""); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1593 _loop = NULL; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1594 _irreducible_entry = false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1595 _rpo_next = NULL; |
0 | 1596 } |
1597 | |
1598 // ------------------------------------------------------------------ | |
1599 // ciTypeFlow::Block::successors | |
1600 // | |
1601 // Get the successors for this Block. | |
1602 GrowableArray<ciTypeFlow::Block*>* | |
1603 ciTypeFlow::Block::successors(ciBytecodeStream* str, | |
1604 ciTypeFlow::StateVector* state, | |
1605 ciTypeFlow::JsrSet* jsrs) { | |
1606 if (_successors == NULL) { | |
1607 if (CITraceTypeFlow) { | |
1608 tty->print(">> Computing successors for block "); | |
1609 print_value_on(tty); | |
1610 tty->cr(); | |
1611 } | |
1612 | |
1613 ciTypeFlow* analyzer = outer(); | |
1614 Arena* arena = analyzer->arena(); | |
1615 Block* block = NULL; | |
1616 bool has_successor = !has_trap() && | |
1617 (control() != ciBlock::fall_through_bci || limit() < analyzer->code_size()); | |
1618 if (!has_successor) { | |
1619 _successors = | |
1620 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1621 // No successors | |
1622 } else if (control() == ciBlock::fall_through_bci) { | |
1623 assert(str->cur_bci() == limit(), "bad block end"); | |
1624 // This block simply falls through to the next. | |
1625 _successors = | |
1626 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1627 | |
1628 Block* block = analyzer->block_at(limit(), _jsrs); | |
1629 assert(_successors->length() == FALL_THROUGH, ""); | |
1630 _successors->append(block); | |
1631 } else { | |
1632 int current_bci = str->cur_bci(); | |
1633 int next_bci = str->next_bci(); | |
1634 int branch_bci = -1; | |
1635 Block* target = NULL; | |
1636 assert(str->next_bci() == limit(), "bad block end"); | |
1637 // This block is not a simple fall-though. Interpret | |
1638 // the current bytecode to find our successors. | |
1639 switch (str->cur_bc()) { | |
1640 case Bytecodes::_ifeq: case Bytecodes::_ifne: | |
1641 case Bytecodes::_iflt: case Bytecodes::_ifge: | |
1642 case Bytecodes::_ifgt: case Bytecodes::_ifle: | |
1643 case Bytecodes::_if_icmpeq: case Bytecodes::_if_icmpne: | |
1644 case Bytecodes::_if_icmplt: case Bytecodes::_if_icmpge: | |
1645 case Bytecodes::_if_icmpgt: case Bytecodes::_if_icmple: | |
1646 case Bytecodes::_if_acmpeq: case Bytecodes::_if_acmpne: | |
1647 case Bytecodes::_ifnull: case Bytecodes::_ifnonnull: | |
1648 // Our successors are the branch target and the next bci. | |
1649 branch_bci = str->get_dest(); | |
1650 _successors = | |
1651 new (arena) GrowableArray<Block*>(arena, 2, 0, NULL); | |
1652 assert(_successors->length() == IF_NOT_TAKEN, ""); | |
1653 _successors->append(analyzer->block_at(next_bci, jsrs)); | |
1654 assert(_successors->length() == IF_TAKEN, ""); | |
1655 _successors->append(analyzer->block_at(branch_bci, jsrs)); | |
1656 break; | |
1657 | |
1658 case Bytecodes::_goto: | |
1659 branch_bci = str->get_dest(); | |
1660 _successors = | |
1661 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1662 assert(_successors->length() == GOTO_TARGET, ""); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1663 _successors->append(analyzer->block_at(branch_bci, jsrs)); |
0 | 1664 break; |
1665 | |
1666 case Bytecodes::_jsr: | |
1667 branch_bci = str->get_dest(); | |
1668 _successors = | |
1669 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1670 assert(_successors->length() == GOTO_TARGET, ""); | |
1671 _successors->append(analyzer->block_at(branch_bci, jsrs)); | |
1672 break; | |
1673 | |
1674 case Bytecodes::_goto_w: | |
1675 case Bytecodes::_jsr_w: | |
1676 _successors = | |
1677 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1678 assert(_successors->length() == GOTO_TARGET, ""); | |
1679 _successors->append(analyzer->block_at(str->get_far_dest(), jsrs)); | |
1680 break; | |
1681 | |
1682 case Bytecodes::_tableswitch: { | |
1683 Bytecode_tableswitch *tableswitch = | |
1684 Bytecode_tableswitch_at(str->cur_bcp()); | |
1685 | |
1686 int len = tableswitch->length(); | |
1687 _successors = | |
1688 new (arena) GrowableArray<Block*>(arena, len+1, 0, NULL); | |
1689 int bci = current_bci + tableswitch->default_offset(); | |
1690 Block* block = analyzer->block_at(bci, jsrs); | |
1691 assert(_successors->length() == SWITCH_DEFAULT, ""); | |
1692 _successors->append(block); | |
1693 while (--len >= 0) { | |
1694 int bci = current_bci + tableswitch->dest_offset_at(len); | |
1695 block = analyzer->block_at(bci, jsrs); | |
1696 assert(_successors->length() >= SWITCH_CASES, ""); | |
1697 _successors->append_if_missing(block); | |
1698 } | |
1699 break; | |
1700 } | |
1701 | |
1702 case Bytecodes::_lookupswitch: { | |
1703 Bytecode_lookupswitch *lookupswitch = | |
1704 Bytecode_lookupswitch_at(str->cur_bcp()); | |
1705 | |
1706 int npairs = lookupswitch->number_of_pairs(); | |
1707 _successors = | |
1708 new (arena) GrowableArray<Block*>(arena, npairs+1, 0, NULL); | |
1709 int bci = current_bci + lookupswitch->default_offset(); | |
1710 Block* block = analyzer->block_at(bci, jsrs); | |
1711 assert(_successors->length() == SWITCH_DEFAULT, ""); | |
1712 _successors->append(block); | |
1713 while(--npairs >= 0) { | |
1714 LookupswitchPair *pair = lookupswitch->pair_at(npairs); | |
1715 int bci = current_bci + pair->offset(); | |
1716 Block* block = analyzer->block_at(bci, jsrs); | |
1717 assert(_successors->length() >= SWITCH_CASES, ""); | |
1718 _successors->append_if_missing(block); | |
1719 } | |
1720 break; | |
1721 } | |
1722 | |
1723 case Bytecodes::_athrow: case Bytecodes::_ireturn: | |
1724 case Bytecodes::_lreturn: case Bytecodes::_freturn: | |
1725 case Bytecodes::_dreturn: case Bytecodes::_areturn: | |
1726 case Bytecodes::_return: | |
1727 _successors = | |
1728 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1729 // No successors | |
1730 break; | |
1731 | |
1732 case Bytecodes::_ret: { | |
1733 _successors = | |
1734 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1735 | |
1736 Cell local = state->local(str->get_index()); | |
1737 ciType* return_address = state->type_at(local); | |
1738 assert(return_address->is_return_address(), "verify: wrong type"); | |
1739 int bci = return_address->as_return_address()->bci(); | |
1740 assert(_successors->length() == GOTO_TARGET, ""); | |
1741 _successors->append(analyzer->block_at(bci, jsrs)); | |
1742 break; | |
1743 } | |
1744 | |
1745 case Bytecodes::_wide: | |
1746 default: | |
1747 ShouldNotReachHere(); | |
1748 break; | |
1749 } | |
1750 } | |
1751 } | |
1752 return _successors; | |
1753 } | |
1754 | |
1755 // ------------------------------------------------------------------ | |
1756 // ciTypeFlow::Block:compute_exceptions | |
1757 // | |
1758 // Compute the exceptional successors and types for this Block. | |
1759 void ciTypeFlow::Block::compute_exceptions() { | |
1760 assert(_exceptions == NULL && _exc_klasses == NULL, "repeat"); | |
1761 | |
1762 if (CITraceTypeFlow) { | |
1763 tty->print(">> Computing exceptions for block "); | |
1764 print_value_on(tty); | |
1765 tty->cr(); | |
1766 } | |
1767 | |
1768 ciTypeFlow* analyzer = outer(); | |
1769 Arena* arena = analyzer->arena(); | |
1770 | |
1771 // Any bci in the block will do. | |
1772 ciExceptionHandlerStream str(analyzer->method(), start()); | |
1773 | |
1774 // Allocate our growable arrays. | |
1775 int exc_count = str.count(); | |
1776 _exceptions = new (arena) GrowableArray<Block*>(arena, exc_count, 0, NULL); | |
1777 _exc_klasses = new (arena) GrowableArray<ciInstanceKlass*>(arena, exc_count, | |
1778 0, NULL); | |
1779 | |
1780 for ( ; !str.is_done(); str.next()) { | |
1781 ciExceptionHandler* handler = str.handler(); | |
1782 int bci = handler->handler_bci(); | |
1783 ciInstanceKlass* klass = NULL; | |
1784 if (bci == -1) { | |
1785 // There is no catch all. It is possible to exit the method. | |
1786 break; | |
1787 } | |
1788 if (handler->is_catch_all()) { | |
1789 klass = analyzer->env()->Throwable_klass(); | |
1790 } else { | |
1791 klass = handler->catch_klass(); | |
1792 } | |
1793 _exceptions->append(analyzer->block_at(bci, _jsrs)); | |
1794 _exc_klasses->append(klass); | |
1795 } | |
1796 } | |
1797 | |
1798 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1799 // ciTypeFlow::Block::set_backedge_copy |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1800 // Use this only to make a pre-existing public block into a backedge copy. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1801 void ciTypeFlow::Block::set_backedge_copy(bool z) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1802 assert(z || (z == is_backedge_copy()), "cannot make a backedge copy public"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1803 _backedge_copy = z; |
0 | 1804 } |
1805 | |
1806 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1807 // ciTypeFlow::Block::is_clonable_exit |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1808 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1809 // At most 2 normal successors, one of which continues looping, |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1810 // and all exceptional successors must exit. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1811 bool ciTypeFlow::Block::is_clonable_exit(ciTypeFlow::Loop* lp) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1812 int normal_cnt = 0; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1813 int in_loop_cnt = 0; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1814 for (SuccIter iter(this); !iter.done(); iter.next()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1815 Block* succ = iter.succ(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1816 if (iter.is_normal_ctrl()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1817 if (++normal_cnt > 2) return false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1818 if (lp->contains(succ->loop())) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1819 if (++in_loop_cnt > 1) return false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1820 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1821 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1822 if (lp->contains(succ->loop())) return false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1823 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1824 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1825 return in_loop_cnt == 1; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1826 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1827 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1828 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1829 // ciTypeFlow::Block::looping_succ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1830 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1831 ciTypeFlow::Block* ciTypeFlow::Block::looping_succ(ciTypeFlow::Loop* lp) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1832 assert(successors()->length() <= 2, "at most 2 normal successors"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1833 for (SuccIter iter(this); !iter.done(); iter.next()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1834 Block* succ = iter.succ(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1835 if (lp->contains(succ->loop())) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1836 return succ; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1837 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1838 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1839 return NULL; |
0 | 1840 } |
1841 | |
1842 #ifndef PRODUCT | |
1843 // ------------------------------------------------------------------ | |
1844 // ciTypeFlow::Block::print_value_on | |
1845 void ciTypeFlow::Block::print_value_on(outputStream* st) const { | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1846 if (has_pre_order()) st->print("#%-2d ", pre_order()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1847 if (has_rpo()) st->print("rpo#%-2d ", rpo()); |
0 | 1848 st->print("[%d - %d)", start(), limit()); |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1849 if (is_loop_head()) st->print(" lphd"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1850 if (is_irreducible_entry()) st->print(" irred"); |
0 | 1851 if (_jsrs->size() > 0) { st->print("/"); _jsrs->print_on(st); } |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1852 if (is_backedge_copy()) st->print("/backedge_copy"); |
0 | 1853 } |
1854 | |
1855 // ------------------------------------------------------------------ | |
1856 // ciTypeFlow::Block::print_on | |
1857 void ciTypeFlow::Block::print_on(outputStream* st) const { | |
1858 if ((Verbose || WizardMode)) { | |
1859 outer()->method()->print_codes_on(start(), limit(), st); | |
1860 } | |
1861 st->print_cr(" ==================================================== "); | |
1862 st->print (" "); | |
1863 print_value_on(st); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1864 st->print(" Stored locals: "); def_locals()->print_on(st, outer()->method()->max_locals()); tty->cr(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1865 if (loop() && loop()->parent() != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1866 st->print(" loops:"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1867 Loop* lp = loop(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1868 do { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1869 st->print(" %d<-%d", lp->head()->pre_order(),lp->tail()->pre_order()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1870 if (lp->is_irreducible()) st->print("(ir)"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1871 lp = lp->parent(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1872 } while (lp->parent() != NULL); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1873 } |
0 | 1874 st->cr(); |
1875 _state->print_on(st); | |
1876 if (_successors == NULL) { | |
1877 st->print_cr(" No successor information"); | |
1878 } else { | |
1879 int num_successors = _successors->length(); | |
1880 st->print_cr(" Successors : %d", num_successors); | |
1881 for (int i = 0; i < num_successors; i++) { | |
1882 Block* successor = _successors->at(i); | |
1883 st->print(" "); | |
1884 successor->print_value_on(st); | |
1885 st->cr(); | |
1886 } | |
1887 } | |
1888 if (_exceptions == NULL) { | |
1889 st->print_cr(" No exception information"); | |
1890 } else { | |
1891 int num_exceptions = _exceptions->length(); | |
1892 st->print_cr(" Exceptions : %d", num_exceptions); | |
1893 for (int i = 0; i < num_exceptions; i++) { | |
1894 Block* exc_succ = _exceptions->at(i); | |
1895 ciInstanceKlass* exc_klass = _exc_klasses->at(i); | |
1896 st->print(" "); | |
1897 exc_succ->print_value_on(st); | |
1898 st->print(" -- "); | |
1899 exc_klass->name()->print_symbol_on(st); | |
1900 st->cr(); | |
1901 } | |
1902 } | |
1903 if (has_trap()) { | |
1904 st->print_cr(" Traps on %d with trap index %d", trap_bci(), trap_index()); | |
1905 } | |
1906 st->print_cr(" ==================================================== "); | |
1907 } | |
1908 #endif | |
1909 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1910 #ifndef PRODUCT |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1911 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1912 // ciTypeFlow::LocalSet::print_on |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1913 void ciTypeFlow::LocalSet::print_on(outputStream* st, int limit) const { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1914 st->print("{"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1915 for (int i = 0; i < max; i++) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1916 if (test(i)) st->print(" %d", i); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1917 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1918 if (limit > max) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1919 st->print(" %d..%d ", max, limit); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1920 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1921 st->print(" }"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1922 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1923 #endif |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1924 |
0 | 1925 // ciTypeFlow |
1926 // | |
1927 // This is a pass over the bytecodes which computes the following: | |
1928 // basic block structure | |
1929 // interpreter type-states (a la the verifier) | |
1930 | |
1931 // ------------------------------------------------------------------ | |
1932 // ciTypeFlow::ciTypeFlow | |
1933 ciTypeFlow::ciTypeFlow(ciEnv* env, ciMethod* method, int osr_bci) { | |
1934 _env = env; | |
1935 _method = method; | |
1936 _methodBlocks = method->get_method_blocks(); | |
1937 _max_locals = method->max_locals(); | |
1938 _max_stack = method->max_stack(); | |
1939 _code_size = method->code_size(); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1940 _has_irreducible_entry = false; |
0 | 1941 _osr_bci = osr_bci; |
1942 _failure_reason = NULL; | |
1943 assert(start_bci() >= 0 && start_bci() < code_size() , "correct osr_bci argument"); | |
1944 _work_list = NULL; | |
1945 | |
1946 _ciblock_count = _methodBlocks->num_blocks(); | |
1947 _idx_to_blocklist = NEW_ARENA_ARRAY(arena(), GrowableArray<Block*>*, _ciblock_count); | |
1948 for (int i = 0; i < _ciblock_count; i++) { | |
1949 _idx_to_blocklist[i] = NULL; | |
1950 } | |
1951 _block_map = NULL; // until all blocks are seen | |
1952 _jsr_count = 0; | |
1953 _jsr_records = NULL; | |
1954 } | |
1955 | |
1956 // ------------------------------------------------------------------ | |
1957 // ciTypeFlow::work_list_next | |
1958 // | |
1959 // Get the next basic block from our work list. | |
1960 ciTypeFlow::Block* ciTypeFlow::work_list_next() { | |
1961 assert(!work_list_empty(), "work list must not be empty"); | |
1962 Block* next_block = _work_list; | |
1963 _work_list = next_block->next(); | |
1964 next_block->set_next(NULL); | |
1965 next_block->set_on_work_list(false); | |
1966 return next_block; | |
1967 } | |
1968 | |
1969 // ------------------------------------------------------------------ | |
1970 // ciTypeFlow::add_to_work_list | |
1971 // | |
1972 // Add a basic block to our work list. | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1973 // List is sorted by decreasing postorder sort (same as increasing RPO) |
0 | 1974 void ciTypeFlow::add_to_work_list(ciTypeFlow::Block* block) { |
1975 assert(!block->is_on_work_list(), "must not already be on work list"); | |
1976 | |
1977 if (CITraceTypeFlow) { | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1978 tty->print(">> Adding block "); |
0 | 1979 block->print_value_on(tty); |
1980 tty->print_cr(" to the work list : "); | |
1981 } | |
1982 | |
1983 block->set_on_work_list(true); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1984 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1985 // decreasing post order sort |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1986 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1987 Block* prev = NULL; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1988 Block* current = _work_list; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1989 int po = block->post_order(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1990 while (current != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1991 if (!current->has_post_order() || po > current->post_order()) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1992 break; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1993 prev = current; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1994 current = current->next(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1995 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1996 if (prev == NULL) { |
0 | 1997 block->set_next(_work_list); |
1998 _work_list = block; | |
1999 } else { | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2000 block->set_next(current); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2001 prev->set_next(block); |
0 | 2002 } |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2003 |
0 | 2004 if (CITraceTypeFlow) { |
2005 tty->cr(); | |
2006 } | |
2007 } | |
2008 | |
2009 // ------------------------------------------------------------------ | |
2010 // ciTypeFlow::block_at | |
2011 // | |
2012 // Return the block beginning at bci which has a JsrSet compatible | |
2013 // with jsrs. | |
2014 ciTypeFlow::Block* ciTypeFlow::block_at(int bci, ciTypeFlow::JsrSet* jsrs, CreateOption option) { | |
2015 // First find the right ciBlock. | |
2016 if (CITraceTypeFlow) { | |
2017 tty->print(">> Requesting block for %d/", bci); | |
2018 jsrs->print_on(tty); | |
2019 tty->cr(); | |
2020 } | |
2021 | |
2022 ciBlock* ciblk = _methodBlocks->block_containing(bci); | |
2023 assert(ciblk->start_bci() == bci, "bad ciBlock boundaries"); | |
2024 Block* block = get_block_for(ciblk->index(), jsrs, option); | |
2025 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2026 assert(block == NULL? (option == no_create): block->is_backedge_copy() == (option == create_backedge_copy), "create option consistent with result"); |
0 | 2027 |
2028 if (CITraceTypeFlow) { | |
2029 if (block != NULL) { | |
2030 tty->print(">> Found block "); | |
2031 block->print_value_on(tty); | |
2032 tty->cr(); | |
2033 } else { | |
2034 tty->print_cr(">> No such block."); | |
2035 } | |
2036 } | |
2037 | |
2038 return block; | |
2039 } | |
2040 | |
2041 // ------------------------------------------------------------------ | |
2042 // ciTypeFlow::make_jsr_record | |
2043 // | |
2044 // Make a JsrRecord for a given (entry, return) pair, if such a record | |
2045 // does not already exist. | |
2046 ciTypeFlow::JsrRecord* ciTypeFlow::make_jsr_record(int entry_address, | |
2047 int return_address) { | |
2048 if (_jsr_records == NULL) { | |
2049 _jsr_records = new (arena()) GrowableArray<JsrRecord*>(arena(), | |
2050 _jsr_count, | |
2051 0, | |
2052 NULL); | |
2053 } | |
2054 JsrRecord* record = NULL; | |
2055 int len = _jsr_records->length(); | |
2056 for (int i = 0; i < len; i++) { | |
2057 JsrRecord* record = _jsr_records->at(i); | |
2058 if (record->entry_address() == entry_address && | |
2059 record->return_address() == return_address) { | |
2060 return record; | |
2061 } | |
2062 } | |
2063 | |
2064 record = new (arena()) JsrRecord(entry_address, return_address); | |
2065 _jsr_records->append(record); | |
2066 return record; | |
2067 } | |
2068 | |
2069 // ------------------------------------------------------------------ | |
2070 // ciTypeFlow::flow_exceptions | |
2071 // | |
2072 // Merge the current state into all exceptional successors at the | |
2073 // current point in the code. | |
2074 void ciTypeFlow::flow_exceptions(GrowableArray<ciTypeFlow::Block*>* exceptions, | |
2075 GrowableArray<ciInstanceKlass*>* exc_klasses, | |
2076 ciTypeFlow::StateVector* state) { | |
2077 int len = exceptions->length(); | |
2078 assert(exc_klasses->length() == len, "must have same length"); | |
2079 for (int i = 0; i < len; i++) { | |
2080 Block* block = exceptions->at(i); | |
2081 ciInstanceKlass* exception_klass = exc_klasses->at(i); | |
2082 | |
2083 if (!exception_klass->is_loaded()) { | |
2084 // Do not compile any code for unloaded exception types. | |
2085 // Following compiler passes are responsible for doing this also. | |
2086 continue; | |
2087 } | |
2088 | |
2089 if (block->meet_exception(exception_klass, state)) { | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2090 // Block was modified and has PO. Add it to the work list. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2091 if (block->has_post_order() && |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2092 !block->is_on_work_list()) { |
0 | 2093 add_to_work_list(block); |
2094 } | |
2095 } | |
2096 } | |
2097 } | |
2098 | |
2099 // ------------------------------------------------------------------ | |
2100 // ciTypeFlow::flow_successors | |
2101 // | |
2102 // Merge the current state into all successors at the current point | |
2103 // in the code. | |
2104 void ciTypeFlow::flow_successors(GrowableArray<ciTypeFlow::Block*>* successors, | |
2105 ciTypeFlow::StateVector* state) { | |
2106 int len = successors->length(); | |
2107 for (int i = 0; i < len; i++) { | |
2108 Block* block = successors->at(i); | |
2109 if (block->meet(state)) { | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2110 // Block was modified and has PO. Add it to the work list. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2111 if (block->has_post_order() && |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2112 !block->is_on_work_list()) { |
0 | 2113 add_to_work_list(block); |
2114 } | |
2115 } | |
2116 } | |
2117 } | |
2118 | |
2119 // ------------------------------------------------------------------ | |
2120 // ciTypeFlow::can_trap | |
2121 // | |
2122 // Tells if a given instruction is able to generate an exception edge. | |
2123 bool ciTypeFlow::can_trap(ciBytecodeStream& str) { | |
2124 // Cf. GenerateOopMap::do_exception_edge. | |
2125 if (!Bytecodes::can_trap(str.cur_bc())) return false; | |
2126 | |
2127 switch (str.cur_bc()) { | |
2128 case Bytecodes::_ldc: | |
2129 case Bytecodes::_ldc_w: | |
2130 case Bytecodes::_ldc2_w: | |
2131 case Bytecodes::_aload_0: | |
2132 // These bytecodes can trap for rewriting. We need to assume that | |
2133 // they do not throw exceptions to make the monitor analysis work. | |
2134 return false; | |
2135 | |
2136 case Bytecodes::_ireturn: | |
2137 case Bytecodes::_lreturn: | |
2138 case Bytecodes::_freturn: | |
2139 case Bytecodes::_dreturn: | |
2140 case Bytecodes::_areturn: | |
2141 case Bytecodes::_return: | |
2142 // We can assume the monitor stack is empty in this analysis. | |
2143 return false; | |
2144 | |
2145 case Bytecodes::_monitorexit: | |
2146 // We can assume monitors are matched in this analysis. | |
2147 return false; | |
2148 } | |
2149 | |
2150 return true; | |
2151 } | |
2152 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2153 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2154 // ciTypeFlow::clone_loop_heads |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2155 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2156 // Clone the loop heads |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2157 bool ciTypeFlow::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:
0
diff
changeset
|
2158 bool rslt = false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2159 for (PreorderLoops iter(loop_tree_root()); !iter.done(); iter.next()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2160 lp = iter.current(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2161 Block* head = lp->head(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2162 if (lp == loop_tree_root() || |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2163 lp->is_irreducible() || |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2164 !head->is_clonable_exit(lp)) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2165 continue; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2166 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2167 // check not already cloned |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2168 if (head->backedge_copy_count() != 0) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2169 continue; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2170 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2171 // check _no_ shared head below us |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2172 Loop* ch; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2173 for (ch = lp->child(); ch != NULL && ch->head() != head; ch = ch->sibling()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2174 if (ch != NULL) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2175 continue; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2176 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2177 // Clone head |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2178 Block* new_head = head->looping_succ(lp); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2179 Block* clone = clone_loop_head(lp, temp_vector, temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2180 // Update lp's info |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2181 clone->set_loop(lp); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2182 lp->set_head(new_head); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2183 lp->set_tail(clone); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2184 // And move original head into outer loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2185 head->set_loop(lp->parent()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2186 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2187 rslt = true; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2188 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2189 return rslt; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2190 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2191 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2192 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2193 // ciTypeFlow::clone_loop_head |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2194 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2195 // 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:
0
diff
changeset
|
2196 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2197 // | |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2198 // v |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2199 // head <-> body |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2200 // | |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2201 // v |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2202 // exit |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2203 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2204 // new_head |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2205 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2206 // | |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2207 // v |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2208 // head ----------\ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2209 // | | |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2210 // | v |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2211 // | clone <-> body |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2212 // | | |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2213 // | /--/ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2214 // | | |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2215 // v v |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2216 // exit |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2217 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2218 ciTypeFlow::Block* ciTypeFlow::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:
0
diff
changeset
|
2219 Block* head = lp->head(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2220 Block* tail = lp->tail(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2221 if (CITraceTypeFlow) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2222 tty->print(">> Requesting clone of loop head "); head->print_value_on(tty); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2223 tty->print(" for predecessor "); tail->print_value_on(tty); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2224 tty->cr(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2225 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2226 Block* clone = block_at(head->start(), head->jsrs(), create_backedge_copy); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2227 assert(clone->backedge_copy_count() == 1, "one backedge copy for all back edges"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2228 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2229 assert(!clone->has_pre_order(), "just created"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2230 clone->set_next_pre_order(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2231 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2232 // Insert clone after (orig) tail in reverse post order |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2233 clone->set_rpo_next(tail->rpo_next()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2234 tail->set_rpo_next(clone); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2235 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2236 // tail->head becomes tail->clone |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2237 for (SuccIter iter(tail); !iter.done(); iter.next()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2238 if (iter.succ() == head) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2239 iter.set_succ(clone); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2240 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2241 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2242 flow_block(tail, temp_vector, temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2243 if (head == tail) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2244 // For self-loops, clone->head becomes clone->clone |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2245 flow_block(clone, temp_vector, temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2246 for (SuccIter iter(clone); !iter.done(); iter.next()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2247 if (iter.succ() == head) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2248 iter.set_succ(clone); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2249 break; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2250 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2251 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2252 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2253 flow_block(clone, temp_vector, temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2254 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2255 return clone; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2256 } |
0 | 2257 |
2258 // ------------------------------------------------------------------ | |
2259 // ciTypeFlow::flow_block | |
2260 // | |
2261 // Interpret the effects of the bytecodes on the incoming state | |
2262 // vector of a basic block. Push the changed state to succeeding | |
2263 // basic blocks. | |
2264 void ciTypeFlow::flow_block(ciTypeFlow::Block* block, | |
2265 ciTypeFlow::StateVector* state, | |
2266 ciTypeFlow::JsrSet* jsrs) { | |
2267 if (CITraceTypeFlow) { | |
2268 tty->print("\n>> ANALYZING BLOCK : "); | |
2269 tty->cr(); | |
2270 block->print_on(tty); | |
2271 } | |
2272 assert(block->has_pre_order(), "pre-order is assigned before 1st flow"); | |
2273 | |
2274 int start = block->start(); | |
2275 int limit = block->limit(); | |
2276 int control = block->control(); | |
2277 if (control != ciBlock::fall_through_bci) { | |
2278 limit = control; | |
2279 } | |
2280 | |
2281 // Grab the state from the current block. | |
2282 block->copy_state_into(state); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2283 state->def_locals()->clear(); |
0 | 2284 |
2285 GrowableArray<Block*>* exceptions = block->exceptions(); | |
2286 GrowableArray<ciInstanceKlass*>* exc_klasses = block->exc_klasses(); | |
2287 bool has_exceptions = exceptions->length() > 0; | |
2288 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2289 bool exceptions_used = false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2290 |
0 | 2291 ciBytecodeStream str(method()); |
2292 str.reset_to_bci(start); | |
2293 Bytecodes::Code code; | |
2294 while ((code = str.next()) != ciBytecodeStream::EOBC() && | |
2295 str.cur_bci() < limit) { | |
2296 // Check for exceptional control flow from this point. | |
2297 if (has_exceptions && can_trap(str)) { | |
2298 flow_exceptions(exceptions, exc_klasses, state); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2299 exceptions_used = true; |
0 | 2300 } |
2301 // Apply the effects of the current bytecode to our state. | |
2302 bool res = state->apply_one_bytecode(&str); | |
2303 | |
2304 // Watch for bailouts. | |
2305 if (failing()) return; | |
2306 | |
2307 if (res) { | |
2308 | |
2309 // We have encountered a trap. Record it in this block. | |
2310 block->set_trap(state->trap_bci(), state->trap_index()); | |
2311 | |
2312 if (CITraceTypeFlow) { | |
2313 tty->print_cr(">> Found trap"); | |
2314 block->print_on(tty); | |
2315 } | |
2316 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2317 // Save set of locals defined in this block |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2318 block->def_locals()->add(state->def_locals()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2319 |
0 | 2320 // Record (no) successors. |
2321 block->successors(&str, state, jsrs); | |
2322 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2323 assert(!has_exceptions || exceptions_used, "Not removing exceptions"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2324 |
0 | 2325 // Discontinue interpretation of this Block. |
2326 return; | |
2327 } | |
2328 } | |
2329 | |
2330 GrowableArray<Block*>* successors = NULL; | |
2331 if (control != ciBlock::fall_through_bci) { | |
2332 // Check for exceptional control flow from this point. | |
2333 if (has_exceptions && can_trap(str)) { | |
2334 flow_exceptions(exceptions, exc_klasses, state); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2335 exceptions_used = true; |
0 | 2336 } |
2337 | |
2338 // Fix the JsrSet to reflect effect of the bytecode. | |
2339 block->copy_jsrs_into(jsrs); | |
2340 jsrs->apply_control(this, &str, state); | |
2341 | |
2342 // Find successor edges based on old state and new JsrSet. | |
2343 successors = block->successors(&str, state, jsrs); | |
2344 | |
2345 // Apply the control changes to the state. | |
2346 state->apply_one_bytecode(&str); | |
2347 } else { | |
2348 // Fall through control | |
2349 successors = block->successors(&str, NULL, NULL); | |
2350 } | |
2351 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2352 // Save set of locals defined in this block |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2353 block->def_locals()->add(state->def_locals()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2354 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2355 // Remove untaken exception paths |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2356 if (!exceptions_used) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2357 exceptions->clear(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2358 |
0 | 2359 // Pass our state to successors. |
2360 flow_successors(successors, state); | |
2361 } | |
2362 | |
2363 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2364 // ciTypeFlow::PostOrderLoops::next |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2365 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2366 // Advance to next loop tree using a postorder, left-to-right traversal. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2367 void ciTypeFlow::PostorderLoops::next() { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2368 assert(!done(), "must not be done."); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2369 if (_current->sibling() != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2370 _current = _current->sibling(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2371 while (_current->child() != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2372 _current = _current->child(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2373 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2374 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2375 _current = _current->parent(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2376 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2377 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2378 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2379 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2380 // ciTypeFlow::PreOrderLoops::next |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2381 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2382 // Advance to next loop tree using a preorder, left-to-right traversal. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2383 void ciTypeFlow::PreorderLoops::next() { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2384 assert(!done(), "must not be done."); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2385 if (_current->child() != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2386 _current = _current->child(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2387 } else if (_current->sibling() != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2388 _current = _current->sibling(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2389 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2390 while (_current != _root && _current->sibling() == NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2391 _current = _current->parent(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2392 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2393 if (_current == _root) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2394 _current = NULL; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2395 assert(done(), "must be done."); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2396 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2397 assert(_current->sibling() != NULL, "must be more to do"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2398 _current = _current->sibling(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2399 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2400 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2401 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2402 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2403 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2404 // ciTypeFlow::Loop::sorted_merge |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2405 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2406 // 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:
0
diff
changeset
|
2407 // pre_orders. Returns the leaf of the merged branch. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2408 // Child and sibling pointers will be setup later. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2409 // Sort is (looking from leaf towards the root) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2410 // descending on primary key: loop head's pre_order, and |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2411 // ascending on secondary key: loop tail's pre_order. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2412 ciTypeFlow::Loop* ciTypeFlow::Loop::sorted_merge(Loop* lp) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2413 Loop* leaf = this; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2414 Loop* prev = NULL; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2415 Loop* current = leaf; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2416 while (lp != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2417 int lp_pre_order = lp->head()->pre_order(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2418 // Find insertion point for "lp" |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2419 while (current != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2420 if (current == lp) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2421 return leaf; // Already in list |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2422 if (current->head()->pre_order() < lp_pre_order) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2423 break; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2424 if (current->head()->pre_order() == lp_pre_order && |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2425 current->tail()->pre_order() > lp->tail()->pre_order()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2426 break; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2427 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2428 prev = current; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2429 current = current->parent(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2430 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2431 Loop* next_lp = lp->parent(); // Save future list of items to insert |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2432 // Insert lp before current |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2433 lp->set_parent(current); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2434 if (prev != NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2435 prev->set_parent(lp); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2436 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2437 leaf = lp; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2438 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2439 prev = lp; // Inserted item is new prev[ious] |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2440 lp = next_lp; // Next item to insert |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2441 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2442 return leaf; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2443 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2444 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2445 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2446 // ciTypeFlow::build_loop_tree |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2447 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2448 // Incrementally build loop tree. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2449 void ciTypeFlow::build_loop_tree(Block* blk) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2450 assert(!blk->is_post_visited(), "precondition"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2451 Loop* innermost = NULL; // merge of loop tree branches over all successors |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2452 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2453 for (SuccIter iter(blk); !iter.done(); iter.next()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2454 Loop* lp = NULL; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2455 Block* succ = iter.succ(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2456 if (!succ->is_post_visited()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2457 // Found backedge since predecessor post visited, but successor is not |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2458 assert(succ->pre_order() <= blk->pre_order(), "should be backedge"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2459 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2460 // Create a LoopNode to mark this loop. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2461 lp = new (arena()) Loop(succ, blk); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2462 if (succ->loop() == NULL) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2463 succ->set_loop(lp); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2464 // succ->loop will be updated to innermost loop on a later call, when blk==succ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2465 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2466 } else { // Nested loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2467 lp = succ->loop(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2468 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2469 // If succ is loop head, find outer loop. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2470 while (lp != NULL && lp->head() == succ) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2471 lp = lp->parent(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2472 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2473 if (lp == NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2474 // Infinite loop, it's parent is the root |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2475 lp = loop_tree_root(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2476 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2477 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2478 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2479 // Check for irreducible loop. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2480 // Successor has already been visited. If the successor's loop head |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2481 // has already been post-visited, then this is another entry into the loop. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2482 while (lp->head()->is_post_visited() && lp != loop_tree_root()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2483 _has_irreducible_entry = true; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2484 lp->set_irreducible(succ); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2485 if (!succ->is_on_work_list()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2486 // Assume irreducible entries need more data flow |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2487 add_to_work_list(succ); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2488 } |
991 | 2489 Loop* plp = lp->parent(); |
2490 if (plp == NULL) { | |
2491 // This only happens for some irreducible cases. The parent | |
2492 // will be updated during a later pass. | |
2493 break; | |
2494 } | |
2495 lp = plp; | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2496 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2497 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2498 // Merge loop tree branch for all successors. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2499 innermost = innermost == NULL ? lp : innermost->sorted_merge(lp); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2500 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2501 } // end loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2502 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2503 if (innermost == NULL) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2504 assert(blk->successors()->length() == 0, "CFG exit"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2505 blk->set_loop(loop_tree_root()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2506 } else if (innermost->head() == blk) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2507 // If loop header, complete the tree pointers |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2508 if (blk->loop() != innermost) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2509 #if ASSERT |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2510 assert(blk->loop()->head() == innermost->head(), "same head"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2511 Loop* dl; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2512 for (dl = innermost; dl != NULL && dl != blk->loop(); dl = dl->parent()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2513 assert(dl == blk->loop(), "blk->loop() already in innermost list"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2514 #endif |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2515 blk->set_loop(innermost); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2516 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2517 innermost->def_locals()->add(blk->def_locals()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2518 Loop* l = innermost; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2519 Loop* p = l->parent(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2520 while (p && l->head() == blk) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2521 l->set_sibling(p->child()); // Put self on parents 'next child' |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2522 p->set_child(l); // Make self the first child of parent |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2523 p->def_locals()->add(l->def_locals()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2524 l = p; // Walk up the parent chain |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2525 p = l->parent(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2526 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2527 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2528 blk->set_loop(innermost); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2529 innermost->def_locals()->add(blk->def_locals()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2530 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2531 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2532 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2533 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2534 // ciTypeFlow::Loop::contains |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2535 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2536 // Returns true if lp is nested loop. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2537 bool ciTypeFlow::Loop::contains(ciTypeFlow::Loop* lp) const { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2538 assert(lp != NULL, ""); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2539 if (this == lp || head() == lp->head()) return true; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2540 int depth1 = depth(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2541 int depth2 = lp->depth(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2542 if (depth1 > depth2) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2543 return false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2544 while (depth1 < depth2) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2545 depth2--; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2546 lp = lp->parent(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2547 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2548 return this == lp; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2549 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2550 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2551 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2552 // ciTypeFlow::Loop::depth |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2553 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2554 // Loop depth |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2555 int ciTypeFlow::Loop::depth() const { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2556 int dp = 0; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2557 for (Loop* lp = this->parent(); lp != NULL; lp = lp->parent()) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2558 dp++; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2559 return dp; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2560 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2561 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2562 #ifndef PRODUCT |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2563 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2564 // ciTypeFlow::Loop::print |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2565 void ciTypeFlow::Loop::print(outputStream* st, int indent) const { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2566 for (int i = 0; i < indent; i++) st->print(" "); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2567 st->print("%d<-%d %s", |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2568 is_root() ? 0 : this->head()->pre_order(), |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2569 is_root() ? 0 : this->tail()->pre_order(), |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2570 is_irreducible()?" irr":""); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2571 st->print(" defs: "); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2572 def_locals()->print_on(st, _head->outer()->method()->max_locals()); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2573 st->cr(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2574 for (Loop* ch = child(); ch != NULL; ch = ch->sibling()) |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2575 ch->print(st, indent+2); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2576 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2577 #endif |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2578 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2579 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2580 // ciTypeFlow::df_flow_types |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2581 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2582 // 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:
0
diff
changeset
|
2583 void ciTypeFlow::df_flow_types(Block* start, |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2584 bool do_flow, |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2585 StateVector* temp_vector, |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2586 JsrSet* temp_set) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2587 int dft_len = 100; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2588 GrowableArray<Block*> stk(arena(), dft_len, 0, NULL); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2589 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2590 ciBlock* dummy = _methodBlocks->make_dummy_block(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2591 JsrSet* root_set = new JsrSet(NULL, 0); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2592 Block* root_head = new (arena()) Block(this, dummy, root_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2593 Block* root_tail = new (arena()) Block(this, dummy, root_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2594 root_head->set_pre_order(0); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2595 root_head->set_post_order(0); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2596 root_tail->set_pre_order(max_jint); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2597 root_tail->set_post_order(max_jint); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2598 set_loop_tree_root(new (arena()) Loop(root_head, root_tail)); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2599 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2600 stk.push(start); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2601 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2602 _next_pre_order = 0; // initialize pre_order counter |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2603 _rpo_list = NULL; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2604 int next_po = 0; // initialize post_order counter |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2605 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2606 // Compute RPO and the control flow graph |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2607 int size; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2608 while ((size = stk.length()) > 0) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2609 Block* blk = stk.top(); // Leave node on stack |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2610 if (!blk->is_visited()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2611 // forward arc in graph |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2612 assert (!blk->has_pre_order(), ""); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2613 blk->set_next_pre_order(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2614 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2615 if (_next_pre_order >= MaxNodeLimit / 2) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2616 // Too many basic blocks. Bail out. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2617 // This can happen when try/finally constructs are nested to depth N, |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2618 // and there is O(2**N) cloning of jsr bodies. See bug 4697245! |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2619 // "MaxNodeLimit / 2" is used because probably the parser will |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2620 // generate at least twice that many nodes and bail out. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2621 record_failure("too many basic blocks"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2622 return; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2623 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2624 if (do_flow) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2625 flow_block(blk, temp_vector, temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2626 if (failing()) return; // Watch for bailouts. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2627 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2628 } else if (!blk->is_post_visited()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2629 // cross or back arc |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2630 for (SuccIter iter(blk); !iter.done(); iter.next()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2631 Block* succ = iter.succ(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2632 if (!succ->is_visited()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2633 stk.push(succ); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2634 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2635 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2636 if (stk.length() == size) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2637 // There were no additional children, post visit node now |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2638 stk.pop(); // Remove node from stack |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2639 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2640 build_loop_tree(blk); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2641 blk->set_post_order(next_po++); // Assign post order |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2642 prepend_to_rpo_list(blk); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2643 assert(blk->is_post_visited(), ""); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2644 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2645 if (blk->is_loop_head() && !blk->is_on_work_list()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2646 // Assume loop heads need more data flow |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2647 add_to_work_list(blk); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2648 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2649 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2650 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2651 stk.pop(); // Remove post-visited node from stack |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2652 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2653 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2654 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2655 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2656 // ------------------------------------------------------------------ |
0 | 2657 // ciTypeFlow::flow_types |
2658 // | |
2659 // Perform the type flow analysis, creating and cloning Blocks as | |
2660 // necessary. | |
2661 void ciTypeFlow::flow_types() { | |
2662 ResourceMark rm; | |
2663 StateVector* temp_vector = new StateVector(this); | |
2664 JsrSet* temp_set = new JsrSet(NULL, 16); | |
2665 | |
2666 // Create the method entry block. | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2667 Block* start = block_at(start_bci(), temp_set); |
0 | 2668 |
2669 // Load the initial state into it. | |
2670 const StateVector* start_state = get_start_state(); | |
2671 if (failing()) return; | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2672 start->meet(start_state); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2673 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2674 // Depth first visit |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2675 df_flow_types(start, true /*do flow*/, temp_vector, temp_set); |
0 | 2676 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2677 if (failing()) return; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2678 assert(_rpo_list == start, "must be start"); |
0 | 2679 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2680 // Any loops found? |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2681 if (loop_tree_root()->child() != NULL && |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2682 env()->comp_level() >= CompLevel_full_optimization) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2683 // Loop optimizations are not performed on Tier1 compiles. |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2684 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2685 bool changed = clone_loop_heads(loop_tree_root(), temp_vector, temp_set); |
0 | 2686 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2687 // If some loop heads were cloned, recompute postorder and loop tree |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2688 if (changed) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2689 loop_tree_root()->set_child(NULL); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2690 for (Block* blk = _rpo_list; blk != NULL;) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2691 Block* next = blk->rpo_next(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2692 blk->df_init(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2693 blk = next; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2694 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2695 df_flow_types(start, false /*no flow*/, temp_vector, temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2696 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2697 } |
0 | 2698 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2699 if (CITraceTypeFlow) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2700 tty->print_cr("\nLoop tree"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2701 loop_tree_root()->print(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2702 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2703 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2704 // Continue flow analysis until fixed point reached |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2705 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2706 debug_only(int max_block = _next_pre_order;) |
0 | 2707 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2708 while (!work_list_empty()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2709 Block* blk = work_list_next(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2710 assert (blk->has_post_order(), "post order assigned above"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2711 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2712 flow_block(blk, temp_vector, temp_set); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2713 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2714 assert (max_block == _next_pre_order, "no new blocks"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2715 assert (!failing(), "no more bailouts"); |
0 | 2716 } |
2717 } | |
2718 | |
2719 // ------------------------------------------------------------------ | |
2720 // ciTypeFlow::map_blocks | |
2721 // | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2722 // Create the block map, which indexes blocks in reverse post-order. |
0 | 2723 void ciTypeFlow::map_blocks() { |
2724 assert(_block_map == NULL, "single initialization"); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2725 int block_ct = _next_pre_order; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2726 _block_map = NEW_ARENA_ARRAY(arena(), Block*, block_ct); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2727 assert(block_ct == block_count(), ""); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2728 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2729 Block* blk = _rpo_list; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2730 for (int m = 0; m < block_ct; m++) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2731 int rpo = blk->rpo(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2732 assert(rpo == m, "should be sequential"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2733 _block_map[rpo] = blk; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2734 blk = blk->rpo_next(); |
0 | 2735 } |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2736 assert(blk == NULL, "should be done"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2737 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2738 for (int j = 0; j < block_ct; j++) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2739 assert(_block_map[j] != NULL, "must not drop any blocks"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2740 Block* block = _block_map[j]; |
0 | 2741 // Remove dead blocks from successor lists: |
2742 for (int e = 0; e <= 1; e++) { | |
2743 GrowableArray<Block*>* l = e? block->exceptions(): block->successors(); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2744 for (int k = 0; k < l->length(); k++) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2745 Block* s = l->at(k); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2746 if (!s->has_post_order()) { |
0 | 2747 if (CITraceTypeFlow) { |
2748 tty->print("Removing dead %s successor of #%d: ", (e? "exceptional": "normal"), block->pre_order()); | |
2749 s->print_value_on(tty); | |
2750 tty->cr(); | |
2751 } | |
2752 l->remove(s); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2753 --k; |
0 | 2754 } |
2755 } | |
2756 } | |
2757 } | |
2758 } | |
2759 | |
2760 // ------------------------------------------------------------------ | |
2761 // ciTypeFlow::get_block_for | |
2762 // | |
2763 // Find a block with this ciBlock which has a compatible JsrSet. | |
2764 // If no such block exists, create it, unless the option is no_create. | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2765 // If the option is create_backedge_copy, always create a fresh backedge copy. |
0 | 2766 ciTypeFlow::Block* ciTypeFlow::get_block_for(int ciBlockIndex, ciTypeFlow::JsrSet* jsrs, CreateOption option) { |
2767 Arena* a = arena(); | |
2768 GrowableArray<Block*>* blocks = _idx_to_blocklist[ciBlockIndex]; | |
2769 if (blocks == NULL) { | |
2770 // Query only? | |
2771 if (option == no_create) return NULL; | |
2772 | |
2773 // Allocate the growable array. | |
2774 blocks = new (a) GrowableArray<Block*>(a, 4, 0, NULL); | |
2775 _idx_to_blocklist[ciBlockIndex] = blocks; | |
2776 } | |
2777 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2778 if (option != create_backedge_copy) { |
0 | 2779 int len = blocks->length(); |
2780 for (int i = 0; i < len; i++) { | |
2781 Block* block = blocks->at(i); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2782 if (!block->is_backedge_copy() && block->is_compatible_with(jsrs)) { |
0 | 2783 return block; |
2784 } | |
2785 } | |
2786 } | |
2787 | |
2788 // Query only? | |
2789 if (option == no_create) return NULL; | |
2790 | |
2791 // We did not find a compatible block. Create one. | |
2792 Block* new_block = new (a) Block(this, _methodBlocks->block(ciBlockIndex), jsrs); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2793 if (option == create_backedge_copy) new_block->set_backedge_copy(true); |
0 | 2794 blocks->append(new_block); |
2795 return new_block; | |
2796 } | |
2797 | |
2798 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2799 // ciTypeFlow::backedge_copy_count |
0 | 2800 // |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2801 int ciTypeFlow::backedge_copy_count(int ciBlockIndex, ciTypeFlow::JsrSet* jsrs) const { |
0 | 2802 GrowableArray<Block*>* blocks = _idx_to_blocklist[ciBlockIndex]; |
2803 | |
2804 if (blocks == NULL) { | |
2805 return 0; | |
2806 } | |
2807 | |
2808 int count = 0; | |
2809 int len = blocks->length(); | |
2810 for (int i = 0; i < len; i++) { | |
2811 Block* block = blocks->at(i); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2812 if (block->is_backedge_copy() && block->is_compatible_with(jsrs)) { |
0 | 2813 count++; |
2814 } | |
2815 } | |
2816 | |
2817 return count; | |
2818 } | |
2819 | |
2820 // ------------------------------------------------------------------ | |
2821 // ciTypeFlow::do_flow | |
2822 // | |
2823 // Perform type inference flow analysis. | |
2824 void ciTypeFlow::do_flow() { | |
2825 if (CITraceTypeFlow) { | |
2826 tty->print_cr("\nPerforming flow analysis on method"); | |
2827 method()->print(); | |
2828 if (is_osr_flow()) tty->print(" at OSR bci %d", start_bci()); | |
2829 tty->cr(); | |
2830 method()->print_codes(); | |
2831 } | |
2832 if (CITraceTypeFlow) { | |
2833 tty->print_cr("Initial CI Blocks"); | |
2834 print_on(tty); | |
2835 } | |
2836 flow_types(); | |
2837 // Watch for bailouts. | |
2838 if (failing()) { | |
2839 return; | |
2840 } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2841 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2842 map_blocks(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2843 |
0 | 2844 if (CIPrintTypeFlow || CITraceTypeFlow) { |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2845 rpo_print_on(tty); |
0 | 2846 } |
2847 } | |
2848 | |
2849 // ------------------------------------------------------------------ | |
2850 // ciTypeFlow::record_failure() | |
2851 // The ciTypeFlow object keeps track of failure reasons separately from the ciEnv. | |
2852 // This is required because there is not a 1-1 relation between the ciEnv and | |
2853 // the TypeFlow passes within a compilation task. For example, if the compiler | |
2854 // is considering inlining a method, it will request a TypeFlow. If that fails, | |
2855 // the compilation as a whole may continue without the inlining. Some TypeFlow | |
2856 // requests are not optional; if they fail the requestor is responsible for | |
2857 // copying the failure reason up to the ciEnv. (See Parse::Parse.) | |
2858 void ciTypeFlow::record_failure(const char* reason) { | |
2859 if (env()->log() != NULL) { | |
2860 env()->log()->elem("failure reason='%s' phase='typeflow'", reason); | |
2861 } | |
2862 if (_failure_reason == NULL) { | |
2863 // Record the first failure reason. | |
2864 _failure_reason = reason; | |
2865 } | |
2866 } | |
2867 | |
2868 #ifndef PRODUCT | |
2869 // ------------------------------------------------------------------ | |
2870 // ciTypeFlow::print_on | |
2871 void ciTypeFlow::print_on(outputStream* st) const { | |
2872 // Walk through CI blocks | |
2873 st->print_cr("********************************************************"); | |
2874 st->print ("TypeFlow for "); | |
2875 method()->name()->print_symbol_on(st); | |
2876 int limit_bci = code_size(); | |
2877 st->print_cr(" %d bytes", limit_bci); | |
2878 ciMethodBlocks *mblks = _methodBlocks; | |
2879 ciBlock* current = NULL; | |
2880 for (int bci = 0; bci < limit_bci; bci++) { | |
2881 ciBlock* blk = mblks->block_containing(bci); | |
2882 if (blk != NULL && blk != current) { | |
2883 current = blk; | |
2884 current->print_on(st); | |
2885 | |
2886 GrowableArray<Block*>* blocks = _idx_to_blocklist[blk->index()]; | |
2887 int num_blocks = (blocks == NULL) ? 0 : blocks->length(); | |
2888 | |
2889 if (num_blocks == 0) { | |
2890 st->print_cr(" No Blocks"); | |
2891 } else { | |
2892 for (int i = 0; i < num_blocks; i++) { | |
2893 Block* block = blocks->at(i); | |
2894 block->print_on(st); | |
2895 } | |
2896 } | |
2897 st->print_cr("--------------------------------------------------------"); | |
2898 st->cr(); | |
2899 } | |
2900 } | |
2901 st->print_cr("********************************************************"); | |
2902 st->cr(); | |
2903 } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2904 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2905 void ciTypeFlow::rpo_print_on(outputStream* st) const { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2906 st->print_cr("********************************************************"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2907 st->print ("TypeFlow for "); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2908 method()->name()->print_symbol_on(st); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2909 int limit_bci = code_size(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2910 st->print_cr(" %d bytes", limit_bci); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2911 for (Block* blk = _rpo_list; blk != NULL; blk = blk->rpo_next()) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2912 blk->print_on(st); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2913 st->print_cr("--------------------------------------------------------"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2914 st->cr(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2915 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2916 st->print_cr("********************************************************"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2917 st->cr(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2918 } |
0 | 2919 #endif |