annotate src/share/vm/c1/c1_IR.cpp @ 1721:413ad0331a0c

6977924: Changes for 6975078 produce build error with certain gcc versions Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error. Reviewed-by: jcoomes, ysr, phh
author johnc
date Wed, 18 Aug 2010 10:59:06 -0700
parents b812ff5abc73
children d5d065957597
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1295
diff changeset
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1295
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1295
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: 1295
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_c1_IR.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // Implementation of XHandlers
a61af66fc99e Initial load
duke
parents:
diff changeset
30 //
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // Note: This code could eventually go away if we are
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // just using the ciExceptionHandlerStream.
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 XHandlers::XHandlers(ciMethod* method) : _list(method->exception_table_length()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
35 ciExceptionHandlerStream s(method);
a61af66fc99e Initial load
duke
parents:
diff changeset
36 while (!s.is_done()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 _list.append(new XHandler(s.handler()));
a61af66fc99e Initial load
duke
parents:
diff changeset
38 s.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
39 }
a61af66fc99e Initial load
duke
parents:
diff changeset
40 assert(s.count() == method->exception_table_length(), "exception table lengths inconsistent");
a61af66fc99e Initial load
duke
parents:
diff changeset
41 }
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // deep copy of all XHandler contained in list
a61af66fc99e Initial load
duke
parents:
diff changeset
44 XHandlers::XHandlers(XHandlers* other) :
a61af66fc99e Initial load
duke
parents:
diff changeset
45 _list(other->length())
a61af66fc99e Initial load
duke
parents:
diff changeset
46 {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 for (int i = 0; i < other->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _list.append(new XHandler(other->handler_at(i)));
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50 }
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // Returns whether a particular exception type can be caught. Also
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // returns true if klass is unloaded or any exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // classes are unloaded. type_is_exact indicates whether the throw
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // is known to be exactly that class or it might throw a subtype.
a61af66fc99e Initial load
duke
parents:
diff changeset
56 bool XHandlers::could_catch(ciInstanceKlass* klass, bool type_is_exact) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // the type is unknown so be conservative
a61af66fc99e Initial load
duke
parents:
diff changeset
58 if (!klass->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 for (int i = 0; i < length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
63 XHandler* handler = handler_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
64 if (handler->is_catch_all()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // catch of ANY
a61af66fc99e Initial load
duke
parents:
diff changeset
66 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 }
a61af66fc99e Initial load
duke
parents:
diff changeset
68 ciInstanceKlass* handler_klass = handler->catch_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // if it's unknown it might be catchable
a61af66fc99e Initial load
duke
parents:
diff changeset
70 if (!handler_klass->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
71 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 }
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // if the throw type is definitely a subtype of the catch type
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // then it can be caught.
a61af66fc99e Initial load
duke
parents:
diff changeset
75 if (klass->is_subtype_of(handler_klass)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78 if (!type_is_exact) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // If the type isn't exactly known then it can also be caught by
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // catch statements where the inexact type is a subtype of the
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // catch type.
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // given: foo extends bar extends Exception
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // throw bar can be caught by catch foo, catch bar, and catch
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // Exception, however it can't be caught by any handlers without
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // bar in its type hierarchy.
a61af66fc99e Initial load
duke
parents:
diff changeset
86 if (handler_klass->is_subtype_of(klass)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 bool XHandlers::equals(XHandlers* others) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 if (others == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 if (length() != others->length()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 for (int i = 0; i < length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 if (!handler_at(i)->equals(others->handler_at(i))) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 bool XHandler::equals(XHandler* other) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 assert(entry_pco() != -1 && other->entry_pco() != -1, "must have entry_pco");
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if (entry_pco() != other->entry_pco()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (scope_count() != other->scope_count()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 if (_desc != other->_desc) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 assert(entry_block() == other->entry_block(), "entry_block must be equal when entry_pco is equal");
a61af66fc99e Initial load
duke
parents:
diff changeset
114 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Implementation of IRScope
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 BlockBegin* IRScope::header_block(BlockBegin* entry, BlockBegin::Flag f, ValueStack* state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 if (entry == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 assert(entry->is_set(f), "entry/flag mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // create header block
a61af66fc99e Initial load
duke
parents:
diff changeset
124 BlockBegin* h = new BlockBegin(entry->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
125 BlockEnd* g = new Goto(entry, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
126 h->set_next(g, entry->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
127 h->set_end(g);
a61af66fc99e Initial load
duke
parents:
diff changeset
128 h->set(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // setup header block end state
a61af66fc99e Initial load
duke
parents:
diff changeset
130 ValueStack* s = state->copy(); // can use copy since stack is empty (=> no phis)
a61af66fc99e Initial load
duke
parents:
diff changeset
131 assert(s->stack_is_empty(), "must have empty stack at entry point");
a61af66fc99e Initial load
duke
parents:
diff changeset
132 g->set_state(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 return h;
a61af66fc99e Initial load
duke
parents:
diff changeset
134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136
a61af66fc99e Initial load
duke
parents:
diff changeset
137 BlockBegin* IRScope::build_graph(Compilation* compilation, int osr_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 GraphBuilder gm(compilation, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 NOT_PRODUCT(if (PrintValueNumbering && Verbose) gm.print_stats());
a61af66fc99e Initial load
duke
parents:
diff changeset
140 if (compilation->bailed_out()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
141 return gm.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 IRScope::IRScope(Compilation* compilation, IRScope* caller, int caller_bci, ciMethod* method, int osr_bci, bool create_graph)
a61af66fc99e Initial load
duke
parents:
diff changeset
146 : _callees(2)
a61af66fc99e Initial load
duke
parents:
diff changeset
147 , _compilation(compilation)
a61af66fc99e Initial load
duke
parents:
diff changeset
148 , _lock_stack_size(-1)
a61af66fc99e Initial load
duke
parents:
diff changeset
149 , _requires_phi_function(method->max_locals())
a61af66fc99e Initial load
duke
parents:
diff changeset
150 {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 _caller = caller;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 _caller_bci = caller == NULL ? -1 : caller_bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 _caller_state = NULL; // Must be set later if needed
a61af66fc99e Initial load
duke
parents:
diff changeset
154 _level = caller == NULL ? 0 : caller->level() + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 _method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
156 _xhandlers = new XHandlers(method);
a61af66fc99e Initial load
duke
parents:
diff changeset
157 _number_of_locks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 _monitor_pairing_ok = method->has_balanced_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
159 _start = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 if (osr_bci == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
162 _requires_phi_function.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
163 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // selective creation of phi functions is not possibel in osr-methods
a61af66fc99e Initial load
duke
parents:
diff changeset
165 _requires_phi_function.set_range(0, method->max_locals());
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 assert(method->holder()->is_loaded() , "method holder must be loaded");
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // build graph if monitor pairing is ok
a61af66fc99e Initial load
duke
parents:
diff changeset
171 if (create_graph && monitor_pairing_ok()) _start = build_graph(compilation, osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 int IRScope::max_stack() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 int my_max = method()->max_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
177 int callee_max = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
178 for (int i = 0; i < number_of_callees(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 callee_max = MAX2(callee_max, callee_no(i)->max_stack());
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181 return my_max + callee_max;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 void IRScope::compute_lock_stack_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (!InlineMethodsWithExceptionHandlers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 _lock_stack_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // Figure out whether we have to preserve expression stack elements
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // for parent scopes, and if so, how many
a61af66fc99e Initial load
duke
parents:
diff changeset
193 IRScope* cur_scope = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
194 while (cur_scope != NULL && !cur_scope->xhandlers()->has_handlers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 cur_scope = cur_scope->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197 _lock_stack_size = (cur_scope == NULL ? 0 :
a61af66fc99e Initial load
duke
parents:
diff changeset
198 (cur_scope->caller_state() == NULL ? 0 :
a61af66fc99e Initial load
duke
parents:
diff changeset
199 cur_scope->caller_state()->stack_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 int IRScope::top_scope_bci() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 assert(!is_top_scope(), "no correct answer for top scope possible");
a61af66fc99e Initial load
duke
parents:
diff changeset
204 const IRScope* scope = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 while (!scope->caller()->is_top_scope()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 scope = scope->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208 return scope->caller_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 470
diff changeset
211 bool IRScopeDebugInfo::should_reexecute() {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 470
diff changeset
212 ciMethod* cur_method = scope()->method();
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 470
diff changeset
213 int cur_bci = bci();
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 470
diff changeset
214 if (cur_method != NULL && cur_bci != SynchronizationEntryBCI) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 470
diff changeset
215 Bytecodes::Code code = cur_method->java_code_at_bci(cur_bci);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 470
diff changeset
216 return Interpreter::bytecode_should_reexecute(code);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 470
diff changeset
217 } else
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 470
diff changeset
218 return false;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 470
diff changeset
219 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // Implementation of CodeEmitInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // Stack must be NON-null
a61af66fc99e Initial load
duke
parents:
diff changeset
225 CodeEmitInfo::CodeEmitInfo(int bci, ValueStack* stack, XHandlers* exception_handlers)
a61af66fc99e Initial load
duke
parents:
diff changeset
226 : _scope(stack->scope())
a61af66fc99e Initial load
duke
parents:
diff changeset
227 , _bci(bci)
a61af66fc99e Initial load
duke
parents:
diff changeset
228 , _scope_debug_info(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
229 , _oop_map(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
230 , _stack(stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
231 , _exception_handlers(exception_handlers)
a61af66fc99e Initial load
duke
parents:
diff changeset
232 , _next(NULL)
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1295
diff changeset
233 , _id(-1)
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1295
diff changeset
234 , _is_method_handle_invoke(false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
235 assert(_stack != NULL, "must be non null");
a61af66fc99e Initial load
duke
parents:
diff changeset
236 assert(_bci == SynchronizationEntryBCI || Bytecodes::is_defined(scope()->method()->java_code_at_bci(_bci)), "make sure bci points at a real bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 CodeEmitInfo::CodeEmitInfo(CodeEmitInfo* info, bool lock_stack_only)
a61af66fc99e Initial load
duke
parents:
diff changeset
241 : _scope(info->_scope)
a61af66fc99e Initial load
duke
parents:
diff changeset
242 , _exception_handlers(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
243 , _bci(info->_bci)
a61af66fc99e Initial load
duke
parents:
diff changeset
244 , _scope_debug_info(NULL)
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1295
diff changeset
245 , _oop_map(NULL)
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1295
diff changeset
246 , _is_method_handle_invoke(info->_is_method_handle_invoke) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247 if (lock_stack_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (info->_stack != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 _stack = info->_stack->copy_locks();
a61af66fc99e Initial load
duke
parents:
diff changeset
250 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
251 _stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 _stack = info->_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // deep copy of exception handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
258 if (info->_exception_handlers != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 _exception_handlers = new XHandlers(info->_exception_handlers);
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1295
diff changeset
264 void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // record the safepoint before recording the debug info for enclosing scopes
a61af66fc99e Initial load
duke
parents:
diff changeset
266 recorder->add_safepoint(pc_offset, _oop_map->deep_copy());
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1295
diff changeset
267 _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/, _is_method_handle_invoke);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
268 recorder->end_safepoint(pc_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 void CodeEmitInfo::add_register_oop(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 assert(_oop_map != NULL, "oop map must already exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
274 assert(opr->is_single_cpu(), "should not call otherwise");
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 int frame_size = frame_map()->framesize();
a61af66fc99e Initial load
duke
parents:
diff changeset
277 int arg_count = frame_map()->oop_map_arg_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
278 VMReg name = frame_map()->regname(opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
279 _oop_map->set_oop(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282
a61af66fc99e Initial load
duke
parents:
diff changeset
283
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // Implementation of IR
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 IR::IR(Compilation* compilation, ciMethod* method, int osr_bci) :
a61af66fc99e Initial load
duke
parents:
diff changeset
288 _locals_size(in_WordSize(-1))
a61af66fc99e Initial load
duke
parents:
diff changeset
289 , _num_loops(0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // setup IR fields
a61af66fc99e Initial load
duke
parents:
diff changeset
291 _compilation = compilation;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 _top_scope = new IRScope(compilation, NULL, -1, method, osr_bci, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
293 _code = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 void IR::optimize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
298 Optimizer opt(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
299 if (DoCEE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 opt.eliminate_conditional_expressions();
a61af66fc99e Initial load
duke
parents:
diff changeset
301 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
302 if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after CEE"); print(true); }
a61af66fc99e Initial load
duke
parents:
diff changeset
303 if (PrintIR || PrintIR1 ) { tty->print_cr("IR after CEE"); print(false); }
a61af66fc99e Initial load
duke
parents:
diff changeset
304 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
306 if (EliminateBlocks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 opt.eliminate_blocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
308 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after block elimination"); print(true); }
a61af66fc99e Initial load
duke
parents:
diff changeset
310 if (PrintIR || PrintIR1 ) { tty->print_cr("IR after block elimination"); print(false); }
a61af66fc99e Initial load
duke
parents:
diff changeset
311 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if (EliminateNullChecks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 opt.eliminate_null_checks();
a61af66fc99e Initial load
duke
parents:
diff changeset
315 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
316 if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after null check elimination"); print(true); }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 if (PrintIR || PrintIR1 ) { tty->print_cr("IR after null check elimination"); print(false); }
a61af66fc99e Initial load
duke
parents:
diff changeset
318 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 static int sort_pairs(BlockPair** a, BlockPair** b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
324 if ((*a)->from() == (*b)->from()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 return (*a)->to()->block_id() - (*b)->to()->block_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
326 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 return (*a)->from()->block_id() - (*b)->from()->block_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
330
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 class CriticalEdgeFinder: public BlockClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
333 BlockPairList blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
334 IR* _ir;
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
337 CriticalEdgeFinder(IR* ir): _ir(ir) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
338 void block_do(BlockBegin* bb) {
a61af66fc99e Initial load
duke
parents:
diff changeset
339 BlockEnd* be = bb->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
340 int nos = be->number_of_sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
341 if (nos >= 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 for (int i = 0; i < nos; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 BlockBegin* sux = be->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 if (sux->number_of_preds() >= 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
345 blocks.append(new BlockPair(bb, sux));
a61af66fc99e Initial load
duke
parents:
diff changeset
346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 void split_edges() {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 BlockPair* last_pair = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
353 blocks.sort(sort_pairs);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 for (int i = 0; i < blocks.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 BlockPair* pair = blocks.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
356 if (last_pair != NULL && pair->is_same(last_pair)) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
357 BlockBegin* from = pair->from();
a61af66fc99e Initial load
duke
parents:
diff changeset
358 BlockBegin* to = pair->to();
a61af66fc99e Initial load
duke
parents:
diff changeset
359 BlockBegin* split = from->insert_block_between(to);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
361 if ((PrintIR || PrintIR1) && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
362 tty->print_cr("Split critical edge B%d -> B%d (new block B%d)",
a61af66fc99e Initial load
duke
parents:
diff changeset
363 from->block_id(), to->block_id(), split->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
366 last_pair = pair;
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369 };
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 void IR::split_critical_edges() {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 CriticalEdgeFinder cef(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
373
a61af66fc99e Initial load
duke
parents:
diff changeset
374 iterate_preorder(&cef);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 cef.split_edges();
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
379 class UseCountComputer: public ValueVisitor, BlockClosure {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
380 private:
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
381 void visit(Value* n) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // Local instructions and Phis for expression stack values at the
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // start of basic blocks are not added to the instruction list
a61af66fc99e Initial load
duke
parents:
diff changeset
384 if ((*n)->bci() == -99 && (*n)->as_Local() == NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
385 (*n)->as_Phi() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 assert(false, "a node was not appended to the graph");
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
387 Compilation::current()->bailout("a node was not appended to the graph");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // use n's input if not visited before
a61af66fc99e Initial load
duke
parents:
diff changeset
390 if (!(*n)->is_pinned() && !(*n)->has_uses()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // note: a) if the instruction is pinned, it will be handled by compute_use_count
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // b) if the instruction has uses, it was touched before
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // => in both cases we don't need to update n's values
a61af66fc99e Initial load
duke
parents:
diff changeset
394 uses_do(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // use n
a61af66fc99e Initial load
duke
parents:
diff changeset
397 (*n)->_use_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
400 Values* worklist;
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
401 int depth;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
402 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 max_recurse_depth = 20
a61af66fc99e Initial load
duke
parents:
diff changeset
404 };
a61af66fc99e Initial load
duke
parents:
diff changeset
405
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
406 void uses_do(Value* n) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
407 depth++;
a61af66fc99e Initial load
duke
parents:
diff changeset
408 if (depth > max_recurse_depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // don't allow the traversal to recurse too deeply
a61af66fc99e Initial load
duke
parents:
diff changeset
410 worklist->push(*n);
a61af66fc99e Initial load
duke
parents:
diff changeset
411 } else {
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
412 (*n)->input_values_do(this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // special handling for some instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
414 if ((*n)->as_BlockEnd() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // note on BlockEnd:
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // must 'use' the stack only if the method doesn't
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // terminate, however, in those cases stack is empty
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
418 (*n)->state_values_do(this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
421 depth--;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
424 void block_do(BlockBegin* b) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
425 depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // process all pinned nodes as the roots of expression trees
a61af66fc99e Initial load
duke
parents:
diff changeset
427 for (Instruction* n = b; n != NULL; n = n->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 if (n->is_pinned()) uses_do(&n);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430 assert(depth == 0, "should have counted back down");
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // now process any unpinned nodes which recursed too deeply
a61af66fc99e Initial load
duke
parents:
diff changeset
433 while (worklist->length() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
434 Value t = worklist->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
435 if (!t->is_pinned()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // compute the use count
a61af66fc99e Initial load
duke
parents:
diff changeset
437 uses_do(&t);
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // pin the instruction so that LIRGenerator doesn't recurse
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // too deeply during it's evaluation.
a61af66fc99e Initial load
duke
parents:
diff changeset
441 t->pin();
a61af66fc99e Initial load
duke
parents:
diff changeset
442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444 assert(depth == 0, "should have counted back down");
a61af66fc99e Initial load
duke
parents:
diff changeset
445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
446
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
447 UseCountComputer() {
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
448 worklist = new Values();
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
449 depth = 0;
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
450 }
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
451
0
a61af66fc99e Initial load
duke
parents:
diff changeset
452 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
453 static void compute(BlockList* blocks) {
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
454 UseCountComputer ucc;
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
455 blocks->iterate_backward(&ucc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457 };
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // helper macro for short definition of trace-output inside code
a61af66fc99e Initial load
duke
parents:
diff changeset
461 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
462 #define TRACE_LINEAR_SCAN(level, code) \
a61af66fc99e Initial load
duke
parents:
diff changeset
463 if (TraceLinearScanLevel >= level) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
464 code; \
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
467 #define TRACE_LINEAR_SCAN(level, code)
a61af66fc99e Initial load
duke
parents:
diff changeset
468 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
469
a61af66fc99e Initial load
duke
parents:
diff changeset
470 class ComputeLinearScanOrder : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
471 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
472 int _max_block_id; // the highest block_id of a block
a61af66fc99e Initial load
duke
parents:
diff changeset
473 int _num_blocks; // total number of blocks (smaller than _max_block_id)
a61af66fc99e Initial load
duke
parents:
diff changeset
474 int _num_loops; // total number of loops
a61af66fc99e Initial load
duke
parents:
diff changeset
475 bool _iterative_dominators;// method requires iterative computation of dominatiors
a61af66fc99e Initial load
duke
parents:
diff changeset
476
a61af66fc99e Initial load
duke
parents:
diff changeset
477 BlockList* _linear_scan_order; // the resulting list of blocks in correct order
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479 BitMap _visited_blocks; // used for recursive processing of blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
480 BitMap _active_blocks; // used for recursive processing of blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
481 BitMap _dominator_blocks; // temproary BitMap used for computation of dominator
a61af66fc99e Initial load
duke
parents:
diff changeset
482 intArray _forward_branches; // number of incoming forward branches for each block
a61af66fc99e Initial load
duke
parents:
diff changeset
483 BlockList _loop_end_blocks; // list of all loop end blocks collected during count_edges
a61af66fc99e Initial load
duke
parents:
diff changeset
484 BitMap2D _loop_map; // two-dimensional bit set: a bit is set if a block is contained in a loop
a61af66fc99e Initial load
duke
parents:
diff changeset
485 BlockList _work_list; // temporary list (used in mark_loops and compute_order)
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // accessors for _visited_blocks and _active_blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
488 void init_visited() { _active_blocks.clear(); _visited_blocks.clear(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
489 bool is_visited(BlockBegin* b) const { return _visited_blocks.at(b->block_id()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 bool is_active(BlockBegin* b) const { return _active_blocks.at(b->block_id()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
491 void set_visited(BlockBegin* b) { assert(!is_visited(b), "already set"); _visited_blocks.set_bit(b->block_id()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
492 void set_active(BlockBegin* b) { assert(!is_active(b), "already set"); _active_blocks.set_bit(b->block_id()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
493 void clear_active(BlockBegin* b) { assert(is_active(b), "not already"); _active_blocks.clear_bit(b->block_id()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // accessors for _forward_branches
a61af66fc99e Initial load
duke
parents:
diff changeset
496 void inc_forward_branches(BlockBegin* b) { _forward_branches.at_put(b->block_id(), _forward_branches.at(b->block_id()) + 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
497 int dec_forward_branches(BlockBegin* b) { _forward_branches.at_put(b->block_id(), _forward_branches.at(b->block_id()) - 1); return _forward_branches.at(b->block_id()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // accessors for _loop_map
a61af66fc99e Initial load
duke
parents:
diff changeset
500 bool is_block_in_loop (int loop_idx, BlockBegin* b) const { return _loop_map.at(loop_idx, b->block_id()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
501 void set_block_in_loop (int loop_idx, BlockBegin* b) { _loop_map.set_bit(loop_idx, b->block_id()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
502 void clear_block_in_loop(int loop_idx, int block_id) { _loop_map.clear_bit(loop_idx, block_id); }
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // count edges between blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
505 void count_edges(BlockBegin* cur, BlockBegin* parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // loop detection
a61af66fc99e Initial load
duke
parents:
diff changeset
508 void mark_loops();
a61af66fc99e Initial load
duke
parents:
diff changeset
509 void clear_non_natural_loops(BlockBegin* start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
510 void assign_loop_depth(BlockBegin* start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // computation of final block order
a61af66fc99e Initial load
duke
parents:
diff changeset
513 BlockBegin* common_dominator(BlockBegin* a, BlockBegin* b);
a61af66fc99e Initial load
duke
parents:
diff changeset
514 void compute_dominator(BlockBegin* cur, BlockBegin* parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
515 int compute_weight(BlockBegin* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
516 bool ready_for_processing(BlockBegin* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
517 void sort_into_work_list(BlockBegin* b);
a61af66fc99e Initial load
duke
parents:
diff changeset
518 void append_block(BlockBegin* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
519 void compute_order(BlockBegin* start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // fixup of dominators for non-natural loops
a61af66fc99e Initial load
duke
parents:
diff changeset
522 bool compute_dominators_iter();
a61af66fc99e Initial load
duke
parents:
diff changeset
523 void compute_dominators();
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // debug functions
a61af66fc99e Initial load
duke
parents:
diff changeset
526 NOT_PRODUCT(void print_blocks();)
a61af66fc99e Initial load
duke
parents:
diff changeset
527 DEBUG_ONLY(void verify();)
a61af66fc99e Initial load
duke
parents:
diff changeset
528
a61af66fc99e Initial load
duke
parents:
diff changeset
529 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
530 ComputeLinearScanOrder(BlockBegin* start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
531
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // accessors for final result
a61af66fc99e Initial load
duke
parents:
diff changeset
533 BlockList* linear_scan_order() const { return _linear_scan_order; }
a61af66fc99e Initial load
duke
parents:
diff changeset
534 int num_loops() const { return _num_loops; }
a61af66fc99e Initial load
duke
parents:
diff changeset
535 };
a61af66fc99e Initial load
duke
parents:
diff changeset
536
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 ComputeLinearScanOrder::ComputeLinearScanOrder(BlockBegin* start_block) :
a61af66fc99e Initial load
duke
parents:
diff changeset
539 _max_block_id(BlockBegin::number_of_blocks()),
a61af66fc99e Initial load
duke
parents:
diff changeset
540 _num_blocks(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
541 _num_loops(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
542 _iterative_dominators(false),
a61af66fc99e Initial load
duke
parents:
diff changeset
543 _visited_blocks(_max_block_id),
a61af66fc99e Initial load
duke
parents:
diff changeset
544 _active_blocks(_max_block_id),
a61af66fc99e Initial load
duke
parents:
diff changeset
545 _dominator_blocks(_max_block_id),
a61af66fc99e Initial load
duke
parents:
diff changeset
546 _forward_branches(_max_block_id, 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
547 _loop_end_blocks(8),
a61af66fc99e Initial load
duke
parents:
diff changeset
548 _work_list(8),
a61af66fc99e Initial load
duke
parents:
diff changeset
549 _linear_scan_order(NULL), // initialized later with correct size
a61af66fc99e Initial load
duke
parents:
diff changeset
550 _loop_map(0, 0) // initialized later with correct size
a61af66fc99e Initial load
duke
parents:
diff changeset
551 {
a61af66fc99e Initial load
duke
parents:
diff changeset
552 TRACE_LINEAR_SCAN(2, "***** computing linear-scan block order");
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 init_visited();
a61af66fc99e Initial load
duke
parents:
diff changeset
555 count_edges(start_block, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if (_num_loops > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 mark_loops();
a61af66fc99e Initial load
duke
parents:
diff changeset
559 clear_non_natural_loops(start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
560 assign_loop_depth(start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
561 }
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 compute_order(start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
564 compute_dominators();
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566 NOT_PRODUCT(print_blocks());
a61af66fc99e Initial load
duke
parents:
diff changeset
567 DEBUG_ONLY(verify());
a61af66fc99e Initial load
duke
parents:
diff changeset
568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Traverse the CFG:
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // * count total number of blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // * count all incoming edges and backward incoming edges
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // * number loop header blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // * create a list with all loop end blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
576 void ComputeLinearScanOrder::count_edges(BlockBegin* cur, BlockBegin* parent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
577 TRACE_LINEAR_SCAN(3, tty->print_cr("Enter count_edges for block B%d coming from B%d", cur->block_id(), parent != NULL ? parent->block_id() : -1));
a61af66fc99e Initial load
duke
parents:
diff changeset
578 assert(cur->dominator() == NULL, "dominator already initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
579
a61af66fc99e Initial load
duke
parents:
diff changeset
580 if (is_active(cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 TRACE_LINEAR_SCAN(3, tty->print_cr("backward branch"));
a61af66fc99e Initial load
duke
parents:
diff changeset
582 assert(is_visited(cur), "block must be visisted when block is active");
a61af66fc99e Initial load
duke
parents:
diff changeset
583 assert(parent != NULL, "must have parent");
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 cur->set(BlockBegin::linear_scan_loop_header_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
586 cur->set(BlockBegin::backward_branch_target_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
587
a61af66fc99e Initial load
duke
parents:
diff changeset
588 parent->set(BlockBegin::linear_scan_loop_end_flag);
428
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
589
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
590 // When a loop header is also the start of an exception handler, then the backward branch is
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
591 // an exception edge. Because such edges are usually critical edges which cannot be split, the
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
592 // loop must be excluded here from processing.
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
593 if (cur->is_set(BlockBegin::exception_entry_flag)) {
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
594 // Make sure that dominators are correct in this weird situation
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
595 _iterative_dominators = true;
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
596 return;
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
597 }
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
598 assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur,
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
599 "loop end blocks must have one successor (critical edges are split)");
334969144810 6758445: loop heads that are exception entry points can crash during count_edges/mark_loops
never
parents: 0
diff changeset
600
0
a61af66fc99e Initial load
duke
parents:
diff changeset
601 _loop_end_blocks.append(parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // increment number of incoming forward branches
a61af66fc99e Initial load
duke
parents:
diff changeset
606 inc_forward_branches(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608 if (is_visited(cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 TRACE_LINEAR_SCAN(3, tty->print_cr("block already visited"));
a61af66fc99e Initial load
duke
parents:
diff changeset
610 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 _num_blocks++;
a61af66fc99e Initial load
duke
parents:
diff changeset
614 set_visited(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
615 set_active(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
616
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // recursive call for all successors
a61af66fc99e Initial load
duke
parents:
diff changeset
618 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
619 for (i = cur->number_of_sux() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
620 count_edges(cur->sux_at(i), cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
622 for (i = cur->number_of_exception_handlers() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
623 count_edges(cur->exception_handler_at(i), cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626 clear_active(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
627
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // Each loop has a unique number.
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // When multiple loops are nested, assign_loop_depth assumes that the
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // innermost loop has the lowest number. This is guaranteed by setting
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // the loop number after the recursive calls for the successors above
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // have returned.
a61af66fc99e Initial load
duke
parents:
diff changeset
633 if (cur->is_set(BlockBegin::linear_scan_loop_header_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
634 assert(cur->loop_index() == -1, "cannot set loop-index twice");
a61af66fc99e Initial load
duke
parents:
diff changeset
635 TRACE_LINEAR_SCAN(3, tty->print_cr("Block B%d is loop header of loop %d", cur->block_id(), _num_loops));
a61af66fc99e Initial load
duke
parents:
diff changeset
636
a61af66fc99e Initial load
duke
parents:
diff changeset
637 cur->set_loop_index(_num_loops);
a61af66fc99e Initial load
duke
parents:
diff changeset
638 _num_loops++;
a61af66fc99e Initial load
duke
parents:
diff changeset
639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641 TRACE_LINEAR_SCAN(3, tty->print_cr("Finished count_edges for block B%d", cur->block_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
643
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 void ComputeLinearScanOrder::mark_loops() {
a61af66fc99e Initial load
duke
parents:
diff changeset
646 TRACE_LINEAR_SCAN(3, tty->print_cr("----- marking loops"));
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 _loop_map = BitMap2D(_num_loops, _max_block_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
649 _loop_map.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 for (int i = _loop_end_blocks.length() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 BlockBegin* loop_end = _loop_end_blocks.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 BlockBegin* loop_start = loop_end->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
654 int loop_idx = loop_start->loop_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 TRACE_LINEAR_SCAN(3, tty->print_cr("Processing loop from B%d to B%d (loop %d):", loop_start->block_id(), loop_end->block_id(), loop_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
657 assert(loop_end->is_set(BlockBegin::linear_scan_loop_end_flag), "loop end flag must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
658 assert(loop_end->number_of_sux() == 1, "incorrect number of successors");
a61af66fc99e Initial load
duke
parents:
diff changeset
659 assert(loop_start->is_set(BlockBegin::linear_scan_loop_header_flag), "loop header flag must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
660 assert(loop_idx >= 0 && loop_idx < _num_loops, "loop index not set");
a61af66fc99e Initial load
duke
parents:
diff changeset
661 assert(_work_list.is_empty(), "work list must be empty before processing");
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // add the end-block of the loop to the working list
a61af66fc99e Initial load
duke
parents:
diff changeset
664 _work_list.push(loop_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
665 set_block_in_loop(loop_idx, loop_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
666 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
667 BlockBegin* cur = _work_list.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 TRACE_LINEAR_SCAN(3, tty->print_cr(" processing B%d", cur->block_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
670 assert(is_block_in_loop(loop_idx, cur), "bit in loop map must be set when block is in work list");
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // recursive processing of all predecessors ends when start block of loop is reached
a61af66fc99e Initial load
duke
parents:
diff changeset
673 if (cur != loop_start && !cur->is_set(BlockBegin::osr_entry_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
674 for (int j = cur->number_of_preds() - 1; j >= 0; j--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
675 BlockBegin* pred = cur->pred_at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 if (!is_block_in_loop(loop_idx, pred) /*&& !pred->is_set(BlockBeginosr_entry_flag)*/) {
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // this predecessor has not been processed yet, so add it to work list
a61af66fc99e Initial load
duke
parents:
diff changeset
679 TRACE_LINEAR_SCAN(3, tty->print_cr(" pushing B%d", pred->block_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
680 _work_list.push(pred);
a61af66fc99e Initial load
duke
parents:
diff changeset
681 set_block_in_loop(loop_idx, pred);
a61af66fc99e Initial load
duke
parents:
diff changeset
682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685 } while (!_work_list.is_empty());
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // check for non-natural loops (loops where the loop header does not dominate
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // all other loop blocks = loops with mulitple entries).
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // such loops are ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
693 void ComputeLinearScanOrder::clear_non_natural_loops(BlockBegin* start_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 for (int i = _num_loops - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 if (is_block_in_loop(i, start_block)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // loop i contains the entry block of the method
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // -> this is not a natural loop, so ignore it
a61af66fc99e Initial load
duke
parents:
diff changeset
698 TRACE_LINEAR_SCAN(2, tty->print_cr("Loop %d is non-natural, so it is ignored", i));
a61af66fc99e Initial load
duke
parents:
diff changeset
699
a61af66fc99e Initial load
duke
parents:
diff changeset
700 for (int block_id = _max_block_id - 1; block_id >= 0; block_id--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
701 clear_block_in_loop(i, block_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703 _iterative_dominators = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
707
a61af66fc99e Initial load
duke
parents:
diff changeset
708 void ComputeLinearScanOrder::assign_loop_depth(BlockBegin* start_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
709 TRACE_LINEAR_SCAN(3, "----- computing loop-depth and weight");
a61af66fc99e Initial load
duke
parents:
diff changeset
710 init_visited();
a61af66fc99e Initial load
duke
parents:
diff changeset
711
a61af66fc99e Initial load
duke
parents:
diff changeset
712 assert(_work_list.is_empty(), "work list must be empty before processing");
a61af66fc99e Initial load
duke
parents:
diff changeset
713 _work_list.append(start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
714
a61af66fc99e Initial load
duke
parents:
diff changeset
715 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
716 BlockBegin* cur = _work_list.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if (!is_visited(cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
719 set_visited(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
720 TRACE_LINEAR_SCAN(4, tty->print_cr("Computing loop depth for block B%d", cur->block_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
721
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // compute loop-depth and loop-index for the block
a61af66fc99e Initial load
duke
parents:
diff changeset
723 assert(cur->loop_depth() == 0, "cannot set loop-depth twice");
a61af66fc99e Initial load
duke
parents:
diff changeset
724 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
725 int loop_depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
726 int min_loop_idx = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
727 for (i = _num_loops - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 if (is_block_in_loop(i, cur)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
729 loop_depth++;
a61af66fc99e Initial load
duke
parents:
diff changeset
730 min_loop_idx = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733 cur->set_loop_depth(loop_depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 cur->set_loop_index(min_loop_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // append all unvisited successors to work list
a61af66fc99e Initial load
duke
parents:
diff changeset
737 for (i = cur->number_of_sux() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
738 _work_list.append(cur->sux_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740 for (i = cur->number_of_exception_handlers() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
741 _work_list.append(cur->exception_handler_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
744 } while (!_work_list.is_empty());
a61af66fc99e Initial load
duke
parents:
diff changeset
745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
746
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 BlockBegin* ComputeLinearScanOrder::common_dominator(BlockBegin* a, BlockBegin* b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 assert(a != NULL && b != NULL, "must have input blocks");
a61af66fc99e Initial load
duke
parents:
diff changeset
750
a61af66fc99e Initial load
duke
parents:
diff changeset
751 _dominator_blocks.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
752 while (a != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
753 _dominator_blocks.set_bit(a->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
754 assert(a->dominator() != NULL || a == _linear_scan_order->at(0), "dominator must be initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
755 a = a->dominator();
a61af66fc99e Initial load
duke
parents:
diff changeset
756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
757 while (b != NULL && !_dominator_blocks.at(b->block_id())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 assert(b->dominator() != NULL || b == _linear_scan_order->at(0), "dominator must be initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
759 b = b->dominator();
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 assert(b != NULL, "could not find dominator");
a61af66fc99e Initial load
duke
parents:
diff changeset
763 return b;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
765
a61af66fc99e Initial load
duke
parents:
diff changeset
766 void ComputeLinearScanOrder::compute_dominator(BlockBegin* cur, BlockBegin* parent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
767 if (cur->dominator() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
768 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: initializing dominator of B%d to B%d", cur->block_id(), parent->block_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
769 cur->set_dominator(parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 } else if (!(cur->is_set(BlockBegin::linear_scan_loop_header_flag) && parent->is_set(BlockBegin::linear_scan_loop_end_flag))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: computing dominator of B%d: common dominator of B%d and B%d is B%d", cur->block_id(), parent->block_id(), cur->dominator()->block_id(), common_dominator(cur->dominator(), parent)->block_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
773 assert(cur->number_of_preds() > 1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
774 cur->set_dominator(common_dominator(cur->dominator(), parent));
a61af66fc99e Initial load
duke
parents:
diff changeset
775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
777
a61af66fc99e Initial load
duke
parents:
diff changeset
778
a61af66fc99e Initial load
duke
parents:
diff changeset
779 int ComputeLinearScanOrder::compute_weight(BlockBegin* cur) {
a61af66fc99e Initial load
duke
parents:
diff changeset
780 BlockBegin* single_sux = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
781 if (cur->number_of_sux() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 single_sux = cur->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
784
a61af66fc99e Initial load
duke
parents:
diff changeset
785 // limit loop-depth to 15 bit (only for security reason, it will never be so big)
a61af66fc99e Initial load
duke
parents:
diff changeset
786 int weight = (cur->loop_depth() & 0x7FFF) << 16;
a61af66fc99e Initial load
duke
parents:
diff changeset
787
a61af66fc99e Initial load
duke
parents:
diff changeset
788 // general macro for short definition of weight flags
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // the first instance of INC_WEIGHT_IF has the highest priority
a61af66fc99e Initial load
duke
parents:
diff changeset
790 int cur_bit = 15;
a61af66fc99e Initial load
duke
parents:
diff changeset
791 #define INC_WEIGHT_IF(condition) if ((condition)) { weight |= (1 << cur_bit); } cur_bit--;
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 // this is necessery for the (very rare) case that two successing blocks have
a61af66fc99e Initial load
duke
parents:
diff changeset
794 // the same loop depth, but a different loop index (can happen for endless loops
a61af66fc99e Initial load
duke
parents:
diff changeset
795 // with exception handlers)
a61af66fc99e Initial load
duke
parents:
diff changeset
796 INC_WEIGHT_IF(!cur->is_set(BlockBegin::linear_scan_loop_header_flag));
a61af66fc99e Initial load
duke
parents:
diff changeset
797
a61af66fc99e Initial load
duke
parents:
diff changeset
798 // loop end blocks (blocks that end with a backward branch) are added
a61af66fc99e Initial load
duke
parents:
diff changeset
799 // after all other blocks of the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
800 INC_WEIGHT_IF(!cur->is_set(BlockBegin::linear_scan_loop_end_flag));
a61af66fc99e Initial load
duke
parents:
diff changeset
801
a61af66fc99e Initial load
duke
parents:
diff changeset
802 // critical edge split blocks are prefered because than they have a bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // proability to be completely empty
a61af66fc99e Initial load
duke
parents:
diff changeset
804 INC_WEIGHT_IF(cur->is_set(BlockBegin::critical_edge_split_flag));
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // exceptions should not be thrown in normal control flow, so these blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
807 // are added as late as possible
a61af66fc99e Initial load
duke
parents:
diff changeset
808 INC_WEIGHT_IF(cur->end()->as_Throw() == NULL && (single_sux == NULL || single_sux->end()->as_Throw() == NULL));
a61af66fc99e Initial load
duke
parents:
diff changeset
809 INC_WEIGHT_IF(cur->end()->as_Return() == NULL && (single_sux == NULL || single_sux->end()->as_Return() == NULL));
a61af66fc99e Initial load
duke
parents:
diff changeset
810
a61af66fc99e Initial load
duke
parents:
diff changeset
811 // exceptions handlers are added as late as possible
a61af66fc99e Initial load
duke
parents:
diff changeset
812 INC_WEIGHT_IF(!cur->is_set(BlockBegin::exception_entry_flag));
a61af66fc99e Initial load
duke
parents:
diff changeset
813
a61af66fc99e Initial load
duke
parents:
diff changeset
814 // guarantee that weight is > 0
a61af66fc99e Initial load
duke
parents:
diff changeset
815 weight |= 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 #undef INC_WEIGHT_IF
a61af66fc99e Initial load
duke
parents:
diff changeset
818 assert(cur_bit >= 0, "too many flags");
a61af66fc99e Initial load
duke
parents:
diff changeset
819 assert(weight > 0, "weight cannot become negative");
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 return weight;
a61af66fc99e Initial load
duke
parents:
diff changeset
822 }
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 bool ComputeLinearScanOrder::ready_for_processing(BlockBegin* cur) {
a61af66fc99e Initial load
duke
parents:
diff changeset
825 // Discount the edge just traveled.
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // When the number drops to zero, all forward branches were processed
a61af66fc99e Initial load
duke
parents:
diff changeset
827 if (dec_forward_branches(cur) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
828 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 assert(_linear_scan_order->index_of(cur) == -1, "block already processed (block can be ready only once)");
a61af66fc99e Initial load
duke
parents:
diff changeset
832 assert(_work_list.index_of(cur) == -1, "block already in work-list (block can be ready only once)");
a61af66fc99e Initial load
duke
parents:
diff changeset
833 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
834 }
a61af66fc99e Initial load
duke
parents:
diff changeset
835
a61af66fc99e Initial load
duke
parents:
diff changeset
836 void ComputeLinearScanOrder::sort_into_work_list(BlockBegin* cur) {
a61af66fc99e Initial load
duke
parents:
diff changeset
837 assert(_work_list.index_of(cur) == -1, "block already in work list");
a61af66fc99e Initial load
duke
parents:
diff changeset
838
a61af66fc99e Initial load
duke
parents:
diff changeset
839 int cur_weight = compute_weight(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // the linear_scan_number is used to cache the weight of a block
a61af66fc99e Initial load
duke
parents:
diff changeset
842 cur->set_linear_scan_number(cur_weight);
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
845 if (StressLinearScan) {
a61af66fc99e Initial load
duke
parents:
diff changeset
846 _work_list.insert_before(0, cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
847 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
849 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
850
a61af66fc99e Initial load
duke
parents:
diff changeset
851 _work_list.append(NULL); // provide space for new element
a61af66fc99e Initial load
duke
parents:
diff changeset
852
a61af66fc99e Initial load
duke
parents:
diff changeset
853 int insert_idx = _work_list.length() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
854 while (insert_idx > 0 && _work_list.at(insert_idx - 1)->linear_scan_number() > cur_weight) {
a61af66fc99e Initial load
duke
parents:
diff changeset
855 _work_list.at_put(insert_idx, _work_list.at(insert_idx - 1));
a61af66fc99e Initial load
duke
parents:
diff changeset
856 insert_idx--;
a61af66fc99e Initial load
duke
parents:
diff changeset
857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
858 _work_list.at_put(insert_idx, cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
859
a61af66fc99e Initial load
duke
parents:
diff changeset
860 TRACE_LINEAR_SCAN(3, tty->print_cr("Sorted B%d into worklist. new worklist:", cur->block_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
861 TRACE_LINEAR_SCAN(3, for (int i = 0; i < _work_list.length(); i++) tty->print_cr("%8d B%2d weight:%6x", i, _work_list.at(i)->block_id(), _work_list.at(i)->linear_scan_number()));
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
864 for (int i = 0; i < _work_list.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
865 assert(_work_list.at(i)->linear_scan_number() > 0, "weight not set");
a61af66fc99e Initial load
duke
parents:
diff changeset
866 assert(i == 0 || _work_list.at(i - 1)->linear_scan_number() <= _work_list.at(i)->linear_scan_number(), "incorrect order in worklist");
a61af66fc99e Initial load
duke
parents:
diff changeset
867 }
a61af66fc99e Initial load
duke
parents:
diff changeset
868 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
870
a61af66fc99e Initial load
duke
parents:
diff changeset
871 void ComputeLinearScanOrder::append_block(BlockBegin* cur) {
a61af66fc99e Initial load
duke
parents:
diff changeset
872 TRACE_LINEAR_SCAN(3, tty->print_cr("appending block B%d (weight 0x%6x) to linear-scan order", cur->block_id(), cur->linear_scan_number()));
a61af66fc99e Initial load
duke
parents:
diff changeset
873 assert(_linear_scan_order->index_of(cur) == -1, "cannot add the same block twice");
a61af66fc99e Initial load
duke
parents:
diff changeset
874
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // currently, the linear scan order and code emit order are equal.
a61af66fc99e Initial load
duke
parents:
diff changeset
876 // therefore the linear_scan_number and the weight of a block must also
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // be equal.
a61af66fc99e Initial load
duke
parents:
diff changeset
878 cur->set_linear_scan_number(_linear_scan_order->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
879 _linear_scan_order->append(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 void ComputeLinearScanOrder::compute_order(BlockBegin* start_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
883 TRACE_LINEAR_SCAN(3, "----- computing final block order");
a61af66fc99e Initial load
duke
parents:
diff changeset
884
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // the start block is always the first block in the linear scan order
a61af66fc99e Initial load
duke
parents:
diff changeset
886 _linear_scan_order = new BlockList(_num_blocks);
a61af66fc99e Initial load
duke
parents:
diff changeset
887 append_block(start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889 assert(start_block->end()->as_Base() != NULL, "start block must end with Base-instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
890 BlockBegin* std_entry = ((Base*)start_block->end())->std_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
891 BlockBegin* osr_entry = ((Base*)start_block->end())->osr_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
892
a61af66fc99e Initial load
duke
parents:
diff changeset
893 BlockBegin* sux_of_osr_entry = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
894 if (osr_entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // special handling for osr entry:
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // ignore the edge between the osr entry and its successor for processing
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // the osr entry block is added manually below
a61af66fc99e Initial load
duke
parents:
diff changeset
898 assert(osr_entry->number_of_sux() == 1, "osr entry must have exactly one successor");
a61af66fc99e Initial load
duke
parents:
diff changeset
899 assert(osr_entry->sux_at(0)->number_of_preds() >= 2, "sucessor of osr entry must have two predecessors (otherwise it is not present in normal control flow");
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 sux_of_osr_entry = osr_entry->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 dec_forward_branches(sux_of_osr_entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
903
a61af66fc99e Initial load
duke
parents:
diff changeset
904 compute_dominator(osr_entry, start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
905 _iterative_dominators = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
907 compute_dominator(std_entry, start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // start processing with standard entry block
a61af66fc99e Initial load
duke
parents:
diff changeset
910 assert(_work_list.is_empty(), "list must be empty before processing");
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912 if (ready_for_processing(std_entry)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
913 sort_into_work_list(std_entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
914 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
915 assert(false, "the std_entry must be ready for processing (otherwise, the method has no start block)");
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 BlockBegin* cur = _work_list.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
920
a61af66fc99e Initial load
duke
parents:
diff changeset
921 if (cur == sux_of_osr_entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // the osr entry block is ignored in normal processing, it is never added to the
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // work list. Instead, it is added as late as possible manually here.
a61af66fc99e Initial load
duke
parents:
diff changeset
924 append_block(osr_entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
925 compute_dominator(cur, osr_entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
927 append_block(cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
928
a61af66fc99e Initial load
duke
parents:
diff changeset
929 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
930 int num_sux = cur->number_of_sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
931 // changed loop order to get "intuitive" order of if- and else-blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
932 for (i = 0; i < num_sux; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
933 BlockBegin* sux = cur->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
934 compute_dominator(sux, cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
935 if (ready_for_processing(sux)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
936 sort_into_work_list(sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939 num_sux = cur->number_of_exception_handlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
940 for (i = 0; i < num_sux; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
941 BlockBegin* sux = cur->exception_handler_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
942 compute_dominator(sux, cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
943 if (ready_for_processing(sux)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
944 sort_into_work_list(sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
947 } while (_work_list.length() > 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950
a61af66fc99e Initial load
duke
parents:
diff changeset
951 bool ComputeLinearScanOrder::compute_dominators_iter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
952 bool changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
953 int num_blocks = _linear_scan_order->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
954
a61af66fc99e Initial load
duke
parents:
diff changeset
955 assert(_linear_scan_order->at(0)->dominator() == NULL, "must not have dominator");
a61af66fc99e Initial load
duke
parents:
diff changeset
956 assert(_linear_scan_order->at(0)->number_of_preds() == 0, "must not have predecessors");
a61af66fc99e Initial load
duke
parents:
diff changeset
957 for (int i = 1; i < num_blocks; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
958 BlockBegin* block = _linear_scan_order->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
959
a61af66fc99e Initial load
duke
parents:
diff changeset
960 BlockBegin* dominator = block->pred_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
961 int num_preds = block->number_of_preds();
a61af66fc99e Initial load
duke
parents:
diff changeset
962 for (int i = 1; i < num_preds; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
963 dominator = common_dominator(dominator, block->pred_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
965
a61af66fc99e Initial load
duke
parents:
diff changeset
966 if (dominator != block->dominator()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
967 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: updating dominator of B%d from B%d to B%d", block->block_id(), block->dominator()->block_id(), dominator->block_id()));
a61af66fc99e Initial load
duke
parents:
diff changeset
968
a61af66fc99e Initial load
duke
parents:
diff changeset
969 block->set_dominator(dominator);
a61af66fc99e Initial load
duke
parents:
diff changeset
970 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
973 return changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
975
a61af66fc99e Initial load
duke
parents:
diff changeset
976 void ComputeLinearScanOrder::compute_dominators() {
a61af66fc99e Initial load
duke
parents:
diff changeset
977 TRACE_LINEAR_SCAN(3, tty->print_cr("----- computing dominators (iterative computation reqired: %d)", _iterative_dominators));
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // iterative computation of dominators is only required for methods with non-natural loops
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // and OSR-methods. For all other methods, the dominators computed when generating the
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // linear scan block order are correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
982 if (_iterative_dominators) {
a61af66fc99e Initial load
duke
parents:
diff changeset
983 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
984 TRACE_LINEAR_SCAN(1, tty->print_cr("DOM: next iteration of fix-point calculation"));
a61af66fc99e Initial load
duke
parents:
diff changeset
985 } while (compute_dominators_iter());
a61af66fc99e Initial load
duke
parents:
diff changeset
986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // check that dominators are correct
a61af66fc99e Initial load
duke
parents:
diff changeset
989 assert(!compute_dominators_iter(), "fix point not reached");
a61af66fc99e Initial load
duke
parents:
diff changeset
990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
991
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
994 void ComputeLinearScanOrder::print_blocks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
995 if (TraceLinearScanLevel >= 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 tty->print_cr("----- loop information:");
a61af66fc99e Initial load
duke
parents:
diff changeset
997 for (int block_idx = 0; block_idx < _linear_scan_order->length(); block_idx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
998 BlockBegin* cur = _linear_scan_order->at(block_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
999
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 tty->print("%4d: B%2d: ", cur->linear_scan_number(), cur->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 for (int loop_idx = 0; loop_idx < _num_loops; loop_idx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 tty->print ("%d ", is_block_in_loop(loop_idx, cur));
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 tty->print_cr(" -> loop_index: %2d, loop_depth: %2d", cur->loop_index(), cur->loop_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1007
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 if (TraceLinearScanLevel >= 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 tty->print_cr("----- linear-scan block order:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 for (int block_idx = 0; block_idx < _linear_scan_order->length(); block_idx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 BlockBegin* cur = _linear_scan_order->at(block_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 tty->print("%4d: B%2d loop: %2d depth: %2d", cur->linear_scan_number(), cur->block_id(), cur->loop_index(), cur->loop_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
1013
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 tty->print(cur->is_set(BlockBegin::exception_entry_flag) ? " ex" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 tty->print(cur->is_set(BlockBegin::critical_edge_split_flag) ? " ce" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 tty->print(cur->is_set(BlockBegin::linear_scan_loop_header_flag) ? " lh" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 tty->print(cur->is_set(BlockBegin::linear_scan_loop_end_flag) ? " le" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1018
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 if (cur->dominator() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 tty->print(" dom: B%d ", cur->dominator()->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 tty->print(" dom: NULL ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 if (cur->number_of_preds() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 tty->print(" preds: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 for (int j = 0; j < cur->number_of_preds(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 BlockBegin* pred = cur->pred_at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 tty->print("B%d ", pred->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 if (cur->number_of_sux() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 tty->print(" sux: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 for (int j = 0; j < cur->number_of_sux(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 BlockBegin* sux = cur->sux_at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 tty->print("B%d ", sux->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 if (cur->number_of_exception_handlers() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 tty->print(" ex: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 for (int j = 0; j < cur->number_of_exception_handlers(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 BlockBegin* ex = cur->exception_handler_at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 tty->print("B%d ", ex->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1051
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 void ComputeLinearScanOrder::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 assert(_linear_scan_order->length() == _num_blocks, "wrong number of blocks in list");
a61af66fc99e Initial load
duke
parents:
diff changeset
1055
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 if (StressLinearScan) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // blocks are scrambled when StressLinearScan is used
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1060
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // check that all successors of a block have a higher linear-scan-number
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 // and that all predecessors of a block have a lower linear-scan-number
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 // (only backward branches of loops are ignored)
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 for (i = 0; i < _linear_scan_order->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 BlockBegin* cur = _linear_scan_order->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 assert(cur->linear_scan_number() == i, "incorrect linear_scan_number");
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 assert(cur->linear_scan_number() >= 0 && cur->linear_scan_number() == _linear_scan_order->index_of(cur), "incorrect linear_scan_number");
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 int j;
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 for (j = cur->number_of_sux() - 1; j >= 0; j--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 BlockBegin* sux = cur->sux_at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1074
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 assert(sux->linear_scan_number() >= 0 && sux->linear_scan_number() == _linear_scan_order->index_of(sux), "incorrect linear_scan_number");
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 if (!cur->is_set(BlockBegin::linear_scan_loop_end_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 assert(cur->linear_scan_number() < sux->linear_scan_number(), "invalid order");
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 if (cur->loop_depth() == sux->loop_depth()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 assert(cur->loop_index() == sux->loop_index() || sux->is_set(BlockBegin::linear_scan_loop_header_flag), "successing blocks with same loop depth must have same loop index");
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 for (j = cur->number_of_preds() - 1; j >= 0; j--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 BlockBegin* pred = cur->pred_at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1086
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 assert(pred->linear_scan_number() >= 0 && pred->linear_scan_number() == _linear_scan_order->index_of(pred), "incorrect linear_scan_number");
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 if (!cur->is_set(BlockBegin::linear_scan_loop_header_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 assert(cur->linear_scan_number() > pred->linear_scan_number(), "invalid order");
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 if (cur->loop_depth() == pred->loop_depth()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 assert(cur->loop_index() == pred->loop_index() || cur->is_set(BlockBegin::linear_scan_loop_header_flag), "successing blocks with same loop depth must have same loop index");
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1094
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 assert(cur->dominator()->linear_scan_number() <= cur->pred_at(j)->linear_scan_number(), "dominator must be before predecessors");
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 // check dominator
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 if (i == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 assert(cur->dominator() == NULL, "first block has no dominator");
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 assert(cur->dominator() != NULL, "all but first block must have dominator");
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 assert(cur->number_of_preds() != 1 || cur->dominator() == cur->pred_at(0), "Single predecessor must also be dominator");
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1106
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // check that all loops are continuous
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 for (int loop_idx = 0; loop_idx < _num_loops; loop_idx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 int block_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 assert(!is_block_in_loop(loop_idx, _linear_scan_order->at(block_idx)), "the first block must not be present in any loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // skip blocks before the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 while (block_idx < _num_blocks && !is_block_in_loop(loop_idx, _linear_scan_order->at(block_idx))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 block_idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // skip blocks of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 while (block_idx < _num_blocks && is_block_in_loop(loop_idx, _linear_scan_order->at(block_idx))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 block_idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 // after the first non-loop block, there must not be another loop-block
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 while (block_idx < _num_blocks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 assert(!is_block_in_loop(loop_idx, _linear_scan_order->at(block_idx)), "loop not continuous in linear-scan order");
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 block_idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1128
a61af66fc99e Initial load
duke
parents:
diff changeset
1129
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 void IR::compute_code() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 assert(is_valid(), "IR must be valid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1132
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 ComputeLinearScanOrder compute_order(start());
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 _num_loops = compute_order.num_loops();
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 _code = compute_order.linear_scan_order();
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1137
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 void IR::compute_use_counts() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // make sure all values coming out of this block get evaluated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 int num_blocks = _code->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 for (int i = 0; i < num_blocks; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 _code->at(i)->end()->state()->pin_stack_for_linear_scan();
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1145
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // compute use counts
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 UseCountComputer::compute(_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 void IR::iterate_preorder(BlockClosure* closure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 assert(is_valid(), "IR must be valid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 start()->iterate_preorder(closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1155
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 void IR::iterate_postorder(BlockClosure* closure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 assert(is_valid(), "IR must be valid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 start()->iterate_postorder(closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1161
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 void IR::iterate_linear_scan_order(BlockClosure* closure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 linear_scan_order()->iterate_forward(closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1165
a61af66fc99e Initial load
duke
parents:
diff changeset
1166
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 class BlockPrinter: public BlockClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 InstructionPrinter* _ip;
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 bool _cfg_only;
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 bool _live_only;
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 BlockPrinter(InstructionPrinter* ip, bool cfg_only, bool live_only = false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 _ip = ip;
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 _cfg_only = cfg_only;
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 _live_only = live_only;
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1180
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 virtual void block_do(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 if (_cfg_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 _ip->print_instr(block); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 block->print_block(*_ip, _live_only);
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1189
a61af66fc99e Initial load
duke
parents:
diff changeset
1190
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 void IR::print(BlockBegin* start, bool cfg_only, bool live_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 InstructionPrinter ip(!cfg_only);
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 BlockPrinter bp(&ip, cfg_only, live_only);
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 start->iterate_preorder(&bp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1198
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 void IR::print(bool cfg_only, bool live_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 if (is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 print(start(), cfg_only, live_only);
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 tty->print_cr("invalid IR");
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1206
a61af66fc99e Initial load
duke
parents:
diff changeset
1207
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 define_array(BlockListArray, BlockList*)
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 define_stack(BlockListList, BlockListArray)
a61af66fc99e Initial load
duke
parents:
diff changeset
1210
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 class PredecessorValidator : public BlockClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 BlockListList* _predecessors;
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 BlockList* _blocks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 static int cmp(BlockBegin** a, BlockBegin** b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 return (*a)->block_id() - (*b)->block_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1219
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 PredecessorValidator(IR* hir) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 _predecessors = new BlockListList(BlockBegin::number_of_blocks(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 _blocks = new BlockList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1225
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 hir->start()->iterate_preorder(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 if (hir->code() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 assert(hir->code()->length() == _blocks->length(), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 for (i = 0; i < _blocks->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 assert(hir->code()->contains(_blocks->at(i)), "should be in both lists");
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 for (i = 0; i < _blocks->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 BlockBegin* block = _blocks->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 BlockList* preds = _predecessors->at(block->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 if (preds == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 assert(block->number_of_preds() == 0, "should be the same");
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1242
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 // clone the pred list so we can mutate it
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 BlockList* pred_copy = new BlockList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 int j;
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 for (j = 0; j < block->number_of_preds(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 pred_copy->append(block->pred_at(j));
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // sort them in the same order
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 preds->sort(cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 pred_copy->sort(cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 int length = MIN2(preds->length(), block->number_of_preds());
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 for (j = 0; j < block->number_of_preds(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 assert(preds->at(j) == pred_copy->at(j), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1256
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 assert(preds->length() == block->number_of_preds(), "should be the same");
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1260
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 virtual void block_do(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 _blocks->append(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 BlockEnd* be = block->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 int n = be->number_of_sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 for (i = 0; i < n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 BlockBegin* sux = be->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 assert(!sux->is_set(BlockBegin::exception_entry_flag), "must not be xhandler");
a61af66fc99e Initial load
duke
parents:
diff changeset
1269
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 BlockList* preds = _predecessors->at_grow(sux->block_id(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 if (preds == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 preds = new BlockList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 _predecessors->at_put(sux->block_id(), preds);
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 preds->append(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1277
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 n = block->number_of_exception_handlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 for (i = 0; i < n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 BlockBegin* sux = block->exception_handler_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 assert(sux->is_set(BlockBegin::exception_entry_flag), "must be xhandler");
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 BlockList* preds = _predecessors->at_grow(sux->block_id(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 if (preds == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 preds = new BlockList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 _predecessors->at_put(sux->block_id(), preds);
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 preds->append(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 void IR::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 PredecessorValidator pv(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1298
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1300
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1301 void SubstitutionResolver::visit(Value* v) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 Value v0 = *v;
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 if (v0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 Value vs = v0->subst();
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 if (vs != v0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 *v = v0->subst();
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1310
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 #ifdef ASSERT
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1312 class SubstitutionChecker: public ValueVisitor {
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1313 void visit(Value* v) {
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1314 Value v0 = *v;
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1315 if (v0) {
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1316 Value vs = v0->subst();
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1317 assert(vs == v0, "missed substitution");
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1318 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 }
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1320 };
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1322
a61af66fc99e Initial load
duke
parents:
diff changeset
1323
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 void SubstitutionResolver::block_do(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 Instruction* last = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 for (Instruction* n = block; n != NULL;) {
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1327 n->values_do(this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // need to remove this instruction from the instruction stream
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 if (n->subst() != n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 assert(last != NULL, "must have last");
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 last->set_next(n->next(), n->next()->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 last = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 n = last->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1337
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 #ifdef ASSERT
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1339 SubstitutionChecker check_substitute;
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1340 if (block->state()) block->state()->values_do(&check_substitute);
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1341 block->block_values_do(&check_substitute);
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
1342 if (block->end() && block->end()->state()) block->end()->state()->values_do(&check_substitute);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 }