void block_do(BlockBegin* bb) { BlockEnd* be = bb->end(); int n = be->number_of_sux(); for (int i = 0; i < n; i++) { BlockBegin* sux = be->sux_at(i); BlockLoopInfo* sux_bli = _lf->get_block_info(sux); sux_bli->add_predecessor(bb); } }
void InstructionPrinter::do_BlockBegin(BlockBegin* x) { // print block id BlockEnd* end = x->end(); tty->print("B%d ", x->block_id()); // print flags bool printed_flag = false; if (x->is_set(BlockBegin::std_entry_flag)) { if (!printed_flag) tty->print("("); tty->print("S"); printed_flag = true; } if (x->is_set(BlockBegin::osr_entry_flag)) { if (!printed_flag) tty->print("("); tty->print("O"); printed_flag = true; } if (x->is_set(BlockBegin::exception_entry_flag)) { if (!printed_flag) tty->print("("); tty->print("E"); printed_flag = true; } if (x->is_set(BlockBegin::subroutine_entry_flag)) { if (!printed_flag) tty->print("("); tty->print("s"); printed_flag = true; } if (x->is_set(BlockBegin::backward_branch_target_flag)) { if (!printed_flag) tty->print("("); tty->print("b"); printed_flag = true; } if (x->is_set(BlockBegin::was_visited_flag)) { if (!printed_flag) tty->print("("); tty->print("V"); printed_flag = true; } if (x->is_set(BlockBegin::single_precision_flag)) { if (!printed_flag) tty->print("("); tty->print("F24"); printed_flag = true; } if (printed_flag) tty->print(") "); // print block bci range tty->print("[%d, %d]", x->bci(), (end == NULL ? -1 : end->bci())); // print block successors if (end != NULL && end->number_of_sux() > 0) { tty->print(" ->"); for (int i = 0; i < end->number_of_sux(); i++) { tty->print(" B%d", end->sux_at(i)->block_id()); } } // print exception handlers if (x->number_of_exception_handlers() > 0) { tty->print(" (xhandlers "); for (int i = 0; i < x->number_of_exception_handlers(); i++) { if (i > 0) tty->print(" "); tty->print("B%d", x->exception_handler_at(i)->block_id()); } tty->put(')'); } }
void LoopFinder::find_loop_exits(BlockBegin* bb, Loop* loop) { BlockLoopInfo* bli = get_block_info(bb); int loop_index = bb->loop_index(); // search all successors and locate the ones that do not have the same loop_index BlockEnd* be = bb->end(); int n = be->number_of_sux() - 1; for(; n >= 0; n--) { BlockBegin* sux = be->sux_at(n); BlockLoopInfo* sux_bli = get_block_info(sux); if (sux->loop_index() != loop_index) { loop->append_loop_exit(bb, sux); } } }
// Gather backedges of natural loops: an edge a -> b where b dominates a LoopList* LoopFinder::find_backedges(boolArray* visited) { int i; LoopList* backedges = new LoopList(); for (i = 0; i < max_blocks(); i++) { if (visited->at(i)) { BlockLoopInfo* bli = _info->at(i); BlockBegin* bb = bli->block(); BlockEnd* be = bb->end(); int n = be->number_of_sux(); for (int i = 0; i < n; i++) { BlockBegin* sux = be->sux_at(i); if (bli->is_dom_block(sux->block_id())) { bli->mark_backedge_start(); backedges->push(new Loop(sux, bb)); } } } } // backedges contains single pairs of blocks which are a backedge. // some of these loops may share entry points, so walk over the backedges // and merge loops which have the same entry point if (backedges->length() > 1) { backedges->sort(sort_by_start_block); Loop* current_loop = backedges->at(0); for (i = 1; i < backedges->length();) { Loop* this_loop = backedges->at(i); if (current_loop->start() == this_loop->start()) { // same entry point assert(this_loop->ends()->length() == 1, "should only have one end at this point"); #ifndef PRODUCT if (PrintLoops && Verbose) { tty->print_cr("Merging loops with same start"); current_loop->print(); this_loop->print(); } #endif BlockBegin* e = this_loop->ends()->at(0); current_loop->add_end(e); backedges->remove(this_loop); } else { // start processing the next loop entry point i++; } } } return backedges; }
// Compute dominators for bb and // walk the successors of bb in depth first order void LoopFinder::dominator_walk_sux(BlockBegin* bb, boolArray* visited) { // we may not visit a block that is jsr-target if (bb->is_set(BlockBegin::subroutine_entry_flag)) set_not_ok(); BlockEnd* be = bb->end(); BlockLoopInfo* bli = get_block_info(bb); visited->at_put(bb->block_id(), true); // compute new dominators using predecessors BitMap map(max_blocks()); map.set_from(*BlockLoopInfo::all_blocks_map()); { // Compute dominators for myself (looking at predecessors) int nof_preds = bli->nof_preds(); for (int i = 0; i < nof_preds; i++) { BlockBegin* pred = bli->pred_no(i); BitMap pred_map = get_block_info(pred)->doms_map(); map.set_intersection(pred_map); } // add itself map.at_put(bb->block_id(), true); // if the computed dominators differ from the one stored, // then we need another iteration BitMap bb_map = bli->doms_map(); if (!bb_map.is_same(map)) { set_changed(true); bb_map.set_from(map); } } { // Visit all successors int n = be->number_of_sux(); for (int i = 0; i < n; i++) { BlockBegin* sux = be->sux_at(i); if (!visited->at(sux->block_id())) { dominator_walk_sux(sux, visited); } } } }
void InstructionPrinter::do_BlockBegin(BlockBegin* x) { // print block id BlockEnd* end = x->end(); output()->print("B%d ", x->block_id()); // print flags bool printed_flag = false; if (x->is_set(BlockBegin::std_entry_flag)) { if (!printed_flag) output()->print("("); output()->print("S"); printed_flag = true; } if (x->is_set(BlockBegin::osr_entry_flag)) { if (!printed_flag) output()->print("("); output()->print("O"); printed_flag = true; } if (x->is_set(BlockBegin::exception_entry_flag)) { if (!printed_flag) output()->print("("); output()->print("E"); printed_flag = true; } if (x->is_set(BlockBegin::subroutine_entry_flag)) { if (!printed_flag) output()->print("("); output()->print("s"); printed_flag = true; } if (x->is_set(BlockBegin::parser_loop_header_flag)) { if (!printed_flag) output()->print("("); output()->print("LH"); printed_flag = true; } if (x->is_set(BlockBegin::backward_branch_target_flag)) { if (!printed_flag) output()->print("("); output()->print("b"); printed_flag = true; } if (x->is_set(BlockBegin::was_visited_flag)) { if (!printed_flag) output()->print("("); output()->print("V"); printed_flag = true; } if (printed_flag) output()->print(") "); // print block bci range output()->print("[%d, %d]",x->bci(),(end==NULL?InvocationEntryBci:end->bci())); // print block successors if (end != NULL && end->number_of_sux() > 0) { output()->print(" ->"); for (int i = 0; i < end->number_of_sux(); i++) { output()->print(" B%d", end->sux_at(i)->block_id()); } } // print exception handlers if (x->number_of_exception_handlers() > 0) { output()->print(" (xhandlers "); for (int i = 0; i < x->number_of_exception_handlers(); i++) { if (i > 0) output()->print(" "); output()->print("B%d", x->exception_handler_at(i)->block_id()); } output()->put(')'); } // print dominator block if (x->dominator() != NULL) { output()->print(" dom B%d", x->dominator()->block_id()); } // print predecessors and successors if (x->successors()->length() > 0) { output()->print(" sux:"); for (int i = 0; i < x->successors()->length(); i ++) { output()->print(" B%d", x->successors()->at(i)->block_id()); } } if (x->number_of_preds() > 0) { output()->print(" pred:"); for (int i = 0; i < x->number_of_preds(); i ++) { output()->print(" B%d", x->pred_at(i)->block_id()); } } if (!_print_phis) { return; } // print phi functions bool has_phis_in_locals = false; bool has_phis_on_stack = false; if (x->end() && x->end()->state()) { ValueStack* state = x->state(); int i = 0; while (!has_phis_on_stack && i < state->stack_size()) { Value v = state->stack_at_inc(i); has_phis_on_stack = is_phi_of_block(v, x); } do { for (i = 0; !has_phis_in_locals && i < state->locals_size();) { Value v = state->local_at(i); has_phis_in_locals = is_phi_of_block(v, x); // also ignore illegal HiWords if (v && !v->type()->is_illegal()) i += v->type()->size(); else i ++; } state = state->caller_state(); } while (state != NULL); } // print values in locals if (has_phis_in_locals) { output()->cr(); output()->print_cr("Locals:"); ValueStack* state = x->state(); do { for (int i = 0; i < state->locals_size();) { Value v = state->local_at(i); if (v) { print_phi(i, v, x); output()->cr(); // also ignore illegal HiWords i += (v->type()->is_illegal() ? 1 : v->type()->size()); } else { i ++; } } output()->cr(); state = state->caller_state(); } while (state != NULL); } // print values on stack if (has_phis_on_stack) { output()->print_cr("Stack:"); int i = 0; while (i < x->state()->stack_size()) { int o = i; Value v = x->state()->stack_at_inc(i); if (v) { print_phi(o, v, x); output()->cr(); } } } }
void LoopFinder::compute_dominators(boolArray* visited) { // set up a bitmap that contains all blocks BitMap all_map(max_blocks()); all_map.clear(); for (int i = 0; i < max_blocks(); i++) all_map.at_put(i, true); BlockLoopInfo::set_all_blocks_map(&all_map); { // initialize block loop info and set all predecessors CreateInfoClosure c(this); ir()->iterate_preorder(&c); SetPredsClosure s(this); ir()->iterate_preorder(&s); } { // compute dominators // init dominators // set entry block (only one exists) and its dominators BlockBegin* root_bb = ir()->start(); assert(!root_bb->is_set(BlockBegin::subroutine_entry_flag), "root may not be jsr target"); { // initialize root dominators (only itself) BitMap root_doms(max_blocks()); root_doms.clear(); root_doms.at_put(root_bb->block_id(), true); BlockLoopInfo* bli = get_block_info(root_bb); bli->doms_map().set_from(root_doms); } // iterate until either iter_count exceeds or dominators stable int iter_count = 0; do { iter_count++; visited->at_put(root_bb->block_id(), true); set_changed(false); BlockEnd* be = root_bb->end(); int n = be->number_of_sux(); for (int i = 0; i < n; i++) { BlockBegin* sux = be->sux_at(i); if (!visited->at(sux->block_id())) { dominator_walk_sux(sux, visited); } } if (changed()) { for (int i = visited->length() - 1; i >= 0; i--) { visited->at_put(i, false); } } } while (changed() && iter_count <= max_nof_dom_iterations); if (iter_count == max_nof_dom_iterations) { if (PrintLoops) { tty->print_cr("could not computer dominators"); } set_not_ok(); } // if (PrintLoops) { // tty->print_cr(" Dominators: %d iterations", iter_count); // PrintBlockDominators p(this); // ir()->iterate_topological(&p); // } } BlockLoopInfo::set_all_blocks_map(NULL); // go through all blocks; if a block has not been analyzed, then check its // predecessors and successors: all must be also un-analyzed; // Note: the block may not be JSR blocks if (ok()) { _valid_doms = true; #ifdef ASSERT CheckDomClosure cc(visited); ir()->iterate_preorder(&cc); #endif } }