Mercurial > hg > truffle
annotate src/share/vm/ci/ciTypeFlow.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 55fb97c4c58d |
children | 4ca6dc0799b6 9dc314de223d |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
8721
diff
changeset
|
2 * Copyright (c) 2000, 2013, 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, | |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
646 bool has_receiver) { |
0 | 647 bool will_link; |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
648 ciSignature* declared_signature = NULL; |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
649 ciMethod* callee = str->get_method(will_link, &declared_signature); |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
650 assert(declared_signature != NULL, "cannot be null"); |
0 | 651 if (!will_link) { |
652 // We weren't able to find the method. | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
653 if (str->cur_bc() == Bytecodes::_invokedynamic) { |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
654 trap(str, NULL, |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
655 Deoptimization::make_trap_request |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
656 (Deoptimization::Reason_uninitialized, |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
657 Deoptimization::Action_reinterpret)); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
658 } else { |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4777
diff
changeset
|
659 ciKlass* unloaded_holder = callee->holder(); |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
660 trap(str, unloaded_holder, str->get_method_holder_index()); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
661 } |
0 | 662 } else { |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
663 // We are using the declared signature here because it might be |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
664 // different from the callee signature (Cf. invokedynamic and |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
665 // invokehandle). |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
666 ciSignatureStream sigstr(declared_signature); |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
667 const int arg_size = declared_signature->size(); |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
668 const int stack_base = stack_size() - arg_size; |
0 | 669 int i = 0; |
670 for( ; !sigstr.at_return_type(); sigstr.next()) { | |
671 ciType* type = sigstr.type(); | |
672 ciType* stack_type = type_at(stack(stack_base + i++)); | |
673 // Do I want to check this type? | |
674 // assert(stack_type->is_subtype_of(type), "bad type for field value"); | |
675 if (type->is_two_word()) { | |
676 ciType* stack_type2 = type_at(stack(stack_base + i++)); | |
677 assert(stack_type2->equals(half_type(type)), "must be 2nd half"); | |
678 } | |
679 } | |
680 assert(arg_size == i, "must match"); | |
681 for (int j = 0; j < arg_size; j++) { | |
682 pop(); | |
683 } | |
684 if (has_receiver) { | |
685 // Check this? | |
686 pop_object(); | |
687 } | |
688 assert(!sigstr.is_done(), "must have return type"); | |
689 ciType* return_type = sigstr.type(); | |
690 if (!return_type->is_void()) { | |
691 if (!return_type->is_loaded()) { | |
692 // As in do_getstatic(), generally speaking, we need the return type to | |
693 // be loaded if we are to do anything interesting with its value. | |
694 // We used to do this: trap(str, str->get_method_signature_index()); | |
695 // | |
696 // We do not trap here since execution can get past this invoke if | |
697 // the return value is null. As long as the value is null, the class | |
698 // does not need to be loaded! The compiler must assume that | |
699 // the value of the unloaded class reference is null; if the code | |
700 // ever sees a non-null value, loading has occurred. | |
701 // | |
702 // See do_getstatic() for similar explanation, as well as bug 4684993. | |
703 do_null_assert(return_type->as_klass()); | |
704 } else { | |
705 push_translate(return_type); | |
706 } | |
707 } | |
708 } | |
709 } | |
710 | |
711 // ------------------------------------------------------------------ | |
712 // ciTypeFlow::StateVector::do_jsr | |
713 void ciTypeFlow::StateVector::do_jsr(ciBytecodeStream* str) { | |
714 push(ciReturnAddress::make(str->next_bci())); | |
715 } | |
716 | |
717 // ------------------------------------------------------------------ | |
718 // ciTypeFlow::StateVector::do_ldc | |
719 void ciTypeFlow::StateVector::do_ldc(ciBytecodeStream* str) { | |
720 ciConstant con = str->get_constant(); | |
721 BasicType basic_type = con.basic_type(); | |
722 if (basic_type == T_ILLEGAL) { | |
723 // OutOfMemoryError in the CI while loading constant | |
724 push_null(); | |
725 outer()->record_failure("ldc did not link"); | |
726 return; | |
727 } | |
728 if (basic_type == T_OBJECT || basic_type == T_ARRAY) { | |
729 ciObject* obj = con.as_object(); | |
730 if (obj->is_null_object()) { | |
731 push_null(); | |
732 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
733 assert(obj->is_instance(), "must be java_mirror of klass"); |
0 | 734 push_object(obj->klass()); |
735 } | |
736 } else { | |
737 push_translate(ciType::make(basic_type)); | |
738 } | |
739 } | |
740 | |
741 // ------------------------------------------------------------------ | |
742 // ciTypeFlow::StateVector::do_multianewarray | |
743 void ciTypeFlow::StateVector::do_multianewarray(ciBytecodeStream* str) { | |
744 int dimensions = str->get_dimensions(); | |
745 bool will_link; | |
746 ciArrayKlass* array_klass = str->get_klass(will_link)->as_array_klass(); | |
747 if (!will_link) { | |
748 trap(str, array_klass, str->get_klass_index()); | |
749 } else { | |
750 for (int i = 0; i < dimensions; i++) { | |
751 pop_int(); | |
752 } | |
753 push_object(array_klass); | |
754 } | |
755 } | |
756 | |
757 // ------------------------------------------------------------------ | |
758 // ciTypeFlow::StateVector::do_new | |
759 void ciTypeFlow::StateVector::do_new(ciBytecodeStream* str) { | |
760 bool will_link; | |
761 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
|
762 if (!will_link || str->is_unresolved_klass()) { |
0 | 763 trap(str, klass, str->get_klass_index()); |
764 } else { | |
765 push_object(klass); | |
766 } | |
767 } | |
768 | |
769 // ------------------------------------------------------------------ | |
770 // ciTypeFlow::StateVector::do_newarray | |
771 void ciTypeFlow::StateVector::do_newarray(ciBytecodeStream* str) { | |
772 pop_int(); | |
773 ciKlass* klass = ciTypeArrayKlass::make((BasicType)str->get_index()); | |
774 push_object(klass); | |
775 } | |
776 | |
777 // ------------------------------------------------------------------ | |
778 // ciTypeFlow::StateVector::do_putfield | |
779 void ciTypeFlow::StateVector::do_putfield(ciBytecodeStream* str) { | |
780 do_putstatic(str); | |
781 if (_trap_bci != -1) return; // unloaded field holder, etc. | |
782 // could add assert here for type of object. | |
783 pop_object(); | |
784 } | |
785 | |
786 // ------------------------------------------------------------------ | |
787 // ciTypeFlow::StateVector::do_putstatic | |
788 void ciTypeFlow::StateVector::do_putstatic(ciBytecodeStream* str) { | |
789 bool will_link; | |
790 ciField* field = str->get_field(will_link); | |
791 if (!will_link) { | |
792 trap(str, field->holder(), str->get_field_holder_index()); | |
793 } else { | |
794 ciType* field_type = field->type(); | |
795 ciType* type = pop_value(); | |
796 // Do I want to check this type? | |
797 // assert(type->is_subtype_of(field_type), "bad type for field value"); | |
798 if (field_type->is_two_word()) { | |
799 ciType* type2 = pop_value(); | |
800 assert(type2->is_two_word(), "must be 2nd half"); | |
801 assert(type == half_type(type2), "must be 2nd half"); | |
802 } | |
803 } | |
804 } | |
805 | |
806 // ------------------------------------------------------------------ | |
807 // ciTypeFlow::StateVector::do_ret | |
808 void ciTypeFlow::StateVector::do_ret(ciBytecodeStream* str) { | |
809 Cell index = local(str->get_index()); | |
810 | |
811 ciType* address = type_at(index); | |
812 assert(address->is_return_address(), "bad return address"); | |
813 set_type_at(index, bottom_type()); | |
814 } | |
815 | |
816 // ------------------------------------------------------------------ | |
817 // ciTypeFlow::StateVector::trap | |
818 // | |
819 // Stop interpretation of this path with a trap. | |
820 void ciTypeFlow::StateVector::trap(ciBytecodeStream* str, ciKlass* klass, int index) { | |
821 _trap_bci = str->cur_bci(); | |
822 _trap_index = index; | |
823 | |
824 // Log information about this trap: | |
825 CompileLog* log = outer()->env()->log(); | |
826 if (log != NULL) { | |
827 int mid = log->identify(outer()->method()); | |
828 int kid = (klass == NULL)? -1: log->identify(klass); | |
829 log->begin_elem("uncommon_trap method='%d' bci='%d'", mid, str->cur_bci()); | |
830 char buf[100]; | |
831 log->print(" %s", Deoptimization::format_trap_request(buf, sizeof(buf), | |
832 index)); | |
833 if (kid >= 0) | |
834 log->print(" klass='%d'", kid); | |
835 log->end_elem(); | |
836 } | |
837 } | |
838 | |
839 // ------------------------------------------------------------------ | |
840 // ciTypeFlow::StateVector::do_null_assert | |
841 // Corresponds to graphKit::do_null_assert. | |
842 void ciTypeFlow::StateVector::do_null_assert(ciKlass* unloaded_klass) { | |
843 if (unloaded_klass->is_loaded()) { | |
844 // We failed to link, but we can still compute with this class, | |
845 // since it is loaded somewhere. The compiler will uncommon_trap | |
846 // if the object is not null, but the typeflow pass can not assume | |
847 // that the object will be null, otherwise it may incorrectly tell | |
848 // the parser that an object is known to be null. 4761344, 4807707 | |
849 push_object(unloaded_klass); | |
850 } else { | |
851 // The class is not loaded anywhere. It is safe to model the | |
852 // null in the typestates, because we can compile in a null check | |
853 // which will deoptimize us if someone manages to load the | |
854 // class later. | |
855 push_null(); | |
856 } | |
857 } | |
858 | |
859 | |
860 // ------------------------------------------------------------------ | |
861 // ciTypeFlow::StateVector::apply_one_bytecode | |
862 // | |
863 // Apply the effect of one bytecode to this StateVector | |
864 bool ciTypeFlow::StateVector::apply_one_bytecode(ciBytecodeStream* str) { | |
865 _trap_bci = -1; | |
866 _trap_index = 0; | |
867 | |
868 if (CITraceTypeFlow) { | |
869 tty->print_cr(">> Interpreting bytecode %d:%s", str->cur_bci(), | |
870 Bytecodes::name(str->cur_bc())); | |
871 } | |
872 | |
873 switch(str->cur_bc()) { | |
874 case Bytecodes::_aaload: do_aaload(str); break; | |
875 | |
876 case Bytecodes::_aastore: | |
877 { | |
878 pop_object(); | |
879 pop_int(); | |
880 pop_objArray(); | |
881 break; | |
882 } | |
883 case Bytecodes::_aconst_null: | |
884 { | |
885 push_null(); | |
886 break; | |
887 } | |
888 case Bytecodes::_aload: load_local_object(str->get_index()); break; | |
889 case Bytecodes::_aload_0: load_local_object(0); break; | |
890 case Bytecodes::_aload_1: load_local_object(1); break; | |
891 case Bytecodes::_aload_2: load_local_object(2); break; | |
892 case Bytecodes::_aload_3: load_local_object(3); break; | |
893 | |
894 case Bytecodes::_anewarray: | |
895 { | |
896 pop_int(); | |
897 bool will_link; | |
898 ciKlass* element_klass = str->get_klass(will_link); | |
899 if (!will_link) { | |
900 trap(str, element_klass, str->get_klass_index()); | |
901 } else { | |
902 push_object(ciObjArrayKlass::make(element_klass)); | |
903 } | |
904 break; | |
905 } | |
906 case Bytecodes::_areturn: | |
907 case Bytecodes::_ifnonnull: | |
908 case Bytecodes::_ifnull: | |
909 { | |
910 pop_object(); | |
911 break; | |
912 } | |
913 case Bytecodes::_monitorenter: | |
914 { | |
915 pop_object(); | |
916 set_monitor_count(monitor_count() + 1); | |
917 break; | |
918 } | |
919 case Bytecodes::_monitorexit: | |
920 { | |
921 pop_object(); | |
922 assert(monitor_count() > 0, "must be a monitor to exit from"); | |
923 set_monitor_count(monitor_count() - 1); | |
924 break; | |
925 } | |
926 case Bytecodes::_arraylength: | |
927 { | |
928 pop_array(); | |
929 push_int(); | |
930 break; | |
931 } | |
932 case Bytecodes::_astore: store_local_object(str->get_index()); break; | |
933 case Bytecodes::_astore_0: store_local_object(0); break; | |
934 case Bytecodes::_astore_1: store_local_object(1); break; | |
935 case Bytecodes::_astore_2: store_local_object(2); break; | |
936 case Bytecodes::_astore_3: store_local_object(3); break; | |
937 | |
938 case Bytecodes::_athrow: | |
939 { | |
940 NEEDS_CLEANUP; | |
941 pop_object(); | |
942 break; | |
943 } | |
944 case Bytecodes::_baload: | |
945 case Bytecodes::_caload: | |
946 case Bytecodes::_iaload: | |
947 case Bytecodes::_saload: | |
948 { | |
949 pop_int(); | |
950 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
951 // Put assert here for right type? | |
952 push_int(); | |
953 break; | |
954 } | |
955 case Bytecodes::_bastore: | |
956 case Bytecodes::_castore: | |
957 case Bytecodes::_iastore: | |
958 case Bytecodes::_sastore: | |
959 { | |
960 pop_int(); | |
961 pop_int(); | |
962 pop_typeArray(); | |
963 // assert here? | |
964 break; | |
965 } | |
966 case Bytecodes::_bipush: | |
967 case Bytecodes::_iconst_m1: | |
968 case Bytecodes::_iconst_0: | |
969 case Bytecodes::_iconst_1: | |
970 case Bytecodes::_iconst_2: | |
971 case Bytecodes::_iconst_3: | |
972 case Bytecodes::_iconst_4: | |
973 case Bytecodes::_iconst_5: | |
974 case Bytecodes::_sipush: | |
975 { | |
976 push_int(); | |
977 break; | |
978 } | |
979 case Bytecodes::_checkcast: do_checkcast(str); break; | |
980 | |
981 case Bytecodes::_d2f: | |
982 { | |
983 pop_double(); | |
984 push_float(); | |
985 break; | |
986 } | |
987 case Bytecodes::_d2i: | |
988 { | |
989 pop_double(); | |
990 push_int(); | |
991 break; | |
992 } | |
993 case Bytecodes::_d2l: | |
994 { | |
995 pop_double(); | |
996 push_long(); | |
997 break; | |
998 } | |
999 case Bytecodes::_dadd: | |
1000 case Bytecodes::_ddiv: | |
1001 case Bytecodes::_dmul: | |
1002 case Bytecodes::_drem: | |
1003 case Bytecodes::_dsub: | |
1004 { | |
1005 pop_double(); | |
1006 pop_double(); | |
1007 push_double(); | |
1008 break; | |
1009 } | |
1010 case Bytecodes::_daload: | |
1011 { | |
1012 pop_int(); | |
1013 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
1014 // Put assert here for right type? | |
1015 push_double(); | |
1016 break; | |
1017 } | |
1018 case Bytecodes::_dastore: | |
1019 { | |
1020 pop_double(); | |
1021 pop_int(); | |
1022 pop_typeArray(); | |
1023 // assert here? | |
1024 break; | |
1025 } | |
1026 case Bytecodes::_dcmpg: | |
1027 case Bytecodes::_dcmpl: | |
1028 { | |
1029 pop_double(); | |
1030 pop_double(); | |
1031 push_int(); | |
1032 break; | |
1033 } | |
1034 case Bytecodes::_dconst_0: | |
1035 case Bytecodes::_dconst_1: | |
1036 { | |
1037 push_double(); | |
1038 break; | |
1039 } | |
1040 case Bytecodes::_dload: load_local_double(str->get_index()); break; | |
1041 case Bytecodes::_dload_0: load_local_double(0); break; | |
1042 case Bytecodes::_dload_1: load_local_double(1); break; | |
1043 case Bytecodes::_dload_2: load_local_double(2); break; | |
1044 case Bytecodes::_dload_3: load_local_double(3); break; | |
1045 | |
1046 case Bytecodes::_dneg: | |
1047 { | |
1048 pop_double(); | |
1049 push_double(); | |
1050 break; | |
1051 } | |
1052 case Bytecodes::_dreturn: | |
1053 { | |
1054 pop_double(); | |
1055 break; | |
1056 } | |
1057 case Bytecodes::_dstore: store_local_double(str->get_index()); break; | |
1058 case Bytecodes::_dstore_0: store_local_double(0); break; | |
1059 case Bytecodes::_dstore_1: store_local_double(1); break; | |
1060 case Bytecodes::_dstore_2: store_local_double(2); break; | |
1061 case Bytecodes::_dstore_3: store_local_double(3); break; | |
1062 | |
1063 case Bytecodes::_dup: | |
1064 { | |
1065 push(type_at_tos()); | |
1066 break; | |
1067 } | |
1068 case Bytecodes::_dup_x1: | |
1069 { | |
1070 ciType* value1 = pop_value(); | |
1071 ciType* value2 = pop_value(); | |
1072 push(value1); | |
1073 push(value2); | |
1074 push(value1); | |
1075 break; | |
1076 } | |
1077 case Bytecodes::_dup_x2: | |
1078 { | |
1079 ciType* value1 = pop_value(); | |
1080 ciType* value2 = pop_value(); | |
1081 ciType* value3 = pop_value(); | |
1082 push(value1); | |
1083 push(value3); | |
1084 push(value2); | |
1085 push(value1); | |
1086 break; | |
1087 } | |
1088 case Bytecodes::_dup2: | |
1089 { | |
1090 ciType* value1 = pop_value(); | |
1091 ciType* value2 = pop_value(); | |
1092 push(value2); | |
1093 push(value1); | |
1094 push(value2); | |
1095 push(value1); | |
1096 break; | |
1097 } | |
1098 case Bytecodes::_dup2_x1: | |
1099 { | |
1100 ciType* value1 = pop_value(); | |
1101 ciType* value2 = pop_value(); | |
1102 ciType* value3 = pop_value(); | |
1103 push(value2); | |
1104 push(value1); | |
1105 push(value3); | |
1106 push(value2); | |
1107 push(value1); | |
1108 break; | |
1109 } | |
1110 case Bytecodes::_dup2_x2: | |
1111 { | |
1112 ciType* value1 = pop_value(); | |
1113 ciType* value2 = pop_value(); | |
1114 ciType* value3 = pop_value(); | |
1115 ciType* value4 = pop_value(); | |
1116 push(value2); | |
1117 push(value1); | |
1118 push(value4); | |
1119 push(value3); | |
1120 push(value2); | |
1121 push(value1); | |
1122 break; | |
1123 } | |
1124 case Bytecodes::_f2d: | |
1125 { | |
1126 pop_float(); | |
1127 push_double(); | |
1128 break; | |
1129 } | |
1130 case Bytecodes::_f2i: | |
1131 { | |
1132 pop_float(); | |
1133 push_int(); | |
1134 break; | |
1135 } | |
1136 case Bytecodes::_f2l: | |
1137 { | |
1138 pop_float(); | |
1139 push_long(); | |
1140 break; | |
1141 } | |
1142 case Bytecodes::_fadd: | |
1143 case Bytecodes::_fdiv: | |
1144 case Bytecodes::_fmul: | |
1145 case Bytecodes::_frem: | |
1146 case Bytecodes::_fsub: | |
1147 { | |
1148 pop_float(); | |
1149 pop_float(); | |
1150 push_float(); | |
1151 break; | |
1152 } | |
1153 case Bytecodes::_faload: | |
1154 { | |
1155 pop_int(); | |
1156 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
1157 // Put assert here. | |
1158 push_float(); | |
1159 break; | |
1160 } | |
1161 case Bytecodes::_fastore: | |
1162 { | |
1163 pop_float(); | |
1164 pop_int(); | |
1165 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
1166 // Put assert here. | |
1167 break; | |
1168 } | |
1169 case Bytecodes::_fcmpg: | |
1170 case Bytecodes::_fcmpl: | |
1171 { | |
1172 pop_float(); | |
1173 pop_float(); | |
1174 push_int(); | |
1175 break; | |
1176 } | |
1177 case Bytecodes::_fconst_0: | |
1178 case Bytecodes::_fconst_1: | |
1179 case Bytecodes::_fconst_2: | |
1180 { | |
1181 push_float(); | |
1182 break; | |
1183 } | |
1184 case Bytecodes::_fload: load_local_float(str->get_index()); break; | |
1185 case Bytecodes::_fload_0: load_local_float(0); break; | |
1186 case Bytecodes::_fload_1: load_local_float(1); break; | |
1187 case Bytecodes::_fload_2: load_local_float(2); break; | |
1188 case Bytecodes::_fload_3: load_local_float(3); break; | |
1189 | |
1190 case Bytecodes::_fneg: | |
1191 { | |
1192 pop_float(); | |
1193 push_float(); | |
1194 break; | |
1195 } | |
1196 case Bytecodes::_freturn: | |
1197 { | |
1198 pop_float(); | |
1199 break; | |
1200 } | |
1201 case Bytecodes::_fstore: store_local_float(str->get_index()); break; | |
1202 case Bytecodes::_fstore_0: store_local_float(0); break; | |
1203 case Bytecodes::_fstore_1: store_local_float(1); break; | |
1204 case Bytecodes::_fstore_2: store_local_float(2); break; | |
1205 case Bytecodes::_fstore_3: store_local_float(3); break; | |
1206 | |
1207 case Bytecodes::_getfield: do_getfield(str); break; | |
1208 case Bytecodes::_getstatic: do_getstatic(str); break; | |
1209 | |
1210 case Bytecodes::_goto: | |
1211 case Bytecodes::_goto_w: | |
1212 case Bytecodes::_nop: | |
1213 case Bytecodes::_return: | |
1214 { | |
1215 // do nothing. | |
1216 break; | |
1217 } | |
1218 case Bytecodes::_i2b: | |
1219 case Bytecodes::_i2c: | |
1220 case Bytecodes::_i2s: | |
1221 case Bytecodes::_ineg: | |
1222 { | |
1223 pop_int(); | |
1224 push_int(); | |
1225 break; | |
1226 } | |
1227 case Bytecodes::_i2d: | |
1228 { | |
1229 pop_int(); | |
1230 push_double(); | |
1231 break; | |
1232 } | |
1233 case Bytecodes::_i2f: | |
1234 { | |
1235 pop_int(); | |
1236 push_float(); | |
1237 break; | |
1238 } | |
1239 case Bytecodes::_i2l: | |
1240 { | |
1241 pop_int(); | |
1242 push_long(); | |
1243 break; | |
1244 } | |
1245 case Bytecodes::_iadd: | |
1246 case Bytecodes::_iand: | |
1247 case Bytecodes::_idiv: | |
1248 case Bytecodes::_imul: | |
1249 case Bytecodes::_ior: | |
1250 case Bytecodes::_irem: | |
1251 case Bytecodes::_ishl: | |
1252 case Bytecodes::_ishr: | |
1253 case Bytecodes::_isub: | |
1254 case Bytecodes::_iushr: | |
1255 case Bytecodes::_ixor: | |
1256 { | |
1257 pop_int(); | |
1258 pop_int(); | |
1259 push_int(); | |
1260 break; | |
1261 } | |
1262 case Bytecodes::_if_acmpeq: | |
1263 case Bytecodes::_if_acmpne: | |
1264 { | |
1265 pop_object(); | |
1266 pop_object(); | |
1267 break; | |
1268 } | |
1269 case Bytecodes::_if_icmpeq: | |
1270 case Bytecodes::_if_icmpge: | |
1271 case Bytecodes::_if_icmpgt: | |
1272 case Bytecodes::_if_icmple: | |
1273 case Bytecodes::_if_icmplt: | |
1274 case Bytecodes::_if_icmpne: | |
1275 { | |
1276 pop_int(); | |
1277 pop_int(); | |
1278 break; | |
1279 } | |
1280 case Bytecodes::_ifeq: | |
1281 case Bytecodes::_ifle: | |
1282 case Bytecodes::_iflt: | |
1283 case Bytecodes::_ifge: | |
1284 case Bytecodes::_ifgt: | |
1285 case Bytecodes::_ifne: | |
1286 case Bytecodes::_ireturn: | |
1287 case Bytecodes::_lookupswitch: | |
1288 case Bytecodes::_tableswitch: | |
1289 { | |
1290 pop_int(); | |
1291 break; | |
1292 } | |
1293 case Bytecodes::_iinc: | |
1294 { | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1295 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
|
1296 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
|
1297 store_to_local(lnum); |
0 | 1298 break; |
1299 } | |
1300 case Bytecodes::_iload: load_local_int(str->get_index()); break; | |
1301 case Bytecodes::_iload_0: load_local_int(0); break; | |
1302 case Bytecodes::_iload_1: load_local_int(1); break; | |
1303 case Bytecodes::_iload_2: load_local_int(2); break; | |
1304 case Bytecodes::_iload_3: load_local_int(3); break; | |
1305 | |
1306 case Bytecodes::_instanceof: | |
1307 { | |
1308 // Check for uncommon trap: | |
1309 do_checkcast(str); | |
1310 pop_object(); | |
1311 push_int(); | |
1312 break; | |
1313 } | |
1314 case Bytecodes::_invokeinterface: do_invoke(str, true); break; | |
1315 case Bytecodes::_invokespecial: do_invoke(str, true); break; | |
1316 case Bytecodes::_invokestatic: do_invoke(str, false); break; | |
1317 case Bytecodes::_invokevirtual: do_invoke(str, true); break; | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
991
diff
changeset
|
1318 case Bytecodes::_invokedynamic: do_invoke(str, false); break; |
0 | 1319 |
1320 case Bytecodes::_istore: store_local_int(str->get_index()); break; | |
1321 case Bytecodes::_istore_0: store_local_int(0); break; | |
1322 case Bytecodes::_istore_1: store_local_int(1); break; | |
1323 case Bytecodes::_istore_2: store_local_int(2); break; | |
1324 case Bytecodes::_istore_3: store_local_int(3); break; | |
1325 | |
1326 case Bytecodes::_jsr: | |
1327 case Bytecodes::_jsr_w: do_jsr(str); break; | |
1328 | |
1329 case Bytecodes::_l2d: | |
1330 { | |
1331 pop_long(); | |
1332 push_double(); | |
1333 break; | |
1334 } | |
1335 case Bytecodes::_l2f: | |
1336 { | |
1337 pop_long(); | |
1338 push_float(); | |
1339 break; | |
1340 } | |
1341 case Bytecodes::_l2i: | |
1342 { | |
1343 pop_long(); | |
1344 push_int(); | |
1345 break; | |
1346 } | |
1347 case Bytecodes::_ladd: | |
1348 case Bytecodes::_land: | |
1349 case Bytecodes::_ldiv: | |
1350 case Bytecodes::_lmul: | |
1351 case Bytecodes::_lor: | |
1352 case Bytecodes::_lrem: | |
1353 case Bytecodes::_lsub: | |
1354 case Bytecodes::_lxor: | |
1355 { | |
1356 pop_long(); | |
1357 pop_long(); | |
1358 push_long(); | |
1359 break; | |
1360 } | |
1361 case Bytecodes::_laload: | |
1362 { | |
1363 pop_int(); | |
1364 ciTypeArrayKlass* array_klass = pop_typeArray(); | |
1365 // Put assert here for right type? | |
1366 push_long(); | |
1367 break; | |
1368 } | |
1369 case Bytecodes::_lastore: | |
1370 { | |
1371 pop_long(); | |
1372 pop_int(); | |
1373 pop_typeArray(); | |
1374 // assert here? | |
1375 break; | |
1376 } | |
1377 case Bytecodes::_lcmp: | |
1378 { | |
1379 pop_long(); | |
1380 pop_long(); | |
1381 push_int(); | |
1382 break; | |
1383 } | |
1384 case Bytecodes::_lconst_0: | |
1385 case Bytecodes::_lconst_1: | |
1386 { | |
1387 push_long(); | |
1388 break; | |
1389 } | |
1390 case Bytecodes::_ldc: | |
1391 case Bytecodes::_ldc_w: | |
1392 case Bytecodes::_ldc2_w: | |
1393 { | |
1394 do_ldc(str); | |
1395 break; | |
1396 } | |
1397 | |
1398 case Bytecodes::_lload: load_local_long(str->get_index()); break; | |
1399 case Bytecodes::_lload_0: load_local_long(0); break; | |
1400 case Bytecodes::_lload_1: load_local_long(1); break; | |
1401 case Bytecodes::_lload_2: load_local_long(2); break; | |
1402 case Bytecodes::_lload_3: load_local_long(3); break; | |
1403 | |
1404 case Bytecodes::_lneg: | |
1405 { | |
1406 pop_long(); | |
1407 push_long(); | |
1408 break; | |
1409 } | |
1410 case Bytecodes::_lreturn: | |
1411 { | |
1412 pop_long(); | |
1413 break; | |
1414 } | |
1415 case Bytecodes::_lshl: | |
1416 case Bytecodes::_lshr: | |
1417 case Bytecodes::_lushr: | |
1418 { | |
1419 pop_int(); | |
1420 pop_long(); | |
1421 push_long(); | |
1422 break; | |
1423 } | |
1424 case Bytecodes::_lstore: store_local_long(str->get_index()); break; | |
1425 case Bytecodes::_lstore_0: store_local_long(0); break; | |
1426 case Bytecodes::_lstore_1: store_local_long(1); break; | |
1427 case Bytecodes::_lstore_2: store_local_long(2); break; | |
1428 case Bytecodes::_lstore_3: store_local_long(3); break; | |
1429 | |
1430 case Bytecodes::_multianewarray: do_multianewarray(str); break; | |
1431 | |
1432 case Bytecodes::_new: do_new(str); break; | |
1433 | |
1434 case Bytecodes::_newarray: do_newarray(str); break; | |
1435 | |
1436 case Bytecodes::_pop: | |
1437 { | |
1438 pop(); | |
1439 break; | |
1440 } | |
1441 case Bytecodes::_pop2: | |
1442 { | |
1443 pop(); | |
1444 pop(); | |
1445 break; | |
1446 } | |
1447 | |
1448 case Bytecodes::_putfield: do_putfield(str); break; | |
1449 case Bytecodes::_putstatic: do_putstatic(str); break; | |
1450 | |
1451 case Bytecodes::_ret: do_ret(str); break; | |
1452 | |
1453 case Bytecodes::_swap: | |
1454 { | |
1455 ciType* value1 = pop_value(); | |
1456 ciType* value2 = pop_value(); | |
1457 push(value1); | |
1458 push(value2); | |
1459 break; | |
1460 } | |
1461 case Bytecodes::_wide: | |
1462 default: | |
1463 { | |
1464 // The iterator should skip this. | |
1465 ShouldNotReachHere(); | |
1466 break; | |
1467 } | |
1468 } | |
1469 | |
1470 if (CITraceTypeFlow) { | |
1471 print_on(tty); | |
1472 } | |
1473 | |
1474 return (_trap_bci != -1); | |
1475 } | |
1476 | |
1477 #ifndef PRODUCT | |
1478 // ------------------------------------------------------------------ | |
1479 // ciTypeFlow::StateVector::print_cell_on | |
1480 void ciTypeFlow::StateVector::print_cell_on(outputStream* st, Cell c) const { | |
1481 ciType* type = type_at(c); | |
1482 if (type == top_type()) { | |
1483 st->print("top"); | |
1484 } else if (type == bottom_type()) { | |
1485 st->print("bottom"); | |
1486 } else if (type == null_type()) { | |
1487 st->print("null"); | |
1488 } else if (type == long2_type()) { | |
1489 st->print("long2"); | |
1490 } else if (type == double2_type()) { | |
1491 st->print("double2"); | |
1492 } else if (is_int(type)) { | |
1493 st->print("int"); | |
1494 } else if (is_long(type)) { | |
1495 st->print("long"); | |
1496 } else if (is_float(type)) { | |
1497 st->print("float"); | |
1498 } else if (is_double(type)) { | |
1499 st->print("double"); | |
1500 } else if (type->is_return_address()) { | |
1501 st->print("address(%d)", type->as_return_address()->bci()); | |
1502 } else { | |
1503 if (type->is_klass()) { | |
1504 type->as_klass()->name()->print_symbol_on(st); | |
1505 } else { | |
1506 st->print("UNEXPECTED TYPE"); | |
1507 type->print(); | |
1508 } | |
1509 } | |
1510 } | |
1511 | |
1512 // ------------------------------------------------------------------ | |
1513 // ciTypeFlow::StateVector::print_on | |
1514 void ciTypeFlow::StateVector::print_on(outputStream* st) const { | |
1515 int num_locals = _outer->max_locals(); | |
1516 int num_stack = stack_size(); | |
1517 int num_monitors = monitor_count(); | |
1518 st->print_cr(" State : locals %d, stack %d, monitors %d", num_locals, num_stack, num_monitors); | |
1519 if (num_stack >= 0) { | |
1520 int i; | |
1521 for (i = 0; i < num_locals; i++) { | |
1522 st->print(" local %2d : ", i); | |
1523 print_cell_on(st, local(i)); | |
1524 st->cr(); | |
1525 } | |
1526 for (i = 0; i < num_stack; i++) { | |
1527 st->print(" stack %2d : ", i); | |
1528 print_cell_on(st, stack(i)); | |
1529 st->cr(); | |
1530 } | |
1531 } | |
1532 } | |
1533 #endif | |
1534 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1535 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1536 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1537 // 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
|
1538 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1539 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
|
1540 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
|
1541 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
|
1542 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
|
1543 _index = next; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1544 _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
|
1545 return; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1546 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1547 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
|
1548 // 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
|
1549 // 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
|
1550 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
|
1551 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
|
1552 _index = next; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1553 _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
|
1554 return; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1555 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1556 next++; |
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 _index = -1; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1559 _succ = NULL; |
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 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1562 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1563 // 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
|
1564 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1565 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
|
1566 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
|
1567 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
|
1568 _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
|
1569 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1570 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
|
1571 _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
|
1572 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1573 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1574 |
0 | 1575 // ciTypeFlow::Block |
1576 // | |
1577 // A basic block. | |
1578 | |
1579 // ------------------------------------------------------------------ | |
1580 // ciTypeFlow::Block::Block | |
1581 ciTypeFlow::Block::Block(ciTypeFlow* outer, | |
1582 ciBlock *ciblk, | |
1583 ciTypeFlow::JsrSet* jsrs) { | |
1584 _ciblock = ciblk; | |
1585 _exceptions = NULL; | |
1586 _exc_klasses = NULL; | |
1587 _successors = NULL; | |
1588 _state = new (outer->arena()) StateVector(outer); | |
1589 JsrSet* new_jsrs = | |
1590 new (outer->arena()) JsrSet(outer->arena(), jsrs->size()); | |
1591 jsrs->copy_into(new_jsrs); | |
1592 _jsrs = new_jsrs; | |
1593 _next = NULL; | |
1594 _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
|
1595 _backedge_copy = false; |
4777 | 1596 _has_monitorenter = false; |
0 | 1597 _trap_bci = -1; |
1598 _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
|
1599 df_init(); |
0 | 1600 |
1601 if (CITraceTypeFlow) { | |
1602 tty->print_cr(">> Created new block"); | |
1603 print_on(tty); | |
1604 } | |
1605 | |
1606 assert(this->outer() == outer, "outer link set up"); | |
1607 assert(!outer->have_block_count(), "must not have mapped blocks yet"); | |
1608 } | |
1609 | |
1610 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1611 // 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
|
1612 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
|
1613 _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
|
1614 _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
|
1615 _loop = NULL; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1616 _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
|
1617 _rpo_next = NULL; |
0 | 1618 } |
1619 | |
1620 // ------------------------------------------------------------------ | |
1621 // ciTypeFlow::Block::successors | |
1622 // | |
1623 // Get the successors for this Block. | |
1624 GrowableArray<ciTypeFlow::Block*>* | |
1625 ciTypeFlow::Block::successors(ciBytecodeStream* str, | |
1626 ciTypeFlow::StateVector* state, | |
1627 ciTypeFlow::JsrSet* jsrs) { | |
1628 if (_successors == NULL) { | |
1629 if (CITraceTypeFlow) { | |
1630 tty->print(">> Computing successors for block "); | |
1631 print_value_on(tty); | |
1632 tty->cr(); | |
1633 } | |
1634 | |
1635 ciTypeFlow* analyzer = outer(); | |
1636 Arena* arena = analyzer->arena(); | |
1637 Block* block = NULL; | |
1638 bool has_successor = !has_trap() && | |
1639 (control() != ciBlock::fall_through_bci || limit() < analyzer->code_size()); | |
1640 if (!has_successor) { | |
1641 _successors = | |
1642 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1643 // No successors | |
1644 } else if (control() == ciBlock::fall_through_bci) { | |
1645 assert(str->cur_bci() == limit(), "bad block end"); | |
1646 // This block simply falls through to the next. | |
1647 _successors = | |
1648 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1649 | |
1650 Block* block = analyzer->block_at(limit(), _jsrs); | |
1651 assert(_successors->length() == FALL_THROUGH, ""); | |
1652 _successors->append(block); | |
1653 } else { | |
1654 int current_bci = str->cur_bci(); | |
1655 int next_bci = str->next_bci(); | |
1656 int branch_bci = -1; | |
1657 Block* target = NULL; | |
1658 assert(str->next_bci() == limit(), "bad block end"); | |
1659 // This block is not a simple fall-though. Interpret | |
1660 // the current bytecode to find our successors. | |
1661 switch (str->cur_bc()) { | |
1662 case Bytecodes::_ifeq: case Bytecodes::_ifne: | |
1663 case Bytecodes::_iflt: case Bytecodes::_ifge: | |
1664 case Bytecodes::_ifgt: case Bytecodes::_ifle: | |
1665 case Bytecodes::_if_icmpeq: case Bytecodes::_if_icmpne: | |
1666 case Bytecodes::_if_icmplt: case Bytecodes::_if_icmpge: | |
1667 case Bytecodes::_if_icmpgt: case Bytecodes::_if_icmple: | |
1668 case Bytecodes::_if_acmpeq: case Bytecodes::_if_acmpne: | |
1669 case Bytecodes::_ifnull: case Bytecodes::_ifnonnull: | |
1670 // Our successors are the branch target and the next bci. | |
1671 branch_bci = str->get_dest(); | |
1672 _successors = | |
1673 new (arena) GrowableArray<Block*>(arena, 2, 0, NULL); | |
1674 assert(_successors->length() == IF_NOT_TAKEN, ""); | |
1675 _successors->append(analyzer->block_at(next_bci, jsrs)); | |
1676 assert(_successors->length() == IF_TAKEN, ""); | |
1677 _successors->append(analyzer->block_at(branch_bci, jsrs)); | |
1678 break; | |
1679 | |
1680 case Bytecodes::_goto: | |
1681 branch_bci = str->get_dest(); | |
1682 _successors = | |
1683 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1684 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
|
1685 _successors->append(analyzer->block_at(branch_bci, jsrs)); |
0 | 1686 break; |
1687 | |
1688 case Bytecodes::_jsr: | |
1689 branch_bci = str->get_dest(); | |
1690 _successors = | |
1691 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1692 assert(_successors->length() == GOTO_TARGET, ""); | |
1693 _successors->append(analyzer->block_at(branch_bci, jsrs)); | |
1694 break; | |
1695 | |
1696 case Bytecodes::_goto_w: | |
1697 case Bytecodes::_jsr_w: | |
1698 _successors = | |
1699 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1700 assert(_successors->length() == GOTO_TARGET, ""); | |
1701 _successors->append(analyzer->block_at(str->get_far_dest(), jsrs)); | |
1702 break; | |
1703 | |
1704 case Bytecodes::_tableswitch: { | |
2142 | 1705 Bytecode_tableswitch tableswitch(str); |
0 | 1706 |
2142 | 1707 int len = tableswitch.length(); |
0 | 1708 _successors = |
1709 new (arena) GrowableArray<Block*>(arena, len+1, 0, NULL); | |
2142 | 1710 int bci = current_bci + tableswitch.default_offset(); |
0 | 1711 Block* block = analyzer->block_at(bci, jsrs); |
1712 assert(_successors->length() == SWITCH_DEFAULT, ""); | |
1713 _successors->append(block); | |
1714 while (--len >= 0) { | |
2142 | 1715 int bci = current_bci + tableswitch.dest_offset_at(len); |
0 | 1716 block = analyzer->block_at(bci, jsrs); |
1717 assert(_successors->length() >= SWITCH_CASES, ""); | |
1718 _successors->append_if_missing(block); | |
1719 } | |
1720 break; | |
1721 } | |
1722 | |
1723 case Bytecodes::_lookupswitch: { | |
2142 | 1724 Bytecode_lookupswitch lookupswitch(str); |
0 | 1725 |
2142 | 1726 int npairs = lookupswitch.number_of_pairs(); |
0 | 1727 _successors = |
1728 new (arena) GrowableArray<Block*>(arena, npairs+1, 0, NULL); | |
2142 | 1729 int bci = current_bci + lookupswitch.default_offset(); |
0 | 1730 Block* block = analyzer->block_at(bci, jsrs); |
1731 assert(_successors->length() == SWITCH_DEFAULT, ""); | |
1732 _successors->append(block); | |
1733 while(--npairs >= 0) { | |
2142 | 1734 LookupswitchPair pair = lookupswitch.pair_at(npairs); |
1735 int bci = current_bci + pair.offset(); | |
0 | 1736 Block* block = analyzer->block_at(bci, jsrs); |
1737 assert(_successors->length() >= SWITCH_CASES, ""); | |
1738 _successors->append_if_missing(block); | |
1739 } | |
1740 break; | |
1741 } | |
1742 | |
1743 case Bytecodes::_athrow: case Bytecodes::_ireturn: | |
1744 case Bytecodes::_lreturn: case Bytecodes::_freturn: | |
1745 case Bytecodes::_dreturn: case Bytecodes::_areturn: | |
1746 case Bytecodes::_return: | |
1747 _successors = | |
1748 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1749 // No successors | |
1750 break; | |
1751 | |
1752 case Bytecodes::_ret: { | |
1753 _successors = | |
1754 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL); | |
1755 | |
1756 Cell local = state->local(str->get_index()); | |
1757 ciType* return_address = state->type_at(local); | |
1758 assert(return_address->is_return_address(), "verify: wrong type"); | |
1759 int bci = return_address->as_return_address()->bci(); | |
1760 assert(_successors->length() == GOTO_TARGET, ""); | |
1761 _successors->append(analyzer->block_at(bci, jsrs)); | |
1762 break; | |
1763 } | |
1764 | |
1765 case Bytecodes::_wide: | |
1766 default: | |
1767 ShouldNotReachHere(); | |
1768 break; | |
1769 } | |
1770 } | |
1771 } | |
1772 return _successors; | |
1773 } | |
1774 | |
1775 // ------------------------------------------------------------------ | |
1776 // ciTypeFlow::Block:compute_exceptions | |
1777 // | |
1778 // Compute the exceptional successors and types for this Block. | |
1779 void ciTypeFlow::Block::compute_exceptions() { | |
1780 assert(_exceptions == NULL && _exc_klasses == NULL, "repeat"); | |
1781 | |
1782 if (CITraceTypeFlow) { | |
1783 tty->print(">> Computing exceptions for block "); | |
1784 print_value_on(tty); | |
1785 tty->cr(); | |
1786 } | |
1787 | |
1788 ciTypeFlow* analyzer = outer(); | |
1789 Arena* arena = analyzer->arena(); | |
1790 | |
1791 // Any bci in the block will do. | |
1792 ciExceptionHandlerStream str(analyzer->method(), start()); | |
1793 | |
1794 // Allocate our growable arrays. | |
1795 int exc_count = str.count(); | |
1796 _exceptions = new (arena) GrowableArray<Block*>(arena, exc_count, 0, NULL); | |
1797 _exc_klasses = new (arena) GrowableArray<ciInstanceKlass*>(arena, exc_count, | |
1798 0, NULL); | |
1799 | |
1800 for ( ; !str.is_done(); str.next()) { | |
1801 ciExceptionHandler* handler = str.handler(); | |
1802 int bci = handler->handler_bci(); | |
1803 ciInstanceKlass* klass = NULL; | |
1804 if (bci == -1) { | |
1805 // There is no catch all. It is possible to exit the method. | |
1806 break; | |
1807 } | |
1808 if (handler->is_catch_all()) { | |
1809 klass = analyzer->env()->Throwable_klass(); | |
1810 } else { | |
1811 klass = handler->catch_klass(); | |
1812 } | |
1813 _exceptions->append(analyzer->block_at(bci, _jsrs)); | |
1814 _exc_klasses->append(klass); | |
1815 } | |
1816 } | |
1817 | |
1818 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1819 // 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
|
1820 // 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
|
1821 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
|
1822 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
|
1823 _backedge_copy = z; |
0 | 1824 } |
1825 | |
1826 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1827 // 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
|
1828 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1829 // 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
|
1830 // 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
|
1831 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
|
1832 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
|
1833 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
|
1834 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
|
1835 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
|
1836 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
|
1837 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
|
1838 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
|
1839 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
|
1840 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1841 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1842 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
|
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 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
|
1846 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1847 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1848 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1849 // 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
|
1850 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1851 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
|
1852 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
|
1853 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
|
1854 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
|
1855 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
|
1856 return succ; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1857 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1858 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1859 return NULL; |
0 | 1860 } |
1861 | |
1862 #ifndef PRODUCT | |
1863 // ------------------------------------------------------------------ | |
1864 // ciTypeFlow::Block::print_value_on | |
1865 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
|
1866 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
|
1867 if (has_rpo()) st->print("rpo#%-2d ", rpo()); |
0 | 1868 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
|
1869 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
|
1870 if (is_irreducible_entry()) st->print(" irred"); |
0 | 1871 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
|
1872 if (is_backedge_copy()) st->print("/backedge_copy"); |
0 | 1873 } |
1874 | |
1875 // ------------------------------------------------------------------ | |
1876 // ciTypeFlow::Block::print_on | |
1877 void ciTypeFlow::Block::print_on(outputStream* st) const { | |
2398
322a41ec766c
7025708: Assertion if using "-XX:+CITraceTypeFlow -XX:+Verbose" together
never
parents:
2142
diff
changeset
|
1878 if ((Verbose || WizardMode) && (limit() >= 0)) { |
322a41ec766c
7025708: Assertion if using "-XX:+CITraceTypeFlow -XX:+Verbose" together
never
parents:
2142
diff
changeset
|
1879 // Don't print 'dummy' blocks (i.e. blocks with limit() '-1') |
0 | 1880 outer()->method()->print_codes_on(start(), limit(), st); |
1881 } | |
1882 st->print_cr(" ==================================================== "); | |
1883 st->print (" "); | |
1884 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
|
1885 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
|
1886 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
|
1887 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
|
1888 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
|
1889 do { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1890 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
|
1891 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
|
1892 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
|
1893 } 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
|
1894 } |
0 | 1895 st->cr(); |
1896 _state->print_on(st); | |
1897 if (_successors == NULL) { | |
1898 st->print_cr(" No successor information"); | |
1899 } else { | |
1900 int num_successors = _successors->length(); | |
1901 st->print_cr(" Successors : %d", num_successors); | |
1902 for (int i = 0; i < num_successors; i++) { | |
1903 Block* successor = _successors->at(i); | |
1904 st->print(" "); | |
1905 successor->print_value_on(st); | |
1906 st->cr(); | |
1907 } | |
1908 } | |
1909 if (_exceptions == NULL) { | |
1910 st->print_cr(" No exception information"); | |
1911 } else { | |
1912 int num_exceptions = _exceptions->length(); | |
1913 st->print_cr(" Exceptions : %d", num_exceptions); | |
1914 for (int i = 0; i < num_exceptions; i++) { | |
1915 Block* exc_succ = _exceptions->at(i); | |
1916 ciInstanceKlass* exc_klass = _exc_klasses->at(i); | |
1917 st->print(" "); | |
1918 exc_succ->print_value_on(st); | |
1919 st->print(" -- "); | |
1920 exc_klass->name()->print_symbol_on(st); | |
1921 st->cr(); | |
1922 } | |
1923 } | |
1924 if (has_trap()) { | |
1925 st->print_cr(" Traps on %d with trap index %d", trap_bci(), trap_index()); | |
1926 } | |
1927 st->print_cr(" ==================================================== "); | |
1928 } | |
1929 #endif | |
1930 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1931 #ifndef PRODUCT |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1932 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1933 // 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
|
1934 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
|
1935 st->print("{"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1936 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
|
1937 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
|
1938 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1939 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
|
1940 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
|
1941 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1942 st->print(" }"); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1943 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1944 #endif |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
1945 |
0 | 1946 // ciTypeFlow |
1947 // | |
1948 // This is a pass over the bytecodes which computes the following: | |
1949 // basic block structure | |
1950 // interpreter type-states (a la the verifier) | |
1951 | |
1952 // ------------------------------------------------------------------ | |
1953 // ciTypeFlow::ciTypeFlow | |
1954 ciTypeFlow::ciTypeFlow(ciEnv* env, ciMethod* method, int osr_bci) { | |
1955 _env = env; | |
1956 _method = method; | |
1957 _methodBlocks = method->get_method_blocks(); | |
1958 _max_locals = method->max_locals(); | |
1959 _max_stack = method->max_stack(); | |
1960 _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
|
1961 _has_irreducible_entry = false; |
0 | 1962 _osr_bci = osr_bci; |
1963 _failure_reason = NULL; | |
1846 | 1964 assert(0 <= start_bci() && start_bci() < code_size() , err_msg("correct osr_bci argument: 0 <= %d < %d", start_bci(), code_size())); |
0 | 1965 _work_list = NULL; |
1966 | |
1967 _ciblock_count = _methodBlocks->num_blocks(); | |
1968 _idx_to_blocklist = NEW_ARENA_ARRAY(arena(), GrowableArray<Block*>*, _ciblock_count); | |
1969 for (int i = 0; i < _ciblock_count; i++) { | |
1970 _idx_to_blocklist[i] = NULL; | |
1971 } | |
1972 _block_map = NULL; // until all blocks are seen | |
1973 _jsr_count = 0; | |
1974 _jsr_records = NULL; | |
1975 } | |
1976 | |
1977 // ------------------------------------------------------------------ | |
1978 // ciTypeFlow::work_list_next | |
1979 // | |
1980 // Get the next basic block from our work list. | |
1981 ciTypeFlow::Block* ciTypeFlow::work_list_next() { | |
1982 assert(!work_list_empty(), "work list must not be empty"); | |
1983 Block* next_block = _work_list; | |
1984 _work_list = next_block->next(); | |
1985 next_block->set_next(NULL); | |
1986 next_block->set_on_work_list(false); | |
1987 return next_block; | |
1988 } | |
1989 | |
1990 // ------------------------------------------------------------------ | |
1991 // ciTypeFlow::add_to_work_list | |
1992 // | |
1993 // 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
|
1994 // List is sorted by decreasing postorder sort (same as increasing RPO) |
0 | 1995 void ciTypeFlow::add_to_work_list(ciTypeFlow::Block* block) { |
1996 assert(!block->is_on_work_list(), "must not already be on work list"); | |
1997 | |
1998 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
|
1999 tty->print(">> Adding block "); |
0 | 2000 block->print_value_on(tty); |
2001 tty->print_cr(" to the work list : "); | |
2002 } | |
2003 | |
2004 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
|
2005 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2006 // 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
|
2007 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2008 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
|
2009 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
|
2010 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
|
2011 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
|
2012 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
|
2013 break; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2014 prev = current; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2015 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
|
2016 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2017 if (prev == NULL) { |
0 | 2018 block->set_next(_work_list); |
2019 _work_list = block; | |
2020 } else { | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2021 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
|
2022 prev->set_next(block); |
0 | 2023 } |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2024 |
0 | 2025 if (CITraceTypeFlow) { |
2026 tty->cr(); | |
2027 } | |
2028 } | |
2029 | |
2030 // ------------------------------------------------------------------ | |
2031 // ciTypeFlow::block_at | |
2032 // | |
2033 // Return the block beginning at bci which has a JsrSet compatible | |
2034 // with jsrs. | |
2035 ciTypeFlow::Block* ciTypeFlow::block_at(int bci, ciTypeFlow::JsrSet* jsrs, CreateOption option) { | |
2036 // First find the right ciBlock. | |
2037 if (CITraceTypeFlow) { | |
2038 tty->print(">> Requesting block for %d/", bci); | |
2039 jsrs->print_on(tty); | |
2040 tty->cr(); | |
2041 } | |
2042 | |
2043 ciBlock* ciblk = _methodBlocks->block_containing(bci); | |
2044 assert(ciblk->start_bci() == bci, "bad ciBlock boundaries"); | |
2045 Block* block = get_block_for(ciblk->index(), jsrs, option); | |
2046 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2047 assert(block == NULL? (option == no_create): block->is_backedge_copy() == (option == create_backedge_copy), "create option consistent with result"); |
0 | 2048 |
2049 if (CITraceTypeFlow) { | |
2050 if (block != NULL) { | |
2051 tty->print(">> Found block "); | |
2052 block->print_value_on(tty); | |
2053 tty->cr(); | |
2054 } else { | |
2055 tty->print_cr(">> No such block."); | |
2056 } | |
2057 } | |
2058 | |
2059 return block; | |
2060 } | |
2061 | |
2062 // ------------------------------------------------------------------ | |
2063 // ciTypeFlow::make_jsr_record | |
2064 // | |
2065 // Make a JsrRecord for a given (entry, return) pair, if such a record | |
2066 // does not already exist. | |
2067 ciTypeFlow::JsrRecord* ciTypeFlow::make_jsr_record(int entry_address, | |
2068 int return_address) { | |
2069 if (_jsr_records == NULL) { | |
2070 _jsr_records = new (arena()) GrowableArray<JsrRecord*>(arena(), | |
2071 _jsr_count, | |
2072 0, | |
2073 NULL); | |
2074 } | |
2075 JsrRecord* record = NULL; | |
2076 int len = _jsr_records->length(); | |
2077 for (int i = 0; i < len; i++) { | |
2078 JsrRecord* record = _jsr_records->at(i); | |
2079 if (record->entry_address() == entry_address && | |
2080 record->return_address() == return_address) { | |
2081 return record; | |
2082 } | |
2083 } | |
2084 | |
2085 record = new (arena()) JsrRecord(entry_address, return_address); | |
2086 _jsr_records->append(record); | |
2087 return record; | |
2088 } | |
2089 | |
2090 // ------------------------------------------------------------------ | |
2091 // ciTypeFlow::flow_exceptions | |
2092 // | |
2093 // Merge the current state into all exceptional successors at the | |
2094 // current point in the code. | |
2095 void ciTypeFlow::flow_exceptions(GrowableArray<ciTypeFlow::Block*>* exceptions, | |
2096 GrowableArray<ciInstanceKlass*>* exc_klasses, | |
2097 ciTypeFlow::StateVector* state) { | |
2098 int len = exceptions->length(); | |
2099 assert(exc_klasses->length() == len, "must have same length"); | |
2100 for (int i = 0; i < len; i++) { | |
2101 Block* block = exceptions->at(i); | |
2102 ciInstanceKlass* exception_klass = exc_klasses->at(i); | |
2103 | |
2104 if (!exception_klass->is_loaded()) { | |
2105 // Do not compile any code for unloaded exception types. | |
2106 // Following compiler passes are responsible for doing this also. | |
2107 continue; | |
2108 } | |
2109 | |
2110 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
|
2111 // 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
|
2112 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
|
2113 !block->is_on_work_list()) { |
0 | 2114 add_to_work_list(block); |
2115 } | |
2116 } | |
2117 } | |
2118 } | |
2119 | |
2120 // ------------------------------------------------------------------ | |
2121 // ciTypeFlow::flow_successors | |
2122 // | |
2123 // Merge the current state into all successors at the current point | |
2124 // in the code. | |
2125 void ciTypeFlow::flow_successors(GrowableArray<ciTypeFlow::Block*>* successors, | |
2126 ciTypeFlow::StateVector* state) { | |
2127 int len = successors->length(); | |
2128 for (int i = 0; i < len; i++) { | |
2129 Block* block = successors->at(i); | |
2130 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
|
2131 // 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
|
2132 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
|
2133 !block->is_on_work_list()) { |
0 | 2134 add_to_work_list(block); |
2135 } | |
2136 } | |
2137 } | |
2138 } | |
2139 | |
2140 // ------------------------------------------------------------------ | |
2141 // ciTypeFlow::can_trap | |
2142 // | |
2143 // Tells if a given instruction is able to generate an exception edge. | |
2144 bool ciTypeFlow::can_trap(ciBytecodeStream& str) { | |
2145 // Cf. GenerateOopMap::do_exception_edge. | |
2146 if (!Bytecodes::can_trap(str.cur_bc())) return false; | |
2147 | |
2148 switch (str.cur_bc()) { | |
1565 | 2149 // %%% FIXME: ldc of Class can generate an exception |
0 | 2150 case Bytecodes::_ldc: |
2151 case Bytecodes::_ldc_w: | |
2152 case Bytecodes::_ldc2_w: | |
2153 case Bytecodes::_aload_0: | |
2154 // These bytecodes can trap for rewriting. We need to assume that | |
2155 // they do not throw exceptions to make the monitor analysis work. | |
2156 return false; | |
2157 | |
2158 case Bytecodes::_ireturn: | |
2159 case Bytecodes::_lreturn: | |
2160 case Bytecodes::_freturn: | |
2161 case Bytecodes::_dreturn: | |
2162 case Bytecodes::_areturn: | |
2163 case Bytecodes::_return: | |
2164 // We can assume the monitor stack is empty in this analysis. | |
2165 return false; | |
2166 | |
2167 case Bytecodes::_monitorexit: | |
2168 // We can assume monitors are matched in this analysis. | |
2169 return false; | |
2170 } | |
2171 | |
2172 return true; | |
2173 } | |
2174 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2175 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2176 // 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
|
2177 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2178 // 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
|
2179 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
|
2180 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
|
2181 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
|
2182 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
|
2183 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
|
2184 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
|
2185 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
|
2186 !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
|
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 |
4777 | 2189 // Avoid BoxLock merge. |
2190 if (EliminateNestedLocks && head->has_monitorenter()) | |
2191 continue; | |
2192 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2193 // 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
|
2194 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
|
2195 continue; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2196 |
6824
f13867c41f73
7199742: A lot of C2 OSR compilations of the same method's bci
kvn
parents:
6725
diff
changeset
|
2197 // Don't clone head of OSR loop to get correct types in start block. |
f13867c41f73
7199742: A lot of C2 OSR compilations of the same method's bci
kvn
parents:
6725
diff
changeset
|
2198 if (is_osr_flow() && head->start() == start_bci()) |
f13867c41f73
7199742: A lot of C2 OSR compilations of the same method's bci
kvn
parents:
6725
diff
changeset
|
2199 continue; |
f13867c41f73
7199742: A lot of C2 OSR compilations of the same method's bci
kvn
parents:
6725
diff
changeset
|
2200 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2201 // 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
|
2202 Loop* ch; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2203 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
|
2204 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
|
2205 continue; |
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 // Clone head |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2208 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
|
2209 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
|
2210 // 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
|
2211 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
|
2212 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
|
2213 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
|
2214 // 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
|
2215 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
|
2216 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2217 rslt = true; |
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 return rslt; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2220 } |
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 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2223 // 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
|
2224 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2225 // 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
|
2226 // |
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 // head <-> 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 // v |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2232 // exit |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2233 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2234 // new_head |
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 // | |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2237 // v |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2238 // head ----------\ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2239 // | | |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2240 // | v |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2241 // | clone <-> body |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2242 // | | |
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 // | | |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2245 // v v |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2246 // exit |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2247 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2248 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
|
2249 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
|
2250 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
|
2251 if (CITraceTypeFlow) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2252 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
|
2253 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
|
2254 tty->cr(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2255 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2256 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
|
2257 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
|
2258 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2259 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
|
2260 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
|
2261 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2262 // 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
|
2263 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
|
2264 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
|
2265 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2266 // 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
|
2267 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
|
2268 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
|
2269 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
|
2270 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2271 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2272 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
|
2273 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
|
2274 // 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
|
2275 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
|
2276 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
|
2277 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
|
2278 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
|
2279 break; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2280 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2281 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2282 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2283 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
|
2284 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2285 return clone; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2286 } |
0 | 2287 |
2288 // ------------------------------------------------------------------ | |
2289 // ciTypeFlow::flow_block | |
2290 // | |
2291 // Interpret the effects of the bytecodes on the incoming state | |
2292 // vector of a basic block. Push the changed state to succeeding | |
2293 // basic blocks. | |
2294 void ciTypeFlow::flow_block(ciTypeFlow::Block* block, | |
2295 ciTypeFlow::StateVector* state, | |
2296 ciTypeFlow::JsrSet* jsrs) { | |
2297 if (CITraceTypeFlow) { | |
2298 tty->print("\n>> ANALYZING BLOCK : "); | |
2299 tty->cr(); | |
2300 block->print_on(tty); | |
2301 } | |
2302 assert(block->has_pre_order(), "pre-order is assigned before 1st flow"); | |
2303 | |
2304 int start = block->start(); | |
2305 int limit = block->limit(); | |
2306 int control = block->control(); | |
2307 if (control != ciBlock::fall_through_bci) { | |
2308 limit = control; | |
2309 } | |
2310 | |
2311 // Grab the state from the current block. | |
2312 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
|
2313 state->def_locals()->clear(); |
0 | 2314 |
2315 GrowableArray<Block*>* exceptions = block->exceptions(); | |
2316 GrowableArray<ciInstanceKlass*>* exc_klasses = block->exc_klasses(); | |
2317 bool has_exceptions = exceptions->length() > 0; | |
2318 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2319 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
|
2320 |
0 | 2321 ciBytecodeStream str(method()); |
2322 str.reset_to_bci(start); | |
2323 Bytecodes::Code code; | |
2324 while ((code = str.next()) != ciBytecodeStream::EOBC() && | |
2325 str.cur_bci() < limit) { | |
2326 // Check for exceptional control flow from this point. | |
2327 if (has_exceptions && can_trap(str)) { | |
2328 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
|
2329 exceptions_used = true; |
0 | 2330 } |
2331 // Apply the effects of the current bytecode to our state. | |
2332 bool res = state->apply_one_bytecode(&str); | |
2333 | |
2334 // Watch for bailouts. | |
2335 if (failing()) return; | |
2336 | |
4777 | 2337 if (str.cur_bc() == Bytecodes::_monitorenter) { |
2338 block->set_has_monitorenter(); | |
2339 } | |
2340 | |
0 | 2341 if (res) { |
2342 | |
2343 // We have encountered a trap. Record it in this block. | |
2344 block->set_trap(state->trap_bci(), state->trap_index()); | |
2345 | |
2346 if (CITraceTypeFlow) { | |
2347 tty->print_cr(">> Found trap"); | |
2348 block->print_on(tty); | |
2349 } | |
2350 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2351 // 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
|
2352 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
|
2353 |
0 | 2354 // Record (no) successors. |
2355 block->successors(&str, state, jsrs); | |
2356 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2357 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
|
2358 |
0 | 2359 // Discontinue interpretation of this Block. |
2360 return; | |
2361 } | |
2362 } | |
2363 | |
2364 GrowableArray<Block*>* successors = NULL; | |
2365 if (control != ciBlock::fall_through_bci) { | |
2366 // Check for exceptional control flow from this point. | |
2367 if (has_exceptions && can_trap(str)) { | |
2368 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
|
2369 exceptions_used = true; |
0 | 2370 } |
2371 | |
2372 // Fix the JsrSet to reflect effect of the bytecode. | |
2373 block->copy_jsrs_into(jsrs); | |
2374 jsrs->apply_control(this, &str, state); | |
2375 | |
2376 // Find successor edges based on old state and new JsrSet. | |
2377 successors = block->successors(&str, state, jsrs); | |
2378 | |
2379 // Apply the control changes to the state. | |
2380 state->apply_one_bytecode(&str); | |
2381 } else { | |
2382 // Fall through control | |
2383 successors = block->successors(&str, NULL, NULL); | |
2384 } | |
2385 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2386 // 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
|
2387 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
|
2388 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2389 // 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
|
2390 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
|
2391 exceptions->clear(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2392 |
0 | 2393 // Pass our state to successors. |
2394 flow_successors(successors, state); | |
2395 } | |
2396 | |
2397 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2398 // 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
|
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 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
|
2401 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
|
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->sibling() != 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->sibling(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2405 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
|
2406 _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
|
2407 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2408 } else { |
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 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2412 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2413 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2414 // 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
|
2415 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2416 // 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
|
2417 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
|
2418 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
|
2419 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
|
2420 _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
|
2421 } 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
|
2422 _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
|
2423 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2424 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
|
2425 _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
|
2426 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2427 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
|
2428 _current = NULL; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2429 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
|
2430 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2431 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
|
2432 _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
|
2433 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2434 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2435 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2436 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2437 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2438 // 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
|
2439 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2440 // 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
|
2441 // 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
|
2442 // 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
|
2443 // 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
|
2444 // 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
|
2445 // 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
|
2446 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
|
2447 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
|
2448 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
|
2449 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
|
2450 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
|
2451 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
|
2452 // 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
|
2453 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
|
2454 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
|
2455 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
|
2456 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
|
2457 break; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2458 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
|
2459 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
|
2460 break; |
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 prev = current; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2463 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
|
2464 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2465 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
|
2466 // 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
|
2467 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
|
2468 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
|
2469 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
|
2470 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2471 leaf = lp; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2472 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2473 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
|
2474 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
|
2475 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2476 return leaf; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2477 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2478 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2479 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2480 // 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
|
2481 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2482 // 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
|
2483 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
|
2484 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
|
2485 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
|
2486 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2487 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
|
2488 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
|
2489 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
|
2490 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
|
2491 // 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
|
2492 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
|
2493 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2494 // 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
|
2495 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
|
2496 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
|
2497 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
|
2498 // 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
|
2499 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2500 } 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
|
2501 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
|
2502 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2503 // If 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
|
2504 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
|
2505 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
|
2506 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2507 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
|
2508 // 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
|
2509 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
|
2510 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2511 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2512 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2513 // 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
|
2514 // 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
|
2515 // 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
|
2516 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
|
2517 _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
|
2518 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
|
2519 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
|
2520 // 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
|
2521 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
|
2522 } |
991 | 2523 Loop* plp = lp->parent(); |
2524 if (plp == NULL) { | |
2525 // This only happens for some irreducible cases. The parent | |
2526 // will be updated during a later pass. | |
2527 break; | |
2528 } | |
2529 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
|
2530 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2531 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2532 // 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
|
2533 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
|
2534 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2535 } // end loop |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2536 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2537 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
|
2538 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
|
2539 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
|
2540 } 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
|
2541 // 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
|
2542 if (blk->loop() != innermost) { |
8721 | 2543 #ifdef ASSERT |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2544 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
|
2545 Loop* dl; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2546 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
|
2547 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
|
2548 #endif |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2549 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
|
2550 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2551 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
|
2552 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
|
2553 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
|
2554 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
|
2555 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
|
2556 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
|
2557 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
|
2558 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
|
2559 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
|
2560 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2561 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2562 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
|
2563 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
|
2564 } |
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 |
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 // 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
|
2569 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2570 // 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
|
2571 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
|
2572 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
|
2573 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
|
2574 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
|
2575 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
|
2576 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
|
2577 return false; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2578 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
|
2579 depth2--; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2580 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
|
2581 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2582 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
|
2583 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2584 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2585 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2586 // 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
|
2587 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2588 // Loop depth |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2589 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
|
2590 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
|
2591 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
|
2592 dp++; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2593 return dp; |
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 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2596 #ifndef PRODUCT |
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::Loop::print |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2599 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
|
2600 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
|
2601 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
|
2602 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
|
2603 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
|
2604 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
|
2605 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
|
2606 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
|
2607 st->cr(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2608 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
|
2609 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
|
2610 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2611 #endif |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2612 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2613 // ------------------------------------------------------------------ |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2614 // 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
|
2615 // |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2616 // 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
|
2617 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
|
2618 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
|
2619 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
|
2620 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
|
2621 int dft_len = 100; |
1685 | 2622 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
|
2623 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2624 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
|
2625 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
|
2626 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
|
2627 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
|
2628 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
|
2629 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
|
2630 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
|
2631 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
|
2632 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
|
2633 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2634 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
|
2635 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2636 _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
|
2637 _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
|
2638 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
|
2639 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2640 // 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
|
2641 int size; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2642 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
|
2643 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
|
2644 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
|
2645 // 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
|
2646 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
|
2647 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
|
2648 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2649 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
|
2650 // 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
|
2651 // 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
|
2652 // 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
|
2653 // "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
|
2654 // 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
|
2655 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
|
2656 return; |
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 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
|
2659 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
|
2660 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
|
2661 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2662 } 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
|
2663 // 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
|
2664 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
|
2665 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
|
2666 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
|
2667 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
|
2668 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2669 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2670 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
|
2671 // 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
|
2672 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
|
2673 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2674 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
|
2675 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
|
2676 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
|
2677 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
|
2678 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2679 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
|
2680 // 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
|
2681 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
|
2682 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2683 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2684 } else { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2685 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
|
2686 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2687 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2688 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2689 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2690 // ------------------------------------------------------------------ |
0 | 2691 // ciTypeFlow::flow_types |
2692 // | |
2693 // Perform the type flow analysis, creating and cloning Blocks as | |
2694 // necessary. | |
2695 void ciTypeFlow::flow_types() { | |
2696 ResourceMark rm; | |
2697 StateVector* temp_vector = new StateVector(this); | |
2698 JsrSet* temp_set = new JsrSet(NULL, 16); | |
2699 | |
2700 // 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
|
2701 Block* start = block_at(start_bci(), temp_set); |
0 | 2702 |
2703 // Load the initial state into it. | |
2704 const StateVector* start_state = get_start_state(); | |
2705 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
|
2706 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
|
2707 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2708 // 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
|
2709 df_flow_types(start, true /*do flow*/, temp_vector, temp_set); |
0 | 2710 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2711 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
|
2712 assert(_rpo_list == start, "must be start"); |
0 | 2713 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2714 // 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
|
2715 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
|
2716 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
|
2717 // 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
|
2718 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2719 bool changed = clone_loop_heads(loop_tree_root(), temp_vector, temp_set); |
0 | 2720 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2721 // 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
|
2722 if (changed) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2723 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
|
2724 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
|
2725 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
|
2726 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
|
2727 blk = next; |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2728 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2729 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
|
2730 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2731 } |
0 | 2732 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2733 if (CITraceTypeFlow) { |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2734 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
|
2735 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
|
2736 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2737 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2738 // 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
|
2739 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2740 debug_only(int max_block = _next_pre_order;) |
0 | 2741 |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2742 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
|
2743 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
|
2744 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
|
2745 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2746 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
|
2747 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2748 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
|
2749 assert (!failing(), "no more bailouts"); |
0 | 2750 } |
2751 } | |
2752 | |
2753 // ------------------------------------------------------------------ | |
2754 // ciTypeFlow::map_blocks | |
2755 // | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2756 // Create the block map, which indexes blocks in reverse post-order. |
0 | 2757 void ciTypeFlow::map_blocks() { |
2758 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
|
2759 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
|
2760 _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
|
2761 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
|
2762 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2763 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
|
2764 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
|
2765 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
|
2766 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
|
2767 _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
|
2768 blk = blk->rpo_next(); |
0 | 2769 } |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2770 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
|
2771 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2772 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
|
2773 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
|
2774 Block* block = _block_map[j]; |
0 | 2775 // Remove dead blocks from successor lists: |
2776 for (int e = 0; e <= 1; e++) { | |
2777 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
|
2778 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
|
2779 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
|
2780 if (!s->has_post_order()) { |
0 | 2781 if (CITraceTypeFlow) { |
2782 tty->print("Removing dead %s successor of #%d: ", (e? "exceptional": "normal"), block->pre_order()); | |
2783 s->print_value_on(tty); | |
2784 tty->cr(); | |
2785 } | |
2786 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
|
2787 --k; |
0 | 2788 } |
2789 } | |
2790 } | |
2791 } | |
2792 } | |
2793 | |
2794 // ------------------------------------------------------------------ | |
2795 // ciTypeFlow::get_block_for | |
2796 // | |
2797 // Find a block with this ciBlock which has a compatible JsrSet. | |
2798 // 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
|
2799 // If the option is create_backedge_copy, always create a fresh backedge copy. |
0 | 2800 ciTypeFlow::Block* ciTypeFlow::get_block_for(int ciBlockIndex, ciTypeFlow::JsrSet* jsrs, CreateOption option) { |
2801 Arena* a = arena(); | |
2802 GrowableArray<Block*>* blocks = _idx_to_blocklist[ciBlockIndex]; | |
2803 if (blocks == NULL) { | |
2804 // Query only? | |
2805 if (option == no_create) return NULL; | |
2806 | |
2807 // Allocate the growable array. | |
2808 blocks = new (a) GrowableArray<Block*>(a, 4, 0, NULL); | |
2809 _idx_to_blocklist[ciBlockIndex] = blocks; | |
2810 } | |
2811 | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2812 if (option != create_backedge_copy) { |
0 | 2813 int len = blocks->length(); |
2814 for (int i = 0; i < len; i++) { | |
2815 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
|
2816 if (!block->is_backedge_copy() && block->is_compatible_with(jsrs)) { |
0 | 2817 return block; |
2818 } | |
2819 } | |
2820 } | |
2821 | |
2822 // Query only? | |
2823 if (option == no_create) return NULL; | |
2824 | |
2825 // We did not find a compatible block. Create one. | |
2826 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
|
2827 if (option == create_backedge_copy) new_block->set_backedge_copy(true); |
0 | 2828 blocks->append(new_block); |
2829 return new_block; | |
2830 } | |
2831 | |
2832 // ------------------------------------------------------------------ | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2833 // ciTypeFlow::backedge_copy_count |
0 | 2834 // |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2835 int ciTypeFlow::backedge_copy_count(int ciBlockIndex, ciTypeFlow::JsrSet* jsrs) const { |
0 | 2836 GrowableArray<Block*>* blocks = _idx_to_blocklist[ciBlockIndex]; |
2837 | |
2838 if (blocks == NULL) { | |
2839 return 0; | |
2840 } | |
2841 | |
2842 int count = 0; | |
2843 int len = blocks->length(); | |
2844 for (int i = 0; i < len; i++) { | |
2845 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
|
2846 if (block->is_backedge_copy() && block->is_compatible_with(jsrs)) { |
0 | 2847 count++; |
2848 } | |
2849 } | |
2850 | |
2851 return count; | |
2852 } | |
2853 | |
2854 // ------------------------------------------------------------------ | |
2855 // ciTypeFlow::do_flow | |
2856 // | |
2857 // Perform type inference flow analysis. | |
2858 void ciTypeFlow::do_flow() { | |
2859 if (CITraceTypeFlow) { | |
2860 tty->print_cr("\nPerforming flow analysis on method"); | |
2861 method()->print(); | |
2862 if (is_osr_flow()) tty->print(" at OSR bci %d", start_bci()); | |
2863 tty->cr(); | |
2864 method()->print_codes(); | |
2865 } | |
2866 if (CITraceTypeFlow) { | |
2867 tty->print_cr("Initial CI Blocks"); | |
2868 print_on(tty); | |
2869 } | |
2870 flow_types(); | |
2871 // Watch for bailouts. | |
2872 if (failing()) { | |
2873 return; | |
2874 } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2875 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2876 map_blocks(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2877 |
0 | 2878 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
|
2879 rpo_print_on(tty); |
0 | 2880 } |
2881 } | |
2882 | |
2883 // ------------------------------------------------------------------ | |
2884 // ciTypeFlow::record_failure() | |
2885 // The ciTypeFlow object keeps track of failure reasons separately from the ciEnv. | |
2886 // This is required because there is not a 1-1 relation between the ciEnv and | |
2887 // the TypeFlow passes within a compilation task. For example, if the compiler | |
2888 // is considering inlining a method, it will request a TypeFlow. If that fails, | |
2889 // the compilation as a whole may continue without the inlining. Some TypeFlow | |
2890 // requests are not optional; if they fail the requestor is responsible for | |
2891 // copying the failure reason up to the ciEnv. (See Parse::Parse.) | |
2892 void ciTypeFlow::record_failure(const char* reason) { | |
2893 if (env()->log() != NULL) { | |
2894 env()->log()->elem("failure reason='%s' phase='typeflow'", reason); | |
2895 } | |
2896 if (_failure_reason == NULL) { | |
2897 // Record the first failure reason. | |
2898 _failure_reason = reason; | |
2899 } | |
2900 } | |
2901 | |
2902 #ifndef PRODUCT | |
2903 // ------------------------------------------------------------------ | |
2904 // ciTypeFlow::print_on | |
2905 void ciTypeFlow::print_on(outputStream* st) const { | |
2906 // Walk through CI blocks | |
2907 st->print_cr("********************************************************"); | |
2908 st->print ("TypeFlow for "); | |
2909 method()->name()->print_symbol_on(st); | |
2910 int limit_bci = code_size(); | |
2911 st->print_cr(" %d bytes", limit_bci); | |
2912 ciMethodBlocks *mblks = _methodBlocks; | |
2913 ciBlock* current = NULL; | |
2914 for (int bci = 0; bci < limit_bci; bci++) { | |
2915 ciBlock* blk = mblks->block_containing(bci); | |
2916 if (blk != NULL && blk != current) { | |
2917 current = blk; | |
2918 current->print_on(st); | |
2919 | |
2920 GrowableArray<Block*>* blocks = _idx_to_blocklist[blk->index()]; | |
2921 int num_blocks = (blocks == NULL) ? 0 : blocks->length(); | |
2922 | |
2923 if (num_blocks == 0) { | |
2924 st->print_cr(" No Blocks"); | |
2925 } else { | |
2926 for (int i = 0; i < num_blocks; i++) { | |
2927 Block* block = blocks->at(i); | |
2928 block->print_on(st); | |
2929 } | |
2930 } | |
2931 st->print_cr("--------------------------------------------------------"); | |
2932 st->cr(); | |
2933 } | |
2934 } | |
2935 st->print_cr("********************************************************"); | |
2936 st->cr(); | |
2937 } | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2938 |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2939 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
|
2940 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
|
2941 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
|
2942 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
|
2943 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
|
2944 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
|
2945 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
|
2946 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
|
2947 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
|
2948 st->cr(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2949 } |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2950 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
|
2951 st->cr(); |
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
0
diff
changeset
|
2952 } |
0 | 2953 #endif |