Mercurial > hg > truffle
annotate src/share/vm/opto/compile.cpp @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | 1419657ed891 |
children | 45467c53f178 085b304a1cc5 |
rev | line source |
---|---|
0 | 1 /* |
10405 | 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
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" |
7199
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7196
diff
changeset
|
26 #include "asm/macroAssembler.hpp" |
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7196
diff
changeset
|
27 #include "asm/macroAssembler.inline.hpp" |
17622 | 28 #include "ci/ciReplay.hpp" |
1972 | 29 #include "classfile/systemDictionary.hpp" |
30 #include "code/exceptionHandlerTable.hpp" | |
31 #include "code/nmethod.hpp" | |
32 #include "compiler/compileLog.hpp" | |
7199
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7196
diff
changeset
|
33 #include "compiler/disassembler.hpp" |
1972 | 34 #include "compiler/oopMap.hpp" |
35 #include "opto/addnode.hpp" | |
36 #include "opto/block.hpp" | |
37 #include "opto/c2compiler.hpp" | |
38 #include "opto/callGenerator.hpp" | |
39 #include "opto/callnode.hpp" | |
40 #include "opto/cfgnode.hpp" | |
41 #include "opto/chaitin.hpp" | |
42 #include "opto/compile.hpp" | |
43 #include "opto/connode.hpp" | |
44 #include "opto/divnode.hpp" | |
45 #include "opto/escape.hpp" | |
46 #include "opto/idealGraphPrinter.hpp" | |
47 #include "opto/loopnode.hpp" | |
48 #include "opto/machnode.hpp" | |
49 #include "opto/macro.hpp" | |
50 #include "opto/matcher.hpp" | |
12888
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
51 #include "opto/mathexactnode.hpp" |
1972 | 52 #include "opto/memnode.hpp" |
53 #include "opto/mulnode.hpp" | |
54 #include "opto/node.hpp" | |
55 #include "opto/opcodes.hpp" | |
56 #include "opto/output.hpp" | |
57 #include "opto/parse.hpp" | |
58 #include "opto/phaseX.hpp" | |
59 #include "opto/rootnode.hpp" | |
60 #include "opto/runtime.hpp" | |
61 #include "opto/stringopts.hpp" | |
62 #include "opto/type.hpp" | |
63 #include "opto/vectornode.hpp" | |
64 #include "runtime/arguments.hpp" | |
65 #include "runtime/signature.hpp" | |
66 #include "runtime/stubRoutines.hpp" | |
67 #include "runtime/timer.hpp" | |
10405 | 68 #include "trace/tracing.hpp" |
1972 | 69 #include "utilities/copy.hpp" |
70 #ifdef TARGET_ARCH_MODEL_x86_32 | |
71 # include "adfiles/ad_x86_32.hpp" | |
72 #endif | |
73 #ifdef TARGET_ARCH_MODEL_x86_64 | |
74 # include "adfiles/ad_x86_64.hpp" | |
75 #endif | |
76 #ifdef TARGET_ARCH_MODEL_sparc | |
77 # include "adfiles/ad_sparc.hpp" | |
78 #endif | |
79 #ifdef TARGET_ARCH_MODEL_zero | |
80 # include "adfiles/ad_zero.hpp" | |
81 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
82 #ifdef TARGET_ARCH_MODEL_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
83 # include "adfiles/ad_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
84 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
85 #ifdef TARGET_ARCH_MODEL_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
86 # include "adfiles/ad_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
87 #endif |
0 | 88 |
2008 | 89 |
90 // -------------------- Compile::mach_constant_base_node ----------------------- | |
91 // Constant table base node singleton. | |
92 MachConstantBaseNode* Compile::mach_constant_base_node() { | |
93 if (_mach_constant_base_node == NULL) { | |
94 _mach_constant_base_node = new (C) MachConstantBaseNode(); | |
95 _mach_constant_base_node->add_req(C->root()); | |
96 } | |
97 return _mach_constant_base_node; | |
98 } | |
99 | |
100 | |
0 | 101 /// Support for intrinsics. |
102 | |
103 // Return the index at which m must be inserted (or already exists). | |
104 // The sort order is by the address of the ciMethod, with is_virtual as minor key. | |
105 int Compile::intrinsic_insertion_index(ciMethod* m, bool is_virtual) { | |
106 #ifdef ASSERT | |
107 for (int i = 1; i < _intrinsics->length(); i++) { | |
108 CallGenerator* cg1 = _intrinsics->at(i-1); | |
109 CallGenerator* cg2 = _intrinsics->at(i); | |
110 assert(cg1->method() != cg2->method() | |
111 ? cg1->method() < cg2->method() | |
112 : cg1->is_virtual() < cg2->is_virtual(), | |
113 "compiler intrinsics list must stay sorted"); | |
114 } | |
115 #endif | |
116 // Binary search sorted list, in decreasing intervals [lo, hi]. | |
117 int lo = 0, hi = _intrinsics->length()-1; | |
118 while (lo <= hi) { | |
119 int mid = (uint)(hi + lo) / 2; | |
120 ciMethod* mid_m = _intrinsics->at(mid)->method(); | |
121 if (m < mid_m) { | |
122 hi = mid-1; | |
123 } else if (m > mid_m) { | |
124 lo = mid+1; | |
125 } else { | |
126 // look at minor sort key | |
127 bool mid_virt = _intrinsics->at(mid)->is_virtual(); | |
128 if (is_virtual < mid_virt) { | |
129 hi = mid-1; | |
130 } else if (is_virtual > mid_virt) { | |
131 lo = mid+1; | |
132 } else { | |
133 return mid; // exact match | |
134 } | |
135 } | |
136 } | |
137 return lo; // inexact match | |
138 } | |
139 | |
140 void Compile::register_intrinsic(CallGenerator* cg) { | |
141 if (_intrinsics == NULL) { | |
7473 | 142 _intrinsics = new (comp_arena())GrowableArray<CallGenerator*>(comp_arena(), 60, 0, NULL); |
0 | 143 } |
144 // This code is stolen from ciObjectFactory::insert. | |
145 // Really, GrowableArray should have methods for | |
146 // insert_at, remove_at, and binary_search. | |
147 int len = _intrinsics->length(); | |
148 int index = intrinsic_insertion_index(cg->method(), cg->is_virtual()); | |
149 if (index == len) { | |
150 _intrinsics->append(cg); | |
151 } else { | |
152 #ifdef ASSERT | |
153 CallGenerator* oldcg = _intrinsics->at(index); | |
154 assert(oldcg->method() != cg->method() || oldcg->is_virtual() != cg->is_virtual(), "don't register twice"); | |
155 #endif | |
156 _intrinsics->append(_intrinsics->at(len-1)); | |
157 int pos; | |
158 for (pos = len-2; pos >= index; pos--) { | |
159 _intrinsics->at_put(pos+1,_intrinsics->at(pos)); | |
160 } | |
161 _intrinsics->at_put(index, cg); | |
162 } | |
163 assert(find_intrinsic(cg->method(), cg->is_virtual()) == cg, "registration worked"); | |
164 } | |
165 | |
166 CallGenerator* Compile::find_intrinsic(ciMethod* m, bool is_virtual) { | |
167 assert(m->is_loaded(), "don't try this on unloaded methods"); | |
168 if (_intrinsics != NULL) { | |
169 int index = intrinsic_insertion_index(m, is_virtual); | |
170 if (index < _intrinsics->length() | |
171 && _intrinsics->at(index)->method() == m | |
172 && _intrinsics->at(index)->is_virtual() == is_virtual) { | |
173 return _intrinsics->at(index); | |
174 } | |
175 } | |
176 // 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
|
177 if (m->intrinsic_id() != vmIntrinsics::_none && |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
647
diff
changeset
|
178 m->intrinsic_id() <= vmIntrinsics::LAST_COMPILER_INLINE) { |
0 | 179 CallGenerator* cg = make_vm_intrinsic(m, is_virtual); |
180 if (cg != NULL) { | |
181 // Save it for next time: | |
182 register_intrinsic(cg); | |
183 return cg; | |
184 } else { | |
185 gather_intrinsic_statistics(m->intrinsic_id(), is_virtual, _intrinsic_disabled); | |
186 } | |
187 } | |
188 return NULL; | |
189 } | |
190 | |
191 // Compile:: register_library_intrinsics and make_vm_intrinsic are defined | |
192 // in library_call.cpp. | |
193 | |
194 | |
195 #ifndef PRODUCT | |
196 // statistics gathering... | |
197 | |
198 juint Compile::_intrinsic_hist_count[vmIntrinsics::ID_LIMIT] = {0}; | |
199 jubyte Compile::_intrinsic_hist_flags[vmIntrinsics::ID_LIMIT] = {0}; | |
200 | |
201 bool Compile::gather_intrinsic_statistics(vmIntrinsics::ID id, bool is_virtual, int flags) { | |
202 assert(id > vmIntrinsics::_none && id < vmIntrinsics::ID_LIMIT, "oob"); | |
203 int oflags = _intrinsic_hist_flags[id]; | |
204 assert(flags != 0, "what happened?"); | |
205 if (is_virtual) { | |
206 flags |= _intrinsic_virtual; | |
207 } | |
208 bool changed = (flags != oflags); | |
209 if ((flags & _intrinsic_worked) != 0) { | |
210 juint count = (_intrinsic_hist_count[id] += 1); | |
211 if (count == 1) { | |
212 changed = true; // first time | |
213 } | |
214 // increment the overall count also: | |
215 _intrinsic_hist_count[vmIntrinsics::_none] += 1; | |
216 } | |
217 if (changed) { | |
218 if (((oflags ^ flags) & _intrinsic_virtual) != 0) { | |
219 // Something changed about the intrinsic's virtuality. | |
220 if ((flags & _intrinsic_virtual) != 0) { | |
221 // This is the first use of this intrinsic as a virtual call. | |
222 if (oflags != 0) { | |
223 // We already saw it as a non-virtual, so note both cases. | |
224 flags |= _intrinsic_both; | |
225 } | |
226 } else if ((oflags & _intrinsic_both) == 0) { | |
227 // This is the first use of this intrinsic as a non-virtual | |
228 flags |= _intrinsic_both; | |
229 } | |
230 } | |
231 _intrinsic_hist_flags[id] = (jubyte) (oflags | flags); | |
232 } | |
233 // update the overall flags also: | |
234 _intrinsic_hist_flags[vmIntrinsics::_none] |= (jubyte) flags; | |
235 return changed; | |
236 } | |
237 | |
238 static char* format_flags(int flags, char* buf) { | |
239 buf[0] = 0; | |
240 if ((flags & Compile::_intrinsic_worked) != 0) strcat(buf, ",worked"); | |
241 if ((flags & Compile::_intrinsic_failed) != 0) strcat(buf, ",failed"); | |
242 if ((flags & Compile::_intrinsic_disabled) != 0) strcat(buf, ",disabled"); | |
243 if ((flags & Compile::_intrinsic_virtual) != 0) strcat(buf, ",virtual"); | |
244 if ((flags & Compile::_intrinsic_both) != 0) strcat(buf, ",nonvirtual"); | |
245 if (buf[0] == 0) strcat(buf, ","); | |
246 assert(buf[0] == ',', "must be"); | |
247 return &buf[1]; | |
248 } | |
249 | |
250 void Compile::print_intrinsic_statistics() { | |
251 char flagsbuf[100]; | |
252 ttyLocker ttyl; | |
253 if (xtty != NULL) xtty->head("statistics type='intrinsic'"); | |
254 tty->print_cr("Compiler intrinsic usage:"); | |
255 juint total = _intrinsic_hist_count[vmIntrinsics::_none]; | |
256 if (total == 0) total = 1; // avoid div0 in case of no successes | |
257 #define PRINT_STAT_LINE(name, c, f) \ | |
258 tty->print_cr(" %4d (%4.1f%%) %s (%s)", (int)(c), ((c) * 100.0) / total, name, f); | |
259 for (int index = 1 + (int)vmIntrinsics::_none; index < (int)vmIntrinsics::ID_LIMIT; index++) { | |
260 vmIntrinsics::ID id = (vmIntrinsics::ID) index; | |
261 int flags = _intrinsic_hist_flags[id]; | |
262 juint count = _intrinsic_hist_count[id]; | |
263 if ((flags | count) != 0) { | |
264 PRINT_STAT_LINE(vmIntrinsics::name_at(id), count, format_flags(flags, flagsbuf)); | |
265 } | |
266 } | |
267 PRINT_STAT_LINE("total", total, format_flags(_intrinsic_hist_flags[vmIntrinsics::_none], flagsbuf)); | |
268 if (xtty != NULL) xtty->tail("statistics"); | |
269 } | |
270 | |
271 void Compile::print_statistics() { | |
272 { ttyLocker ttyl; | |
273 if (xtty != NULL) xtty->head("statistics type='opto'"); | |
274 Parse::print_statistics(); | |
275 PhaseCCP::print_statistics(); | |
276 PhaseRegAlloc::print_statistics(); | |
277 Scheduling::print_statistics(); | |
278 PhasePeephole::print_statistics(); | |
279 PhaseIdealLoop::print_statistics(); | |
280 if (xtty != NULL) xtty->tail("statistics"); | |
281 } | |
282 if (_intrinsic_hist_flags[vmIntrinsics::_none] != 0) { | |
283 // put this under its own <statistics> element. | |
284 print_intrinsic_statistics(); | |
285 } | |
286 } | |
287 #endif //PRODUCT | |
288 | |
289 // Support for bundling info | |
290 Bundle* Compile::node_bundling(const Node *n) { | |
291 assert(valid_bundle_info(n), "oob"); | |
292 return &_node_bundling_base[n->_idx]; | |
293 } | |
294 | |
295 bool Compile::valid_bundle_info(const Node *n) { | |
296 return (_node_bundling_limit > n->_idx); | |
297 } | |
298 | |
299 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
300 void Compile::gvn_replace_by(Node* n, Node* nn) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
301 for (DUIterator_Last imin, i = n->last_outs(imin); i >= imin; ) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
302 Node* use = n->last_out(i); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
303 bool is_in_table = initial_gvn()->hash_delete(use); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
304 uint uses_found = 0; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
305 for (uint j = 0; j < use->len(); j++) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
306 if (use->in(j) == n) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
307 if (j < use->req()) |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
308 use->set_req(j, nn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
309 else |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
310 use->set_prec(j, nn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
311 uses_found++; |
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 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
314 if (is_in_table) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
315 // reinsert into table |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
316 initial_gvn()->hash_find_insert(use); |
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 record_for_igvn(use); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
319 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
|
320 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
321 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
322 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
323 |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
324 static inline bool not_a_node(const Node* n) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
325 if (n == NULL) return true; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
326 if (((intptr_t)n & 1) != 0) return true; // uninitialized, etc. |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
327 if (*(address*)n == badAddress) return true; // kill by Node::destruct |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
328 return false; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
329 } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
330 |
0 | 331 // Identify all nodes that are reachable from below, useful. |
332 // Use breadth-first pass that records state in a Unique_Node_List, | |
333 // recursive traversal is slower. | |
334 void Compile::identify_useful_nodes(Unique_Node_List &useful) { | |
335 int estimated_worklist_size = unique(); | |
336 useful.map( estimated_worklist_size, NULL ); // preallocate space | |
337 | |
338 // Initialize worklist | |
339 if (root() != NULL) { useful.push(root()); } | |
340 // If 'top' is cached, declare it useful to preserve cached node | |
341 if( cached_top_node() ) { useful.push(cached_top_node()); } | |
342 | |
343 // Push all useful nodes onto the list, breadthfirst | |
344 for( uint next = 0; next < useful.size(); ++next ) { | |
345 assert( next < unique(), "Unique useful nodes < total nodes"); | |
346 Node *n = useful.at(next); | |
347 uint max = n->len(); | |
348 for( uint i = 0; i < max; ++i ) { | |
349 Node *m = n->in(i); | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
350 if (not_a_node(m)) continue; |
0 | 351 useful.push(m); |
352 } | |
353 } | |
354 } | |
355 | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
356 // Update dead_node_list with any missing dead nodes using useful |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
357 // list. Consider all non-useful nodes to be useless i.e., dead nodes. |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
358 void Compile::update_dead_node_list(Unique_Node_List &useful) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
359 uint max_idx = unique(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
360 VectorSet& useful_node_set = useful.member_set(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
361 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
362 for (uint node_idx = 0; node_idx < max_idx; node_idx++) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
363 // If node with index node_idx is not in useful set, |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
364 // mark it as dead in dead node list. |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
365 if (! useful_node_set.test(node_idx) ) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
366 record_dead_node(node_idx); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
367 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
368 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
369 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
370 |
7473 | 371 void Compile::remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful) { |
372 int shift = 0; | |
373 for (int i = 0; i < inlines->length(); i++) { | |
374 CallGenerator* cg = inlines->at(i); | |
375 CallNode* call = cg->call_node(); | |
376 if (shift > 0) { | |
377 inlines->at_put(i-shift, cg); | |
378 } | |
379 if (!useful.member(call)) { | |
380 shift++; | |
381 } | |
382 } | |
383 inlines->trunc_to(inlines->length()-shift); | |
384 } | |
385 | |
0 | 386 // Disconnect all useless nodes by disconnecting those at the boundary. |
387 void Compile::remove_useless_nodes(Unique_Node_List &useful) { | |
388 uint next = 0; | |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
389 while (next < useful.size()) { |
0 | 390 Node *n = useful.at(next++); |
391 // Use raw traversal of out edges since this code removes out edges | |
392 int max = n->outcnt(); | |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
393 for (int j = 0; j < max; ++j) { |
0 | 394 Node* child = n->raw_out(j); |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
395 if (! useful.member(child)) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
396 assert(!child->is_top() || child != top(), |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
397 "If top is cached in Compile object it is in useful list"); |
0 | 398 // Only need to remove this out-edge to the useless node |
399 n->raw_del_out(j); | |
400 --j; | |
401 --max; | |
402 } | |
403 } | |
404 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
|
405 record_for_igvn(n->unique_out()); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
406 } |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
407 } |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
408 // Remove useless macro and predicate opaq nodes |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
409 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
|
410 Node* n = C->macro_node(i); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
411 if (!useful.member(n)) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
412 remove_macro_node(n); |
0 | 413 } |
414 } | |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
415 // Remove useless expensive node |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
416 for (int i = C->expensive_count()-1; i >= 0; i--) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
417 Node* n = C->expensive_node(i); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
418 if (!useful.member(n)) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
419 remove_expensive_node(n); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
420 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
421 } |
7473 | 422 // clean up the late inline lists |
423 remove_useless_late_inlines(&_string_late_inlines, useful); | |
10278 | 424 remove_useless_late_inlines(&_boxing_late_inlines, useful); |
7473 | 425 remove_useless_late_inlines(&_late_inlines, useful); |
0 | 426 debug_only(verify_graph_edges(true/*check for no_dead_code*/);) |
427 } | |
428 | |
429 //------------------------------frame_size_in_words----------------------------- | |
430 // frame_slots in units of words | |
431 int Compile::frame_size_in_words() const { | |
432 // shift is 0 in LP32 and 1 in LP64 | |
433 const int shift = (LogBytesPerWord - LogBytesPerInt); | |
434 int words = _frame_slots >> shift; | |
435 assert( words << shift == _frame_slots, "frame size must be properly aligned in LP64" ); | |
436 return words; | |
437 } | |
438 | |
439 // ============================================================================ | |
440 //------------------------------CompileWrapper--------------------------------- | |
441 class CompileWrapper : public StackObj { | |
442 Compile *const _compile; | |
443 public: | |
444 CompileWrapper(Compile* compile); | |
445 | |
446 ~CompileWrapper(); | |
447 }; | |
448 | |
449 CompileWrapper::CompileWrapper(Compile* compile) : _compile(compile) { | |
450 // the Compile* pointer is stored in the current ciEnv: | |
451 ciEnv* env = compile->env(); | |
452 assert(env == ciEnv::current(), "must already be a ciEnv active"); | |
453 assert(env->compiler_data() == NULL, "compile already active?"); | |
454 env->set_compiler_data(compile); | |
455 assert(compile == Compile::current(), "sanity"); | |
456 | |
457 compile->set_type_dict(NULL); | |
458 compile->set_type_hwm(NULL); | |
459 compile->set_type_last_size(0); | |
460 compile->set_last_tf(NULL, NULL); | |
461 compile->set_indexSet_arena(NULL); | |
462 compile->set_indexSet_free_block_list(NULL); | |
463 compile->init_type_arena(); | |
464 Type::Initialize(compile); | |
465 _compile->set_scratch_buffer_blob(NULL); | |
466 _compile->begin_method(); | |
467 } | |
468 CompileWrapper::~CompileWrapper() { | |
469 _compile->end_method(); | |
470 if (_compile->scratch_buffer_blob() != NULL) | |
471 BufferBlob::free(_compile->scratch_buffer_blob()); | |
472 _compile->env()->set_compiler_data(NULL); | |
473 } | |
474 | |
475 | |
476 //----------------------------print_compile_messages--------------------------- | |
477 void Compile::print_compile_messages() { | |
478 #ifndef PRODUCT | |
479 // Check if recompiling | |
480 if (_subsume_loads == false && PrintOpto) { | |
481 // Recompiling without allowing machine instructions to subsume loads | |
482 tty->print_cr("*********************************************************"); | |
483 tty->print_cr("** Bailout: Recompile without subsuming loads **"); | |
484 tty->print_cr("*********************************************************"); | |
485 } | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
486 if (_do_escape_analysis != DoEscapeAnalysis && PrintOpto) { |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
487 // Recompiling without escape analysis |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
488 tty->print_cr("*********************************************************"); |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
489 tty->print_cr("** Bailout: Recompile without escape analysis **"); |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
490 tty->print_cr("*********************************************************"); |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
491 } |
10278 | 492 if (_eliminate_boxing != EliminateAutoBox && PrintOpto) { |
493 // Recompiling without boxing elimination | |
494 tty->print_cr("*********************************************************"); | |
495 tty->print_cr("** Bailout: Recompile without boxing elimination **"); | |
496 tty->print_cr("*********************************************************"); | |
497 } | |
0 | 498 if (env()->break_at_compile()) { |
605 | 499 // Open the debugger when compiling this method. |
0 | 500 tty->print("### Breaking when compiling: "); |
501 method()->print_short_name(); | |
502 tty->cr(); | |
503 BREAKPOINT; | |
504 } | |
505 | |
506 if( PrintOpto ) { | |
507 if (is_osr_compilation()) { | |
508 tty->print("[OSR]%3d", _compile_id); | |
509 } else { | |
510 tty->print("%3d", _compile_id); | |
511 } | |
512 } | |
513 #endif | |
514 } | |
515 | |
516 | |
2091
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
517 //-----------------------init_scratch_buffer_blob------------------------------ |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
518 // Construct a temporary BufferBlob and cache it for this compile. |
2008 | 519 void Compile::init_scratch_buffer_blob(int const_size) { |
2091
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
520 // 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
|
521 // constant section is big enough, use it. Otherwise free the |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
522 // current and allocate a new one. |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
523 BufferBlob* blob = scratch_buffer_blob(); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
524 if ((blob != NULL) && (const_size <= _scratch_const_size)) { |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
525 // Use the current blob. |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
526 } else { |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
527 if (blob != NULL) { |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
528 BufferBlob::free(blob); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
529 } |
0 | 530 |
2091
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
531 ResourceMark rm; |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
532 _scratch_const_size = const_size; |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
533 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
|
534 blob = BufferBlob::create("Compile::scratch_buffer", size); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
535 // Record the buffer blob for next time. |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
536 set_scratch_buffer_blob(blob); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
537 // Have we run out of code space? |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
538 if (scratch_buffer_blob() == NULL) { |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
539 // Let CompilerBroker disable further compilations. |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
540 record_failure("Not enough space for scratch buffer in CodeCache"); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
541 return; |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
542 } |
163 | 543 } |
0 | 544 |
545 // Initialize the relocation buffers | |
1748 | 546 relocInfo* locs_buf = (relocInfo*) blob->content_end() - MAX_locs_size; |
0 | 547 set_scratch_locs_memory(locs_buf); |
548 } | |
549 | |
550 | |
551 //-----------------------scratch_emit_size------------------------------------- | |
552 // Helper function that computes size by emitting code | |
553 uint Compile::scratch_emit_size(const Node* n) { | |
2008 | 554 // Start scratch_emit_size section. |
555 set_in_scratch_emit_size(true); | |
556 | |
0 | 557 // Emit into a trash buffer and count bytes emitted. |
558 // This is a pretty expensive way to compute a size, | |
559 // but it works well enough if seldom used. | |
560 // All common fixed-size instructions are given a size | |
561 // method by the AD file. | |
562 // Note that the scratch buffer blob and locs memory are | |
563 // allocated at the beginning of the compile task, and | |
564 // may be shared by several calls to scratch_emit_size. | |
565 // The allocation of the scratch buffer blob is particularly | |
566 // expensive, since it has to grab the code cache lock. | |
567 BufferBlob* blob = this->scratch_buffer_blob(); | |
568 assert(blob != NULL, "Initialize BufferBlob at start"); | |
569 assert(blob->size() > MAX_inst_size, "sanity"); | |
570 relocInfo* locs_buf = scratch_locs_memory(); | |
1748 | 571 address blob_begin = blob->content_begin(); |
0 | 572 address blob_end = (address)locs_buf; |
1748 | 573 assert(blob->content_contains(blob_end), "sanity"); |
0 | 574 CodeBuffer buf(blob_begin, blob_end - blob_begin); |
2008 | 575 buf.initialize_consts_size(_scratch_const_size); |
0 | 576 buf.initialize_stubs_size(MAX_stubs_size); |
577 assert(locs_buf != NULL, "sanity"); | |
2008 | 578 int lsize = MAX_locs_size / 3; |
579 buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize); | |
580 buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize); | |
581 buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize); | |
582 | |
583 // Do the emission. | |
3839 | 584 |
585 Label fakeL; // Fake label for branch instructions. | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
586 Label* saveL = NULL; |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
587 uint save_bnum = 0; |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
588 bool is_branch = n->is_MachBranch(); |
3839 | 589 if (is_branch) { |
590 MacroAssembler masm(&buf); | |
591 masm.bind(fakeL); | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
592 n->as_MachBranch()->save_label(&saveL, &save_bnum); |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
593 n->as_MachBranch()->label_set(&fakeL, 0); |
3839 | 594 } |
0 | 595 n->emit(buf, this->regalloc()); |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
596 if (is_branch) // Restore label. |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
597 n->as_MachBranch()->label_set(saveL, save_bnum); |
2008 | 598 |
599 // End scratch_emit_size section. | |
600 set_in_scratch_emit_size(false); | |
601 | |
1748 | 602 return buf.insts_size(); |
0 | 603 } |
604 | |
605 | |
606 // ============================================================================ | |
607 //------------------------------Compile standard------------------------------- | |
608 debug_only( int Compile::_debug_idx = 100000; ) | |
609 | |
610 // Compile a method. entry_bci is -1 for normal compilations and indicates | |
611 // the continuation bci for on stack replacement. | |
612 | |
613 | |
10278 | 614 Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci, |
615 bool subsume_loads, bool do_escape_analysis, bool eliminate_boxing ) | |
0 | 616 : Phase(Compiler), |
617 _env(ci_env), | |
618 _log(ci_env->log()), | |
619 _compile_id(ci_env->compile_id()), | |
620 _save_argument_registers(false), | |
621 _stub_name(NULL), | |
622 _stub_function(NULL), | |
623 _stub_entry_point(NULL), | |
624 _method(target), | |
625 _entry_bci(osr_bci), | |
626 _initial_gvn(NULL), | |
627 _for_igvn(NULL), | |
628 _warm_calls(NULL), | |
629 _subsume_loads(subsume_loads), | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
630 _do_escape_analysis(do_escape_analysis), |
10278 | 631 _eliminate_boxing(eliminate_boxing), |
0 | 632 _failure_reason(NULL), |
633 _code_buffer("Compile::Fill_buffer"), | |
634 _orig_pc_slot(0), | |
635 _orig_pc_slot_offset_in_bytes(0), | |
1265 | 636 _has_method_handle_invokes(false), |
2008 | 637 _mach_constant_base_node(NULL), |
0 | 638 _node_bundling_limit(0), |
639 _node_bundling_base(NULL), | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
640 _java_calls(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
641 _inner_loops(0), |
2008 | 642 _scratch_const_size(-1), |
643 _in_scratch_emit_size(false), | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
644 _dead_node_list(comp_arena()), |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
645 _dead_node_count(0), |
0 | 646 #ifndef PRODUCT |
647 _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")), | |
648 _printer(IdealGraphPrinter::printer()), | |
649 #endif | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
650 _congraph(NULL), |
17622 | 651 _replay_inline_data(NULL), |
7473 | 652 _late_inlines(comp_arena(), 2, 0, NULL), |
653 _string_late_inlines(comp_arena(), 2, 0, NULL), | |
10278 | 654 _boxing_late_inlines(comp_arena(), 2, 0, NULL), |
7473 | 655 _late_inlines_pos(0), |
656 _number_of_mh_late_inlines(0), | |
657 _inlining_progress(false), | |
658 _inlining_incrementally(false), | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
659 _print_inlining_list(NULL), |
12956
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12888
diff
changeset
|
660 _print_inlining_idx(0), |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12888
diff
changeset
|
661 _preserve_jvm_state(0) { |
0 | 662 C = this; |
663 | |
664 CompileWrapper cw(this); | |
665 #ifndef PRODUCT | |
666 if (TimeCompiler2) { | |
667 tty->print(" "); | |
668 target->holder()->name()->print(); | |
669 tty->print("."); | |
670 target->print_short_name(); | |
671 tty->print(" "); | |
672 } | |
673 TraceTime t1("Total compilation time", &_t_totalCompilation, TimeCompiler, TimeCompiler2); | |
674 TraceTime t2(NULL, &_t_methodCompilation, TimeCompiler, false); | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
675 bool print_opto_assembly = PrintOptoAssembly || _method->has_option("PrintOptoAssembly"); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
676 if (!print_opto_assembly) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
677 bool print_assembly = (PrintAssembly || _method->should_print_assembly()); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
678 if (print_assembly && !Disassembler::can_decode()) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
679 tty->print_cr("PrintAssembly request changed to PrintOptoAssembly"); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
680 print_opto_assembly = true; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
681 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
682 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
683 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
|
684 set_parsed_irreducible_loop(false); |
17622 | 685 |
686 if (method()->has_option("ReplayInline")) { | |
687 _replay_inline_data = ciReplay::load_inline_data(method(), entry_bci(), ci_env->comp_level()); | |
688 } | |
0 | 689 #endif |
12295 | 690 set_print_inlining(PrintInlining || method()->has_option("PrintInlining") NOT_PRODUCT( || PrintOptoInlining)); |
691 set_print_intrinsics(PrintIntrinsics || method()->has_option("PrintIntrinsics")); | |
0 | 692 |
693 if (ProfileTraps) { | |
694 // Make sure the method being compiled gets its own MDO, | |
695 // 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
|
696 method()->ensure_method_data(); |
0 | 697 } |
698 | |
699 Init(::AliasLevel); | |
700 | |
701 | |
702 print_compile_messages(); | |
703 | |
17672 | 704 _ilt = InlineTree::build_inline_tree_root(); |
0 | 705 |
706 // Even if NO memory addresses are used, MergeMem nodes must have at least 1 slice | |
707 assert(num_alias_types() >= AliasIdxRaw, ""); | |
708 | |
709 #define MINIMUM_NODE_HASH 1023 | |
710 // Node list that Iterative GVN will start with | |
711 Unique_Node_List for_igvn(comp_arena()); | |
712 set_for_igvn(&for_igvn); | |
713 | |
714 // GVN that will be run immediately on new nodes | |
715 uint estimated_size = method()->code_size()*4+64; | |
716 estimated_size = (estimated_size < MINIMUM_NODE_HASH ? MINIMUM_NODE_HASH : estimated_size); | |
717 PhaseGVN gvn(node_arena(), estimated_size); | |
718 set_initial_gvn(&gvn); | |
719 | |
12295 | 720 if (print_inlining() || print_intrinsics()) { |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
721 _print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer()); |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
722 } |
0 | 723 { // Scope for timing the parser |
724 TracePhase t3("parse", &_t_parser, true); | |
725 | |
726 // Put top into the hash table ASAP. | |
727 initial_gvn()->transform_no_reclaim(top()); | |
728 | |
729 // 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
|
730 CallGenerator* cg = NULL; |
0 | 731 if (is_osr_compilation()) { |
732 const TypeTuple *domain = StartOSRNode::osr_domain(); | |
733 const TypeTuple *range = TypeTuple::make_range(method()->signature()); | |
734 init_tf(TypeFunc::make(domain, range)); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
735 StartNode* s = new (this) StartOSRNode(root(), domain); |
0 | 736 initial_gvn()->set_type_bottom(s); |
737 init_start(s); | |
738 cg = CallGenerator::for_osr(method(), entry_bci()); | |
739 } else { | |
740 // Normal case. | |
741 init_tf(TypeFunc::make(method())); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
742 StartNode* s = new (this) StartNode(root(), tf()->domain()); |
0 | 743 initial_gvn()->set_type_bottom(s); |
744 init_start(s); | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
745 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
|
746 // 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
|
747 // 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
|
748 // 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
|
749 // 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
|
750 // the pre-barrier code. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
751 // 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
|
752 // 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
|
753 // 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
|
754 // 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
|
755 // reference processing. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
756 cg = find_intrinsic(method(), false); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
757 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
758 if (cg == NULL) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
759 float past_uses = method()->interpreter_invocation_count(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
760 float expected_uses = past_uses; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
761 cg = CallGenerator::for_inline(method(), expected_uses); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
762 } |
0 | 763 } |
764 if (failing()) return; | |
765 if (cg == NULL) { | |
766 record_method_not_compilable_all_tiers("cannot parse method"); | |
767 return; | |
768 } | |
769 JVMState* jvms = build_start_state(start(), tf()); | |
12956
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12888
diff
changeset
|
770 if ((jvms = cg->generate(jvms, NULL)) == NULL) { |
0 | 771 record_method_not_compilable("method parse failed"); |
772 return; | |
773 } | |
774 GraphKit kit(jvms); | |
775 | |
776 if (!kit.stopped()) { | |
777 // Accept return values, and transfer control we know not where. | |
778 // This is done by a special, unique ReturnNode bound to root. | |
779 return_values(kit.jvms()); | |
780 } | |
781 | |
782 if (kit.has_exceptions()) { | |
783 // Any exceptions that escape from this call must be rethrown | |
784 // to whatever caller is dynamically above us on the stack. | |
785 // This is done by a special, unique RethrowNode bound to root. | |
786 rethrow_exceptions(kit.transfer_exceptions_into_jvms()); | |
787 } | |
788 | |
7473 | 789 assert(IncrementalInline || (_late_inlines.length() == 0 && !has_mh_late_inlines()), "incremental inlining is off"); |
790 | |
791 if (_late_inlines.length() == 0 && !has_mh_late_inlines() && !failing() && has_stringbuilder()) { | |
792 inline_string_calls(true); | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
793 } |
7473 | 794 |
795 if (failing()) return; | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
796 |
10405 | 797 print_method(PHASE_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
|
798 |
0 | 799 // Remove clutter produced by parsing. |
800 if (!failing()) { | |
801 ResourceMark rm; | |
802 PhaseRemoveUseless pru(initial_gvn(), &for_igvn); | |
803 } | |
804 } | |
805 | |
806 // Note: Large methods are capped off in do_one_bytecode(). | |
807 if (failing()) return; | |
808 | |
809 // After parsing, node notes are no longer automagic. | |
810 // They must be propagated by register_new_node_with_optimizer(), | |
811 // clone(), or the like. | |
812 set_default_node_notes(NULL); | |
813 | |
814 for (;;) { | |
815 int successes = Inline_Warm(); | |
816 if (failing()) return; | |
817 if (successes == 0) break; | |
818 } | |
819 | |
820 // Drain the list. | |
821 Finish_Warm(); | |
822 #ifndef PRODUCT | |
823 if (_printer) { | |
824 _printer->print_inlining(this); | |
825 } | |
826 #endif | |
827 | |
828 if (failing()) return; | |
829 NOT_PRODUCT( verify_graph_edges(); ) | |
830 | |
831 // Now optimize | |
832 Optimize(); | |
833 if (failing()) return; | |
834 NOT_PRODUCT( verify_graph_edges(); ) | |
835 | |
836 #ifndef PRODUCT | |
837 if (PrintIdeal) { | |
838 ttyLocker ttyl; // keep the following output all in one block | |
839 // This output goes directly to the tty, not the compiler log. | |
840 // To enable tools to match it up with the compilation activity, | |
841 // be sure to tag this tty output with the compile ID. | |
842 if (xtty != NULL) { | |
843 xtty->head("ideal compile_id='%d'%s", compile_id(), | |
844 is_osr_compilation() ? " compile_kind='osr'" : | |
845 ""); | |
846 } | |
847 root()->dump(9999); | |
848 if (xtty != NULL) { | |
849 xtty->tail("ideal"); | |
850 } | |
851 } | |
852 #endif | |
853 | |
13045
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
854 NOT_PRODUCT( verify_barriers(); ) |
17622 | 855 |
856 // Dump compilation data to replay it. | |
857 if (method()->has_option("DumpReplay")) { | |
858 env()->dump_replay_data(_compile_id); | |
859 } | |
860 if (method()->has_option("DumpInline") && (ilt() != NULL)) { | |
861 env()->dump_inline_data(_compile_id); | |
862 } | |
863 | |
0 | 864 // Now that we know the size of all the monitors we can add a fixed slot |
865 // for the original deopt pc. | |
866 | |
867 _orig_pc_slot = fixed_slots(); | |
868 int next_slot = _orig_pc_slot + (sizeof(address) / VMRegImpl::stack_slot_size); | |
869 set_fixed_slots(next_slot); | |
870 | |
871 // Now generate code | |
872 Code_Gen(); | |
873 if (failing()) return; | |
874 | |
875 // Check if we want to skip execution of all compiled code. | |
876 { | |
877 #ifndef PRODUCT | |
878 if (OptoNoExecute) { | |
879 record_method_not_compilable("+OptoNoExecute"); // Flag as failed | |
880 return; | |
881 } | |
882 TracePhase t2("install_code", &_t_registerMethod, TimeCompiler); | |
883 #endif | |
884 | |
885 if (is_osr_compilation()) { | |
886 _code_offsets.set_value(CodeOffsets::Verified_Entry, 0); | |
887 _code_offsets.set_value(CodeOffsets::OSR_Entry, _first_block_size); | |
888 } else { | |
889 _code_offsets.set_value(CodeOffsets::Verified_Entry, _first_block_size); | |
890 _code_offsets.set_value(CodeOffsets::OSR_Entry, 0); | |
891 } | |
892 | |
893 env()->register_method(_method, _entry_bci, | |
894 &_code_offsets, | |
895 _orig_pc_slot_offset_in_bytes, | |
896 code_buffer(), | |
897 frame_size_in_words(), _oop_map_set, | |
898 &_handler_table, &_inc_table, | |
899 compiler, | |
900 env()->comp_level(), | |
6792
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6725
diff
changeset
|
901 has_unsafe_access(), |
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6725
diff
changeset
|
902 SharedRuntime::is_wide_vector(max_vector_size()) |
0 | 903 ); |
6843 | 904 |
905 if (log() != NULL) // Print code cache state into compiler log | |
906 log()->code_cache_state(); | |
0 | 907 } |
908 } | |
909 | |
910 //------------------------------Compile---------------------------------------- | |
911 // Compile a runtime stub | |
912 Compile::Compile( ciEnv* ci_env, | |
913 TypeFunc_generator generator, | |
914 address stub_function, | |
915 const char *stub_name, | |
916 int is_fancy_jump, | |
917 bool pass_tls, | |
918 bool save_arg_registers, | |
919 bool return_pc ) | |
920 : Phase(Compiler), | |
921 _env(ci_env), | |
922 _log(ci_env->log()), | |
8730
b7c2c5b2572c
8005772: Stubs report compile id -1 in phase events
neliasso
parents:
8694
diff
changeset
|
923 _compile_id(0), |
0 | 924 _save_argument_registers(save_arg_registers), |
925 _method(NULL), | |
926 _stub_name(stub_name), | |
927 _stub_function(stub_function), | |
928 _stub_entry_point(NULL), | |
929 _entry_bci(InvocationEntryBci), | |
930 _initial_gvn(NULL), | |
931 _for_igvn(NULL), | |
932 _warm_calls(NULL), | |
933 _orig_pc_slot(0), | |
934 _orig_pc_slot_offset_in_bytes(0), | |
935 _subsume_loads(true), | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
936 _do_escape_analysis(false), |
10278 | 937 _eliminate_boxing(false), |
0 | 938 _failure_reason(NULL), |
939 _code_buffer("Compile::Fill_buffer"), | |
1265 | 940 _has_method_handle_invokes(false), |
2008 | 941 _mach_constant_base_node(NULL), |
0 | 942 _node_bundling_limit(0), |
943 _node_bundling_base(NULL), | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
944 _java_calls(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
945 _inner_loops(0), |
0 | 946 #ifndef PRODUCT |
947 _trace_opto_output(TraceOptoOutput), | |
948 _printer(NULL), | |
949 #endif | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
950 _dead_node_list(comp_arena()), |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
951 _dead_node_count(0), |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
952 _congraph(NULL), |
17622 | 953 _replay_inline_data(NULL), |
7473 | 954 _number_of_mh_late_inlines(0), |
955 _inlining_progress(false), | |
956 _inlining_incrementally(false), | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
957 _print_inlining_list(NULL), |
12956
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12888
diff
changeset
|
958 _print_inlining_idx(0), |
3213ba4d3dff
8024069: replace_in_map() should operate on parent maps
roland
parents:
12888
diff
changeset
|
959 _preserve_jvm_state(0) { |
0 | 960 C = this; |
961 | |
962 #ifndef PRODUCT | |
963 TraceTime t1(NULL, &_t_totalCompilation, TimeCompiler, false); | |
964 TraceTime t2(NULL, &_t_stubCompilation, TimeCompiler, false); | |
965 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
|
966 set_parsed_irreducible_loop(false); |
0 | 967 #endif |
968 CompileWrapper cw(this); | |
969 Init(/*AliasLevel=*/ 0); | |
970 init_tf((*generator)()); | |
971 | |
972 { | |
973 // The following is a dummy for the sake of GraphKit::gen_stub | |
974 Unique_Node_List for_igvn(comp_arena()); | |
975 set_for_igvn(&for_igvn); // not used, but some GraphKit guys push on this | |
976 PhaseGVN gvn(Thread::current()->resource_area(),255); | |
977 set_initial_gvn(&gvn); // not significant, but GraphKit guys use it pervasively | |
978 gvn.transform_no_reclaim(top()); | |
979 | |
980 GraphKit kit; | |
981 kit.gen_stub(stub_function, stub_name, is_fancy_jump, pass_tls, return_pc); | |
982 } | |
983 | |
984 NOT_PRODUCT( verify_graph_edges(); ) | |
985 Code_Gen(); | |
986 if (failing()) return; | |
987 | |
988 | |
989 // Entry point will be accessed using compile->stub_entry_point(); | |
990 if (code_buffer() == NULL) { | |
991 Matcher::soft_match_failure(); | |
992 } else { | |
993 if (PrintAssembly && (WizardMode || Verbose)) | |
994 tty->print_cr("### Stub::%s", stub_name); | |
995 | |
996 if (!failing()) { | |
997 assert(_fixed_slots == 0, "no fixed slots used for runtime stubs"); | |
998 | |
999 // Make the NMethod | |
1000 // For now we mark the frame as never safe for profile stackwalking | |
1001 RuntimeStub *rs = RuntimeStub::new_runtime_stub(stub_name, | |
1002 code_buffer(), | |
1003 CodeOffsets::frame_never_safe, | |
1004 // _code_offsets.value(CodeOffsets::Frame_Complete), | |
1005 frame_size_in_words(), | |
1006 _oop_map_set, | |
1007 save_arg_registers); | |
1008 assert(rs != NULL && rs->is_runtime_stub(), "sanity check"); | |
1009 | |
1010 _stub_entry_point = rs->entry_point(); | |
1011 } | |
1012 } | |
1013 } | |
1014 | |
1015 //------------------------------Init------------------------------------------- | |
1016 // Prepare for a single compilation | |
1017 void Compile::Init(int aliaslevel) { | |
1018 _unique = 0; | |
1019 _regalloc = NULL; | |
1020 | |
1021 _tf = NULL; // filled in later | |
1022 _top = NULL; // cached later | |
1023 _matcher = NULL; // filled in later | |
1024 _cfg = NULL; // filled in later | |
1025 | |
1026 set_24_bit_selection_and_mode(Use24BitFP, false); | |
1027 | |
1028 _node_note_array = NULL; | |
1029 _default_node_notes = NULL; | |
1030 | |
1031 _immutable_memory = NULL; // filled in at first inquiry | |
1032 | |
1033 // Globally visible Nodes | |
1034 // First set TOP to NULL to give safe behavior during creation of RootNode | |
1035 set_cached_top_node(NULL); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
1036 set_root(new (this) RootNode()); |
0 | 1037 // Now that you have a Root to point to, create the real TOP |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
1038 set_cached_top_node( new (this) ConNode(Type::TOP) ); |
0 | 1039 set_recent_alloc(NULL, NULL); |
1040 | |
1041 // Create Debug Information Recorder to record scopes, oopmaps, etc. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
1042 env()->set_oop_recorder(new OopRecorder(env()->arena())); |
0 | 1043 env()->set_debug_info(new DebugInformationRecorder(env()->oop_recorder())); |
1044 env()->set_dependencies(new Dependencies(env())); | |
1045 | |
1046 _fixed_slots = 0; | |
1047 set_has_split_ifs(false); | |
1048 set_has_loops(has_method() && method()->has_loops()); // first approximation | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
1049 set_has_stringbuilder(false); |
10278 | 1050 set_has_boxed_value(false); |
0 | 1051 _trap_can_recompile = false; // no traps emitted yet |
1052 _major_progress = true; // start out assuming good things will happen | |
1053 set_has_unsafe_access(false); | |
6792
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6725
diff
changeset
|
1054 set_max_vector_size(0); |
0 | 1055 Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist)); |
1056 set_decompile_count(0); | |
1057 | |
418 | 1058 set_do_freq_based_layout(BlockLayoutByFrequency || method_has_option("BlockLayoutByFrequency")); |
1783 | 1059 set_num_loop_opts(LoopOptsCount); |
1060 set_do_inlining(Inline); | |
1061 set_max_inline_size(MaxInlineSize); | |
1062 set_freq_inline_size(FreqInlineSize); | |
1063 set_do_scheduling(OptoScheduling); | |
1064 set_do_count_invocations(false); | |
1065 set_do_method_data_update(false); | |
0 | 1066 |
1067 if (debug_info()->recording_non_safepoints()) { | |
1068 set_node_note_array(new(comp_arena()) GrowableArray<Node_Notes*> | |
1069 (comp_arena(), 8, 0, NULL)); | |
1070 set_default_node_notes(Node_Notes::make(this)); | |
1071 } | |
1072 | |
1073 // // -- Initialize types before each compile -- | |
1074 // // Update cached type information | |
1075 // if( _method && _method->constants() ) | |
1076 // Type::update_loaded_types(_method, _method->constants()); | |
1077 | |
1078 // Init alias_type map. | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
1079 if (!_do_escape_analysis && aliaslevel == 3) |
0 | 1080 aliaslevel = 2; // No unique types without escape analysis |
1081 _AliasLevel = aliaslevel; | |
1082 const int grow_ats = 16; | |
1083 _max_alias_types = grow_ats; | |
1084 _alias_types = NEW_ARENA_ARRAY(comp_arena(), AliasType*, grow_ats); | |
1085 AliasType* ats = NEW_ARENA_ARRAY(comp_arena(), AliasType, grow_ats); | |
1086 Copy::zero_to_bytes(ats, sizeof(AliasType)*grow_ats); | |
1087 { | |
1088 for (int i = 0; i < grow_ats; i++) _alias_types[i] = &ats[i]; | |
1089 } | |
1090 // Initialize the first few types. | |
1091 _alias_types[AliasIdxTop]->Init(AliasIdxTop, NULL); | |
1092 _alias_types[AliasIdxBot]->Init(AliasIdxBot, TypePtr::BOTTOM); | |
1093 _alias_types[AliasIdxRaw]->Init(AliasIdxRaw, TypeRawPtr::BOTTOM); | |
1094 _num_alias_types = AliasIdxRaw+1; | |
1095 // Zero out the alias type cache. | |
1096 Copy::zero_to_bytes(_alias_cache, sizeof(_alias_cache)); | |
1097 // A NULL adr_type hits in the cache right away. Preload the right answer. | |
1098 probe_alias_cache(NULL)->_index = AliasIdxTop; | |
1099 | |
1100 _intrinsics = NULL; | |
1685 | 1101 _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
1102 _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
1103 _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
0 | 1104 register_library_intrinsics(); |
1105 } | |
1106 | |
1107 //---------------------------init_start---------------------------------------- | |
1108 // Install the StartNode on this compile object. | |
1109 void Compile::init_start(StartNode* s) { | |
1110 if (failing()) | |
1111 return; // already failing | |
1112 assert(s == start(), ""); | |
1113 } | |
1114 | |
1115 StartNode* Compile::start() const { | |
1116 assert(!failing(), ""); | |
1117 for (DUIterator_Fast imax, i = root()->fast_outs(imax); i < imax; i++) { | |
1118 Node* start = root()->fast_out(i); | |
1119 if( start->is_Start() ) | |
1120 return start->as_Start(); | |
1121 } | |
1122 ShouldNotReachHere(); | |
1123 return NULL; | |
1124 } | |
1125 | |
1126 //-------------------------------immutable_memory------------------------------------- | |
1127 // Access immutable memory | |
1128 Node* Compile::immutable_memory() { | |
1129 if (_immutable_memory != NULL) { | |
1130 return _immutable_memory; | |
1131 } | |
1132 StartNode* s = start(); | |
1133 for (DUIterator_Fast imax, i = s->fast_outs(imax); true; i++) { | |
1134 Node *p = s->fast_out(i); | |
1135 if (p != s && p->as_Proj()->_con == TypeFunc::Memory) { | |
1136 _immutable_memory = p; | |
1137 return _immutable_memory; | |
1138 } | |
1139 } | |
1140 ShouldNotReachHere(); | |
1141 return NULL; | |
1142 } | |
1143 | |
1144 //----------------------set_cached_top_node------------------------------------ | |
1145 // Install the cached top node, and make sure Node::is_top works correctly. | |
1146 void Compile::set_cached_top_node(Node* tn) { | |
1147 if (tn != NULL) verify_top(tn); | |
1148 Node* old_top = _top; | |
1149 _top = tn; | |
1150 // Calling Node::setup_is_top allows the nodes the chance to adjust | |
1151 // their _out arrays. | |
1152 if (_top != NULL) _top->setup_is_top(); | |
1153 if (old_top != NULL) old_top->setup_is_top(); | |
1154 assert(_top == NULL || top()->is_top(), ""); | |
1155 } | |
1156 | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1157 #ifdef ASSERT |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1158 uint Compile::count_live_nodes_by_graph_walk() { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1159 Unique_Node_List useful(comp_arena()); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1160 // Get useful node list by walking the graph. |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1161 identify_useful_nodes(useful); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1162 return useful.size(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1163 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1164 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1165 void Compile::print_missing_nodes() { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1166 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1167 // Return if CompileLog is NULL and PrintIdealNodeCount is false. |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1168 if ((_log == NULL) && (! PrintIdealNodeCount)) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1169 return; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1170 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1171 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1172 // This is an expensive function. It is executed only when the user |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1173 // specifies VerifyIdealNodeCount option or otherwise knows the |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1174 // additional work that needs to be done to identify reachable nodes |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1175 // by walking the flow graph and find the missing ones using |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1176 // _dead_node_list. |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1177 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1178 Unique_Node_List useful(comp_arena()); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1179 // Get useful node list by walking the graph. |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1180 identify_useful_nodes(useful); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1181 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1182 uint l_nodes = C->live_nodes(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1183 uint l_nodes_by_walk = useful.size(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1184 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1185 if (l_nodes != l_nodes_by_walk) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1186 if (_log != NULL) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1187 _log->begin_head("mismatched_nodes count='%d'", abs((int) (l_nodes - l_nodes_by_walk))); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1188 _log->stamp(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1189 _log->end_head(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1190 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1191 VectorSet& useful_member_set = useful.member_set(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1192 int last_idx = l_nodes_by_walk; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1193 for (int i = 0; i < last_idx; i++) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1194 if (useful_member_set.test(i)) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1195 if (_dead_node_list.test(i)) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1196 if (_log != NULL) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1197 _log->elem("mismatched_node_info node_idx='%d' type='both live and dead'", i); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1198 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1199 if (PrintIdealNodeCount) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1200 // Print the log message to tty |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1201 tty->print_cr("mismatched_node idx='%d' both live and dead'", i); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1202 useful.at(i)->dump(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1203 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1204 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1205 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1206 else if (! _dead_node_list.test(i)) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1207 if (_log != NULL) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1208 _log->elem("mismatched_node_info node_idx='%d' type='neither live nor dead'", i); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1209 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1210 if (PrintIdealNodeCount) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1211 // Print the log message to tty |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1212 tty->print_cr("mismatched_node idx='%d' type='neither live nor dead'", i); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1213 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1214 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1215 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1216 if (_log != NULL) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1217 _log->tail("mismatched_nodes"); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1218 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1219 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1220 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1221 #endif |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
1222 |
0 | 1223 #ifndef PRODUCT |
1224 void Compile::verify_top(Node* tn) const { | |
1225 if (tn != NULL) { | |
1226 assert(tn->is_Con(), "top node must be a constant"); | |
1227 assert(((ConNode*)tn)->type() == Type::TOP, "top node must have correct type"); | |
1228 assert(tn->in(0) != NULL, "must have live top node"); | |
1229 } | |
1230 } | |
1231 #endif | |
1232 | |
1233 | |
1234 ///-------------------Managing Per-Node Debug & Profile Info------------------- | |
1235 | |
1236 void Compile::grow_node_notes(GrowableArray<Node_Notes*>* arr, int grow_by) { | |
1237 guarantee(arr != NULL, ""); | |
1238 int num_blocks = arr->length(); | |
1239 if (grow_by < num_blocks) grow_by = num_blocks; | |
1240 int num_notes = grow_by * _node_notes_block_size; | |
1241 Node_Notes* notes = NEW_ARENA_ARRAY(node_arena(), Node_Notes, num_notes); | |
1242 Copy::zero_to_bytes(notes, num_notes * sizeof(Node_Notes)); | |
1243 while (num_notes > 0) { | |
1244 arr->append(notes); | |
1245 notes += _node_notes_block_size; | |
1246 num_notes -= _node_notes_block_size; | |
1247 } | |
1248 assert(num_notes == 0, "exact multiple, please"); | |
1249 } | |
1250 | |
1251 bool Compile::copy_node_notes_to(Node* dest, Node* source) { | |
1252 if (source == NULL || dest == NULL) return false; | |
1253 | |
1254 if (dest->is_Con()) | |
1255 return false; // Do not push debug info onto constants. | |
1256 | |
1257 #ifdef ASSERT | |
1258 // Leave a bread crumb trail pointing to the original node: | |
1259 if (dest != NULL && dest != source && dest->debug_orig() == NULL) { | |
1260 dest->set_debug_orig(source); | |
1261 } | |
1262 #endif | |
1263 | |
1264 if (node_note_array() == NULL) | |
1265 return false; // Not collecting any notes now. | |
1266 | |
1267 // This is a copy onto a pre-existing node, which may already have notes. | |
1268 // If both nodes have notes, do not overwrite any pre-existing notes. | |
1269 Node_Notes* source_notes = node_notes_at(source->_idx); | |
1270 if (source_notes == NULL || source_notes->is_clear()) return false; | |
1271 Node_Notes* dest_notes = node_notes_at(dest->_idx); | |
1272 if (dest_notes == NULL || dest_notes->is_clear()) { | |
1273 return set_node_notes_at(dest->_idx, source_notes); | |
1274 } | |
1275 | |
1276 Node_Notes merged_notes = (*source_notes); | |
1277 // The order of operations here ensures that dest notes will win... | |
1278 merged_notes.update_from(dest_notes); | |
1279 return set_node_notes_at(dest->_idx, &merged_notes); | |
1280 } | |
1281 | |
1282 | |
1283 //--------------------------allow_range_check_smearing------------------------- | |
1284 // Gating condition for coalescing similar range checks. | |
1285 // Sometimes we try 'speculatively' replacing a series of a range checks by a | |
1286 // single covering check that is at least as strong as any of them. | |
1287 // If the optimization succeeds, the simplified (strengthened) range check | |
1288 // will always succeed. If it fails, we will deopt, and then give up | |
1289 // on the optimization. | |
1290 bool Compile::allow_range_check_smearing() const { | |
1291 // If this method has already thrown a range-check, | |
1292 // assume it was because we already tried range smearing | |
1293 // and it failed. | |
1294 uint already_trapped = trap_count(Deoptimization::Reason_range_check); | |
1295 return !already_trapped; | |
1296 } | |
1297 | |
1298 | |
1299 //------------------------------flatten_alias_type----------------------------- | |
1300 const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { | |
1301 int offset = tj->offset(); | |
1302 TypePtr::PTR ptr = tj->ptr(); | |
1303 | |
247 | 1304 // Known instance (scalarizable allocation) alias only with itself. |
1305 bool is_known_inst = tj->isa_oopptr() != NULL && | |
1306 tj->is_oopptr()->is_known_instance(); | |
1307 | |
0 | 1308 // Process weird unsafe references. |
1309 if (offset == Type::OffsetBot && (tj->isa_instptr() /*|| tj->isa_klassptr()*/)) { | |
1310 assert(InlineUnsafeOps, "indeterminate pointers come only from unsafe ops"); | |
247 | 1311 assert(!is_known_inst, "scalarizable allocation should not have unsafe references"); |
0 | 1312 tj = TypeOopPtr::BOTTOM; |
1313 ptr = tj->ptr(); | |
1314 offset = tj->offset(); | |
1315 } | |
1316 | |
1317 // Array pointers need some flattening | |
1318 const TypeAryPtr *ta = tj->isa_aryptr(); | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1319 if (ta && ta->is_stable()) { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1320 // Erase stability property for alias analysis. |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1321 tj = ta = ta->cast_to_stable(false); |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1322 } |
247 | 1323 if( ta && is_known_inst ) { |
1324 if ( offset != Type::OffsetBot && | |
1325 offset > arrayOopDesc::length_offset_in_bytes() ) { | |
1326 offset = Type::OffsetBot; // Flatten constant access into array body only | |
1327 tj = ta = TypeAryPtr::make(ptr, ta->ary(), ta->klass(), true, offset, ta->instance_id()); | |
1328 } | |
1329 } else if( ta && _AliasLevel >= 2 ) { | |
0 | 1330 // For arrays indexed by constant indices, we flatten the alias |
1331 // space to include all of the array body. Only the header, klass | |
1332 // and array length can be accessed un-aliased. | |
1333 if( offset != Type::OffsetBot ) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
1334 if( ta->const_oop() ) { // MethodData* or Method* |
0 | 1335 offset = Type::OffsetBot; // Flatten constant access into array body |
247 | 1336 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset); |
0 | 1337 } else if( offset == arrayOopDesc::length_offset_in_bytes() ) { |
1338 // range is OK as-is. | |
1339 tj = ta = TypeAryPtr::RANGE; | |
1340 } else if( offset == oopDesc::klass_offset_in_bytes() ) { | |
1341 tj = TypeInstPtr::KLASS; // all klass loads look alike | |
1342 ta = TypeAryPtr::RANGE; // generic ignored junk | |
1343 ptr = TypePtr::BotPTR; | |
1344 } else if( offset == oopDesc::mark_offset_in_bytes() ) { | |
1345 tj = TypeInstPtr::MARK; | |
1346 ta = TypeAryPtr::RANGE; // generic ignored junk | |
1347 ptr = TypePtr::BotPTR; | |
1348 } else { // Random constant offset into array body | |
1349 offset = Type::OffsetBot; // Flatten constant access into array body | |
247 | 1350 tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset); |
0 | 1351 } |
1352 } | |
1353 // Arrays of fixed size alias with arrays of unknown size. | |
1354 if (ta->size() != TypeInt::POS) { | |
1355 const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS); | |
247 | 1356 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset); |
0 | 1357 } |
1358 // 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
|
1359 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
|
1360 const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size()); |
247 | 1361 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
|
1362 } |
0 | 1363 if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) { |
1364 const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size()); | |
247 | 1365 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); |
0 | 1366 } |
1367 // Arrays of bytes and of booleans both use 'bastore' and 'baload' so | |
1368 // cannot be distinguished by bytecode alone. | |
1369 if (ta->elem() == TypeInt::BOOL) { | |
1370 const TypeAry *tary = TypeAry::make(TypeInt::BYTE, ta->size()); | |
1371 ciKlass* aklass = ciTypeArrayKlass::make(T_BYTE); | |
247 | 1372 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset); |
0 | 1373 } |
1374 // During the 2nd round of IterGVN, NotNull castings are removed. | |
1375 // Make sure the Bottom and NotNull variants alias the same. | |
1376 // Also, make sure exact and non-exact variants alias the same. | |
12966 | 1377 if (ptr == TypePtr::NotNull || ta->klass_is_exact() || ta->speculative() != NULL) { |
3789 | 1378 tj = ta = TypeAryPtr::make(TypePtr::BotPTR,ta->ary(),ta->klass(),false,offset); |
0 | 1379 } |
1380 } | |
1381 | |
1382 // Oop pointers need some flattening | |
1383 const TypeInstPtr *to = tj->isa_instptr(); | |
1384 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
|
1385 ciInstanceKlass *k = to->klass()->as_instance_klass(); |
0 | 1386 if( ptr == TypePtr::Constant ) { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1387 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
|
1388 offset < k->size_helper() * wordSize) { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1389 // 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
|
1390 // unknown strings. |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1391 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
|
1392 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
|
1393 } |
247 | 1394 } else if( is_known_inst ) { |
163 | 1395 tj = to; // Keep NotNull and klass_is_exact for instance type |
0 | 1396 } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) { |
1397 // During the 2nd round of IterGVN, NotNull castings are removed. | |
1398 // Make sure the Bottom and NotNull variants alias the same. | |
1399 // Also, make sure exact and non-exact variants alias the same. | |
247 | 1400 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); |
0 | 1401 } |
12966 | 1402 if (to->speculative() != NULL) { |
1403 tj = to = TypeInstPtr::make(to->ptr(),to->klass(),to->klass_is_exact(),to->const_oop(),to->offset(), to->instance_id()); | |
1404 } | |
0 | 1405 // 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
|
1406 if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) { |
0 | 1407 // First handle header references such as a LoadKlassNode, even if the |
1408 // object's klass is unloaded at compile time (4965979). | |
247 | 1409 if (!is_known_inst) { // Do it only for non-instance types |
1410 tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset); | |
1411 } | |
0 | 1412 } 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
|
1413 // 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
|
1414 // 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
|
1415 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
|
1416 to = NULL; |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1417 tj = TypeOopPtr::BOTTOM; |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1418 offset = tj->offset(); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1419 } |
0 | 1420 } else { |
1421 ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset); | |
1422 if (!k->equals(canonical_holder) || tj->offset() != offset) { | |
247 | 1423 if( is_known_inst ) { |
1424 tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id()); | |
1425 } else { | |
1426 tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset); | |
1427 } | |
0 | 1428 } |
1429 } | |
1430 } | |
1431 | |
1432 // Klass pointers to object array klasses need some flattening | |
1433 const TypeKlassPtr *tk = tj->isa_klassptr(); | |
1434 if( tk ) { | |
1435 // If we are referencing a field within a Klass, we need | |
1436 // to assume the worst case of an Object. Both exact and | |
4760
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1437 // inexact types must flatten to the same alias class so |
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1438 // use NotNull as the PTR. |
0 | 1439 if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) { |
1440 | |
4760
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1441 tj = tk = TypeKlassPtr::make(TypePtr::NotNull, |
0 | 1442 TypeKlassPtr::OBJECT->klass(), |
1443 offset); | |
1444 } | |
1445 | |
1446 ciKlass* klass = tk->klass(); | |
1447 if( klass->is_obj_array_klass() ) { | |
1448 ciKlass* k = TypeAryPtr::OOPS->klass(); | |
1449 if( !k || !k->is_loaded() ) // Only fails for some -Xcomp runs | |
1450 k = TypeInstPtr::BOTTOM->klass(); | |
1451 tj = tk = TypeKlassPtr::make( TypePtr::NotNull, k, offset ); | |
1452 } | |
1453 | |
1454 // Check for precise loads from the primary supertype array and force them | |
1455 // to the supertype cache alias index. Check for generic array loads from | |
1456 // the primary supertype array and also force them to the supertype cache | |
1457 // alias index. Since the same load can reach both, we need to merge | |
1458 // these 2 disparate memories into the same alias class. Since the | |
1459 // primary supertype array is read-only, there's no chance of confusion | |
1460 // where we bypass an array load and an array store. | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1461 int primary_supers_offset = in_bytes(Klass::primary_supers_offset()); |
4760
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1462 if (offset == Type::OffsetBot || |
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1463 (offset >= primary_supers_offset && |
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1464 offset < (int)(primary_supers_offset + Klass::primary_super_limit() * wordSize)) || |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1465 offset == (int)in_bytes(Klass::secondary_super_cache_offset())) { |
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1466 offset = in_bytes(Klass::secondary_super_cache_offset()); |
0 | 1467 tj = tk = TypeKlassPtr::make( TypePtr::NotNull, tk->klass(), offset ); |
1468 } | |
1469 } | |
1470 | |
1471 // Flatten all Raw pointers together. | |
1472 if (tj->base() == Type::RawPtr) | |
1473 tj = TypeRawPtr::BOTTOM; | |
1474 | |
1475 if (tj->base() == Type::AnyPtr) | |
1476 tj = TypePtr::BOTTOM; // An error, which the caller must check for. | |
1477 | |
1478 // Flatten all to bottom for now | |
1479 switch( _AliasLevel ) { | |
1480 case 0: | |
1481 tj = TypePtr::BOTTOM; | |
1482 break; | |
1483 case 1: // Flatten to: oop, static, field or array | |
1484 switch (tj->base()) { | |
1485 //case Type::AryPtr: tj = TypeAryPtr::RANGE; break; | |
1486 case Type::RawPtr: tj = TypeRawPtr::BOTTOM; break; | |
1487 case Type::AryPtr: // do not distinguish arrays at all | |
1488 case Type::InstPtr: tj = TypeInstPtr::BOTTOM; break; | |
1489 case Type::KlassPtr: tj = TypeKlassPtr::OBJECT; break; | |
1490 case Type::AnyPtr: tj = TypePtr::BOTTOM; break; // caller checks it | |
1491 default: ShouldNotReachHere(); | |
1492 } | |
1493 break; | |
605 | 1494 case 2: // No collapsing at level 2; keep all splits |
1495 case 3: // No collapsing at level 3; keep all splits | |
0 | 1496 break; |
1497 default: | |
1498 Unimplemented(); | |
1499 } | |
1500 | |
1501 offset = tj->offset(); | |
1502 assert( offset != Type::OffsetTop, "Offset has fallen from constant" ); | |
1503 | |
1504 assert( (offset != Type::OffsetBot && tj->base() != Type::AryPtr) || | |
1505 (offset == Type::OffsetBot && tj->base() == Type::AryPtr) || | |
1506 (offset == Type::OffsetBot && tj == TypeOopPtr::BOTTOM) || | |
1507 (offset == Type::OffsetBot && tj == TypePtr::BOTTOM) || | |
1508 (offset == oopDesc::mark_offset_in_bytes() && tj->base() == Type::AryPtr) || | |
1509 (offset == oopDesc::klass_offset_in_bytes() && tj->base() == Type::AryPtr) || | |
1510 (offset == arrayOopDesc::length_offset_in_bytes() && tj->base() == Type::AryPtr) , | |
1511 "For oops, klasses, raw offset must be constant; for arrays the offset is never known" ); | |
1512 assert( tj->ptr() != TypePtr::TopPTR && | |
1513 tj->ptr() != TypePtr::AnyNull && | |
1514 tj->ptr() != TypePtr::Null, "No imprecise addresses" ); | |
1515 // assert( tj->ptr() != TypePtr::Constant || | |
1516 // tj->base() == Type::RawPtr || | |
1517 // tj->base() == Type::KlassPtr, "No constant oop addresses" ); | |
1518 | |
1519 return tj; | |
1520 } | |
1521 | |
1522 void Compile::AliasType::Init(int i, const TypePtr* at) { | |
1523 _index = i; | |
1524 _adr_type = at; | |
1525 _field = NULL; | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1526 _element = NULL; |
0 | 1527 _is_rewritable = true; // default |
1528 const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL; | |
223 | 1529 if (atoop != NULL && atoop->is_known_instance()) { |
1530 const TypeOopPtr *gt = atoop->cast_to_instance_id(TypeOopPtr::InstanceBot); | |
0 | 1531 _general_index = Compile::current()->get_alias_index(gt); |
1532 } else { | |
1533 _general_index = 0; | |
1534 } | |
1535 } | |
1536 | |
1537 //---------------------------------print_on------------------------------------ | |
1538 #ifndef PRODUCT | |
1539 void Compile::AliasType::print_on(outputStream* st) { | |
1540 if (index() < 10) | |
1541 st->print("@ <%d> ", index()); | |
1542 else st->print("@ <%d>", index()); | |
1543 st->print(is_rewritable() ? " " : " RO"); | |
1544 int offset = adr_type()->offset(); | |
1545 if (offset == Type::OffsetBot) | |
1546 st->print(" +any"); | |
1547 else st->print(" +%-3d", offset); | |
1548 st->print(" in "); | |
1549 adr_type()->dump_on(st); | |
1550 const TypeOopPtr* tjp = adr_type()->isa_oopptr(); | |
1551 if (field() != NULL && tjp) { | |
1552 if (tjp->klass() != field()->holder() || | |
1553 tjp->offset() != field()->offset_in_bytes()) { | |
1554 st->print(" != "); | |
1555 field()->print(); | |
1556 st->print(" ***"); | |
1557 } | |
1558 } | |
1559 } | |
1560 | |
1561 void print_alias_types() { | |
1562 Compile* C = Compile::current(); | |
1563 tty->print_cr("--- Alias types, AliasIdxBot .. %d", C->num_alias_types()-1); | |
1564 for (int idx = Compile::AliasIdxBot; idx < C->num_alias_types(); idx++) { | |
1565 C->alias_type(idx)->print_on(tty); | |
1566 tty->cr(); | |
1567 } | |
1568 } | |
1569 #endif | |
1570 | |
1571 | |
1572 //----------------------------probe_alias_cache-------------------------------- | |
1573 Compile::AliasCacheEntry* Compile::probe_alias_cache(const TypePtr* adr_type) { | |
1574 intptr_t key = (intptr_t) adr_type; | |
1575 key ^= key >> logAliasCacheSize; | |
1576 return &_alias_cache[key & right_n_bits(logAliasCacheSize)]; | |
1577 } | |
1578 | |
1579 | |
1580 //-----------------------------grow_alias_types-------------------------------- | |
1581 void Compile::grow_alias_types() { | |
1582 const int old_ats = _max_alias_types; // how many before? | |
1583 const int new_ats = old_ats; // how many more? | |
1584 const int grow_ats = old_ats+new_ats; // how many now? | |
1585 _max_alias_types = grow_ats; | |
1586 _alias_types = REALLOC_ARENA_ARRAY(comp_arena(), AliasType*, _alias_types, old_ats, grow_ats); | |
1587 AliasType* ats = NEW_ARENA_ARRAY(comp_arena(), AliasType, new_ats); | |
1588 Copy::zero_to_bytes(ats, sizeof(AliasType)*new_ats); | |
1589 for (int i = 0; i < new_ats; i++) _alias_types[old_ats+i] = &ats[i]; | |
1590 } | |
1591 | |
1592 | |
1593 //--------------------------------find_alias_type------------------------------ | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1594 Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_create, ciField* original_field) { |
0 | 1595 if (_AliasLevel == 0) |
1596 return alias_type(AliasIdxBot); | |
1597 | |
1598 AliasCacheEntry* ace = probe_alias_cache(adr_type); | |
1599 if (ace->_adr_type == adr_type) { | |
1600 return alias_type(ace->_index); | |
1601 } | |
1602 | |
1603 // Handle special cases. | |
1604 if (adr_type == NULL) return alias_type(AliasIdxTop); | |
1605 if (adr_type == TypePtr::BOTTOM) return alias_type(AliasIdxBot); | |
1606 | |
1607 // Do it the slow way. | |
1608 const TypePtr* flat = flatten_alias_type(adr_type); | |
1609 | |
1610 #ifdef ASSERT | |
1611 assert(flat == flatten_alias_type(flat), "idempotent"); | |
1612 assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr"); | |
1613 if (flat->isa_oopptr() && !flat->isa_klassptr()) { | |
1614 const TypeOopPtr* foop = flat->is_oopptr(); | |
247 | 1615 // Scalarizable allocations have exact klass always. |
1616 bool exact = !foop->klass_is_exact() || foop->is_known_instance(); | |
1617 const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr(); | |
0 | 1618 assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type"); |
1619 } | |
1620 assert(flat == flatten_alias_type(flat), "exact bit doesn't matter"); | |
1621 #endif | |
1622 | |
1623 int idx = AliasIdxTop; | |
1624 for (int i = 0; i < num_alias_types(); i++) { | |
1625 if (alias_type(i)->adr_type() == flat) { | |
1626 idx = i; | |
1627 break; | |
1628 } | |
1629 } | |
1630 | |
1631 if (idx == AliasIdxTop) { | |
1632 if (no_create) return NULL; | |
1633 // Grow the array if necessary. | |
1634 if (_num_alias_types == _max_alias_types) grow_alias_types(); | |
1635 // Add a new alias type. | |
1636 idx = _num_alias_types++; | |
1637 _alias_types[idx]->Init(idx, flat); | |
1638 if (flat == TypeInstPtr::KLASS) alias_type(idx)->set_rewritable(false); | |
1639 if (flat == TypeAryPtr::RANGE) alias_type(idx)->set_rewritable(false); | |
1640 if (flat->isa_instptr()) { | |
1641 if (flat->offset() == java_lang_Class::klass_offset_in_bytes() | |
1642 && flat->is_instptr()->klass() == env()->Class_klass()) | |
1643 alias_type(idx)->set_rewritable(false); | |
1644 } | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1645 if (flat->isa_aryptr()) { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1646 #ifdef ASSERT |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1647 const int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE); |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1648 // (T_BYTE has the weakest alignment and size restrictions...) |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1649 assert(flat->offset() < header_size_min, "array body reference must be OffsetBot"); |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1650 #endif |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1651 if (flat->offset() == TypePtr::OffsetBot) { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1652 alias_type(idx)->set_element(flat->is_aryptr()->elem()); |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1653 } |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1654 } |
0 | 1655 if (flat->isa_klassptr()) { |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1656 if (flat->offset() == in_bytes(Klass::super_check_offset_offset())) |
0 | 1657 alias_type(idx)->set_rewritable(false); |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1658 if (flat->offset() == in_bytes(Klass::modifier_flags_offset())) |
0 | 1659 alias_type(idx)->set_rewritable(false); |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1660 if (flat->offset() == in_bytes(Klass::access_flags_offset())) |
0 | 1661 alias_type(idx)->set_rewritable(false); |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1662 if (flat->offset() == in_bytes(Klass::java_mirror_offset())) |
0 | 1663 alias_type(idx)->set_rewritable(false); |
1664 } | |
1665 // %%% (We would like to finalize JavaThread::threadObj_offset(), | |
1666 // but the base pointer type is not distinctive enough to identify | |
1667 // references into JavaThread.) | |
1668 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1669 // Check for final fields. |
0 | 1670 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
|
1671 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
|
1672 ciField* field; |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1673 if (tinst->const_oop() != NULL && |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1674 tinst->klass() == ciEnv::current()->Class_klass() && |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1675 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
|
1676 // static field |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1677 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
|
1678 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
|
1679 } else { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1680 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
|
1681 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
|
1682 } |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1683 assert(field == NULL || |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1684 original_field == NULL || |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1685 (field->holder() == original_field->holder() && |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1686 field->offset() == original_field->offset() && |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1687 field->is_static() == original_field->is_static()), "wrong field?"); |
0 | 1688 // Set field() and is_rewritable() attributes. |
1689 if (field != NULL) alias_type(idx)->set_field(field); | |
1690 } | |
1691 } | |
1692 | |
1693 // Fill the cache for next time. | |
1694 ace->_adr_type = adr_type; | |
1695 ace->_index = idx; | |
1696 assert(alias_type(adr_type) == alias_type(idx), "type must be installed"); | |
1697 | |
1698 // Might as well try to fill the cache for the flattened version, too. | |
1699 AliasCacheEntry* face = probe_alias_cache(flat); | |
1700 if (face->_adr_type == NULL) { | |
1701 face->_adr_type = flat; | |
1702 face->_index = idx; | |
1703 assert(alias_type(flat) == alias_type(idx), "flat type must work too"); | |
1704 } | |
1705 | |
1706 return alias_type(idx); | |
1707 } | |
1708 | |
1709 | |
1710 Compile::AliasType* Compile::alias_type(ciField* field) { | |
1711 const TypeOopPtr* t; | |
1712 if (field->is_static()) | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1713 t = TypeInstPtr::make(field->holder()->java_mirror()); |
0 | 1714 else |
1715 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
|
1716 AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes()), field); |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
12167
diff
changeset
|
1717 assert((field->is_final() || field->is_stable()) == !atp->is_rewritable(), "must get the rewritable bits correct"); |
0 | 1718 return atp; |
1719 } | |
1720 | |
1721 | |
1722 //------------------------------have_alias_type-------------------------------- | |
1723 bool Compile::have_alias_type(const TypePtr* adr_type) { | |
1724 AliasCacheEntry* ace = probe_alias_cache(adr_type); | |
1725 if (ace->_adr_type == adr_type) { | |
1726 return true; | |
1727 } | |
1728 | |
1729 // Handle special cases. | |
1730 if (adr_type == NULL) return true; | |
1731 if (adr_type == TypePtr::BOTTOM) return true; | |
1732 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1733 return find_alias_type(adr_type, true, NULL) != NULL; |
0 | 1734 } |
1735 | |
1736 //-----------------------------must_alias-------------------------------------- | |
1737 // True if all values of the given address type are in the given alias category. | |
1738 bool Compile::must_alias(const TypePtr* adr_type, int alias_idx) { | |
1739 if (alias_idx == AliasIdxBot) return true; // the universal category | |
1740 if (adr_type == NULL) return true; // NULL serves as TypePtr::TOP | |
1741 if (alias_idx == AliasIdxTop) return false; // the empty category | |
1742 if (adr_type->base() == Type::AnyPtr) return false; // TypePtr::BOTTOM or its twins | |
1743 | |
1744 // the only remaining possible overlap is identity | |
1745 int adr_idx = get_alias_index(adr_type); | |
1746 assert(adr_idx != AliasIdxBot && adr_idx != AliasIdxTop, ""); | |
1747 assert(adr_idx == alias_idx || | |
1748 (alias_type(alias_idx)->adr_type() != TypeOopPtr::BOTTOM | |
1749 && adr_type != TypeOopPtr::BOTTOM), | |
1750 "should not be testing for overlap with an unsafe pointer"); | |
1751 return adr_idx == alias_idx; | |
1752 } | |
1753 | |
1754 //------------------------------can_alias-------------------------------------- | |
1755 // True if any values of the given address type are in the given alias category. | |
1756 bool Compile::can_alias(const TypePtr* adr_type, int alias_idx) { | |
1757 if (alias_idx == AliasIdxTop) return false; // the empty category | |
1758 if (adr_type == NULL) return false; // NULL serves as TypePtr::TOP | |
1759 if (alias_idx == AliasIdxBot) return true; // the universal category | |
1760 if (adr_type->base() == Type::AnyPtr) return true; // TypePtr::BOTTOM or its twins | |
1761 | |
1762 // the only remaining possible overlap is identity | |
1763 int adr_idx = get_alias_index(adr_type); | |
1764 assert(adr_idx != AliasIdxBot && adr_idx != AliasIdxTop, ""); | |
1765 return adr_idx == alias_idx; | |
1766 } | |
1767 | |
1768 | |
1769 | |
1770 //---------------------------pop_warm_call------------------------------------- | |
1771 WarmCallInfo* Compile::pop_warm_call() { | |
1772 WarmCallInfo* wci = _warm_calls; | |
1773 if (wci != NULL) _warm_calls = wci->remove_from(wci); | |
1774 return wci; | |
1775 } | |
1776 | |
1777 //----------------------------Inline_Warm-------------------------------------- | |
1778 int Compile::Inline_Warm() { | |
1779 // If there is room, try to inline some more warm call sites. | |
1780 // %%% Do a graph index compaction pass when we think we're out of space? | |
1781 if (!InlineWarmCalls) return 0; | |
1782 | |
1783 int calls_made_hot = 0; | |
1784 int room_to_grow = NodeCountInliningCutoff - unique(); | |
1785 int amount_to_grow = MIN2(room_to_grow, (int)NodeCountInliningStep); | |
1786 int amount_grown = 0; | |
1787 WarmCallInfo* call; | |
1788 while (amount_to_grow > 0 && (call = pop_warm_call()) != NULL) { | |
1789 int est_size = (int)call->size(); | |
1790 if (est_size > (room_to_grow - amount_grown)) { | |
1791 // This one won't fit anyway. Get rid of it. | |
1792 call->make_cold(); | |
1793 continue; | |
1794 } | |
1795 call->make_hot(); | |
1796 calls_made_hot++; | |
1797 amount_grown += est_size; | |
1798 amount_to_grow -= est_size; | |
1799 } | |
1800 | |
1801 if (calls_made_hot > 0) set_major_progress(); | |
1802 return calls_made_hot; | |
1803 } | |
1804 | |
1805 | |
1806 //----------------------------Finish_Warm-------------------------------------- | |
1807 void Compile::Finish_Warm() { | |
1808 if (!InlineWarmCalls) return; | |
1809 if (failing()) return; | |
1810 if (warm_calls() == NULL) return; | |
1811 | |
1812 // Clean up loose ends, if we are out of space for inlining. | |
1813 WarmCallInfo* call; | |
1814 while ((call = pop_warm_call()) != NULL) { | |
1815 call->make_cold(); | |
1816 } | |
1817 } | |
1818 | |
1172 | 1819 //---------------------cleanup_loop_predicates----------------------- |
1820 // Remove the opaque nodes that protect the predicates so that all unused | |
1821 // checks and uncommon_traps will be eliminated from the ideal graph | |
1822 void Compile::cleanup_loop_predicates(PhaseIterGVN &igvn) { | |
1823 if (predicate_count()==0) return; | |
1824 for (int i = predicate_count(); i > 0; i--) { | |
1825 Node * n = predicate_opaque1_node(i-1); | |
1826 assert(n->Opcode() == Op_Opaque1, "must be"); | |
1827 igvn.replace_node(n, n->in(1)); | |
1828 } | |
1829 assert(predicate_count()==0, "should be clean!"); | |
1830 } | |
0 | 1831 |
7473 | 1832 // StringOpts and late inlining of string methods |
1833 void Compile::inline_string_calls(bool parse_time) { | |
1834 { | |
1835 // remove useless nodes to make the usage analysis simpler | |
1836 ResourceMark rm; | |
1837 PhaseRemoveUseless pru(initial_gvn(), for_igvn()); | |
1838 } | |
1839 | |
1840 { | |
1841 ResourceMark rm; | |
10405 | 1842 print_method(PHASE_BEFORE_STRINGOPTS, 3); |
7473 | 1843 PhaseStringOpts pso(initial_gvn(), for_igvn()); |
10405 | 1844 print_method(PHASE_AFTER_STRINGOPTS, 3); |
7473 | 1845 } |
1846 | |
1847 // now inline anything that we skipped the first time around | |
1848 if (!parse_time) { | |
1849 _late_inlines_pos = _late_inlines.length(); | |
1850 } | |
1851 | |
1852 while (_string_late_inlines.length() > 0) { | |
1853 CallGenerator* cg = _string_late_inlines.pop(); | |
1854 cg->do_late_inline(); | |
1855 if (failing()) return; | |
1856 } | |
1857 _string_late_inlines.trunc_to(0); | |
1858 } | |
1859 | |
10278 | 1860 // Late inlining of boxing methods |
1861 void Compile::inline_boxing_calls(PhaseIterGVN& igvn) { | |
1862 if (_boxing_late_inlines.length() > 0) { | |
1863 assert(has_boxed_value(), "inconsistent"); | |
1864 | |
1865 PhaseGVN* gvn = initial_gvn(); | |
1866 set_inlining_incrementally(true); | |
1867 | |
1868 assert( igvn._worklist.size() == 0, "should be done with igvn" ); | |
1869 for_igvn()->clear(); | |
1870 gvn->replace_with(&igvn); | |
1871 | |
1872 while (_boxing_late_inlines.length() > 0) { | |
1873 CallGenerator* cg = _boxing_late_inlines.pop(); | |
1874 cg->do_late_inline(); | |
1875 if (failing()) return; | |
1876 } | |
1877 _boxing_late_inlines.trunc_to(0); | |
1878 | |
1879 { | |
1880 ResourceMark rm; | |
1881 PhaseRemoveUseless pru(gvn, for_igvn()); | |
1882 } | |
1883 | |
1884 igvn = PhaseIterGVN(gvn); | |
1885 igvn.optimize(); | |
1886 | |
1887 set_inlining_progress(false); | |
1888 set_inlining_incrementally(false); | |
1889 } | |
1890 } | |
1891 | |
7473 | 1892 void Compile::inline_incrementally_one(PhaseIterGVN& igvn) { |
1893 assert(IncrementalInline, "incremental inlining should be on"); | |
1894 PhaseGVN* gvn = initial_gvn(); | |
1895 | |
1896 set_inlining_progress(false); | |
1897 for_igvn()->clear(); | |
1898 gvn->replace_with(&igvn); | |
1899 | |
1900 int i = 0; | |
1901 | |
1902 for (; i <_late_inlines.length() && !inlining_progress(); i++) { | |
1903 CallGenerator* cg = _late_inlines.at(i); | |
1904 _late_inlines_pos = i+1; | |
1905 cg->do_late_inline(); | |
1906 if (failing()) return; | |
1907 } | |
1908 int j = 0; | |
1909 for (; i < _late_inlines.length(); i++, j++) { | |
1910 _late_inlines.at_put(j, _late_inlines.at(i)); | |
1911 } | |
1912 _late_inlines.trunc_to(j); | |
1913 | |
1914 { | |
1915 ResourceMark rm; | |
10278 | 1916 PhaseRemoveUseless pru(gvn, for_igvn()); |
7473 | 1917 } |
1918 | |
1919 igvn = PhaseIterGVN(gvn); | |
1920 } | |
1921 | |
1922 // Perform incremental inlining until bound on number of live nodes is reached | |
1923 void Compile::inline_incrementally(PhaseIterGVN& igvn) { | |
1924 PhaseGVN* gvn = initial_gvn(); | |
1925 | |
1926 set_inlining_incrementally(true); | |
1927 set_inlining_progress(true); | |
1928 uint low_live_nodes = 0; | |
1929 | |
1930 while(inlining_progress() && _late_inlines.length() > 0) { | |
1931 | |
1932 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { | |
1933 if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) { | |
1934 // PhaseIdealLoop is expensive so we only try it once we are | |
1935 // out of loop and we only try it again if the previous helped | |
1936 // got the number of nodes down significantly | |
1937 PhaseIdealLoop ideal_loop( igvn, false, true ); | |
1938 if (failing()) return; | |
1939 low_live_nodes = live_nodes(); | |
1940 _major_progress = true; | |
1941 } | |
1942 | |
1943 if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { | |
1944 break; | |
1945 } | |
1946 } | |
1947 | |
1948 inline_incrementally_one(igvn); | |
1949 | |
1950 if (failing()) return; | |
1951 | |
1952 igvn.optimize(); | |
1953 | |
1954 if (failing()) return; | |
1955 } | |
1956 | |
1957 assert( igvn._worklist.size() == 0, "should be done with igvn" ); | |
1958 | |
1959 if (_string_late_inlines.length() > 0) { | |
1960 assert(has_stringbuilder(), "inconsistent"); | |
1961 for_igvn()->clear(); | |
1962 initial_gvn()->replace_with(&igvn); | |
1963 | |
1964 inline_string_calls(false); | |
1965 | |
1966 if (failing()) return; | |
1967 | |
1968 { | |
1969 ResourceMark rm; | |
1970 PhaseRemoveUseless pru(initial_gvn(), for_igvn()); | |
1971 } | |
1972 | |
1973 igvn = PhaseIterGVN(gvn); | |
1974 | |
1975 igvn.optimize(); | |
1976 } | |
1977 | |
1978 set_inlining_incrementally(false); | |
1979 } | |
1980 | |
1981 | |
0 | 1982 //------------------------------Optimize--------------------------------------- |
1983 // Given a graph, optimize it. | |
1984 void Compile::Optimize() { | |
1985 TracePhase t1("optimizer", &_t_optimizer, true); | |
1986 | |
1987 #ifndef PRODUCT | |
1988 if (env()->break_at_compile()) { | |
1989 BREAKPOINT; | |
1990 } | |
1991 | |
1992 #endif | |
1993 | |
1994 ResourceMark rm; | |
1995 int loop_opts_cnt; | |
1996 | |
1997 NOT_PRODUCT( verify_graph_edges(); ) | |
1998 | |
10405 | 1999 print_method(PHASE_AFTER_PARSING); |
0 | 2000 |
2001 { | |
2002 // Iterative Global Value Numbering, including ideal transforms | |
2003 // Initialize IterGVN with types and values from parse-time GVN | |
2004 PhaseIterGVN igvn(initial_gvn()); | |
2005 { | |
2006 NOT_PRODUCT( TracePhase t2("iterGVN", &_t_iterGVN, TimeCompiler); ) | |
2007 igvn.optimize(); | |
2008 } | |
2009 | |
10405 | 2010 print_method(PHASE_ITER_GVN1, 2); |
0 | 2011 |
2012 if (failing()) return; | |
2013 | |
10278 | 2014 { |
2015 NOT_PRODUCT( TracePhase t2("incrementalInline", &_t_incrInline, TimeCompiler); ) | |
2016 inline_incrementally(igvn); | |
2017 } | |
7473 | 2018 |
10405 | 2019 print_method(PHASE_INCREMENTAL_INLINE, 2); |
7473 | 2020 |
2021 if (failing()) return; | |
2022 | |
10278 | 2023 if (eliminate_boxing()) { |
2024 NOT_PRODUCT( TracePhase t2("incrementalInline", &_t_incrInline, TimeCompiler); ) | |
2025 // Inline valueOf() methods now. | |
2026 inline_boxing_calls(igvn); | |
2027 | |
10405 | 2028 print_method(PHASE_INCREMENTAL_BOXING_INLINE, 2); |
10278 | 2029 |
2030 if (failing()) return; | |
2031 } | |
2032 | |
12966 | 2033 // Remove the speculative part of types and clean up the graph from |
2034 // the extra CastPP nodes whose only purpose is to carry them. Do | |
2035 // that early so that optimizations are not disrupted by the extra | |
2036 // CastPP nodes. | |
2037 remove_speculative_types(igvn); | |
2038 | |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
2039 // No more new expensive nodes will be added to the list from here |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
2040 // so keep only the actual candidates for optimizations. |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
2041 cleanup_expensive_nodes(igvn); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
2042 |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2043 // Perform escape analysis |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2044 if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
2045 if (has_loops()) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
2046 // Cleanup graph (remove dead nodes). |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
2047 TracePhase t2("idealLoop", &_t_idealLoop, true); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
2048 PhaseIdealLoop ideal_loop( igvn, false, true ); |
10405 | 2049 if (major_progress()) print_method(PHASE_PHASEIDEAL_BEFORE_EA, 2); |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
2050 if (failing()) return; |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
2051 } |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2052 ConnectionGraph::do_analysis(this, &igvn); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2053 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2054 if (failing()) return; |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2055 |
4115 | 2056 // Optimize out fields loads from scalar replaceable allocations. |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2057 igvn.optimize(); |
10405 | 2058 print_method(PHASE_ITER_GVN_AFTER_EA, 2); |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2059 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2060 if (failing()) return; |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2061 |
4115 | 2062 if (congraph() != NULL && macro_count() > 0) { |
5948
ee138854b3a6
7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents:
4767
diff
changeset
|
2063 NOT_PRODUCT( TracePhase t2("macroEliminate", &_t_macroEliminate, TimeCompiler); ) |
4115 | 2064 PhaseMacroExpand mexp(igvn); |
2065 mexp.eliminate_macro_nodes(); | |
2066 igvn.set_delay_transform(false); | |
2067 | |
2068 igvn.optimize(); | |
10405 | 2069 print_method(PHASE_ITER_GVN_AFTER_ELIMINATION, 2); |
4115 | 2070 |
2071 if (failing()) return; | |
2072 } | |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2073 } |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
2074 |
0 | 2075 // Loop transforms on the ideal graph. Range Check Elimination, |
2076 // peeling, unrolling, etc. | |
2077 | |
2078 // Set loop opts counter | |
2079 loop_opts_cnt = num_loop_opts(); | |
2080 if((loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) { | |
2081 { | |
2082 TracePhase t2("idealLoop", &_t_idealLoop, true); | |
2445 | 2083 PhaseIdealLoop ideal_loop( igvn, true ); |
0 | 2084 loop_opts_cnt--; |
10405 | 2085 if (major_progress()) print_method(PHASE_PHASEIDEALLOOP1, 2); |
0 | 2086 if (failing()) return; |
2087 } | |
2088 // Loop opts pass if partial peeling occurred in previous pass | |
2089 if(PartialPeelLoop && major_progress() && (loop_opts_cnt > 0)) { | |
2090 TracePhase t3("idealLoop", &_t_idealLoop, true); | |
2445 | 2091 PhaseIdealLoop ideal_loop( igvn, false ); |
0 | 2092 loop_opts_cnt--; |
10405 | 2093 if (major_progress()) print_method(PHASE_PHASEIDEALLOOP2, 2); |
0 | 2094 if (failing()) return; |
2095 } | |
2096 // Loop opts pass for loop-unrolling before CCP | |
2097 if(major_progress() && (loop_opts_cnt > 0)) { | |
2098 TracePhase t4("idealLoop", &_t_idealLoop, true); | |
2445 | 2099 PhaseIdealLoop ideal_loop( igvn, false ); |
0 | 2100 loop_opts_cnt--; |
10405 | 2101 if (major_progress()) print_method(PHASE_PHASEIDEALLOOP3, 2); |
0 | 2102 } |
921
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2103 if (!failing()) { |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2104 // 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
|
2105 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2106 PhaseIdealLoop::verify(igvn); |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2107 } |
0 | 2108 } |
2109 if (failing()) return; | |
2110 | |
2111 // Conditional Constant Propagation; | |
2112 PhaseCCP ccp( &igvn ); | |
2113 assert( true, "Break here to ccp.dump_nodes_and_types(_root,999,1)"); | |
2114 { | |
2115 TracePhase t2("ccp", &_t_ccp, true); | |
2116 ccp.do_transform(); | |
2117 } | |
10405 | 2118 print_method(PHASE_CPP1, 2); |
0 | 2119 |
2120 assert( true, "Break here to ccp.dump_old2new_map()"); | |
2121 | |
2122 // Iterative Global Value Numbering, including ideal transforms | |
2123 { | |
2124 NOT_PRODUCT( TracePhase t2("iterGVN2", &_t_iterGVN2, TimeCompiler); ) | |
2125 igvn = ccp; | |
2126 igvn.optimize(); | |
2127 } | |
2128 | |
10405 | 2129 print_method(PHASE_ITER_GVN2, 2); |
0 | 2130 |
2131 if (failing()) return; | |
2132 | |
2133 // Loop transforms on the ideal graph. Range Check Elimination, | |
2134 // peeling, unrolling, etc. | |
2135 if(loop_opts_cnt > 0) { | |
2136 debug_only( int cnt = 0; ); | |
2137 while(major_progress() && (loop_opts_cnt > 0)) { | |
2138 TracePhase t2("idealLoop", &_t_idealLoop, true); | |
2139 assert( cnt++ < 40, "infinite cycle in loop optimization" ); | |
2445 | 2140 PhaseIdealLoop ideal_loop( igvn, true); |
0 | 2141 loop_opts_cnt--; |
10405 | 2142 if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2); |
0 | 2143 if (failing()) return; |
2144 } | |
2145 } | |
921
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2146 |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2147 { |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2148 // Verify that all previous optimizations produced a valid graph |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2149 // 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
|
2150 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2151 PhaseIdealLoop::verify(igvn); |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2152 } |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
2153 |
0 | 2154 { |
2155 NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); ) | |
2156 PhaseMacroExpand mex(igvn); | |
2157 if (mex.expand_macro_nodes()) { | |
2158 assert(failing(), "must bail out w/ explicit message"); | |
2159 return; | |
2160 } | |
2161 } | |
2162 | |
2163 } // (End scope of igvn; run destructor if necessary for asserts.) | |
2164 | |
7605 | 2165 dump_inlining(); |
0 | 2166 // A method with only infinite loops has no edges entering loops from root |
2167 { | |
2168 NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); ) | |
2169 if (final_graph_reshaping()) { | |
2170 assert(failing(), "must bail out w/ explicit message"); | |
2171 return; | |
2172 } | |
2173 } | |
2174 | |
10405 | 2175 print_method(PHASE_OPTIMIZE_FINISHED, 2); |
0 | 2176 } |
2177 | |
2178 | |
2179 //------------------------------Code_Gen--------------------------------------- | |
2180 // Given a graph, generate code for it | |
2181 void Compile::Code_Gen() { | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2182 if (failing()) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2183 return; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2184 } |
0 | 2185 |
2186 // Perform instruction selection. You might think we could reclaim Matcher | |
2187 // memory PDQ, but actually the Matcher is used in generating spill code. | |
2188 // Internals of the Matcher (including some VectorSets) must remain live | |
2189 // for awhile - thus I cannot reclaim Matcher memory lest a VectorSet usage | |
2190 // set a bit in reclaimed memory. | |
2191 | |
2192 // In debug mode can dump m._nodes.dump() for mapping of ideal to machine | |
2193 // nodes. Mapping is only valid at the root of each matched subtree. | |
2194 NOT_PRODUCT( verify_graph_edges(); ) | |
2195 | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2196 Matcher matcher; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2197 _matcher = &matcher; |
0 | 2198 { |
2199 TracePhase t2("matcher", &_t_matcher, true); | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2200 matcher.match(); |
0 | 2201 } |
2202 // In debug mode can dump m._nodes.dump() for mapping of ideal to machine | |
2203 // nodes. Mapping is only valid at the root of each matched subtree. | |
2204 NOT_PRODUCT( verify_graph_edges(); ) | |
2205 | |
2206 // If you have too many nodes, or if matching has failed, bail out | |
2207 check_node_count(0, "out of nodes matching instructions"); | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2208 if (failing()) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2209 return; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2210 } |
0 | 2211 |
2212 // Build a proper-looking CFG | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2213 PhaseCFG cfg(node_arena(), root(), matcher); |
0 | 2214 _cfg = &cfg; |
2215 { | |
2216 NOT_PRODUCT( TracePhase t2("scheduler", &_t_scheduler, TimeCompiler); ) | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2217 bool success = cfg.do_global_code_motion(); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2218 if (!success) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2219 return; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2220 } |
0 | 2221 |
10405 | 2222 print_method(PHASE_GLOBAL_CODE_MOTION, 2); |
0 | 2223 NOT_PRODUCT( verify_graph_edges(); ) |
2224 debug_only( cfg.verify(); ) | |
2225 } | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2226 |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2227 PhaseChaitin regalloc(unique(), cfg, matcher); |
0 | 2228 _regalloc = ®alloc; |
2229 { | |
2230 TracePhase t2("regalloc", &_t_registerAllocation, true); | |
2231 // Perform register allocation. After Chaitin, use-def chains are | |
2232 // no longer accurate (at spill code) and so must be ignored. | |
2233 // Node->LRG->reg mappings are still accurate. | |
2234 _regalloc->Register_Allocate(); | |
2235 | |
2236 // Bail out if the allocator builds too many nodes | |
10111 | 2237 if (failing()) { |
2238 return; | |
2239 } | |
0 | 2240 } |
2241 | |
2242 // Prior to register allocation we kept empty basic blocks in case the | |
2243 // the allocator needed a place to spill. After register allocation we | |
2244 // are not adding any new instructions. If any basic block is empty, we | |
2245 // can now safely remove it. | |
2246 { | |
418 | 2247 NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); ) |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2248 cfg.remove_empty_blocks(); |
418 | 2249 if (do_freq_based_layout()) { |
2250 PhaseBlockLayout layout(cfg); | |
2251 } else { | |
2252 cfg.set_loop_alignment(); | |
2253 } | |
2254 cfg.fixup_flow(); | |
0 | 2255 } |
2256 | |
2257 // Apply peephole optimizations | |
2258 if( OptoPeephole ) { | |
2259 NOT_PRODUCT( TracePhase t2("peephole", &_t_peephole, TimeCompiler); ) | |
2260 PhasePeephole peep( _regalloc, cfg); | |
2261 peep.do_transform(); | |
2262 } | |
2263 | |
2264 // Convert Nodes to instruction bits in a buffer | |
2265 { | |
2266 // %%%% workspace merge brought two timers together for one job | |
2267 TracePhase t2a("output", &_t_output, true); | |
2268 NOT_PRODUCT( TraceTime t2b(NULL, &_t_codeGeneration, TimeCompiler, false); ) | |
2269 Output(); | |
2270 } | |
2271 | |
10405 | 2272 print_method(PHASE_FINAL_CODE); |
0 | 2273 |
2274 // He's dead, Jim. | |
2275 _cfg = (PhaseCFG*)0xdeadbeef; | |
2276 _regalloc = (PhaseChaitin*)0xdeadbeef; | |
2277 } | |
2278 | |
2279 | |
2280 //------------------------------dump_asm--------------------------------------- | |
2281 // Dump formatted assembly | |
2282 #ifndef PRODUCT | |
2283 void Compile::dump_asm(int *pcs, uint pc_limit) { | |
2284 bool cut_short = false; | |
2285 tty->print_cr("#"); | |
2286 tty->print("# "); _tf->dump(); tty->cr(); | |
2287 tty->print_cr("#"); | |
2288 | |
2289 // For all blocks | |
2290 int pc = 0x0; // Program counter | |
2291 char starts_bundle = ' '; | |
2292 _regalloc->dump_frame(); | |
2293 | |
2294 Node *n = NULL; | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2295 for (uint i = 0; i < _cfg->number_of_blocks(); i++) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2296 if (VMThread::should_terminate()) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2297 cut_short = true; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2298 break; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2299 } |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2300 Block* block = _cfg->get_block(i); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2301 if (block->is_connector() && !Verbose) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2302 continue; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2303 } |
12167
650868c062a9
8023691: Create interface for nodes in class Block
adlertz
parents:
12071
diff
changeset
|
2304 n = block->head(); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2305 if (pcs && n->_idx < pc_limit) { |
0 | 2306 tty->print("%3.3x ", pcs[n->_idx]); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2307 } else { |
0 | 2308 tty->print(" "); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2309 } |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2310 block->dump_head(_cfg); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2311 if (block->is_connector()) { |
0 | 2312 tty->print_cr(" # Empty connector block"); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2313 } else if (block->num_preds() == 2 && block->pred(1)->is_CatchProj() && block->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) { |
0 | 2314 tty->print_cr(" # Block is sole successor of call"); |
2315 } | |
2316 | |
2317 // For all instructions | |
2318 Node *delay = NULL; | |
12167
650868c062a9
8023691: Create interface for nodes in class Block
adlertz
parents:
12071
diff
changeset
|
2319 for (uint j = 0; j < block->number_of_nodes(); j++) { |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2320 if (VMThread::should_terminate()) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2321 cut_short = true; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2322 break; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2323 } |
12167
650868c062a9
8023691: Create interface for nodes in class Block
adlertz
parents:
12071
diff
changeset
|
2324 n = block->get_node(j); |
0 | 2325 if (valid_bundle_info(n)) { |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2326 Bundle* bundle = node_bundling(n); |
0 | 2327 if (bundle->used_in_unconditional_delay()) { |
2328 delay = n; | |
2329 continue; | |
2330 } | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2331 if (bundle->starts_bundle()) { |
0 | 2332 starts_bundle = '+'; |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2333 } |
0 | 2334 } |
2335 | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2336 if (WizardMode) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2337 n->dump(); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
2338 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2339 |
0 | 2340 if( !n->is_Region() && // Dont print in the Assembly |
2341 !n->is_Phi() && // a few noisely useless nodes | |
2342 !n->is_Proj() && | |
2343 !n->is_MachTemp() && | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2344 !n->is_SafePointScalarObject() && |
0 | 2345 !n->is_Catch() && // Would be nice to print exception table targets |
2346 !n->is_MergeMem() && // Not very interesting | |
2347 !n->is_top() && // Debug info table constants | |
2348 !(n->is_Con() && !n->is_Mach())// Debug info table constants | |
2349 ) { | |
2350 if (pcs && n->_idx < pc_limit) | |
2351 tty->print("%3.3x", pcs[n->_idx]); | |
2352 else | |
2353 tty->print(" "); | |
2354 tty->print(" %c ", starts_bundle); | |
2355 starts_bundle = ' '; | |
2356 tty->print("\t"); | |
2357 n->format(_regalloc, tty); | |
2358 tty->cr(); | |
2359 } | |
2360 | |
2361 // If we have an instruction with a delay slot, and have seen a delay, | |
2362 // then back up and print it | |
2363 if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) { | |
2364 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
|
2365 if (WizardMode) delay->dump(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2366 |
0 | 2367 if (node_bundling(delay)->starts_bundle()) |
2368 starts_bundle = '+'; | |
2369 if (pcs && n->_idx < pc_limit) | |
2370 tty->print("%3.3x", pcs[n->_idx]); | |
2371 else | |
2372 tty->print(" "); | |
2373 tty->print(" %c ", starts_bundle); | |
2374 starts_bundle = ' '; | |
2375 tty->print("\t"); | |
2376 delay->format(_regalloc, tty); | |
2377 tty->print_cr(""); | |
2378 delay = NULL; | |
2379 } | |
2380 | |
2381 // Dump the exception table as well | |
2382 if( n->is_Catch() && (Verbose || WizardMode) ) { | |
2383 // Print the exception table for this offset | |
2384 _handler_table.print_subtable_for(pc); | |
2385 } | |
2386 } | |
2387 | |
2388 if (pcs && n->_idx < pc_limit) | |
2389 tty->print_cr("%3.3x", pcs[n->_idx]); | |
2390 else | |
2391 tty->print_cr(""); | |
2392 | |
2393 assert(cut_short || delay == NULL, "no unconditional delay branch"); | |
2394 | |
2395 } // End of per-block dump | |
2396 tty->print_cr(""); | |
2397 | |
2398 if (cut_short) tty->print_cr("*** disassembly is cut short ***"); | |
2399 } | |
2400 #endif | |
2401 | |
2402 //------------------------------Final_Reshape_Counts--------------------------- | |
2403 // This class defines counters to help identify when a method | |
2404 // may/must be executed using hardware with only 24-bit precision. | |
2405 struct Final_Reshape_Counts : public StackObj { | |
2406 int _call_count; // count non-inlined 'common' calls | |
2407 int _float_count; // count float ops requiring 24-bit precision | |
2408 int _double_count; // count double ops requiring more precision | |
2409 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
|
2410 int _inner_loop_count; // count loops which need alignment |
0 | 2411 VectorSet _visited; // Visitation flags |
2412 Node_List _tests; // Set of IfNodes & PCTableNodes | |
2413 | |
2414 Final_Reshape_Counts() : | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2415 _call_count(0), _float_count(0), _double_count(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2416 _java_call_count(0), _inner_loop_count(0), |
0 | 2417 _visited( Thread::current()->resource_area() ) { } |
2418 | |
2419 void inc_call_count () { _call_count ++; } | |
2420 void inc_float_count () { _float_count ++; } | |
2421 void inc_double_count() { _double_count++; } | |
2422 void inc_java_call_count() { _java_call_count++; } | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2423 void inc_inner_loop_count() { _inner_loop_count++; } |
0 | 2424 |
2425 int get_call_count () const { return _call_count ; } | |
2426 int get_float_count () const { return _float_count ; } | |
2427 int get_double_count() const { return _double_count; } | |
2428 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
|
2429 int get_inner_loop_count() const { return _inner_loop_count; } |
0 | 2430 }; |
2431 | |
9060
cc32ccaaf47f
8003310: Enable -Wunused-function when compiling with gcc
mikael
parents:
8730
diff
changeset
|
2432 #ifdef ASSERT |
0 | 2433 static bool oop_offset_is_sane(const TypeInstPtr* tp) { |
2434 ciInstanceKlass *k = tp->klass()->as_instance_klass(); | |
2435 // 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
|
2436 return k->contains_field_offset(tp->offset()); |
0 | 2437 // Note that OffsetBot and OffsetTop are very negative. |
2438 } | |
9060
cc32ccaaf47f
8003310: Enable -Wunused-function when compiling with gcc
mikael
parents:
8730
diff
changeset
|
2439 #endif |
0 | 2440 |
3248
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2441 // Eliminate trivially redundant StoreCMs and accumulate their |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2442 // precedence edges. |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2443 void Compile::eliminate_redundant_card_marks(Node* n) { |
3248
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2444 assert(n->Opcode() == Op_StoreCM, "expected StoreCM"); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2445 if (n->in(MemNode::Address)->outcnt() > 1) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2446 // 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
|
2447 // possible to eliminate some of the StoreCMs |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2448 Node* mem = n->in(MemNode::Memory); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2449 Node* adr = n->in(MemNode::Address); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2450 Node* val = n->in(MemNode::ValueIn); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2451 Node* prev = n; |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2452 bool done = false; |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2453 // Walk the chain of StoreCMs eliminating ones that match. As |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2454 // 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
|
2455 // safe. Eliminating partially redundant StoreCMs would require |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2456 // cloning copies down the other paths. |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2457 while (mem->Opcode() == Op_StoreCM && mem->outcnt() == 1 && !done) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2458 if (adr == mem->in(MemNode::Address) && |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2459 val == mem->in(MemNode::ValueIn)) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2460 // redundant StoreCM |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2461 if (mem->req() > MemNode::OopStore) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2462 // Hasn't been processed by this code yet. |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2463 n->add_prec(mem->in(MemNode::OopStore)); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2464 } else { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2465 // Already converted to precedence edge |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2466 for (uint i = mem->req(); i < mem->len(); i++) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2467 // Accumulate any precedence edges |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2468 if (mem->in(i) != NULL) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2469 n->add_prec(mem->in(i)); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2470 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2471 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2472 // Everything above this point has been processed. |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2473 done = true; |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2474 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2475 // Eliminate the previous StoreCM |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2476 prev->set_req(MemNode::Memory, mem->in(MemNode::Memory)); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2477 assert(mem->outcnt() == 0, "should be dead"); |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2478 mem->disconnect_inputs(NULL, this); |
3248
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2479 } else { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2480 prev = mem; |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2481 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2482 mem = prev->in(MemNode::Memory); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2483 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2484 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2485 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2486 |
0 | 2487 //------------------------------final_graph_reshaping_impl---------------------- |
2488 // Implement items 1-5 from final_graph_reshaping below. | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2489 void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) { |
0 | 2490 |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2491 if ( n->outcnt() == 0 ) return; // dead node |
0 | 2492 uint nop = n->Opcode(); |
2493 | |
2494 // Check for 2-input instruction with "last use" on right input. | |
2495 // Swap to left input. Implements item (2). | |
2496 if( n->req() == 3 && // two-input instruction | |
2497 n->in(1)->outcnt() > 1 && // left use is NOT a last use | |
2498 (!n->in(1)->is_Phi() || n->in(1)->in(2) != n) && // it is not data loop | |
2499 n->in(2)->outcnt() == 1 &&// right use IS a last use | |
2500 !n->in(2)->is_Con() ) { // right use is not a constant | |
2501 // Check for commutative opcode | |
2502 switch( nop ) { | |
2503 case Op_AddI: case Op_AddF: case Op_AddD: case Op_AddL: | |
2504 case Op_MaxI: case Op_MinI: | |
2505 case Op_MulI: case Op_MulF: case Op_MulD: case Op_MulL: | |
2506 case Op_AndL: case Op_XorL: case Op_OrL: | |
2507 case Op_AndI: case Op_XorI: case Op_OrI: { | |
2508 // Move "last use" input to left by swapping inputs | |
2509 n->swap_edges(1, 2); | |
2510 break; | |
2511 } | |
2512 default: | |
2513 break; | |
2514 } | |
2515 } | |
2516 | |
1609 | 2517 #ifdef ASSERT |
2518 if( n->is_Mem() ) { | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2519 int alias_idx = get_alias_index(n->as_Mem()->adr_type()); |
1609 | 2520 assert( n->in(0) != NULL || alias_idx != Compile::AliasIdxRaw || |
2521 // oop will be recorded in oop map if load crosses safepoint | |
2522 n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() || | |
2523 LoadNode::is_immutable_value(n->in(MemNode::Address))), | |
2524 "raw memory operations should have control edge"); | |
2525 } | |
2526 #endif | |
0 | 2527 // Count FPU ops and common calls, implements item (3) |
2528 switch( nop ) { | |
2529 // Count all float operations that may use FPU | |
2530 case Op_AddF: | |
2531 case Op_SubF: | |
2532 case Op_MulF: | |
2533 case Op_DivF: | |
2534 case Op_NegF: | |
2535 case Op_ModF: | |
2536 case Op_ConvI2F: | |
2537 case Op_ConF: | |
2538 case Op_CmpF: | |
2539 case Op_CmpF3: | |
2540 // 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
|
2541 frc.inc_float_count(); |
0 | 2542 break; |
2543 | |
2544 case Op_ConvF2D: | |
2545 case Op_ConvD2F: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2546 frc.inc_float_count(); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2547 frc.inc_double_count(); |
0 | 2548 break; |
2549 | |
2550 // Count all double operations that may use FPU | |
2551 case Op_AddD: | |
2552 case Op_SubD: | |
2553 case Op_MulD: | |
2554 case Op_DivD: | |
2555 case Op_NegD: | |
2556 case Op_ModD: | |
2557 case Op_ConvI2D: | |
2558 case Op_ConvD2I: | |
2559 // case Op_ConvL2D: // handled by leaf call | |
2560 // case Op_ConvD2L: // handled by leaf call | |
2561 case Op_ConD: | |
2562 case Op_CmpD: | |
2563 case Op_CmpD3: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2564 frc.inc_double_count(); |
0 | 2565 break; |
2566 case Op_Opaque1: // Remove Opaque Nodes before matching | |
2567 case Op_Opaque2: // Remove Opaque Nodes before matching | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2568 n->subsume_by(n->in(1), this); |
0 | 2569 break; |
2570 case Op_CallStaticJava: | |
2571 case Op_CallJava: | |
2572 case Op_CallDynamicJava: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2573 frc.inc_java_call_count(); // Count java call site; |
0 | 2574 case Op_CallRuntime: |
2575 case Op_CallLeaf: | |
2576 case Op_CallLeafNoFP: { | |
2577 assert( n->is_Call(), "" ); | |
2578 CallNode *call = n->as_Call(); | |
2579 // Count call sites where the FP mode bit would have to be flipped. | |
2580 // Do not count uncommon runtime calls: | |
2581 // uncommon_trap, _complete_monitor_locking, _complete_monitor_unlocking, | |
2582 // _new_Java, _new_typeArray, _new_objArray, _rethrow_Java, ... | |
2583 if( !call->is_CallStaticJava() || !call->as_CallStaticJava()->_name ) { | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2584 frc.inc_call_count(); // Count the call site |
0 | 2585 } else { // See if uncommon argument is shared |
2586 Node *n = call->in(TypeFunc::Parms); | |
2587 int nop = n->Opcode(); | |
2588 // Clone shared simple arguments to uncommon calls, item (1). | |
2589 if( n->outcnt() > 1 && | |
2590 !n->is_Proj() && | |
2591 nop != Op_CreateEx && | |
2592 nop != Op_CheckCastPP && | |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2593 nop != Op_DecodeN && |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2594 nop != Op_DecodeNKlass && |
0 | 2595 !n->is_Mem() ) { |
2596 Node *x = n->clone(); | |
2597 call->set_req( TypeFunc::Parms, x ); | |
2598 } | |
2599 } | |
2600 break; | |
2601 } | |
2602 | |
2603 case Op_StoreD: | |
2604 case Op_LoadD: | |
2605 case Op_LoadD_unaligned: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2606 frc.inc_double_count(); |
0 | 2607 goto handle_mem; |
2608 case Op_StoreF: | |
2609 case Op_LoadF: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2610 frc.inc_float_count(); |
0 | 2611 goto handle_mem; |
2612 | |
3248
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2613 case Op_StoreCM: |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2614 { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2615 // Convert OopStore dependence into precedence edge |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2616 Node* prec = n->in(MemNode::OopStore); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2617 n->del_req(MemNode::OopStore); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2618 n->add_prec(prec); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2619 eliminate_redundant_card_marks(n); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2620 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2621 |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2622 // fall through |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2623 |
0 | 2624 case Op_StoreB: |
2625 case Op_StoreC: | |
2626 case Op_StorePConditional: | |
2627 case Op_StoreI: | |
2628 case Op_StoreL: | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
418
diff
changeset
|
2629 case Op_StoreIConditional: |
0 | 2630 case Op_StoreLConditional: |
2631 case Op_CompareAndSwapI: | |
2632 case Op_CompareAndSwapL: | |
2633 case Op_CompareAndSwapP: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2634 case Op_CompareAndSwapN: |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2635 case Op_GetAndAddI: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2636 case Op_GetAndAddL: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2637 case Op_GetAndSetI: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2638 case Op_GetAndSetL: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2639 case Op_GetAndSetP: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2640 case Op_GetAndSetN: |
0 | 2641 case Op_StoreP: |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2642 case Op_StoreN: |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2643 case Op_StoreNKlass: |
0 | 2644 case Op_LoadB: |
624 | 2645 case Op_LoadUB: |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
492
diff
changeset
|
2646 case Op_LoadUS: |
0 | 2647 case Op_LoadI: |
2648 case Op_LoadKlass: | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2649 case Op_LoadNKlass: |
0 | 2650 case Op_LoadL: |
2651 case Op_LoadL_unaligned: | |
2652 case Op_LoadPLocked: | |
2653 case Op_LoadP: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2654 case Op_LoadN: |
0 | 2655 case Op_LoadRange: |
2656 case Op_LoadS: { | |
2657 handle_mem: | |
2658 #ifdef ASSERT | |
2659 if( VerifyOptoOopOffsets ) { | |
2660 assert( n->is_Mem(), "" ); | |
2661 MemNode *mem = (MemNode*)n; | |
2662 // Check to see if address types have grounded out somehow. | |
2663 const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr(); | |
2664 assert( !tp || oop_offset_is_sane(tp), "" ); | |
2665 } | |
2666 #endif | |
2667 break; | |
2668 } | |
2669 | |
2670 case Op_AddP: { // Assert sane base pointers | |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2671 Node *addp = n->in(AddPNode::Address); |
0 | 2672 assert( !addp->is_AddP() || |
2673 addp->in(AddPNode::Base)->is_top() || // Top OK for allocation | |
2674 addp->in(AddPNode::Base) == n->in(AddPNode::Base), | |
2675 "Base pointers must match" ); | |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2676 #ifdef _LP64 |
12226
7944aba7ba41
8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents:
12167
diff
changeset
|
2677 if ((UseCompressedOops || UseCompressedClassPointers) && |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2678 addp->Opcode() == Op_ConP && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2679 addp == n->in(AddPNode::Base) && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2680 n->in(AddPNode::Offset)->is_Con()) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2681 // 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
|
2682 // 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
|
2683 // instructions (4) then load 64-bits constant (7). |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2684 // 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
|
2685 const Type* t = addp->bottom_type(); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2686 if (t->isa_oopptr() || t->isa_klassptr()) { |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2687 Node* nn = NULL; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2688 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2689 int op = t->isa_oopptr() ? Op_ConN : Op_ConNKlass; |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2690 |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2691 // Look for existing ConN node of the same exact type. |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2692 Node* r = root(); |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2693 uint cnt = r->outcnt(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2694 for (uint i = 0; i < cnt; i++) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2695 Node* m = r->raw_out(i); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2696 if (m!= NULL && m->Opcode() == op && |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
182
diff
changeset
|
2697 m->bottom_type()->make_ptr() == t) { |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2698 nn = m; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2699 break; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2700 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2701 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2702 if (nn != NULL) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2703 // Decode a narrow oop to match address |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2704 // [R12 + narrow_oop_reg<<3 + offset] |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2705 if (t->isa_oopptr()) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2706 nn = new (this) DecodeNNode(nn, t); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2707 } else { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2708 nn = new (this) DecodeNKlassNode(nn, t); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2709 } |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2710 n->set_req(AddPNode::Base, nn); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2711 n->set_req(AddPNode::Address, nn); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2712 if (addp->outcnt() == 0) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2713 addp->disconnect_inputs(NULL, this); |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2714 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2715 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2716 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2717 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2718 #endif |
0 | 2719 break; |
2720 } | |
2721 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2722 #ifdef _LP64 |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2723 case Op_CastPP: |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2724 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
|
2725 Node* in1 = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2726 const Type* t = n->bottom_type(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2727 Node* new_in1 = in1->clone(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2728 new_in1->as_DecodeN()->set_type(t); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2729 |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2730 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
|
2731 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2732 // 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
|
2733 // 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
|
2734 // 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
|
2735 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2736 // [R12 + narrow_oop_reg<<3 + offset] |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2737 // NullCheck narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2738 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2739 // 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
|
2740 // 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
|
2741 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2742 // 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
|
2743 // [base_reg + offset] |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2744 // NullCheck base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2745 // |
605 | 2746 // 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
|
2747 // 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
|
2748 // 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
|
2749 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2750 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
|
2751 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2752 |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2753 n->subsume_by(new_in1, this); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2754 if (in1->outcnt() == 0) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2755 in1->disconnect_inputs(NULL, this); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2756 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2757 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2758 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2759 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2760 case Op_CmpP: |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2761 // 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
|
2762 // other TypePtr related Ideal optimizations (for example, ptr nullness). |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2763 if (n->in(1)->is_DecodeNarrowPtr() || n->in(2)->is_DecodeNarrowPtr()) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2764 Node* in1 = n->in(1); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2765 Node* in2 = n->in(2); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2766 if (!in1->is_DecodeNarrowPtr()) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2767 in2 = in1; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2768 in1 = n->in(2); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2769 } |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2770 assert(in1->is_DecodeNarrowPtr(), "sanity"); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2771 |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2772 Node* new_in2 = NULL; |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2773 if (in2->is_DecodeNarrowPtr()) { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2774 assert(in2->Opcode() == in1->Opcode(), "must be same node type"); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2775 new_in2 = in2->in(1); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2776 } else if (in2->Opcode() == Op_ConP) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2777 const Type* t = in2->bottom_type(); |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2778 if (t == TypePtr::NULL_PTR) { |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2779 assert(in1->is_DecodeN(), "compare klass to null?"); |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2780 // 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
|
2781 // oops implicit null check is not generated. |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2782 // 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
|
2783 if (Matcher::gen_narrow_oop_implicit_null_checks()) |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2784 new_in2 = ConNode::make(this, TypeNarrowOop::NULL_PTR); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2785 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2786 // This transformation together with CastPP transformation above |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2787 // 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
|
2788 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2789 // The original code after Optimize() |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2790 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2791 // LoadN memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2792 // decode narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2793 // CmpP base_reg, NULL |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2794 // CastPP base_reg // NotNull |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2795 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2796 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2797 // after these transformations will be |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2798 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2799 // LoadN memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2800 // CmpN narrow_oop_reg, NULL |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2801 // 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
|
2802 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2803 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2804 // 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
|
2805 // 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
|
2806 // final_graph_reshaping_walk()). |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2807 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2808 // 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
|
2809 // on x86: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2810 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2811 // Load_narrow_oop memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2812 // 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
|
2813 // NullCheck narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2814 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2815 // and on sparc: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2816 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2817 // Load_narrow_oop memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2818 // 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
|
2819 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2820 // NullCheck base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2821 // |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2822 } else if (t->isa_oopptr()) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2823 new_in2 = ConNode::make(this, t->make_narrowoop()); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2824 } else if (t->isa_klassptr()) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2825 new_in2 = ConNode::make(this, t->make_narrowklass()); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2826 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2827 } |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2828 if (new_in2 != NULL) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2829 Node* cmpN = new (this) CmpNNode(in1->in(1), new_in2); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2830 n->subsume_by(cmpN, this); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2831 if (in1->outcnt() == 0) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2832 in1->disconnect_inputs(NULL, this); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2833 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2834 if (in2->outcnt() == 0) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2835 in2->disconnect_inputs(NULL, this); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2836 } |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2837 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2838 } |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
2839 break; |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2840 |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2841 case Op_DecodeN: |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2842 case Op_DecodeNKlass: |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2843 assert(!n->in(1)->is_EncodeNarrowPtr(), "should be optimized out"); |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2844 // 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
|
2845 // an address expression, see the code for Op_CastPP above. |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2846 assert(n->in(0) == NULL || (UseCompressedOops && !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
|
2847 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2848 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2849 case Op_EncodeP: |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2850 case Op_EncodePKlass: { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2851 Node* in1 = n->in(1); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2852 if (in1->is_DecodeNarrowPtr()) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2853 n->subsume_by(in1->in(1), this); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2854 } else if (in1->Opcode() == Op_ConP) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2855 const Type* t = in1->bottom_type(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2856 if (t == TypePtr::NULL_PTR) { |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2857 assert(t->isa_oopptr(), "null klass?"); |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2858 n->subsume_by(ConNode::make(this, TypeNarrowOop::NULL_PTR), this); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2859 } else if (t->isa_oopptr()) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2860 n->subsume_by(ConNode::make(this, t->make_narrowoop()), this); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2861 } else if (t->isa_klassptr()) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2862 n->subsume_by(ConNode::make(this, t->make_narrowklass()), this); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2863 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2864 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2865 if (in1->outcnt() == 0) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2866 in1->disconnect_inputs(NULL, this); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2867 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2868 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2869 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2870 |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2871 case Op_Proj: { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2872 if (OptimizeStringConcat) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2873 ProjNode* p = n->as_Proj(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2874 if (p->_is_io_use) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2875 // Separate projections were used for the exception path which |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2876 // 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
|
2877 // then they will hang around and should just be replaced with |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2878 // the original one. |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2879 Node* proj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2880 // Replace with just one |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2881 for (SimpleDUIterator i(p->in(0)); i.has_next(); i.next()) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2882 Node *use = i.get(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2883 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
|
2884 proj = use; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2885 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2886 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2887 } |
4767 | 2888 assert(proj != NULL, "must be found"); |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2889 p->subsume_by(proj, this); |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2890 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2891 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2892 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2893 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2894 |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2895 case Op_Phi: |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2896 if (n->as_Phi()->bottom_type()->isa_narrowoop() || n->as_Phi()->bottom_type()->isa_narrowklass()) { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2897 // 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
|
2898 // 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
|
2899 Node* unique_in = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2900 assert(unique_in != NULL, ""); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2901 uint cnt = n->req(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2902 for (uint i = 2; i < cnt; i++) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2903 Node* m = n->in(i); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2904 assert(m != NULL, ""); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2905 if (unique_in != m) |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2906 unique_in = NULL; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2907 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2908 if (unique_in != NULL) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2909 n->subsume_by(unique_in, this); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2910 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2911 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2912 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2913 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2914 #endif |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2915 |
0 | 2916 case Op_ModI: |
2917 if (UseDivMod) { | |
2918 // Check if a%b and a/b both exist | |
2919 Node* d = n->find_similar(Op_DivI); | |
2920 if (d) { | |
2921 // Replace them with a fused divmod if supported | |
2922 if (Matcher::has_match_rule(Op_DivModI)) { | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2923 DivModINode* divmod = DivModINode::make(this, n); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2924 d->subsume_by(divmod->div_proj(), this); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2925 n->subsume_by(divmod->mod_proj(), this); |
0 | 2926 } else { |
2927 // replace a%b with a-((a/b)*b) | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2928 Node* mult = new (this) MulINode(d, d->in(2)); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2929 Node* sub = new (this) SubINode(d->in(1), mult); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2930 n->subsume_by(sub, this); |
0 | 2931 } |
2932 } | |
2933 } | |
2934 break; | |
2935 | |
2936 case Op_ModL: | |
2937 if (UseDivMod) { | |
2938 // Check if a%b and a/b both exist | |
2939 Node* d = n->find_similar(Op_DivL); | |
2940 if (d) { | |
2941 // Replace them with a fused divmod if supported | |
2942 if (Matcher::has_match_rule(Op_DivModL)) { | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2943 DivModLNode* divmod = DivModLNode::make(this, n); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2944 d->subsume_by(divmod->div_proj(), this); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2945 n->subsume_by(divmod->mod_proj(), this); |
0 | 2946 } else { |
2947 // replace a%b with a-((a/b)*b) | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2948 Node* mult = new (this) MulLNode(d, d->in(2)); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2949 Node* sub = new (this) SubLNode(d->in(1), mult); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2950 n->subsume_by(sub, this); |
0 | 2951 } |
2952 } | |
2953 } | |
2954 break; | |
2955 | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
2956 case Op_LoadVector: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
2957 case Op_StoreVector: |
0 | 2958 break; |
2959 | |
2960 case Op_PackB: | |
2961 case Op_PackS: | |
2962 case Op_PackI: | |
2963 case Op_PackF: | |
2964 case Op_PackL: | |
2965 case Op_PackD: | |
2966 if (n->req()-1 > 2) { | |
2967 // Replace many operand PackNodes with a binary tree for matching | |
2968 PackNode* p = (PackNode*) n; | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2969 Node* btp = p->binary_tree_pack(this, 1, n->req()); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2970 n->subsume_by(btp, this); |
0 | 2971 } |
2972 break; | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2973 case Op_Loop: |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2974 case Op_CountedLoop: |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2975 if (n->as_Loop()->is_inner_loop()) { |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2976 frc.inc_inner_loop_count(); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2977 } |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2978 break; |
2401
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2979 case Op_LShiftI: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2980 case Op_RShiftI: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2981 case Op_URShiftI: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2982 case Op_LShiftL: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2983 case Op_RShiftL: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2984 case Op_URShiftL: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2985 if (Matcher::need_masked_shift_count) { |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2986 // 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
|
2987 // lower 5/6 bits. We need to do the masking ourselves. |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2988 Node* in2 = n->in(2); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2989 juint mask = (n->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2990 const TypeInt* t = in2->find_int_type(); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2991 if (t != NULL && t->is_con()) { |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2992 juint shift = t->get_con(); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2993 if (shift > mask) { // Unsigned cmp |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2994 n->set_req(2, ConNode::make(this, TypeInt::make(shift & mask))); |
2401
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2995 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2996 } else { |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2997 if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
2998 Node* shift = new (this) AndINode(in2, ConNode::make(this, TypeInt::make(mask))); |
2401
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2999 n->set_req(2, shift); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
3000 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
3001 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
3002 if (in2->outcnt() == 0) { // Remove dead node |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3003 in2->disconnect_inputs(NULL, this); |
2401
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
3004 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
3005 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
3006 break; |
8694
8651f608fea4
8009460: C2compiler crash in machnode::in_regmask(unsigned int)
roland
parents:
8691
diff
changeset
|
3007 case Op_MemBarStoreStore: |
10278 | 3008 case Op_MemBarRelease: |
8694
8651f608fea4
8009460: C2compiler crash in machnode::in_regmask(unsigned int)
roland
parents:
8691
diff
changeset
|
3009 // Break the link with AllocateNode: it is no longer useful and |
8651f608fea4
8009460: C2compiler crash in machnode::in_regmask(unsigned int)
roland
parents:
8691
diff
changeset
|
3010 // confuses register allocation. |
8651f608fea4
8009460: C2compiler crash in machnode::in_regmask(unsigned int)
roland
parents:
8691
diff
changeset
|
3011 if (n->req() > MemBarNode::Precedent) { |
8651f608fea4
8009460: C2compiler crash in machnode::in_regmask(unsigned int)
roland
parents:
8691
diff
changeset
|
3012 n->set_req(MemBarNode::Precedent, top()); |
8651f608fea4
8009460: C2compiler crash in machnode::in_regmask(unsigned int)
roland
parents:
8691
diff
changeset
|
3013 } |
8651f608fea4
8009460: C2compiler crash in machnode::in_regmask(unsigned int)
roland
parents:
8691
diff
changeset
|
3014 break; |
12888
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3015 // Must set a control edge on all nodes that produce a FlagsProj |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3016 // so they can't escape the block that consumes the flags. |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3017 // Must also set the non throwing branch as the control |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3018 // for all nodes that depends on the result. Unless the node |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3019 // already have a control that isn't the control of the |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3020 // flag producer |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3021 case Op_FlagsProj: |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3022 { |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3023 MathExactNode* math = (MathExactNode*) n->in(0); |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3024 Node* ctrl = math->control_node(); |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3025 Node* non_throwing = math->non_throwing_branch(); |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3026 math->set_req(0, ctrl); |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3027 |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3028 Node* result = math->result_node(); |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3029 if (result != NULL) { |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3030 for (DUIterator_Fast jmax, j = result->fast_outs(jmax); j < jmax; j++) { |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3031 Node* out = result->fast_out(j); |
12963
435c7b4577cd
8026959: assert(!n->pinned() || n->is_MachConstantBase()) failed: only pinned MachConstantBase node is expected here
rbackman
parents:
12956
diff
changeset
|
3032 // Phi nodes shouldn't be moved. They would only match below if they |
435c7b4577cd
8026959: assert(!n->pinned() || n->is_MachConstantBase()) failed: only pinned MachConstantBase node is expected here
rbackman
parents:
12956
diff
changeset
|
3033 // had the same control as the MathExactNode. The only time that |
435c7b4577cd
8026959: assert(!n->pinned() || n->is_MachConstantBase()) failed: only pinned MachConstantBase node is expected here
rbackman
parents:
12956
diff
changeset
|
3034 // would happen is if the Phi is also an input to the MathExact |
13043
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3035 // |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3036 // Cmp nodes shouldn't have control set at all. |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3037 if (out->is_Phi() || |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3038 out->is_Cmp()) { |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3039 continue; |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3040 } |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3041 |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3042 if (out->in(0) == NULL) { |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3043 out->set_req(0, non_throwing); |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3044 } else if (out->in(0) == ctrl) { |
e428d5e768e3
8027622: java.time.Instant.create failing since hs25-b56
rbackman
parents:
12966
diff
changeset
|
3045 out->set_req(0, non_throwing); |
12888
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3046 } |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3047 } |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3048 } |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3049 } |
4a2acfb16e97
8025657: compiler/intrinsics/mathexact/ConstantTest.java fails on assert in lcm.cpp on solaris x64
rbackman
parents:
12295
diff
changeset
|
3050 break; |
0 | 3051 default: |
3052 assert( !n->is_Call(), "" ); | |
3053 assert( !n->is_Mem(), "" ); | |
3054 break; | |
3055 } | |
127 | 3056 |
3057 // Collect CFG split points | |
3058 if (n->is_MultiBranch()) | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3059 frc._tests.push(n); |
0 | 3060 } |
3061 | |
3062 //------------------------------final_graph_reshaping_walk--------------------- | |
3063 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), | |
3064 // requires that the walk visits a node's inputs before visiting the node. | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3065 void Compile::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
|
3066 ResourceArea *area = Thread::current()->resource_area(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3067 Unique_Node_List sfpt(area); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3068 |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3069 frc._visited.set(root->_idx); // first, mark node as visited |
0 | 3070 uint cnt = root->req(); |
3071 Node *n = root; | |
3072 uint i = 0; | |
3073 while (true) { | |
3074 if (i < cnt) { | |
3075 // Place all non-visited non-null inputs onto stack | |
3076 Node* m = n->in(i); | |
3077 ++i; | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3078 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
|
3079 if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3080 sfpt.push(m); |
0 | 3081 cnt = m->req(); |
3082 nstack.push(n, i); // put on stack parent and next input's index | |
3083 n = m; | |
3084 i = 0; | |
3085 } | |
3086 } else { | |
3087 // Now do post-visit work | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3088 final_graph_reshaping_impl( n, frc ); |
0 | 3089 if (nstack.is_empty()) |
3090 break; // finished | |
3091 n = nstack.node(); // Get node from stack | |
3092 cnt = n->req(); | |
3093 i = nstack.index(); | |
3094 nstack.pop(); // Shift to the next node on stack | |
3095 } | |
3096 } | |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3097 |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
3098 // Skip next transformation if compressed oops are not used. |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
3099 if ((UseCompressedOops && !Matcher::gen_narrow_oop_implicit_null_checks()) || |
12226
7944aba7ba41
8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents:
12167
diff
changeset
|
3100 (!UseCompressedOops && !UseCompressedClassPointers)) |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
3101 return; |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
3102 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
3103 // Go over safepoints nodes to skip DecodeN/DecodeNKlass nodes for debug edges. |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3104 // It could be done for an uncommon traps or any safepoints/calls |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
3105 // if the DecodeN/DecodeNKlass node is referenced only in a debug info. |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3106 while (sfpt.size() > 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3107 n = sfpt.pop(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3108 JVMState *jvms = n->as_SafePoint()->jvms(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3109 assert(jvms != NULL, "sanity"); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3110 int start = jvms->debug_start(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3111 int end = n->req(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3112 bool is_uncommon = (n->is_CallStaticJava() && |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3113 n->as_CallStaticJava()->uncommon_trap_request() != 0); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3114 for (int j = start; j < end; j++) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3115 Node* in = n->in(j); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
3116 if (in->is_DecodeNarrowPtr()) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3117 bool safe_to_skip = true; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3118 if (!is_uncommon ) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3119 // Is it safe to skip? |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3120 for (uint i = 0; i < in->outcnt(); i++) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3121 Node* u = in->raw_out(i); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3122 if (!u->is_SafePoint() || |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3123 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
|
3124 safe_to_skip = false; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3125 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3126 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3127 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3128 if (safe_to_skip) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3129 n->set_req(j, in->in(1)); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3130 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3131 if (in->outcnt() == 0) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3132 in->disconnect_inputs(NULL, this); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3133 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3134 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3135 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
3136 } |
0 | 3137 } |
3138 | |
3139 //------------------------------final_graph_reshaping-------------------------- | |
3140 // Final Graph Reshaping. | |
3141 // | |
3142 // (1) Clone simple inputs to uncommon calls, so they can be scheduled late | |
3143 // and not commoned up and forced early. Must come after regular | |
3144 // optimizations to avoid GVN undoing the cloning. Clone constant | |
3145 // inputs to Loop Phis; these will be split by the allocator anyways. | |
3146 // Remove Opaque nodes. | |
3147 // (2) Move last-uses by commutative operations to the left input to encourage | |
3148 // Intel update-in-place two-address operations and better register usage | |
3149 // on RISCs. Must come after regular optimizations to avoid GVN Ideal | |
3150 // calls canonicalizing them back. | |
3151 // (3) Count the number of double-precision FP ops, single-precision FP ops | |
3152 // and call sites. On Intel, we can get correct rounding either by | |
3153 // forcing singles to memory (requires extra stores and loads after each | |
3154 // FP bytecode) or we can set a rounding mode bit (requires setting and | |
3155 // clearing the mode bit around call sites). The mode bit is only used | |
3156 // if the relative frequency of single FP ops to calls is low enough. | |
3157 // This is a key transform for SPEC mpeg_audio. | |
3158 // (4) Detect infinite loops; blobs of code reachable from above but not | |
3159 // below. Several of the Code_Gen algorithms fail on such code shapes, | |
3160 // so we simply bail out. Happens a lot in ZKM.jar, but also happens | |
3161 // from time to time in other codes (such as -Xcomp finalizer loops, etc). | |
3162 // Detection is by looking for IfNodes where only 1 projection is | |
3163 // reachable from below or CatchNodes missing some targets. | |
3164 // (5) Assert for insane oop offsets in debug mode. | |
3165 | |
3166 bool Compile::final_graph_reshaping() { | |
3167 // an infinite loop may have been eliminated by the optimizer, | |
3168 // in which case the graph will be empty. | |
3169 if (root()->req() == 1) { | |
3170 record_method_not_compilable("trivial infinite loop"); | |
3171 return true; | |
3172 } | |
3173 | |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3174 // Expensive nodes have their control input set to prevent the GVN |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3175 // from freely commoning them. There's no GVN beyond this point so |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3176 // no need to keep the control input. We want the expensive nodes to |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3177 // be freely moved to the least frequent code path by gcm. |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3178 assert(OptimizeExpensiveOps || expensive_count() == 0, "optimization off but list non empty?"); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3179 for (int i = 0; i < expensive_count(); i++) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3180 _expensive_nodes->at(i)->set_req(0, NULL); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3181 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3182 |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3183 Final_Reshape_Counts frc; |
0 | 3184 |
3185 // Visit everybody reachable! | |
3186 // Allocate stack of size C->unique()/2 to avoid frequent realloc | |
3187 Node_Stack nstack(unique() >> 1); | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3188 final_graph_reshaping_walk(nstack, root(), frc); |
0 | 3189 |
3190 // 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
|
3191 for( uint i = 0; i < frc._tests.size(); i++ ) { |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3192 MultiBranchNode *n = frc._tests[i]->as_MultiBranch(); |
127 | 3193 // Get number of CFG targets. |
0 | 3194 // Note that PCTables include exception targets after calls. |
127 | 3195 uint required_outcnt = n->required_outcnt(); |
3196 if (n->outcnt() != required_outcnt) { | |
0 | 3197 // Check for a few special cases. Rethrow Nodes never take the |
3198 // 'fall-thru' path, so expected kids is 1 less. | |
3199 if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { | |
3200 if (n->in(0)->in(0)->is_Call()) { | |
3201 CallNode *call = n->in(0)->in(0)->as_Call(); | |
3202 if (call->entry_point() == OptoRuntime::rethrow_stub()) { | |
127 | 3203 required_outcnt--; // Rethrow always has 1 less kid |
0 | 3204 } else if (call->req() > TypeFunc::Parms && |
3205 call->is_CallDynamicJava()) { | |
3206 // Check for null receiver. In such case, the optimizer has | |
3207 // detected that the virtual call will always result in a null | |
3208 // pointer exception. The fall-through projection of this CatchNode | |
3209 // will not be populated. | |
3210 Node *arg0 = call->in(TypeFunc::Parms); | |
3211 if (arg0->is_Type() && | |
3212 arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { | |
127 | 3213 required_outcnt--; |
0 | 3214 } |
3215 } else if (call->entry_point() == OptoRuntime::new_array_Java() && | |
3216 call->req() > TypeFunc::Parms+1 && | |
3217 call->is_CallStaticJava()) { | |
3218 // Check for negative array length. In such case, the optimizer has | |
3219 // detected that the allocation attempt will always result in an | |
3220 // exception. There is no fall-through projection of this CatchNode . | |
3221 Node *arg1 = call->in(TypeFunc::Parms+1); | |
3222 if (arg1->is_Type() && | |
3223 arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { | |
127 | 3224 required_outcnt--; |
0 | 3225 } |
3226 } | |
3227 } | |
3228 } | |
127 | 3229 // Recheck with a better notion of 'required_outcnt' |
3230 if (n->outcnt() != required_outcnt) { | |
0 | 3231 record_method_not_compilable("malformed control flow"); |
3232 return true; // Not all targets reachable! | |
3233 } | |
3234 } | |
3235 // Check that I actually visited all kids. Unreached kids | |
3236 // must be infinite loops. | |
3237 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
|
3238 if (!frc._visited.test(n->fast_out(j)->_idx)) { |
0 | 3239 record_method_not_compilable("infinite loop"); |
3240 return true; // Found unvisited kid; must be unreach | |
3241 } | |
3242 } | |
3243 | |
3244 // If original bytecodes contained a mixture of floats and doubles | |
3245 // 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
|
3246 if( Use24BitFPMode && Use24BitFP && UseSSE == 0 && |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3247 frc.get_float_count() > 32 && |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3248 frc.get_double_count() == 0 && |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3249 (10 * frc.get_call_count() < frc.get_float_count()) ) { |
0 | 3250 set_24_bit_selection_and_mode( false, true ); |
3251 } | |
3252 | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3253 set_java_calls(frc.get_java_call_count()); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
3254 set_inner_loops(frc.get_inner_loop_count()); |
0 | 3255 |
3256 // No infinite loops, no reason to bail out. | |
3257 return false; | |
3258 } | |
3259 | |
3260 //-----------------------------too_many_traps---------------------------------- | |
3261 // Report if there are too many traps at the current method and bci. | |
3262 // Return true if there was a trap, and/or PerMethodTrapLimit is exceeded. | |
3263 bool Compile::too_many_traps(ciMethod* method, | |
3264 int bci, | |
3265 Deoptimization::DeoptReason reason) { | |
3266 ciMethodData* md = method->method_data(); | |
3267 if (md->is_empty()) { | |
3268 // Assume the trap has not occurred, or that it occurred only | |
3269 // because of a transient condition during start-up in the interpreter. | |
3270 return false; | |
3271 } | |
3272 if (md->has_trap_at(bci, reason) != 0) { | |
3273 // Assume PerBytecodeTrapLimit==0, for a more conservative heuristic. | |
3274 // Also, if there are multiple reasons, or if there is no per-BCI record, | |
3275 // assume the worst. | |
3276 if (log()) | |
3277 log()->elem("observe trap='%s' count='%d'", | |
3278 Deoptimization::trap_reason_name(reason), | |
3279 md->trap_count(reason)); | |
3280 return true; | |
3281 } else { | |
3282 // Ignore method/bci and see if there have been too many globally. | |
3283 return too_many_traps(reason, md); | |
3284 } | |
3285 } | |
3286 | |
3287 // Less-accurate variant which does not require a method and bci. | |
3288 bool Compile::too_many_traps(Deoptimization::DeoptReason reason, | |
3289 ciMethodData* logmd) { | |
3290 if (trap_count(reason) >= (uint)PerMethodTrapLimit) { | |
3291 // Too many traps globally. | |
3292 // Note that we use cumulative trap_count, not just md->trap_count. | |
3293 if (log()) { | |
3294 int mcount = (logmd == NULL)? -1: (int)logmd->trap_count(reason); | |
3295 log()->elem("observe trap='%s' count='0' mcount='%d' ccount='%d'", | |
3296 Deoptimization::trap_reason_name(reason), | |
3297 mcount, trap_count(reason)); | |
3298 } | |
3299 return true; | |
3300 } else { | |
3301 // The coast is clear. | |
3302 return false; | |
3303 } | |
3304 } | |
3305 | |
3306 //--------------------------too_many_recompiles-------------------------------- | |
3307 // Report if there are too many recompiles at the current method and bci. | |
3308 // Consults PerBytecodeRecompilationCutoff and PerMethodRecompilationCutoff. | |
3309 // Is not eager to return true, since this will cause the compiler to use | |
3310 // Action_none for a trap point, to avoid too many recompilations. | |
3311 bool Compile::too_many_recompiles(ciMethod* method, | |
3312 int bci, | |
3313 Deoptimization::DeoptReason reason) { | |
3314 ciMethodData* md = method->method_data(); | |
3315 if (md->is_empty()) { | |
3316 // Assume the trap has not occurred, or that it occurred only | |
3317 // because of a transient condition during start-up in the interpreter. | |
3318 return false; | |
3319 } | |
3320 // Pick a cutoff point well within PerBytecodeRecompilationCutoff. | |
3321 uint bc_cutoff = (uint) PerBytecodeRecompilationCutoff / 8; | |
3322 uint m_cutoff = (uint) PerMethodRecompilationCutoff / 2 + 1; // not zero | |
3323 Deoptimization::DeoptReason per_bc_reason | |
3324 = Deoptimization::reason_recorded_per_bytecode_if_any(reason); | |
3325 if ((per_bc_reason == Deoptimization::Reason_none | |
3326 || md->has_trap_at(bci, reason) != 0) | |
3327 // The trap frequency measure we care about is the recompile count: | |
3328 && md->trap_recompiled_at(bci) | |
3329 && md->overflow_recompile_count() >= bc_cutoff) { | |
3330 // Do not emit a trap here if it has already caused recompilations. | |
3331 // Also, if there are multiple reasons, or if there is no per-BCI record, | |
3332 // assume the worst. | |
3333 if (log()) | |
3334 log()->elem("observe trap='%s recompiled' count='%d' recompiles2='%d'", | |
3335 Deoptimization::trap_reason_name(reason), | |
3336 md->trap_count(reason), | |
3337 md->overflow_recompile_count()); | |
3338 return true; | |
3339 } else if (trap_count(reason) != 0 | |
3340 && decompile_count() >= m_cutoff) { | |
3341 // Too many recompiles globally, and we have seen this sort of trap. | |
3342 // Use cumulative decompile_count, not just md->decompile_count. | |
3343 if (log()) | |
3344 log()->elem("observe trap='%s' count='%d' mcount='%d' decompiles='%d' mdecompiles='%d'", | |
3345 Deoptimization::trap_reason_name(reason), | |
3346 md->trap_count(reason), trap_count(reason), | |
3347 md->decompile_count(), decompile_count()); | |
3348 return true; | |
3349 } else { | |
3350 // The coast is clear. | |
3351 return false; | |
3352 } | |
3353 } | |
3354 | |
3355 | |
3356 #ifndef PRODUCT | |
3357 //------------------------------verify_graph_edges--------------------------- | |
3358 // Walk the Graph and verify that there is a one-to-one correspondence | |
3359 // between Use-Def edges and Def-Use edges in the graph. | |
3360 void Compile::verify_graph_edges(bool no_dead_code) { | |
3361 if (VerifyGraphEdges) { | |
3362 ResourceArea *area = Thread::current()->resource_area(); | |
3363 Unique_Node_List visited(area); | |
3364 // Call recursive graph walk to check edges | |
3365 _root->verify_edges(visited); | |
3366 if (no_dead_code) { | |
3367 // Now make sure that no visited node is used by an unvisited node. | |
3368 bool dead_nodes = 0; | |
3369 Unique_Node_List checked(area); | |
3370 while (visited.size() > 0) { | |
3371 Node* n = visited.pop(); | |
3372 checked.push(n); | |
3373 for (uint i = 0; i < n->outcnt(); i++) { | |
3374 Node* use = n->raw_out(i); | |
3375 if (checked.member(use)) continue; // already checked | |
3376 if (visited.member(use)) continue; // already in the graph | |
3377 if (use->is_Con()) continue; // a dead ConNode is OK | |
3378 // At this point, we have found a dead node which is DU-reachable. | |
3379 if (dead_nodes++ == 0) | |
3380 tty->print_cr("*** Dead nodes reachable via DU edges:"); | |
3381 use->dump(2); | |
3382 tty->print_cr("---"); | |
3383 checked.push(use); // No repeats; pretend it is now checked. | |
3384 } | |
3385 } | |
3386 assert(dead_nodes == 0, "using nodes must be reachable from root"); | |
3387 } | |
3388 } | |
3389 } | |
13045
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3390 |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3391 // Verify GC barriers consistency |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3392 // Currently supported: |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3393 // - G1 pre-barriers (see GraphKit::g1_write_barrier_pre()) |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3394 void Compile::verify_barriers() { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3395 if (UseG1GC) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3396 // Verify G1 pre-barriers |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3397 const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3398 |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3399 ResourceArea *area = Thread::current()->resource_area(); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3400 Unique_Node_List visited(area); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3401 Node_List worklist(area); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3402 // We're going to walk control flow backwards starting from the Root |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3403 worklist.push(_root); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3404 while (worklist.size() > 0) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3405 Node* x = worklist.pop(); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3406 if (x == NULL || x == top()) continue; |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3407 if (visited.member(x)) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3408 continue; |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3409 } else { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3410 visited.push(x); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3411 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3412 |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3413 if (x->is_Region()) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3414 for (uint i = 1; i < x->req(); i++) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3415 worklist.push(x->in(i)); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3416 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3417 } else { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3418 worklist.push(x->in(0)); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3419 // We are looking for the pattern: |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3420 // /->ThreadLocal |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3421 // If->Bool->CmpI->LoadB->AddP->ConL(marking_offset) |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3422 // \->ConI(0) |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3423 // We want to verify that the If and the LoadB have the same control |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3424 // See GraphKit::g1_write_barrier_pre() |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3425 if (x->is_If()) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3426 IfNode *iff = x->as_If(); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3427 if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3428 CmpNode *cmp = iff->in(1)->in(1)->as_Cmp(); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3429 if (cmp->Opcode() == Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0 |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3430 && cmp->in(1)->is_Load()) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3431 LoadNode* load = cmp->in(1)->as_Load(); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3432 if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3433 && load->in(2)->in(3)->is_Con() |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3434 && load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3435 |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3436 Node* if_ctrl = iff->in(0); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3437 Node* load_ctrl = load->in(0); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3438 |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3439 if (if_ctrl != load_ctrl) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3440 // Skip possible CProj->NeverBranch in infinite loops |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3441 if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj) |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3442 && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) { |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3443 if_ctrl = if_ctrl->in(0)->in(0); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3444 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3445 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3446 assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match"); |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3447 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3448 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3449 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3450 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3451 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3452 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3453 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3454 } |
94a83e0f9ce1
8017065: C2 allows safepoint checks to leak into G1 pre-barriers
iveresov
parents:
12966
diff
changeset
|
3455 |
0 | 3456 #endif |
3457 | |
3458 // The Compile object keeps track of failure reasons separately from the ciEnv. | |
3459 // This is required because there is not quite a 1-1 relation between the | |
3460 // ciEnv and its compilation task and the Compile object. Note that one | |
3461 // ciEnv might use two Compile objects, if C2Compiler::compile_method decides | |
3462 // to backtrack and retry without subsuming loads. Other than this backtracking | |
3463 // behavior, the Compile's failure reason is quietly copied up to the ciEnv | |
3464 // by the logic in C2Compiler. | |
3465 void Compile::record_failure(const char* reason) { | |
3466 if (log() != NULL) { | |
3467 log()->elem("failure reason='%s' phase='compile'", reason); | |
3468 } | |
3469 if (_failure_reason == NULL) { | |
3470 // Record the first failure reason. | |
3471 _failure_reason = reason; | |
3472 } | |
10405 | 3473 |
3474 EventCompilerFailure event; | |
3475 if (event.should_commit()) { | |
3476 event.set_compileID(Compile::compile_id()); | |
3477 event.set_failure(reason); | |
3478 event.commit(); | |
3479 } | |
3480 | |
222 | 3481 if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) { |
10405 | 3482 C->print_method(PHASE_FAILURE); |
222 | 3483 } |
0 | 3484 _root = NULL; // flush the graph, too |
3485 } | |
3486 | |
3487 Compile::TracePhase::TracePhase(const char* name, elapsedTimer* accumulator, bool dolog) | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3488 : TraceTime(NULL, accumulator, false NOT_PRODUCT( || TimeCompiler ), false), |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3489 _phase_name(name), _dolog(dolog) |
0 | 3490 { |
3491 if (dolog) { | |
3492 C = Compile::current(); | |
3493 _log = C->log(); | |
3494 } else { | |
3495 C = NULL; | |
3496 _log = NULL; | |
3497 } | |
3498 if (_log != NULL) { | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3499 _log->begin_head("phase name='%s' nodes='%d' live='%d'", _phase_name, C->unique(), C->live_nodes()); |
0 | 3500 _log->stamp(); |
3501 _log->end_head(); | |
3502 } | |
3503 } | |
3504 | |
3505 Compile::TracePhase::~TracePhase() { | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3506 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3507 C = Compile::current(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3508 if (_dolog) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3509 _log = C->log(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3510 } else { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3511 _log = NULL; |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3512 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3513 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3514 #ifdef ASSERT |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3515 if (PrintIdealNodeCount) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3516 tty->print_cr("phase name='%s' nodes='%d' live='%d' live_graph_walk='%d'", |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3517 _phase_name, C->unique(), C->live_nodes(), C->count_live_nodes_by_graph_walk()); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3518 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3519 |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3520 if (VerifyIdealNodeCount) { |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3521 Compile::current()->print_missing_nodes(); |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3522 } |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3523 #endif |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3524 |
0 | 3525 if (_log != NULL) { |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6888
diff
changeset
|
3526 _log->done("phase name='%s' nodes='%d' live='%d'", _phase_name, C->unique(), C->live_nodes()); |
0 | 3527 } |
3528 } | |
2008 | 3529 |
3530 //============================================================================= | |
3531 // Two Constant's are equal when the type and the value are equal. | |
3532 bool Compile::Constant::operator==(const Constant& other) { | |
3533 if (type() != other.type() ) return false; | |
3534 if (can_be_reused() != other.can_be_reused()) return false; | |
3535 // For floating point values we compare the bit pattern. | |
3536 switch (type()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3537 case T_FLOAT: return (_v._value.i == other._v._value.i); |
2008 | 3538 case T_LONG: |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3539 case T_DOUBLE: return (_v._value.j == other._v._value.j); |
2008 | 3540 case T_OBJECT: |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3541 case T_ADDRESS: return (_v._value.l == other._v._value.l); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3542 case T_VOID: return (_v._value.l == other._v._value.l); // jump-table entries |
6888
cfe522e6461c
8000623: tools/javac/Diagnostics/6769027/T6769027.java crashes in PSPromotionManager::copy_to_survivor_space
kvn
parents:
6849
diff
changeset
|
3543 case T_METADATA: return (_v._metadata == other._v._metadata); |
2008 | 3544 default: ShouldNotReachHere(); |
3545 } | |
3546 return false; | |
3547 } | |
3548 | |
3549 static int type_to_size_in_bytes(BasicType t) { | |
3550 switch (t) { | |
3551 case T_LONG: return sizeof(jlong ); | |
3552 case T_FLOAT: return sizeof(jfloat ); | |
3553 case T_DOUBLE: return sizeof(jdouble); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3554 case T_METADATA: return sizeof(Metadata*); |
2008 | 3555 // 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
|
3556 // need an internal word relocation. |
2008 | 3557 case T_VOID: |
3558 case T_ADDRESS: | |
3559 case T_OBJECT: return sizeof(jobject); | |
3560 } | |
3561 | |
3562 ShouldNotReachHere(); | |
3563 return -1; | |
3564 } | |
3565 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3566 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
|
3567 // sort descending |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3568 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
|
3569 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
|
3570 return 0; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3571 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3572 |
2008 | 3573 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
|
3574 // First, sort the array by frequencies. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3575 _constants.sort(qsort_comparator); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3576 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3577 #ifdef ASSERT |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3578 // 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
|
3579 // array (they have a negative frequency). |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3580 bool found_void = false; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3581 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
|
3582 Constant con = _constants.at(i); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3583 if (con.type() == T_VOID) |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3584 found_void = true; // jump-tables |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3585 else |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3586 assert(!found_void, "wrong sorting"); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3587 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3588 #endif |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3589 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3590 int offset = 0; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3591 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
|
3592 Constant* con = _constants.adr_at(i); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3593 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3594 // Align offset for type. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3595 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
|
3596 offset = align_size_up(offset, typesize); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3597 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
|
3598 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3599 if (con->type() == T_VOID) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3600 MachConstantNode* n = (MachConstantNode*) con->get_jobject(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3601 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
|
3602 } else { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3603 offset = offset + typesize; |
2008 | 3604 } |
3605 } | |
3606 | |
3607 // Align size up to the next section start (which is insts; see | |
3608 // CodeBuffer::align_at_start). | |
3609 assert(_size == -1, "already set?"); | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3610 _size = align_size_up(offset, CodeEntryAlignment); |
2008 | 3611 } |
3612 | |
3613 void Compile::ConstantTable::emit(CodeBuffer& cb) { | |
3614 MacroAssembler _masm(&cb); | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3615 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
|
3616 Constant con = _constants.at(i); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3617 address constant_addr; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3618 switch (con.type()) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3619 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
|
3620 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
|
3621 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
|
3622 case T_OBJECT: { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3623 jobject obj = con.get_jobject(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3624 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
|
3625 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
|
3626 break; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3627 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3628 case T_ADDRESS: { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3629 address addr = (address) con.get_jobject(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3630 constant_addr = _masm.address_constant(addr); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3631 break; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3632 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3633 // 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
|
3634 // need an internal word relocation. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3635 case T_VOID: { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3636 MachConstantNode* n = (MachConstantNode*) con.get_jobject(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3637 // 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
|
3638 // 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
|
3639 address dummy = (address) n; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3640 constant_addr = _masm.address_constant(dummy); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3641 // Expand jump-table |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3642 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
|
3643 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
|
3644 assert(temp_addr, "consts section too small"); |
2008 | 3645 } |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3646 break; |
2008 | 3647 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3648 case T_METADATA: { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3649 Metadata* obj = con.get_metadata(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3650 int metadata_index = _masm.oop_recorder()->find_index(obj); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3651 constant_addr = _masm.address_constant((address) obj, metadata_Relocation::spec(metadata_index)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3652 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3653 } |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3654 default: ShouldNotReachHere(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3655 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3656 assert(constant_addr, "consts section too small"); |
6268
6c5b7a6becc8
7187454: stack overflow in C2 compiler thread on Solaris x86
kvn
parents:
6179
diff
changeset
|
3657 assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg_res("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset())); |
2008 | 3658 } |
3659 } | |
3660 | |
3661 int Compile::ConstantTable::find_offset(Constant& con) const { | |
3662 int idx = _constants.find(con); | |
3663 assert(idx != -1, "constant must be in constant table"); | |
3664 int offset = _constants.at(idx).offset(); | |
3665 assert(offset != -1, "constant table not emitted yet?"); | |
3666 return offset; | |
3667 } | |
3668 | |
3669 void Compile::ConstantTable::add(Constant& con) { | |
3670 if (con.can_be_reused()) { | |
3671 int idx = _constants.find(con); | |
3672 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
|
3673 _constants.adr_at(idx)->inc_freq(con.freq()); // increase the frequency by the current value |
2008 | 3674 return; |
3675 } | |
3676 } | |
3677 (void) _constants.append(con); | |
3678 } | |
3679 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3680 Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, BasicType type, jvalue value) { |
12023
d1034bd8cefc
8022284: Hide internal data structure in PhaseCFG
adlertz
parents:
10405
diff
changeset
|
3681 Block* b = Compile::current()->cfg()->get_block_for_node(n); |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3682 Constant con(type, value, b->_freq); |
2008 | 3683 add(con); |
3684 return con; | |
3685 } | |
3686 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3687 Compile::Constant Compile::ConstantTable::add(Metadata* metadata) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3688 Constant con(metadata); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3689 add(con); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3690 return con; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3691 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3692 |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3693 Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, MachOper* oper) { |
2008 | 3694 jvalue value; |
3695 BasicType type = oper->type()->basic_type(); | |
3696 switch (type) { | |
3697 case T_LONG: value.j = oper->constantL(); break; | |
3698 case T_FLOAT: value.f = oper->constantF(); break; | |
3699 case T_DOUBLE: value.d = oper->constantD(); break; | |
3700 case T_OBJECT: | |
3701 case T_ADDRESS: value.l = (jobject) oper->constant(); break; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3702 case T_METADATA: return add((Metadata*)oper->constant()); break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3703 default: guarantee(false, err_msg_res("unhandled type: %s", type2name(type))); |
2008 | 3704 } |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3705 return add(n, type, value); |
2008 | 3706 } |
3707 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3708 Compile::Constant Compile::ConstantTable::add_jump_table(MachConstantNode* n) { |
2008 | 3709 jvalue value; |
3710 // We can use the node pointer here to identify the right jump-table | |
3711 // as this method is called from Compile::Fill_buffer right before | |
3712 // the MachNodes are emitted and the jump-table is filled (means the | |
3713 // MachNode pointers do not change anymore). | |
3714 value.l = (jobject) n; | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3715 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
|
3716 add(con); |
2008 | 3717 return con; |
3718 } | |
3719 | |
3720 void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const { | |
3721 // If called from Compile::scratch_emit_size do nothing. | |
3722 if (Compile::current()->in_scratch_emit_size()) return; | |
3723 | |
3724 assert(labels.is_nonempty(), "must be"); | |
6268
6c5b7a6becc8
7187454: stack overflow in C2 compiler thread on Solaris x86
kvn
parents:
6179
diff
changeset
|
3725 assert((uint) labels.length() == n->outcnt(), err_msg_res("must be equal: %d == %d", labels.length(), n->outcnt())); |
2008 | 3726 |
3727 // Since MachConstantNode::constant_offset() also contains | |
3728 // table_base_offset() we need to subtract the table_base_offset() | |
3729 // to get the plain offset into the constant table. | |
3730 int offset = n->constant_offset() - table_base_offset(); | |
3731 | |
3732 MacroAssembler _masm(&cb); | |
3733 address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset); | |
3734 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3735 for (uint i = 0; i < n->outcnt(); i++) { |
2008 | 3736 address* constant_addr = &jump_table_base[i]; |
6268
6c5b7a6becc8
7187454: stack overflow in C2 compiler thread on Solaris x86
kvn
parents:
6179
diff
changeset
|
3737 assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i))); |
2008 | 3738 *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr); |
3739 cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type); | |
3740 } | |
3741 } | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
3742 |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
3743 void Compile::dump_inlining() { |
12295 | 3744 if (print_inlining() || print_intrinsics()) { |
7473 | 3745 // Print inlining message for candidates that we couldn't inline |
3746 // for lack of space or non constant receiver | |
3747 for (int i = 0; i < _late_inlines.length(); i++) { | |
3748 CallGenerator* cg = _late_inlines.at(i); | |
3749 cg->print_inlining_late("live nodes > LiveNodeCountInliningCutoff"); | |
3750 } | |
3751 Unique_Node_List useful; | |
3752 useful.push(root()); | |
3753 for (uint next = 0; next < useful.size(); ++next) { | |
3754 Node* n = useful.at(next); | |
3755 if (n->is_Call() && n->as_Call()->generator() != NULL && n->as_Call()->generator()->call_node() == n) { | |
3756 CallNode* call = n->as_Call(); | |
3757 CallGenerator* cg = call->generator(); | |
3758 cg->print_inlining_late("receiver not constant"); | |
3759 } | |
3760 uint max = n->len(); | |
3761 for ( uint i = 0; i < max; ++i ) { | |
3762 Node *m = n->in(i); | |
3763 if ( m == NULL ) continue; | |
3764 useful.push(m); | |
3765 } | |
3766 } | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
3767 for (int i = 0; i < _print_inlining_list->length(); i++) { |
12295 | 3768 tty->print(_print_inlining_list->adr_at(i)->ss()->as_string()); |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
3769 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
3770 } |
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
7199
diff
changeset
|
3771 } |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3772 |
17622 | 3773 // Dump inlining replay data to the stream. |
3774 // Don't change thread state and acquire any locks. | |
3775 void Compile::dump_inline_data(outputStream* out) { | |
3776 InlineTree* inl_tree = ilt(); | |
3777 if (inl_tree != NULL) { | |
3778 out->print(" inline %d", inl_tree->count()); | |
3779 inl_tree->dump_replay_data(out); | |
3780 } | |
3781 } | |
3782 | |
8048
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3783 int Compile::cmp_expensive_nodes(Node* n1, Node* n2) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3784 if (n1->Opcode() < n2->Opcode()) return -1; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3785 else if (n1->Opcode() > n2->Opcode()) return 1; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3786 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3787 assert(n1->req() == n2->req(), err_msg_res("can't compare %s nodes: n1->req() = %d, n2->req() = %d", NodeClassNames[n1->Opcode()], n1->req(), n2->req())); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3788 for (uint i = 1; i < n1->req(); i++) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3789 if (n1->in(i) < n2->in(i)) return -1; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3790 else if (n1->in(i) > n2->in(i)) return 1; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3791 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3792 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3793 return 0; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3794 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3795 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3796 int Compile::cmp_expensive_nodes(Node** n1p, Node** n2p) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3797 Node* n1 = *n1p; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3798 Node* n2 = *n2p; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3799 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3800 return cmp_expensive_nodes(n1, n2); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3801 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3802 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3803 void Compile::sort_expensive_nodes() { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3804 if (!expensive_nodes_sorted()) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3805 _expensive_nodes->sort(cmp_expensive_nodes); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3806 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3807 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3808 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3809 bool Compile::expensive_nodes_sorted() const { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3810 for (int i = 1; i < _expensive_nodes->length(); i++) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3811 if (cmp_expensive_nodes(_expensive_nodes->adr_at(i), _expensive_nodes->adr_at(i-1)) < 0) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3812 return false; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3813 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3814 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3815 return true; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3816 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3817 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3818 bool Compile::should_optimize_expensive_nodes(PhaseIterGVN &igvn) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3819 if (_expensive_nodes->length() == 0) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3820 return false; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3821 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3822 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3823 assert(OptimizeExpensiveOps, "optimization off?"); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3824 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3825 // Take this opportunity to remove dead nodes from the list |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3826 int j = 0; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3827 for (int i = 0; i < _expensive_nodes->length(); i++) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3828 Node* n = _expensive_nodes->at(i); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3829 if (!n->is_unreachable(igvn)) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3830 assert(n->is_expensive(), "should be expensive"); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3831 _expensive_nodes->at_put(j, n); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3832 j++; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3833 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3834 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3835 _expensive_nodes->trunc_to(j); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3836 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3837 // Then sort the list so that similar nodes are next to each other |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3838 // and check for at least two nodes of identical kind with same data |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3839 // inputs. |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3840 sort_expensive_nodes(); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3841 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3842 for (int i = 0; i < _expensive_nodes->length()-1; i++) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3843 if (cmp_expensive_nodes(_expensive_nodes->adr_at(i), _expensive_nodes->adr_at(i+1)) == 0) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3844 return true; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3845 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3846 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3847 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3848 return false; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3849 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3850 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3851 void Compile::cleanup_expensive_nodes(PhaseIterGVN &igvn) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3852 if (_expensive_nodes->length() == 0) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3853 return; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3854 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3855 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3856 assert(OptimizeExpensiveOps, "optimization off?"); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3857 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3858 // Sort to bring similar nodes next to each other and clear the |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3859 // control input of nodes for which there's only a single copy. |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3860 sort_expensive_nodes(); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3861 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3862 int j = 0; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3863 int identical = 0; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3864 int i = 0; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3865 for (; i < _expensive_nodes->length()-1; i++) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3866 assert(j <= i, "can't write beyond current index"); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3867 if (_expensive_nodes->at(i)->Opcode() == _expensive_nodes->at(i+1)->Opcode()) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3868 identical++; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3869 _expensive_nodes->at_put(j++, _expensive_nodes->at(i)); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3870 continue; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3871 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3872 if (identical > 0) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3873 _expensive_nodes->at_put(j++, _expensive_nodes->at(i)); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3874 identical = 0; |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3875 } else { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3876 Node* n = _expensive_nodes->at(i); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3877 igvn.hash_delete(n); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3878 n->set_req(0, NULL); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3879 igvn.hash_insert(n); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3880 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3881 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3882 if (identical > 0) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3883 _expensive_nodes->at_put(j++, _expensive_nodes->at(i)); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3884 } else if (_expensive_nodes->length() >= 1) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3885 Node* n = _expensive_nodes->at(i); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3886 igvn.hash_delete(n); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3887 n->set_req(0, NULL); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3888 igvn.hash_insert(n); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3889 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3890 _expensive_nodes->trunc_to(j); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3891 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3892 |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3893 void Compile::add_expensive_node(Node * n) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3894 assert(!_expensive_nodes->contains(n), "duplicate entry in expensive list"); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3895 assert(n->is_expensive(), "expensive nodes with non-null control here only"); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3896 assert(!n->is_CFG() && !n->is_Mem(), "no cfg or memory nodes here"); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3897 if (OptimizeExpensiveOps) { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3898 _expensive_nodes->append(n); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3899 } else { |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3900 // Clear control input and let IGVN optimize expensive nodes if |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3901 // OptimizeExpensiveOps is off. |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3902 n->set_req(0, NULL); |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3903 } |
8b3da8d14c93
7197327: 40% regression on 8 b41 comp 8 b40 on specjvm2008.mpegaudio on oob
roland
parents:
7605
diff
changeset
|
3904 } |
8691
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3905 |
12966 | 3906 /** |
3907 * Remove the speculative part of types and clean up the graph | |
3908 */ | |
3909 void Compile::remove_speculative_types(PhaseIterGVN &igvn) { | |
3910 if (UseTypeSpeculation) { | |
3911 Unique_Node_List worklist; | |
3912 worklist.push(root()); | |
3913 int modified = 0; | |
3914 // Go over all type nodes that carry a speculative type, drop the | |
3915 // speculative part of the type and enqueue the node for an igvn | |
3916 // which may optimize it out. | |
3917 for (uint next = 0; next < worklist.size(); ++next) { | |
3918 Node *n = worklist.at(next); | |
17671
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3919 if (n->is_Type()) { |
12966 | 3920 TypeNode* tn = n->as_Type(); |
17671
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3921 const Type* t = tn->type(); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3922 const Type* t_no_spec = t->remove_speculative(); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3923 if (t_no_spec != t) { |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3924 bool in_hash = igvn.hash_delete(n); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3925 assert(in_hash, "node should be in igvn hash table"); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3926 tn->set_type(t_no_spec); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3927 igvn.hash_insert(n); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3928 igvn._worklist.push(n); // give it a chance to go away |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3929 modified++; |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3930 } |
12966 | 3931 } |
3932 uint max = n->len(); | |
3933 for( uint i = 0; i < max; ++i ) { | |
3934 Node *m = n->in(i); | |
3935 if (not_a_node(m)) continue; | |
3936 worklist.push(m); | |
3937 } | |
3938 } | |
3939 // Drop the speculative part of all types in the igvn's type table | |
3940 igvn.remove_speculative_types(); | |
3941 if (modified > 0) { | |
3942 igvn.optimize(); | |
3943 } | |
17671
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3944 #ifdef ASSERT |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3945 // Verify that after the IGVN is over no speculative type has resurfaced |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3946 worklist.clear(); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3947 worklist.push(root()); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3948 for (uint next = 0; next < worklist.size(); ++next) { |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3949 Node *n = worklist.at(next); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3950 const Type* t = igvn.type(n); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3951 assert(t == t->remove_speculative(), "no more speculative types"); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3952 if (n->is_Type()) { |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3953 t = n->as_Type()->type(); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3954 assert(t == t->remove_speculative(), "no more speculative types"); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3955 } |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3956 uint max = n->len(); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3957 for( uint i = 0; i < max; ++i ) { |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3958 Node *m = n->in(i); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3959 if (not_a_node(m)) continue; |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3960 worklist.push(m); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3961 } |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3962 } |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3963 igvn.check_no_speculative_types(); |
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
17622
diff
changeset
|
3964 #endif |
12966 | 3965 } |
3966 } | |
3967 | |
8691
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3968 // Auxiliary method to support randomized stressing/fuzzing. |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3969 // |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3970 // This method can be called the arbitrary number of times, with current count |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3971 // as the argument. The logic allows selecting a single candidate from the |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3972 // running list of candidates as follows: |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3973 // int count = 0; |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3974 // Cand* selected = null; |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3975 // while(cand = cand->next()) { |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3976 // if (randomized_select(++count)) { |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3977 // selected = cand; |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3978 // } |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3979 // } |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3980 // |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3981 // Including count equalizes the chances any candidate is "selected". |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3982 // This is useful when we don't have the complete list of candidates to choose |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3983 // from uniformly. In this case, we need to adjust the randomicity of the |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3984 // selection, or else we will end up biasing the selection towards the latter |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3985 // candidates. |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3986 // |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3987 // Quick back-envelope calculation shows that for the list of n candidates |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3988 // the equal probability for the candidate to persist as "best" can be |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3989 // achieved by replacing it with "next" k-th candidate with the probability |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3990 // of 1/k. It can be easily shown that by the end of the run, the |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3991 // probability for any candidate is converged to 1/n, thus giving the |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3992 // uniform distribution among all the candidates. |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3993 // |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3994 // We don't care about the domain size as long as (RANDOMIZED_DOMAIN / count) is large. |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3995 #define RANDOMIZED_DOMAIN_POW 29 |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3996 #define RANDOMIZED_DOMAIN (1 << RANDOMIZED_DOMAIN_POW) |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3997 #define RANDOMIZED_DOMAIN_MASK ((1 << (RANDOMIZED_DOMAIN_POW + 1)) - 1) |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3998 bool Compile::randomized_select(int count) { |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
3999 assert(count > 0, "only positive"); |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
4000 return (os::random() & RANDOMIZED_DOMAIN_MASK) < (RANDOMIZED_DOMAIN / count); |
571076d3c79d
8009120: Fuzz instruction scheduling in HotSpot compilers
shade
parents:
8048
diff
changeset
|
4001 } |