duke@435: /* mikael@6198: * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #include "precompiled.hpp" stefank@2314: #include "c1/c1_Compilation.hpp" stefank@2314: #include "c1/c1_FrameMap.hpp" stefank@2314: #include "c1/c1_GraphBuilder.hpp" stefank@2314: #include "c1/c1_IR.hpp" stefank@2314: #include "c1/c1_InstructionPrinter.hpp" stefank@2314: #include "c1/c1_Optimizer.hpp" stefank@2314: #include "utilities/bitMap.inline.hpp" duke@435: duke@435: duke@435: // Implementation of XHandlers duke@435: // duke@435: // Note: This code could eventually go away if we are duke@435: // just using the ciExceptionHandlerStream. duke@435: duke@435: XHandlers::XHandlers(ciMethod* method) : _list(method->exception_table_length()) { duke@435: ciExceptionHandlerStream s(method); duke@435: while (!s.is_done()) { duke@435: _list.append(new XHandler(s.handler())); duke@435: s.next(); duke@435: } duke@435: assert(s.count() == method->exception_table_length(), "exception table lengths inconsistent"); duke@435: } duke@435: duke@435: // deep copy of all XHandler contained in list duke@435: XHandlers::XHandlers(XHandlers* other) : duke@435: _list(other->length()) duke@435: { duke@435: for (int i = 0; i < other->length(); i++) { duke@435: _list.append(new XHandler(other->handler_at(i))); duke@435: } duke@435: } duke@435: duke@435: // Returns whether a particular exception type can be caught. Also duke@435: // returns true if klass is unloaded or any exception handler duke@435: // classes are unloaded. type_is_exact indicates whether the throw duke@435: // is known to be exactly that class or it might throw a subtype. duke@435: bool XHandlers::could_catch(ciInstanceKlass* klass, bool type_is_exact) const { duke@435: // the type is unknown so be conservative duke@435: if (!klass->is_loaded()) { duke@435: return true; duke@435: } duke@435: duke@435: for (int i = 0; i < length(); i++) { duke@435: XHandler* handler = handler_at(i); duke@435: if (handler->is_catch_all()) { duke@435: // catch of ANY duke@435: return true; duke@435: } duke@435: ciInstanceKlass* handler_klass = handler->catch_klass(); duke@435: // if it's unknown it might be catchable duke@435: if (!handler_klass->is_loaded()) { duke@435: return true; duke@435: } duke@435: // if the throw type is definitely a subtype of the catch type duke@435: // then it can be caught. duke@435: if (klass->is_subtype_of(handler_klass)) { duke@435: return true; duke@435: } duke@435: if (!type_is_exact) { duke@435: // If the type isn't exactly known then it can also be caught by duke@435: // catch statements where the inexact type is a subtype of the duke@435: // catch type. duke@435: // given: foo extends bar extends Exception duke@435: // throw bar can be caught by catch foo, catch bar, and catch duke@435: // Exception, however it can't be caught by any handlers without duke@435: // bar in its type hierarchy. duke@435: if (handler_klass->is_subtype_of(klass)) { duke@435: return true; duke@435: } duke@435: } duke@435: } duke@435: duke@435: return false; duke@435: } duke@435: duke@435: duke@435: bool XHandlers::equals(XHandlers* others) const { duke@435: if (others == NULL) return false; duke@435: if (length() != others->length()) return false; duke@435: duke@435: for (int i = 0; i < length(); i++) { duke@435: if (!handler_at(i)->equals(others->handler_at(i))) return false; duke@435: } duke@435: return true; duke@435: } duke@435: duke@435: bool XHandler::equals(XHandler* other) const { duke@435: assert(entry_pco() != -1 && other->entry_pco() != -1, "must have entry_pco"); duke@435: duke@435: if (entry_pco() != other->entry_pco()) return false; duke@435: if (scope_count() != other->scope_count()) return false; duke@435: if (_desc != other->_desc) return false; duke@435: duke@435: assert(entry_block() == other->entry_block(), "entry_block must be equal when entry_pco is equal"); duke@435: return true; duke@435: } duke@435: duke@435: duke@435: // Implementation of IRScope duke@435: BlockBegin* IRScope::build_graph(Compilation* compilation, int osr_bci) { duke@435: GraphBuilder gm(compilation, this); duke@435: NOT_PRODUCT(if (PrintValueNumbering && Verbose) gm.print_stats()); duke@435: if (compilation->bailed_out()) return NULL; duke@435: return gm.start(); duke@435: } duke@435: duke@435: duke@435: IRScope::IRScope(Compilation* compilation, IRScope* caller, int caller_bci, ciMethod* method, int osr_bci, bool create_graph) duke@435: : _callees(2) duke@435: , _compilation(compilation) duke@435: , _requires_phi_function(method->max_locals()) duke@435: { duke@435: _caller = caller; duke@435: _level = caller == NULL ? 0 : caller->level() + 1; duke@435: _method = method; duke@435: _xhandlers = new XHandlers(method); duke@435: _number_of_locks = 0; duke@435: _monitor_pairing_ok = method->has_balanced_monitors(); jiangli@3592: _wrote_final = false; duke@435: _start = NULL; duke@435: duke@435: if (osr_bci == -1) { duke@435: _requires_phi_function.clear(); duke@435: } else { duke@435: // selective creation of phi functions is not possibel in osr-methods duke@435: _requires_phi_function.set_range(0, method->max_locals()); duke@435: } duke@435: duke@435: assert(method->holder()->is_loaded() , "method holder must be loaded"); duke@435: duke@435: // build graph if monitor pairing is ok duke@435: if (create_graph && monitor_pairing_ok()) _start = build_graph(compilation, osr_bci); duke@435: } duke@435: duke@435: duke@435: int IRScope::max_stack() const { duke@435: int my_max = method()->max_stack(); duke@435: int callee_max = 0; duke@435: for (int i = 0; i < number_of_callees(); i++) { duke@435: callee_max = MAX2(callee_max, callee_no(i)->max_stack()); duke@435: } duke@435: return my_max + callee_max; duke@435: } duke@435: duke@435: cfang@1335: bool IRScopeDebugInfo::should_reexecute() { cfang@1335: ciMethod* cur_method = scope()->method(); cfang@1335: int cur_bci = bci(); cfang@1335: if (cur_method != NULL && cur_bci != SynchronizationEntryBCI) { cfang@1335: Bytecodes::Code code = cur_method->java_code_at_bci(cur_bci); cfang@1335: return Interpreter::bytecode_should_reexecute(code); cfang@1335: } else cfang@1335: return false; cfang@1335: } duke@435: duke@435: duke@435: // Implementation of CodeEmitInfo duke@435: duke@435: // Stack must be NON-null roland@4860: CodeEmitInfo::CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception) duke@435: : _scope(stack->scope()) duke@435: , _scope_debug_info(NULL) duke@435: , _oop_map(NULL) duke@435: , _stack(stack) duke@435: , _exception_handlers(exception_handlers) roland@4860: , _is_method_handle_invoke(false) roland@4860: , _deoptimize_on_exception(deoptimize_on_exception) { duke@435: assert(_stack != NULL, "must be non null"); duke@435: } duke@435: duke@435: roland@2174: CodeEmitInfo::CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack) duke@435: : _scope(info->_scope) duke@435: , _exception_handlers(NULL) duke@435: , _scope_debug_info(NULL) twisti@1919: , _oop_map(NULL) roland@2174: , _stack(stack == NULL ? info->_stack : stack) roland@4860: , _is_method_handle_invoke(info->_is_method_handle_invoke) roland@4860: , _deoptimize_on_exception(info->_deoptimize_on_exception) { duke@435: duke@435: // deep copy of exception handlers duke@435: if (info->_exception_handlers != NULL) { duke@435: _exception_handlers = new XHandlers(info->_exception_handlers); duke@435: } duke@435: } duke@435: duke@435: twisti@1919: void CodeEmitInfo::record_debug_info(DebugInformationRecorder* recorder, int pc_offset) { duke@435: // record the safepoint before recording the debug info for enclosing scopes duke@435: recorder->add_safepoint(pc_offset, _oop_map->deep_copy()); twisti@1919: _scope_debug_info->record_debug_info(recorder, pc_offset, true/*topmost*/, _is_method_handle_invoke); duke@435: recorder->end_safepoint(pc_offset); duke@435: } duke@435: duke@435: duke@435: void CodeEmitInfo::add_register_oop(LIR_Opr opr) { duke@435: assert(_oop_map != NULL, "oop map must already exist"); duke@435: assert(opr->is_single_cpu(), "should not call otherwise"); duke@435: duke@435: VMReg name = frame_map()->regname(opr); duke@435: _oop_map->set_oop(name); duke@435: } duke@435: roland@6723: // Mirror the stack size calculation in the deopt code roland@6723: // How much stack space would we need at this point in the program in roland@6723: // case of deoptimization? roland@6723: int CodeEmitInfo::interpreter_frame_size() const { roland@6723: ValueStack* state = _stack; roland@6723: int size = 0; roland@6723: int callee_parameters = 0; roland@6723: int callee_locals = 0; roland@6723: int extra_args = state->scope()->method()->max_stack() - state->stack_size(); duke@435: roland@6723: while (state != NULL) { roland@6723: int locks = state->locks_size(); roland@6723: int temps = state->stack_size(); roland@6723: bool is_top_frame = (state == _stack); roland@6723: ciMethod* method = state->scope()->method(); duke@435: roland@6723: int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(), roland@6723: temps + callee_parameters, roland@6723: extra_args, roland@6723: locks, roland@6723: callee_parameters, roland@6723: callee_locals, roland@6723: is_top_frame); roland@6723: size += frame_size; roland@6723: roland@6723: callee_parameters = method->size_of_parameters(); roland@6723: callee_locals = method->max_locals(); roland@6723: extra_args = 0; roland@6723: state = state->caller_state(); roland@6723: } roland@6723: return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord; roland@6723: } duke@435: duke@435: // Implementation of IR duke@435: duke@435: IR::IR(Compilation* compilation, ciMethod* method, int osr_bci) : duke@435: _locals_size(in_WordSize(-1)) duke@435: , _num_loops(0) { duke@435: // setup IR fields duke@435: _compilation = compilation; duke@435: _top_scope = new IRScope(compilation, NULL, -1, method, osr_bci, true); duke@435: _code = NULL; duke@435: } duke@435: duke@435: roland@4860: void IR::optimize_blocks() { duke@435: Optimizer opt(this); iveresov@2138: if (!compilation()->profile_branches()) { iveresov@2138: if (DoCEE) { iveresov@2138: opt.eliminate_conditional_expressions(); duke@435: #ifndef PRODUCT iveresov@2138: if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after CEE"); print(true); } iveresov@2138: if (PrintIR || PrintIR1 ) { tty->print_cr("IR after CEE"); print(false); } duke@435: #endif iveresov@2138: } iveresov@2138: if (EliminateBlocks) { iveresov@2138: opt.eliminate_blocks(); duke@435: #ifndef PRODUCT iveresov@2138: if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after block elimination"); print(true); } iveresov@2138: if (PrintIR || PrintIR1 ) { tty->print_cr("IR after block elimination"); print(false); } duke@435: #endif iveresov@2138: } duke@435: } roland@4860: } roland@4860: roland@4860: void IR::eliminate_null_checks() { roland@4860: Optimizer opt(this); duke@435: if (EliminateNullChecks) { duke@435: opt.eliminate_null_checks(); duke@435: #ifndef PRODUCT duke@435: if (PrintCFG || PrintCFG1) { tty->print_cr("CFG after null check elimination"); print(true); } duke@435: if (PrintIR || PrintIR1 ) { tty->print_cr("IR after null check elimination"); print(false); } duke@435: #endif duke@435: } duke@435: } duke@435: duke@435: duke@435: static int sort_pairs(BlockPair** a, BlockPair** b) { duke@435: if ((*a)->from() == (*b)->from()) { duke@435: return (*a)->to()->block_id() - (*b)->to()->block_id(); duke@435: } else { duke@435: return (*a)->from()->block_id() - (*b)->from()->block_id(); duke@435: } duke@435: } duke@435: duke@435: duke@435: class CriticalEdgeFinder: public BlockClosure { duke@435: BlockPairList blocks; duke@435: IR* _ir; duke@435: duke@435: public: duke@435: CriticalEdgeFinder(IR* ir): _ir(ir) {} duke@435: void block_do(BlockBegin* bb) { duke@435: BlockEnd* be = bb->end(); duke@435: int nos = be->number_of_sux(); duke@435: if (nos >= 2) { duke@435: for (int i = 0; i < nos; i++) { duke@435: BlockBegin* sux = be->sux_at(i); duke@435: if (sux->number_of_preds() >= 2) { duke@435: blocks.append(new BlockPair(bb, sux)); duke@435: } duke@435: } duke@435: } duke@435: } duke@435: duke@435: void split_edges() { duke@435: BlockPair* last_pair = NULL; duke@435: blocks.sort(sort_pairs); duke@435: for (int i = 0; i < blocks.length(); i++) { duke@435: BlockPair* pair = blocks.at(i); duke@435: if (last_pair != NULL && pair->is_same(last_pair)) continue; duke@435: BlockBegin* from = pair->from(); duke@435: BlockBegin* to = pair->to(); duke@435: BlockBegin* split = from->insert_block_between(to); duke@435: #ifndef PRODUCT duke@435: if ((PrintIR || PrintIR1) && Verbose) { duke@435: tty->print_cr("Split critical edge B%d -> B%d (new block B%d)", duke@435: from->block_id(), to->block_id(), split->block_id()); duke@435: } duke@435: #endif duke@435: last_pair = pair; duke@435: } duke@435: } duke@435: }; duke@435: duke@435: void IR::split_critical_edges() { duke@435: CriticalEdgeFinder cef(this); duke@435: duke@435: iterate_preorder(&cef); duke@435: cef.split_edges(); duke@435: } duke@435: duke@435: iveresov@1939: class UseCountComputer: public ValueVisitor, BlockClosure { duke@435: private: iveresov@1939: void visit(Value* n) { duke@435: // Local instructions and Phis for expression stack values at the duke@435: // start of basic blocks are not added to the instruction list roland@2254: if (!(*n)->is_linked() && (*n)->can_be_linked()) { duke@435: assert(false, "a node was not appended to the graph"); iveresov@1939: Compilation::current()->bailout("a node was not appended to the graph"); duke@435: } duke@435: // use n's input if not visited before duke@435: if (!(*n)->is_pinned() && !(*n)->has_uses()) { duke@435: // note: a) if the instruction is pinned, it will be handled by compute_use_count duke@435: // b) if the instruction has uses, it was touched before duke@435: // => in both cases we don't need to update n's values duke@435: uses_do(n); duke@435: } duke@435: // use n duke@435: (*n)->_use_count++; duke@435: } duke@435: iveresov@1939: Values* worklist; iveresov@1939: int depth; duke@435: enum { duke@435: max_recurse_depth = 20 duke@435: }; duke@435: iveresov@1939: void uses_do(Value* n) { duke@435: depth++; duke@435: if (depth > max_recurse_depth) { duke@435: // don't allow the traversal to recurse too deeply duke@435: worklist->push(*n); duke@435: } else { iveresov@1939: (*n)->input_values_do(this); duke@435: // special handling for some instructions duke@435: if ((*n)->as_BlockEnd() != NULL) { duke@435: // note on BlockEnd: duke@435: // must 'use' the stack only if the method doesn't duke@435: // terminate, however, in those cases stack is empty iveresov@1939: (*n)->state_values_do(this); duke@435: } duke@435: } duke@435: depth--; duke@435: } duke@435: iveresov@1939: void block_do(BlockBegin* b) { duke@435: depth = 0; duke@435: // process all pinned nodes as the roots of expression trees duke@435: for (Instruction* n = b; n != NULL; n = n->next()) { duke@435: if (n->is_pinned()) uses_do(&n); duke@435: } duke@435: assert(depth == 0, "should have counted back down"); duke@435: duke@435: // now process any unpinned nodes which recursed too deeply duke@435: while (worklist->length() > 0) { duke@435: Value t = worklist->pop(); duke@435: if (!t->is_pinned()) { duke@435: // compute the use count duke@435: uses_do(&t); duke@435: duke@435: // pin the instruction so that LIRGenerator doesn't recurse duke@435: // too deeply during it's evaluation. duke@435: t->pin(); duke@435: } duke@435: } duke@435: assert(depth == 0, "should have counted back down"); duke@435: } duke@435: iveresov@1939: UseCountComputer() { iveresov@1939: worklist = new Values(); iveresov@1939: depth = 0; iveresov@1939: } iveresov@1939: duke@435: public: duke@435: static void compute(BlockList* blocks) { iveresov@1939: UseCountComputer ucc; iveresov@1939: blocks->iterate_backward(&ucc); duke@435: } duke@435: }; duke@435: duke@435: duke@435: // helper macro for short definition of trace-output inside code duke@435: #ifndef PRODUCT duke@435: #define TRACE_LINEAR_SCAN(level, code) \ duke@435: if (TraceLinearScanLevel >= level) { \ duke@435: code; \ duke@435: } duke@435: #else duke@435: #define TRACE_LINEAR_SCAN(level, code) duke@435: #endif duke@435: duke@435: class ComputeLinearScanOrder : public StackObj { duke@435: private: duke@435: int _max_block_id; // the highest block_id of a block duke@435: int _num_blocks; // total number of blocks (smaller than _max_block_id) duke@435: int _num_loops; // total number of loops duke@435: bool _iterative_dominators;// method requires iterative computation of dominatiors duke@435: duke@435: BlockList* _linear_scan_order; // the resulting list of blocks in correct order duke@435: duke@435: BitMap _visited_blocks; // used for recursive processing of blocks duke@435: BitMap _active_blocks; // used for recursive processing of blocks duke@435: BitMap _dominator_blocks; // temproary BitMap used for computation of dominator duke@435: intArray _forward_branches; // number of incoming forward branches for each block duke@435: BlockList _loop_end_blocks; // list of all loop end blocks collected during count_edges duke@435: BitMap2D _loop_map; // two-dimensional bit set: a bit is set if a block is contained in a loop duke@435: BlockList _work_list; // temporary list (used in mark_loops and compute_order) roland@4860: BlockList _loop_headers; duke@435: iveresov@2138: Compilation* _compilation; iveresov@2138: duke@435: // accessors for _visited_blocks and _active_blocks duke@435: void init_visited() { _active_blocks.clear(); _visited_blocks.clear(); } duke@435: bool is_visited(BlockBegin* b) const { return _visited_blocks.at(b->block_id()); } duke@435: bool is_active(BlockBegin* b) const { return _active_blocks.at(b->block_id()); } duke@435: void set_visited(BlockBegin* b) { assert(!is_visited(b), "already set"); _visited_blocks.set_bit(b->block_id()); } duke@435: void set_active(BlockBegin* b) { assert(!is_active(b), "already set"); _active_blocks.set_bit(b->block_id()); } duke@435: void clear_active(BlockBegin* b) { assert(is_active(b), "not already"); _active_blocks.clear_bit(b->block_id()); } duke@435: duke@435: // accessors for _forward_branches duke@435: void inc_forward_branches(BlockBegin* b) { _forward_branches.at_put(b->block_id(), _forward_branches.at(b->block_id()) + 1); } duke@435: 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()); } duke@435: duke@435: // accessors for _loop_map duke@435: bool is_block_in_loop (int loop_idx, BlockBegin* b) const { return _loop_map.at(loop_idx, b->block_id()); } duke@435: void set_block_in_loop (int loop_idx, BlockBegin* b) { _loop_map.set_bit(loop_idx, b->block_id()); } duke@435: void clear_block_in_loop(int loop_idx, int block_id) { _loop_map.clear_bit(loop_idx, block_id); } duke@435: duke@435: // count edges between blocks duke@435: void count_edges(BlockBegin* cur, BlockBegin* parent); duke@435: duke@435: // loop detection duke@435: void mark_loops(); duke@435: void clear_non_natural_loops(BlockBegin* start_block); duke@435: void assign_loop_depth(BlockBegin* start_block); duke@435: duke@435: // computation of final block order duke@435: BlockBegin* common_dominator(BlockBegin* a, BlockBegin* b); duke@435: void compute_dominator(BlockBegin* cur, BlockBegin* parent); duke@435: int compute_weight(BlockBegin* cur); duke@435: bool ready_for_processing(BlockBegin* cur); duke@435: void sort_into_work_list(BlockBegin* b); duke@435: void append_block(BlockBegin* cur); duke@435: void compute_order(BlockBegin* start_block); duke@435: duke@435: // fixup of dominators for non-natural loops duke@435: bool compute_dominators_iter(); duke@435: void compute_dominators(); duke@435: duke@435: // debug functions duke@435: NOT_PRODUCT(void print_blocks();) duke@435: DEBUG_ONLY(void verify();) duke@435: iveresov@2138: Compilation* compilation() const { return _compilation; } duke@435: public: iveresov@2138: ComputeLinearScanOrder(Compilation* c, BlockBegin* start_block); duke@435: duke@435: // accessors for final result duke@435: BlockList* linear_scan_order() const { return _linear_scan_order; } duke@435: int num_loops() const { return _num_loops; } duke@435: }; duke@435: duke@435: iveresov@2138: ComputeLinearScanOrder::ComputeLinearScanOrder(Compilation* c, BlockBegin* start_block) : duke@435: _max_block_id(BlockBegin::number_of_blocks()), duke@435: _num_blocks(0), duke@435: _num_loops(0), duke@435: _iterative_dominators(false), duke@435: _visited_blocks(_max_block_id), duke@435: _active_blocks(_max_block_id), duke@435: _dominator_blocks(_max_block_id), duke@435: _forward_branches(_max_block_id, 0), duke@435: _loop_end_blocks(8), duke@435: _work_list(8), duke@435: _linear_scan_order(NULL), // initialized later with correct size iveresov@2138: _loop_map(0, 0), // initialized later with correct size iveresov@2138: _compilation(c) duke@435: { ccheung@5259: TRACE_LINEAR_SCAN(2, tty->print_cr("***** computing linear-scan block order")); duke@435: duke@435: init_visited(); duke@435: count_edges(start_block, NULL); duke@435: iveresov@2138: if (compilation()->is_profiling()) { iveresov@2349: ciMethod *method = compilation()->method(); iveresov@2349: if (!method->is_accessor()) { iveresov@2349: ciMethodData* md = method->method_data_or_null(); iveresov@2349: assert(md != NULL, "Sanity"); iveresov@2349: md->set_compilation_stats(_num_loops, _num_blocks); iveresov@2349: } iveresov@2138: } iveresov@2138: duke@435: if (_num_loops > 0) { duke@435: mark_loops(); duke@435: clear_non_natural_loops(start_block); duke@435: assign_loop_depth(start_block); duke@435: } duke@435: duke@435: compute_order(start_block); duke@435: compute_dominators(); duke@435: duke@435: NOT_PRODUCT(print_blocks()); duke@435: DEBUG_ONLY(verify()); duke@435: } duke@435: duke@435: duke@435: // Traverse the CFG: duke@435: // * count total number of blocks duke@435: // * count all incoming edges and backward incoming edges duke@435: // * number loop header blocks duke@435: // * create a list with all loop end blocks duke@435: void ComputeLinearScanOrder::count_edges(BlockBegin* cur, BlockBegin* parent) { duke@435: 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)); duke@435: assert(cur->dominator() == NULL, "dominator already initialized"); duke@435: duke@435: if (is_active(cur)) { duke@435: TRACE_LINEAR_SCAN(3, tty->print_cr("backward branch")); duke@435: assert(is_visited(cur), "block must be visisted when block is active"); duke@435: assert(parent != NULL, "must have parent"); duke@435: duke@435: cur->set(BlockBegin::linear_scan_loop_header_flag); duke@435: cur->set(BlockBegin::backward_branch_target_flag); duke@435: duke@435: parent->set(BlockBegin::linear_scan_loop_end_flag); never@863: never@863: // When a loop header is also the start of an exception handler, then the backward branch is never@863: // an exception edge. Because such edges are usually critical edges which cannot be split, the never@863: // loop must be excluded here from processing. never@863: if (cur->is_set(BlockBegin::exception_entry_flag)) { never@863: // Make sure that dominators are correct in this weird situation never@863: _iterative_dominators = true; never@863: return; never@863: } never@863: assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur, never@863: "loop end blocks must have one successor (critical edges are split)"); never@863: duke@435: _loop_end_blocks.append(parent); duke@435: return; duke@435: } duke@435: duke@435: // increment number of incoming forward branches duke@435: inc_forward_branches(cur); duke@435: duke@435: if (is_visited(cur)) { duke@435: TRACE_LINEAR_SCAN(3, tty->print_cr("block already visited")); duke@435: return; duke@435: } duke@435: duke@435: _num_blocks++; duke@435: set_visited(cur); duke@435: set_active(cur); duke@435: duke@435: // recursive call for all successors duke@435: int i; duke@435: for (i = cur->number_of_sux() - 1; i >= 0; i--) { duke@435: count_edges(cur->sux_at(i), cur); duke@435: } duke@435: for (i = cur->number_of_exception_handlers() - 1; i >= 0; i--) { duke@435: count_edges(cur->exception_handler_at(i), cur); duke@435: } duke@435: duke@435: clear_active(cur); duke@435: duke@435: // Each loop has a unique number. duke@435: // When multiple loops are nested, assign_loop_depth assumes that the duke@435: // innermost loop has the lowest number. This is guaranteed by setting duke@435: // the loop number after the recursive calls for the successors above duke@435: // have returned. duke@435: if (cur->is_set(BlockBegin::linear_scan_loop_header_flag)) { duke@435: assert(cur->loop_index() == -1, "cannot set loop-index twice"); duke@435: TRACE_LINEAR_SCAN(3, tty->print_cr("Block B%d is loop header of loop %d", cur->block_id(), _num_loops)); duke@435: duke@435: cur->set_loop_index(_num_loops); roland@4860: _loop_headers.append(cur); duke@435: _num_loops++; duke@435: } duke@435: duke@435: TRACE_LINEAR_SCAN(3, tty->print_cr("Finished count_edges for block B%d", cur->block_id())); duke@435: } duke@435: duke@435: duke@435: void ComputeLinearScanOrder::mark_loops() { duke@435: TRACE_LINEAR_SCAN(3, tty->print_cr("----- marking loops")); duke@435: duke@435: _loop_map = BitMap2D(_num_loops, _max_block_id); duke@435: _loop_map.clear(); duke@435: duke@435: for (int i = _loop_end_blocks.length() - 1; i >= 0; i--) { duke@435: BlockBegin* loop_end = _loop_end_blocks.at(i); duke@435: BlockBegin* loop_start = loop_end->sux_at(0); duke@435: int loop_idx = loop_start->loop_index(); duke@435: duke@435: 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)); duke@435: assert(loop_end->is_set(BlockBegin::linear_scan_loop_end_flag), "loop end flag must be set"); duke@435: assert(loop_end->number_of_sux() == 1, "incorrect number of successors"); duke@435: assert(loop_start->is_set(BlockBegin::linear_scan_loop_header_flag), "loop header flag must be set"); duke@435: assert(loop_idx >= 0 && loop_idx < _num_loops, "loop index not set"); duke@435: assert(_work_list.is_empty(), "work list must be empty before processing"); duke@435: duke@435: // add the end-block of the loop to the working list duke@435: _work_list.push(loop_end); duke@435: set_block_in_loop(loop_idx, loop_end); duke@435: do { duke@435: BlockBegin* cur = _work_list.pop(); duke@435: duke@435: TRACE_LINEAR_SCAN(3, tty->print_cr(" processing B%d", cur->block_id())); duke@435: assert(is_block_in_loop(loop_idx, cur), "bit in loop map must be set when block is in work list"); duke@435: duke@435: // recursive processing of all predecessors ends when start block of loop is reached duke@435: if (cur != loop_start && !cur->is_set(BlockBegin::osr_entry_flag)) { duke@435: for (int j = cur->number_of_preds() - 1; j >= 0; j--) { duke@435: BlockBegin* pred = cur->pred_at(j); duke@435: duke@435: if (!is_block_in_loop(loop_idx, pred) /*&& !pred->is_set(BlockBeginosr_entry_flag)*/) { duke@435: // this predecessor has not been processed yet, so add it to work list duke@435: TRACE_LINEAR_SCAN(3, tty->print_cr(" pushing B%d", pred->block_id())); duke@435: _work_list.push(pred); duke@435: set_block_in_loop(loop_idx, pred); duke@435: } duke@435: } duke@435: } duke@435: } while (!_work_list.is_empty()); duke@435: } duke@435: } duke@435: duke@435: duke@435: // check for non-natural loops (loops where the loop header does not dominate duke@435: // all other loop blocks = loops with mulitple entries). duke@435: // such loops are ignored duke@435: void ComputeLinearScanOrder::clear_non_natural_loops(BlockBegin* start_block) { duke@435: for (int i = _num_loops - 1; i >= 0; i--) { duke@435: if (is_block_in_loop(i, start_block)) { duke@435: // loop i contains the entry block of the method duke@435: // -> this is not a natural loop, so ignore it duke@435: TRACE_LINEAR_SCAN(2, tty->print_cr("Loop %d is non-natural, so it is ignored", i)); duke@435: roland@4860: BlockBegin *loop_header = _loop_headers.at(i); roland@4860: assert(loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Must be loop header"); roland@4860: roland@4860: for (int j = 0; j < loop_header->number_of_preds(); j++) { roland@4860: BlockBegin *pred = loop_header->pred_at(j); roland@4860: pred->clear(BlockBegin::linear_scan_loop_end_flag); roland@4860: } roland@4860: roland@4860: loop_header->clear(BlockBegin::linear_scan_loop_header_flag); roland@4860: duke@435: for (int block_id = _max_block_id - 1; block_id >= 0; block_id--) { duke@435: clear_block_in_loop(i, block_id); duke@435: } duke@435: _iterative_dominators = true; duke@435: } duke@435: } duke@435: } duke@435: duke@435: void ComputeLinearScanOrder::assign_loop_depth(BlockBegin* start_block) { ccheung@5259: TRACE_LINEAR_SCAN(3, tty->print_cr("----- computing loop-depth and weight")); duke@435: init_visited(); duke@435: duke@435: assert(_work_list.is_empty(), "work list must be empty before processing"); duke@435: _work_list.append(start_block); duke@435: duke@435: do { duke@435: BlockBegin* cur = _work_list.pop(); duke@435: duke@435: if (!is_visited(cur)) { duke@435: set_visited(cur); duke@435: TRACE_LINEAR_SCAN(4, tty->print_cr("Computing loop depth for block B%d", cur->block_id())); duke@435: duke@435: // compute loop-depth and loop-index for the block duke@435: assert(cur->loop_depth() == 0, "cannot set loop-depth twice"); duke@435: int i; duke@435: int loop_depth = 0; duke@435: int min_loop_idx = -1; duke@435: for (i = _num_loops - 1; i >= 0; i--) { duke@435: if (is_block_in_loop(i, cur)) { duke@435: loop_depth++; duke@435: min_loop_idx = i; duke@435: } duke@435: } duke@435: cur->set_loop_depth(loop_depth); duke@435: cur->set_loop_index(min_loop_idx); duke@435: duke@435: // append all unvisited successors to work list duke@435: for (i = cur->number_of_sux() - 1; i >= 0; i--) { duke@435: _work_list.append(cur->sux_at(i)); duke@435: } duke@435: for (i = cur->number_of_exception_handlers() - 1; i >= 0; i--) { duke@435: _work_list.append(cur->exception_handler_at(i)); duke@435: } duke@435: } duke@435: } while (!_work_list.is_empty()); duke@435: } duke@435: duke@435: duke@435: BlockBegin* ComputeLinearScanOrder::common_dominator(BlockBegin* a, BlockBegin* b) { duke@435: assert(a != NULL && b != NULL, "must have input blocks"); duke@435: duke@435: _dominator_blocks.clear(); duke@435: while (a != NULL) { duke@435: _dominator_blocks.set_bit(a->block_id()); duke@435: assert(a->dominator() != NULL || a == _linear_scan_order->at(0), "dominator must be initialized"); duke@435: a = a->dominator(); duke@435: } duke@435: while (b != NULL && !_dominator_blocks.at(b->block_id())) { duke@435: assert(b->dominator() != NULL || b == _linear_scan_order->at(0), "dominator must be initialized"); duke@435: b = b->dominator(); duke@435: } duke@435: duke@435: assert(b != NULL, "could not find dominator"); duke@435: return b; duke@435: } duke@435: duke@435: void ComputeLinearScanOrder::compute_dominator(BlockBegin* cur, BlockBegin* parent) { duke@435: if (cur->dominator() == NULL) { duke@435: TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: initializing dominator of B%d to B%d", cur->block_id(), parent->block_id())); duke@435: cur->set_dominator(parent); duke@435: duke@435: } else if (!(cur->is_set(BlockBegin::linear_scan_loop_header_flag) && parent->is_set(BlockBegin::linear_scan_loop_end_flag))) { duke@435: 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())); roland@4860: // Does not hold for exception blocks roland@4860: assert(cur->number_of_preds() > 1 || cur->is_set(BlockBegin::exception_entry_flag), ""); duke@435: cur->set_dominator(common_dominator(cur->dominator(), parent)); duke@435: } roland@4860: roland@4860: // Additional edge to xhandler of all our successors roland@4860: // range check elimination needs that the state at the end of a roland@4860: // block be valid in every block it dominates so cur must dominate roland@4860: // the exception handlers of its successors. roland@4860: int num_cur_xhandler = cur->number_of_exception_handlers(); roland@4860: for (int j = 0; j < num_cur_xhandler; j++) { roland@4860: BlockBegin* xhandler = cur->exception_handler_at(j); roland@4860: compute_dominator(xhandler, parent); roland@4860: } duke@435: } duke@435: duke@435: duke@435: int ComputeLinearScanOrder::compute_weight(BlockBegin* cur) { duke@435: BlockBegin* single_sux = NULL; duke@435: if (cur->number_of_sux() == 1) { duke@435: single_sux = cur->sux_at(0); duke@435: } duke@435: duke@435: // limit loop-depth to 15 bit (only for security reason, it will never be so big) duke@435: int weight = (cur->loop_depth() & 0x7FFF) << 16; duke@435: duke@435: // general macro for short definition of weight flags duke@435: // the first instance of INC_WEIGHT_IF has the highest priority duke@435: int cur_bit = 15; duke@435: #define INC_WEIGHT_IF(condition) if ((condition)) { weight |= (1 << cur_bit); } cur_bit--; duke@435: duke@435: // this is necessery for the (very rare) case that two successing blocks have duke@435: // the same loop depth, but a different loop index (can happen for endless loops duke@435: // with exception handlers) duke@435: INC_WEIGHT_IF(!cur->is_set(BlockBegin::linear_scan_loop_header_flag)); duke@435: duke@435: // loop end blocks (blocks that end with a backward branch) are added duke@435: // after all other blocks of the loop. duke@435: INC_WEIGHT_IF(!cur->is_set(BlockBegin::linear_scan_loop_end_flag)); duke@435: duke@435: // critical edge split blocks are prefered because than they have a bigger duke@435: // proability to be completely empty duke@435: INC_WEIGHT_IF(cur->is_set(BlockBegin::critical_edge_split_flag)); duke@435: duke@435: // exceptions should not be thrown in normal control flow, so these blocks duke@435: // are added as late as possible duke@435: INC_WEIGHT_IF(cur->end()->as_Throw() == NULL && (single_sux == NULL || single_sux->end()->as_Throw() == NULL)); duke@435: INC_WEIGHT_IF(cur->end()->as_Return() == NULL && (single_sux == NULL || single_sux->end()->as_Return() == NULL)); duke@435: duke@435: // exceptions handlers are added as late as possible duke@435: INC_WEIGHT_IF(!cur->is_set(BlockBegin::exception_entry_flag)); duke@435: duke@435: // guarantee that weight is > 0 duke@435: weight |= 1; duke@435: duke@435: #undef INC_WEIGHT_IF duke@435: assert(cur_bit >= 0, "too many flags"); duke@435: assert(weight > 0, "weight cannot become negative"); duke@435: duke@435: return weight; duke@435: } duke@435: duke@435: bool ComputeLinearScanOrder::ready_for_processing(BlockBegin* cur) { duke@435: // Discount the edge just traveled. duke@435: // When the number drops to zero, all forward branches were processed duke@435: if (dec_forward_branches(cur) != 0) { duke@435: return false; duke@435: } duke@435: duke@435: assert(_linear_scan_order->index_of(cur) == -1, "block already processed (block can be ready only once)"); duke@435: assert(_work_list.index_of(cur) == -1, "block already in work-list (block can be ready only once)"); duke@435: return true; duke@435: } duke@435: duke@435: void ComputeLinearScanOrder::sort_into_work_list(BlockBegin* cur) { duke@435: assert(_work_list.index_of(cur) == -1, "block already in work list"); duke@435: duke@435: int cur_weight = compute_weight(cur); duke@435: duke@435: // the linear_scan_number is used to cache the weight of a block duke@435: cur->set_linear_scan_number(cur_weight); duke@435: duke@435: #ifndef PRODUCT duke@435: if (StressLinearScan) { duke@435: _work_list.insert_before(0, cur); duke@435: return; duke@435: } duke@435: #endif duke@435: duke@435: _work_list.append(NULL); // provide space for new element duke@435: duke@435: int insert_idx = _work_list.length() - 1; duke@435: while (insert_idx > 0 && _work_list.at(insert_idx - 1)->linear_scan_number() > cur_weight) { duke@435: _work_list.at_put(insert_idx, _work_list.at(insert_idx - 1)); duke@435: insert_idx--; duke@435: } duke@435: _work_list.at_put(insert_idx, cur); duke@435: duke@435: TRACE_LINEAR_SCAN(3, tty->print_cr("Sorted B%d into worklist. new worklist:", cur->block_id())); duke@435: 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())); duke@435: duke@435: #ifdef ASSERT duke@435: for (int i = 0; i < _work_list.length(); i++) { duke@435: assert(_work_list.at(i)->linear_scan_number() > 0, "weight not set"); duke@435: assert(i == 0 || _work_list.at(i - 1)->linear_scan_number() <= _work_list.at(i)->linear_scan_number(), "incorrect order in worklist"); duke@435: } duke@435: #endif duke@435: } duke@435: duke@435: void ComputeLinearScanOrder::append_block(BlockBegin* cur) { duke@435: 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())); duke@435: assert(_linear_scan_order->index_of(cur) == -1, "cannot add the same block twice"); duke@435: duke@435: // currently, the linear scan order and code emit order are equal. duke@435: // therefore the linear_scan_number and the weight of a block must also duke@435: // be equal. duke@435: cur->set_linear_scan_number(_linear_scan_order->length()); duke@435: _linear_scan_order->append(cur); duke@435: } duke@435: duke@435: void ComputeLinearScanOrder::compute_order(BlockBegin* start_block) { ccheung@5259: TRACE_LINEAR_SCAN(3, tty->print_cr("----- computing final block order")); duke@435: duke@435: // the start block is always the first block in the linear scan order duke@435: _linear_scan_order = new BlockList(_num_blocks); duke@435: append_block(start_block); duke@435: duke@435: assert(start_block->end()->as_Base() != NULL, "start block must end with Base-instruction"); duke@435: BlockBegin* std_entry = ((Base*)start_block->end())->std_entry(); duke@435: BlockBegin* osr_entry = ((Base*)start_block->end())->osr_entry(); duke@435: duke@435: BlockBegin* sux_of_osr_entry = NULL; duke@435: if (osr_entry != NULL) { duke@435: // special handling for osr entry: duke@435: // ignore the edge between the osr entry and its successor for processing duke@435: // the osr entry block is added manually below duke@435: assert(osr_entry->number_of_sux() == 1, "osr entry must have exactly one successor"); duke@435: 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"); duke@435: duke@435: sux_of_osr_entry = osr_entry->sux_at(0); duke@435: dec_forward_branches(sux_of_osr_entry); duke@435: duke@435: compute_dominator(osr_entry, start_block); duke@435: _iterative_dominators = true; duke@435: } duke@435: compute_dominator(std_entry, start_block); duke@435: duke@435: // start processing with standard entry block duke@435: assert(_work_list.is_empty(), "list must be empty before processing"); duke@435: duke@435: if (ready_for_processing(std_entry)) { duke@435: sort_into_work_list(std_entry); duke@435: } else { duke@435: assert(false, "the std_entry must be ready for processing (otherwise, the method has no start block)"); duke@435: } duke@435: duke@435: do { duke@435: BlockBegin* cur = _work_list.pop(); duke@435: duke@435: if (cur == sux_of_osr_entry) { duke@435: // the osr entry block is ignored in normal processing, it is never added to the duke@435: // work list. Instead, it is added as late as possible manually here. duke@435: append_block(osr_entry); duke@435: compute_dominator(cur, osr_entry); duke@435: } duke@435: append_block(cur); duke@435: duke@435: int i; duke@435: int num_sux = cur->number_of_sux(); duke@435: // changed loop order to get "intuitive" order of if- and else-blocks duke@435: for (i = 0; i < num_sux; i++) { duke@435: BlockBegin* sux = cur->sux_at(i); duke@435: compute_dominator(sux, cur); duke@435: if (ready_for_processing(sux)) { duke@435: sort_into_work_list(sux); duke@435: } duke@435: } duke@435: num_sux = cur->number_of_exception_handlers(); duke@435: for (i = 0; i < num_sux; i++) { duke@435: BlockBegin* sux = cur->exception_handler_at(i); duke@435: if (ready_for_processing(sux)) { duke@435: sort_into_work_list(sux); duke@435: } duke@435: } duke@435: } while (_work_list.length() > 0); duke@435: } duke@435: duke@435: duke@435: bool ComputeLinearScanOrder::compute_dominators_iter() { duke@435: bool changed = false; duke@435: int num_blocks = _linear_scan_order->length(); duke@435: duke@435: assert(_linear_scan_order->at(0)->dominator() == NULL, "must not have dominator"); duke@435: assert(_linear_scan_order->at(0)->number_of_preds() == 0, "must not have predecessors"); duke@435: for (int i = 1; i < num_blocks; i++) { duke@435: BlockBegin* block = _linear_scan_order->at(i); duke@435: duke@435: BlockBegin* dominator = block->pred_at(0); duke@435: int num_preds = block->number_of_preds(); roland@4860: roland@4860: TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: Processing B%d", block->block_id())); roland@4860: roland@4860: for (int j = 0; j < num_preds; j++) { roland@4860: roland@4860: BlockBegin *pred = block->pred_at(j); roland@4860: TRACE_LINEAR_SCAN(4, tty->print_cr(" DOM: Subrocessing B%d", pred->block_id())); roland@4860: roland@4860: if (block->is_set(BlockBegin::exception_entry_flag)) { roland@4860: dominator = common_dominator(dominator, pred); roland@4860: int num_pred_preds = pred->number_of_preds(); roland@4860: for (int k = 0; k < num_pred_preds; k++) { roland@4860: dominator = common_dominator(dominator, pred->pred_at(k)); roland@4860: } roland@4860: } else { roland@4860: dominator = common_dominator(dominator, pred); roland@4860: } duke@435: } duke@435: duke@435: if (dominator != block->dominator()) { duke@435: 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())); duke@435: duke@435: block->set_dominator(dominator); duke@435: changed = true; duke@435: } duke@435: } duke@435: return changed; duke@435: } duke@435: duke@435: void ComputeLinearScanOrder::compute_dominators() { duke@435: TRACE_LINEAR_SCAN(3, tty->print_cr("----- computing dominators (iterative computation reqired: %d)", _iterative_dominators)); duke@435: duke@435: // iterative computation of dominators is only required for methods with non-natural loops duke@435: // and OSR-methods. For all other methods, the dominators computed when generating the duke@435: // linear scan block order are correct. duke@435: if (_iterative_dominators) { duke@435: do { duke@435: TRACE_LINEAR_SCAN(1, tty->print_cr("DOM: next iteration of fix-point calculation")); duke@435: } while (compute_dominators_iter()); duke@435: } duke@435: duke@435: // check that dominators are correct duke@435: assert(!compute_dominators_iter(), "fix point not reached"); roland@4860: roland@4860: // Add Blocks to dominates-Array roland@4860: int num_blocks = _linear_scan_order->length(); roland@4860: for (int i = 0; i < num_blocks; i++) { roland@4860: BlockBegin* block = _linear_scan_order->at(i); roland@4860: roland@4860: BlockBegin *dom = block->dominator(); roland@4860: if (dom) { roland@4860: assert(dom->dominator_depth() != -1, "Dominator must have been visited before"); roland@4860: dom->dominates()->append(block); roland@4860: block->set_dominator_depth(dom->dominator_depth() + 1); roland@4860: } else { roland@4860: block->set_dominator_depth(0); roland@4860: } roland@4860: } duke@435: } duke@435: duke@435: duke@435: #ifndef PRODUCT duke@435: void ComputeLinearScanOrder::print_blocks() { duke@435: if (TraceLinearScanLevel >= 2) { duke@435: tty->print_cr("----- loop information:"); duke@435: for (int block_idx = 0; block_idx < _linear_scan_order->length(); block_idx++) { duke@435: BlockBegin* cur = _linear_scan_order->at(block_idx); duke@435: duke@435: tty->print("%4d: B%2d: ", cur->linear_scan_number(), cur->block_id()); duke@435: for (int loop_idx = 0; loop_idx < _num_loops; loop_idx++) { duke@435: tty->print ("%d ", is_block_in_loop(loop_idx, cur)); duke@435: } duke@435: tty->print_cr(" -> loop_index: %2d, loop_depth: %2d", cur->loop_index(), cur->loop_depth()); duke@435: } duke@435: } duke@435: duke@435: if (TraceLinearScanLevel >= 1) { duke@435: tty->print_cr("----- linear-scan block order:"); duke@435: for (int block_idx = 0; block_idx < _linear_scan_order->length(); block_idx++) { duke@435: BlockBegin* cur = _linear_scan_order->at(block_idx); duke@435: tty->print("%4d: B%2d loop: %2d depth: %2d", cur->linear_scan_number(), cur->block_id(), cur->loop_index(), cur->loop_depth()); duke@435: duke@435: tty->print(cur->is_set(BlockBegin::exception_entry_flag) ? " ex" : " "); duke@435: tty->print(cur->is_set(BlockBegin::critical_edge_split_flag) ? " ce" : " "); duke@435: tty->print(cur->is_set(BlockBegin::linear_scan_loop_header_flag) ? " lh" : " "); duke@435: tty->print(cur->is_set(BlockBegin::linear_scan_loop_end_flag) ? " le" : " "); duke@435: duke@435: if (cur->dominator() != NULL) { duke@435: tty->print(" dom: B%d ", cur->dominator()->block_id()); duke@435: } else { duke@435: tty->print(" dom: NULL "); duke@435: } duke@435: duke@435: if (cur->number_of_preds() > 0) { duke@435: tty->print(" preds: "); duke@435: for (int j = 0; j < cur->number_of_preds(); j++) { duke@435: BlockBegin* pred = cur->pred_at(j); duke@435: tty->print("B%d ", pred->block_id()); duke@435: } duke@435: } duke@435: if (cur->number_of_sux() > 0) { duke@435: tty->print(" sux: "); duke@435: for (int j = 0; j < cur->number_of_sux(); j++) { duke@435: BlockBegin* sux = cur->sux_at(j); duke@435: tty->print("B%d ", sux->block_id()); duke@435: } duke@435: } duke@435: if (cur->number_of_exception_handlers() > 0) { duke@435: tty->print(" ex: "); duke@435: for (int j = 0; j < cur->number_of_exception_handlers(); j++) { duke@435: BlockBegin* ex = cur->exception_handler_at(j); duke@435: tty->print("B%d ", ex->block_id()); duke@435: } duke@435: } duke@435: tty->cr(); duke@435: } duke@435: } duke@435: } duke@435: #endif duke@435: duke@435: #ifdef ASSERT duke@435: void ComputeLinearScanOrder::verify() { duke@435: assert(_linear_scan_order->length() == _num_blocks, "wrong number of blocks in list"); duke@435: duke@435: if (StressLinearScan) { duke@435: // blocks are scrambled when StressLinearScan is used duke@435: return; duke@435: } duke@435: duke@435: // check that all successors of a block have a higher linear-scan-number duke@435: // and that all predecessors of a block have a lower linear-scan-number duke@435: // (only backward branches of loops are ignored) duke@435: int i; duke@435: for (i = 0; i < _linear_scan_order->length(); i++) { duke@435: BlockBegin* cur = _linear_scan_order->at(i); duke@435: duke@435: assert(cur->linear_scan_number() == i, "incorrect linear_scan_number"); duke@435: assert(cur->linear_scan_number() >= 0 && cur->linear_scan_number() == _linear_scan_order->index_of(cur), "incorrect linear_scan_number"); duke@435: duke@435: int j; duke@435: for (j = cur->number_of_sux() - 1; j >= 0; j--) { duke@435: BlockBegin* sux = cur->sux_at(j); duke@435: duke@435: assert(sux->linear_scan_number() >= 0 && sux->linear_scan_number() == _linear_scan_order->index_of(sux), "incorrect linear_scan_number"); roland@4860: if (!sux->is_set(BlockBegin::backward_branch_target_flag)) { duke@435: assert(cur->linear_scan_number() < sux->linear_scan_number(), "invalid order"); duke@435: } duke@435: if (cur->loop_depth() == sux->loop_depth()) { duke@435: 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"); duke@435: } duke@435: } duke@435: duke@435: for (j = cur->number_of_preds() - 1; j >= 0; j--) { duke@435: BlockBegin* pred = cur->pred_at(j); duke@435: duke@435: assert(pred->linear_scan_number() >= 0 && pred->linear_scan_number() == _linear_scan_order->index_of(pred), "incorrect linear_scan_number"); roland@4860: if (!cur->is_set(BlockBegin::backward_branch_target_flag)) { duke@435: assert(cur->linear_scan_number() > pred->linear_scan_number(), "invalid order"); duke@435: } duke@435: if (cur->loop_depth() == pred->loop_depth()) { duke@435: 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"); duke@435: } duke@435: duke@435: assert(cur->dominator()->linear_scan_number() <= cur->pred_at(j)->linear_scan_number(), "dominator must be before predecessors"); duke@435: } duke@435: duke@435: // check dominator duke@435: if (i == 0) { duke@435: assert(cur->dominator() == NULL, "first block has no dominator"); duke@435: } else { duke@435: assert(cur->dominator() != NULL, "all but first block must have dominator"); duke@435: } roland@4860: // Assertion does not hold for exception handlers roland@4860: 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"); duke@435: } duke@435: duke@435: // check that all loops are continuous duke@435: for (int loop_idx = 0; loop_idx < _num_loops; loop_idx++) { duke@435: int block_idx = 0; duke@435: assert(!is_block_in_loop(loop_idx, _linear_scan_order->at(block_idx)), "the first block must not be present in any loop"); duke@435: duke@435: // skip blocks before the loop duke@435: while (block_idx < _num_blocks && !is_block_in_loop(loop_idx, _linear_scan_order->at(block_idx))) { duke@435: block_idx++; duke@435: } duke@435: // skip blocks of loop duke@435: while (block_idx < _num_blocks && is_block_in_loop(loop_idx, _linear_scan_order->at(block_idx))) { duke@435: block_idx++; duke@435: } duke@435: // after the first non-loop block, there must not be another loop-block duke@435: while (block_idx < _num_blocks) { duke@435: assert(!is_block_in_loop(loop_idx, _linear_scan_order->at(block_idx)), "loop not continuous in linear-scan order"); duke@435: block_idx++; duke@435: } duke@435: } duke@435: } duke@435: #endif duke@435: duke@435: duke@435: void IR::compute_code() { duke@435: assert(is_valid(), "IR must be valid"); duke@435: iveresov@2138: ComputeLinearScanOrder compute_order(compilation(), start()); duke@435: _num_loops = compute_order.num_loops(); duke@435: _code = compute_order.linear_scan_order(); duke@435: } duke@435: duke@435: duke@435: void IR::compute_use_counts() { duke@435: // make sure all values coming out of this block get evaluated. duke@435: int num_blocks = _code->length(); duke@435: for (int i = 0; i < num_blocks; i++) { duke@435: _code->at(i)->end()->state()->pin_stack_for_linear_scan(); duke@435: } duke@435: duke@435: // compute use counts duke@435: UseCountComputer::compute(_code); duke@435: } duke@435: duke@435: duke@435: void IR::iterate_preorder(BlockClosure* closure) { duke@435: assert(is_valid(), "IR must be valid"); duke@435: start()->iterate_preorder(closure); duke@435: } duke@435: duke@435: duke@435: void IR::iterate_postorder(BlockClosure* closure) { duke@435: assert(is_valid(), "IR must be valid"); duke@435: start()->iterate_postorder(closure); duke@435: } duke@435: duke@435: void IR::iterate_linear_scan_order(BlockClosure* closure) { duke@435: linear_scan_order()->iterate_forward(closure); duke@435: } duke@435: duke@435: duke@435: #ifndef PRODUCT duke@435: class BlockPrinter: public BlockClosure { duke@435: private: duke@435: InstructionPrinter* _ip; duke@435: bool _cfg_only; duke@435: bool _live_only; duke@435: duke@435: public: duke@435: BlockPrinter(InstructionPrinter* ip, bool cfg_only, bool live_only = false) { duke@435: _ip = ip; duke@435: _cfg_only = cfg_only; duke@435: _live_only = live_only; duke@435: } duke@435: duke@435: virtual void block_do(BlockBegin* block) { duke@435: if (_cfg_only) { duke@435: _ip->print_instr(block); tty->cr(); duke@435: } else { duke@435: block->print_block(*_ip, _live_only); duke@435: } duke@435: } duke@435: }; duke@435: duke@435: duke@435: void IR::print(BlockBegin* start, bool cfg_only, bool live_only) { duke@435: ttyLocker ttyl; duke@435: InstructionPrinter ip(!cfg_only); duke@435: BlockPrinter bp(&ip, cfg_only, live_only); duke@435: start->iterate_preorder(&bp); duke@435: tty->cr(); duke@435: } duke@435: duke@435: void IR::print(bool cfg_only, bool live_only) { duke@435: if (is_valid()) { duke@435: print(start(), cfg_only, live_only); duke@435: } else { duke@435: tty->print_cr("invalid IR"); duke@435: } duke@435: } duke@435: duke@435: duke@435: define_array(BlockListArray, BlockList*) duke@435: define_stack(BlockListList, BlockListArray) duke@435: duke@435: class PredecessorValidator : public BlockClosure { duke@435: private: duke@435: BlockListList* _predecessors; duke@435: BlockList* _blocks; duke@435: duke@435: static int cmp(BlockBegin** a, BlockBegin** b) { duke@435: return (*a)->block_id() - (*b)->block_id(); duke@435: } duke@435: duke@435: public: duke@435: PredecessorValidator(IR* hir) { duke@435: ResourceMark rm; duke@435: _predecessors = new BlockListList(BlockBegin::number_of_blocks(), NULL); duke@435: _blocks = new BlockList(); duke@435: duke@435: int i; duke@435: hir->start()->iterate_preorder(this); duke@435: if (hir->code() != NULL) { duke@435: assert(hir->code()->length() == _blocks->length(), "must match"); duke@435: for (i = 0; i < _blocks->length(); i++) { duke@435: assert(hir->code()->contains(_blocks->at(i)), "should be in both lists"); duke@435: } duke@435: } duke@435: duke@435: for (i = 0; i < _blocks->length(); i++) { duke@435: BlockBegin* block = _blocks->at(i); duke@435: BlockList* preds = _predecessors->at(block->block_id()); duke@435: if (preds == NULL) { duke@435: assert(block->number_of_preds() == 0, "should be the same"); duke@435: continue; duke@435: } duke@435: duke@435: // clone the pred list so we can mutate it duke@435: BlockList* pred_copy = new BlockList(); duke@435: int j; duke@435: for (j = 0; j < block->number_of_preds(); j++) { duke@435: pred_copy->append(block->pred_at(j)); duke@435: } duke@435: // sort them in the same order duke@435: preds->sort(cmp); duke@435: pred_copy->sort(cmp); duke@435: int length = MIN2(preds->length(), block->number_of_preds()); duke@435: for (j = 0; j < block->number_of_preds(); j++) { duke@435: assert(preds->at(j) == pred_copy->at(j), "must match"); duke@435: } duke@435: duke@435: assert(preds->length() == block->number_of_preds(), "should be the same"); duke@435: } duke@435: } duke@435: duke@435: virtual void block_do(BlockBegin* block) { duke@435: _blocks->append(block); duke@435: BlockEnd* be = block->end(); duke@435: int n = be->number_of_sux(); duke@435: int i; duke@435: for (i = 0; i < n; i++) { duke@435: BlockBegin* sux = be->sux_at(i); duke@435: assert(!sux->is_set(BlockBegin::exception_entry_flag), "must not be xhandler"); duke@435: duke@435: BlockList* preds = _predecessors->at_grow(sux->block_id(), NULL); duke@435: if (preds == NULL) { duke@435: preds = new BlockList(); duke@435: _predecessors->at_put(sux->block_id(), preds); duke@435: } duke@435: preds->append(block); duke@435: } duke@435: duke@435: n = block->number_of_exception_handlers(); duke@435: for (i = 0; i < n; i++) { duke@435: BlockBegin* sux = block->exception_handler_at(i); duke@435: assert(sux->is_set(BlockBegin::exception_entry_flag), "must be xhandler"); duke@435: duke@435: BlockList* preds = _predecessors->at_grow(sux->block_id(), NULL); duke@435: if (preds == NULL) { duke@435: preds = new BlockList(); duke@435: _predecessors->at_put(sux->block_id(), preds); duke@435: } duke@435: preds->append(block); duke@435: } duke@435: } duke@435: }; duke@435: roland@4860: class VerifyBlockBeginField : public BlockClosure { roland@4860: roland@4860: public: roland@4860: roland@4860: virtual void block_do(BlockBegin *block) { roland@4860: for ( Instruction *cur = block; cur != NULL; cur = cur->next()) { roland@4860: assert(cur->block() == block, "Block begin is not correct"); roland@4860: } roland@4860: } roland@4860: }; roland@4860: duke@435: void IR::verify() { duke@435: #ifdef ASSERT duke@435: PredecessorValidator pv(this); roland@4860: VerifyBlockBeginField verifier; roland@4860: this->iterate_postorder(&verifier); duke@435: #endif duke@435: } duke@435: duke@435: #endif // PRODUCT duke@435: iveresov@1939: void SubstitutionResolver::visit(Value* v) { duke@435: Value v0 = *v; duke@435: if (v0) { duke@435: Value vs = v0->subst(); duke@435: if (vs != v0) { duke@435: *v = v0->subst(); duke@435: } duke@435: } duke@435: } duke@435: duke@435: #ifdef ASSERT iveresov@1939: class SubstitutionChecker: public ValueVisitor { iveresov@1939: void visit(Value* v) { iveresov@1939: Value v0 = *v; iveresov@1939: if (v0) { iveresov@1939: Value vs = v0->subst(); iveresov@1939: assert(vs == v0, "missed substitution"); iveresov@1939: } duke@435: } iveresov@1939: }; duke@435: #endif duke@435: duke@435: duke@435: void SubstitutionResolver::block_do(BlockBegin* block) { duke@435: Instruction* last = NULL; duke@435: for (Instruction* n = block; n != NULL;) { iveresov@1939: n->values_do(this); duke@435: // need to remove this instruction from the instruction stream duke@435: if (n->subst() != n) { duke@435: assert(last != NULL, "must have last"); roland@2174: last->set_next(n->next()); duke@435: } else { duke@435: last = n; duke@435: } duke@435: n = last->next(); duke@435: } duke@435: duke@435: #ifdef ASSERT iveresov@1939: SubstitutionChecker check_substitute; iveresov@1939: if (block->state()) block->state()->values_do(&check_substitute); iveresov@1939: block->block_values_do(&check_substitute); iveresov@1939: if (block->end() && block->end()->state()) block->end()->state()->values_do(&check_substitute); duke@435: #endif duke@435: }