src/share/vm/c1/c1_LinearScan.cpp

Print this page
rev 4136 : 7153771: array bound check elimination for c1
Summary: when possible optimize out array bound checks, inserting predicates when needed.
Reviewed-by:


6214       assert(last_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch");
6215       LIR_OpBranch* last_branch = (LIR_OpBranch*)last_op;
6216 
6217       assert(last_branch->block() != NULL, "last branch must always have a block as target");
6218       assert(last_branch->label() == last_branch->block()->label(), "must be equal");
6219 
6220       if (last_branch->info() == NULL) {
6221         if (last_branch->block() == code->at(i + 1)) {
6222 
6223           TRACE_LINEAR_SCAN(3, tty->print_cr("Deleting unconditional branch at end of block B%d", block->block_id()));
6224 
6225           // delete last branch instruction
6226           instructions->truncate(instructions->length() - 1);
6227 
6228         } else {
6229           LIR_Op* prev_op = instructions->at(instructions->length() - 2);
6230           if (prev_op->code() == lir_branch || prev_op->code() == lir_cond_float_branch) {
6231             assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch");
6232             LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op;
6233 


6234             LIR_Op2* prev_cmp = NULL;
6235 
6236             for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) {
6237               prev_op = instructions->at(j);
6238               if(prev_op->code() == lir_cmp) {
6239                 assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2");
6240                 prev_cmp = (LIR_Op2*)prev_op;
6241                 assert(prev_branch->cond() == prev_cmp->condition(), "should be the same");
6242               }
6243             }
6244             assert(prev_cmp != NULL, "should have found comp instruction for branch");
6245             if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) {
6246 
6247               TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id()));
6248 
6249               // eliminate a conditional branch to the immediate successor
6250               prev_branch->change_block(last_branch->block());
6251               prev_branch->negate_cond();
6252               prev_cmp->set_condition(prev_branch->cond());
6253               instructions->truncate(instructions->length() - 1);

6254             }
6255           }
6256         }
6257       }
6258     }
6259   }
6260 
6261   DEBUG_ONLY(verify(code));
6262 }
6263 
6264 void ControlFlowOptimizer::delete_jumps_to_return(BlockList* code) {
6265 #ifdef ASSERT
6266   BitMap return_converted(BlockBegin::number_of_blocks());
6267   return_converted.clear();
6268 #endif
6269 
6270   for (int i = code->length() - 1; i >= 0; i--) {
6271     BlockBegin* block = code->at(i);
6272     LIR_OpList* cur_instructions = block->lir()->instructions_list();
6273     LIR_Op*     cur_last_op = cur_instructions->last();




6214       assert(last_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch");
6215       LIR_OpBranch* last_branch = (LIR_OpBranch*)last_op;
6216 
6217       assert(last_branch->block() != NULL, "last branch must always have a block as target");
6218       assert(last_branch->label() == last_branch->block()->label(), "must be equal");
6219 
6220       if (last_branch->info() == NULL) {
6221         if (last_branch->block() == code->at(i + 1)) {
6222 
6223           TRACE_LINEAR_SCAN(3, tty->print_cr("Deleting unconditional branch at end of block B%d", block->block_id()));
6224 
6225           // delete last branch instruction
6226           instructions->truncate(instructions->length() - 1);
6227 
6228         } else {
6229           LIR_Op* prev_op = instructions->at(instructions->length() - 2);
6230           if (prev_op->code() == lir_branch || prev_op->code() == lir_cond_float_branch) {
6231             assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch");
6232             LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op;
6233 
6234             if (prev_branch->stub() == NULL) {
6235 
6236               LIR_Op2* prev_cmp = NULL;
6237               
6238               for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) {
6239                 prev_op = instructions->at(j);
6240                 if (prev_op->code() == lir_cmp) {
6241                   assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2");
6242                   prev_cmp = (LIR_Op2*)prev_op;
6243                   assert(prev_branch->cond() == prev_cmp->condition(), "should be the same");
6244                 }
6245               }
6246               assert(prev_cmp != NULL, "should have found comp instruction for branch");
6247               if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) {
6248                 
6249                 TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id()));
6250                 
6251                 // eliminate a conditional branch to the immediate successor
6252                 prev_branch->change_block(last_branch->block());
6253                 prev_branch->negate_cond();
6254                 prev_cmp->set_condition(prev_branch->cond());
6255                 instructions->truncate(instructions->length() - 1);
6256               }
6257             }
6258           }
6259         }
6260       }
6261     }
6262   }
6263 
6264   DEBUG_ONLY(verify(code));
6265 }
6266 
6267 void ControlFlowOptimizer::delete_jumps_to_return(BlockList* code) {
6268 #ifdef ASSERT
6269   BitMap return_converted(BlockBegin::number_of_blocks());
6270   return_converted.clear();
6271 #endif
6272 
6273   for (int i = code->length() - 1; i >= 0; i--) {
6274     BlockBegin* block = code->at(i);
6275     LIR_OpList* cur_instructions = block->lir()->instructions_list();
6276     LIR_Op*     cur_last_op = cur_instructions->last();