annotate src/share/vm/c1/c1_IR.cpp @ 2007:5ddfcf4b079e

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