src/share/vm/c1/c1_Compilation.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:

*** 31,47 **** #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_ValueMap.hpp" #include "c1/c1_ValueStack.hpp" #include "code/debugInfoRec.hpp" #include "compiler/compileLog.hpp" typedef enum { _t_compile, _t_setup, - _t_optimizeIR, _t_buildIR, _t_emit_lir, _t_linearScan, _t_lirGeneration, _t_lir_schedule, _t_codeemit, --- 31,50 ---- #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_ValueMap.hpp" #include "c1/c1_ValueStack.hpp" #include "code/debugInfoRec.hpp" #include "compiler/compileLog.hpp" + #include "c1/c1_RangeCheckElimination.hpp" typedef enum { _t_compile, _t_setup, _t_buildIR, + _t_optimize_blocks, + _t_optimize_null_checks, + _t_rangeCheckElimination, _t_emit_lir, _t_linearScan, _t_lirGeneration, _t_lir_schedule, _t_codeemit,
*** 50,60 **** } TimerName; static const char * timer_name[] = { "compile", "setup", ! "optimizeIR", "buildIR", "emit_lir", "linearScan", "lirGeneration", "lir_schedule", --- 53,65 ---- } TimerName; static const char * timer_name[] = { "compile", "setup", ! "optimize_blocks", ! "optimize_null_checks", ! "rangeCheckElimination", "buildIR", "emit_lir", "linearScan", "lirGeneration", "lir_schedule",
*** 157,169 **** _hir->verify(); if (UseC1Optimizations) { NEEDS_CLEANUP // optimization ! PhaseTraceTime timeit(_t_optimizeIR); ! _hir->optimize(); } _hir->verify(); _hir->split_critical_edges(); --- 162,174 ---- _hir->verify(); if (UseC1Optimizations) { NEEDS_CLEANUP // optimization ! PhaseTraceTime timeit(_t_optimize_blocks); ! _hir->optimize_blocks(); } _hir->verify(); _hir->split_critical_edges();
*** 178,194 **** // compute block ordering for code generation // the control flow must not be changed from here on _hir->compute_code(); if (UseGlobalValueNumbering) { ! ResourceMark rm; int instructions = Instruction::number_of_instructions(); GlobalValueNumbering gvn(_hir); assert(instructions == Instruction::number_of_instructions(), "shouldn't have created an instructions"); } // compute use counts after global value numbering _hir->compute_use_counts(); #ifndef PRODUCT if (PrintCFG || PrintCFG2) { tty->print_cr("CFG before code generation"); _hir->code()->print(true); } --- 183,235 ---- // compute block ordering for code generation // the control flow must not be changed from here on _hir->compute_code(); if (UseGlobalValueNumbering) { ! // No resource mark here! LoopInvariantCodeMotion can allocate ValueStack objects. int instructions = Instruction::number_of_instructions(); GlobalValueNumbering gvn(_hir); assert(instructions == Instruction::number_of_instructions(), "shouldn't have created an instructions"); } + _hir->verify(); + + #ifndef PRODUCT + + if (PrintCFGToFile) { + CFGPrinter::print_cfg(_hir, "Before RangeCheckElimination", true, false); + } + + #endif + + if (RangeCheckElimination) { + if (_hir->osr_entry() == NULL) { + PhaseTraceTime timeit(_t_rangeCheckElimination); + RangeCheckElimination::eliminate(_hir); + } + } + + #ifndef PRODUCT + if (PrintCFGToFile) { + CFGPrinter::print_cfg(_hir, "After RangeCheckElimination", true, false); + } + #endif + + if (UseC1Optimizations) { + // loop invariant code motion reorders instructions and range + // check elimination adds new instructions so do null check + // elimination after. + NEEDS_CLEANUP + // optimization + PhaseTraceTime timeit(_t_optimize_null_checks); + + _hir->eliminate_null_checks(); + } + + _hir->verify(); + // compute use counts after global value numbering _hir->compute_use_counts(); #ifndef PRODUCT if (PrintCFG || PrintCFG2) { tty->print_cr("CFG before code generation"); _hir->code()->print(true); }
*** 500,509 **** --- 541,551 ---- , _exception_info_list(NULL) , _allocator(NULL) , _next_id(0) , _next_block_id(0) , _code(buffer_blob) + , _has_access_indexed(false) , _current_instruction(NULL) #ifndef PRODUCT , _last_instruction_printed(NULL) #endif // PRODUCT {
*** 565,575 **** tty->print_cr(" Detailed C1 Timings"); tty->print_cr(" Setup time: %6.3f s (%4.1f%%)", timers[_t_setup].seconds(), (timers[_t_setup].seconds() / total) * 100.0); tty->print_cr(" Build IR: %6.3f s (%4.1f%%)", timers[_t_buildIR].seconds(), (timers[_t_buildIR].seconds() / total) * 100.0); ! tty->print_cr(" Optimize: %6.3f s (%4.1f%%)", timers[_t_optimizeIR].seconds(), (timers[_t_optimizeIR].seconds() / total) * 100.0); tty->print_cr(" Emit LIR: %6.3f s (%4.1f%%)", timers[_t_emit_lir].seconds(), (timers[_t_emit_lir].seconds() / total) * 100.0); tty->print_cr(" LIR Gen: %6.3f s (%4.1f%%)", timers[_t_lirGeneration].seconds(), (timers[_t_lirGeneration].seconds() / total) * 100.0); tty->print_cr(" Linear Scan: %6.3f s (%4.1f%%)", timers[_t_linearScan].seconds(), (timers[_t_linearScan].seconds() / total) * 100.0); NOT_PRODUCT(LinearScan::print_timers(timers[_t_linearScan].seconds())); tty->print_cr(" LIR Schedule: %6.3f s (%4.1f%%)", timers[_t_lir_schedule].seconds(), (timers[_t_lir_schedule].seconds() / total) * 100.0); --- 607,619 ---- tty->print_cr(" Detailed C1 Timings"); tty->print_cr(" Setup time: %6.3f s (%4.1f%%)", timers[_t_setup].seconds(), (timers[_t_setup].seconds() / total) * 100.0); tty->print_cr(" Build IR: %6.3f s (%4.1f%%)", timers[_t_buildIR].seconds(), (timers[_t_buildIR].seconds() / total) * 100.0); ! float t_optimizeIR = timers[_t_optimize_blocks].seconds() + timers[_t_optimize_null_checks].seconds(); ! tty->print_cr(" Optimize: %6.3f s (%4.1f%%)", t_optimizeIR, (t_optimizeIR / total) * 100.0); ! tty->print_cr(" RCE: %6.3f s (%4.1f%%)", timers[_t_rangeCheckElimination].seconds(), (timers[_t_rangeCheckElimination].seconds() / total) * 100.0); tty->print_cr(" Emit LIR: %6.3f s (%4.1f%%)", timers[_t_emit_lir].seconds(), (timers[_t_emit_lir].seconds() / total) * 100.0); tty->print_cr(" LIR Gen: %6.3f s (%4.1f%%)", timers[_t_lirGeneration].seconds(), (timers[_t_lirGeneration].seconds() / total) * 100.0); tty->print_cr(" Linear Scan: %6.3f s (%4.1f%%)", timers[_t_linearScan].seconds(), (timers[_t_linearScan].seconds() / total) * 100.0); NOT_PRODUCT(LinearScan::print_timers(timers[_t_linearScan].seconds())); tty->print_cr(" LIR Schedule: %6.3f s (%4.1f%%)", timers[_t_lir_schedule].seconds(), (timers[_t_lir_schedule].seconds() / total) * 100.0);