Mercurial > hg > graal-compiler
annotate src/share/vm/opto/compile.cpp @ 1941:79d04223b8a5
Added caching for resolved types and resolved fields.
This is crucial, because the local load elimination will lead to wrong results, if field equality (of two RiField objects with the same object and the same RiType) is not given. The caching makes sure that the default equals implementation is sufficient.
author | Thomas Wuerthinger <wuerthinger@ssw.jku.at> |
---|---|
date | Tue, 28 Dec 2010 18:33:26 +0100 |
parents | d5d065957597 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
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:
1397
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_compile.cpp.incl" | |
27 | |
28 /// Support for intrinsics. | |
29 | |
30 // Return the index at which m must be inserted (or already exists). | |
31 // The sort order is by the address of the ciMethod, with is_virtual as minor key. | |
32 int Compile::intrinsic_insertion_index(ciMethod* m, bool is_virtual) { | |
33 #ifdef ASSERT | |
34 for (int i = 1; i < _intrinsics->length(); i++) { | |
35 CallGenerator* cg1 = _intrinsics->at(i-1); | |
36 CallGenerator* cg2 = _intrinsics->at(i); | |
37 assert(cg1->method() != cg2->method() | |
38 ? cg1->method() < cg2->method() | |
39 : cg1->is_virtual() < cg2->is_virtual(), | |
40 "compiler intrinsics list must stay sorted"); | |
41 } | |
42 #endif | |
43 // Binary search sorted list, in decreasing intervals [lo, hi]. | |
44 int lo = 0, hi = _intrinsics->length()-1; | |
45 while (lo <= hi) { | |
46 int mid = (uint)(hi + lo) / 2; | |
47 ciMethod* mid_m = _intrinsics->at(mid)->method(); | |
48 if (m < mid_m) { | |
49 hi = mid-1; | |
50 } else if (m > mid_m) { | |
51 lo = mid+1; | |
52 } else { | |
53 // look at minor sort key | |
54 bool mid_virt = _intrinsics->at(mid)->is_virtual(); | |
55 if (is_virtual < mid_virt) { | |
56 hi = mid-1; | |
57 } else if (is_virtual > mid_virt) { | |
58 lo = mid+1; | |
59 } else { | |
60 return mid; // exact match | |
61 } | |
62 } | |
63 } | |
64 return lo; // inexact match | |
65 } | |
66 | |
67 void Compile::register_intrinsic(CallGenerator* cg) { | |
68 if (_intrinsics == NULL) { | |
69 _intrinsics = new GrowableArray<CallGenerator*>(60); | |
70 } | |
71 // This code is stolen from ciObjectFactory::insert. | |
72 // Really, GrowableArray should have methods for | |
73 // insert_at, remove_at, and binary_search. | |
74 int len = _intrinsics->length(); | |
75 int index = intrinsic_insertion_index(cg->method(), cg->is_virtual()); | |
76 if (index == len) { | |
77 _intrinsics->append(cg); | |
78 } else { | |
79 #ifdef ASSERT | |
80 CallGenerator* oldcg = _intrinsics->at(index); | |
81 assert(oldcg->method() != cg->method() || oldcg->is_virtual() != cg->is_virtual(), "don't register twice"); | |
82 #endif | |
83 _intrinsics->append(_intrinsics->at(len-1)); | |
84 int pos; | |
85 for (pos = len-2; pos >= index; pos--) { | |
86 _intrinsics->at_put(pos+1,_intrinsics->at(pos)); | |
87 } | |
88 _intrinsics->at_put(index, cg); | |
89 } | |
90 assert(find_intrinsic(cg->method(), cg->is_virtual()) == cg, "registration worked"); | |
91 } | |
92 | |
93 CallGenerator* Compile::find_intrinsic(ciMethod* m, bool is_virtual) { | |
94 assert(m->is_loaded(), "don't try this on unloaded methods"); | |
95 if (_intrinsics != NULL) { | |
96 int index = intrinsic_insertion_index(m, is_virtual); | |
97 if (index < _intrinsics->length() | |
98 && _intrinsics->at(index)->method() == m | |
99 && _intrinsics->at(index)->is_virtual() == is_virtual) { | |
100 return _intrinsics->at(index); | |
101 } | |
102 } | |
103 // Lazily create intrinsics for intrinsic IDs well-known in the runtime. | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
647
diff
changeset
|
104 if (m->intrinsic_id() != vmIntrinsics::_none && |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
647
diff
changeset
|
105 m->intrinsic_id() <= vmIntrinsics::LAST_COMPILER_INLINE) { |
0 | 106 CallGenerator* cg = make_vm_intrinsic(m, is_virtual); |
107 if (cg != NULL) { | |
108 // Save it for next time: | |
109 register_intrinsic(cg); | |
110 return cg; | |
111 } else { | |
112 gather_intrinsic_statistics(m->intrinsic_id(), is_virtual, _intrinsic_disabled); | |
113 } | |
114 } | |
115 return NULL; | |
116 } | |
117 | |
118 // Compile:: register_library_intrinsics and make_vm_intrinsic are defined | |
119 // in library_call.cpp. | |
120 | |
121 | |
122 #ifndef PRODUCT | |
123 // statistics gathering... | |
124 | |
125 juint Compile::_intrinsic_hist_count[vmIntrinsics::ID_LIMIT] = {0}; | |
126 jubyte Compile::_intrinsic_hist_flags[vmIntrinsics::ID_LIMIT] = {0}; | |
127 | |
128 bool Compile::gather_intrinsic_statistics(vmIntrinsics::ID id, bool is_virtual, int flags) { | |
129 assert(id > vmIntrinsics::_none && id < vmIntrinsics::ID_LIMIT, "oob"); | |
130 int oflags = _intrinsic_hist_flags[id]; | |
131 assert(flags != 0, "what happened?"); | |
132 if (is_virtual) { | |
133 flags |= _intrinsic_virtual; | |
134 } | |
135 bool changed = (flags != oflags); | |
136 if ((flags & _intrinsic_worked) != 0) { | |
137 juint count = (_intrinsic_hist_count[id] += 1); | |
138 if (count == 1) { | |
139 changed = true; // first time | |
140 } | |
141 // increment the overall count also: | |
142 _intrinsic_hist_count[vmIntrinsics::_none] += 1; | |
143 } | |
144 if (changed) { | |
145 if (((oflags ^ flags) & _intrinsic_virtual) != 0) { | |
146 // Something changed about the intrinsic's virtuality. | |
147 if ((flags & _intrinsic_virtual) != 0) { | |
148 // This is the first use of this intrinsic as a virtual call. | |
149 if (oflags != 0) { | |
150 // We already saw it as a non-virtual, so note both cases. | |
151 flags |= _intrinsic_both; | |
152 } | |
153 } else if ((oflags & _intrinsic_both) == 0) { | |
154 // This is the first use of this intrinsic as a non-virtual | |
155 flags |= _intrinsic_both; | |
156 } | |
157 } | |
158 _intrinsic_hist_flags[id] = (jubyte) (oflags | flags); | |
159 } | |
160 // update the overall flags also: | |
161 _intrinsic_hist_flags[vmIntrinsics::_none] |= (jubyte) flags; | |
162 return changed; | |
163 } | |
164 | |
165 static char* format_flags(int flags, char* buf) { | |
166 buf[0] = 0; | |
167 if ((flags & Compile::_intrinsic_worked) != 0) strcat(buf, ",worked"); | |
168 if ((flags & Compile::_intrinsic_failed) != 0) strcat(buf, ",failed"); | |
169 if ((flags & Compile::_intrinsic_disabled) != 0) strcat(buf, ",disabled"); | |
170 if ((flags & Compile::_intrinsic_virtual) != 0) strcat(buf, ",virtual"); | |
171 if ((flags & Compile::_intrinsic_both) != 0) strcat(buf, ",nonvirtual"); | |
172 if (buf[0] == 0) strcat(buf, ","); | |
173 assert(buf[0] == ',', "must be"); | |
174 return &buf[1]; | |
175 } | |
176 | |
177 void Compile::print_intrinsic_statistics() { | |
178 char flagsbuf[100]; | |
179 ttyLocker ttyl; | |
180 if (xtty != NULL) xtty->head("statistics type='intrinsic'"); | |
181 tty->print_cr("Compiler intrinsic usage:"); | |
182 juint total = _intrinsic_hist_count[vmIntrinsics::_none]; | |
183 if (total == 0) total = 1; // avoid div0 in case of no successes | |
184 #define PRINT_STAT_LINE(name, c, f) \ | |
185 tty->print_cr(" %4d (%4.1f%%) %s (%s)", (int)(c), ((c) * 100.0) / total, name, f); | |
186 for (int index = 1 + (int)vmIntrinsics::_none; index < (int)vmIntrinsics::ID_LIMIT; index++) { | |
187 vmIntrinsics::ID id = (vmIntrinsics::ID) index; | |
188 int flags = _intrinsic_hist_flags[id]; | |
189 juint count = _intrinsic_hist_count[id]; | |
190 if ((flags | count) != 0) { | |
191 PRINT_STAT_LINE(vmIntrinsics::name_at(id), count, format_flags(flags, flagsbuf)); | |
192 } | |
193 } | |
194 PRINT_STAT_LINE("total", total, format_flags(_intrinsic_hist_flags[vmIntrinsics::_none], flagsbuf)); | |
195 if (xtty != NULL) xtty->tail("statistics"); | |
196 } | |
197 | |
198 void Compile::print_statistics() { | |
199 { ttyLocker ttyl; | |
200 if (xtty != NULL) xtty->head("statistics type='opto'"); | |
201 Parse::print_statistics(); | |
202 PhaseCCP::print_statistics(); | |
203 PhaseRegAlloc::print_statistics(); | |
204 Scheduling::print_statistics(); | |
205 PhasePeephole::print_statistics(); | |
206 PhaseIdealLoop::print_statistics(); | |
207 if (xtty != NULL) xtty->tail("statistics"); | |
208 } | |
209 if (_intrinsic_hist_flags[vmIntrinsics::_none] != 0) { | |
210 // put this under its own <statistics> element. | |
211 print_intrinsic_statistics(); | |
212 } | |
213 } | |
214 #endif //PRODUCT | |
215 | |
216 // Support for bundling info | |
217 Bundle* Compile::node_bundling(const Node *n) { | |
218 assert(valid_bundle_info(n), "oob"); | |
219 return &_node_bundling_base[n->_idx]; | |
220 } | |
221 | |
222 bool Compile::valid_bundle_info(const Node *n) { | |
223 return (_node_bundling_limit > n->_idx); | |
224 } | |
225 | |
226 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
227 void Compile::gvn_replace_by(Node* n, Node* nn) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
228 for (DUIterator_Last imin, i = n->last_outs(imin); i >= imin; ) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
229 Node* use = n->last_out(i); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
230 bool is_in_table = initial_gvn()->hash_delete(use); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
231 uint uses_found = 0; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
232 for (uint j = 0; j < use->len(); j++) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
233 if (use->in(j) == n) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
234 if (j < use->req()) |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
235 use->set_req(j, nn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
236 else |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
237 use->set_prec(j, nn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
238 uses_found++; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
239 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
240 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
241 if (is_in_table) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
242 // reinsert into table |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
243 initial_gvn()->hash_find_insert(use); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
244 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
245 record_for_igvn(use); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
246 i -= uses_found; // we deleted 1 or more copies of this edge |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
247 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
248 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
249 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
250 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
251 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
252 |
0 | 253 // Identify all nodes that are reachable from below, useful. |
254 // Use breadth-first pass that records state in a Unique_Node_List, | |
255 // recursive traversal is slower. | |
256 void Compile::identify_useful_nodes(Unique_Node_List &useful) { | |
257 int estimated_worklist_size = unique(); | |
258 useful.map( estimated_worklist_size, NULL ); // preallocate space | |
259 | |
260 // Initialize worklist | |
261 if (root() != NULL) { useful.push(root()); } | |
262 // If 'top' is cached, declare it useful to preserve cached node | |
263 if( cached_top_node() ) { useful.push(cached_top_node()); } | |
264 | |
265 // Push all useful nodes onto the list, breadthfirst | |
266 for( uint next = 0; next < useful.size(); ++next ) { | |
267 assert( next < unique(), "Unique useful nodes < total nodes"); | |
268 Node *n = useful.at(next); | |
269 uint max = n->len(); | |
270 for( uint i = 0; i < max; ++i ) { | |
271 Node *m = n->in(i); | |
272 if( m == NULL ) continue; | |
273 useful.push(m); | |
274 } | |
275 } | |
276 } | |
277 | |
278 // Disconnect all useless nodes by disconnecting those at the boundary. | |
279 void Compile::remove_useless_nodes(Unique_Node_List &useful) { | |
280 uint next = 0; | |
281 while( next < useful.size() ) { | |
282 Node *n = useful.at(next++); | |
283 // Use raw traversal of out edges since this code removes out edges | |
284 int max = n->outcnt(); | |
285 for (int j = 0; j < max; ++j ) { | |
286 Node* child = n->raw_out(j); | |
287 if( ! useful.member(child) ) { | |
288 assert( !child->is_top() || child != top(), | |
289 "If top is cached in Compile object it is in useful list"); | |
290 // Only need to remove this out-edge to the useless node | |
291 n->raw_del_out(j); | |
292 --j; | |
293 --max; | |
294 } | |
295 } | |
296 if (n->outcnt() == 1 && n->has_special_unique_user()) { | |
297 record_for_igvn( n->unique_out() ); | |
298 } | |
299 } | |
300 debug_only(verify_graph_edges(true/*check for no_dead_code*/);) | |
301 } | |
302 | |
303 //------------------------------frame_size_in_words----------------------------- | |
304 // frame_slots in units of words | |
305 int Compile::frame_size_in_words() const { | |
306 // shift is 0 in LP32 and 1 in LP64 | |
307 const int shift = (LogBytesPerWord - LogBytesPerInt); | |
308 int words = _frame_slots >> shift; | |
309 assert( words << shift == _frame_slots, "frame size must be properly aligned in LP64" ); | |
310 return words; | |
311 } | |
312 | |
313 // ============================================================================ | |
314 //------------------------------CompileWrapper--------------------------------- | |
315 class CompileWrapper : public StackObj { | |
316 Compile *const _compile; | |
317 public: | |
318 CompileWrapper(Compile* compile); | |
319 | |
320 ~CompileWrapper(); | |
321 }; | |
322 | |
323 CompileWrapper::CompileWrapper(Compile* compile) : _compile(compile) { | |
324 // the Compile* pointer is stored in the current ciEnv: | |
325 ciEnv* env = compile->env(); | |
326 assert(env == ciEnv::current(), "must already be a ciEnv active"); | |
327 assert(env->compiler_data() == NULL, "compile already active?"); | |
328 env->set_compiler_data(compile); | |
329 assert(compile == Compile::current(), "sanity"); | |
330 | |
331 compile->set_type_dict(NULL); | |
332 compile->set_type_hwm(NULL); | |
333 compile->set_type_last_size(0); | |
334 compile->set_last_tf(NULL, NULL); | |
335 compile->set_indexSet_arena(NULL); | |
336 compile->set_indexSet_free_block_list(NULL); | |
337 compile->init_type_arena(); | |
338 Type::Initialize(compile); | |
339 _compile->set_scratch_buffer_blob(NULL); | |
340 _compile->begin_method(); | |
341 } | |
342 CompileWrapper::~CompileWrapper() { | |
343 _compile->end_method(); | |
344 if (_compile->scratch_buffer_blob() != NULL) | |
345 BufferBlob::free(_compile->scratch_buffer_blob()); | |
346 _compile->env()->set_compiler_data(NULL); | |
347 } | |
348 | |
349 | |
350 //----------------------------print_compile_messages--------------------------- | |
351 void Compile::print_compile_messages() { | |
352 #ifndef PRODUCT | |
353 // Check if recompiling | |
354 if (_subsume_loads == false && PrintOpto) { | |
355 // Recompiling without allowing machine instructions to subsume loads | |
356 tty->print_cr("*********************************************************"); | |
357 tty->print_cr("** Bailout: Recompile without subsuming loads **"); | |
358 tty->print_cr("*********************************************************"); | |
359 } | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
360 if (_do_escape_analysis != DoEscapeAnalysis && PrintOpto) { |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
361 // Recompiling without escape analysis |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
362 tty->print_cr("*********************************************************"); |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
363 tty->print_cr("** Bailout: Recompile without escape analysis **"); |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
364 tty->print_cr("*********************************************************"); |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
365 } |
0 | 366 if (env()->break_at_compile()) { |
605 | 367 // Open the debugger when compiling this method. |
0 | 368 tty->print("### Breaking when compiling: "); |
369 method()->print_short_name(); | |
370 tty->cr(); | |
371 BREAKPOINT; | |
372 } | |
373 | |
374 if( PrintOpto ) { | |
375 if (is_osr_compilation()) { | |
376 tty->print("[OSR]%3d", _compile_id); | |
377 } else { | |
378 tty->print("%3d", _compile_id); | |
379 } | |
380 } | |
381 #endif | |
382 } | |
383 | |
384 | |
385 void Compile::init_scratch_buffer_blob() { | |
386 if( scratch_buffer_blob() != NULL ) return; | |
387 | |
388 // Construct a temporary CodeBuffer to have it construct a BufferBlob | |
389 // Cache this BufferBlob for this compile. | |
390 ResourceMark rm; | |
391 int size = (MAX_inst_size + MAX_stubs_size + MAX_const_size); | |
392 BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size); | |
393 // Record the buffer blob for next time. | |
394 set_scratch_buffer_blob(blob); | |
163 | 395 // Have we run out of code space? |
396 if (scratch_buffer_blob() == NULL) { | |
397 // Let CompilerBroker disable further compilations. | |
398 record_failure("Not enough space for scratch buffer in CodeCache"); | |
399 return; | |
400 } | |
0 | 401 |
402 // Initialize the relocation buffers | |
1748 | 403 relocInfo* locs_buf = (relocInfo*) blob->content_end() - MAX_locs_size; |
0 | 404 set_scratch_locs_memory(locs_buf); |
405 } | |
406 | |
407 | |
408 //-----------------------scratch_emit_size------------------------------------- | |
409 // Helper function that computes size by emitting code | |
410 uint Compile::scratch_emit_size(const Node* n) { | |
411 // Emit into a trash buffer and count bytes emitted. | |
412 // This is a pretty expensive way to compute a size, | |
413 // but it works well enough if seldom used. | |
414 // All common fixed-size instructions are given a size | |
415 // method by the AD file. | |
416 // Note that the scratch buffer blob and locs memory are | |
417 // allocated at the beginning of the compile task, and | |
418 // may be shared by several calls to scratch_emit_size. | |
419 // The allocation of the scratch buffer blob is particularly | |
420 // expensive, since it has to grab the code cache lock. | |
421 BufferBlob* blob = this->scratch_buffer_blob(); | |
422 assert(blob != NULL, "Initialize BufferBlob at start"); | |
423 assert(blob->size() > MAX_inst_size, "sanity"); | |
424 relocInfo* locs_buf = scratch_locs_memory(); | |
1748 | 425 address blob_begin = blob->content_begin(); |
0 | 426 address blob_end = (address)locs_buf; |
1748 | 427 assert(blob->content_contains(blob_end), "sanity"); |
0 | 428 CodeBuffer buf(blob_begin, blob_end - blob_begin); |
429 buf.initialize_consts_size(MAX_const_size); | |
430 buf.initialize_stubs_size(MAX_stubs_size); | |
431 assert(locs_buf != NULL, "sanity"); | |
432 int lsize = MAX_locs_size / 2; | |
433 buf.insts()->initialize_shared_locs(&locs_buf[0], lsize); | |
434 buf.stubs()->initialize_shared_locs(&locs_buf[lsize], lsize); | |
435 n->emit(buf, this->regalloc()); | |
1748 | 436 return buf.insts_size(); |
0 | 437 } |
438 | |
439 | |
440 // ============================================================================ | |
441 //------------------------------Compile standard------------------------------- | |
442 debug_only( int Compile::_debug_idx = 100000; ) | |
443 | |
444 // Compile a method. entry_bci is -1 for normal compilations and indicates | |
445 // the continuation bci for on stack replacement. | |
446 | |
447 | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
448 Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci, bool subsume_loads, bool do_escape_analysis ) |
0 | 449 : Phase(Compiler), |
450 _env(ci_env), | |
451 _log(ci_env->log()), | |
452 _compile_id(ci_env->compile_id()), | |
453 _save_argument_registers(false), | |
454 _stub_name(NULL), | |
455 _stub_function(NULL), | |
456 _stub_entry_point(NULL), | |
457 _method(target), | |
458 _entry_bci(osr_bci), | |
459 _initial_gvn(NULL), | |
460 _for_igvn(NULL), | |
461 _warm_calls(NULL), | |
462 _subsume_loads(subsume_loads), | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
463 _do_escape_analysis(do_escape_analysis), |
0 | 464 _failure_reason(NULL), |
465 _code_buffer("Compile::Fill_buffer"), | |
466 _orig_pc_slot(0), | |
467 _orig_pc_slot_offset_in_bytes(0), | |
1265 | 468 _has_method_handle_invokes(false), |
0 | 469 _node_bundling_limit(0), |
470 _node_bundling_base(NULL), | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
471 _java_calls(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
472 _inner_loops(0), |
0 | 473 #ifndef PRODUCT |
474 _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")), | |
475 _printer(IdealGraphPrinter::printer()), | |
476 #endif | |
477 _congraph(NULL) { | |
478 C = this; | |
479 | |
480 CompileWrapper cw(this); | |
481 #ifndef PRODUCT | |
482 if (TimeCompiler2) { | |
483 tty->print(" "); | |
484 target->holder()->name()->print(); | |
485 tty->print("."); | |
486 target->print_short_name(); | |
487 tty->print(" "); | |
488 } | |
489 TraceTime t1("Total compilation time", &_t_totalCompilation, TimeCompiler, TimeCompiler2); | |
490 TraceTime t2(NULL, &_t_methodCompilation, TimeCompiler, false); | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
491 bool print_opto_assembly = PrintOptoAssembly || _method->has_option("PrintOptoAssembly"); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
492 if (!print_opto_assembly) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
493 bool print_assembly = (PrintAssembly || _method->should_print_assembly()); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
494 if (print_assembly && !Disassembler::can_decode()) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
495 tty->print_cr("PrintAssembly request changed to PrintOptoAssembly"); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
496 print_opto_assembly = true; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
497 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
498 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
499 set_print_assembly(print_opto_assembly); |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
333
diff
changeset
|
500 set_parsed_irreducible_loop(false); |
0 | 501 #endif |
502 | |
503 if (ProfileTraps) { | |
504 // Make sure the method being compiled gets its own MDO, | |
505 // so we can at least track the decompile_count(). | |
506 method()->build_method_data(); | |
507 } | |
508 | |
509 Init(::AliasLevel); | |
510 | |
511 | |
512 print_compile_messages(); | |
513 | |
514 if (UseOldInlining || PrintCompilation NOT_PRODUCT( || PrintOpto) ) | |
515 _ilt = InlineTree::build_inline_tree_root(); | |
516 else | |
517 _ilt = NULL; | |
518 | |
519 // Even if NO memory addresses are used, MergeMem nodes must have at least 1 slice | |
520 assert(num_alias_types() >= AliasIdxRaw, ""); | |
521 | |
522 #define MINIMUM_NODE_HASH 1023 | |
523 // Node list that Iterative GVN will start with | |
524 Unique_Node_List for_igvn(comp_arena()); | |
525 set_for_igvn(&for_igvn); | |
526 | |
527 // GVN that will be run immediately on new nodes | |
528 uint estimated_size = method()->code_size()*4+64; | |
529 estimated_size = (estimated_size < MINIMUM_NODE_HASH ? MINIMUM_NODE_HASH : estimated_size); | |
530 PhaseGVN gvn(node_arena(), estimated_size); | |
531 set_initial_gvn(&gvn); | |
532 | |
533 { // Scope for timing the parser | |
534 TracePhase t3("parse", &_t_parser, true); | |
535 | |
536 // Put top into the hash table ASAP. | |
537 initial_gvn()->transform_no_reclaim(top()); | |
538 | |
539 // Set up tf(), start(), and find a CallGenerator. | |
540 CallGenerator* cg; | |
541 if (is_osr_compilation()) { | |
542 const TypeTuple *domain = StartOSRNode::osr_domain(); | |
543 const TypeTuple *range = TypeTuple::make_range(method()->signature()); | |
544 init_tf(TypeFunc::make(domain, range)); | |
545 StartNode* s = new (this, 2) StartOSRNode(root(), domain); | |
546 initial_gvn()->set_type_bottom(s); | |
547 init_start(s); | |
548 cg = CallGenerator::for_osr(method(), entry_bci()); | |
549 } else { | |
550 // Normal case. | |
551 init_tf(TypeFunc::make(method())); | |
552 StartNode* s = new (this, 2) StartNode(root(), tf()->domain()); | |
553 initial_gvn()->set_type_bottom(s); | |
554 init_start(s); | |
555 float past_uses = method()->interpreter_invocation_count(); | |
556 float expected_uses = past_uses; | |
557 cg = CallGenerator::for_inline(method(), expected_uses); | |
558 } | |
559 if (failing()) return; | |
560 if (cg == NULL) { | |
561 record_method_not_compilable_all_tiers("cannot parse method"); | |
562 return; | |
563 } | |
564 JVMState* jvms = build_start_state(start(), tf()); | |
565 if ((jvms = cg->generate(jvms)) == NULL) { | |
566 record_method_not_compilable("method parse failed"); | |
567 return; | |
568 } | |
569 GraphKit kit(jvms); | |
570 | |
571 if (!kit.stopped()) { | |
572 // Accept return values, and transfer control we know not where. | |
573 // This is done by a special, unique ReturnNode bound to root. | |
574 return_values(kit.jvms()); | |
575 } | |
576 | |
577 if (kit.has_exceptions()) { | |
578 // Any exceptions that escape from this call must be rethrown | |
579 // to whatever caller is dynamically above us on the stack. | |
580 // This is done by a special, unique RethrowNode bound to root. | |
581 rethrow_exceptions(kit.transfer_exceptions_into_jvms()); | |
582 } | |
583 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
584 if (!failing() && has_stringbuilder()) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
585 { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
586 // remove useless nodes to make the usage analysis simpler |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
587 ResourceMark rm; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
588 PhaseRemoveUseless pru(initial_gvn(), &for_igvn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
589 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
590 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
591 { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
592 ResourceMark rm; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
593 print_method("Before StringOpts", 3); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
594 PhaseStringOpts pso(initial_gvn(), &for_igvn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
595 print_method("After StringOpts", 3); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
596 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
597 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
598 // now inline anything that we skipped the first time around |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
599 while (_late_inlines.length() > 0) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
600 CallGenerator* cg = _late_inlines.pop(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
601 cg->do_late_inline(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
602 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
603 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
604 assert(_late_inlines.length() == 0, "should have been processed"); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
605 |
417 | 606 print_method("Before RemoveUseless", 3); |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
333
diff
changeset
|
607 |
0 | 608 // Remove clutter produced by parsing. |
609 if (!failing()) { | |
610 ResourceMark rm; | |
611 PhaseRemoveUseless pru(initial_gvn(), &for_igvn); | |
612 } | |
613 } | |
614 | |
615 // Note: Large methods are capped off in do_one_bytecode(). | |
616 if (failing()) return; | |
617 | |
618 // After parsing, node notes are no longer automagic. | |
619 // They must be propagated by register_new_node_with_optimizer(), | |
620 // clone(), or the like. | |
621 set_default_node_notes(NULL); | |
622 | |
623 for (;;) { | |
624 int successes = Inline_Warm(); | |
625 if (failing()) return; | |
626 if (successes == 0) break; | |
627 } | |
628 | |
629 // Drain the list. | |
630 Finish_Warm(); | |
631 #ifndef PRODUCT | |
632 if (_printer) { | |
633 _printer->print_inlining(this); | |
634 } | |
635 #endif | |
636 | |
637 if (failing()) return; | |
638 NOT_PRODUCT( verify_graph_edges(); ) | |
639 | |
640 // Now optimize | |
641 Optimize(); | |
642 if (failing()) return; | |
643 NOT_PRODUCT( verify_graph_edges(); ) | |
644 | |
645 #ifndef PRODUCT | |
646 if (PrintIdeal) { | |
647 ttyLocker ttyl; // keep the following output all in one block | |
648 // This output goes directly to the tty, not the compiler log. | |
649 // To enable tools to match it up with the compilation activity, | |
650 // be sure to tag this tty output with the compile ID. | |
651 if (xtty != NULL) { | |
652 xtty->head("ideal compile_id='%d'%s", compile_id(), | |
653 is_osr_compilation() ? " compile_kind='osr'" : | |
654 ""); | |
655 } | |
656 root()->dump(9999); | |
657 if (xtty != NULL) { | |
658 xtty->tail("ideal"); | |
659 } | |
660 } | |
661 #endif | |
662 | |
663 // Now that we know the size of all the monitors we can add a fixed slot | |
664 // for the original deopt pc. | |
665 | |
666 _orig_pc_slot = fixed_slots(); | |
667 int next_slot = _orig_pc_slot + (sizeof(address) / VMRegImpl::stack_slot_size); | |
668 set_fixed_slots(next_slot); | |
669 | |
670 // Now generate code | |
671 Code_Gen(); | |
672 if (failing()) return; | |
673 | |
674 // Check if we want to skip execution of all compiled code. | |
675 { | |
676 #ifndef PRODUCT | |
677 if (OptoNoExecute) { | |
678 record_method_not_compilable("+OptoNoExecute"); // Flag as failed | |
679 return; | |
680 } | |
681 TracePhase t2("install_code", &_t_registerMethod, TimeCompiler); | |
682 #endif | |
683 | |
684 if (is_osr_compilation()) { | |
685 _code_offsets.set_value(CodeOffsets::Verified_Entry, 0); | |
686 _code_offsets.set_value(CodeOffsets::OSR_Entry, _first_block_size); | |
687 } else { | |
688 _code_offsets.set_value(CodeOffsets::Verified_Entry, _first_block_size); | |
689 _code_offsets.set_value(CodeOffsets::OSR_Entry, 0); | |
690 } | |
691 | |
692 env()->register_method(_method, _entry_bci, | |
693 &_code_offsets, | |
694 _orig_pc_slot_offset_in_bytes, | |
695 code_buffer(), | |
696 frame_size_in_words(), _oop_map_set, | |
697 &_handler_table, &_inc_table, | |
698 compiler, | |
699 env()->comp_level(), | |
700 true, /*has_debug_info*/ | |
701 has_unsafe_access() | |
702 ); | |
703 } | |
704 } | |
705 | |
706 //------------------------------Compile---------------------------------------- | |
707 // Compile a runtime stub | |
708 Compile::Compile( ciEnv* ci_env, | |
709 TypeFunc_generator generator, | |
710 address stub_function, | |
711 const char *stub_name, | |
712 int is_fancy_jump, | |
713 bool pass_tls, | |
714 bool save_arg_registers, | |
715 bool return_pc ) | |
716 : Phase(Compiler), | |
717 _env(ci_env), | |
718 _log(ci_env->log()), | |
719 _compile_id(-1), | |
720 _save_argument_registers(save_arg_registers), | |
721 _method(NULL), | |
722 _stub_name(stub_name), | |
723 _stub_function(stub_function), | |
724 _stub_entry_point(NULL), | |
725 _entry_bci(InvocationEntryBci), | |
726 _initial_gvn(NULL), | |
727 _for_igvn(NULL), | |
728 _warm_calls(NULL), | |
729 _orig_pc_slot(0), | |
730 _orig_pc_slot_offset_in_bytes(0), | |
731 _subsume_loads(true), | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
732 _do_escape_analysis(false), |
0 | 733 _failure_reason(NULL), |
734 _code_buffer("Compile::Fill_buffer"), | |
1265 | 735 _has_method_handle_invokes(false), |
0 | 736 _node_bundling_limit(0), |
737 _node_bundling_base(NULL), | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
738 _java_calls(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
739 _inner_loops(0), |
0 | 740 #ifndef PRODUCT |
741 _trace_opto_output(TraceOptoOutput), | |
742 _printer(NULL), | |
743 #endif | |
744 _congraph(NULL) { | |
745 C = this; | |
746 | |
747 #ifndef PRODUCT | |
748 TraceTime t1(NULL, &_t_totalCompilation, TimeCompiler, false); | |
749 TraceTime t2(NULL, &_t_stubCompilation, TimeCompiler, false); | |
750 set_print_assembly(PrintFrameConverterAssembly); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
333
diff
changeset
|
751 set_parsed_irreducible_loop(false); |
0 | 752 #endif |
753 CompileWrapper cw(this); | |
754 Init(/*AliasLevel=*/ 0); | |
755 init_tf((*generator)()); | |
756 | |
757 { | |
758 // The following is a dummy for the sake of GraphKit::gen_stub | |
759 Unique_Node_List for_igvn(comp_arena()); | |
760 set_for_igvn(&for_igvn); // not used, but some GraphKit guys push on this | |
761 PhaseGVN gvn(Thread::current()->resource_area(),255); | |
762 set_initial_gvn(&gvn); // not significant, but GraphKit guys use it pervasively | |
763 gvn.transform_no_reclaim(top()); | |
764 | |
765 GraphKit kit; | |
766 kit.gen_stub(stub_function, stub_name, is_fancy_jump, pass_tls, return_pc); | |
767 } | |
768 | |
769 NOT_PRODUCT( verify_graph_edges(); ) | |
770 Code_Gen(); | |
771 if (failing()) return; | |
772 | |
773 | |
774 // Entry point will be accessed using compile->stub_entry_point(); | |
775 if (code_buffer() == NULL) { | |
776 Matcher::soft_match_failure(); | |
777 } else { | |
778 if (PrintAssembly && (WizardMode || Verbose)) | |
779 tty->print_cr("### Stub::%s", stub_name); | |
780 | |
781 if (!failing()) { | |
782 assert(_fixed_slots == 0, "no fixed slots used for runtime stubs"); | |
783 | |
784 // Make the NMethod | |
785 // For now we mark the frame as never safe for profile stackwalking | |
786 RuntimeStub *rs = RuntimeStub::new_runtime_stub(stub_name, | |
787 code_buffer(), | |
788 CodeOffsets::frame_never_safe, | |
789 // _code_offsets.value(CodeOffsets::Frame_Complete), | |
790 frame_size_in_words(), | |
791 _oop_map_set, | |
792 save_arg_registers); | |
793 assert(rs != NULL && rs->is_runtime_stub(), "sanity check"); | |
794 | |
795 _stub_entry_point = rs->entry_point(); | |
796 } | |
797 } | |
798 } | |
799 | |
800 #ifndef PRODUCT | |
801 void print_opto_verbose_signature( const TypeFunc *j_sig, const char *stub_name ) { | |
802 if(PrintOpto && Verbose) { | |
803 tty->print("%s ", stub_name); j_sig->print_flattened(); tty->cr(); | |
804 } | |
805 } | |
806 #endif | |
807 | |
808 void Compile::print_codes() { | |
809 } | |
810 | |
811 //------------------------------Init------------------------------------------- | |
812 // Prepare for a single compilation | |
813 void Compile::Init(int aliaslevel) { | |
814 _unique = 0; | |
815 _regalloc = NULL; | |
816 | |
817 _tf = NULL; // filled in later | |
818 _top = NULL; // cached later | |
819 _matcher = NULL; // filled in later | |
820 _cfg = NULL; // filled in later | |
821 | |
822 set_24_bit_selection_and_mode(Use24BitFP, false); | |
823 | |
824 _node_note_array = NULL; | |
825 _default_node_notes = NULL; | |
826 | |
827 _immutable_memory = NULL; // filled in at first inquiry | |
828 | |
829 // Globally visible Nodes | |
830 // First set TOP to NULL to give safe behavior during creation of RootNode | |
831 set_cached_top_node(NULL); | |
832 set_root(new (this, 3) RootNode()); | |
833 // Now that you have a Root to point to, create the real TOP | |
834 set_cached_top_node( new (this, 1) ConNode(Type::TOP) ); | |
835 set_recent_alloc(NULL, NULL); | |
836 | |
837 // Create Debug Information Recorder to record scopes, oopmaps, etc. | |
838 env()->set_oop_recorder(new OopRecorder(comp_arena())); | |
839 env()->set_debug_info(new DebugInformationRecorder(env()->oop_recorder())); | |
840 env()->set_dependencies(new Dependencies(env())); | |
841 | |
842 _fixed_slots = 0; | |
843 set_has_split_ifs(false); | |
844 set_has_loops(has_method() && method()->has_loops()); // first approximation | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
845 set_has_stringbuilder(false); |
0 | 846 _trap_can_recompile = false; // no traps emitted yet |
847 _major_progress = true; // start out assuming good things will happen | |
848 set_has_unsafe_access(false); | |
849 Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist)); | |
850 set_decompile_count(0); | |
851 | |
418 | 852 set_do_freq_based_layout(BlockLayoutByFrequency || method_has_option("BlockLayoutByFrequency")); |
1783 | 853 set_num_loop_opts(LoopOptsCount); |
854 set_do_inlining(Inline); | |
855 set_max_inline_size(MaxInlineSize); | |
856 set_freq_inline_size(FreqInlineSize); | |
857 set_do_scheduling(OptoScheduling); | |
858 set_do_count_invocations(false); | |
859 set_do_method_data_update(false); | |
0 | 860 |
861 if (debug_info()->recording_non_safepoints()) { | |
862 set_node_note_array(new(comp_arena()) GrowableArray<Node_Notes*> | |
863 (comp_arena(), 8, 0, NULL)); | |
864 set_default_node_notes(Node_Notes::make(this)); | |
865 } | |
866 | |
867 // // -- Initialize types before each compile -- | |
868 // // Update cached type information | |
869 // if( _method && _method->constants() ) | |
870 // Type::update_loaded_types(_method, _method->constants()); | |
871 | |
872 // Init alias_type map. | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
873 if (!_do_escape_analysis && aliaslevel == 3) |
0 | 874 aliaslevel = 2; // No unique types without escape analysis |
875 _AliasLevel = aliaslevel; | |
876 const int grow_ats = 16; | |
877 _max_alias_types = grow_ats; | |
878 _alias_types = NEW_ARENA_ARRAY(comp_arena(), AliasType*, grow_ats); | |
879 AliasType* ats = NEW_ARENA_ARRAY(comp_arena(), AliasType, grow_ats); | |
880 Copy::zero_to_bytes(ats, sizeof(AliasType)*grow_ats); | |
881 { | |
882 for (int i = 0; i < grow_ats; i++) _alias_types[i] = &ats[i]; | |
883 } | |
884 // Initialize the first few types. | |
885 _alias_types[AliasIdxTop]->Init(AliasIdxTop, NULL); | |
886 _alias_types[AliasIdxBot]->Init(AliasIdxBot, TypePtr::BOTTOM); | |
887 _alias_types[AliasIdxRaw]->Init(AliasIdxRaw, TypeRawPtr::BOTTOM); | |
888 _num_alias_types = AliasIdxRaw+1; | |
889 // Zero out the alias type cache. | |
890 Copy::zero_to_bytes(_alias_cache, sizeof(_alias_cache)); | |
891 // A NULL adr_type hits in the cache right away. Preload the right answer. | |
892 probe_alias_cache(NULL)->_index = AliasIdxTop; | |
893 | |
894 _intrinsics = NULL; | |
1685 | 895 _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
896 _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | |
0 | 897 register_library_intrinsics(); |
898 } | |
899 | |
900 //---------------------------init_start---------------------------------------- | |
901 // Install the StartNode on this compile object. | |
902 void Compile::init_start(StartNode* s) { | |
903 if (failing()) | |
904 return; // already failing | |
905 assert(s == start(), ""); | |
906 } | |
907 | |
908 StartNode* Compile::start() const { | |
909 assert(!failing(), ""); | |
910 for (DUIterator_Fast imax, i = root()->fast_outs(imax); i < imax; i++) { | |
911 Node* start = root()->fast_out(i); | |
912 if( start->is_Start() ) | |
913 return start->as_Start(); | |
914 } | |
915 ShouldNotReachHere(); | |
916 return NULL; | |
917 } | |
918 | |
919 //-------------------------------immutable_memory------------------------------------- | |
920 // Access immutable memory | |
921 Node* Compile::immutable_memory() { | |
922 if (_immutable_memory != NULL) { | |
923 return _immutable_memory; | |
924 } | |
925 StartNode* s = start(); | |
926 for (DUIterator_Fast imax, i = s->fast_outs(imax); true; i++) { | |
927 Node *p = s->fast_out(i); | |
928 if (p != s && p->as_Proj()->_con == TypeFunc::Memory) { | |
929 _immutable_memory = p; | |
930 return _immutable_memory; | |
931 } | |
932 } | |
933 ShouldNotReachHere(); | |
934 return NULL; | |
935 } | |
936 | |
937 //----------------------set_cached_top_node------------------------------------ | |
938 // Install the cached top node, and make sure Node::is_top works correctly. | |
939 void Compile::set_cached_top_node(Node* tn) { | |
940 if (tn != NULL) verify_top(tn); | |
941 Node* old_top = _top; | |
942 _top = tn; | |
943 // Calling Node::setup_is_top allows the nodes the chance to adjust | |
944 // their _out arrays. | |
945 if (_top != NULL) _top->setup_is_top(); | |
946 if (old_top != NULL) old_top->setup_is_top(); | |
947 assert(_top == NULL || top()->is_top(), ""); | |
948 } | |
949 | |
950 #ifndef PRODUCT | |
951 void Compile::verify_top(Node* tn) const { | |
952 if (tn != NULL) { | |
953 assert(tn->is_Con(), "top node must be a constant"); | |
954 assert(((ConNode*)tn)->type() == Type::TOP, "top node must have correct type"); | |
955 assert(tn->in(0) != NULL, "must have live top node"); | |
956 } | |
957 } | |
958 #endif | |
959 | |
960 | |
961 ///-------------------Managing Per-Node Debug & Profile Info------------------- | |
962 | |
963 void Compile::grow_node_notes(GrowableArray<Node_Notes*>* arr, int grow_by) { | |
964 guarantee(arr != NULL, ""); | |
965 int num_blocks = arr->length(); | |
966 if (grow_by < num_blocks) grow_by = num_blocks; | |
967 int num_notes = grow_by * _node_notes_block_size; | |
968 Node_Notes* notes = NEW_ARENA_ARRAY(node_arena(), Node_Notes, num_notes); | |
969 Copy::zero_to_bytes(notes, num_notes * sizeof(Node_Notes)); | |
970 while (num_notes > 0) { | |
971 arr->append(notes); | |
972 notes += _node_notes_block_size; | |
973 num_notes -= _node_notes_block_size; | |
974 } | |
975 assert(num_notes == 0, "exact multiple, please"); | |
976 } | |
977 | |
978 bool Compile::copy_node_notes_to(Node* dest, Node* source) { | |
979 if (source == NULL || dest == NULL) return false; | |
980 | |
981 if (dest->is_Con()) | |
982 return false; // Do not push debug info onto constants. | |
983 | |
984 #ifdef ASSERT | |
985 // Leave a bread crumb trail pointing to the original node: | |
986 if (dest != NULL && dest != source && dest->debug_orig() == NULL) { | |
987 dest->set_debug_orig(source); | |
988 } | |
989 #endif | |
990 | |
991 if (node_note_array() == NULL) | |
992 return false; // Not collecting any notes now. | |
993 | |
994 // This is a copy onto a pre-existing node, which may already have notes. | |
995 // If both nodes have notes, do not overwrite any pre-existing notes. | |
996 Node_Notes* source_notes = node_notes_at(source->_idx); | |
997 if (source_notes == NULL || source_notes->is_clear()) return false; | |
998 Node_Notes* dest_notes = node_notes_at(dest->_idx); | |
999 if (dest_notes == NULL || dest_notes->is_clear()) { | |
1000 return set_node_notes_at(dest->_idx, source_notes); | |
1001 } | |
1002 | |
1003 Node_Notes merged_notes = (*source_notes); | |
1004 // The order of operations here ensures that dest notes will win... | |
1005 merged_notes.update_from(dest_notes); | |
1006 return set_node_notes_at(dest->_idx, &merged_notes); | |
1007 } | |
1008 | |
1009 | |
1010 //--------------------------allow_range_check_smearing------------------------- | |
1011 // Gating condition for coalescing similar range checks. | |
1012 // Sometimes we try 'speculatively' replacing a series of a range checks by a | |
1013 // single covering check that is at least as strong as any of them. | |
1014 // If the optimization succeeds, the simplified (strengthened) range check | |
1015 // will always succeed. If it fails, we will deopt, and then give up | |
1016 // on the optimization. | |
1017 bool Compile::allow_range_check_smearing() const { | |
1018 // If this method has already thrown a range-check, | |
1019 // assume it was because we already tried range smearing | |
1020 // and it failed. | |
1021 uint already_trapped = trap_count(Deoptimization::Reason_range_check); | |
1022 return !already_trapped; | |
1023 } | |
1024 | |
1025 | |
1026 //------------------------------flatten_alias_type----------------------------- | |
1027 const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { | |
1028 int offset = tj->offset(); | |
1029 TypePtr::PTR ptr = tj->ptr(); | |
1030 | |
247 | 1031 // Known instance (scalarizable allocation) alias only with itself. |
1032 bool is_known_inst = tj->isa_oopptr() != NULL && | |
1033 tj->is_oopptr()->is_known_instance(); | |
1034 | |
0 | 1035 // Process weird unsafe references. |
1036 if (offset == Type::OffsetBot && (tj->isa_instptr() /*|| tj->isa_klassptr()*/)) { | |
1037 assert(InlineUnsafeOps, "indeterminate pointers come only from unsafe ops"); | |
247 | 1038 assert(!is_known_inst, "scalarizable allocation should not have unsafe references"); |
0 | 1039 tj = TypeOopPtr::BOTTOM; |
1040 ptr = tj->ptr(); | |
1041 offset = tj->offset(); | |
1042 } | |
1043 | |
1044 // Array pointers need some flattening | |
1045 const TypeAryPtr *ta = tj->isa_aryptr(); | |
247 | 1046 if( ta && is_known_inst ) { |
1047 if ( offset != Type::OffsetBot && | |
1048 offset > arrayOopDesc::length_offset_in_bytes() ) { | |
1049 offset = Type::OffsetBot; // Flatten constant access into array body only | |
1050 tj = ta = TypeAryPtr::make(ptr, ta->ary(), ta->klass(), true, offset, ta->instance_id()); | |
1051 } | |
1052 } else if( ta && _AliasLevel >= 2 ) { | |
0 | 1053 // For arrays indexed by constant indices, we flatten the alias |
1054 // space to include all of the array body. Only the header, klass | |
1055 // and array length can be accessed un-aliased. | |
1056 if( offset != Type::OffsetBot ) { | |
1057 if( ta->const_oop() ) { // methodDataOop or methodOop | |
1058 offset = Type::OffsetBot; // Flatten constant access into array body | |
247 | 1059 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset); |
0 | 1060 } else if( offset == arrayOopDesc::length_offset_in_bytes() ) { |
1061 // range is OK as-is. | |
1062 tj = ta = TypeAryPtr::RANGE; | |
1063 } else if( offset == oopDesc::klass_offset_in_bytes() ) { | |
1064 tj = TypeInstPtr::KLASS; // all klass loads look alike | |
1065 ta = TypeAryPtr::RANGE; // generic ignored junk | |
1066 ptr = TypePtr::BotPTR; | |
1067 } else if( offset == oopDesc::mark_offset_in_bytes() ) { | |
1068 tj = TypeInstPtr::MARK; | |
1069 ta = TypeAryPtr::RANGE; // generic ignored junk | |
1070 ptr = TypePtr::BotPTR; | |
1071 } else { // Random constant offset into array body | |
1072 offset = Type::OffsetBot; // Flatten constant access into array body | |
247 | 1073 tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset); |
0 | 1074 } |
1075 } | |
1076 // Arrays of fixed size alias with arrays of unknown size. | |
1077 if (ta->size() != TypeInt::POS) { | |
1078 const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS); | |
247 | 1079 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset); |
0 | 1080 } |
1081 // Arrays of known objects become arrays of unknown objects. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1082 if (ta->elem()->isa_narrowoop() && ta->elem() != TypeNarrowOop::BOTTOM) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1083 const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size()); |
247 | 1084 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1085 } |
0 | 1086 if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) { |
1087 const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size()); | |
247 | 1088 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); |
0 | 1089 } |
1090 // Arrays of bytes and of booleans both use 'bastore' and 'baload' so | |
1091 // cannot be distinguished by bytecode alone. | |
1092 if (ta->elem() == TypeInt::BOOL) { | |
1093 const TypeAry *tary = TypeAry::make(TypeInt::BYTE, ta->size()); | |
1094 ciKlass* aklass = ciTypeArrayKlass::make(T_BYTE); | |
247 | 1095 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset); |
0 | 1096 } |
1097 // During the 2nd round of IterGVN, NotNull castings are removed. | |
1098 // Make sure the Bottom and NotNull variants alias the same. | |
1099 // Also, make sure exact and non-exact variants alias the same. | |
1100 if( ptr == TypePtr::NotNull || ta->klass_is_exact() ) { | |
1101 if (ta->const_oop()) { | |
1102 tj = ta = TypeAryPtr::make(TypePtr::Constant,ta->const_oop(),ta->ary(),ta->klass(),false,offset); | |
1103 } else { | |
1104 tj = ta = TypeAryPtr::make(TypePtr::BotPTR,ta->ary(),ta->klass(),false,offset); | |
1105 } | |
1106 } | |
1107 } | |
1108 | |
1109 // Oop pointers need some flattening | |
1110 const TypeInstPtr *to = tj->isa_instptr(); | |
1111 if( to && _AliasLevel >= 2 && to != TypeOopPtr::BOTTOM ) { | |
1112 if( ptr == TypePtr::Constant ) { | |
1113 // No constant oop pointers (such as Strings); they alias with | |
1114 // unknown strings. | |
247 | 1115 assert(!is_known_inst, "not scalarizable allocation"); |
0 | 1116 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); |
247 | 1117 } else if( is_known_inst ) { |
163 | 1118 tj = to; // Keep NotNull and klass_is_exact for instance type |
0 | 1119 } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) { |
1120 // During the 2nd round of IterGVN, NotNull castings are removed. | |
1121 // Make sure the Bottom and NotNull variants alias the same. | |
1122 // Also, make sure exact and non-exact variants alias the same. | |
247 | 1123 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); |
0 | 1124 } |
1125 // Canonicalize the holder of this field | |
1126 ciInstanceKlass *k = to->klass()->as_instance_klass(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1127 if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) { |
0 | 1128 // First handle header references such as a LoadKlassNode, even if the |
1129 // object's klass is unloaded at compile time (4965979). | |
247 | 1130 if (!is_known_inst) { // Do it only for non-instance types |
1131 tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset); | |
1132 } | |
0 | 1133 } else if (offset < 0 || offset >= k->size_helper() * wordSize) { |
1134 to = NULL; | |
1135 tj = TypeOopPtr::BOTTOM; | |
1136 offset = tj->offset(); | |
1137 } else { | |
1138 ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset); | |
1139 if (!k->equals(canonical_holder) || tj->offset() != offset) { | |
247 | 1140 if( is_known_inst ) { |
1141 tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id()); | |
1142 } else { | |
1143 tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset); | |
1144 } | |
0 | 1145 } |
1146 } | |
1147 } | |
1148 | |
1149 // Klass pointers to object array klasses need some flattening | |
1150 const TypeKlassPtr *tk = tj->isa_klassptr(); | |
1151 if( tk ) { | |
1152 // If we are referencing a field within a Klass, we need | |
1153 // to assume the worst case of an Object. Both exact and | |
1154 // inexact types must flatten to the same alias class. | |
1155 // Since the flattened result for a klass is defined to be | |
1156 // precisely java.lang.Object, use a constant ptr. | |
1157 if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) { | |
1158 | |
1159 tj = tk = TypeKlassPtr::make(TypePtr::Constant, | |
1160 TypeKlassPtr::OBJECT->klass(), | |
1161 offset); | |
1162 } | |
1163 | |
1164 ciKlass* klass = tk->klass(); | |
1165 if( klass->is_obj_array_klass() ) { | |
1166 ciKlass* k = TypeAryPtr::OOPS->klass(); | |
1167 if( !k || !k->is_loaded() ) // Only fails for some -Xcomp runs | |
1168 k = TypeInstPtr::BOTTOM->klass(); | |
1169 tj = tk = TypeKlassPtr::make( TypePtr::NotNull, k, offset ); | |
1170 } | |
1171 | |
1172 // Check for precise loads from the primary supertype array and force them | |
1173 // to the supertype cache alias index. Check for generic array loads from | |
1174 // the primary supertype array and also force them to the supertype cache | |
1175 // alias index. Since the same load can reach both, we need to merge | |
1176 // these 2 disparate memories into the same alias class. Since the | |
1177 // primary supertype array is read-only, there's no chance of confusion | |
1178 // where we bypass an array load and an array store. | |
1179 uint off2 = offset - Klass::primary_supers_offset_in_bytes(); | |
1180 if( offset == Type::OffsetBot || | |
1181 off2 < Klass::primary_super_limit()*wordSize ) { | |
1182 offset = sizeof(oopDesc) +Klass::secondary_super_cache_offset_in_bytes(); | |
1183 tj = tk = TypeKlassPtr::make( TypePtr::NotNull, tk->klass(), offset ); | |
1184 } | |
1185 } | |
1186 | |
1187 // Flatten all Raw pointers together. | |
1188 if (tj->base() == Type::RawPtr) | |
1189 tj = TypeRawPtr::BOTTOM; | |
1190 | |
1191 if (tj->base() == Type::AnyPtr) | |
1192 tj = TypePtr::BOTTOM; // An error, which the caller must check for. | |
1193 | |
1194 // Flatten all to bottom for now | |
1195 switch( _AliasLevel ) { | |
1196 case 0: | |
1197 tj = TypePtr::BOTTOM; | |
1198 break; | |
1199 case 1: // Flatten to: oop, static, field or array | |
1200 switch (tj->base()) { | |
1201 //case Type::AryPtr: tj = TypeAryPtr::RANGE; break; | |
1202 case Type::RawPtr: tj = TypeRawPtr::BOTTOM; break; | |
1203 case Type::AryPtr: // do not distinguish arrays at all | |
1204 case Type::InstPtr: tj = TypeInstPtr::BOTTOM; break; | |
1205 case Type::KlassPtr: tj = TypeKlassPtr::OBJECT; break; | |
1206 case Type::AnyPtr: tj = TypePtr::BOTTOM; break; // caller checks it | |
1207 default: ShouldNotReachHere(); | |
1208 } | |
1209 break; | |
605 | 1210 case 2: // No collapsing at level 2; keep all splits |
1211 case 3: // No collapsing at level 3; keep all splits | |
0 | 1212 break; |
1213 default: | |
1214 Unimplemented(); | |
1215 } | |
1216 | |
1217 offset = tj->offset(); | |
1218 assert( offset != Type::OffsetTop, "Offset has fallen from constant" ); | |
1219 | |
1220 assert( (offset != Type::OffsetBot && tj->base() != Type::AryPtr) || | |
1221 (offset == Type::OffsetBot && tj->base() == Type::AryPtr) || | |
1222 (offset == Type::OffsetBot && tj == TypeOopPtr::BOTTOM) || | |
1223 (offset == Type::OffsetBot && tj == TypePtr::BOTTOM) || | |
1224 (offset == oopDesc::mark_offset_in_bytes() && tj->base() == Type::AryPtr) || | |
1225 (offset == oopDesc::klass_offset_in_bytes() && tj->base() == Type::AryPtr) || | |
1226 (offset == arrayOopDesc::length_offset_in_bytes() && tj->base() == Type::AryPtr) , | |
1227 "For oops, klasses, raw offset must be constant; for arrays the offset is never known" ); | |
1228 assert( tj->ptr() != TypePtr::TopPTR && | |
1229 tj->ptr() != TypePtr::AnyNull && | |
1230 tj->ptr() != TypePtr::Null, "No imprecise addresses" ); | |
1231 // assert( tj->ptr() != TypePtr::Constant || | |
1232 // tj->base() == Type::RawPtr || | |
1233 // tj->base() == Type::KlassPtr, "No constant oop addresses" ); | |
1234 | |
1235 return tj; | |
1236 } | |
1237 | |
1238 void Compile::AliasType::Init(int i, const TypePtr* at) { | |
1239 _index = i; | |
1240 _adr_type = at; | |
1241 _field = NULL; | |
1242 _is_rewritable = true; // default | |
1243 const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL; | |
223 | 1244 if (atoop != NULL && atoop->is_known_instance()) { |
1245 const TypeOopPtr *gt = atoop->cast_to_instance_id(TypeOopPtr::InstanceBot); | |
0 | 1246 _general_index = Compile::current()->get_alias_index(gt); |
1247 } else { | |
1248 _general_index = 0; | |
1249 } | |
1250 } | |
1251 | |
1252 //---------------------------------print_on------------------------------------ | |
1253 #ifndef PRODUCT | |
1254 void Compile::AliasType::print_on(outputStream* st) { | |
1255 if (index() < 10) | |
1256 st->print("@ <%d> ", index()); | |
1257 else st->print("@ <%d>", index()); | |
1258 st->print(is_rewritable() ? " " : " RO"); | |
1259 int offset = adr_type()->offset(); | |
1260 if (offset == Type::OffsetBot) | |
1261 st->print(" +any"); | |
1262 else st->print(" +%-3d", offset); | |
1263 st->print(" in "); | |
1264 adr_type()->dump_on(st); | |
1265 const TypeOopPtr* tjp = adr_type()->isa_oopptr(); | |
1266 if (field() != NULL && tjp) { | |
1267 if (tjp->klass() != field()->holder() || | |
1268 tjp->offset() != field()->offset_in_bytes()) { | |
1269 st->print(" != "); | |
1270 field()->print(); | |
1271 st->print(" ***"); | |
1272 } | |
1273 } | |
1274 } | |
1275 | |
1276 void print_alias_types() { | |
1277 Compile* C = Compile::current(); | |
1278 tty->print_cr("--- Alias types, AliasIdxBot .. %d", C->num_alias_types()-1); | |
1279 for (int idx = Compile::AliasIdxBot; idx < C->num_alias_types(); idx++) { | |
1280 C->alias_type(idx)->print_on(tty); | |
1281 tty->cr(); | |
1282 } | |
1283 } | |
1284 #endif | |
1285 | |
1286 | |
1287 //----------------------------probe_alias_cache-------------------------------- | |
1288 Compile::AliasCacheEntry* Compile::probe_alias_cache(const TypePtr* adr_type) { | |
1289 intptr_t key = (intptr_t) adr_type; | |
1290 key ^= key >> logAliasCacheSize; | |
1291 return &_alias_cache[key & right_n_bits(logAliasCacheSize)]; | |
1292 } | |
1293 | |
1294 | |
1295 //-----------------------------grow_alias_types-------------------------------- | |
1296 void Compile::grow_alias_types() { | |
1297 const int old_ats = _max_alias_types; // how many before? | |
1298 const int new_ats = old_ats; // how many more? | |
1299 const int grow_ats = old_ats+new_ats; // how many now? | |
1300 _max_alias_types = grow_ats; | |
1301 _alias_types = REALLOC_ARENA_ARRAY(comp_arena(), AliasType*, _alias_types, old_ats, grow_ats); | |
1302 AliasType* ats = NEW_ARENA_ARRAY(comp_arena(), AliasType, new_ats); | |
1303 Copy::zero_to_bytes(ats, sizeof(AliasType)*new_ats); | |
1304 for (int i = 0; i < new_ats; i++) _alias_types[old_ats+i] = &ats[i]; | |
1305 } | |
1306 | |
1307 | |
1308 //--------------------------------find_alias_type------------------------------ | |
1309 Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_create) { | |
1310 if (_AliasLevel == 0) | |
1311 return alias_type(AliasIdxBot); | |
1312 | |
1313 AliasCacheEntry* ace = probe_alias_cache(adr_type); | |
1314 if (ace->_adr_type == adr_type) { | |
1315 return alias_type(ace->_index); | |
1316 } | |
1317 | |
1318 // Handle special cases. | |
1319 if (adr_type == NULL) return alias_type(AliasIdxTop); | |
1320 if (adr_type == TypePtr::BOTTOM) return alias_type(AliasIdxBot); | |
1321 | |
1322 // Do it the slow way. | |
1323 const TypePtr* flat = flatten_alias_type(adr_type); | |
1324 | |
1325 #ifdef ASSERT | |
1326 assert(flat == flatten_alias_type(flat), "idempotent"); | |
1327 assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr"); | |
1328 if (flat->isa_oopptr() && !flat->isa_klassptr()) { | |
1329 const TypeOopPtr* foop = flat->is_oopptr(); | |
247 | 1330 // Scalarizable allocations have exact klass always. |
1331 bool exact = !foop->klass_is_exact() || foop->is_known_instance(); | |
1332 const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr(); | |
0 | 1333 assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type"); |
1334 } | |
1335 assert(flat == flatten_alias_type(flat), "exact bit doesn't matter"); | |
1336 #endif | |
1337 | |
1338 int idx = AliasIdxTop; | |
1339 for (int i = 0; i < num_alias_types(); i++) { | |
1340 if (alias_type(i)->adr_type() == flat) { | |
1341 idx = i; | |
1342 break; | |
1343 } | |
1344 } | |
1345 | |
1346 if (idx == AliasIdxTop) { | |
1347 if (no_create) return NULL; | |
1348 // Grow the array if necessary. | |
1349 if (_num_alias_types == _max_alias_types) grow_alias_types(); | |
1350 // Add a new alias type. | |
1351 idx = _num_alias_types++; | |
1352 _alias_types[idx]->Init(idx, flat); | |
1353 if (flat == TypeInstPtr::KLASS) alias_type(idx)->set_rewritable(false); | |
1354 if (flat == TypeAryPtr::RANGE) alias_type(idx)->set_rewritable(false); | |
1355 if (flat->isa_instptr()) { | |
1356 if (flat->offset() == java_lang_Class::klass_offset_in_bytes() | |
1357 && flat->is_instptr()->klass() == env()->Class_klass()) | |
1358 alias_type(idx)->set_rewritable(false); | |
1359 } | |
1360 if (flat->isa_klassptr()) { | |
1361 if (flat->offset() == Klass::super_check_offset_offset_in_bytes() + (int)sizeof(oopDesc)) | |
1362 alias_type(idx)->set_rewritable(false); | |
1363 if (flat->offset() == Klass::modifier_flags_offset_in_bytes() + (int)sizeof(oopDesc)) | |
1364 alias_type(idx)->set_rewritable(false); | |
1365 if (flat->offset() == Klass::access_flags_offset_in_bytes() + (int)sizeof(oopDesc)) | |
1366 alias_type(idx)->set_rewritable(false); | |
1367 if (flat->offset() == Klass::java_mirror_offset_in_bytes() + (int)sizeof(oopDesc)) | |
1368 alias_type(idx)->set_rewritable(false); | |
1369 } | |
1370 // %%% (We would like to finalize JavaThread::threadObj_offset(), | |
1371 // but the base pointer type is not distinctive enough to identify | |
1372 // references into JavaThread.) | |
1373 | |
1374 // Check for final instance fields. | |
1375 const TypeInstPtr* tinst = flat->isa_instptr(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1376 if (tinst && tinst->offset() >= instanceOopDesc::base_offset_in_bytes()) { |
0 | 1377 ciInstanceKlass *k = tinst->klass()->as_instance_klass(); |
1378 ciField* field = k->get_field_by_offset(tinst->offset(), false); | |
1379 // Set field() and is_rewritable() attributes. | |
1380 if (field != NULL) alias_type(idx)->set_field(field); | |
1381 } | |
1382 const TypeKlassPtr* tklass = flat->isa_klassptr(); | |
1383 // Check for final static fields. | |
1384 if (tklass && tklass->klass()->is_instance_klass()) { | |
1385 ciInstanceKlass *k = tklass->klass()->as_instance_klass(); | |
1386 ciField* field = k->get_field_by_offset(tklass->offset(), true); | |
1387 // Set field() and is_rewritable() attributes. | |
1388 if (field != NULL) alias_type(idx)->set_field(field); | |
1389 } | |
1390 } | |
1391 | |
1392 // Fill the cache for next time. | |
1393 ace->_adr_type = adr_type; | |
1394 ace->_index = idx; | |
1395 assert(alias_type(adr_type) == alias_type(idx), "type must be installed"); | |
1396 | |
1397 // Might as well try to fill the cache for the flattened version, too. | |
1398 AliasCacheEntry* face = probe_alias_cache(flat); | |
1399 if (face->_adr_type == NULL) { | |
1400 face->_adr_type = flat; | |
1401 face->_index = idx; | |
1402 assert(alias_type(flat) == alias_type(idx), "flat type must work too"); | |
1403 } | |
1404 | |
1405 return alias_type(idx); | |
1406 } | |
1407 | |
1408 | |
1409 Compile::AliasType* Compile::alias_type(ciField* field) { | |
1410 const TypeOopPtr* t; | |
1411 if (field->is_static()) | |
1412 t = TypeKlassPtr::make(field->holder()); | |
1413 else | |
1414 t = TypeOopPtr::make_from_klass_raw(field->holder()); | |
1415 AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes())); | |
1416 assert(field->is_final() == !atp->is_rewritable(), "must get the rewritable bits correct"); | |
1417 return atp; | |
1418 } | |
1419 | |
1420 | |
1421 //------------------------------have_alias_type-------------------------------- | |
1422 bool Compile::have_alias_type(const TypePtr* adr_type) { | |
1423 AliasCacheEntry* ace = probe_alias_cache(adr_type); | |
1424 if (ace->_adr_type == adr_type) { | |
1425 return true; | |
1426 } | |
1427 | |
1428 // Handle special cases. | |
1429 if (adr_type == NULL) return true; | |
1430 if (adr_type == TypePtr::BOTTOM) return true; | |
1431 | |
1432 return find_alias_type(adr_type, true) != NULL; | |
1433 } | |
1434 | |
1435 //-----------------------------must_alias-------------------------------------- | |
1436 // True if all values of the given address type are in the given alias category. | |
1437 bool Compile::must_alias(const TypePtr* adr_type, int alias_idx) { | |
1438 if (alias_idx == AliasIdxBot) return true; // the universal category | |
1439 if (adr_type == NULL) return true; // NULL serves as TypePtr::TOP | |
1440 if (alias_idx == AliasIdxTop) return false; // the empty category | |
1441 if (adr_type->base() == Type::AnyPtr) return false; // TypePtr::BOTTOM or its twins | |
1442 | |
1443 // the only remaining possible overlap is identity | |
1444 int adr_idx = get_alias_index(adr_type); | |
1445 assert(adr_idx != AliasIdxBot && adr_idx != AliasIdxTop, ""); | |
1446 assert(adr_idx == alias_idx || | |
1447 (alias_type(alias_idx)->adr_type() != TypeOopPtr::BOTTOM | |
1448 && adr_type != TypeOopPtr::BOTTOM), | |
1449 "should not be testing for overlap with an unsafe pointer"); | |
1450 return adr_idx == alias_idx; | |
1451 } | |
1452 | |
1453 //------------------------------can_alias-------------------------------------- | |
1454 // True if any values of the given address type are in the given alias category. | |
1455 bool Compile::can_alias(const TypePtr* adr_type, int alias_idx) { | |
1456 if (alias_idx == AliasIdxTop) return false; // the empty category | |
1457 if (adr_type == NULL) return false; // NULL serves as TypePtr::TOP | |
1458 if (alias_idx == AliasIdxBot) return true; // the universal category | |
1459 if (adr_type->base() == Type::AnyPtr) return true; // TypePtr::BOTTOM or its twins | |
1460 | |
1461 // the only remaining possible overlap is identity | |
1462 int adr_idx = get_alias_index(adr_type); | |
1463 assert(adr_idx != AliasIdxBot && adr_idx != AliasIdxTop, ""); | |
1464 return adr_idx == alias_idx; | |
1465 } | |
1466 | |
1467 | |
1468 | |
1469 //---------------------------pop_warm_call------------------------------------- | |
1470 WarmCallInfo* Compile::pop_warm_call() { | |
1471 WarmCallInfo* wci = _warm_calls; | |
1472 if (wci != NULL) _warm_calls = wci->remove_from(wci); | |
1473 return wci; | |
1474 } | |
1475 | |
1476 //----------------------------Inline_Warm-------------------------------------- | |
1477 int Compile::Inline_Warm() { | |
1478 // If there is room, try to inline some more warm call sites. | |
1479 // %%% Do a graph index compaction pass when we think we're out of space? | |
1480 if (!InlineWarmCalls) return 0; | |
1481 | |
1482 int calls_made_hot = 0; | |
1483 int room_to_grow = NodeCountInliningCutoff - unique(); | |
1484 int amount_to_grow = MIN2(room_to_grow, (int)NodeCountInliningStep); | |
1485 int amount_grown = 0; | |
1486 WarmCallInfo* call; | |
1487 while (amount_to_grow > 0 && (call = pop_warm_call()) != NULL) { | |
1488 int est_size = (int)call->size(); | |
1489 if (est_size > (room_to_grow - amount_grown)) { | |
1490 // This one won't fit anyway. Get rid of it. | |
1491 call->make_cold(); | |
1492 continue; | |
1493 } | |
1494 call->make_hot(); | |
1495 calls_made_hot++; | |
1496 amount_grown += est_size; | |
1497 amount_to_grow -= est_size; | |
1498 } | |
1499 | |
1500 if (calls_made_hot > 0) set_major_progress(); | |
1501 return calls_made_hot; | |
1502 } | |
1503 | |
1504 | |
1505 //----------------------------Finish_Warm-------------------------------------- | |
1506 void Compile::Finish_Warm() { | |
1507 if (!InlineWarmCalls) return; | |
1508 if (failing()) return; | |
1509 if (warm_calls() == NULL) return; | |
1510 | |
1511 // Clean up loose ends, if we are out of space for inlining. | |
1512 WarmCallInfo* call; | |
1513 while ((call = pop_warm_call()) != NULL) { | |
1514 call->make_cold(); | |
1515 } | |
1516 } | |
1517 | |
1172 | 1518 //---------------------cleanup_loop_predicates----------------------- |
1519 // Remove the opaque nodes that protect the predicates so that all unused | |
1520 // checks and uncommon_traps will be eliminated from the ideal graph | |
1521 void Compile::cleanup_loop_predicates(PhaseIterGVN &igvn) { | |
1522 if (predicate_count()==0) return; | |
1523 for (int i = predicate_count(); i > 0; i--) { | |
1524 Node * n = predicate_opaque1_node(i-1); | |
1525 assert(n->Opcode() == Op_Opaque1, "must be"); | |
1526 igvn.replace_node(n, n->in(1)); | |
1527 } | |
1528 assert(predicate_count()==0, "should be clean!"); | |
1529 igvn.optimize(); | |
1530 } | |
0 | 1531 |
1532 //------------------------------Optimize--------------------------------------- | |
1533 // Given a graph, optimize it. | |
1534 void Compile::Optimize() { | |
1535 TracePhase t1("optimizer", &_t_optimizer, true); | |
1536 | |
1537 #ifndef PRODUCT | |
1538 if (env()->break_at_compile()) { | |
1539 BREAKPOINT; | |
1540 } | |
1541 | |
1542 #endif | |
1543 | |
1544 ResourceMark rm; | |
1545 int loop_opts_cnt; | |
1546 | |
1547 NOT_PRODUCT( verify_graph_edges(); ) | |
1548 | |
222 | 1549 print_method("After Parsing"); |
0 | 1550 |
1551 { | |
1552 // Iterative Global Value Numbering, including ideal transforms | |
1553 // Initialize IterGVN with types and values from parse-time GVN | |
1554 PhaseIterGVN igvn(initial_gvn()); | |
1555 { | |
1556 NOT_PRODUCT( TracePhase t2("iterGVN", &_t_iterGVN, TimeCompiler); ) | |
1557 igvn.optimize(); | |
1558 } | |
1559 | |
1560 print_method("Iter GVN 1", 2); | |
1561 | |
1562 if (failing()) return; | |
1563 | |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1564 // Perform escape analysis |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1565 if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1566 TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1567 ConnectionGraph::do_analysis(this, &igvn); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1568 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1569 if (failing()) return; |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1570 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1571 igvn.optimize(); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1572 print_method("Iter GVN 3", 2); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1573 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1574 if (failing()) return; |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1575 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1576 } |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1577 |
0 | 1578 // Loop transforms on the ideal graph. Range Check Elimination, |
1579 // peeling, unrolling, etc. | |
1580 | |
1581 // Set loop opts counter | |
1582 loop_opts_cnt = num_loop_opts(); | |
1583 if((loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) { | |
1584 { | |
1585 TracePhase t2("idealLoop", &_t_idealLoop, true); | |
1172 | 1586 PhaseIdealLoop ideal_loop( igvn, true, UseLoopPredicate); |
0 | 1587 loop_opts_cnt--; |
1588 if (major_progress()) print_method("PhaseIdealLoop 1", 2); | |
1589 if (failing()) return; | |
1590 } | |
1591 // Loop opts pass if partial peeling occurred in previous pass | |
1592 if(PartialPeelLoop && major_progress() && (loop_opts_cnt > 0)) { | |
1593 TracePhase t3("idealLoop", &_t_idealLoop, true); | |
1172 | 1594 PhaseIdealLoop ideal_loop( igvn, false, UseLoopPredicate); |
0 | 1595 loop_opts_cnt--; |
1596 if (major_progress()) print_method("PhaseIdealLoop 2", 2); | |
1597 if (failing()) return; | |
1598 } | |
1599 // Loop opts pass for loop-unrolling before CCP | |
1600 if(major_progress() && (loop_opts_cnt > 0)) { | |
1601 TracePhase t4("idealLoop", &_t_idealLoop, true); | |
1172 | 1602 PhaseIdealLoop ideal_loop( igvn, false, UseLoopPredicate); |
0 | 1603 loop_opts_cnt--; |
1604 if (major_progress()) print_method("PhaseIdealLoop 3", 2); | |
1605 } | |
921
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1606 if (!failing()) { |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1607 // Verify that last round of loop opts produced a valid graph |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1608 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1609 PhaseIdealLoop::verify(igvn); |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1610 } |
0 | 1611 } |
1612 if (failing()) return; | |
1613 | |
1614 // Conditional Constant Propagation; | |
1615 PhaseCCP ccp( &igvn ); | |
1616 assert( true, "Break here to ccp.dump_nodes_and_types(_root,999,1)"); | |
1617 { | |
1618 TracePhase t2("ccp", &_t_ccp, true); | |
1619 ccp.do_transform(); | |
1620 } | |
1621 print_method("PhaseCPP 1", 2); | |
1622 | |
1623 assert( true, "Break here to ccp.dump_old2new_map()"); | |
1624 | |
1625 // Iterative Global Value Numbering, including ideal transforms | |
1626 { | |
1627 NOT_PRODUCT( TracePhase t2("iterGVN2", &_t_iterGVN2, TimeCompiler); ) | |
1628 igvn = ccp; | |
1629 igvn.optimize(); | |
1630 } | |
1631 | |
1632 print_method("Iter GVN 2", 2); | |
1633 | |
1634 if (failing()) return; | |
1635 | |
1636 // Loop transforms on the ideal graph. Range Check Elimination, | |
1637 // peeling, unrolling, etc. | |
1638 if(loop_opts_cnt > 0) { | |
1639 debug_only( int cnt = 0; ); | |
1172 | 1640 bool loop_predication = UseLoopPredicate; |
0 | 1641 while(major_progress() && (loop_opts_cnt > 0)) { |
1642 TracePhase t2("idealLoop", &_t_idealLoop, true); | |
1643 assert( cnt++ < 40, "infinite cycle in loop optimization" ); | |
1172 | 1644 PhaseIdealLoop ideal_loop( igvn, true, loop_predication); |
0 | 1645 loop_opts_cnt--; |
1646 if (major_progress()) print_method("PhaseIdealLoop iterations", 2); | |
1647 if (failing()) return; | |
1172 | 1648 // Perform loop predication optimization during first iteration after CCP. |
1649 // After that switch it off and cleanup unused loop predicates. | |
1650 if (loop_predication) { | |
1651 loop_predication = false; | |
1652 cleanup_loop_predicates(igvn); | |
1653 if (failing()) return; | |
1654 } | |
0 | 1655 } |
1656 } | |
921
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1657 |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1658 { |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1659 // Verify that all previous optimizations produced a valid graph |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1660 // at least to this point, even if no loop optimizations were done. |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1661 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1662 PhaseIdealLoop::verify(igvn); |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1663 } |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1664 |
0 | 1665 { |
1666 NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); ) | |
1667 PhaseMacroExpand mex(igvn); | |
1668 if (mex.expand_macro_nodes()) { | |
1669 assert(failing(), "must bail out w/ explicit message"); | |
1670 return; | |
1671 } | |
1672 } | |
1673 | |
1674 } // (End scope of igvn; run destructor if necessary for asserts.) | |
1675 | |
1676 // A method with only infinite loops has no edges entering loops from root | |
1677 { | |
1678 NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); ) | |
1679 if (final_graph_reshaping()) { | |
1680 assert(failing(), "must bail out w/ explicit message"); | |
1681 return; | |
1682 } | |
1683 } | |
1684 | |
1685 print_method("Optimize finished", 2); | |
1686 } | |
1687 | |
1688 | |
1689 //------------------------------Code_Gen--------------------------------------- | |
1690 // Given a graph, generate code for it | |
1691 void Compile::Code_Gen() { | |
1692 if (failing()) return; | |
1693 | |
1694 // Perform instruction selection. You might think we could reclaim Matcher | |
1695 // memory PDQ, but actually the Matcher is used in generating spill code. | |
1696 // Internals of the Matcher (including some VectorSets) must remain live | |
1697 // for awhile - thus I cannot reclaim Matcher memory lest a VectorSet usage | |
1698 // set a bit in reclaimed memory. | |
1699 | |
1700 // In debug mode can dump m._nodes.dump() for mapping of ideal to machine | |
1701 // nodes. Mapping is only valid at the root of each matched subtree. | |
1702 NOT_PRODUCT( verify_graph_edges(); ) | |
1703 | |
1704 Node_List proj_list; | |
1705 Matcher m(proj_list); | |
1706 _matcher = &m; | |
1707 { | |
1708 TracePhase t2("matcher", &_t_matcher, true); | |
1709 m.match(); | |
1710 } | |
1711 // In debug mode can dump m._nodes.dump() for mapping of ideal to machine | |
1712 // nodes. Mapping is only valid at the root of each matched subtree. | |
1713 NOT_PRODUCT( verify_graph_edges(); ) | |
1714 | |
1715 // If you have too many nodes, or if matching has failed, bail out | |
1716 check_node_count(0, "out of nodes matching instructions"); | |
1717 if (failing()) return; | |
1718 | |
1719 // Build a proper-looking CFG | |
1720 PhaseCFG cfg(node_arena(), root(), m); | |
1721 _cfg = &cfg; | |
1722 { | |
1723 NOT_PRODUCT( TracePhase t2("scheduler", &_t_scheduler, TimeCompiler); ) | |
1724 cfg.Dominators(); | |
1725 if (failing()) return; | |
1726 | |
1727 NOT_PRODUCT( verify_graph_edges(); ) | |
1728 | |
1729 cfg.Estimate_Block_Frequency(); | |
1730 cfg.GlobalCodeMotion(m,unique(),proj_list); | |
1731 | |
1732 print_method("Global code motion", 2); | |
1733 | |
1734 if (failing()) return; | |
1735 NOT_PRODUCT( verify_graph_edges(); ) | |
1736 | |
1737 debug_only( cfg.verify(); ) | |
1738 } | |
1739 NOT_PRODUCT( verify_graph_edges(); ) | |
1740 | |
1741 PhaseChaitin regalloc(unique(),cfg,m); | |
1742 _regalloc = ®alloc; | |
1743 { | |
1744 TracePhase t2("regalloc", &_t_registerAllocation, true); | |
1745 // Perform any platform dependent preallocation actions. This is used, | |
1746 // for example, to avoid taking an implicit null pointer exception | |
1747 // using the frame pointer on win95. | |
1748 _regalloc->pd_preallocate_hook(); | |
1749 | |
1750 // Perform register allocation. After Chaitin, use-def chains are | |
1751 // no longer accurate (at spill code) and so must be ignored. | |
1752 // Node->LRG->reg mappings are still accurate. | |
1753 _regalloc->Register_Allocate(); | |
1754 | |
1755 // Bail out if the allocator builds too many nodes | |
1756 if (failing()) return; | |
1757 } | |
1758 | |
1759 // Prior to register allocation we kept empty basic blocks in case the | |
1760 // the allocator needed a place to spill. After register allocation we | |
1761 // are not adding any new instructions. If any basic block is empty, we | |
1762 // can now safely remove it. | |
1763 { | |
418 | 1764 NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); ) |
1765 cfg.remove_empty(); | |
1766 if (do_freq_based_layout()) { | |
1767 PhaseBlockLayout layout(cfg); | |
1768 } else { | |
1769 cfg.set_loop_alignment(); | |
1770 } | |
1771 cfg.fixup_flow(); | |
0 | 1772 } |
1773 | |
1774 // Perform any platform dependent postallocation verifications. | |
1775 debug_only( _regalloc->pd_postallocate_verify_hook(); ) | |
1776 | |
1777 // Apply peephole optimizations | |
1778 if( OptoPeephole ) { | |
1779 NOT_PRODUCT( TracePhase t2("peephole", &_t_peephole, TimeCompiler); ) | |
1780 PhasePeephole peep( _regalloc, cfg); | |
1781 peep.do_transform(); | |
1782 } | |
1783 | |
1784 // Convert Nodes to instruction bits in a buffer | |
1785 { | |
1786 // %%%% workspace merge brought two timers together for one job | |
1787 TracePhase t2a("output", &_t_output, true); | |
1788 NOT_PRODUCT( TraceTime t2b(NULL, &_t_codeGeneration, TimeCompiler, false); ) | |
1789 Output(); | |
1790 } | |
1791 | |
222 | 1792 print_method("Final Code"); |
0 | 1793 |
1794 // He's dead, Jim. | |
1795 _cfg = (PhaseCFG*)0xdeadbeef; | |
1796 _regalloc = (PhaseChaitin*)0xdeadbeef; | |
1797 } | |
1798 | |
1799 | |
1800 //------------------------------dump_asm--------------------------------------- | |
1801 // Dump formatted assembly | |
1802 #ifndef PRODUCT | |
1803 void Compile::dump_asm(int *pcs, uint pc_limit) { | |
1804 bool cut_short = false; | |
1805 tty->print_cr("#"); | |
1806 tty->print("# "); _tf->dump(); tty->cr(); | |
1807 tty->print_cr("#"); | |
1808 | |
1809 // For all blocks | |
1810 int pc = 0x0; // Program counter | |
1811 char starts_bundle = ' '; | |
1812 _regalloc->dump_frame(); | |
1813 | |
1814 Node *n = NULL; | |
1815 for( uint i=0; i<_cfg->_num_blocks; i++ ) { | |
1816 if (VMThread::should_terminate()) { cut_short = true; break; } | |
1817 Block *b = _cfg->_blocks[i]; | |
1818 if (b->is_connector() && !Verbose) continue; | |
1819 n = b->_nodes[0]; | |
1820 if (pcs && n->_idx < pc_limit) | |
1821 tty->print("%3.3x ", pcs[n->_idx]); | |
1822 else | |
1823 tty->print(" "); | |
1824 b->dump_head( &_cfg->_bbs ); | |
1825 if (b->is_connector()) { | |
1826 tty->print_cr(" # Empty connector block"); | |
1827 } else if (b->num_preds() == 2 && b->pred(1)->is_CatchProj() && b->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) { | |
1828 tty->print_cr(" # Block is sole successor of call"); | |
1829 } | |
1830 | |
1831 // For all instructions | |
1832 Node *delay = NULL; | |
1833 for( uint j = 0; j<b->_nodes.size(); j++ ) { | |
1834 if (VMThread::should_terminate()) { cut_short = true; break; } | |
1835 n = b->_nodes[j]; | |
1836 if (valid_bundle_info(n)) { | |
1837 Bundle *bundle = node_bundling(n); | |
1838 if (bundle->used_in_unconditional_delay()) { | |
1839 delay = n; | |
1840 continue; | |
1841 } | |
1842 if (bundle->starts_bundle()) | |
1843 starts_bundle = '+'; | |
1844 } | |
1845 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1846 if (WizardMode) n->dump(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1847 |
0 | 1848 if( !n->is_Region() && // Dont print in the Assembly |
1849 !n->is_Phi() && // a few noisely useless nodes | |
1850 !n->is_Proj() && | |
1851 !n->is_MachTemp() && | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
1852 !n->is_SafePointScalarObject() && |
0 | 1853 !n->is_Catch() && // Would be nice to print exception table targets |
1854 !n->is_MergeMem() && // Not very interesting | |
1855 !n->is_top() && // Debug info table constants | |
1856 !(n->is_Con() && !n->is_Mach())// Debug info table constants | |
1857 ) { | |
1858 if (pcs && n->_idx < pc_limit) | |
1859 tty->print("%3.3x", pcs[n->_idx]); | |
1860 else | |
1861 tty->print(" "); | |
1862 tty->print(" %c ", starts_bundle); | |
1863 starts_bundle = ' '; | |
1864 tty->print("\t"); | |
1865 n->format(_regalloc, tty); | |
1866 tty->cr(); | |
1867 } | |
1868 | |
1869 // If we have an instruction with a delay slot, and have seen a delay, | |
1870 // then back up and print it | |
1871 if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) { | |
1872 assert(delay != NULL, "no unconditional delay instruction"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1873 if (WizardMode) delay->dump(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1874 |
0 | 1875 if (node_bundling(delay)->starts_bundle()) |
1876 starts_bundle = '+'; | |
1877 if (pcs && n->_idx < pc_limit) | |
1878 tty->print("%3.3x", pcs[n->_idx]); | |
1879 else | |
1880 tty->print(" "); | |
1881 tty->print(" %c ", starts_bundle); | |
1882 starts_bundle = ' '; | |
1883 tty->print("\t"); | |
1884 delay->format(_regalloc, tty); | |
1885 tty->print_cr(""); | |
1886 delay = NULL; | |
1887 } | |
1888 | |
1889 // Dump the exception table as well | |
1890 if( n->is_Catch() && (Verbose || WizardMode) ) { | |
1891 // Print the exception table for this offset | |
1892 _handler_table.print_subtable_for(pc); | |
1893 } | |
1894 } | |
1895 | |
1896 if (pcs && n->_idx < pc_limit) | |
1897 tty->print_cr("%3.3x", pcs[n->_idx]); | |
1898 else | |
1899 tty->print_cr(""); | |
1900 | |
1901 assert(cut_short || delay == NULL, "no unconditional delay branch"); | |
1902 | |
1903 } // End of per-block dump | |
1904 tty->print_cr(""); | |
1905 | |
1906 if (cut_short) tty->print_cr("*** disassembly is cut short ***"); | |
1907 } | |
1908 #endif | |
1909 | |
1910 //------------------------------Final_Reshape_Counts--------------------------- | |
1911 // This class defines counters to help identify when a method | |
1912 // may/must be executed using hardware with only 24-bit precision. | |
1913 struct Final_Reshape_Counts : public StackObj { | |
1914 int _call_count; // count non-inlined 'common' calls | |
1915 int _float_count; // count float ops requiring 24-bit precision | |
1916 int _double_count; // count double ops requiring more precision | |
1917 int _java_call_count; // count non-inlined 'java' calls | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
1918 int _inner_loop_count; // count loops which need alignment |
0 | 1919 VectorSet _visited; // Visitation flags |
1920 Node_List _tests; // Set of IfNodes & PCTableNodes | |
1921 | |
1922 Final_Reshape_Counts() : | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
1923 _call_count(0), _float_count(0), _double_count(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
1924 _java_call_count(0), _inner_loop_count(0), |
0 | 1925 _visited( Thread::current()->resource_area() ) { } |
1926 | |
1927 void inc_call_count () { _call_count ++; } | |
1928 void inc_float_count () { _float_count ++; } | |
1929 void inc_double_count() { _double_count++; } | |
1930 void inc_java_call_count() { _java_call_count++; } | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
1931 void inc_inner_loop_count() { _inner_loop_count++; } |
0 | 1932 |
1933 int get_call_count () const { return _call_count ; } | |
1934 int get_float_count () const { return _float_count ; } | |
1935 int get_double_count() const { return _double_count; } | |
1936 int get_java_call_count() const { return _java_call_count; } | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
1937 int get_inner_loop_count() const { return _inner_loop_count; } |
0 | 1938 }; |
1939 | |
1940 static bool oop_offset_is_sane(const TypeInstPtr* tp) { | |
1941 ciInstanceKlass *k = tp->klass()->as_instance_klass(); | |
1942 // Make sure the offset goes inside the instance layout. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1943 return k->contains_field_offset(tp->offset()); |
0 | 1944 // Note that OffsetBot and OffsetTop are very negative. |
1945 } | |
1946 | |
1947 //------------------------------final_graph_reshaping_impl---------------------- | |
1948 // Implement items 1-5 from final_graph_reshaping below. | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
1949 static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) { |
0 | 1950 |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
1951 if ( n->outcnt() == 0 ) return; // dead node |
0 | 1952 uint nop = n->Opcode(); |
1953 | |
1954 // Check for 2-input instruction with "last use" on right input. | |
1955 // Swap to left input. Implements item (2). | |
1956 if( n->req() == 3 && // two-input instruction | |
1957 n->in(1)->outcnt() > 1 && // left use is NOT a last use | |
1958 (!n->in(1)->is_Phi() || n->in(1)->in(2) != n) && // it is not data loop | |
1959 n->in(2)->outcnt() == 1 &&// right use IS a last use | |
1960 !n->in(2)->is_Con() ) { // right use is not a constant | |
1961 // Check for commutative opcode | |
1962 switch( nop ) { | |
1963 case Op_AddI: case Op_AddF: case Op_AddD: case Op_AddL: | |
1964 case Op_MaxI: case Op_MinI: | |
1965 case Op_MulI: case Op_MulF: case Op_MulD: case Op_MulL: | |
1966 case Op_AndL: case Op_XorL: case Op_OrL: | |
1967 case Op_AndI: case Op_XorI: case Op_OrI: { | |
1968 // Move "last use" input to left by swapping inputs | |
1969 n->swap_edges(1, 2); | |
1970 break; | |
1971 } | |
1972 default: | |
1973 break; | |
1974 } | |
1975 } | |
1976 | |
1609 | 1977 #ifdef ASSERT |
1978 if( n->is_Mem() ) { | |
1979 Compile* C = Compile::current(); | |
1980 int alias_idx = C->get_alias_index(n->as_Mem()->adr_type()); | |
1981 assert( n->in(0) != NULL || alias_idx != Compile::AliasIdxRaw || | |
1982 // oop will be recorded in oop map if load crosses safepoint | |
1983 n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() || | |
1984 LoadNode::is_immutable_value(n->in(MemNode::Address))), | |
1985 "raw memory operations should have control edge"); | |
1986 } | |
1987 #endif | |
0 | 1988 // Count FPU ops and common calls, implements item (3) |
1989 switch( nop ) { | |
1990 // Count all float operations that may use FPU | |
1991 case Op_AddF: | |
1992 case Op_SubF: | |
1993 case Op_MulF: | |
1994 case Op_DivF: | |
1995 case Op_NegF: | |
1996 case Op_ModF: | |
1997 case Op_ConvI2F: | |
1998 case Op_ConF: | |
1999 case Op_CmpF: | |
2000 case Op_CmpF3: | |
2001 // case Op_ConvL2F: // longs are split into 32-bit halves | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2002 frc.inc_float_count(); |
0 | 2003 break; |
2004 | |
2005 case Op_ConvF2D: | |
2006 case Op_ConvD2F: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2007 frc.inc_float_count(); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2008 frc.inc_double_count(); |
0 | 2009 break; |
2010 | |
2011 // Count all double operations that may use FPU | |
2012 case Op_AddD: | |
2013 case Op_SubD: | |
2014 case Op_MulD: | |
2015 case Op_DivD: | |
2016 case Op_NegD: | |
2017 case Op_ModD: | |
2018 case Op_ConvI2D: | |
2019 case Op_ConvD2I: | |
2020 // case Op_ConvL2D: // handled by leaf call | |
2021 // case Op_ConvD2L: // handled by leaf call | |
2022 case Op_ConD: | |
2023 case Op_CmpD: | |
2024 case Op_CmpD3: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2025 frc.inc_double_count(); |
0 | 2026 break; |
2027 case Op_Opaque1: // Remove Opaque Nodes before matching | |
2028 case Op_Opaque2: // Remove Opaque Nodes before matching | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2029 n->subsume_by(n->in(1)); |
0 | 2030 break; |
2031 case Op_CallStaticJava: | |
2032 case Op_CallJava: | |
2033 case Op_CallDynamicJava: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2034 frc.inc_java_call_count(); // Count java call site; |
0 | 2035 case Op_CallRuntime: |
2036 case Op_CallLeaf: | |
2037 case Op_CallLeafNoFP: { | |
2038 assert( n->is_Call(), "" ); | |
2039 CallNode *call = n->as_Call(); | |
2040 // Count call sites where the FP mode bit would have to be flipped. | |
2041 // Do not count uncommon runtime calls: | |
2042 // uncommon_trap, _complete_monitor_locking, _complete_monitor_unlocking, | |
2043 // _new_Java, _new_typeArray, _new_objArray, _rethrow_Java, ... | |
2044 if( !call->is_CallStaticJava() || !call->as_CallStaticJava()->_name ) { | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2045 frc.inc_call_count(); // Count the call site |
0 | 2046 } else { // See if uncommon argument is shared |
2047 Node *n = call->in(TypeFunc::Parms); | |
2048 int nop = n->Opcode(); | |
2049 // Clone shared simple arguments to uncommon calls, item (1). | |
2050 if( n->outcnt() > 1 && | |
2051 !n->is_Proj() && | |
2052 nop != Op_CreateEx && | |
2053 nop != Op_CheckCastPP && | |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2054 nop != Op_DecodeN && |
0 | 2055 !n->is_Mem() ) { |
2056 Node *x = n->clone(); | |
2057 call->set_req( TypeFunc::Parms, x ); | |
2058 } | |
2059 } | |
2060 break; | |
2061 } | |
2062 | |
2063 case Op_StoreD: | |
2064 case Op_LoadD: | |
2065 case Op_LoadD_unaligned: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2066 frc.inc_double_count(); |
0 | 2067 goto handle_mem; |
2068 case Op_StoreF: | |
2069 case Op_LoadF: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2070 frc.inc_float_count(); |
0 | 2071 goto handle_mem; |
2072 | |
2073 case Op_StoreB: | |
2074 case Op_StoreC: | |
2075 case Op_StoreCM: | |
2076 case Op_StorePConditional: | |
2077 case Op_StoreI: | |
2078 case Op_StoreL: | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
418
diff
changeset
|
2079 case Op_StoreIConditional: |
0 | 2080 case Op_StoreLConditional: |
2081 case Op_CompareAndSwapI: | |
2082 case Op_CompareAndSwapL: | |
2083 case Op_CompareAndSwapP: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2084 case Op_CompareAndSwapN: |
0 | 2085 case Op_StoreP: |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2086 case Op_StoreN: |
0 | 2087 case Op_LoadB: |
624 | 2088 case Op_LoadUB: |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
492
diff
changeset
|
2089 case Op_LoadUS: |
0 | 2090 case Op_LoadI: |
624 | 2091 case Op_LoadUI2L: |
0 | 2092 case Op_LoadKlass: |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2093 case Op_LoadNKlass: |
0 | 2094 case Op_LoadL: |
2095 case Op_LoadL_unaligned: | |
2096 case Op_LoadPLocked: | |
2097 case Op_LoadLLocked: | |
2098 case Op_LoadP: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2099 case Op_LoadN: |
0 | 2100 case Op_LoadRange: |
2101 case Op_LoadS: { | |
2102 handle_mem: | |
2103 #ifdef ASSERT | |
2104 if( VerifyOptoOopOffsets ) { | |
2105 assert( n->is_Mem(), "" ); | |
2106 MemNode *mem = (MemNode*)n; | |
2107 // Check to see if address types have grounded out somehow. | |
2108 const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr(); | |
2109 assert( !tp || oop_offset_is_sane(tp), "" ); | |
2110 } | |
2111 #endif | |
2112 break; | |
2113 } | |
2114 | |
2115 case Op_AddP: { // Assert sane base pointers | |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2116 Node *addp = n->in(AddPNode::Address); |
0 | 2117 assert( !addp->is_AddP() || |
2118 addp->in(AddPNode::Base)->is_top() || // Top OK for allocation | |
2119 addp->in(AddPNode::Base) == n->in(AddPNode::Base), | |
2120 "Base pointers must match" ); | |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2121 #ifdef _LP64 |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2122 if (UseCompressedOops && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2123 addp->Opcode() == Op_ConP && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2124 addp == n->in(AddPNode::Base) && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2125 n->in(AddPNode::Offset)->is_Con()) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2126 // Use addressing with narrow klass to load with offset on x86. |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2127 // On sparc loading 32-bits constant and decoding it have less |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2128 // instructions (4) then load 64-bits constant (7). |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2129 // Do this transformation here since IGVN will convert ConN back to ConP. |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2130 const Type* t = addp->bottom_type(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2131 if (t->isa_oopptr()) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2132 Node* nn = NULL; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2133 |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2134 // Look for existing ConN node of the same exact type. |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2135 Compile* C = Compile::current(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2136 Node* r = C->root(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2137 uint cnt = r->outcnt(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2138 for (uint i = 0; i < cnt; i++) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2139 Node* m = r->raw_out(i); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2140 if (m!= NULL && m->Opcode() == Op_ConN && |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
182
diff
changeset
|
2141 m->bottom_type()->make_ptr() == t) { |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2142 nn = m; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2143 break; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2144 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2145 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2146 if (nn != NULL) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2147 // Decode a narrow oop to match address |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2148 // [R12 + narrow_oop_reg<<3 + offset] |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2149 nn = new (C, 2) DecodeNNode(nn, t); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2150 n->set_req(AddPNode::Base, nn); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2151 n->set_req(AddPNode::Address, nn); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2152 if (addp->outcnt() == 0) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2153 addp->disconnect_inputs(NULL); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2154 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2155 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2156 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2157 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2158 #endif |
0 | 2159 break; |
2160 } | |
2161 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2162 #ifdef _LP64 |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2163 case Op_CastPP: |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2164 if (n->in(1)->is_DecodeN() && Matcher::gen_narrow_oop_implicit_null_checks()) { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2165 Compile* C = Compile::current(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2166 Node* in1 = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2167 const Type* t = n->bottom_type(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2168 Node* new_in1 = in1->clone(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2169 new_in1->as_DecodeN()->set_type(t); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2170 |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2171 if (!Matcher::narrow_oop_use_complex_address()) { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2172 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2173 // x86, ARM and friends can handle 2 adds in addressing mode |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2174 // and Matcher can fold a DecodeN node into address by using |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2175 // a narrow oop directly and do implicit NULL check in address: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2176 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2177 // [R12 + narrow_oop_reg<<3 + offset] |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2178 // NullCheck narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2179 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2180 // On other platforms (Sparc) we have to keep new DecodeN node and |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2181 // use it to do implicit NULL check in address: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2182 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2183 // decode_not_null narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2184 // [base_reg + offset] |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2185 // NullCheck base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2186 // |
605 | 2187 // Pin the new DecodeN node to non-null path on these platform (Sparc) |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2188 // to keep the information to which NULL check the new DecodeN node |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2189 // corresponds to use it as value in implicit_null_check(). |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2190 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2191 new_in1->set_req(0, n->in(0)); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2192 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2193 |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2194 n->subsume_by(new_in1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2195 if (in1->outcnt() == 0) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2196 in1->disconnect_inputs(NULL); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2197 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2198 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2199 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2200 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2201 case Op_CmpP: |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2202 // Do this transformation here to preserve CmpPNode::sub() and |
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2203 // other TypePtr related Ideal optimizations (for example, ptr nullness). |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2204 if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2205 Node* in1 = n->in(1); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2206 Node* in2 = n->in(2); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2207 if (!in1->is_DecodeN()) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2208 in2 = in1; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2209 in1 = n->in(2); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2210 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2211 assert(in1->is_DecodeN(), "sanity"); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2212 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2213 Compile* C = Compile::current(); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2214 Node* new_in2 = NULL; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2215 if (in2->is_DecodeN()) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2216 new_in2 = in2->in(1); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2217 } else if (in2->Opcode() == Op_ConP) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2218 const Type* t = in2->bottom_type(); |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2219 if (t == TypePtr::NULL_PTR) { |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2220 // Don't convert CmpP null check into CmpN if compressed |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2221 // oops implicit null check is not generated. |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2222 // This will allow to generate normal oop implicit null check. |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2223 if (Matcher::gen_narrow_oop_implicit_null_checks()) |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2224 new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2225 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2226 // This transformation together with CastPP transformation above |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2227 // will generated code for implicit NULL checks for compressed oops. |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2228 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2229 // The original code after Optimize() |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2230 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2231 // LoadN memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2232 // decode narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2233 // CmpP base_reg, NULL |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2234 // CastPP base_reg // NotNull |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2235 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2236 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2237 // after these transformations will be |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2238 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2239 // LoadN memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2240 // CmpN narrow_oop_reg, NULL |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2241 // decode_not_null narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2242 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2243 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2244 // and the uncommon path (== NULL) will use narrow_oop_reg directly |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2245 // since narrow oops can be used in debug info now (see the code in |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2246 // final_graph_reshaping_walk()). |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2247 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2248 // At the end the code will be matched to |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2249 // on x86: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2250 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2251 // Load_narrow_oop memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2252 // Load [R12 + narrow_oop_reg<<3 + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2253 // NullCheck narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2254 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2255 // and on sparc: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2256 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2257 // Load_narrow_oop memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2258 // decode_not_null narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2259 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2260 // NullCheck base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2261 // |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2262 } else if (t->isa_oopptr()) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2263 new_in2 = ConNode::make(C, t->make_narrowoop()); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2264 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2265 } |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2266 if (new_in2 != NULL) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2267 Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2); |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2268 n->subsume_by( cmpN ); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2269 if (in1->outcnt() == 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2270 in1->disconnect_inputs(NULL); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2271 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2272 if (in2->outcnt() == 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2273 in2->disconnect_inputs(NULL); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2274 } |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2275 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2276 } |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
2277 break; |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2278 |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2279 case Op_DecodeN: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2280 assert(!n->in(1)->is_EncodeP(), "should be optimized out"); |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2281 // DecodeN could be pinned when it can't be fold into |
492
5496e074077f
6787050: assert(n->in(0) == 0L,"no control") with UseCompressedOops on sparcv9
kvn
parents:
490
diff
changeset
|
2282 // an address expression, see the code for Op_CastPP above. |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2283 assert(n->in(0) == NULL || !Matcher::narrow_oop_use_complex_address(), "no control"); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2284 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2285 |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2286 case Op_EncodeP: { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2287 Node* in1 = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2288 if (in1->is_DecodeN()) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2289 n->subsume_by(in1->in(1)); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2290 } else if (in1->Opcode() == Op_ConP) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2291 Compile* C = Compile::current(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2292 const Type* t = in1->bottom_type(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2293 if (t == TypePtr::NULL_PTR) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2294 n->subsume_by(ConNode::make(C, TypeNarrowOop::NULL_PTR)); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2295 } else if (t->isa_oopptr()) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2296 n->subsume_by(ConNode::make(C, t->make_narrowoop())); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2297 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2298 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2299 if (in1->outcnt() == 0) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2300 in1->disconnect_inputs(NULL); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2301 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2302 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2303 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2304 |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2305 case Op_Proj: { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2306 if (OptimizeStringConcat) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2307 ProjNode* p = n->as_Proj(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2308 if (p->_is_io_use) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2309 // Separate projections were used for the exception path which |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2310 // are normally removed by a late inline. If it wasn't inlined |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2311 // then they will hang around and should just be replaced with |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2312 // the original one. |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2313 Node* proj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2314 // Replace with just one |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2315 for (SimpleDUIterator i(p->in(0)); i.has_next(); i.next()) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2316 Node *use = i.get(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2317 if (use->is_Proj() && p != use && use->as_Proj()->_con == p->_con) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2318 proj = use; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2319 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2320 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2321 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2322 assert(p != NULL, "must be found"); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2323 p->subsume_by(proj); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2324 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2325 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2326 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2327 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2328 |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2329 case Op_Phi: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2330 if (n->as_Phi()->bottom_type()->isa_narrowoop()) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2331 // The EncodeP optimization may create Phi with the same edges |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2332 // for all paths. It is not handled well by Register Allocator. |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2333 Node* unique_in = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2334 assert(unique_in != NULL, ""); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2335 uint cnt = n->req(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2336 for (uint i = 2; i < cnt; i++) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2337 Node* m = n->in(i); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2338 assert(m != NULL, ""); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2339 if (unique_in != m) |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2340 unique_in = NULL; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2341 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2342 if (unique_in != NULL) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2343 n->subsume_by(unique_in); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2344 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2345 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2346 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2347 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2348 #endif |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2349 |
0 | 2350 case Op_ModI: |
2351 if (UseDivMod) { | |
2352 // Check if a%b and a/b both exist | |
2353 Node* d = n->find_similar(Op_DivI); | |
2354 if (d) { | |
2355 // Replace them with a fused divmod if supported | |
2356 Compile* C = Compile::current(); | |
2357 if (Matcher::has_match_rule(Op_DivModI)) { | |
2358 DivModINode* divmod = DivModINode::make(C, n); | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2359 d->subsume_by(divmod->div_proj()); |
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2360 n->subsume_by(divmod->mod_proj()); |
0 | 2361 } else { |
2362 // replace a%b with a-((a/b)*b) | |
2363 Node* mult = new (C, 3) MulINode(d, d->in(2)); | |
2364 Node* sub = new (C, 3) SubINode(d->in(1), mult); | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2365 n->subsume_by( sub ); |
0 | 2366 } |
2367 } | |
2368 } | |
2369 break; | |
2370 | |
2371 case Op_ModL: | |
2372 if (UseDivMod) { | |
2373 // Check if a%b and a/b both exist | |
2374 Node* d = n->find_similar(Op_DivL); | |
2375 if (d) { | |
2376 // Replace them with a fused divmod if supported | |
2377 Compile* C = Compile::current(); | |
2378 if (Matcher::has_match_rule(Op_DivModL)) { | |
2379 DivModLNode* divmod = DivModLNode::make(C, n); | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2380 d->subsume_by(divmod->div_proj()); |
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2381 n->subsume_by(divmod->mod_proj()); |
0 | 2382 } else { |
2383 // replace a%b with a-((a/b)*b) | |
2384 Node* mult = new (C, 3) MulLNode(d, d->in(2)); | |
2385 Node* sub = new (C, 3) SubLNode(d->in(1), mult); | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2386 n->subsume_by( sub ); |
0 | 2387 } |
2388 } | |
2389 } | |
2390 break; | |
2391 | |
2392 case Op_Load16B: | |
2393 case Op_Load8B: | |
2394 case Op_Load4B: | |
2395 case Op_Load8S: | |
2396 case Op_Load4S: | |
2397 case Op_Load2S: | |
2398 case Op_Load8C: | |
2399 case Op_Load4C: | |
2400 case Op_Load2C: | |
2401 case Op_Load4I: | |
2402 case Op_Load2I: | |
2403 case Op_Load2L: | |
2404 case Op_Load4F: | |
2405 case Op_Load2F: | |
2406 case Op_Load2D: | |
2407 case Op_Store16B: | |
2408 case Op_Store8B: | |
2409 case Op_Store4B: | |
2410 case Op_Store8C: | |
2411 case Op_Store4C: | |
2412 case Op_Store2C: | |
2413 case Op_Store4I: | |
2414 case Op_Store2I: | |
2415 case Op_Store2L: | |
2416 case Op_Store4F: | |
2417 case Op_Store2F: | |
2418 case Op_Store2D: | |
2419 break; | |
2420 | |
2421 case Op_PackB: | |
2422 case Op_PackS: | |
2423 case Op_PackC: | |
2424 case Op_PackI: | |
2425 case Op_PackF: | |
2426 case Op_PackL: | |
2427 case Op_PackD: | |
2428 if (n->req()-1 > 2) { | |
2429 // Replace many operand PackNodes with a binary tree for matching | |
2430 PackNode* p = (PackNode*) n; | |
2431 Node* btp = p->binaryTreePack(Compile::current(), 1, n->req()); | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2432 n->subsume_by(btp); |
0 | 2433 } |
2434 break; | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2435 case Op_Loop: |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2436 case Op_CountedLoop: |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2437 if (n->as_Loop()->is_inner_loop()) { |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2438 frc.inc_inner_loop_count(); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2439 } |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2440 break; |
0 | 2441 default: |
2442 assert( !n->is_Call(), "" ); | |
2443 assert( !n->is_Mem(), "" ); | |
2444 break; | |
2445 } | |
127 | 2446 |
2447 // Collect CFG split points | |
2448 if (n->is_MultiBranch()) | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2449 frc._tests.push(n); |
0 | 2450 } |
2451 | |
2452 //------------------------------final_graph_reshaping_walk--------------------- | |
2453 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), | |
2454 // requires that the walk visits a node's inputs before visiting the node. | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2455 static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &frc ) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2456 ResourceArea *area = Thread::current()->resource_area(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2457 Unique_Node_List sfpt(area); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2458 |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2459 frc._visited.set(root->_idx); // first, mark node as visited |
0 | 2460 uint cnt = root->req(); |
2461 Node *n = root; | |
2462 uint i = 0; | |
2463 while (true) { | |
2464 if (i < cnt) { | |
2465 // Place all non-visited non-null inputs onto stack | |
2466 Node* m = n->in(i); | |
2467 ++i; | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2468 if (m != NULL && !frc._visited.test_set(m->_idx)) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2469 if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2470 sfpt.push(m); |
0 | 2471 cnt = m->req(); |
2472 nstack.push(n, i); // put on stack parent and next input's index | |
2473 n = m; | |
2474 i = 0; | |
2475 } | |
2476 } else { | |
2477 // Now do post-visit work | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2478 final_graph_reshaping_impl( n, frc ); |
0 | 2479 if (nstack.is_empty()) |
2480 break; // finished | |
2481 n = nstack.node(); // Get node from stack | |
2482 cnt = n->req(); | |
2483 i = nstack.index(); | |
2484 nstack.pop(); // Shift to the next node on stack | |
2485 } | |
2486 } | |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2487 |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2488 // Skip next transformation if compressed oops are not used. |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2489 if (!UseCompressedOops || !Matcher::gen_narrow_oop_implicit_null_checks()) |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2490 return; |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2491 |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2492 // Go over safepoints nodes to skip DecodeN nodes for debug edges. |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2493 // It could be done for an uncommon traps or any safepoints/calls |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2494 // if the DecodeN node is referenced only in a debug info. |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2495 while (sfpt.size() > 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2496 n = sfpt.pop(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2497 JVMState *jvms = n->as_SafePoint()->jvms(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2498 assert(jvms != NULL, "sanity"); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2499 int start = jvms->debug_start(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2500 int end = n->req(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2501 bool is_uncommon = (n->is_CallStaticJava() && |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2502 n->as_CallStaticJava()->uncommon_trap_request() != 0); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2503 for (int j = start; j < end; j++) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2504 Node* in = n->in(j); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2505 if (in->is_DecodeN()) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2506 bool safe_to_skip = true; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2507 if (!is_uncommon ) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2508 // Is it safe to skip? |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2509 for (uint i = 0; i < in->outcnt(); i++) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2510 Node* u = in->raw_out(i); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2511 if (!u->is_SafePoint() || |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2512 u->is_Call() && u->as_Call()->has_non_debug_use(n)) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2513 safe_to_skip = false; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2514 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2515 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2516 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2517 if (safe_to_skip) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2518 n->set_req(j, in->in(1)); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2519 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2520 if (in->outcnt() == 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2521 in->disconnect_inputs(NULL); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2522 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2523 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2524 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2525 } |
0 | 2526 } |
2527 | |
2528 //------------------------------final_graph_reshaping-------------------------- | |
2529 // Final Graph Reshaping. | |
2530 // | |
2531 // (1) Clone simple inputs to uncommon calls, so they can be scheduled late | |
2532 // and not commoned up and forced early. Must come after regular | |
2533 // optimizations to avoid GVN undoing the cloning. Clone constant | |
2534 // inputs to Loop Phis; these will be split by the allocator anyways. | |
2535 // Remove Opaque nodes. | |
2536 // (2) Move last-uses by commutative operations to the left input to encourage | |
2537 // Intel update-in-place two-address operations and better register usage | |
2538 // on RISCs. Must come after regular optimizations to avoid GVN Ideal | |
2539 // calls canonicalizing them back. | |
2540 // (3) Count the number of double-precision FP ops, single-precision FP ops | |
2541 // and call sites. On Intel, we can get correct rounding either by | |
2542 // forcing singles to memory (requires extra stores and loads after each | |
2543 // FP bytecode) or we can set a rounding mode bit (requires setting and | |
2544 // clearing the mode bit around call sites). The mode bit is only used | |
2545 // if the relative frequency of single FP ops to calls is low enough. | |
2546 // This is a key transform for SPEC mpeg_audio. | |
2547 // (4) Detect infinite loops; blobs of code reachable from above but not | |
2548 // below. Several of the Code_Gen algorithms fail on such code shapes, | |
2549 // so we simply bail out. Happens a lot in ZKM.jar, but also happens | |
2550 // from time to time in other codes (such as -Xcomp finalizer loops, etc). | |
2551 // Detection is by looking for IfNodes where only 1 projection is | |
2552 // reachable from below or CatchNodes missing some targets. | |
2553 // (5) Assert for insane oop offsets in debug mode. | |
2554 | |
2555 bool Compile::final_graph_reshaping() { | |
2556 // an infinite loop may have been eliminated by the optimizer, | |
2557 // in which case the graph will be empty. | |
2558 if (root()->req() == 1) { | |
2559 record_method_not_compilable("trivial infinite loop"); | |
2560 return true; | |
2561 } | |
2562 | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2563 Final_Reshape_Counts frc; |
0 | 2564 |
2565 // Visit everybody reachable! | |
2566 // Allocate stack of size C->unique()/2 to avoid frequent realloc | |
2567 Node_Stack nstack(unique() >> 1); | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2568 final_graph_reshaping_walk(nstack, root(), frc); |
0 | 2569 |
2570 // Check for unreachable (from below) code (i.e., infinite loops). | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2571 for( uint i = 0; i < frc._tests.size(); i++ ) { |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2572 MultiBranchNode *n = frc._tests[i]->as_MultiBranch(); |
127 | 2573 // Get number of CFG targets. |
0 | 2574 // Note that PCTables include exception targets after calls. |
127 | 2575 uint required_outcnt = n->required_outcnt(); |
2576 if (n->outcnt() != required_outcnt) { | |
0 | 2577 // Check for a few special cases. Rethrow Nodes never take the |
2578 // 'fall-thru' path, so expected kids is 1 less. | |
2579 if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { | |
2580 if (n->in(0)->in(0)->is_Call()) { | |
2581 CallNode *call = n->in(0)->in(0)->as_Call(); | |
2582 if (call->entry_point() == OptoRuntime::rethrow_stub()) { | |
127 | 2583 required_outcnt--; // Rethrow always has 1 less kid |
0 | 2584 } else if (call->req() > TypeFunc::Parms && |
2585 call->is_CallDynamicJava()) { | |
2586 // Check for null receiver. In such case, the optimizer has | |
2587 // detected that the virtual call will always result in a null | |
2588 // pointer exception. The fall-through projection of this CatchNode | |
2589 // will not be populated. | |
2590 Node *arg0 = call->in(TypeFunc::Parms); | |
2591 if (arg0->is_Type() && | |
2592 arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { | |
127 | 2593 required_outcnt--; |
0 | 2594 } |
2595 } else if (call->entry_point() == OptoRuntime::new_array_Java() && | |
2596 call->req() > TypeFunc::Parms+1 && | |
2597 call->is_CallStaticJava()) { | |
2598 // Check for negative array length. In such case, the optimizer has | |
2599 // detected that the allocation attempt will always result in an | |
2600 // exception. There is no fall-through projection of this CatchNode . | |
2601 Node *arg1 = call->in(TypeFunc::Parms+1); | |
2602 if (arg1->is_Type() && | |
2603 arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { | |
127 | 2604 required_outcnt--; |
0 | 2605 } |
2606 } | |
2607 } | |
2608 } | |
127 | 2609 // Recheck with a better notion of 'required_outcnt' |
2610 if (n->outcnt() != required_outcnt) { | |
0 | 2611 record_method_not_compilable("malformed control flow"); |
2612 return true; // Not all targets reachable! | |
2613 } | |
2614 } | |
2615 // Check that I actually visited all kids. Unreached kids | |
2616 // must be infinite loops. | |
2617 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2618 if (!frc._visited.test(n->fast_out(j)->_idx)) { |
0 | 2619 record_method_not_compilable("infinite loop"); |
2620 return true; // Found unvisited kid; must be unreach | |
2621 } | |
2622 } | |
2623 | |
2624 // If original bytecodes contained a mixture of floats and doubles | |
2625 // check if the optimizer has made it homogenous, item (3). | |
929
cd18bd5e667c
6873777: FPU control word optimization still performed with SSE
never
parents:
921
diff
changeset
|
2626 if( Use24BitFPMode && Use24BitFP && UseSSE == 0 && |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2627 frc.get_float_count() > 32 && |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2628 frc.get_double_count() == 0 && |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2629 (10 * frc.get_call_count() < frc.get_float_count()) ) { |
0 | 2630 set_24_bit_selection_and_mode( false, true ); |
2631 } | |
2632 | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2633 set_java_calls(frc.get_java_call_count()); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2634 set_inner_loops(frc.get_inner_loop_count()); |
0 | 2635 |
2636 // No infinite loops, no reason to bail out. | |
2637 return false; | |
2638 } | |
2639 | |
2640 //-----------------------------too_many_traps---------------------------------- | |
2641 // Report if there are too many traps at the current method and bci. | |
2642 // Return true if there was a trap, and/or PerMethodTrapLimit is exceeded. | |
2643 bool Compile::too_many_traps(ciMethod* method, | |
2644 int bci, | |
2645 Deoptimization::DeoptReason reason) { | |
2646 ciMethodData* md = method->method_data(); | |
2647 if (md->is_empty()) { | |
2648 // Assume the trap has not occurred, or that it occurred only | |
2649 // because of a transient condition during start-up in the interpreter. | |
2650 return false; | |
2651 } | |
2652 if (md->has_trap_at(bci, reason) != 0) { | |
2653 // Assume PerBytecodeTrapLimit==0, for a more conservative heuristic. | |
2654 // Also, if there are multiple reasons, or if there is no per-BCI record, | |
2655 // assume the worst. | |
2656 if (log()) | |
2657 log()->elem("observe trap='%s' count='%d'", | |
2658 Deoptimization::trap_reason_name(reason), | |
2659 md->trap_count(reason)); | |
2660 return true; | |
2661 } else { | |
2662 // Ignore method/bci and see if there have been too many globally. | |
2663 return too_many_traps(reason, md); | |
2664 } | |
2665 } | |
2666 | |
2667 // Less-accurate variant which does not require a method and bci. | |
2668 bool Compile::too_many_traps(Deoptimization::DeoptReason reason, | |
2669 ciMethodData* logmd) { | |
2670 if (trap_count(reason) >= (uint)PerMethodTrapLimit) { | |
2671 // Too many traps globally. | |
2672 // Note that we use cumulative trap_count, not just md->trap_count. | |
2673 if (log()) { | |
2674 int mcount = (logmd == NULL)? -1: (int)logmd->trap_count(reason); | |
2675 log()->elem("observe trap='%s' count='0' mcount='%d' ccount='%d'", | |
2676 Deoptimization::trap_reason_name(reason), | |
2677 mcount, trap_count(reason)); | |
2678 } | |
2679 return true; | |
2680 } else { | |
2681 // The coast is clear. | |
2682 return false; | |
2683 } | |
2684 } | |
2685 | |
2686 //--------------------------too_many_recompiles-------------------------------- | |
2687 // Report if there are too many recompiles at the current method and bci. | |
2688 // Consults PerBytecodeRecompilationCutoff and PerMethodRecompilationCutoff. | |
2689 // Is not eager to return true, since this will cause the compiler to use | |
2690 // Action_none for a trap point, to avoid too many recompilations. | |
2691 bool Compile::too_many_recompiles(ciMethod* method, | |
2692 int bci, | |
2693 Deoptimization::DeoptReason reason) { | |
2694 ciMethodData* md = method->method_data(); | |
2695 if (md->is_empty()) { | |
2696 // Assume the trap has not occurred, or that it occurred only | |
2697 // because of a transient condition during start-up in the interpreter. | |
2698 return false; | |
2699 } | |
2700 // Pick a cutoff point well within PerBytecodeRecompilationCutoff. | |
2701 uint bc_cutoff = (uint) PerBytecodeRecompilationCutoff / 8; | |
2702 uint m_cutoff = (uint) PerMethodRecompilationCutoff / 2 + 1; // not zero | |
2703 Deoptimization::DeoptReason per_bc_reason | |
2704 = Deoptimization::reason_recorded_per_bytecode_if_any(reason); | |
2705 if ((per_bc_reason == Deoptimization::Reason_none | |
2706 || md->has_trap_at(bci, reason) != 0) | |
2707 // The trap frequency measure we care about is the recompile count: | |
2708 && md->trap_recompiled_at(bci) | |
2709 && md->overflow_recompile_count() >= bc_cutoff) { | |
2710 // Do not emit a trap here if it has already caused recompilations. | |
2711 // Also, if there are multiple reasons, or if there is no per-BCI record, | |
2712 // assume the worst. | |
2713 if (log()) | |
2714 log()->elem("observe trap='%s recompiled' count='%d' recompiles2='%d'", | |
2715 Deoptimization::trap_reason_name(reason), | |
2716 md->trap_count(reason), | |
2717 md->overflow_recompile_count()); | |
2718 return true; | |
2719 } else if (trap_count(reason) != 0 | |
2720 && decompile_count() >= m_cutoff) { | |
2721 // Too many recompiles globally, and we have seen this sort of trap. | |
2722 // Use cumulative decompile_count, not just md->decompile_count. | |
2723 if (log()) | |
2724 log()->elem("observe trap='%s' count='%d' mcount='%d' decompiles='%d' mdecompiles='%d'", | |
2725 Deoptimization::trap_reason_name(reason), | |
2726 md->trap_count(reason), trap_count(reason), | |
2727 md->decompile_count(), decompile_count()); | |
2728 return true; | |
2729 } else { | |
2730 // The coast is clear. | |
2731 return false; | |
2732 } | |
2733 } | |
2734 | |
2735 | |
2736 #ifndef PRODUCT | |
2737 //------------------------------verify_graph_edges--------------------------- | |
2738 // Walk the Graph and verify that there is a one-to-one correspondence | |
2739 // between Use-Def edges and Def-Use edges in the graph. | |
2740 void Compile::verify_graph_edges(bool no_dead_code) { | |
2741 if (VerifyGraphEdges) { | |
2742 ResourceArea *area = Thread::current()->resource_area(); | |
2743 Unique_Node_List visited(area); | |
2744 // Call recursive graph walk to check edges | |
2745 _root->verify_edges(visited); | |
2746 if (no_dead_code) { | |
2747 // Now make sure that no visited node is used by an unvisited node. | |
2748 bool dead_nodes = 0; | |
2749 Unique_Node_List checked(area); | |
2750 while (visited.size() > 0) { | |
2751 Node* n = visited.pop(); | |
2752 checked.push(n); | |
2753 for (uint i = 0; i < n->outcnt(); i++) { | |
2754 Node* use = n->raw_out(i); | |
2755 if (checked.member(use)) continue; // already checked | |
2756 if (visited.member(use)) continue; // already in the graph | |
2757 if (use->is_Con()) continue; // a dead ConNode is OK | |
2758 // At this point, we have found a dead node which is DU-reachable. | |
2759 if (dead_nodes++ == 0) | |
2760 tty->print_cr("*** Dead nodes reachable via DU edges:"); | |
2761 use->dump(2); | |
2762 tty->print_cr("---"); | |
2763 checked.push(use); // No repeats; pretend it is now checked. | |
2764 } | |
2765 } | |
2766 assert(dead_nodes == 0, "using nodes must be reachable from root"); | |
2767 } | |
2768 } | |
2769 } | |
2770 #endif | |
2771 | |
2772 // The Compile object keeps track of failure reasons separately from the ciEnv. | |
2773 // This is required because there is not quite a 1-1 relation between the | |
2774 // ciEnv and its compilation task and the Compile object. Note that one | |
2775 // ciEnv might use two Compile objects, if C2Compiler::compile_method decides | |
2776 // to backtrack and retry without subsuming loads. Other than this backtracking | |
2777 // behavior, the Compile's failure reason is quietly copied up to the ciEnv | |
2778 // by the logic in C2Compiler. | |
2779 void Compile::record_failure(const char* reason) { | |
2780 if (log() != NULL) { | |
2781 log()->elem("failure reason='%s' phase='compile'", reason); | |
2782 } | |
2783 if (_failure_reason == NULL) { | |
2784 // Record the first failure reason. | |
2785 _failure_reason = reason; | |
2786 } | |
222 | 2787 if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) { |
2788 C->print_method(_failure_reason); | |
2789 } | |
0 | 2790 _root = NULL; // flush the graph, too |
2791 } | |
2792 | |
2793 Compile::TracePhase::TracePhase(const char* name, elapsedTimer* accumulator, bool dolog) | |
2794 : TraceTime(NULL, accumulator, false NOT_PRODUCT( || TimeCompiler ), false) | |
2795 { | |
2796 if (dolog) { | |
2797 C = Compile::current(); | |
2798 _log = C->log(); | |
2799 } else { | |
2800 C = NULL; | |
2801 _log = NULL; | |
2802 } | |
2803 if (_log != NULL) { | |
2804 _log->begin_head("phase name='%s' nodes='%d'", name, C->unique()); | |
2805 _log->stamp(); | |
2806 _log->end_head(); | |
2807 } | |
2808 } | |
2809 | |
2810 Compile::TracePhase::~TracePhase() { | |
2811 if (_log != NULL) { | |
2812 _log->done("phase nodes='%d'", C->unique()); | |
2813 } | |
2814 } |