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