< prev index next >
src/share/vm/opto/block.cpp
Print this page
*** 772,785 ****
--- 772,794 ----
void PhaseCFG::fixup_flow() {
// Fixup final control flow for the blocks. Remove jump-to-next
// block. If neither arm of an IF follows the conditional branch, we
// have to add a second jump after the conditional. We place the
// TRUE branch target in succs[0] for both GOTOs and IFs.
+ bool found_fixup_loops = false;
for (uint i = 0; i < number_of_blocks(); i++) {
Block* block = get_block(i);
block->_pre_order = i; // turn pre-order into block-index
+ Node *bh = block->head();
+ if (bh->is_Loop()) {
+ LoopNode *loop = bh->as_Loop();
+ if (loop->is_inner_loop() && loop->is_multiversioned() && loop->is_vectorized_loop() && !loop->range_checks_present()) {
+ found_fixup_loops = true;
+ }
+ }
+
// Connector blocks need no further processing.
if (block->is_connector()) {
assert((i+1) == number_of_blocks() || get_block(i + 1)->is_connector(), "All connector blocks should sink to the end");
continue;
}
*** 925,934 ****
--- 934,987 ----
} else {
// Multi-exit block, e.g. a switch statement
// But we don't need to do anything here
}
} // End of for all blocks
+
+ if (found_fixup_loops) {
+ // find all fixup-loops and process them
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ Node *bh = block->head();
+ if (bh->is_Loop()) {
+ LoopNode *loop = bh->as_Loop();
+ // fixup loops are only marked for processing when they are predicated and
+ // vectorized else they are just post loops.
+ if (Matcher::has_predicated_vectors()) {
+ if (loop->is_inner_loop() && loop->is_multiversioned() && loop->is_vectorized_loop() && !loop->range_checks_present()) {
+ CFGLoop *cur_loop = block->_loop;
+ // fixup loops can have multiple exits, so we need to find the backedge
+ Block *back_edge = cur_loop->backedge_block();
+ if (back_edge) {
+ // fetch the region of the back edge
+ Node *backedge_region = back_edge->get_node(0);
+ Block *idom = back_edge->_idom;
+ if (backedge_region->is_Region()) {
+ Node *if_true = backedge_region->in(1);
+ if (if_true->Opcode() == Op_IfTrue) {
+ Node *backedge_iff = if_true->in(0);
+ if (backedge_iff->is_MachIf() && idom) {
+ for (uint j = 0; j < idom->number_of_nodes(); j++) {
+ Node *n = idom->get_node(j);
+ if (n == backedge_iff) {
+ MachMskNode *mask = new MachMskNode(true);
+ if (mask) {
+ idom->insert_node(mask, j);
+ map_node_to_block(mask, idom);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
// postalloc_expand: Expand nodes after register allocation.
//
< prev index next >