Mercurial > hg > truffle
annotate src/share/vm/opto/compile.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | 0e35fa8ebccd |
children | 3e8fbc61cee8 |
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 | |
403 relocInfo* locs_buf = (relocInfo*) blob->instructions_end() - MAX_locs_size; | |
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(); | |
425 address blob_begin = blob->instructions_begin(); | |
426 address blob_end = (address)locs_buf; | |
427 assert(blob->instructions_contains(blob_end), "sanity"); | |
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()); | |
436 return buf.code_size(); | |
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")); |
0 | 853 // Compilation level related initialization |
854 if (env()->comp_level() == CompLevel_fast_compile) { | |
855 set_num_loop_opts(Tier1LoopOptsCount); | |
856 set_do_inlining(Tier1Inline != 0); | |
857 set_max_inline_size(Tier1MaxInlineSize); | |
858 set_freq_inline_size(Tier1FreqInlineSize); | |
859 set_do_scheduling(false); | |
860 set_do_count_invocations(Tier1CountInvocations); | |
861 set_do_method_data_update(Tier1UpdateMethodData); | |
862 } else { | |
863 assert(env()->comp_level() == CompLevel_full_optimization, "unknown comp level"); | |
864 set_num_loop_opts(LoopOptsCount); | |
865 set_do_inlining(Inline); | |
866 set_max_inline_size(MaxInlineSize); | |
867 set_freq_inline_size(FreqInlineSize); | |
868 set_do_scheduling(OptoScheduling); | |
869 set_do_count_invocations(false); | |
870 set_do_method_data_update(false); | |
871 } | |
872 | |
873 if (debug_info()->recording_non_safepoints()) { | |
874 set_node_note_array(new(comp_arena()) GrowableArray<Node_Notes*> | |
875 (comp_arena(), 8, 0, NULL)); | |
876 set_default_node_notes(Node_Notes::make(this)); | |
877 } | |
878 | |
879 // // -- Initialize types before each compile -- | |
880 // // Update cached type information | |
881 // if( _method && _method->constants() ) | |
882 // Type::update_loaded_types(_method, _method->constants()); | |
883 | |
884 // Init alias_type map. | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
885 if (!_do_escape_analysis && aliaslevel == 3) |
0 | 886 aliaslevel = 2; // No unique types without escape analysis |
887 _AliasLevel = aliaslevel; | |
888 const int grow_ats = 16; | |
889 _max_alias_types = grow_ats; | |
890 _alias_types = NEW_ARENA_ARRAY(comp_arena(), AliasType*, grow_ats); | |
891 AliasType* ats = NEW_ARENA_ARRAY(comp_arena(), AliasType, grow_ats); | |
892 Copy::zero_to_bytes(ats, sizeof(AliasType)*grow_ats); | |
893 { | |
894 for (int i = 0; i < grow_ats; i++) _alias_types[i] = &ats[i]; | |
895 } | |
896 // Initialize the first few types. | |
897 _alias_types[AliasIdxTop]->Init(AliasIdxTop, NULL); | |
898 _alias_types[AliasIdxBot]->Init(AliasIdxBot, TypePtr::BOTTOM); | |
899 _alias_types[AliasIdxRaw]->Init(AliasIdxRaw, TypeRawPtr::BOTTOM); | |
900 _num_alias_types = AliasIdxRaw+1; | |
901 // Zero out the alias type cache. | |
902 Copy::zero_to_bytes(_alias_cache, sizeof(_alias_cache)); | |
903 // A NULL adr_type hits in the cache right away. Preload the right answer. | |
904 probe_alias_cache(NULL)->_index = AliasIdxTop; | |
905 | |
906 _intrinsics = NULL; | |
1685 | 907 _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
908 _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | |
0 | 909 register_library_intrinsics(); |
910 } | |
911 | |
912 //---------------------------init_start---------------------------------------- | |
913 // Install the StartNode on this compile object. | |
914 void Compile::init_start(StartNode* s) { | |
915 if (failing()) | |
916 return; // already failing | |
917 assert(s == start(), ""); | |
918 } | |
919 | |
920 StartNode* Compile::start() const { | |
921 assert(!failing(), ""); | |
922 for (DUIterator_Fast imax, i = root()->fast_outs(imax); i < imax; i++) { | |
923 Node* start = root()->fast_out(i); | |
924 if( start->is_Start() ) | |
925 return start->as_Start(); | |
926 } | |
927 ShouldNotReachHere(); | |
928 return NULL; | |
929 } | |
930 | |
931 //-------------------------------immutable_memory------------------------------------- | |
932 // Access immutable memory | |
933 Node* Compile::immutable_memory() { | |
934 if (_immutable_memory != NULL) { | |
935 return _immutable_memory; | |
936 } | |
937 StartNode* s = start(); | |
938 for (DUIterator_Fast imax, i = s->fast_outs(imax); true; i++) { | |
939 Node *p = s->fast_out(i); | |
940 if (p != s && p->as_Proj()->_con == TypeFunc::Memory) { | |
941 _immutable_memory = p; | |
942 return _immutable_memory; | |
943 } | |
944 } | |
945 ShouldNotReachHere(); | |
946 return NULL; | |
947 } | |
948 | |
949 //----------------------set_cached_top_node------------------------------------ | |
950 // Install the cached top node, and make sure Node::is_top works correctly. | |
951 void Compile::set_cached_top_node(Node* tn) { | |
952 if (tn != NULL) verify_top(tn); | |
953 Node* old_top = _top; | |
954 _top = tn; | |
955 // Calling Node::setup_is_top allows the nodes the chance to adjust | |
956 // their _out arrays. | |
957 if (_top != NULL) _top->setup_is_top(); | |
958 if (old_top != NULL) old_top->setup_is_top(); | |
959 assert(_top == NULL || top()->is_top(), ""); | |
960 } | |
961 | |
962 #ifndef PRODUCT | |
963 void Compile::verify_top(Node* tn) const { | |
964 if (tn != NULL) { | |
965 assert(tn->is_Con(), "top node must be a constant"); | |
966 assert(((ConNode*)tn)->type() == Type::TOP, "top node must have correct type"); | |
967 assert(tn->in(0) != NULL, "must have live top node"); | |
968 } | |
969 } | |
970 #endif | |
971 | |
972 | |
973 ///-------------------Managing Per-Node Debug & Profile Info------------------- | |
974 | |
975 void Compile::grow_node_notes(GrowableArray<Node_Notes*>* arr, int grow_by) { | |
976 guarantee(arr != NULL, ""); | |
977 int num_blocks = arr->length(); | |
978 if (grow_by < num_blocks) grow_by = num_blocks; | |
979 int num_notes = grow_by * _node_notes_block_size; | |
980 Node_Notes* notes = NEW_ARENA_ARRAY(node_arena(), Node_Notes, num_notes); | |
981 Copy::zero_to_bytes(notes, num_notes * sizeof(Node_Notes)); | |
982 while (num_notes > 0) { | |
983 arr->append(notes); | |
984 notes += _node_notes_block_size; | |
985 num_notes -= _node_notes_block_size; | |
986 } | |
987 assert(num_notes == 0, "exact multiple, please"); | |
988 } | |
989 | |
990 bool Compile::copy_node_notes_to(Node* dest, Node* source) { | |
991 if (source == NULL || dest == NULL) return false; | |
992 | |
993 if (dest->is_Con()) | |
994 return false; // Do not push debug info onto constants. | |
995 | |
996 #ifdef ASSERT | |
997 // Leave a bread crumb trail pointing to the original node: | |
998 if (dest != NULL && dest != source && dest->debug_orig() == NULL) { | |
999 dest->set_debug_orig(source); | |
1000 } | |
1001 #endif | |
1002 | |
1003 if (node_note_array() == NULL) | |
1004 return false; // Not collecting any notes now. | |
1005 | |
1006 // This is a copy onto a pre-existing node, which may already have notes. | |
1007 // If both nodes have notes, do not overwrite any pre-existing notes. | |
1008 Node_Notes* source_notes = node_notes_at(source->_idx); | |
1009 if (source_notes == NULL || source_notes->is_clear()) return false; | |
1010 Node_Notes* dest_notes = node_notes_at(dest->_idx); | |
1011 if (dest_notes == NULL || dest_notes->is_clear()) { | |
1012 return set_node_notes_at(dest->_idx, source_notes); | |
1013 } | |
1014 | |
1015 Node_Notes merged_notes = (*source_notes); | |
1016 // The order of operations here ensures that dest notes will win... | |
1017 merged_notes.update_from(dest_notes); | |
1018 return set_node_notes_at(dest->_idx, &merged_notes); | |
1019 } | |
1020 | |
1021 | |
1022 //--------------------------allow_range_check_smearing------------------------- | |
1023 // Gating condition for coalescing similar range checks. | |
1024 // Sometimes we try 'speculatively' replacing a series of a range checks by a | |
1025 // single covering check that is at least as strong as any of them. | |
1026 // If the optimization succeeds, the simplified (strengthened) range check | |
1027 // will always succeed. If it fails, we will deopt, and then give up | |
1028 // on the optimization. | |
1029 bool Compile::allow_range_check_smearing() const { | |
1030 // If this method has already thrown a range-check, | |
1031 // assume it was because we already tried range smearing | |
1032 // and it failed. | |
1033 uint already_trapped = trap_count(Deoptimization::Reason_range_check); | |
1034 return !already_trapped; | |
1035 } | |
1036 | |
1037 | |
1038 //------------------------------flatten_alias_type----------------------------- | |
1039 const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { | |
1040 int offset = tj->offset(); | |
1041 TypePtr::PTR ptr = tj->ptr(); | |
1042 | |
247 | 1043 // Known instance (scalarizable allocation) alias only with itself. |
1044 bool is_known_inst = tj->isa_oopptr() != NULL && | |
1045 tj->is_oopptr()->is_known_instance(); | |
1046 | |
0 | 1047 // Process weird unsafe references. |
1048 if (offset == Type::OffsetBot && (tj->isa_instptr() /*|| tj->isa_klassptr()*/)) { | |
1049 assert(InlineUnsafeOps, "indeterminate pointers come only from unsafe ops"); | |
247 | 1050 assert(!is_known_inst, "scalarizable allocation should not have unsafe references"); |
0 | 1051 tj = TypeOopPtr::BOTTOM; |
1052 ptr = tj->ptr(); | |
1053 offset = tj->offset(); | |
1054 } | |
1055 | |
1056 // Array pointers need some flattening | |
1057 const TypeAryPtr *ta = tj->isa_aryptr(); | |
247 | 1058 if( ta && is_known_inst ) { |
1059 if ( offset != Type::OffsetBot && | |
1060 offset > arrayOopDesc::length_offset_in_bytes() ) { | |
1061 offset = Type::OffsetBot; // Flatten constant access into array body only | |
1062 tj = ta = TypeAryPtr::make(ptr, ta->ary(), ta->klass(), true, offset, ta->instance_id()); | |
1063 } | |
1064 } else if( ta && _AliasLevel >= 2 ) { | |
0 | 1065 // For arrays indexed by constant indices, we flatten the alias |
1066 // space to include all of the array body. Only the header, klass | |
1067 // and array length can be accessed un-aliased. | |
1068 if( offset != Type::OffsetBot ) { | |
1069 if( ta->const_oop() ) { // methodDataOop or methodOop | |
1070 offset = Type::OffsetBot; // Flatten constant access into array body | |
247 | 1071 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset); |
0 | 1072 } else if( offset == arrayOopDesc::length_offset_in_bytes() ) { |
1073 // range is OK as-is. | |
1074 tj = ta = TypeAryPtr::RANGE; | |
1075 } else if( offset == oopDesc::klass_offset_in_bytes() ) { | |
1076 tj = TypeInstPtr::KLASS; // all klass loads look alike | |
1077 ta = TypeAryPtr::RANGE; // generic ignored junk | |
1078 ptr = TypePtr::BotPTR; | |
1079 } else if( offset == oopDesc::mark_offset_in_bytes() ) { | |
1080 tj = TypeInstPtr::MARK; | |
1081 ta = TypeAryPtr::RANGE; // generic ignored junk | |
1082 ptr = TypePtr::BotPTR; | |
1083 } else { // Random constant offset into array body | |
1084 offset = Type::OffsetBot; // Flatten constant access into array body | |
247 | 1085 tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset); |
0 | 1086 } |
1087 } | |
1088 // Arrays of fixed size alias with arrays of unknown size. | |
1089 if (ta->size() != TypeInt::POS) { | |
1090 const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS); | |
247 | 1091 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset); |
0 | 1092 } |
1093 // 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
|
1094 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
|
1095 const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size()); |
247 | 1096 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
|
1097 } |
0 | 1098 if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) { |
1099 const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size()); | |
247 | 1100 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); |
0 | 1101 } |
1102 // Arrays of bytes and of booleans both use 'bastore' and 'baload' so | |
1103 // cannot be distinguished by bytecode alone. | |
1104 if (ta->elem() == TypeInt::BOOL) { | |
1105 const TypeAry *tary = TypeAry::make(TypeInt::BYTE, ta->size()); | |
1106 ciKlass* aklass = ciTypeArrayKlass::make(T_BYTE); | |
247 | 1107 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset); |
0 | 1108 } |
1109 // During the 2nd round of IterGVN, NotNull castings are removed. | |
1110 // Make sure the Bottom and NotNull variants alias the same. | |
1111 // Also, make sure exact and non-exact variants alias the same. | |
1112 if( ptr == TypePtr::NotNull || ta->klass_is_exact() ) { | |
1113 if (ta->const_oop()) { | |
1114 tj = ta = TypeAryPtr::make(TypePtr::Constant,ta->const_oop(),ta->ary(),ta->klass(),false,offset); | |
1115 } else { | |
1116 tj = ta = TypeAryPtr::make(TypePtr::BotPTR,ta->ary(),ta->klass(),false,offset); | |
1117 } | |
1118 } | |
1119 } | |
1120 | |
1121 // Oop pointers need some flattening | |
1122 const TypeInstPtr *to = tj->isa_instptr(); | |
1123 if( to && _AliasLevel >= 2 && to != TypeOopPtr::BOTTOM ) { | |
1124 if( ptr == TypePtr::Constant ) { | |
1125 // No constant oop pointers (such as Strings); they alias with | |
1126 // unknown strings. | |
247 | 1127 assert(!is_known_inst, "not scalarizable allocation"); |
0 | 1128 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); |
247 | 1129 } else if( is_known_inst ) { |
163 | 1130 tj = to; // Keep NotNull and klass_is_exact for instance type |
0 | 1131 } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) { |
1132 // During the 2nd round of IterGVN, NotNull castings are removed. | |
1133 // Make sure the Bottom and NotNull variants alias the same. | |
1134 // Also, make sure exact and non-exact variants alias the same. | |
247 | 1135 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); |
0 | 1136 } |
1137 // Canonicalize the holder of this field | |
1138 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
|
1139 if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) { |
0 | 1140 // First handle header references such as a LoadKlassNode, even if the |
1141 // object's klass is unloaded at compile time (4965979). | |
247 | 1142 if (!is_known_inst) { // Do it only for non-instance types |
1143 tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset); | |
1144 } | |
0 | 1145 } else if (offset < 0 || offset >= k->size_helper() * wordSize) { |
1146 to = NULL; | |
1147 tj = TypeOopPtr::BOTTOM; | |
1148 offset = tj->offset(); | |
1149 } else { | |
1150 ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset); | |
1151 if (!k->equals(canonical_holder) || tj->offset() != offset) { | |
247 | 1152 if( is_known_inst ) { |
1153 tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id()); | |
1154 } else { | |
1155 tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset); | |
1156 } | |
0 | 1157 } |
1158 } | |
1159 } | |
1160 | |
1161 // Klass pointers to object array klasses need some flattening | |
1162 const TypeKlassPtr *tk = tj->isa_klassptr(); | |
1163 if( tk ) { | |
1164 // If we are referencing a field within a Klass, we need | |
1165 // to assume the worst case of an Object. Both exact and | |
1166 // inexact types must flatten to the same alias class. | |
1167 // Since the flattened result for a klass is defined to be | |
1168 // precisely java.lang.Object, use a constant ptr. | |
1169 if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) { | |
1170 | |
1171 tj = tk = TypeKlassPtr::make(TypePtr::Constant, | |
1172 TypeKlassPtr::OBJECT->klass(), | |
1173 offset); | |
1174 } | |
1175 | |
1176 ciKlass* klass = tk->klass(); | |
1177 if( klass->is_obj_array_klass() ) { | |
1178 ciKlass* k = TypeAryPtr::OOPS->klass(); | |
1179 if( !k || !k->is_loaded() ) // Only fails for some -Xcomp runs | |
1180 k = TypeInstPtr::BOTTOM->klass(); | |
1181 tj = tk = TypeKlassPtr::make( TypePtr::NotNull, k, offset ); | |
1182 } | |
1183 | |
1184 // Check for precise loads from the primary supertype array and force them | |
1185 // to the supertype cache alias index. Check for generic array loads from | |
1186 // the primary supertype array and also force them to the supertype cache | |
1187 // alias index. Since the same load can reach both, we need to merge | |
1188 // these 2 disparate memories into the same alias class. Since the | |
1189 // primary supertype array is read-only, there's no chance of confusion | |
1190 // where we bypass an array load and an array store. | |
1191 uint off2 = offset - Klass::primary_supers_offset_in_bytes(); | |
1192 if( offset == Type::OffsetBot || | |
1193 off2 < Klass::primary_super_limit()*wordSize ) { | |
1194 offset = sizeof(oopDesc) +Klass::secondary_super_cache_offset_in_bytes(); | |
1195 tj = tk = TypeKlassPtr::make( TypePtr::NotNull, tk->klass(), offset ); | |
1196 } | |
1197 } | |
1198 | |
1199 // Flatten all Raw pointers together. | |
1200 if (tj->base() == Type::RawPtr) | |
1201 tj = TypeRawPtr::BOTTOM; | |
1202 | |
1203 if (tj->base() == Type::AnyPtr) | |
1204 tj = TypePtr::BOTTOM; // An error, which the caller must check for. | |
1205 | |
1206 // Flatten all to bottom for now | |
1207 switch( _AliasLevel ) { | |
1208 case 0: | |
1209 tj = TypePtr::BOTTOM; | |
1210 break; | |
1211 case 1: // Flatten to: oop, static, field or array | |
1212 switch (tj->base()) { | |
1213 //case Type::AryPtr: tj = TypeAryPtr::RANGE; break; | |
1214 case Type::RawPtr: tj = TypeRawPtr::BOTTOM; break; | |
1215 case Type::AryPtr: // do not distinguish arrays at all | |
1216 case Type::InstPtr: tj = TypeInstPtr::BOTTOM; break; | |
1217 case Type::KlassPtr: tj = TypeKlassPtr::OBJECT; break; | |
1218 case Type::AnyPtr: tj = TypePtr::BOTTOM; break; // caller checks it | |
1219 default: ShouldNotReachHere(); | |
1220 } | |
1221 break; | |
605 | 1222 case 2: // No collapsing at level 2; keep all splits |
1223 case 3: // No collapsing at level 3; keep all splits | |
0 | 1224 break; |
1225 default: | |
1226 Unimplemented(); | |
1227 } | |
1228 | |
1229 offset = tj->offset(); | |
1230 assert( offset != Type::OffsetTop, "Offset has fallen from constant" ); | |
1231 | |
1232 assert( (offset != Type::OffsetBot && tj->base() != Type::AryPtr) || | |
1233 (offset == Type::OffsetBot && tj->base() == Type::AryPtr) || | |
1234 (offset == Type::OffsetBot && tj == TypeOopPtr::BOTTOM) || | |
1235 (offset == Type::OffsetBot && tj == TypePtr::BOTTOM) || | |
1236 (offset == oopDesc::mark_offset_in_bytes() && tj->base() == Type::AryPtr) || | |
1237 (offset == oopDesc::klass_offset_in_bytes() && tj->base() == Type::AryPtr) || | |
1238 (offset == arrayOopDesc::length_offset_in_bytes() && tj->base() == Type::AryPtr) , | |
1239 "For oops, klasses, raw offset must be constant; for arrays the offset is never known" ); | |
1240 assert( tj->ptr() != TypePtr::TopPTR && | |
1241 tj->ptr() != TypePtr::AnyNull && | |
1242 tj->ptr() != TypePtr::Null, "No imprecise addresses" ); | |
1243 // assert( tj->ptr() != TypePtr::Constant || | |
1244 // tj->base() == Type::RawPtr || | |
1245 // tj->base() == Type::KlassPtr, "No constant oop addresses" ); | |
1246 | |
1247 return tj; | |
1248 } | |
1249 | |
1250 void Compile::AliasType::Init(int i, const TypePtr* at) { | |
1251 _index = i; | |
1252 _adr_type = at; | |
1253 _field = NULL; | |
1254 _is_rewritable = true; // default | |
1255 const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL; | |
223 | 1256 if (atoop != NULL && atoop->is_known_instance()) { |
1257 const TypeOopPtr *gt = atoop->cast_to_instance_id(TypeOopPtr::InstanceBot); | |
0 | 1258 _general_index = Compile::current()->get_alias_index(gt); |
1259 } else { | |
1260 _general_index = 0; | |
1261 } | |
1262 } | |
1263 | |
1264 //---------------------------------print_on------------------------------------ | |
1265 #ifndef PRODUCT | |
1266 void Compile::AliasType::print_on(outputStream* st) { | |
1267 if (index() < 10) | |
1268 st->print("@ <%d> ", index()); | |
1269 else st->print("@ <%d>", index()); | |
1270 st->print(is_rewritable() ? " " : " RO"); | |
1271 int offset = adr_type()->offset(); | |
1272 if (offset == Type::OffsetBot) | |
1273 st->print(" +any"); | |
1274 else st->print(" +%-3d", offset); | |
1275 st->print(" in "); | |
1276 adr_type()->dump_on(st); | |
1277 const TypeOopPtr* tjp = adr_type()->isa_oopptr(); | |
1278 if (field() != NULL && tjp) { | |
1279 if (tjp->klass() != field()->holder() || | |
1280 tjp->offset() != field()->offset_in_bytes()) { | |
1281 st->print(" != "); | |
1282 field()->print(); | |
1283 st->print(" ***"); | |
1284 } | |
1285 } | |
1286 } | |
1287 | |
1288 void print_alias_types() { | |
1289 Compile* C = Compile::current(); | |
1290 tty->print_cr("--- Alias types, AliasIdxBot .. %d", C->num_alias_types()-1); | |
1291 for (int idx = Compile::AliasIdxBot; idx < C->num_alias_types(); idx++) { | |
1292 C->alias_type(idx)->print_on(tty); | |
1293 tty->cr(); | |
1294 } | |
1295 } | |
1296 #endif | |
1297 | |
1298 | |
1299 //----------------------------probe_alias_cache-------------------------------- | |
1300 Compile::AliasCacheEntry* Compile::probe_alias_cache(const TypePtr* adr_type) { | |
1301 intptr_t key = (intptr_t) adr_type; | |
1302 key ^= key >> logAliasCacheSize; | |
1303 return &_alias_cache[key & right_n_bits(logAliasCacheSize)]; | |
1304 } | |
1305 | |
1306 | |
1307 //-----------------------------grow_alias_types-------------------------------- | |
1308 void Compile::grow_alias_types() { | |
1309 const int old_ats = _max_alias_types; // how many before? | |
1310 const int new_ats = old_ats; // how many more? | |
1311 const int grow_ats = old_ats+new_ats; // how many now? | |
1312 _max_alias_types = grow_ats; | |
1313 _alias_types = REALLOC_ARENA_ARRAY(comp_arena(), AliasType*, _alias_types, old_ats, grow_ats); | |
1314 AliasType* ats = NEW_ARENA_ARRAY(comp_arena(), AliasType, new_ats); | |
1315 Copy::zero_to_bytes(ats, sizeof(AliasType)*new_ats); | |
1316 for (int i = 0; i < new_ats; i++) _alias_types[old_ats+i] = &ats[i]; | |
1317 } | |
1318 | |
1319 | |
1320 //--------------------------------find_alias_type------------------------------ | |
1321 Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_create) { | |
1322 if (_AliasLevel == 0) | |
1323 return alias_type(AliasIdxBot); | |
1324 | |
1325 AliasCacheEntry* ace = probe_alias_cache(adr_type); | |
1326 if (ace->_adr_type == adr_type) { | |
1327 return alias_type(ace->_index); | |
1328 } | |
1329 | |
1330 // Handle special cases. | |
1331 if (adr_type == NULL) return alias_type(AliasIdxTop); | |
1332 if (adr_type == TypePtr::BOTTOM) return alias_type(AliasIdxBot); | |
1333 | |
1334 // Do it the slow way. | |
1335 const TypePtr* flat = flatten_alias_type(adr_type); | |
1336 | |
1337 #ifdef ASSERT | |
1338 assert(flat == flatten_alias_type(flat), "idempotent"); | |
1339 assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr"); | |
1340 if (flat->isa_oopptr() && !flat->isa_klassptr()) { | |
1341 const TypeOopPtr* foop = flat->is_oopptr(); | |
247 | 1342 // Scalarizable allocations have exact klass always. |
1343 bool exact = !foop->klass_is_exact() || foop->is_known_instance(); | |
1344 const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr(); | |
0 | 1345 assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type"); |
1346 } | |
1347 assert(flat == flatten_alias_type(flat), "exact bit doesn't matter"); | |
1348 #endif | |
1349 | |
1350 int idx = AliasIdxTop; | |
1351 for (int i = 0; i < num_alias_types(); i++) { | |
1352 if (alias_type(i)->adr_type() == flat) { | |
1353 idx = i; | |
1354 break; | |
1355 } | |
1356 } | |
1357 | |
1358 if (idx == AliasIdxTop) { | |
1359 if (no_create) return NULL; | |
1360 // Grow the array if necessary. | |
1361 if (_num_alias_types == _max_alias_types) grow_alias_types(); | |
1362 // Add a new alias type. | |
1363 idx = _num_alias_types++; | |
1364 _alias_types[idx]->Init(idx, flat); | |
1365 if (flat == TypeInstPtr::KLASS) alias_type(idx)->set_rewritable(false); | |
1366 if (flat == TypeAryPtr::RANGE) alias_type(idx)->set_rewritable(false); | |
1367 if (flat->isa_instptr()) { | |
1368 if (flat->offset() == java_lang_Class::klass_offset_in_bytes() | |
1369 && flat->is_instptr()->klass() == env()->Class_klass()) | |
1370 alias_type(idx)->set_rewritable(false); | |
1371 } | |
1372 if (flat->isa_klassptr()) { | |
1373 if (flat->offset() == Klass::super_check_offset_offset_in_bytes() + (int)sizeof(oopDesc)) | |
1374 alias_type(idx)->set_rewritable(false); | |
1375 if (flat->offset() == Klass::modifier_flags_offset_in_bytes() + (int)sizeof(oopDesc)) | |
1376 alias_type(idx)->set_rewritable(false); | |
1377 if (flat->offset() == Klass::access_flags_offset_in_bytes() + (int)sizeof(oopDesc)) | |
1378 alias_type(idx)->set_rewritable(false); | |
1379 if (flat->offset() == Klass::java_mirror_offset_in_bytes() + (int)sizeof(oopDesc)) | |
1380 alias_type(idx)->set_rewritable(false); | |
1381 } | |
1382 // %%% (We would like to finalize JavaThread::threadObj_offset(), | |
1383 // but the base pointer type is not distinctive enough to identify | |
1384 // references into JavaThread.) | |
1385 | |
1386 // Check for final instance fields. | |
1387 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
|
1388 if (tinst && tinst->offset() >= instanceOopDesc::base_offset_in_bytes()) { |
0 | 1389 ciInstanceKlass *k = tinst->klass()->as_instance_klass(); |
1390 ciField* field = k->get_field_by_offset(tinst->offset(), false); | |
1391 // Set field() and is_rewritable() attributes. | |
1392 if (field != NULL) alias_type(idx)->set_field(field); | |
1393 } | |
1394 const TypeKlassPtr* tklass = flat->isa_klassptr(); | |
1395 // Check for final static fields. | |
1396 if (tklass && tklass->klass()->is_instance_klass()) { | |
1397 ciInstanceKlass *k = tklass->klass()->as_instance_klass(); | |
1398 ciField* field = k->get_field_by_offset(tklass->offset(), true); | |
1399 // Set field() and is_rewritable() attributes. | |
1400 if (field != NULL) alias_type(idx)->set_field(field); | |
1401 } | |
1402 } | |
1403 | |
1404 // Fill the cache for next time. | |
1405 ace->_adr_type = adr_type; | |
1406 ace->_index = idx; | |
1407 assert(alias_type(adr_type) == alias_type(idx), "type must be installed"); | |
1408 | |
1409 // Might as well try to fill the cache for the flattened version, too. | |
1410 AliasCacheEntry* face = probe_alias_cache(flat); | |
1411 if (face->_adr_type == NULL) { | |
1412 face->_adr_type = flat; | |
1413 face->_index = idx; | |
1414 assert(alias_type(flat) == alias_type(idx), "flat type must work too"); | |
1415 } | |
1416 | |
1417 return alias_type(idx); | |
1418 } | |
1419 | |
1420 | |
1421 Compile::AliasType* Compile::alias_type(ciField* field) { | |
1422 const TypeOopPtr* t; | |
1423 if (field->is_static()) | |
1424 t = TypeKlassPtr::make(field->holder()); | |
1425 else | |
1426 t = TypeOopPtr::make_from_klass_raw(field->holder()); | |
1427 AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes())); | |
1428 assert(field->is_final() == !atp->is_rewritable(), "must get the rewritable bits correct"); | |
1429 return atp; | |
1430 } | |
1431 | |
1432 | |
1433 //------------------------------have_alias_type-------------------------------- | |
1434 bool Compile::have_alias_type(const TypePtr* adr_type) { | |
1435 AliasCacheEntry* ace = probe_alias_cache(adr_type); | |
1436 if (ace->_adr_type == adr_type) { | |
1437 return true; | |
1438 } | |
1439 | |
1440 // Handle special cases. | |
1441 if (adr_type == NULL) return true; | |
1442 if (adr_type == TypePtr::BOTTOM) return true; | |
1443 | |
1444 return find_alias_type(adr_type, true) != NULL; | |
1445 } | |
1446 | |
1447 //-----------------------------must_alias-------------------------------------- | |
1448 // True if all values of the given address type are in the given alias category. | |
1449 bool Compile::must_alias(const TypePtr* adr_type, int alias_idx) { | |
1450 if (alias_idx == AliasIdxBot) return true; // the universal category | |
1451 if (adr_type == NULL) return true; // NULL serves as TypePtr::TOP | |
1452 if (alias_idx == AliasIdxTop) return false; // the empty category | |
1453 if (adr_type->base() == Type::AnyPtr) return false; // TypePtr::BOTTOM or its twins | |
1454 | |
1455 // the only remaining possible overlap is identity | |
1456 int adr_idx = get_alias_index(adr_type); | |
1457 assert(adr_idx != AliasIdxBot && adr_idx != AliasIdxTop, ""); | |
1458 assert(adr_idx == alias_idx || | |
1459 (alias_type(alias_idx)->adr_type() != TypeOopPtr::BOTTOM | |
1460 && adr_type != TypeOopPtr::BOTTOM), | |
1461 "should not be testing for overlap with an unsafe pointer"); | |
1462 return adr_idx == alias_idx; | |
1463 } | |
1464 | |
1465 //------------------------------can_alias-------------------------------------- | |
1466 // True if any values of the given address type are in the given alias category. | |
1467 bool Compile::can_alias(const TypePtr* adr_type, int alias_idx) { | |
1468 if (alias_idx == AliasIdxTop) return false; // the empty category | |
1469 if (adr_type == NULL) return false; // NULL serves as TypePtr::TOP | |
1470 if (alias_idx == AliasIdxBot) return true; // the universal category | |
1471 if (adr_type->base() == Type::AnyPtr) return true; // TypePtr::BOTTOM or its twins | |
1472 | |
1473 // the only remaining possible overlap is identity | |
1474 int adr_idx = get_alias_index(adr_type); | |
1475 assert(adr_idx != AliasIdxBot && adr_idx != AliasIdxTop, ""); | |
1476 return adr_idx == alias_idx; | |
1477 } | |
1478 | |
1479 | |
1480 | |
1481 //---------------------------pop_warm_call------------------------------------- | |
1482 WarmCallInfo* Compile::pop_warm_call() { | |
1483 WarmCallInfo* wci = _warm_calls; | |
1484 if (wci != NULL) _warm_calls = wci->remove_from(wci); | |
1485 return wci; | |
1486 } | |
1487 | |
1488 //----------------------------Inline_Warm-------------------------------------- | |
1489 int Compile::Inline_Warm() { | |
1490 // If there is room, try to inline some more warm call sites. | |
1491 // %%% Do a graph index compaction pass when we think we're out of space? | |
1492 if (!InlineWarmCalls) return 0; | |
1493 | |
1494 int calls_made_hot = 0; | |
1495 int room_to_grow = NodeCountInliningCutoff - unique(); | |
1496 int amount_to_grow = MIN2(room_to_grow, (int)NodeCountInliningStep); | |
1497 int amount_grown = 0; | |
1498 WarmCallInfo* call; | |
1499 while (amount_to_grow > 0 && (call = pop_warm_call()) != NULL) { | |
1500 int est_size = (int)call->size(); | |
1501 if (est_size > (room_to_grow - amount_grown)) { | |
1502 // This one won't fit anyway. Get rid of it. | |
1503 call->make_cold(); | |
1504 continue; | |
1505 } | |
1506 call->make_hot(); | |
1507 calls_made_hot++; | |
1508 amount_grown += est_size; | |
1509 amount_to_grow -= est_size; | |
1510 } | |
1511 | |
1512 if (calls_made_hot > 0) set_major_progress(); | |
1513 return calls_made_hot; | |
1514 } | |
1515 | |
1516 | |
1517 //----------------------------Finish_Warm-------------------------------------- | |
1518 void Compile::Finish_Warm() { | |
1519 if (!InlineWarmCalls) return; | |
1520 if (failing()) return; | |
1521 if (warm_calls() == NULL) return; | |
1522 | |
1523 // Clean up loose ends, if we are out of space for inlining. | |
1524 WarmCallInfo* call; | |
1525 while ((call = pop_warm_call()) != NULL) { | |
1526 call->make_cold(); | |
1527 } | |
1528 } | |
1529 | |
1172 | 1530 //---------------------cleanup_loop_predicates----------------------- |
1531 // Remove the opaque nodes that protect the predicates so that all unused | |
1532 // checks and uncommon_traps will be eliminated from the ideal graph | |
1533 void Compile::cleanup_loop_predicates(PhaseIterGVN &igvn) { | |
1534 if (predicate_count()==0) return; | |
1535 for (int i = predicate_count(); i > 0; i--) { | |
1536 Node * n = predicate_opaque1_node(i-1); | |
1537 assert(n->Opcode() == Op_Opaque1, "must be"); | |
1538 igvn.replace_node(n, n->in(1)); | |
1539 } | |
1540 assert(predicate_count()==0, "should be clean!"); | |
1541 igvn.optimize(); | |
1542 } | |
0 | 1543 |
1544 //------------------------------Optimize--------------------------------------- | |
1545 // Given a graph, optimize it. | |
1546 void Compile::Optimize() { | |
1547 TracePhase t1("optimizer", &_t_optimizer, true); | |
1548 | |
1549 #ifndef PRODUCT | |
1550 if (env()->break_at_compile()) { | |
1551 BREAKPOINT; | |
1552 } | |
1553 | |
1554 #endif | |
1555 | |
1556 ResourceMark rm; | |
1557 int loop_opts_cnt; | |
1558 | |
1559 NOT_PRODUCT( verify_graph_edges(); ) | |
1560 | |
222 | 1561 print_method("After Parsing"); |
0 | 1562 |
1563 { | |
1564 // Iterative Global Value Numbering, including ideal transforms | |
1565 // Initialize IterGVN with types and values from parse-time GVN | |
1566 PhaseIterGVN igvn(initial_gvn()); | |
1567 { | |
1568 NOT_PRODUCT( TracePhase t2("iterGVN", &_t_iterGVN, TimeCompiler); ) | |
1569 igvn.optimize(); | |
1570 } | |
1571 | |
1572 print_method("Iter GVN 1", 2); | |
1573 | |
1574 if (failing()) return; | |
1575 | |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1576 // Perform escape analysis |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1577 if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1578 TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1579 ConnectionGraph::do_analysis(this, &igvn); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1580 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1581 if (failing()) return; |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1582 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1583 igvn.optimize(); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1584 print_method("Iter GVN 3", 2); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1585 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1586 if (failing()) return; |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1587 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1588 } |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1589 |
0 | 1590 // Loop transforms on the ideal graph. Range Check Elimination, |
1591 // peeling, unrolling, etc. | |
1592 | |
1593 // Set loop opts counter | |
1594 loop_opts_cnt = num_loop_opts(); | |
1595 if((loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) { | |
1596 { | |
1597 TracePhase t2("idealLoop", &_t_idealLoop, true); | |
1172 | 1598 PhaseIdealLoop ideal_loop( igvn, true, UseLoopPredicate); |
0 | 1599 loop_opts_cnt--; |
1600 if (major_progress()) print_method("PhaseIdealLoop 1", 2); | |
1601 if (failing()) return; | |
1602 } | |
1603 // Loop opts pass if partial peeling occurred in previous pass | |
1604 if(PartialPeelLoop && major_progress() && (loop_opts_cnt > 0)) { | |
1605 TracePhase t3("idealLoop", &_t_idealLoop, true); | |
1172 | 1606 PhaseIdealLoop ideal_loop( igvn, false, UseLoopPredicate); |
0 | 1607 loop_opts_cnt--; |
1608 if (major_progress()) print_method("PhaseIdealLoop 2", 2); | |
1609 if (failing()) return; | |
1610 } | |
1611 // Loop opts pass for loop-unrolling before CCP | |
1612 if(major_progress() && (loop_opts_cnt > 0)) { | |
1613 TracePhase t4("idealLoop", &_t_idealLoop, true); | |
1172 | 1614 PhaseIdealLoop ideal_loop( igvn, false, UseLoopPredicate); |
0 | 1615 loop_opts_cnt--; |
1616 if (major_progress()) print_method("PhaseIdealLoop 3", 2); | |
1617 } | |
921
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1618 if (!failing()) { |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1619 // 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
|
1620 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1621 PhaseIdealLoop::verify(igvn); |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1622 } |
0 | 1623 } |
1624 if (failing()) return; | |
1625 | |
1626 // Conditional Constant Propagation; | |
1627 PhaseCCP ccp( &igvn ); | |
1628 assert( true, "Break here to ccp.dump_nodes_and_types(_root,999,1)"); | |
1629 { | |
1630 TracePhase t2("ccp", &_t_ccp, true); | |
1631 ccp.do_transform(); | |
1632 } | |
1633 print_method("PhaseCPP 1", 2); | |
1634 | |
1635 assert( true, "Break here to ccp.dump_old2new_map()"); | |
1636 | |
1637 // Iterative Global Value Numbering, including ideal transforms | |
1638 { | |
1639 NOT_PRODUCT( TracePhase t2("iterGVN2", &_t_iterGVN2, TimeCompiler); ) | |
1640 igvn = ccp; | |
1641 igvn.optimize(); | |
1642 } | |
1643 | |
1644 print_method("Iter GVN 2", 2); | |
1645 | |
1646 if (failing()) return; | |
1647 | |
1648 // Loop transforms on the ideal graph. Range Check Elimination, | |
1649 // peeling, unrolling, etc. | |
1650 if(loop_opts_cnt > 0) { | |
1651 debug_only( int cnt = 0; ); | |
1172 | 1652 bool loop_predication = UseLoopPredicate; |
0 | 1653 while(major_progress() && (loop_opts_cnt > 0)) { |
1654 TracePhase t2("idealLoop", &_t_idealLoop, true); | |
1655 assert( cnt++ < 40, "infinite cycle in loop optimization" ); | |
1172 | 1656 PhaseIdealLoop ideal_loop( igvn, true, loop_predication); |
0 | 1657 loop_opts_cnt--; |
1658 if (major_progress()) print_method("PhaseIdealLoop iterations", 2); | |
1659 if (failing()) return; | |
1172 | 1660 // Perform loop predication optimization during first iteration after CCP. |
1661 // After that switch it off and cleanup unused loop predicates. | |
1662 if (loop_predication) { | |
1663 loop_predication = false; | |
1664 cleanup_loop_predicates(igvn); | |
1665 if (failing()) return; | |
1666 } | |
0 | 1667 } |
1668 } | |
921
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1669 |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1670 { |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1671 // Verify that all previous optimizations produced a valid graph |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1672 // 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
|
1673 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1674 PhaseIdealLoop::verify(igvn); |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1675 } |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1676 |
0 | 1677 { |
1678 NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); ) | |
1679 PhaseMacroExpand mex(igvn); | |
1680 if (mex.expand_macro_nodes()) { | |
1681 assert(failing(), "must bail out w/ explicit message"); | |
1682 return; | |
1683 } | |
1684 } | |
1685 | |
1686 } // (End scope of igvn; run destructor if necessary for asserts.) | |
1687 | |
1688 // A method with only infinite loops has no edges entering loops from root | |
1689 { | |
1690 NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); ) | |
1691 if (final_graph_reshaping()) { | |
1692 assert(failing(), "must bail out w/ explicit message"); | |
1693 return; | |
1694 } | |
1695 } | |
1696 | |
1697 print_method("Optimize finished", 2); | |
1698 } | |
1699 | |
1700 | |
1701 //------------------------------Code_Gen--------------------------------------- | |
1702 // Given a graph, generate code for it | |
1703 void Compile::Code_Gen() { | |
1704 if (failing()) return; | |
1705 | |
1706 // Perform instruction selection. You might think we could reclaim Matcher | |
1707 // memory PDQ, but actually the Matcher is used in generating spill code. | |
1708 // Internals of the Matcher (including some VectorSets) must remain live | |
1709 // for awhile - thus I cannot reclaim Matcher memory lest a VectorSet usage | |
1710 // set a bit in reclaimed memory. | |
1711 | |
1712 // In debug mode can dump m._nodes.dump() for mapping of ideal to machine | |
1713 // nodes. Mapping is only valid at the root of each matched subtree. | |
1714 NOT_PRODUCT( verify_graph_edges(); ) | |
1715 | |
1716 Node_List proj_list; | |
1717 Matcher m(proj_list); | |
1718 _matcher = &m; | |
1719 { | |
1720 TracePhase t2("matcher", &_t_matcher, true); | |
1721 m.match(); | |
1722 } | |
1723 // In debug mode can dump m._nodes.dump() for mapping of ideal to machine | |
1724 // nodes. Mapping is only valid at the root of each matched subtree. | |
1725 NOT_PRODUCT( verify_graph_edges(); ) | |
1726 | |
1727 // If you have too many nodes, or if matching has failed, bail out | |
1728 check_node_count(0, "out of nodes matching instructions"); | |
1729 if (failing()) return; | |
1730 | |
1731 // Build a proper-looking CFG | |
1732 PhaseCFG cfg(node_arena(), root(), m); | |
1733 _cfg = &cfg; | |
1734 { | |
1735 NOT_PRODUCT( TracePhase t2("scheduler", &_t_scheduler, TimeCompiler); ) | |
1736 cfg.Dominators(); | |
1737 if (failing()) return; | |
1738 | |
1739 NOT_PRODUCT( verify_graph_edges(); ) | |
1740 | |
1741 cfg.Estimate_Block_Frequency(); | |
1742 cfg.GlobalCodeMotion(m,unique(),proj_list); | |
1743 | |
1744 print_method("Global code motion", 2); | |
1745 | |
1746 if (failing()) return; | |
1747 NOT_PRODUCT( verify_graph_edges(); ) | |
1748 | |
1749 debug_only( cfg.verify(); ) | |
1750 } | |
1751 NOT_PRODUCT( verify_graph_edges(); ) | |
1752 | |
1753 PhaseChaitin regalloc(unique(),cfg,m); | |
1754 _regalloc = ®alloc; | |
1755 { | |
1756 TracePhase t2("regalloc", &_t_registerAllocation, true); | |
1757 // Perform any platform dependent preallocation actions. This is used, | |
1758 // for example, to avoid taking an implicit null pointer exception | |
1759 // using the frame pointer on win95. | |
1760 _regalloc->pd_preallocate_hook(); | |
1761 | |
1762 // Perform register allocation. After Chaitin, use-def chains are | |
1763 // no longer accurate (at spill code) and so must be ignored. | |
1764 // Node->LRG->reg mappings are still accurate. | |
1765 _regalloc->Register_Allocate(); | |
1766 | |
1767 // Bail out if the allocator builds too many nodes | |
1768 if (failing()) return; | |
1769 } | |
1770 | |
1771 // Prior to register allocation we kept empty basic blocks in case the | |
1772 // the allocator needed a place to spill. After register allocation we | |
1773 // are not adding any new instructions. If any basic block is empty, we | |
1774 // can now safely remove it. | |
1775 { | |
418 | 1776 NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); ) |
1777 cfg.remove_empty(); | |
1778 if (do_freq_based_layout()) { | |
1779 PhaseBlockLayout layout(cfg); | |
1780 } else { | |
1781 cfg.set_loop_alignment(); | |
1782 } | |
1783 cfg.fixup_flow(); | |
0 | 1784 } |
1785 | |
1786 // Perform any platform dependent postallocation verifications. | |
1787 debug_only( _regalloc->pd_postallocate_verify_hook(); ) | |
1788 | |
1789 // Apply peephole optimizations | |
1790 if( OptoPeephole ) { | |
1791 NOT_PRODUCT( TracePhase t2("peephole", &_t_peephole, TimeCompiler); ) | |
1792 PhasePeephole peep( _regalloc, cfg); | |
1793 peep.do_transform(); | |
1794 } | |
1795 | |
1796 // Convert Nodes to instruction bits in a buffer | |
1797 { | |
1798 // %%%% workspace merge brought two timers together for one job | |
1799 TracePhase t2a("output", &_t_output, true); | |
1800 NOT_PRODUCT( TraceTime t2b(NULL, &_t_codeGeneration, TimeCompiler, false); ) | |
1801 Output(); | |
1802 } | |
1803 | |
222 | 1804 print_method("Final Code"); |
0 | 1805 |
1806 // He's dead, Jim. | |
1807 _cfg = (PhaseCFG*)0xdeadbeef; | |
1808 _regalloc = (PhaseChaitin*)0xdeadbeef; | |
1809 } | |
1810 | |
1811 | |
1812 //------------------------------dump_asm--------------------------------------- | |
1813 // Dump formatted assembly | |
1814 #ifndef PRODUCT | |
1815 void Compile::dump_asm(int *pcs, uint pc_limit) { | |
1816 bool cut_short = false; | |
1817 tty->print_cr("#"); | |
1818 tty->print("# "); _tf->dump(); tty->cr(); | |
1819 tty->print_cr("#"); | |
1820 | |
1821 // For all blocks | |
1822 int pc = 0x0; // Program counter | |
1823 char starts_bundle = ' '; | |
1824 _regalloc->dump_frame(); | |
1825 | |
1826 Node *n = NULL; | |
1827 for( uint i=0; i<_cfg->_num_blocks; i++ ) { | |
1828 if (VMThread::should_terminate()) { cut_short = true; break; } | |
1829 Block *b = _cfg->_blocks[i]; | |
1830 if (b->is_connector() && !Verbose) continue; | |
1831 n = b->_nodes[0]; | |
1832 if (pcs && n->_idx < pc_limit) | |
1833 tty->print("%3.3x ", pcs[n->_idx]); | |
1834 else | |
1835 tty->print(" "); | |
1836 b->dump_head( &_cfg->_bbs ); | |
1837 if (b->is_connector()) { | |
1838 tty->print_cr(" # Empty connector block"); | |
1839 } else if (b->num_preds() == 2 && b->pred(1)->is_CatchProj() && b->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) { | |
1840 tty->print_cr(" # Block is sole successor of call"); | |
1841 } | |
1842 | |
1843 // For all instructions | |
1844 Node *delay = NULL; | |
1845 for( uint j = 0; j<b->_nodes.size(); j++ ) { | |
1846 if (VMThread::should_terminate()) { cut_short = true; break; } | |
1847 n = b->_nodes[j]; | |
1848 if (valid_bundle_info(n)) { | |
1849 Bundle *bundle = node_bundling(n); | |
1850 if (bundle->used_in_unconditional_delay()) { | |
1851 delay = n; | |
1852 continue; | |
1853 } | |
1854 if (bundle->starts_bundle()) | |
1855 starts_bundle = '+'; | |
1856 } | |
1857 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1858 if (WizardMode) n->dump(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1859 |
0 | 1860 if( !n->is_Region() && // Dont print in the Assembly |
1861 !n->is_Phi() && // a few noisely useless nodes | |
1862 !n->is_Proj() && | |
1863 !n->is_MachTemp() && | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
1864 !n->is_SafePointScalarObject() && |
0 | 1865 !n->is_Catch() && // Would be nice to print exception table targets |
1866 !n->is_MergeMem() && // Not very interesting | |
1867 !n->is_top() && // Debug info table constants | |
1868 !(n->is_Con() && !n->is_Mach())// Debug info table constants | |
1869 ) { | |
1870 if (pcs && n->_idx < pc_limit) | |
1871 tty->print("%3.3x", pcs[n->_idx]); | |
1872 else | |
1873 tty->print(" "); | |
1874 tty->print(" %c ", starts_bundle); | |
1875 starts_bundle = ' '; | |
1876 tty->print("\t"); | |
1877 n->format(_regalloc, tty); | |
1878 tty->cr(); | |
1879 } | |
1880 | |
1881 // If we have an instruction with a delay slot, and have seen a delay, | |
1882 // then back up and print it | |
1883 if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) { | |
1884 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
|
1885 if (WizardMode) delay->dump(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1886 |
0 | 1887 if (node_bundling(delay)->starts_bundle()) |
1888 starts_bundle = '+'; | |
1889 if (pcs && n->_idx < pc_limit) | |
1890 tty->print("%3.3x", pcs[n->_idx]); | |
1891 else | |
1892 tty->print(" "); | |
1893 tty->print(" %c ", starts_bundle); | |
1894 starts_bundle = ' '; | |
1895 tty->print("\t"); | |
1896 delay->format(_regalloc, tty); | |
1897 tty->print_cr(""); | |
1898 delay = NULL; | |
1899 } | |
1900 | |
1901 // Dump the exception table as well | |
1902 if( n->is_Catch() && (Verbose || WizardMode) ) { | |
1903 // Print the exception table for this offset | |
1904 _handler_table.print_subtable_for(pc); | |
1905 } | |
1906 } | |
1907 | |
1908 if (pcs && n->_idx < pc_limit) | |
1909 tty->print_cr("%3.3x", pcs[n->_idx]); | |
1910 else | |
1911 tty->print_cr(""); | |
1912 | |
1913 assert(cut_short || delay == NULL, "no unconditional delay branch"); | |
1914 | |
1915 } // End of per-block dump | |
1916 tty->print_cr(""); | |
1917 | |
1918 if (cut_short) tty->print_cr("*** disassembly is cut short ***"); | |
1919 } | |
1920 #endif | |
1921 | |
1922 //------------------------------Final_Reshape_Counts--------------------------- | |
1923 // This class defines counters to help identify when a method | |
1924 // may/must be executed using hardware with only 24-bit precision. | |
1925 struct Final_Reshape_Counts : public StackObj { | |
1926 int _call_count; // count non-inlined 'common' calls | |
1927 int _float_count; // count float ops requiring 24-bit precision | |
1928 int _double_count; // count double ops requiring more precision | |
1929 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
|
1930 int _inner_loop_count; // count loops which need alignment |
0 | 1931 VectorSet _visited; // Visitation flags |
1932 Node_List _tests; // Set of IfNodes & PCTableNodes | |
1933 | |
1934 Final_Reshape_Counts() : | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
1935 _call_count(0), _float_count(0), _double_count(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
1936 _java_call_count(0), _inner_loop_count(0), |
0 | 1937 _visited( Thread::current()->resource_area() ) { } |
1938 | |
1939 void inc_call_count () { _call_count ++; } | |
1940 void inc_float_count () { _float_count ++; } | |
1941 void inc_double_count() { _double_count++; } | |
1942 void inc_java_call_count() { _java_call_count++; } | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
1943 void inc_inner_loop_count() { _inner_loop_count++; } |
0 | 1944 |
1945 int get_call_count () const { return _call_count ; } | |
1946 int get_float_count () const { return _float_count ; } | |
1947 int get_double_count() const { return _double_count; } | |
1948 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
|
1949 int get_inner_loop_count() const { return _inner_loop_count; } |
0 | 1950 }; |
1951 | |
1952 static bool oop_offset_is_sane(const TypeInstPtr* tp) { | |
1953 ciInstanceKlass *k = tp->klass()->as_instance_klass(); | |
1954 // 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
|
1955 return k->contains_field_offset(tp->offset()); |
0 | 1956 // Note that OffsetBot and OffsetTop are very negative. |
1957 } | |
1958 | |
1959 //------------------------------final_graph_reshaping_impl---------------------- | |
1960 // 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
|
1961 static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) { |
0 | 1962 |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
1963 if ( n->outcnt() == 0 ) return; // dead node |
0 | 1964 uint nop = n->Opcode(); |
1965 | |
1966 // Check for 2-input instruction with "last use" on right input. | |
1967 // Swap to left input. Implements item (2). | |
1968 if( n->req() == 3 && // two-input instruction | |
1969 n->in(1)->outcnt() > 1 && // left use is NOT a last use | |
1970 (!n->in(1)->is_Phi() || n->in(1)->in(2) != n) && // it is not data loop | |
1971 n->in(2)->outcnt() == 1 &&// right use IS a last use | |
1972 !n->in(2)->is_Con() ) { // right use is not a constant | |
1973 // Check for commutative opcode | |
1974 switch( nop ) { | |
1975 case Op_AddI: case Op_AddF: case Op_AddD: case Op_AddL: | |
1976 case Op_MaxI: case Op_MinI: | |
1977 case Op_MulI: case Op_MulF: case Op_MulD: case Op_MulL: | |
1978 case Op_AndL: case Op_XorL: case Op_OrL: | |
1979 case Op_AndI: case Op_XorI: case Op_OrI: { | |
1980 // Move "last use" input to left by swapping inputs | |
1981 n->swap_edges(1, 2); | |
1982 break; | |
1983 } | |
1984 default: | |
1985 break; | |
1986 } | |
1987 } | |
1988 | |
1609 | 1989 #ifdef ASSERT |
1990 if( n->is_Mem() ) { | |
1991 Compile* C = Compile::current(); | |
1992 int alias_idx = C->get_alias_index(n->as_Mem()->adr_type()); | |
1993 assert( n->in(0) != NULL || alias_idx != Compile::AliasIdxRaw || | |
1994 // oop will be recorded in oop map if load crosses safepoint | |
1995 n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() || | |
1996 LoadNode::is_immutable_value(n->in(MemNode::Address))), | |
1997 "raw memory operations should have control edge"); | |
1998 } | |
1999 #endif | |
0 | 2000 // Count FPU ops and common calls, implements item (3) |
2001 switch( nop ) { | |
2002 // Count all float operations that may use FPU | |
2003 case Op_AddF: | |
2004 case Op_SubF: | |
2005 case Op_MulF: | |
2006 case Op_DivF: | |
2007 case Op_NegF: | |
2008 case Op_ModF: | |
2009 case Op_ConvI2F: | |
2010 case Op_ConF: | |
2011 case Op_CmpF: | |
2012 case Op_CmpF3: | |
2013 // 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
|
2014 frc.inc_float_count(); |
0 | 2015 break; |
2016 | |
2017 case Op_ConvF2D: | |
2018 case Op_ConvD2F: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2019 frc.inc_float_count(); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2020 frc.inc_double_count(); |
0 | 2021 break; |
2022 | |
2023 // Count all double operations that may use FPU | |
2024 case Op_AddD: | |
2025 case Op_SubD: | |
2026 case Op_MulD: | |
2027 case Op_DivD: | |
2028 case Op_NegD: | |
2029 case Op_ModD: | |
2030 case Op_ConvI2D: | |
2031 case Op_ConvD2I: | |
2032 // case Op_ConvL2D: // handled by leaf call | |
2033 // case Op_ConvD2L: // handled by leaf call | |
2034 case Op_ConD: | |
2035 case Op_CmpD: | |
2036 case Op_CmpD3: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2037 frc.inc_double_count(); |
0 | 2038 break; |
2039 case Op_Opaque1: // Remove Opaque Nodes before matching | |
2040 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
|
2041 n->subsume_by(n->in(1)); |
0 | 2042 break; |
2043 case Op_CallStaticJava: | |
2044 case Op_CallJava: | |
2045 case Op_CallDynamicJava: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2046 frc.inc_java_call_count(); // Count java call site; |
0 | 2047 case Op_CallRuntime: |
2048 case Op_CallLeaf: | |
2049 case Op_CallLeafNoFP: { | |
2050 assert( n->is_Call(), "" ); | |
2051 CallNode *call = n->as_Call(); | |
2052 // Count call sites where the FP mode bit would have to be flipped. | |
2053 // Do not count uncommon runtime calls: | |
2054 // uncommon_trap, _complete_monitor_locking, _complete_monitor_unlocking, | |
2055 // _new_Java, _new_typeArray, _new_objArray, _rethrow_Java, ... | |
2056 if( !call->is_CallStaticJava() || !call->as_CallStaticJava()->_name ) { | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2057 frc.inc_call_count(); // Count the call site |
0 | 2058 } else { // See if uncommon argument is shared |
2059 Node *n = call->in(TypeFunc::Parms); | |
2060 int nop = n->Opcode(); | |
2061 // Clone shared simple arguments to uncommon calls, item (1). | |
2062 if( n->outcnt() > 1 && | |
2063 !n->is_Proj() && | |
2064 nop != Op_CreateEx && | |
2065 nop != Op_CheckCastPP && | |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2066 nop != Op_DecodeN && |
0 | 2067 !n->is_Mem() ) { |
2068 Node *x = n->clone(); | |
2069 call->set_req( TypeFunc::Parms, x ); | |
2070 } | |
2071 } | |
2072 break; | |
2073 } | |
2074 | |
2075 case Op_StoreD: | |
2076 case Op_LoadD: | |
2077 case Op_LoadD_unaligned: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2078 frc.inc_double_count(); |
0 | 2079 goto handle_mem; |
2080 case Op_StoreF: | |
2081 case Op_LoadF: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2082 frc.inc_float_count(); |
0 | 2083 goto handle_mem; |
2084 | |
2085 case Op_StoreB: | |
2086 case Op_StoreC: | |
2087 case Op_StoreCM: | |
2088 case Op_StorePConditional: | |
2089 case Op_StoreI: | |
2090 case Op_StoreL: | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
418
diff
changeset
|
2091 case Op_StoreIConditional: |
0 | 2092 case Op_StoreLConditional: |
2093 case Op_CompareAndSwapI: | |
2094 case Op_CompareAndSwapL: | |
2095 case Op_CompareAndSwapP: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2096 case Op_CompareAndSwapN: |
0 | 2097 case Op_StoreP: |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2098 case Op_StoreN: |
0 | 2099 case Op_LoadB: |
624 | 2100 case Op_LoadUB: |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
492
diff
changeset
|
2101 case Op_LoadUS: |
0 | 2102 case Op_LoadI: |
624 | 2103 case Op_LoadUI2L: |
0 | 2104 case Op_LoadKlass: |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2105 case Op_LoadNKlass: |
0 | 2106 case Op_LoadL: |
2107 case Op_LoadL_unaligned: | |
2108 case Op_LoadPLocked: | |
2109 case Op_LoadLLocked: | |
2110 case Op_LoadP: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2111 case Op_LoadN: |
0 | 2112 case Op_LoadRange: |
2113 case Op_LoadS: { | |
2114 handle_mem: | |
2115 #ifdef ASSERT | |
2116 if( VerifyOptoOopOffsets ) { | |
2117 assert( n->is_Mem(), "" ); | |
2118 MemNode *mem = (MemNode*)n; | |
2119 // Check to see if address types have grounded out somehow. | |
2120 const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr(); | |
2121 assert( !tp || oop_offset_is_sane(tp), "" ); | |
2122 } | |
2123 #endif | |
2124 break; | |
2125 } | |
2126 | |
2127 case Op_AddP: { // Assert sane base pointers | |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2128 Node *addp = n->in(AddPNode::Address); |
0 | 2129 assert( !addp->is_AddP() || |
2130 addp->in(AddPNode::Base)->is_top() || // Top OK for allocation | |
2131 addp->in(AddPNode::Base) == n->in(AddPNode::Base), | |
2132 "Base pointers must match" ); | |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2133 #ifdef _LP64 |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2134 if (UseCompressedOops && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2135 addp->Opcode() == Op_ConP && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2136 addp == n->in(AddPNode::Base) && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2137 n->in(AddPNode::Offset)->is_Con()) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2138 // 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
|
2139 // 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
|
2140 // instructions (4) then load 64-bits constant (7). |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2141 // 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
|
2142 const Type* t = addp->bottom_type(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2143 if (t->isa_oopptr()) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2144 Node* nn = NULL; |
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 // Look for existing ConN node of the same exact type. |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2147 Compile* C = Compile::current(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2148 Node* r = C->root(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2149 uint cnt = r->outcnt(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2150 for (uint i = 0; i < cnt; i++) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2151 Node* m = r->raw_out(i); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2152 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
|
2153 m->bottom_type()->make_ptr() == t) { |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2154 nn = m; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2155 break; |
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 if (nn != NULL) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2159 // Decode a narrow oop to match address |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2160 // [R12 + narrow_oop_reg<<3 + offset] |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2161 nn = new (C, 2) DecodeNNode(nn, t); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2162 n->set_req(AddPNode::Base, nn); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2163 n->set_req(AddPNode::Address, nn); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2164 if (addp->outcnt() == 0) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2165 addp->disconnect_inputs(NULL); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2166 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2167 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2168 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2169 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2170 #endif |
0 | 2171 break; |
2172 } | |
2173 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2174 #ifdef _LP64 |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2175 case Op_CastPP: |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2176 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
|
2177 Compile* C = Compile::current(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2178 Node* in1 = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2179 const Type* t = n->bottom_type(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2180 Node* new_in1 = in1->clone(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2181 new_in1->as_DecodeN()->set_type(t); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2182 |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2183 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
|
2184 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2185 // 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
|
2186 // 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
|
2187 // 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
|
2188 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2189 // [R12 + narrow_oop_reg<<3 + offset] |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2190 // NullCheck narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2191 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2192 // 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
|
2193 // 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
|
2194 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2195 // 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
|
2196 // [base_reg + offset] |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2197 // NullCheck base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2198 // |
605 | 2199 // 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
|
2200 // 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
|
2201 // 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
|
2202 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2203 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
|
2204 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2205 |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2206 n->subsume_by(new_in1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2207 if (in1->outcnt() == 0) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2208 in1->disconnect_inputs(NULL); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2209 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2210 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2211 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
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 case Op_CmpP: |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2214 // 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
|
2215 // 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
|
2216 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
|
2217 Node* in1 = n->in(1); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2218 Node* in2 = n->in(2); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2219 if (!in1->is_DecodeN()) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2220 in2 = in1; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2221 in1 = n->in(2); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2222 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2223 assert(in1->is_DecodeN(), "sanity"); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2224 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2225 Compile* C = Compile::current(); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2226 Node* new_in2 = NULL; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2227 if (in2->is_DecodeN()) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2228 new_in2 = in2->in(1); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2229 } else if (in2->Opcode() == Op_ConP) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2230 const Type* t = in2->bottom_type(); |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2231 if (t == TypePtr::NULL_PTR) { |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2232 // 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
|
2233 // oops implicit null check is not generated. |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2234 // 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
|
2235 if (Matcher::gen_narrow_oop_implicit_null_checks()) |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2236 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
|
2237 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2238 // This transformation together with CastPP transformation above |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2239 // 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
|
2240 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2241 // The original code after Optimize() |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2242 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2243 // LoadN memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2244 // decode narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2245 // CmpP base_reg, NULL |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2246 // CastPP base_reg // NotNull |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2247 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2248 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2249 // after these transformations will be |
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 // LoadN memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2252 // CmpN narrow_oop_reg, NULL |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2253 // 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
|
2254 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2255 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2256 // 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
|
2257 // 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
|
2258 // final_graph_reshaping_walk()). |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2259 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2260 // 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
|
2261 // on x86: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2262 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2263 // Load_narrow_oop memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2264 // 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
|
2265 // NullCheck narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2266 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2267 // and on sparc: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2268 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2269 // Load_narrow_oop memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2270 // 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
|
2271 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2272 // NullCheck base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2273 // |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2274 } else if (t->isa_oopptr()) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2275 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
|
2276 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2277 } |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2278 if (new_in2 != NULL) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2279 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
|
2280 n->subsume_by( cmpN ); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2281 if (in1->outcnt() == 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2282 in1->disconnect_inputs(NULL); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2283 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2284 if (in2->outcnt() == 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2285 in2->disconnect_inputs(NULL); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2286 } |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2287 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2288 } |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
2289 break; |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2290 |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2291 case Op_DecodeN: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2292 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
|
2293 // 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
|
2294 // 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
|
2295 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
|
2296 break; |
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 case Op_EncodeP: { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2299 Node* in1 = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2300 if (in1->is_DecodeN()) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2301 n->subsume_by(in1->in(1)); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2302 } else if (in1->Opcode() == Op_ConP) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2303 Compile* C = Compile::current(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2304 const Type* t = in1->bottom_type(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2305 if (t == TypePtr::NULL_PTR) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2306 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
|
2307 } else if (t->isa_oopptr()) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2308 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
|
2309 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2310 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2311 if (in1->outcnt() == 0) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2312 in1->disconnect_inputs(NULL); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2313 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2314 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2315 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2316 |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2317 case Op_Proj: { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2318 if (OptimizeStringConcat) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2319 ProjNode* p = n->as_Proj(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2320 if (p->_is_io_use) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2321 // Separate projections were used for the exception path which |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2322 // 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
|
2323 // then they will hang around and should just be replaced with |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2324 // the original one. |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2325 Node* proj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2326 // Replace with just one |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2327 for (SimpleDUIterator i(p->in(0)); i.has_next(); i.next()) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2328 Node *use = i.get(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2329 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
|
2330 proj = use; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2331 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2332 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2333 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2334 assert(p != NULL, "must be found"); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2335 p->subsume_by(proj); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2336 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2337 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2338 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2339 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2340 |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2341 case Op_Phi: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2342 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
|
2343 // 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
|
2344 // 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
|
2345 Node* unique_in = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2346 assert(unique_in != NULL, ""); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2347 uint cnt = n->req(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2348 for (uint i = 2; i < cnt; i++) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2349 Node* m = n->in(i); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2350 assert(m != NULL, ""); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2351 if (unique_in != m) |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2352 unique_in = NULL; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2353 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2354 if (unique_in != NULL) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2355 n->subsume_by(unique_in); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2356 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2357 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2358 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2359 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2360 #endif |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2361 |
0 | 2362 case Op_ModI: |
2363 if (UseDivMod) { | |
2364 // Check if a%b and a/b both exist | |
2365 Node* d = n->find_similar(Op_DivI); | |
2366 if (d) { | |
2367 // Replace them with a fused divmod if supported | |
2368 Compile* C = Compile::current(); | |
2369 if (Matcher::has_match_rule(Op_DivModI)) { | |
2370 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
|
2371 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
|
2372 n->subsume_by(divmod->mod_proj()); |
0 | 2373 } else { |
2374 // replace a%b with a-((a/b)*b) | |
2375 Node* mult = new (C, 3) MulINode(d, d->in(2)); | |
2376 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
|
2377 n->subsume_by( sub ); |
0 | 2378 } |
2379 } | |
2380 } | |
2381 break; | |
2382 | |
2383 case Op_ModL: | |
2384 if (UseDivMod) { | |
2385 // Check if a%b and a/b both exist | |
2386 Node* d = n->find_similar(Op_DivL); | |
2387 if (d) { | |
2388 // Replace them with a fused divmod if supported | |
2389 Compile* C = Compile::current(); | |
2390 if (Matcher::has_match_rule(Op_DivModL)) { | |
2391 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
|
2392 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
|
2393 n->subsume_by(divmod->mod_proj()); |
0 | 2394 } else { |
2395 // replace a%b with a-((a/b)*b) | |
2396 Node* mult = new (C, 3) MulLNode(d, d->in(2)); | |
2397 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
|
2398 n->subsume_by( sub ); |
0 | 2399 } |
2400 } | |
2401 } | |
2402 break; | |
2403 | |
2404 case Op_Load16B: | |
2405 case Op_Load8B: | |
2406 case Op_Load4B: | |
2407 case Op_Load8S: | |
2408 case Op_Load4S: | |
2409 case Op_Load2S: | |
2410 case Op_Load8C: | |
2411 case Op_Load4C: | |
2412 case Op_Load2C: | |
2413 case Op_Load4I: | |
2414 case Op_Load2I: | |
2415 case Op_Load2L: | |
2416 case Op_Load4F: | |
2417 case Op_Load2F: | |
2418 case Op_Load2D: | |
2419 case Op_Store16B: | |
2420 case Op_Store8B: | |
2421 case Op_Store4B: | |
2422 case Op_Store8C: | |
2423 case Op_Store4C: | |
2424 case Op_Store2C: | |
2425 case Op_Store4I: | |
2426 case Op_Store2I: | |
2427 case Op_Store2L: | |
2428 case Op_Store4F: | |
2429 case Op_Store2F: | |
2430 case Op_Store2D: | |
2431 break; | |
2432 | |
2433 case Op_PackB: | |
2434 case Op_PackS: | |
2435 case Op_PackC: | |
2436 case Op_PackI: | |
2437 case Op_PackF: | |
2438 case Op_PackL: | |
2439 case Op_PackD: | |
2440 if (n->req()-1 > 2) { | |
2441 // Replace many operand PackNodes with a binary tree for matching | |
2442 PackNode* p = (PackNode*) n; | |
2443 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
|
2444 n->subsume_by(btp); |
0 | 2445 } |
2446 break; | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2447 case Op_Loop: |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2448 case Op_CountedLoop: |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2449 if (n->as_Loop()->is_inner_loop()) { |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2450 frc.inc_inner_loop_count(); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2451 } |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2452 break; |
0 | 2453 default: |
2454 assert( !n->is_Call(), "" ); | |
2455 assert( !n->is_Mem(), "" ); | |
2456 break; | |
2457 } | |
127 | 2458 |
2459 // Collect CFG split points | |
2460 if (n->is_MultiBranch()) | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2461 frc._tests.push(n); |
0 | 2462 } |
2463 | |
2464 //------------------------------final_graph_reshaping_walk--------------------- | |
2465 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), | |
2466 // 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
|
2467 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
|
2468 ResourceArea *area = Thread::current()->resource_area(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2469 Unique_Node_List sfpt(area); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2470 |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2471 frc._visited.set(root->_idx); // first, mark node as visited |
0 | 2472 uint cnt = root->req(); |
2473 Node *n = root; | |
2474 uint i = 0; | |
2475 while (true) { | |
2476 if (i < cnt) { | |
2477 // Place all non-visited non-null inputs onto stack | |
2478 Node* m = n->in(i); | |
2479 ++i; | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2480 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
|
2481 if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2482 sfpt.push(m); |
0 | 2483 cnt = m->req(); |
2484 nstack.push(n, i); // put on stack parent and next input's index | |
2485 n = m; | |
2486 i = 0; | |
2487 } | |
2488 } else { | |
2489 // Now do post-visit work | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2490 final_graph_reshaping_impl( n, frc ); |
0 | 2491 if (nstack.is_empty()) |
2492 break; // finished | |
2493 n = nstack.node(); // Get node from stack | |
2494 cnt = n->req(); | |
2495 i = nstack.index(); | |
2496 nstack.pop(); // Shift to the next node on stack | |
2497 } | |
2498 } | |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2499 |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2500 // Skip next transformation if compressed oops are not used. |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2501 if (!UseCompressedOops || !Matcher::gen_narrow_oop_implicit_null_checks()) |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2502 return; |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2503 |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2504 // 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
|
2505 // 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
|
2506 // 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
|
2507 while (sfpt.size() > 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2508 n = sfpt.pop(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2509 JVMState *jvms = n->as_SafePoint()->jvms(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2510 assert(jvms != NULL, "sanity"); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2511 int start = jvms->debug_start(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2512 int end = n->req(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2513 bool is_uncommon = (n->is_CallStaticJava() && |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2514 n->as_CallStaticJava()->uncommon_trap_request() != 0); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2515 for (int j = start; j < end; j++) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2516 Node* in = n->in(j); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2517 if (in->is_DecodeN()) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2518 bool safe_to_skip = true; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2519 if (!is_uncommon ) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2520 // Is it safe to skip? |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2521 for (uint i = 0; i < in->outcnt(); i++) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2522 Node* u = in->raw_out(i); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2523 if (!u->is_SafePoint() || |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2524 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
|
2525 safe_to_skip = false; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2526 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2527 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2528 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2529 if (safe_to_skip) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2530 n->set_req(j, in->in(1)); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2531 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2532 if (in->outcnt() == 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2533 in->disconnect_inputs(NULL); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2534 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2535 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2536 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2537 } |
0 | 2538 } |
2539 | |
2540 //------------------------------final_graph_reshaping-------------------------- | |
2541 // Final Graph Reshaping. | |
2542 // | |
2543 // (1) Clone simple inputs to uncommon calls, so they can be scheduled late | |
2544 // and not commoned up and forced early. Must come after regular | |
2545 // optimizations to avoid GVN undoing the cloning. Clone constant | |
2546 // inputs to Loop Phis; these will be split by the allocator anyways. | |
2547 // Remove Opaque nodes. | |
2548 // (2) Move last-uses by commutative operations to the left input to encourage | |
2549 // Intel update-in-place two-address operations and better register usage | |
2550 // on RISCs. Must come after regular optimizations to avoid GVN Ideal | |
2551 // calls canonicalizing them back. | |
2552 // (3) Count the number of double-precision FP ops, single-precision FP ops | |
2553 // and call sites. On Intel, we can get correct rounding either by | |
2554 // forcing singles to memory (requires extra stores and loads after each | |
2555 // FP bytecode) or we can set a rounding mode bit (requires setting and | |
2556 // clearing the mode bit around call sites). The mode bit is only used | |
2557 // if the relative frequency of single FP ops to calls is low enough. | |
2558 // This is a key transform for SPEC mpeg_audio. | |
2559 // (4) Detect infinite loops; blobs of code reachable from above but not | |
2560 // below. Several of the Code_Gen algorithms fail on such code shapes, | |
2561 // so we simply bail out. Happens a lot in ZKM.jar, but also happens | |
2562 // from time to time in other codes (such as -Xcomp finalizer loops, etc). | |
2563 // Detection is by looking for IfNodes where only 1 projection is | |
2564 // reachable from below or CatchNodes missing some targets. | |
2565 // (5) Assert for insane oop offsets in debug mode. | |
2566 | |
2567 bool Compile::final_graph_reshaping() { | |
2568 // an infinite loop may have been eliminated by the optimizer, | |
2569 // in which case the graph will be empty. | |
2570 if (root()->req() == 1) { | |
2571 record_method_not_compilable("trivial infinite loop"); | |
2572 return true; | |
2573 } | |
2574 | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2575 Final_Reshape_Counts frc; |
0 | 2576 |
2577 // Visit everybody reachable! | |
2578 // Allocate stack of size C->unique()/2 to avoid frequent realloc | |
2579 Node_Stack nstack(unique() >> 1); | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2580 final_graph_reshaping_walk(nstack, root(), frc); |
0 | 2581 |
2582 // 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
|
2583 for( uint i = 0; i < frc._tests.size(); i++ ) { |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2584 MultiBranchNode *n = frc._tests[i]->as_MultiBranch(); |
127 | 2585 // Get number of CFG targets. |
0 | 2586 // Note that PCTables include exception targets after calls. |
127 | 2587 uint required_outcnt = n->required_outcnt(); |
2588 if (n->outcnt() != required_outcnt) { | |
0 | 2589 // Check for a few special cases. Rethrow Nodes never take the |
2590 // 'fall-thru' path, so expected kids is 1 less. | |
2591 if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { | |
2592 if (n->in(0)->in(0)->is_Call()) { | |
2593 CallNode *call = n->in(0)->in(0)->as_Call(); | |
2594 if (call->entry_point() == OptoRuntime::rethrow_stub()) { | |
127 | 2595 required_outcnt--; // Rethrow always has 1 less kid |
0 | 2596 } else if (call->req() > TypeFunc::Parms && |
2597 call->is_CallDynamicJava()) { | |
2598 // Check for null receiver. In such case, the optimizer has | |
2599 // detected that the virtual call will always result in a null | |
2600 // pointer exception. The fall-through projection of this CatchNode | |
2601 // will not be populated. | |
2602 Node *arg0 = call->in(TypeFunc::Parms); | |
2603 if (arg0->is_Type() && | |
2604 arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { | |
127 | 2605 required_outcnt--; |
0 | 2606 } |
2607 } else if (call->entry_point() == OptoRuntime::new_array_Java() && | |
2608 call->req() > TypeFunc::Parms+1 && | |
2609 call->is_CallStaticJava()) { | |
2610 // Check for negative array length. In such case, the optimizer has | |
2611 // detected that the allocation attempt will always result in an | |
2612 // exception. There is no fall-through projection of this CatchNode . | |
2613 Node *arg1 = call->in(TypeFunc::Parms+1); | |
2614 if (arg1->is_Type() && | |
2615 arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { | |
127 | 2616 required_outcnt--; |
0 | 2617 } |
2618 } | |
2619 } | |
2620 } | |
127 | 2621 // Recheck with a better notion of 'required_outcnt' |
2622 if (n->outcnt() != required_outcnt) { | |
0 | 2623 record_method_not_compilable("malformed control flow"); |
2624 return true; // Not all targets reachable! | |
2625 } | |
2626 } | |
2627 // Check that I actually visited all kids. Unreached kids | |
2628 // must be infinite loops. | |
2629 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
|
2630 if (!frc._visited.test(n->fast_out(j)->_idx)) { |
0 | 2631 record_method_not_compilable("infinite loop"); |
2632 return true; // Found unvisited kid; must be unreach | |
2633 } | |
2634 } | |
2635 | |
2636 // If original bytecodes contained a mixture of floats and doubles | |
2637 // 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
|
2638 if( Use24BitFPMode && Use24BitFP && UseSSE == 0 && |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2639 frc.get_float_count() > 32 && |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2640 frc.get_double_count() == 0 && |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2641 (10 * frc.get_call_count() < frc.get_float_count()) ) { |
0 | 2642 set_24_bit_selection_and_mode( false, true ); |
2643 } | |
2644 | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2645 set_java_calls(frc.get_java_call_count()); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2646 set_inner_loops(frc.get_inner_loop_count()); |
0 | 2647 |
2648 // No infinite loops, no reason to bail out. | |
2649 return false; | |
2650 } | |
2651 | |
2652 //-----------------------------too_many_traps---------------------------------- | |
2653 // Report if there are too many traps at the current method and bci. | |
2654 // Return true if there was a trap, and/or PerMethodTrapLimit is exceeded. | |
2655 bool Compile::too_many_traps(ciMethod* method, | |
2656 int bci, | |
2657 Deoptimization::DeoptReason reason) { | |
2658 ciMethodData* md = method->method_data(); | |
2659 if (md->is_empty()) { | |
2660 // Assume the trap has not occurred, or that it occurred only | |
2661 // because of a transient condition during start-up in the interpreter. | |
2662 return false; | |
2663 } | |
2664 if (md->has_trap_at(bci, reason) != 0) { | |
2665 // Assume PerBytecodeTrapLimit==0, for a more conservative heuristic. | |
2666 // Also, if there are multiple reasons, or if there is no per-BCI record, | |
2667 // assume the worst. | |
2668 if (log()) | |
2669 log()->elem("observe trap='%s' count='%d'", | |
2670 Deoptimization::trap_reason_name(reason), | |
2671 md->trap_count(reason)); | |
2672 return true; | |
2673 } else { | |
2674 // Ignore method/bci and see if there have been too many globally. | |
2675 return too_many_traps(reason, md); | |
2676 } | |
2677 } | |
2678 | |
2679 // Less-accurate variant which does not require a method and bci. | |
2680 bool Compile::too_many_traps(Deoptimization::DeoptReason reason, | |
2681 ciMethodData* logmd) { | |
2682 if (trap_count(reason) >= (uint)PerMethodTrapLimit) { | |
2683 // Too many traps globally. | |
2684 // Note that we use cumulative trap_count, not just md->trap_count. | |
2685 if (log()) { | |
2686 int mcount = (logmd == NULL)? -1: (int)logmd->trap_count(reason); | |
2687 log()->elem("observe trap='%s' count='0' mcount='%d' ccount='%d'", | |
2688 Deoptimization::trap_reason_name(reason), | |
2689 mcount, trap_count(reason)); | |
2690 } | |
2691 return true; | |
2692 } else { | |
2693 // The coast is clear. | |
2694 return false; | |
2695 } | |
2696 } | |
2697 | |
2698 //--------------------------too_many_recompiles-------------------------------- | |
2699 // Report if there are too many recompiles at the current method and bci. | |
2700 // Consults PerBytecodeRecompilationCutoff and PerMethodRecompilationCutoff. | |
2701 // Is not eager to return true, since this will cause the compiler to use | |
2702 // Action_none for a trap point, to avoid too many recompilations. | |
2703 bool Compile::too_many_recompiles(ciMethod* method, | |
2704 int bci, | |
2705 Deoptimization::DeoptReason reason) { | |
2706 ciMethodData* md = method->method_data(); | |
2707 if (md->is_empty()) { | |
2708 // Assume the trap has not occurred, or that it occurred only | |
2709 // because of a transient condition during start-up in the interpreter. | |
2710 return false; | |
2711 } | |
2712 // Pick a cutoff point well within PerBytecodeRecompilationCutoff. | |
2713 uint bc_cutoff = (uint) PerBytecodeRecompilationCutoff / 8; | |
2714 uint m_cutoff = (uint) PerMethodRecompilationCutoff / 2 + 1; // not zero | |
2715 Deoptimization::DeoptReason per_bc_reason | |
2716 = Deoptimization::reason_recorded_per_bytecode_if_any(reason); | |
2717 if ((per_bc_reason == Deoptimization::Reason_none | |
2718 || md->has_trap_at(bci, reason) != 0) | |
2719 // The trap frequency measure we care about is the recompile count: | |
2720 && md->trap_recompiled_at(bci) | |
2721 && md->overflow_recompile_count() >= bc_cutoff) { | |
2722 // Do not emit a trap here if it has already caused recompilations. | |
2723 // Also, if there are multiple reasons, or if there is no per-BCI record, | |
2724 // assume the worst. | |
2725 if (log()) | |
2726 log()->elem("observe trap='%s recompiled' count='%d' recompiles2='%d'", | |
2727 Deoptimization::trap_reason_name(reason), | |
2728 md->trap_count(reason), | |
2729 md->overflow_recompile_count()); | |
2730 return true; | |
2731 } else if (trap_count(reason) != 0 | |
2732 && decompile_count() >= m_cutoff) { | |
2733 // Too many recompiles globally, and we have seen this sort of trap. | |
2734 // Use cumulative decompile_count, not just md->decompile_count. | |
2735 if (log()) | |
2736 log()->elem("observe trap='%s' count='%d' mcount='%d' decompiles='%d' mdecompiles='%d'", | |
2737 Deoptimization::trap_reason_name(reason), | |
2738 md->trap_count(reason), trap_count(reason), | |
2739 md->decompile_count(), decompile_count()); | |
2740 return true; | |
2741 } else { | |
2742 // The coast is clear. | |
2743 return false; | |
2744 } | |
2745 } | |
2746 | |
2747 | |
2748 #ifndef PRODUCT | |
2749 //------------------------------verify_graph_edges--------------------------- | |
2750 // Walk the Graph and verify that there is a one-to-one correspondence | |
2751 // between Use-Def edges and Def-Use edges in the graph. | |
2752 void Compile::verify_graph_edges(bool no_dead_code) { | |
2753 if (VerifyGraphEdges) { | |
2754 ResourceArea *area = Thread::current()->resource_area(); | |
2755 Unique_Node_List visited(area); | |
2756 // Call recursive graph walk to check edges | |
2757 _root->verify_edges(visited); | |
2758 if (no_dead_code) { | |
2759 // Now make sure that no visited node is used by an unvisited node. | |
2760 bool dead_nodes = 0; | |
2761 Unique_Node_List checked(area); | |
2762 while (visited.size() > 0) { | |
2763 Node* n = visited.pop(); | |
2764 checked.push(n); | |
2765 for (uint i = 0; i < n->outcnt(); i++) { | |
2766 Node* use = n->raw_out(i); | |
2767 if (checked.member(use)) continue; // already checked | |
2768 if (visited.member(use)) continue; // already in the graph | |
2769 if (use->is_Con()) continue; // a dead ConNode is OK | |
2770 // At this point, we have found a dead node which is DU-reachable. | |
2771 if (dead_nodes++ == 0) | |
2772 tty->print_cr("*** Dead nodes reachable via DU edges:"); | |
2773 use->dump(2); | |
2774 tty->print_cr("---"); | |
2775 checked.push(use); // No repeats; pretend it is now checked. | |
2776 } | |
2777 } | |
2778 assert(dead_nodes == 0, "using nodes must be reachable from root"); | |
2779 } | |
2780 } | |
2781 } | |
2782 #endif | |
2783 | |
2784 // The Compile object keeps track of failure reasons separately from the ciEnv. | |
2785 // This is required because there is not quite a 1-1 relation between the | |
2786 // ciEnv and its compilation task and the Compile object. Note that one | |
2787 // ciEnv might use two Compile objects, if C2Compiler::compile_method decides | |
2788 // to backtrack and retry without subsuming loads. Other than this backtracking | |
2789 // behavior, the Compile's failure reason is quietly copied up to the ciEnv | |
2790 // by the logic in C2Compiler. | |
2791 void Compile::record_failure(const char* reason) { | |
2792 if (log() != NULL) { | |
2793 log()->elem("failure reason='%s' phase='compile'", reason); | |
2794 } | |
2795 if (_failure_reason == NULL) { | |
2796 // Record the first failure reason. | |
2797 _failure_reason = reason; | |
2798 } | |
222 | 2799 if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) { |
2800 C->print_method(_failure_reason); | |
2801 } | |
0 | 2802 _root = NULL; // flush the graph, too |
2803 } | |
2804 | |
2805 Compile::TracePhase::TracePhase(const char* name, elapsedTimer* accumulator, bool dolog) | |
2806 : TraceTime(NULL, accumulator, false NOT_PRODUCT( || TimeCompiler ), false) | |
2807 { | |
2808 if (dolog) { | |
2809 C = Compile::current(); | |
2810 _log = C->log(); | |
2811 } else { | |
2812 C = NULL; | |
2813 _log = NULL; | |
2814 } | |
2815 if (_log != NULL) { | |
2816 _log->begin_head("phase name='%s' nodes='%d'", name, C->unique()); | |
2817 _log->stamp(); | |
2818 _log->end_head(); | |
2819 } | |
2820 } | |
2821 | |
2822 Compile::TracePhase::~TracePhase() { | |
2823 if (_log != NULL) { | |
2824 _log->done("phase nodes='%d'", C->unique()); | |
2825 } | |
2826 } |