Bug Summary

File:jdk/src/hotspot/share/c1/c1_IR.cpp
Warning:line 904, column 3
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

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