annotate src/share/vm/c1/c1_IR.cpp @ 6862:8a5ea0a9ccc4

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