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