Mercurial > hg > truffle
comparison src/share/vm/c1/c1_Compilation.cpp @ 8860:46f6f063b272
7153771: array bound check elimination for c1
Summary: when possible optimize out array bound checks, inserting predicates when needed.
Reviewed-by: never, kvn, twisti
Contributed-by: thomaswue <thomas.wuerthinger@oracle.com>
author | roland |
---|---|
date | Thu, 21 Mar 2013 09:27:54 +0100 |
parents | c5d414e98fd4 |
children | e47de6dfec5d |
comparison
equal
deleted
inserted
replaced
8780:98f3af397705 | 8860:46f6f063b272 |
---|---|
31 #include "c1/c1_MacroAssembler.hpp" | 31 #include "c1/c1_MacroAssembler.hpp" |
32 #include "c1/c1_ValueMap.hpp" | 32 #include "c1/c1_ValueMap.hpp" |
33 #include "c1/c1_ValueStack.hpp" | 33 #include "c1/c1_ValueStack.hpp" |
34 #include "code/debugInfoRec.hpp" | 34 #include "code/debugInfoRec.hpp" |
35 #include "compiler/compileLog.hpp" | 35 #include "compiler/compileLog.hpp" |
36 #include "c1/c1_RangeCheckElimination.hpp" | |
36 | 37 |
37 | 38 |
38 typedef enum { | 39 typedef enum { |
39 _t_compile, | 40 _t_compile, |
40 _t_setup, | 41 _t_setup, |
41 _t_optimizeIR, | |
42 _t_buildIR, | 42 _t_buildIR, |
43 _t_optimize_blocks, | |
44 _t_optimize_null_checks, | |
45 _t_rangeCheckElimination, | |
43 _t_emit_lir, | 46 _t_emit_lir, |
44 _t_linearScan, | 47 _t_linearScan, |
45 _t_lirGeneration, | 48 _t_lirGeneration, |
46 _t_lir_schedule, | 49 _t_lir_schedule, |
47 _t_codeemit, | 50 _t_codeemit, |
50 } TimerName; | 53 } TimerName; |
51 | 54 |
52 static const char * timer_name[] = { | 55 static const char * timer_name[] = { |
53 "compile", | 56 "compile", |
54 "setup", | 57 "setup", |
55 "optimizeIR", | |
56 "buildIR", | 58 "buildIR", |
59 "optimize_blocks", | |
60 "optimize_null_checks", | |
61 "rangeCheckElimination", | |
57 "emit_lir", | 62 "emit_lir", |
58 "linearScan", | 63 "linearScan", |
59 "lirGeneration", | 64 "lirGeneration", |
60 "lir_schedule", | 65 "lir_schedule", |
61 "codeemit", | 66 "codeemit", |
157 _hir->verify(); | 162 _hir->verify(); |
158 | 163 |
159 if (UseC1Optimizations) { | 164 if (UseC1Optimizations) { |
160 NEEDS_CLEANUP | 165 NEEDS_CLEANUP |
161 // optimization | 166 // optimization |
162 PhaseTraceTime timeit(_t_optimizeIR); | 167 PhaseTraceTime timeit(_t_optimize_blocks); |
163 | 168 |
164 _hir->optimize(); | 169 _hir->optimize_blocks(); |
165 } | 170 } |
166 | 171 |
167 _hir->verify(); | 172 _hir->verify(); |
168 | 173 |
169 _hir->split_critical_edges(); | 174 _hir->split_critical_edges(); |
178 // compute block ordering for code generation | 183 // compute block ordering for code generation |
179 // the control flow must not be changed from here on | 184 // the control flow must not be changed from here on |
180 _hir->compute_code(); | 185 _hir->compute_code(); |
181 | 186 |
182 if (UseGlobalValueNumbering) { | 187 if (UseGlobalValueNumbering) { |
183 ResourceMark rm; | 188 // No resource mark here! LoopInvariantCodeMotion can allocate ValueStack objects. |
184 int instructions = Instruction::number_of_instructions(); | 189 int instructions = Instruction::number_of_instructions(); |
185 GlobalValueNumbering gvn(_hir); | 190 GlobalValueNumbering gvn(_hir); |
186 assert(instructions == Instruction::number_of_instructions(), | 191 assert(instructions == Instruction::number_of_instructions(), |
187 "shouldn't have created an instructions"); | 192 "shouldn't have created an instructions"); |
188 } | 193 } |
194 | |
195 _hir->verify(); | |
196 | |
197 #ifndef PRODUCT | |
198 if (PrintCFGToFile) { | |
199 CFGPrinter::print_cfg(_hir, "Before RangeCheckElimination", true, false); | |
200 } | |
201 #endif | |
202 | |
203 if (RangeCheckElimination) { | |
204 if (_hir->osr_entry() == NULL) { | |
205 PhaseTraceTime timeit(_t_rangeCheckElimination); | |
206 RangeCheckElimination::eliminate(_hir); | |
207 } | |
208 } | |
209 | |
210 #ifndef PRODUCT | |
211 if (PrintCFGToFile) { | |
212 CFGPrinter::print_cfg(_hir, "After RangeCheckElimination", true, false); | |
213 } | |
214 #endif | |
215 | |
216 if (UseC1Optimizations) { | |
217 // loop invariant code motion reorders instructions and range | |
218 // check elimination adds new instructions so do null check | |
219 // elimination after. | |
220 NEEDS_CLEANUP | |
221 // optimization | |
222 PhaseTraceTime timeit(_t_optimize_null_checks); | |
223 | |
224 _hir->eliminate_null_checks(); | |
225 } | |
226 | |
227 _hir->verify(); | |
189 | 228 |
190 // compute use counts after global value numbering | 229 // compute use counts after global value numbering |
191 _hir->compute_use_counts(); | 230 _hir->compute_use_counts(); |
192 | 231 |
193 #ifndef PRODUCT | 232 #ifndef PRODUCT |
500 , _exception_info_list(NULL) | 539 , _exception_info_list(NULL) |
501 , _allocator(NULL) | 540 , _allocator(NULL) |
502 , _next_id(0) | 541 , _next_id(0) |
503 , _next_block_id(0) | 542 , _next_block_id(0) |
504 , _code(buffer_blob) | 543 , _code(buffer_blob) |
544 , _has_access_indexed(false) | |
505 , _current_instruction(NULL) | 545 , _current_instruction(NULL) |
506 #ifndef PRODUCT | 546 #ifndef PRODUCT |
507 , _last_instruction_printed(NULL) | 547 , _last_instruction_printed(NULL) |
508 #endif // PRODUCT | 548 #endif // PRODUCT |
509 { | 549 { |
565 | 605 |
566 | 606 |
567 tty->print_cr(" Detailed C1 Timings"); | 607 tty->print_cr(" Detailed C1 Timings"); |
568 tty->print_cr(" Setup time: %6.3f s (%4.1f%%)", timers[_t_setup].seconds(), (timers[_t_setup].seconds() / total) * 100.0); | 608 tty->print_cr(" Setup time: %6.3f s (%4.1f%%)", timers[_t_setup].seconds(), (timers[_t_setup].seconds() / total) * 100.0); |
569 tty->print_cr(" Build IR: %6.3f s (%4.1f%%)", timers[_t_buildIR].seconds(), (timers[_t_buildIR].seconds() / total) * 100.0); | 609 tty->print_cr(" Build IR: %6.3f s (%4.1f%%)", timers[_t_buildIR].seconds(), (timers[_t_buildIR].seconds() / total) * 100.0); |
570 tty->print_cr(" Optimize: %6.3f s (%4.1f%%)", timers[_t_optimizeIR].seconds(), (timers[_t_optimizeIR].seconds() / total) * 100.0); | 610 float t_optimizeIR = timers[_t_optimize_blocks].seconds() + timers[_t_optimize_null_checks].seconds(); |
611 tty->print_cr(" Optimize: %6.3f s (%4.1f%%)", t_optimizeIR, (t_optimizeIR / total) * 100.0); | |
612 tty->print_cr(" RCE: %6.3f s (%4.1f%%)", timers[_t_rangeCheckElimination].seconds(), (timers[_t_rangeCheckElimination].seconds() / total) * 100.0); | |
571 tty->print_cr(" Emit LIR: %6.3f s (%4.1f%%)", timers[_t_emit_lir].seconds(), (timers[_t_emit_lir].seconds() / total) * 100.0); | 613 tty->print_cr(" Emit LIR: %6.3f s (%4.1f%%)", timers[_t_emit_lir].seconds(), (timers[_t_emit_lir].seconds() / total) * 100.0); |
572 tty->print_cr(" LIR Gen: %6.3f s (%4.1f%%)", timers[_t_lirGeneration].seconds(), (timers[_t_lirGeneration].seconds() / total) * 100.0); | 614 tty->print_cr(" LIR Gen: %6.3f s (%4.1f%%)", timers[_t_lirGeneration].seconds(), (timers[_t_lirGeneration].seconds() / total) * 100.0); |
573 tty->print_cr(" Linear Scan: %6.3f s (%4.1f%%)", timers[_t_linearScan].seconds(), (timers[_t_linearScan].seconds() / total) * 100.0); | 615 tty->print_cr(" Linear Scan: %6.3f s (%4.1f%%)", timers[_t_linearScan].seconds(), (timers[_t_linearScan].seconds() / total) * 100.0); |
574 NOT_PRODUCT(LinearScan::print_timers(timers[_t_linearScan].seconds())); | 616 NOT_PRODUCT(LinearScan::print_timers(timers[_t_linearScan].seconds())); |
575 tty->print_cr(" LIR Schedule: %6.3f s (%4.1f%%)", timers[_t_lir_schedule].seconds(), (timers[_t_lir_schedule].seconds() / total) * 100.0); | 617 tty->print_cr(" LIR Schedule: %6.3f s (%4.1f%%)", timers[_t_lir_schedule].seconds(), (timers[_t_lir_schedule].seconds() / total) * 100.0); |