Thu, 21 Mar 2013 09:27:54 +0100
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>
1.1 --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Wed Mar 20 17:04:45 2013 -0700 1.2 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Thu Mar 21 09:27:54 2013 +0100 1.3 @@ -51,6 +51,16 @@ 1.4 void RangeCheckStub::emit_code(LIR_Assembler* ce) { 1.5 __ bind(_entry); 1.6 1.7 + if (_info->deoptimize_on_exception()) { 1.8 + address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); 1.9 + __ call(a, relocInfo::runtime_call_type); 1.10 + __ delayed()->nop(); 1.11 + ce->add_call_info_here(_info); 1.12 + ce->verify_oop_map(_info); 1.13 + debug_only(__ should_not_reach_here()); 1.14 + return; 1.15 + } 1.16 + 1.17 if (_index->is_register()) { 1.18 __ mov(_index->as_register(), G4); 1.19 } else { 1.20 @@ -64,11 +74,22 @@ 1.21 __ delayed()->nop(); 1.22 ce->add_call_info_here(_info); 1.23 ce->verify_oop_map(_info); 1.24 -#ifdef ASSERT 1.25 - __ should_not_reach_here(); 1.26 -#endif 1.27 + debug_only(__ should_not_reach_here()); 1.28 } 1.29 1.30 +PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) { 1.31 + _info = new CodeEmitInfo(info); 1.32 +} 1.33 + 1.34 +void PredicateFailedStub::emit_code(LIR_Assembler* ce) { 1.35 + __ bind(_entry); 1.36 + address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); 1.37 + __ call(a, relocInfo::runtime_call_type); 1.38 + __ delayed()->nop(); 1.39 + ce->add_call_info_here(_info); 1.40 + ce->verify_oop_map(_info); 1.41 + debug_only(__ should_not_reach_here()); 1.42 +} 1.43 1.44 void CounterOverflowStub::emit_code(LIR_Assembler* ce) { 1.45 __ bind(_entry); 1.46 @@ -99,10 +120,17 @@ 1.47 1.48 1.49 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) { 1.50 + address a; 1.51 + if (_info->deoptimize_on_exception()) { 1.52 + // Deoptimize, do not throw the exception, because it is probably wrong to do it here. 1.53 + a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); 1.54 + } else { 1.55 + a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id); 1.56 + } 1.57 + 1.58 ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); 1.59 __ bind(_entry); 1.60 - __ call(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id), 1.61 - relocInfo::runtime_call_type); 1.62 + __ call(a, relocInfo::runtime_call_type); 1.63 __ delayed()->nop(); 1.64 ce->add_call_info_here(_info); 1.65 ce->verify_oop_map(_info);
2.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Mar 20 17:04:45 2013 -0700 2.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Mar 21 09:27:54 2013 +0100 2.3 @@ -3361,6 +3361,45 @@ 2.4 __ mov(G2_thread, result_reg->as_register()); 2.5 } 2.6 2.7 +#ifdef ASSERT 2.8 +// emit run-time assertion 2.9 +void LIR_Assembler::emit_assert(LIR_OpAssert* op) { 2.10 + assert(op->code() == lir_assert, "must be"); 2.11 + 2.12 + if (op->in_opr1()->is_valid()) { 2.13 + assert(op->in_opr2()->is_valid(), "both operands must be valid"); 2.14 + comp_op(op->condition(), op->in_opr1(), op->in_opr2(), op); 2.15 + } else { 2.16 + assert(op->in_opr2()->is_illegal(), "both operands must be illegal"); 2.17 + assert(op->condition() == lir_cond_always, "no other conditions allowed"); 2.18 + } 2.19 + 2.20 + Label ok; 2.21 + if (op->condition() != lir_cond_always) { 2.22 + Assembler::Condition acond; 2.23 + switch (op->condition()) { 2.24 + case lir_cond_equal: acond = Assembler::equal; break; 2.25 + case lir_cond_notEqual: acond = Assembler::notEqual; break; 2.26 + case lir_cond_less: acond = Assembler::less; break; 2.27 + case lir_cond_lessEqual: acond = Assembler::lessEqual; break; 2.28 + case lir_cond_greaterEqual: acond = Assembler::greaterEqual; break; 2.29 + case lir_cond_greater: acond = Assembler::greater; break; 2.30 + case lir_cond_aboveEqual: acond = Assembler::greaterEqualUnsigned; break; 2.31 + case lir_cond_belowEqual: acond = Assembler::lessEqualUnsigned; break; 2.32 + default: ShouldNotReachHere(); 2.33 + }; 2.34 + __ br(acond, false, Assembler::pt, ok); 2.35 + __ delayed()->nop(); 2.36 + } 2.37 + if (op->halt()) { 2.38 + const char* str = __ code_string(op->msg()); 2.39 + __ stop(str); 2.40 + } else { 2.41 + breakpoint(); 2.42 + } 2.43 + __ bind(ok); 2.44 +} 2.45 +#endif 2.46 2.47 void LIR_Assembler::peephole(LIR_List* lir) { 2.48 LIR_OpList* inst = lir->instructions_list();
3.1 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Wed Mar 20 17:04:45 2013 -0700 3.2 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Mar 21 09:27:54 2013 +0100 3.3 @@ -324,7 +324,7 @@ 3.4 3.5 void LIRGenerator::do_StoreIndexed(StoreIndexed* x) { 3.6 assert(x->is_pinned(),""); 3.7 - bool needs_range_check = true; 3.8 + bool needs_range_check = x->compute_needs_range_check(); 3.9 bool use_length = x->length() != NULL; 3.10 bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT; 3.11 bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL || 3.12 @@ -339,12 +339,9 @@ 3.13 array.load_item(); 3.14 index.load_nonconstant(); 3.15 3.16 - if (use_length) { 3.17 - needs_range_check = x->compute_needs_range_check(); 3.18 - if (needs_range_check) { 3.19 - length.set_instruction(x->length()); 3.20 - length.load_item(); 3.21 - } 3.22 + if (use_length && needs_range_check) { 3.23 + length.set_instruction(x->length()); 3.24 + length.load_item(); 3.25 } 3.26 if (needs_store_check) { 3.27 value.load_item();
4.1 --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Wed Mar 20 17:04:45 2013 -0700 4.2 +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Thu Mar 21 09:27:54 2013 +0100 4.3 @@ -987,6 +987,25 @@ 4.4 break; 4.5 #endif // INCLUDE_ALL_GCS 4.6 4.7 + case predicate_failed_trap_id: 4.8 + { 4.9 + __ set_info("predicate_failed_trap", dont_gc_arguments); 4.10 + OopMap* oop_map = save_live_registers(sasm); 4.11 + 4.12 + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap)); 4.13 + 4.14 + oop_maps = new OopMapSet(); 4.15 + oop_maps->add_gc_map(call_offset, oop_map); 4.16 + 4.17 + DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); 4.18 + assert(deopt_blob != NULL, "deoptimization blob must have been created"); 4.19 + restore_live_registers(sasm); 4.20 + __ restore(); 4.21 + __ br(Assembler::always, false, Assembler::pt, deopt_blob->unpack_with_reexecution(), relocInfo::runtime_call_type); 4.22 + __ delayed()->nop(); 4.23 + } 4.24 + break; 4.25 + 4.26 default: 4.27 { __ set_info("unimplemented entry", dont_gc_arguments); 4.28 __ save_frame(0);
5.1 --- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Wed Mar 20 17:04:45 2013 -0700 5.2 +++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Thu Mar 21 09:27:54 2013 +0100 5.3 @@ -101,6 +101,15 @@ 5.4 5.5 void RangeCheckStub::emit_code(LIR_Assembler* ce) { 5.6 __ bind(_entry); 5.7 + if (_info->deoptimize_on_exception()) { 5.8 + address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); 5.9 + __ call(RuntimeAddress(a)); 5.10 + ce->add_call_info_here(_info); 5.11 + ce->verify_oop_map(_info); 5.12 + debug_only(__ should_not_reach_here()); 5.13 + return; 5.14 + } 5.15 + 5.16 // pass the array index on stack because all registers must be preserved 5.17 if (_index->is_cpu_register()) { 5.18 ce->store_parameter(_index->as_register(), 0); 5.19 @@ -115,9 +124,22 @@ 5.20 } 5.21 __ call(RuntimeAddress(Runtime1::entry_for(stub_id))); 5.22 ce->add_call_info_here(_info); 5.23 + ce->verify_oop_map(_info); 5.24 debug_only(__ should_not_reach_here()); 5.25 } 5.26 5.27 +PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) { 5.28 + _info = new CodeEmitInfo(info); 5.29 +} 5.30 + 5.31 +void PredicateFailedStub::emit_code(LIR_Assembler* ce) { 5.32 + __ bind(_entry); 5.33 + address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); 5.34 + __ call(RuntimeAddress(a)); 5.35 + ce->add_call_info_here(_info); 5.36 + ce->verify_oop_map(_info); 5.37 + debug_only(__ should_not_reach_here()); 5.38 +} 5.39 5.40 void DivByZeroStub::emit_code(LIR_Assembler* ce) { 5.41 if (_offset != -1) { 5.42 @@ -414,10 +436,19 @@ 5.43 5.44 5.45 void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) { 5.46 + address a; 5.47 + if (_info->deoptimize_on_exception()) { 5.48 + // Deoptimize, do not throw the exception, because it is probably wrong to do it here. 5.49 + a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id); 5.50 + } else { 5.51 + a = Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id); 5.52 + } 5.53 + 5.54 ce->compilation()->implicit_exception_table()->append(_offset, __ offset()); 5.55 __ bind(_entry); 5.56 - __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id))); 5.57 + __ call(RuntimeAddress(a)); 5.58 ce->add_call_info_here(_info); 5.59 + ce->verify_oop_map(_info); 5.60 debug_only(__ should_not_reach_here()); 5.61 } 5.62
6.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Mar 20 17:04:45 2013 -0700 6.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Mar 21 09:27:54 2013 +0100 6.3 @@ -3755,6 +3755,44 @@ 6.4 } 6.5 } 6.6 6.7 +#ifdef ASSERT 6.8 +// emit run-time assertion 6.9 +void LIR_Assembler::emit_assert(LIR_OpAssert* op) { 6.10 + assert(op->code() == lir_assert, "must be"); 6.11 + 6.12 + if (op->in_opr1()->is_valid()) { 6.13 + assert(op->in_opr2()->is_valid(), "both operands must be valid"); 6.14 + comp_op(op->condition(), op->in_opr1(), op->in_opr2(), op); 6.15 + } else { 6.16 + assert(op->in_opr2()->is_illegal(), "both operands must be illegal"); 6.17 + assert(op->condition() == lir_cond_always, "no other conditions allowed"); 6.18 + } 6.19 + 6.20 + Label ok; 6.21 + if (op->condition() != lir_cond_always) { 6.22 + Assembler::Condition acond = Assembler::zero; 6.23 + switch (op->condition()) { 6.24 + case lir_cond_equal: acond = Assembler::equal; break; 6.25 + case lir_cond_notEqual: acond = Assembler::notEqual; break; 6.26 + case lir_cond_less: acond = Assembler::less; break; 6.27 + case lir_cond_lessEqual: acond = Assembler::lessEqual; break; 6.28 + case lir_cond_greaterEqual: acond = Assembler::greaterEqual;break; 6.29 + case lir_cond_greater: acond = Assembler::greater; break; 6.30 + case lir_cond_belowEqual: acond = Assembler::belowEqual; break; 6.31 + case lir_cond_aboveEqual: acond = Assembler::aboveEqual; break; 6.32 + default: ShouldNotReachHere(); 6.33 + } 6.34 + __ jcc(acond, ok); 6.35 + } 6.36 + if (op->halt()) { 6.37 + const char* str = __ code_string(op->msg()); 6.38 + __ stop(str); 6.39 + } else { 6.40 + breakpoint(); 6.41 + } 6.42 + __ bind(ok); 6.43 +} 6.44 +#endif 6.45 6.46 void LIR_Assembler::membar() { 6.47 // QQQ sparc TSO uses this,
7.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Mar 20 17:04:45 2013 -0700 7.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Mar 21 09:27:54 2013 +0100 7.3 @@ -263,7 +263,7 @@ 7.4 7.5 void LIRGenerator::do_StoreIndexed(StoreIndexed* x) { 7.6 assert(x->is_pinned(),""); 7.7 - bool needs_range_check = true; 7.8 + bool needs_range_check = x->compute_needs_range_check(); 7.9 bool use_length = x->length() != NULL; 7.10 bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT; 7.11 bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL || 7.12 @@ -278,12 +278,10 @@ 7.13 array.load_item(); 7.14 index.load_nonconstant(); 7.15 7.16 - if (use_length) { 7.17 - needs_range_check = x->compute_needs_range_check(); 7.18 - if (needs_range_check) { 7.19 - length.set_instruction(x->length()); 7.20 - length.load_item(); 7.21 - } 7.22 + if (use_length && needs_range_check) { 7.23 + length.set_instruction(x->length()); 7.24 + length.load_item(); 7.25 + 7.26 } 7.27 if (needs_store_check) { 7.28 value.load_item();
8.1 --- a/src/cpu/x86/vm/c1_LinearScan_x86.cpp Wed Mar 20 17:04:45 2013 -0700 8.2 +++ b/src/cpu/x86/vm/c1_LinearScan_x86.cpp Thu Mar 21 09:27:54 2013 +0100 8.3 @@ -675,7 +675,8 @@ 8.4 switch (op2->code()) { 8.5 case lir_cmp: 8.6 case lir_cmp_fd2i: 8.7 - case lir_ucmp_fd2i: { 8.8 + case lir_ucmp_fd2i: 8.9 + case lir_assert: { 8.10 assert(left->is_fpu_register(), "invalid LIR"); 8.11 assert(right->is_fpu_register(), "invalid LIR"); 8.12
9.1 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Mar 20 17:04:45 2013 -0700 9.2 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Mar 21 09:27:54 2013 +0100 9.3 @@ -1807,6 +1807,24 @@ 9.4 break; 9.5 #endif // INCLUDE_ALL_GCS 9.6 9.7 + case predicate_failed_trap_id: 9.8 + { 9.9 + StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments); 9.10 + 9.11 + OopMap* map = save_live_registers(sasm, 1); 9.12 + 9.13 + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap)); 9.14 + oop_maps = new OopMapSet(); 9.15 + oop_maps->add_gc_map(call_offset, map); 9.16 + restore_live_registers(sasm); 9.17 + __ leave(); 9.18 + DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); 9.19 + assert(deopt_blob != NULL, "deoptimization blob must have been created"); 9.20 + 9.21 + __ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution())); 9.22 + } 9.23 + break; 9.24 + 9.25 default: 9.26 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); 9.27 __ movptr(rax, (int)id);
10.1 --- a/src/share/vm/c1/c1_Canonicalizer.cpp Wed Mar 20 17:04:45 2013 -0700 10.2 +++ b/src/share/vm/c1/c1_Canonicalizer.cpp Thu Mar 21 09:27:54 2013 +0100 10.3 @@ -937,4 +937,6 @@ 10.4 void Canonicalizer::do_ProfileCall(ProfileCall* x) {} 10.5 void Canonicalizer::do_ProfileInvoke(ProfileInvoke* x) {} 10.6 void Canonicalizer::do_RuntimeCall(RuntimeCall* x) {} 10.7 +void Canonicalizer::do_RangeCheckPredicate(RangeCheckPredicate* x) {} 10.8 +void Canonicalizer::do_Assert(Assert* x) {} 10.9 void Canonicalizer::do_MemBar(MemBar* x) {}
11.1 --- a/src/share/vm/c1/c1_Canonicalizer.hpp Wed Mar 20 17:04:45 2013 -0700 11.2 +++ b/src/share/vm/c1/c1_Canonicalizer.hpp Thu Mar 21 09:27:54 2013 +0100 11.3 @@ -107,6 +107,8 @@ 11.4 virtual void do_ProfileInvoke (ProfileInvoke* x); 11.5 virtual void do_RuntimeCall (RuntimeCall* x); 11.6 virtual void do_MemBar (MemBar* x); 11.7 + virtual void do_RangeCheckPredicate(RangeCheckPredicate* x); 11.8 + virtual void do_Assert (Assert* x); 11.9 }; 11.10 11.11 #endif // SHARE_VM_C1_C1_CANONICALIZER_HPP
12.1 --- a/src/share/vm/c1/c1_CodeStubs.hpp Wed Mar 20 17:04:45 2013 -0700 12.2 +++ b/src/share/vm/c1/c1_CodeStubs.hpp Thu Mar 21 09:27:54 2013 +0100 12.3 @@ -166,6 +166,22 @@ 12.4 #endif // PRODUCT 12.5 }; 12.6 12.7 +// stub used when predicate fails and deoptimization is needed 12.8 +class PredicateFailedStub: public CodeStub { 12.9 + private: 12.10 + CodeEmitInfo* _info; 12.11 + 12.12 + public: 12.13 + PredicateFailedStub(CodeEmitInfo* info); 12.14 + virtual void emit_code(LIR_Assembler* e); 12.15 + virtual CodeEmitInfo* info() const { return _info; } 12.16 + virtual void visit(LIR_OpVisitState* visitor) { 12.17 + visitor->do_slow_case(_info); 12.18 + } 12.19 +#ifndef PRODUCT 12.20 + virtual void print_name(outputStream* out) const { out->print("PredicateFailedStub"); } 12.21 +#endif // PRODUCT 12.22 +}; 12.23 12.24 class DivByZeroStub: public CodeStub { 12.25 private:
13.1 --- a/src/share/vm/c1/c1_Compilation.cpp Wed Mar 20 17:04:45 2013 -0700 13.2 +++ b/src/share/vm/c1/c1_Compilation.cpp Thu Mar 21 09:27:54 2013 +0100 13.3 @@ -33,13 +33,16 @@ 13.4 #include "c1/c1_ValueStack.hpp" 13.5 #include "code/debugInfoRec.hpp" 13.6 #include "compiler/compileLog.hpp" 13.7 +#include "c1/c1_RangeCheckElimination.hpp" 13.8 13.9 13.10 typedef enum { 13.11 _t_compile, 13.12 _t_setup, 13.13 - _t_optimizeIR, 13.14 _t_buildIR, 13.15 + _t_optimize_blocks, 13.16 + _t_optimize_null_checks, 13.17 + _t_rangeCheckElimination, 13.18 _t_emit_lir, 13.19 _t_linearScan, 13.20 _t_lirGeneration, 13.21 @@ -52,8 +55,10 @@ 13.22 static const char * timer_name[] = { 13.23 "compile", 13.24 "setup", 13.25 - "optimizeIR", 13.26 "buildIR", 13.27 + "optimize_blocks", 13.28 + "optimize_null_checks", 13.29 + "rangeCheckElimination", 13.30 "emit_lir", 13.31 "linearScan", 13.32 "lirGeneration", 13.33 @@ -159,9 +164,9 @@ 13.34 if (UseC1Optimizations) { 13.35 NEEDS_CLEANUP 13.36 // optimization 13.37 - PhaseTraceTime timeit(_t_optimizeIR); 13.38 + PhaseTraceTime timeit(_t_optimize_blocks); 13.39 13.40 - _hir->optimize(); 13.41 + _hir->optimize_blocks(); 13.42 } 13.43 13.44 _hir->verify(); 13.45 @@ -180,13 +185,47 @@ 13.46 _hir->compute_code(); 13.47 13.48 if (UseGlobalValueNumbering) { 13.49 - ResourceMark rm; 13.50 + // No resource mark here! LoopInvariantCodeMotion can allocate ValueStack objects. 13.51 int instructions = Instruction::number_of_instructions(); 13.52 GlobalValueNumbering gvn(_hir); 13.53 assert(instructions == Instruction::number_of_instructions(), 13.54 "shouldn't have created an instructions"); 13.55 } 13.56 13.57 + _hir->verify(); 13.58 + 13.59 +#ifndef PRODUCT 13.60 + if (PrintCFGToFile) { 13.61 + CFGPrinter::print_cfg(_hir, "Before RangeCheckElimination", true, false); 13.62 + } 13.63 +#endif 13.64 + 13.65 + if (RangeCheckElimination) { 13.66 + if (_hir->osr_entry() == NULL) { 13.67 + PhaseTraceTime timeit(_t_rangeCheckElimination); 13.68 + RangeCheckElimination::eliminate(_hir); 13.69 + } 13.70 + } 13.71 + 13.72 +#ifndef PRODUCT 13.73 + if (PrintCFGToFile) { 13.74 + CFGPrinter::print_cfg(_hir, "After RangeCheckElimination", true, false); 13.75 + } 13.76 +#endif 13.77 + 13.78 + if (UseC1Optimizations) { 13.79 + // loop invariant code motion reorders instructions and range 13.80 + // check elimination adds new instructions so do null check 13.81 + // elimination after. 13.82 + NEEDS_CLEANUP 13.83 + // optimization 13.84 + PhaseTraceTime timeit(_t_optimize_null_checks); 13.85 + 13.86 + _hir->eliminate_null_checks(); 13.87 + } 13.88 + 13.89 + _hir->verify(); 13.90 + 13.91 // compute use counts after global value numbering 13.92 _hir->compute_use_counts(); 13.93 13.94 @@ -502,6 +541,7 @@ 13.95 , _next_id(0) 13.96 , _next_block_id(0) 13.97 , _code(buffer_blob) 13.98 +, _has_access_indexed(false) 13.99 , _current_instruction(NULL) 13.100 #ifndef PRODUCT 13.101 , _last_instruction_printed(NULL) 13.102 @@ -567,7 +607,9 @@ 13.103 tty->print_cr(" Detailed C1 Timings"); 13.104 tty->print_cr(" Setup time: %6.3f s (%4.1f%%)", timers[_t_setup].seconds(), (timers[_t_setup].seconds() / total) * 100.0); 13.105 tty->print_cr(" Build IR: %6.3f s (%4.1f%%)", timers[_t_buildIR].seconds(), (timers[_t_buildIR].seconds() / total) * 100.0); 13.106 - tty->print_cr(" Optimize: %6.3f s (%4.1f%%)", timers[_t_optimizeIR].seconds(), (timers[_t_optimizeIR].seconds() / total) * 100.0); 13.107 + float t_optimizeIR = timers[_t_optimize_blocks].seconds() + timers[_t_optimize_null_checks].seconds(); 13.108 + tty->print_cr(" Optimize: %6.3f s (%4.1f%%)", t_optimizeIR, (t_optimizeIR / total) * 100.0); 13.109 + tty->print_cr(" RCE: %6.3f s (%4.1f%%)", timers[_t_rangeCheckElimination].seconds(), (timers[_t_rangeCheckElimination].seconds() / total) * 100.0); 13.110 tty->print_cr(" Emit LIR: %6.3f s (%4.1f%%)", timers[_t_emit_lir].seconds(), (timers[_t_emit_lir].seconds() / total) * 100.0); 13.111 tty->print_cr(" LIR Gen: %6.3f s (%4.1f%%)", timers[_t_lirGeneration].seconds(), (timers[_t_lirGeneration].seconds() / total) * 100.0); 13.112 tty->print_cr(" Linear Scan: %6.3f s (%4.1f%%)", timers[_t_linearScan].seconds(), (timers[_t_linearScan].seconds() / total) * 100.0);
14.1 --- a/src/share/vm/c1/c1_Compilation.hpp Wed Mar 20 17:04:45 2013 -0700 14.2 +++ b/src/share/vm/c1/c1_Compilation.hpp Thu Mar 21 09:27:54 2013 +0100 14.3 @@ -26,8 +26,10 @@ 14.4 #define SHARE_VM_C1_C1_COMPILATION_HPP 14.5 14.6 #include "ci/ciEnv.hpp" 14.7 +#include "ci/ciMethodData.hpp" 14.8 #include "code/exceptionHandlerTable.hpp" 14.9 #include "memory/resourceArea.hpp" 14.10 +#include "runtime/deoptimization.hpp" 14.11 14.12 class CompilationResourceObj; 14.13 class XHandlers; 14.14 @@ -85,6 +87,7 @@ 14.15 LinearScan* _allocator; 14.16 CodeOffsets _offsets; 14.17 CodeBuffer _code; 14.18 + bool _has_access_indexed; 14.19 14.20 // compilation helpers 14.21 void initialize(); 14.22 @@ -140,6 +143,7 @@ 14.23 C1_MacroAssembler* masm() const { return _masm; } 14.24 CodeOffsets* offsets() { return &_offsets; } 14.25 Arena* arena() { return _arena; } 14.26 + bool has_access_indexed() { return _has_access_indexed; } 14.27 14.28 // Instruction ids 14.29 int get_next_id() { return _next_id++; } 14.30 @@ -154,6 +158,7 @@ 14.31 void set_has_fpu_code(bool f) { _has_fpu_code = f; } 14.32 void set_has_unsafe_access(bool f) { _has_unsafe_access = f; } 14.33 void set_would_profile(bool f) { _would_profile = f; } 14.34 + void set_has_access_indexed(bool f) { _has_access_indexed = f; } 14.35 // Add a set of exception handlers covering the given PC offset 14.36 void add_exception_handlers_for_pco(int pco, XHandlers* exception_handlers); 14.37 // Statistics gathering 14.38 @@ -233,6 +238,14 @@ 14.39 return env()->comp_level() == CompLevel_full_profile && 14.40 C1UpdateMethodData && C1ProfileCheckcasts; 14.41 } 14.42 + 14.43 + // will compilation make optimistic assumptions that might lead to 14.44 + // deoptimization and that the runtime will account for? 14.45 + bool is_optimistic() const { 14.46 + return !TieredCompilation && 14.47 + (RangeCheckElimination || UseLoopInvariantCodeMotion) && 14.48 + method()->method_data()->trap_count(Deoptimization::Reason_none) == 0; 14.49 + } 14.50 }; 14.51 14.52
15.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Wed Mar 20 17:04:45 2013 -0700 15.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Thu Mar 21 09:27:54 2013 +0100 15.3 @@ -947,7 +947,9 @@ 15.4 15.5 15.6 void GraphBuilder::load_indexed(BasicType type) { 15.7 - ValueStack* state_before = copy_state_for_exception(); 15.8 + // In case of in block code motion in range check elimination 15.9 + ValueStack* state_before = copy_state_indexed_access(); 15.10 + compilation()->set_has_access_indexed(true); 15.11 Value index = ipop(); 15.12 Value array = apop(); 15.13 Value length = NULL; 15.14 @@ -961,7 +963,9 @@ 15.15 15.16 15.17 void GraphBuilder::store_indexed(BasicType type) { 15.18 - ValueStack* state_before = copy_state_for_exception(); 15.19 + // In case of in block code motion in range check elimination 15.20 + ValueStack* state_before = copy_state_indexed_access(); 15.21 + compilation()->set_has_access_indexed(true); 15.22 Value value = pop(as_ValueType(type)); 15.23 Value index = ipop(); 15.24 Value array = apop(); 15.25 @@ -1179,7 +1183,9 @@ 15.26 BlockBegin* tsux = block_at(stream()->get_dest()); 15.27 BlockBegin* fsux = block_at(stream()->next_bci()); 15.28 bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci(); 15.29 - Instruction *i = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb)); 15.30 + // In case of loop invariant code motion or predicate insertion 15.31 + // before the body of a loop the state is needed 15.32 + Instruction *i = append(new If(x, cond, false, y, tsux, fsux, (is_bb || compilation()->is_optimistic()) ? state_before : NULL, is_bb)); 15.33 15.34 assert(i->as_Goto() == NULL || 15.35 (i->as_Goto()->sux_at(0) == tsux && i->as_Goto()->is_safepoint() == tsux->bci() < stream()->cur_bci()) || 15.36 @@ -1294,7 +1300,9 @@ 15.37 BlockBegin* tsux = block_at(bci() + sw.dest_offset_at(0)); 15.38 BlockBegin* fsux = block_at(bci() + sw.default_offset()); 15.39 bool is_bb = tsux->bci() < bci() || fsux->bci() < bci(); 15.40 - ValueStack* state_before = is_bb ? copy_state_before() : NULL; 15.41 + // In case of loop invariant code motion or predicate insertion 15.42 + // before the body of a loop the state is needed 15.43 + ValueStack* state_before = copy_state_if_bb(is_bb); 15.44 append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb)); 15.45 } else { 15.46 // collect successors 15.47 @@ -1308,7 +1316,9 @@ 15.48 // add default successor 15.49 if (sw.default_offset() < 0) has_bb = true; 15.50 sux->at_put(i, block_at(bci() + sw.default_offset())); 15.51 - ValueStack* state_before = has_bb ? copy_state_before() : NULL; 15.52 + // In case of loop invariant code motion or predicate insertion 15.53 + // before the body of a loop the state is needed 15.54 + ValueStack* state_before = copy_state_if_bb(has_bb); 15.55 Instruction* res = append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb)); 15.56 #ifdef ASSERT 15.57 if (res->as_Goto()) { 15.58 @@ -1336,7 +1346,9 @@ 15.59 BlockBegin* tsux = block_at(bci() + pair.offset()); 15.60 BlockBegin* fsux = block_at(bci() + sw.default_offset()); 15.61 bool is_bb = tsux->bci() < bci() || fsux->bci() < bci(); 15.62 - ValueStack* state_before = is_bb ? copy_state_before() : NULL; 15.63 + // In case of loop invariant code motion or predicate insertion 15.64 + // before the body of a loop the state is needed 15.65 + ValueStack* state_before = copy_state_if_bb(is_bb);; 15.66 append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb)); 15.67 } else { 15.68 // collect successors & keys 15.69 @@ -1353,7 +1365,9 @@ 15.70 // add default successor 15.71 if (sw.default_offset() < 0) has_bb = true; 15.72 sux->at_put(i, block_at(bci() + sw.default_offset())); 15.73 - ValueStack* state_before = has_bb ? copy_state_before() : NULL; 15.74 + // In case of loop invariant code motion or predicate insertion 15.75 + // before the body of a loop the state is needed 15.76 + ValueStack* state_before = copy_state_if_bb(has_bb); 15.77 Instruction* res = append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb)); 15.78 #ifdef ASSERT 15.79 if (res->as_Goto()) {
16.1 --- a/src/share/vm/c1/c1_GraphBuilder.hpp Wed Mar 20 17:04:45 2013 -0700 16.2 +++ b/src/share/vm/c1/c1_GraphBuilder.hpp Thu Mar 21 09:27:54 2013 +0100 16.3 @@ -301,6 +301,8 @@ 16.4 ValueStack* copy_state_exhandling(); 16.5 ValueStack* copy_state_for_exception_with_bci(int bci); 16.6 ValueStack* copy_state_for_exception(); 16.7 + ValueStack* copy_state_if_bb(bool is_bb) { return (is_bb || compilation()->is_optimistic()) ? copy_state_before() : NULL; } 16.8 + ValueStack* copy_state_indexed_access() { return compilation()->is_optimistic() ? copy_state_before() : copy_state_for_exception(); } 16.9 16.10 // 16.11 // Inlining support
17.1 --- a/src/share/vm/c1/c1_IR.cpp Wed Mar 20 17:04:45 2013 -0700 17.2 +++ b/src/share/vm/c1/c1_IR.cpp Thu Mar 21 09:27:54 2013 +0100 17.3 @@ -182,13 +182,14 @@ 17.4 // Implementation of CodeEmitInfo 17.5 17.6 // Stack must be NON-null 17.7 -CodeEmitInfo::CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers) 17.8 +CodeEmitInfo::CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception) 17.9 : _scope(stack->scope()) 17.10 , _scope_debug_info(NULL) 17.11 , _oop_map(NULL) 17.12 , _stack(stack) 17.13 , _exception_handlers(exception_handlers) 17.14 - , _is_method_handle_invoke(false) { 17.15 + , _is_method_handle_invoke(false) 17.16 + , _deoptimize_on_exception(deoptimize_on_exception) { 17.17 assert(_stack != NULL, "must be non null"); 17.18 } 17.19 17.20 @@ -199,7 +200,8 @@ 17.21 , _scope_debug_info(NULL) 17.22 , _oop_map(NULL) 17.23 , _stack(stack == NULL ? info->_stack : stack) 17.24 - , _is_method_handle_invoke(info->_is_method_handle_invoke) { 17.25 + , _is_method_handle_invoke(info->_is_method_handle_invoke) 17.26 + , _deoptimize_on_exception(info->_deoptimize_on_exception) { 17.27 17.28 // deep copy of exception handlers 17.29 if (info->_exception_handlers != NULL) { 17.30 @@ -239,7 +241,7 @@ 17.31 } 17.32 17.33 17.34 -void IR::optimize() { 17.35 +void IR::optimize_blocks() { 17.36 Optimizer opt(this); 17.37 if (!compilation()->profile_branches()) { 17.38 if (DoCEE) { 17.39 @@ -257,6 +259,10 @@ 17.40 #endif 17.41 } 17.42 } 17.43 +} 17.44 + 17.45 +void IR::eliminate_null_checks() { 17.46 + Optimizer opt(this); 17.47 if (EliminateNullChecks) { 17.48 opt.eliminate_null_checks(); 17.49 #ifndef PRODUCT 17.50 @@ -429,6 +435,7 @@ 17.51 BlockList _loop_end_blocks; // list of all loop end blocks collected during count_edges 17.52 BitMap2D _loop_map; // two-dimensional bit set: a bit is set if a block is contained in a loop 17.53 BlockList _work_list; // temporary list (used in mark_loops and compute_order) 17.54 + BlockList _loop_headers; 17.55 17.56 Compilation* _compilation; 17.57 17.58 @@ -594,6 +601,7 @@ 17.59 TRACE_LINEAR_SCAN(3, tty->print_cr("Block B%d is loop header of loop %d", cur->block_id(), _num_loops)); 17.60 17.61 cur->set_loop_index(_num_loops); 17.62 + _loop_headers.append(cur); 17.63 _num_loops++; 17.64 } 17.65 17.66 @@ -656,6 +664,16 @@ 17.67 // -> this is not a natural loop, so ignore it 17.68 TRACE_LINEAR_SCAN(2, tty->print_cr("Loop %d is non-natural, so it is ignored", i)); 17.69 17.70 + BlockBegin *loop_header = _loop_headers.at(i); 17.71 + assert(loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Must be loop header"); 17.72 + 17.73 + for (int j = 0; j < loop_header->number_of_preds(); j++) { 17.74 + BlockBegin *pred = loop_header->pred_at(j); 17.75 + pred->clear(BlockBegin::linear_scan_loop_end_flag); 17.76 + } 17.77 + 17.78 + loop_header->clear(BlockBegin::linear_scan_loop_header_flag); 17.79 + 17.80 for (int block_id = _max_block_id - 1; block_id >= 0; block_id--) { 17.81 clear_block_in_loop(i, block_id); 17.82 } 17.83 @@ -729,9 +747,20 @@ 17.84 17.85 } else if (!(cur->is_set(BlockBegin::linear_scan_loop_header_flag) && parent->is_set(BlockBegin::linear_scan_loop_end_flag))) { 17.86 TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: computing dominator of B%d: common dominator of B%d and B%d is B%d", cur->block_id(), parent->block_id(), cur->dominator()->block_id(), common_dominator(cur->dominator(), parent)->block_id())); 17.87 - assert(cur->number_of_preds() > 1, ""); 17.88 + // Does not hold for exception blocks 17.89 + assert(cur->number_of_preds() > 1 || cur->is_set(BlockBegin::exception_entry_flag), ""); 17.90 cur->set_dominator(common_dominator(cur->dominator(), parent)); 17.91 } 17.92 + 17.93 + // Additional edge to xhandler of all our successors 17.94 + // range check elimination needs that the state at the end of a 17.95 + // block be valid in every block it dominates so cur must dominate 17.96 + // the exception handlers of its successors. 17.97 + int num_cur_xhandler = cur->number_of_exception_handlers(); 17.98 + for (int j = 0; j < num_cur_xhandler; j++) { 17.99 + BlockBegin* xhandler = cur->exception_handler_at(j); 17.100 + compute_dominator(xhandler, parent); 17.101 + } 17.102 } 17.103 17.104 17.105 @@ -898,7 +927,6 @@ 17.106 num_sux = cur->number_of_exception_handlers(); 17.107 for (i = 0; i < num_sux; i++) { 17.108 BlockBegin* sux = cur->exception_handler_at(i); 17.109 - compute_dominator(sux, cur); 17.110 if (ready_for_processing(sux)) { 17.111 sort_into_work_list(sux); 17.112 } 17.113 @@ -918,8 +946,23 @@ 17.114 17.115 BlockBegin* dominator = block->pred_at(0); 17.116 int num_preds = block->number_of_preds(); 17.117 - for (int i = 1; i < num_preds; i++) { 17.118 - dominator = common_dominator(dominator, block->pred_at(i)); 17.119 + 17.120 + TRACE_LINEAR_SCAN(4, tty->print_cr("DOM: Processing B%d", block->block_id())); 17.121 + 17.122 + for (int j = 0; j < num_preds; j++) { 17.123 + 17.124 + BlockBegin *pred = block->pred_at(j); 17.125 + TRACE_LINEAR_SCAN(4, tty->print_cr(" DOM: Subrocessing B%d", pred->block_id())); 17.126 + 17.127 + if (block->is_set(BlockBegin::exception_entry_flag)) { 17.128 + dominator = common_dominator(dominator, pred); 17.129 + int num_pred_preds = pred->number_of_preds(); 17.130 + for (int k = 0; k < num_pred_preds; k++) { 17.131 + dominator = common_dominator(dominator, pred->pred_at(k)); 17.132 + } 17.133 + } else { 17.134 + dominator = common_dominator(dominator, pred); 17.135 + } 17.136 } 17.137 17.138 if (dominator != block->dominator()) { 17.139 @@ -946,6 +989,21 @@ 17.140 17.141 // check that dominators are correct 17.142 assert(!compute_dominators_iter(), "fix point not reached"); 17.143 + 17.144 + // Add Blocks to dominates-Array 17.145 + int num_blocks = _linear_scan_order->length(); 17.146 + for (int i = 0; i < num_blocks; i++) { 17.147 + BlockBegin* block = _linear_scan_order->at(i); 17.148 + 17.149 + BlockBegin *dom = block->dominator(); 17.150 + if (dom) { 17.151 + assert(dom->dominator_depth() != -1, "Dominator must have been visited before"); 17.152 + dom->dominates()->append(block); 17.153 + block->set_dominator_depth(dom->dominator_depth() + 1); 17.154 + } else { 17.155 + block->set_dominator_depth(0); 17.156 + } 17.157 + } 17.158 } 17.159 17.160 17.161 @@ -1032,7 +1090,7 @@ 17.162 BlockBegin* sux = cur->sux_at(j); 17.163 17.164 assert(sux->linear_scan_number() >= 0 && sux->linear_scan_number() == _linear_scan_order->index_of(sux), "incorrect linear_scan_number"); 17.165 - if (!cur->is_set(BlockBegin::linear_scan_loop_end_flag)) { 17.166 + if (!sux->is_set(BlockBegin::backward_branch_target_flag)) { 17.167 assert(cur->linear_scan_number() < sux->linear_scan_number(), "invalid order"); 17.168 } 17.169 if (cur->loop_depth() == sux->loop_depth()) { 17.170 @@ -1044,7 +1102,7 @@ 17.171 BlockBegin* pred = cur->pred_at(j); 17.172 17.173 assert(pred->linear_scan_number() >= 0 && pred->linear_scan_number() == _linear_scan_order->index_of(pred), "incorrect linear_scan_number"); 17.174 - if (!cur->is_set(BlockBegin::linear_scan_loop_header_flag)) { 17.175 + if (!cur->is_set(BlockBegin::backward_branch_target_flag)) { 17.176 assert(cur->linear_scan_number() > pred->linear_scan_number(), "invalid order"); 17.177 } 17.178 if (cur->loop_depth() == pred->loop_depth()) { 17.179 @@ -1060,7 +1118,8 @@ 17.180 } else { 17.181 assert(cur->dominator() != NULL, "all but first block must have dominator"); 17.182 } 17.183 - assert(cur->number_of_preds() != 1 || cur->dominator() == cur->pred_at(0), "Single predecessor must also be dominator"); 17.184 + // Assertion does not hold for exception handlers 17.185 + assert(cur->number_of_preds() != 1 || cur->dominator() == cur->pred_at(0) || cur->is_set(BlockBegin::exception_entry_flag), "Single predecessor must also be dominator"); 17.186 } 17.187 17.188 // check that all loops are continuous 17.189 @@ -1249,9 +1308,22 @@ 17.190 } 17.191 }; 17.192 17.193 +class VerifyBlockBeginField : public BlockClosure { 17.194 + 17.195 +public: 17.196 + 17.197 + virtual void block_do(BlockBegin *block) { 17.198 + for ( Instruction *cur = block; cur != NULL; cur = cur->next()) { 17.199 + assert(cur->block() == block, "Block begin is not correct"); 17.200 + } 17.201 + } 17.202 +}; 17.203 + 17.204 void IR::verify() { 17.205 #ifdef ASSERT 17.206 PredecessorValidator pv(this); 17.207 + VerifyBlockBeginField verifier; 17.208 + this->iterate_postorder(&verifier); 17.209 #endif 17.210 } 17.211
18.1 --- a/src/share/vm/c1/c1_IR.hpp Wed Mar 20 17:04:45 2013 -0700 18.2 +++ b/src/share/vm/c1/c1_IR.hpp Thu Mar 21 09:27:54 2013 +0100 18.3 @@ -254,6 +254,7 @@ 18.4 OopMap* _oop_map; 18.5 ValueStack* _stack; // used by deoptimization (contains also monitors 18.6 bool _is_method_handle_invoke; // true if the associated call site is a MethodHandle call site. 18.7 + bool _deoptimize_on_exception; 18.8 18.9 FrameMap* frame_map() const { return scope()->compilation()->frame_map(); } 18.10 Compilation* compilation() const { return scope()->compilation(); } 18.11 @@ -261,7 +262,7 @@ 18.12 public: 18.13 18.14 // use scope from ValueStack 18.15 - CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers); 18.16 + CodeEmitInfo(ValueStack* stack, XHandlers* exception_handlers, bool deoptimize_on_exception = false); 18.17 18.18 // make a copy 18.19 CodeEmitInfo(CodeEmitInfo* info, ValueStack* stack = NULL); 18.20 @@ -272,6 +273,7 @@ 18.21 IRScope* scope() const { return _scope; } 18.22 XHandlers* exception_handlers() const { return _exception_handlers; } 18.23 ValueStack* stack() const { return _stack; } 18.24 + bool deoptimize_on_exception() const { return _deoptimize_on_exception; } 18.25 18.26 void add_register_oop(LIR_Opr opr); 18.27 void record_debug_info(DebugInformationRecorder* recorder, int pc_offset); 18.28 @@ -309,7 +311,8 @@ 18.29 int max_stack() const { return top_scope()->max_stack(); } // expensive 18.30 18.31 // ir manipulation 18.32 - void optimize(); 18.33 + void optimize_blocks(); 18.34 + void eliminate_null_checks(); 18.35 void compute_predecessors(); 18.36 void split_critical_edges(); 18.37 void compute_code();
19.1 --- a/src/share/vm/c1/c1_Instruction.cpp Wed Mar 20 17:04:45 2013 -0700 19.2 +++ b/src/share/vm/c1/c1_Instruction.cpp Thu Mar 21 09:27:54 2013 +0100 19.3 @@ -34,6 +34,15 @@ 19.4 // Implementation of Instruction 19.5 19.6 19.7 +int Instruction::dominator_depth() { 19.8 + int result = -1; 19.9 + if (block()) { 19.10 + result = block()->dominator_depth(); 19.11 + } 19.12 + assert(result != -1 || this->as_Local(), "Only locals have dominator depth -1"); 19.13 + return result; 19.14 +} 19.15 + 19.16 Instruction::Condition Instruction::mirror(Condition cond) { 19.17 switch (cond) { 19.18 case eql: return eql; 19.19 @@ -42,6 +51,8 @@ 19.20 case leq: return geq; 19.21 case gtr: return lss; 19.22 case geq: return leq; 19.23 + case aeq: return beq; 19.24 + case beq: return aeq; 19.25 } 19.26 ShouldNotReachHere(); 19.27 return eql; 19.28 @@ -56,6 +67,8 @@ 19.29 case leq: return gtr; 19.30 case gtr: return leq; 19.31 case geq: return lss; 19.32 + case aeq: assert(false, "Above equal cannot be negated"); 19.33 + case beq: assert(false, "Below equal cannot be negated"); 19.34 } 19.35 ShouldNotReachHere(); 19.36 return eql; 19.37 @@ -70,10 +83,10 @@ 19.38 } 19.39 } 19.40 19.41 - 19.42 -Instruction* Instruction::prev(BlockBegin* block) { 19.43 +// Prev without need to have BlockBegin 19.44 +Instruction* Instruction::prev() { 19.45 Instruction* p = NULL; 19.46 - Instruction* q = block; 19.47 + Instruction* q = block(); 19.48 while (q != this) { 19.49 assert(q != NULL, "this is not in the block's instruction list"); 19.50 p = q; q = q->next(); 19.51 @@ -122,15 +135,24 @@ 19.52 19.53 // perform constant and interval tests on index value 19.54 bool AccessIndexed::compute_needs_range_check() { 19.55 - Constant* clength = length()->as_Constant(); 19.56 - Constant* cindex = index()->as_Constant(); 19.57 - if (clength && cindex) { 19.58 - IntConstant* l = clength->type()->as_IntConstant(); 19.59 - IntConstant* i = cindex->type()->as_IntConstant(); 19.60 - if (l && i && i->value() < l->value() && i->value() >= 0) { 19.61 - return false; 19.62 + 19.63 + if (length()) { 19.64 + 19.65 + Constant* clength = length()->as_Constant(); 19.66 + Constant* cindex = index()->as_Constant(); 19.67 + if (clength && cindex) { 19.68 + IntConstant* l = clength->type()->as_IntConstant(); 19.69 + IntConstant* i = cindex->type()->as_IntConstant(); 19.70 + if (l && i && i->value() < l->value() && i->value() >= 0) { 19.71 + return false; 19.72 + } 19.73 } 19.74 } 19.75 + 19.76 + if (!this->check_flag(NeedsRangeCheckFlag)) { 19.77 + return false; 19.78 + } 19.79 + 19.80 return true; 19.81 } 19.82 19.83 @@ -631,19 +653,25 @@ 19.84 // of the inserted block, without recomputing the values of the other blocks 19.85 // in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless. 19.86 BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) { 19.87 - BlockBegin* new_sux = new BlockBegin(end()->state()->bci()); 19.88 + int bci = sux->bci(); 19.89 + // critical edge splitting may introduce a goto after a if and array 19.90 + // bound check elimination may insert a predicate between the if and 19.91 + // goto. The bci of the goto can't be the one of the if otherwise 19.92 + // the state and bci are inconsistent and a deoptimization triggered 19.93 + // by the predicate would lead to incorrect execution/a crash. 19.94 + BlockBegin* new_sux = new BlockBegin(bci); 19.95 19.96 // mark this block (special treatment when block order is computed) 19.97 new_sux->set(critical_edge_split_flag); 19.98 19.99 // This goto is not a safepoint. 19.100 Goto* e = new Goto(sux, false); 19.101 - new_sux->set_next(e, end()->state()->bci()); 19.102 + new_sux->set_next(e, bci); 19.103 new_sux->set_end(e); 19.104 // setup states 19.105 ValueStack* s = end()->state(); 19.106 - new_sux->set_state(s->copy()); 19.107 - e->set_state(s->copy()); 19.108 + new_sux->set_state(s->copy(s->kind(), bci)); 19.109 + e->set_state(s->copy(s->kind(), bci)); 19.110 assert(new_sux->state()->locals_size() == s->locals_size(), "local size mismatch!"); 19.111 assert(new_sux->state()->stack_size() == s->stack_size(), "stack size mismatch!"); 19.112 assert(new_sux->state()->locks_size() == s->locks_size(), "locks size mismatch!"); 19.113 @@ -960,15 +988,14 @@ 19.114 BlockList* sux = NULL; 19.115 if (begin != NULL) { 19.116 sux = begin->successors(); 19.117 - } else if (_begin != NULL) { 19.118 + } else if (this->begin() != NULL) { 19.119 // copy our sux list 19.120 - BlockList* sux = new BlockList(_begin->number_of_sux()); 19.121 - for (int i = 0; i < _begin->number_of_sux(); i++) { 19.122 - sux->append(_begin->sux_at(i)); 19.123 + BlockList* sux = new BlockList(this->begin()->number_of_sux()); 19.124 + for (int i = 0; i < this->begin()->number_of_sux(); i++) { 19.125 + sux->append(this->begin()->sux_at(i)); 19.126 } 19.127 } 19.128 _sux = sux; 19.129 - _begin = begin; 19.130 } 19.131 19.132 19.133 @@ -1008,7 +1035,38 @@ 19.134 } 19.135 } 19.136 19.137 +#ifdef ASSERT 19.138 +// Constructor of Assert 19.139 +Assert::Assert(Value x, Condition cond, bool unordered_is_true, Value y) : Instruction(illegalType) 19.140 + , _x(x) 19.141 + , _cond(cond) 19.142 + , _y(y) 19.143 +{ 19.144 + set_flag(UnorderedIsTrueFlag, unordered_is_true); 19.145 + assert(x->type()->tag() == y->type()->tag(), "types must match"); 19.146 + pin(); 19.147 19.148 + stringStream strStream; 19.149 + Compilation::current()->method()->print_name(&strStream); 19.150 + 19.151 + stringStream strStream1; 19.152 + InstructionPrinter ip1(1, &strStream1); 19.153 + ip1.print_instr(x); 19.154 + 19.155 + stringStream strStream2; 19.156 + InstructionPrinter ip2(1, &strStream2); 19.157 + ip2.print_instr(y); 19.158 + 19.159 + stringStream ss; 19.160 + ss.print("Assertion %s %s %s in method %s", strStream1.as_string(), ip2.cond_name(cond), strStream2.as_string(), strStream.as_string()); 19.161 + 19.162 + _message = ss.as_string(); 19.163 +} 19.164 +#endif 19.165 + 19.166 +void RangeCheckPredicate::check_state() { 19.167 + assert(state()->kind() != ValueStack::EmptyExceptionState && state()->kind() != ValueStack::ExceptionState, "will deopt with empty state"); 19.168 +} 19.169 19.170 void ProfileInvoke::state_values_do(ValueVisitor* f) { 19.171 if (state() != NULL) state()->values_do(f);
20.1 --- a/src/share/vm/c1/c1_Instruction.hpp Wed Mar 20 17:04:45 2013 -0700 20.2 +++ b/src/share/vm/c1/c1_Instruction.hpp Thu Mar 21 09:27:54 2013 +0100 20.3 @@ -110,6 +110,8 @@ 20.4 class ProfileInvoke; 20.5 class RuntimeCall; 20.6 class MemBar; 20.7 +class RangeCheckPredicate; 20.8 +class Assert; 20.9 20.10 // A Value is a reference to the instruction creating the value 20.11 typedef Instruction* Value; 20.12 @@ -210,6 +212,10 @@ 20.13 virtual void do_ProfileInvoke (ProfileInvoke* x) = 0; 20.14 virtual void do_RuntimeCall (RuntimeCall* x) = 0; 20.15 virtual void do_MemBar (MemBar* x) = 0; 20.16 + virtual void do_RangeCheckPredicate(RangeCheckPredicate* x) = 0; 20.17 +#ifdef ASSERT 20.18 + virtual void do_Assert (Assert* x) = 0; 20.19 +#endif 20.20 }; 20.21 20.22 20.23 @@ -306,8 +312,9 @@ 20.24 20.25 void update_exception_state(ValueStack* state); 20.26 20.27 - //protected: 20.28 - public: 20.29 + protected: 20.30 + BlockBegin* _block; // Block that contains this instruction 20.31 + 20.32 void set_type(ValueType* type) { 20.33 assert(type != NULL, "type must exist"); 20.34 _type = type; 20.35 @@ -342,6 +349,9 @@ 20.36 ThrowIncompatibleClassChangeErrorFlag, 20.37 ProfileMDOFlag, 20.38 IsLinkedInBlockFlag, 20.39 + NeedsRangeCheckFlag, 20.40 + InWorkListFlag, 20.41 + DeoptimizeOnException, 20.42 InstructionLastFlag 20.43 }; 20.44 20.45 @@ -351,7 +361,7 @@ 20.46 20.47 // 'globally' used condition values 20.48 enum Condition { 20.49 - eql, neq, lss, leq, gtr, geq 20.50 + eql, neq, lss, leq, gtr, geq, aeq, beq 20.51 }; 20.52 20.53 // Instructions may be pinned for many reasons and under certain conditions 20.54 @@ -381,6 +391,7 @@ 20.55 , _pin_state(0) 20.56 , _type(type) 20.57 , _next(NULL) 20.58 + , _block(NULL) 20.59 , _subst(NULL) 20.60 , _flags(0) 20.61 , _operand(LIR_OprFact::illegalOpr) 20.62 @@ -399,11 +410,13 @@ 20.63 int printable_bci() const { assert(has_printable_bci(), "_printable_bci should have been set"); return _printable_bci; } 20.64 void set_printable_bci(int bci) { _printable_bci = bci; } 20.65 #endif 20.66 + int dominator_depth(); 20.67 int use_count() const { return _use_count; } 20.68 int pin_state() const { return _pin_state; } 20.69 bool is_pinned() const { return _pin_state != 0 || PinAllInstructions; } 20.70 ValueType* type() const { return _type; } 20.71 - Instruction* prev(BlockBegin* block); // use carefully, expensive operation 20.72 + BlockBegin *block() const { return _block; } 20.73 + Instruction* prev(); // use carefully, expensive operation 20.74 Instruction* next() const { return _next; } 20.75 bool has_subst() const { return _subst != NULL; } 20.76 Instruction* subst() { return _subst == NULL ? this : _subst->subst(); } 20.77 @@ -432,6 +445,9 @@ 20.78 assert(as_BlockEnd() == NULL, "BlockEnd instructions must have no next"); 20.79 assert(next->can_be_linked(), "shouldn't link these instructions into list"); 20.80 20.81 + BlockBegin *block = this->block(); 20.82 + next->_block = block; 20.83 + 20.84 next->set_flag(Instruction::IsLinkedInBlockFlag, true); 20.85 _next = next; 20.86 return next; 20.87 @@ -444,6 +460,29 @@ 20.88 return set_next(next); 20.89 } 20.90 20.91 + // when blocks are merged 20.92 + void fixup_block_pointers() { 20.93 + Instruction *cur = next()->next(); // next()'s block is set in set_next 20.94 + while (cur && cur->_block != block()) { 20.95 + cur->_block = block(); 20.96 + cur = cur->next(); 20.97 + } 20.98 + } 20.99 + 20.100 + Instruction *insert_after(Instruction *i) { 20.101 + Instruction* n = _next; 20.102 + set_next(i); 20.103 + i->set_next(n); 20.104 + return _next; 20.105 + } 20.106 + 20.107 + Instruction *insert_after_same_bci(Instruction *i) { 20.108 +#ifndef PRODUCT 20.109 + i->set_printable_bci(printable_bci()); 20.110 +#endif 20.111 + return insert_after(i); 20.112 + } 20.113 + 20.114 void set_subst(Instruction* subst) { 20.115 assert(subst == NULL || 20.116 type()->base() == subst->type()->base() || 20.117 @@ -452,6 +491,7 @@ 20.118 } 20.119 void set_exception_handlers(XHandlers *xhandlers) { _exception_handlers = xhandlers; } 20.120 void set_exception_state(ValueStack* s) { check_state(s); _exception_state = s; } 20.121 + void set_state_before(ValueStack* s) { check_state(s); _state_before = s; } 20.122 20.123 // machine-specifics 20.124 void set_operand(LIR_Opr operand) { assert(operand != LIR_OprFact::illegalOpr, "operand must exist"); _operand = operand; } 20.125 @@ -509,6 +549,11 @@ 20.126 virtual ExceptionObject* as_ExceptionObject() { return NULL; } 20.127 virtual UnsafeOp* as_UnsafeOp() { return NULL; } 20.128 virtual ProfileInvoke* as_ProfileInvoke() { return NULL; } 20.129 + virtual RangeCheckPredicate* as_RangeCheckPredicate() { return NULL; } 20.130 + 20.131 +#ifdef ASSERT 20.132 + virtual Assert* as_Assert() { return NULL; } 20.133 +#endif 20.134 20.135 virtual void visit(InstructionVisitor* v) = 0; 20.136 20.137 @@ -570,7 +615,6 @@ 20.138 20.139 LEAF(Phi, Instruction) 20.140 private: 20.141 - BlockBegin* _block; // the block to which the phi function belongs 20.142 int _pf_flags; // the flags of the phi function 20.143 int _index; // to value on operand stack (index < 0) or to local 20.144 public: 20.145 @@ -578,9 +622,9 @@ 20.146 Phi(ValueType* type, BlockBegin* b, int index) 20.147 : Instruction(type->base()) 20.148 , _pf_flags(0) 20.149 - , _block(b) 20.150 , _index(index) 20.151 { 20.152 + _block = b; 20.153 NOT_PRODUCT(set_printable_bci(Value(b)->printable_bci())); 20.154 if (type->is_illegal()) { 20.155 make_illegal(); 20.156 @@ -603,8 +647,6 @@ 20.157 Value operand_at(int i) const; 20.158 int operand_count() const; 20.159 20.160 - BlockBegin* block() const { return _block; } 20.161 - 20.162 void set(Flag f) { _pf_flags |= f; } 20.163 void clear(Flag f) { _pf_flags &= ~f; } 20.164 bool is_set(Flag f) const { return (_pf_flags & f) != 0; } 20.165 @@ -670,6 +712,7 @@ 20.166 pin(); 20.167 } 20.168 20.169 + // generic 20.170 virtual bool can_trap() const { return state_before() != NULL; } 20.171 virtual void input_values_do(ValueVisitor* f) { /* no values */ } 20.172 20.173 @@ -852,6 +895,7 @@ 20.174 , _length(length) 20.175 , _elt_type(elt_type) 20.176 { 20.177 + set_flag(Instruction::NeedsRangeCheckFlag, true); 20.178 ASSERT_VALUES 20.179 } 20.180 20.181 @@ -860,6 +904,7 @@ 20.182 Value length() const { return _length; } 20.183 BasicType elt_type() const { return _elt_type; } 20.184 20.185 + void clear_length() { _length = NULL; } 20.186 // perform elimination of range checks involving constants 20.187 bool compute_needs_range_check(); 20.188 20.189 @@ -1524,6 +1569,7 @@ 20.190 int _bci; // start-bci of block 20.191 int _depth_first_number; // number of this block in a depth-first ordering 20.192 int _linear_scan_number; // number of this block in linear-scan ordering 20.193 + int _dominator_depth; 20.194 int _loop_depth; // the loop nesting level of this block 20.195 int _loop_index; // number of the innermost loop of this block 20.196 int _flags; // the flags associated with this block 20.197 @@ -1535,6 +1581,7 @@ 20.198 // SSA specific fields: (factor out later) 20.199 BlockList _successors; // the successors of this block 20.200 BlockList _predecessors; // the predecessors of this block 20.201 + BlockList _dominates; // list of blocks that are dominated by this block 20.202 BlockBegin* _dominator; // the dominator of this block 20.203 // SSA specific ends 20.204 BlockEnd* _end; // the last instruction of this block 20.205 @@ -1583,10 +1630,12 @@ 20.206 , _linear_scan_number(-1) 20.207 , _loop_depth(0) 20.208 , _flags(0) 20.209 + , _dominator_depth(-1) 20.210 , _dominator(NULL) 20.211 , _end(NULL) 20.212 , _predecessors(2) 20.213 , _successors(2) 20.214 + , _dominates(2) 20.215 , _exception_handlers(1) 20.216 , _exception_states(NULL) 20.217 , _exception_handler_pco(-1) 20.218 @@ -1603,6 +1652,7 @@ 20.219 , _total_preds(0) 20.220 , _stores_to_locals() 20.221 { 20.222 + _block = this; 20.223 #ifndef PRODUCT 20.224 set_printable_bci(bci); 20.225 #endif 20.226 @@ -1612,8 +1662,10 @@ 20.227 int block_id() const { return _block_id; } 20.228 int bci() const { return _bci; } 20.229 BlockList* successors() { return &_successors; } 20.230 + BlockList* dominates() { return &_dominates; } 20.231 BlockBegin* dominator() const { return _dominator; } 20.232 int loop_depth() const { return _loop_depth; } 20.233 + int dominator_depth() const { return _dominator_depth; } 20.234 int depth_first_number() const { return _depth_first_number; } 20.235 int linear_scan_number() const { return _linear_scan_number; } 20.236 BlockEnd* end() const { return _end; } 20.237 @@ -1634,6 +1686,7 @@ 20.238 // manipulation 20.239 void set_dominator(BlockBegin* dom) { _dominator = dom; } 20.240 void set_loop_depth(int d) { _loop_depth = d; } 20.241 + void set_dominator_depth(int d) { _dominator_depth = d; } 20.242 void set_depth_first_number(int dfn) { _depth_first_number = dfn; } 20.243 void set_linear_scan_number(int lsn) { _linear_scan_number = lsn; } 20.244 void set_end(BlockEnd* end); 20.245 @@ -1695,7 +1748,8 @@ 20.246 parser_loop_header_flag = 1 << 7, // set by parser to identify blocks where phi functions can not be created on demand 20.247 critical_edge_split_flag = 1 << 8, // set for all blocks that are introduced when critical edges are split 20.248 linear_scan_loop_header_flag = 1 << 9, // set during loop-detection for LinearScan 20.249 - linear_scan_loop_end_flag = 1 << 10 // set during loop-detection for LinearScan 20.250 + linear_scan_loop_end_flag = 1 << 10, // set during loop-detection for LinearScan 20.251 + donot_eliminate_range_checks = 1 << 11 // Should be try to eliminate range checks in this block 20.252 }; 20.253 20.254 void set(Flag f) { _flags |= f; } 20.255 @@ -1728,7 +1782,6 @@ 20.256 20.257 BASE(BlockEnd, StateSplit) 20.258 private: 20.259 - BlockBegin* _begin; 20.260 BlockList* _sux; 20.261 20.262 protected: 20.263 @@ -1746,7 +1799,6 @@ 20.264 // creation 20.265 BlockEnd(ValueType* type, ValueStack* state_before, bool is_safepoint) 20.266 : StateSplit(type, state_before) 20.267 - , _begin(NULL) 20.268 , _sux(NULL) 20.269 { 20.270 set_flag(IsSafepointFlag, is_safepoint); 20.271 @@ -1754,7 +1806,8 @@ 20.272 20.273 // accessors 20.274 bool is_safepoint() const { return check_flag(IsSafepointFlag); } 20.275 - BlockBegin* begin() const { return _begin; } 20.276 + // For compatibility with old code, for new code use block() 20.277 + BlockBegin* begin() const { return _block; } 20.278 20.279 // manipulation 20.280 void set_begin(BlockBegin* begin); 20.281 @@ -1811,6 +1864,74 @@ 20.282 void set_direction(Direction d) { _direction = d; } 20.283 }; 20.284 20.285 +#ifdef ASSERT 20.286 +LEAF(Assert, Instruction) 20.287 + private: 20.288 + Value _x; 20.289 + Condition _cond; 20.290 + Value _y; 20.291 + char *_message; 20.292 + 20.293 + public: 20.294 + // creation 20.295 + // unordered_is_true is valid for float/double compares only 20.296 + Assert(Value x, Condition cond, bool unordered_is_true, Value y); 20.297 + 20.298 + // accessors 20.299 + Value x() const { return _x; } 20.300 + Condition cond() const { return _cond; } 20.301 + bool unordered_is_true() const { return check_flag(UnorderedIsTrueFlag); } 20.302 + Value y() const { return _y; } 20.303 + const char *message() const { return _message; } 20.304 + 20.305 + // generic 20.306 + virtual void input_values_do(ValueVisitor* f) { f->visit(&_x); f->visit(&_y); } 20.307 +}; 20.308 +#endif 20.309 + 20.310 +LEAF(RangeCheckPredicate, StateSplit) 20.311 + private: 20.312 + Value _x; 20.313 + Condition _cond; 20.314 + Value _y; 20.315 + 20.316 + void check_state(); 20.317 + 20.318 + public: 20.319 + // creation 20.320 + // unordered_is_true is valid for float/double compares only 20.321 + RangeCheckPredicate(Value x, Condition cond, bool unordered_is_true, Value y, ValueStack* state) : StateSplit(illegalType) 20.322 + , _x(x) 20.323 + , _cond(cond) 20.324 + , _y(y) 20.325 + { 20.326 + ASSERT_VALUES 20.327 + set_flag(UnorderedIsTrueFlag, unordered_is_true); 20.328 + assert(x->type()->tag() == y->type()->tag(), "types must match"); 20.329 + this->set_state(state); 20.330 + check_state(); 20.331 + } 20.332 + 20.333 + // Always deoptimize 20.334 + RangeCheckPredicate(ValueStack* state) : StateSplit(illegalType) 20.335 + { 20.336 + this->set_state(state); 20.337 + _x = _y = NULL; 20.338 + check_state(); 20.339 + } 20.340 + 20.341 + // accessors 20.342 + Value x() const { return _x; } 20.343 + Condition cond() const { return _cond; } 20.344 + bool unordered_is_true() const { return check_flag(UnorderedIsTrueFlag); } 20.345 + Value y() const { return _y; } 20.346 + 20.347 + void always_fail() { _x = _y = NULL; } 20.348 + 20.349 + // generic 20.350 + virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_x); f->visit(&_y); } 20.351 + HASHING3(RangeCheckPredicate, true, x()->subst(), y()->subst(), cond()) 20.352 +}; 20.353 20.354 LEAF(If, BlockEnd) 20.355 private:
21.1 --- a/src/share/vm/c1/c1_InstructionPrinter.cpp Wed Mar 20 17:04:45 2013 -0700 21.2 +++ b/src/share/vm/c1/c1_InstructionPrinter.cpp Thu Mar 21 09:27:54 2013 +0100 21.3 @@ -57,6 +57,8 @@ 21.4 case If::leq: return "<="; 21.5 case If::gtr: return ">"; 21.6 case If::geq: return ">="; 21.7 + case If::aeq: return "|>=|"; 21.8 + case If::beq: return "|<=|"; 21.9 } 21.10 ShouldNotReachHere(); 21.11 return NULL; 21.12 @@ -181,6 +183,11 @@ 21.13 output()->put('['); 21.14 print_value(indexed->index()); 21.15 output()->put(']'); 21.16 + if (indexed->length() != NULL) { 21.17 + output()->put('('); 21.18 + print_value(indexed->length()); 21.19 + output()->put(')'); 21.20 + } 21.21 } 21.22 21.23 21.24 @@ -373,6 +380,7 @@ 21.25 void InstructionPrinter::do_LoadField(LoadField* x) { 21.26 print_field(x); 21.27 output()->print(" (%c)", type2char(x->field()->type()->basic_type())); 21.28 + output()->print(" %s", x->field()->name()->as_utf8()); 21.29 } 21.30 21.31 21.32 @@ -381,6 +389,7 @@ 21.33 output()->print(" := "); 21.34 print_value(x->value()); 21.35 output()->print(" (%c)", type2char(x->field()->type()->basic_type())); 21.36 + output()->print(" %s", x->field()->name()->as_utf8()); 21.37 } 21.38 21.39 21.40 @@ -393,6 +402,9 @@ 21.41 void InstructionPrinter::do_LoadIndexed(LoadIndexed* x) { 21.42 print_indexed(x); 21.43 output()->print(" (%c)", type2char(x->elt_type())); 21.44 + if (x->check_flag(Instruction::NeedsRangeCheckFlag)) { 21.45 + output()->print(" [rc]"); 21.46 + } 21.47 } 21.48 21.49 21.50 @@ -401,6 +413,9 @@ 21.51 output()->print(" := "); 21.52 print_value(x->value()); 21.53 output()->print(" (%c)", type2char(x->elt_type())); 21.54 + if (x->check_flag(Instruction::NeedsRangeCheckFlag)) { 21.55 + output()->print(" [rc]"); 21.56 + } 21.57 } 21.58 21.59 void InstructionPrinter::do_NegateOp(NegateOp* x) { 21.60 @@ -843,6 +858,25 @@ 21.61 output()->put(')'); 21.62 } 21.63 21.64 +void InstructionPrinter::do_RangeCheckPredicate(RangeCheckPredicate* x) { 21.65 + 21.66 + if (x->x() != NULL && x->y() != NULL) { 21.67 + output()->print("if "); 21.68 + print_value(x->x()); 21.69 + output()->print(" %s ", cond_name(x->cond())); 21.70 + print_value(x->y()); 21.71 + output()->print(" then deoptimize!"); 21.72 + } else { 21.73 + output()->print("always deoptimize!"); 21.74 + } 21.75 +} 21.76 + 21.77 +void InstructionPrinter::do_Assert(Assert* x) { 21.78 + output()->print("assert "); 21.79 + print_value(x->x()); 21.80 + output()->print(" %s ", cond_name(x->cond())); 21.81 + print_value(x->y()); 21.82 +} 21.83 21.84 void InstructionPrinter::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { 21.85 print_unsafe_object_op(x, "UnsafePrefetchWrite");
22.1 --- a/src/share/vm/c1/c1_InstructionPrinter.hpp Wed Mar 20 17:04:45 2013 -0700 22.2 +++ b/src/share/vm/c1/c1_InstructionPrinter.hpp Thu Mar 21 09:27:54 2013 +0100 22.3 @@ -135,6 +135,8 @@ 22.4 virtual void do_ProfileInvoke (ProfileInvoke* x); 22.5 virtual void do_RuntimeCall (RuntimeCall* x); 22.6 virtual void do_MemBar (MemBar* x); 22.7 + virtual void do_RangeCheckPredicate(RangeCheckPredicate* x); 22.8 + virtual void do_Assert (Assert* x); 22.9 }; 22.10 #endif // PRODUCT 22.11
23.1 --- a/src/share/vm/c1/c1_LIR.cpp Wed Mar 20 17:04:45 2013 -0700 23.2 +++ b/src/share/vm/c1/c1_LIR.cpp Thu Mar 21 09:27:54 2013 +0100 23.3 @@ -633,6 +633,7 @@ 23.4 case lir_ushr: 23.5 case lir_xadd: 23.6 case lir_xchg: 23.7 + case lir_assert: 23.8 { 23.9 assert(op->as_Op2() != NULL, "must be"); 23.10 LIR_Op2* op2 = (LIR_Op2*)op; 23.11 @@ -1112,6 +1113,11 @@ 23.12 } 23.13 } 23.14 23.15 +#ifdef ASSERT 23.16 +void LIR_OpAssert::emit_code(LIR_Assembler* masm) { 23.17 + masm->emit_assert(this); 23.18 +} 23.19 +#endif 23.20 23.21 void LIR_OpDelay::emit_code(LIR_Assembler* masm) { 23.22 masm->emit_delay(this); 23.23 @@ -1771,6 +1777,8 @@ 23.24 case lir_cas_int: s = "cas_int"; break; 23.25 // LIR_OpProfileCall 23.26 case lir_profile_call: s = "profile_call"; break; 23.27 + // LIR_OpAssert 23.28 + case lir_assert: s = "assert"; break; 23.29 case lir_none: ShouldNotReachHere();break; 23.30 default: s = "illegal_op"; break; 23.31 } 23.32 @@ -2017,6 +2025,13 @@ 23.33 out->print("[lbl:0x%x]", stub()->entry()); 23.34 } 23.35 23.36 +void LIR_OpAssert::print_instr(outputStream* out) const { 23.37 + print_condition(out, condition()); out->print(" "); 23.38 + in_opr1()->print(out); out->print(" "); 23.39 + in_opr2()->print(out); out->print(", \""); 23.40 + out->print(msg()); out->print("\""); 23.41 +} 23.42 + 23.43 23.44 void LIR_OpDelay::print_instr(outputStream* out) const { 23.45 _op->print_on(out);
24.1 --- a/src/share/vm/c1/c1_LIR.hpp Wed Mar 20 17:04:45 2013 -0700 24.2 +++ b/src/share/vm/c1/c1_LIR.hpp Thu Mar 21 09:27:54 2013 +0100 24.3 @@ -881,6 +881,7 @@ 24.4 class LIR_OpTypeCheck; 24.5 class LIR_OpCompareAndSwap; 24.6 class LIR_OpProfileCall; 24.7 +class LIR_OpAssert; 24.8 24.9 24.10 // LIR operation codes 24.11 @@ -1000,6 +1001,9 @@ 24.12 , begin_opMDOProfile 24.13 , lir_profile_call 24.14 , end_opMDOProfile 24.15 + , begin_opAssert 24.16 + , lir_assert 24.17 + , end_opAssert 24.18 }; 24.19 24.20 24.21 @@ -1135,6 +1139,7 @@ 24.22 virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; } 24.23 virtual LIR_OpCompareAndSwap* as_OpCompareAndSwap() { return NULL; } 24.24 virtual LIR_OpProfileCall* as_OpProfileCall() { return NULL; } 24.25 + virtual LIR_OpAssert* as_OpAssert() { return NULL; } 24.26 24.27 virtual void verify() const {} 24.28 }; 24.29 @@ -1623,7 +1628,7 @@ 24.30 , _tmp3(LIR_OprFact::illegalOpr) 24.31 , _tmp4(LIR_OprFact::illegalOpr) 24.32 , _tmp5(LIR_OprFact::illegalOpr) { 24.33 - assert(code == lir_cmp, "code check"); 24.34 + assert(code == lir_cmp || code == lir_assert, "code check"); 24.35 } 24.36 24.37 LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) 24.38 @@ -1683,7 +1688,7 @@ 24.39 LIR_Opr tmp4_opr() const { return _tmp4; } 24.40 LIR_Opr tmp5_opr() const { return _tmp5; } 24.41 LIR_Condition condition() const { 24.42 - assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove"); return _condition; 24.43 + assert(code() == lir_cmp || code() == lir_cmove || code() == lir_assert, "only valid for cmp and cmove and assert"); return _condition; 24.44 } 24.45 void set_condition(LIR_Condition condition) { 24.46 assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove"); _condition = condition; 24.47 @@ -1823,6 +1828,30 @@ 24.48 CodeEmitInfo* call_info() const { return info(); } 24.49 }; 24.50 24.51 +#ifdef ASSERT 24.52 +// LIR_OpAssert 24.53 +class LIR_OpAssert : public LIR_Op2 { 24.54 + friend class LIR_OpVisitState; 24.55 + 24.56 + private: 24.57 + const char* _msg; 24.58 + bool _halt; 24.59 + 24.60 + public: 24.61 + LIR_OpAssert(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, const char* msg, bool halt) 24.62 + : LIR_Op2(lir_assert, condition, opr1, opr2) 24.63 + , _halt(halt) 24.64 + , _msg(msg) { 24.65 + } 24.66 + 24.67 + const char* msg() const { return _msg; } 24.68 + bool halt() const { return _halt; } 24.69 + 24.70 + virtual void emit_code(LIR_Assembler* masm); 24.71 + virtual LIR_OpAssert* as_OpAssert() { return this; } 24.72 + virtual void print_instr(outputStream* out) const PRODUCT_RETURN; 24.73 +}; 24.74 +#endif 24.75 24.76 // LIR_OpCompareAndSwap 24.77 class LIR_OpCompareAndSwap : public LIR_Op { 24.78 @@ -2196,6 +2225,9 @@ 24.79 24.80 void xadd(LIR_Opr src, LIR_Opr add, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xadd, src, add, res, tmp)); } 24.81 void xchg(LIR_Opr src, LIR_Opr set, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xchg, src, set, res, tmp)); } 24.82 +#ifdef ASSERT 24.83 + void lir_assert(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, const char* msg, bool halt) { append(new LIR_OpAssert(condition, opr1, opr2, msg, halt)); } 24.84 +#endif 24.85 }; 24.86 24.87 void print_LIR(BlockList* blocks);
25.1 --- a/src/share/vm/c1/c1_LIRAssembler.hpp Wed Mar 20 17:04:45 2013 -0700 25.2 +++ b/src/share/vm/c1/c1_LIRAssembler.hpp Thu Mar 21 09:27:54 2013 +0100 25.3 @@ -210,6 +210,9 @@ 25.4 void arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack); 25.5 void arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info); 25.6 void intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op* op); 25.7 +#ifdef ASSERT 25.8 + void emit_assert(LIR_OpAssert* op); 25.9 +#endif 25.10 25.11 void logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest); 25.12
26.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Wed Mar 20 17:04:45 2013 -0700 26.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Thu Mar 21 09:27:54 2013 +0100 26.3 @@ -403,6 +403,10 @@ 26.4 CodeEmitInfo* LIRGenerator::state_for(Instruction* x, ValueStack* state, bool ignore_xhandler) { 26.5 assert(state != NULL, "state must be defined"); 26.6 26.7 +#ifndef PRODUCT 26.8 + state->verify(); 26.9 +#endif 26.10 + 26.11 ValueStack* s = state; 26.12 for_each_state(s) { 26.13 if (s->kind() == ValueStack::EmptyExceptionState) { 26.14 @@ -453,7 +457,7 @@ 26.15 } 26.16 } 26.17 26.18 - return new CodeEmitInfo(state, ignore_xhandler ? NULL : x->exception_handlers()); 26.19 + return new CodeEmitInfo(state, ignore_xhandler ? NULL : x->exception_handlers(), x->check_flag(Instruction::DeoptimizeOnException)); 26.20 } 26.21 26.22 26.23 @@ -1792,11 +1796,18 @@ 26.24 } 26.25 #endif 26.26 26.27 + bool stress_deopt = StressLoopInvariantCodeMotion && info && info->deoptimize_on_exception(); 26.28 if (x->needs_null_check() && 26.29 (needs_patching || 26.30 - MacroAssembler::needs_explicit_null_check(x->offset()))) { 26.31 + MacroAssembler::needs_explicit_null_check(x->offset()) || 26.32 + stress_deopt)) { 26.33 + LIR_Opr obj = object.result(); 26.34 + if (stress_deopt) { 26.35 + obj = new_register(T_OBJECT); 26.36 + __ move(LIR_OprFact::oopConst(NULL), obj); 26.37 + } 26.38 // emit an explicit null check because the offset is too large 26.39 - __ null_check(object.result(), new CodeEmitInfo(info)); 26.40 + __ null_check(obj, new CodeEmitInfo(info)); 26.41 } 26.42 26.43 LIR_Opr reg = rlock_result(x, field_type); 26.44 @@ -1861,6 +1872,8 @@ 26.45 26.46 26.47 void LIRGenerator::do_ArrayLength(ArrayLength* x) { 26.48 + if (x->use_count() == 0 && !x->can_trap()) return; 26.49 + 26.50 LIRItem array(x->array(), this); 26.51 array.load_item(); 26.52 LIR_Opr reg = rlock_result(x); 26.53 @@ -1873,6 +1886,11 @@ 26.54 } else { 26.55 info = state_for(nc); 26.56 } 26.57 + if (StressLoopInvariantCodeMotion && info->deoptimize_on_exception()) { 26.58 + LIR_Opr obj = new_register(T_OBJECT); 26.59 + __ move(LIR_OprFact::oopConst(NULL), obj); 26.60 + __ null_check(obj, new CodeEmitInfo(info)); 26.61 + } 26.62 } 26.63 __ load(new LIR_Address(array.result(), arrayOopDesc::length_offset_in_bytes(), T_INT), reg, info, lir_patch_none); 26.64 } 26.65 @@ -1883,14 +1901,11 @@ 26.66 LIRItem array(x->array(), this); 26.67 LIRItem index(x->index(), this); 26.68 LIRItem length(this); 26.69 - bool needs_range_check = true; 26.70 - 26.71 - if (use_length) { 26.72 - needs_range_check = x->compute_needs_range_check(); 26.73 - if (needs_range_check) { 26.74 - length.set_instruction(x->length()); 26.75 - length.load_item(); 26.76 - } 26.77 + bool needs_range_check = x->compute_needs_range_check(); 26.78 + 26.79 + if (use_length && needs_range_check) { 26.80 + length.set_instruction(x->length()); 26.81 + length.load_item(); 26.82 } 26.83 26.84 array.load_item(); 26.85 @@ -1910,13 +1925,20 @@ 26.86 } else { 26.87 null_check_info = range_check_info; 26.88 } 26.89 + if (StressLoopInvariantCodeMotion && null_check_info->deoptimize_on_exception()) { 26.90 + LIR_Opr obj = new_register(T_OBJECT); 26.91 + __ move(LIR_OprFact::oopConst(NULL), obj); 26.92 + __ null_check(obj, new CodeEmitInfo(null_check_info)); 26.93 + } 26.94 } 26.95 26.96 // emit array address setup early so it schedules better 26.97 LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), false); 26.98 26.99 if (GenerateRangeChecks && needs_range_check) { 26.100 - if (use_length) { 26.101 + if (StressLoopInvariantCodeMotion && range_check_info->deoptimize_on_exception()) { 26.102 + __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result())); 26.103 + } else if (use_length) { 26.104 // TODO: use a (modified) version of array_range_check that does not require a 26.105 // constant length to be loaded to a register 26.106 __ cmp(lir_cond_belowEqual, length.result(), index.result()); 26.107 @@ -2634,7 +2656,7 @@ 26.108 LIR_Opr lock = new_register(T_INT); 26.109 __ load_stack_address_monitor(0, lock); 26.110 26.111 - CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL); 26.112 + CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, x->check_flag(Instruction::DeoptimizeOnException)); 26.113 CodeStub* slow_path = new MonitorEnterStub(obj, lock, info); 26.114 26.115 // receiver is guaranteed non-NULL so don't need CodeEmitInfo 26.116 @@ -2644,7 +2666,7 @@ 26.117 26.118 // increment invocation counters if needed 26.119 if (!method()->is_accessor()) { // Accessors do not have MDOs, so no counting. 26.120 - CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL); 26.121 + CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, false); 26.122 increment_invocation_counter(info); 26.123 } 26.124 26.125 @@ -3102,6 +3124,95 @@ 26.126 } 26.127 } 26.128 26.129 +void LIRGenerator::do_Assert(Assert *x) { 26.130 +#ifdef ASSERT 26.131 + ValueTag tag = x->x()->type()->tag(); 26.132 + If::Condition cond = x->cond(); 26.133 + 26.134 + LIRItem xitem(x->x(), this); 26.135 + LIRItem yitem(x->y(), this); 26.136 + LIRItem* xin = &xitem; 26.137 + LIRItem* yin = &yitem; 26.138 + 26.139 + assert(tag == intTag, "Only integer assertions are valid!"); 26.140 + 26.141 + xin->load_item(); 26.142 + yin->dont_load_item(); 26.143 + 26.144 + set_no_result(x); 26.145 + 26.146 + LIR_Opr left = xin->result(); 26.147 + LIR_Opr right = yin->result(); 26.148 + 26.149 + __ lir_assert(lir_cond(x->cond()), left, right, x->message(), true); 26.150 +#endif 26.151 +} 26.152 + 26.153 + 26.154 +void LIRGenerator::do_RangeCheckPredicate(RangeCheckPredicate *x) { 26.155 + 26.156 + 26.157 + Instruction *a = x->x(); 26.158 + Instruction *b = x->y(); 26.159 + if (!a || StressRangeCheckElimination) { 26.160 + assert(!b || StressRangeCheckElimination, "B must also be null"); 26.161 + 26.162 + CodeEmitInfo *info = state_for(x, x->state()); 26.163 + CodeStub* stub = new PredicateFailedStub(info); 26.164 + 26.165 + __ jump(stub); 26.166 + } else if (a->type()->as_IntConstant() && b->type()->as_IntConstant()) { 26.167 + int a_int = a->type()->as_IntConstant()->value(); 26.168 + int b_int = b->type()->as_IntConstant()->value(); 26.169 + 26.170 + bool ok = false; 26.171 + 26.172 + switch(x->cond()) { 26.173 + case Instruction::eql: ok = (a_int == b_int); break; 26.174 + case Instruction::neq: ok = (a_int != b_int); break; 26.175 + case Instruction::lss: ok = (a_int < b_int); break; 26.176 + case Instruction::leq: ok = (a_int <= b_int); break; 26.177 + case Instruction::gtr: ok = (a_int > b_int); break; 26.178 + case Instruction::geq: ok = (a_int >= b_int); break; 26.179 + case Instruction::aeq: ok = ((unsigned int)a_int >= (unsigned int)b_int); break; 26.180 + case Instruction::beq: ok = ((unsigned int)a_int <= (unsigned int)b_int); break; 26.181 + default: ShouldNotReachHere(); 26.182 + } 26.183 + 26.184 + if (ok) { 26.185 + 26.186 + CodeEmitInfo *info = state_for(x, x->state()); 26.187 + CodeStub* stub = new PredicateFailedStub(info); 26.188 + 26.189 + __ jump(stub); 26.190 + } 26.191 + } else { 26.192 + 26.193 + ValueTag tag = x->x()->type()->tag(); 26.194 + If::Condition cond = x->cond(); 26.195 + LIRItem xitem(x->x(), this); 26.196 + LIRItem yitem(x->y(), this); 26.197 + LIRItem* xin = &xitem; 26.198 + LIRItem* yin = &yitem; 26.199 + 26.200 + assert(tag == intTag, "Only integer deoptimizations are valid!"); 26.201 + 26.202 + xin->load_item(); 26.203 + yin->dont_load_item(); 26.204 + set_no_result(x); 26.205 + 26.206 + LIR_Opr left = xin->result(); 26.207 + LIR_Opr right = yin->result(); 26.208 + 26.209 + CodeEmitInfo *info = state_for(x, x->state()); 26.210 + CodeStub* stub = new PredicateFailedStub(info); 26.211 + 26.212 + __ cmp(lir_cond(cond), left, right); 26.213 + __ branch(lir_cond(cond), right->type(), stub); 26.214 + } 26.215 +} 26.216 + 26.217 + 26.218 LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) { 26.219 LIRItemList args(1); 26.220 LIRItem value(arg1, this);
27.1 --- a/src/share/vm/c1/c1_LIRGenerator.hpp Wed Mar 20 17:04:45 2013 -0700 27.2 +++ b/src/share/vm/c1/c1_LIRGenerator.hpp Thu Mar 21 09:27:54 2013 +0100 27.3 @@ -412,6 +412,8 @@ 27.4 case If::leq: l = lir_cond_lessEqual; break; 27.5 case If::geq: l = lir_cond_greaterEqual; break; 27.6 case If::gtr: l = lir_cond_greater; break; 27.7 + case If::aeq: l = lir_cond_aboveEqual; break; 27.8 + case If::beq: l = lir_cond_belowEqual; break; 27.9 }; 27.10 return l; 27.11 } 27.12 @@ -534,6 +536,8 @@ 27.13 virtual void do_ProfileInvoke (ProfileInvoke* x); 27.14 virtual void do_RuntimeCall (RuntimeCall* x); 27.15 virtual void do_MemBar (MemBar* x); 27.16 + virtual void do_RangeCheckPredicate(RangeCheckPredicate* x); 27.17 + virtual void do_Assert (Assert* x); 27.18 }; 27.19 27.20
28.1 --- a/src/share/vm/c1/c1_LinearScan.cpp Wed Mar 20 17:04:45 2013 -0700 28.2 +++ b/src/share/vm/c1/c1_LinearScan.cpp Thu Mar 21 09:27:54 2013 +0100 28.3 @@ -6231,26 +6231,29 @@ 28.4 assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch"); 28.5 LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op; 28.6 28.7 - LIR_Op2* prev_cmp = NULL; 28.8 - 28.9 - for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) { 28.10 - prev_op = instructions->at(j); 28.11 - if(prev_op->code() == lir_cmp) { 28.12 - assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2"); 28.13 - prev_cmp = (LIR_Op2*)prev_op; 28.14 - assert(prev_branch->cond() == prev_cmp->condition(), "should be the same"); 28.15 + if (prev_branch->stub() == NULL) { 28.16 + 28.17 + LIR_Op2* prev_cmp = NULL; 28.18 + 28.19 + for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) { 28.20 + prev_op = instructions->at(j); 28.21 + if (prev_op->code() == lir_cmp) { 28.22 + assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2"); 28.23 + prev_cmp = (LIR_Op2*)prev_op; 28.24 + assert(prev_branch->cond() == prev_cmp->condition(), "should be the same"); 28.25 + } 28.26 } 28.27 - } 28.28 - assert(prev_cmp != NULL, "should have found comp instruction for branch"); 28.29 - if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) { 28.30 - 28.31 - TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id())); 28.32 - 28.33 - // eliminate a conditional branch to the immediate successor 28.34 - prev_branch->change_block(last_branch->block()); 28.35 - prev_branch->negate_cond(); 28.36 - prev_cmp->set_condition(prev_branch->cond()); 28.37 - instructions->truncate(instructions->length() - 1); 28.38 + assert(prev_cmp != NULL, "should have found comp instruction for branch"); 28.39 + if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) { 28.40 + 28.41 + TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id())); 28.42 + 28.43 + // eliminate a conditional branch to the immediate successor 28.44 + prev_branch->change_block(last_branch->block()); 28.45 + prev_branch->negate_cond(); 28.46 + prev_cmp->set_condition(prev_branch->cond()); 28.47 + instructions->truncate(instructions->length() - 1); 28.48 + } 28.49 } 28.50 } 28.51 }
29.1 --- a/src/share/vm/c1/c1_Optimizer.cpp Wed Mar 20 17:04:45 2013 -0700 29.2 +++ b/src/share/vm/c1/c1_Optimizer.cpp Thu Mar 21 09:27:54 2013 +0100 29.3 @@ -178,7 +178,7 @@ 29.4 // 2) substitute conditional expression 29.5 // with an IfOp followed by a Goto 29.6 // cut if_ away and get node before 29.7 - Instruction* cur_end = if_->prev(block); 29.8 + Instruction* cur_end = if_->prev(); 29.9 29.10 // append constants of true- and false-block if necessary 29.11 // clone constants because original block must not be destroyed 29.12 @@ -202,7 +202,7 @@ 29.13 } 29.14 29.15 // append Goto to successor 29.16 - ValueStack* state_before = if_->is_safepoint() ? if_->state_before() : NULL; 29.17 + ValueStack* state_before = if_->state_before(); 29.18 Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint()); 29.19 29.20 // prepare state for Goto 29.21 @@ -367,10 +367,11 @@ 29.22 #endif 29.23 29.24 // find instruction before end & append first instruction of sux block 29.25 - Instruction* prev = end->prev(block); 29.26 + Instruction* prev = end->prev(); 29.27 Instruction* next = sux->next(); 29.28 assert(prev->as_BlockEnd() == NULL, "must not be a BlockEnd"); 29.29 prev->set_next(next); 29.30 + prev->fixup_block_pointers(); 29.31 sux->disconnect_from_graph(); 29.32 block->set_end(sux->end()); 29.33 // add exception handlers of deleted block, if any 29.34 @@ -533,6 +534,8 @@ 29.35 void do_ProfileInvoke (ProfileInvoke* x); 29.36 void do_RuntimeCall (RuntimeCall* x); 29.37 void do_MemBar (MemBar* x); 29.38 + void do_RangeCheckPredicate(RangeCheckPredicate* x); 29.39 + void do_Assert (Assert* x); 29.40 }; 29.41 29.42 29.43 @@ -714,6 +717,8 @@ 29.44 void NullCheckVisitor::do_ProfileInvoke (ProfileInvoke* x) {} 29.45 void NullCheckVisitor::do_RuntimeCall (RuntimeCall* x) {} 29.46 void NullCheckVisitor::do_MemBar (MemBar* x) {} 29.47 +void NullCheckVisitor::do_RangeCheckPredicate(RangeCheckPredicate* x) {} 29.48 +void NullCheckVisitor::do_Assert (Assert* x) {} 29.49 29.50 29.51 void NullCheckEliminator::visit(Value* p) {
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/src/share/vm/c1/c1_RangeCheckElimination.cpp Thu Mar 21 09:27:54 2013 +0100 30.3 @@ -0,0 +1,1517 @@ 30.4 +/* 30.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.7 + * 30.8 + * This code is free software; you can redistribute it and/or modify it 30.9 + * under the terms of the GNU General Public License version 2 only, as 30.10 + * published by the Free Software Foundation. 30.11 + * 30.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 30.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 30.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 30.15 + * version 2 for more details (a copy is included in the LICENSE file that 30.16 + * accompanied this code). 30.17 + * 30.18 + * You should have received a copy of the GNU General Public License version 30.19 + * 2 along with this work; if not, write to the Free Software Foundation, 30.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 30.21 + * 30.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 30.23 + * or visit www.oracle.com if you need additional information or have any 30.24 + * questions. 30.25 + * 30.26 + */ 30.27 + 30.28 +#include "precompiled.hpp" 30.29 +#include "c1/c1_ValueStack.hpp" 30.30 +#include "c1/c1_RangeCheckElimination.hpp" 30.31 +#include "c1/c1_IR.hpp" 30.32 +#include "c1/c1_Canonicalizer.hpp" 30.33 +#include "c1/c1_ValueMap.hpp" 30.34 +#include "ci/ciMethodData.hpp" 30.35 +#include "runtime/deoptimization.hpp" 30.36 + 30.37 +// Macros for the Trace and the Assertion flag 30.38 +#ifdef ASSERT 30.39 +#define TRACE_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination) { code; } 30.40 +#define ASSERT_RANGE_CHECK_ELIMINATION(code) if (AssertRangeCheckElimination) { code; } 30.41 +#define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code) if (TraceRangeCheckElimination || AssertRangeCheckElimination) { code; } 30.42 +#else 30.43 +#define TRACE_RANGE_CHECK_ELIMINATION(code) 30.44 +#define ASSERT_RANGE_CHECK_ELIMINATION(code) 30.45 +#define TRACE_OR_ASSERT_RANGE_CHECK_ELIMINATION(code) 30.46 +#endif 30.47 + 30.48 +// Entry point for the optimization 30.49 +void RangeCheckElimination::eliminate(IR *ir) { 30.50 + bool do_elimination = ir->compilation()->has_access_indexed(); 30.51 + ASSERT_RANGE_CHECK_ELIMINATION(do_elimination = true); 30.52 + if (do_elimination) { 30.53 + RangeCheckEliminator rce(ir); 30.54 + } 30.55 +} 30.56 + 30.57 +// Constructor 30.58 +RangeCheckEliminator::RangeCheckEliminator(IR *ir) : 30.59 + _bounds(Instruction::number_of_instructions(), NULL), 30.60 + _access_indexed_info(Instruction::number_of_instructions(), NULL) 30.61 +{ 30.62 + _visitor.set_range_check_eliminator(this); 30.63 + _ir = ir; 30.64 + _number_of_instructions = Instruction::number_of_instructions(); 30.65 + _optimistic = ir->compilation()->is_optimistic(); 30.66 + 30.67 + TRACE_RANGE_CHECK_ELIMINATION( 30.68 + tty->print_cr(""); 30.69 + tty->print_cr("Range check elimination"); 30.70 + ir->method()->print_name(tty); 30.71 + tty->print_cr(""); 30.72 + ); 30.73 + 30.74 + TRACE_RANGE_CHECK_ELIMINATION( 30.75 + tty->print_cr("optimistic=%d", (int)_optimistic); 30.76 + ); 30.77 + 30.78 +#ifdef ASSERT 30.79 + // Verifies several conditions that must be true on the IR-input. Only used for debugging purposes. 30.80 + TRACE_RANGE_CHECK_ELIMINATION( 30.81 + tty->print_cr("Verification of IR . . ."); 30.82 + ); 30.83 + Verification verification(ir); 30.84 +#endif 30.85 + 30.86 + // Set process block flags 30.87 + // Optimization so a blocks is only processed if it contains an access indexed instruction or if 30.88 + // one of its children in the dominator tree contains an access indexed instruction. 30.89 + set_process_block_flags(ir->start()); 30.90 + 30.91 + // Pass over instructions in the dominator tree 30.92 + TRACE_RANGE_CHECK_ELIMINATION( 30.93 + tty->print_cr("Starting pass over dominator tree . . .") 30.94 + ); 30.95 + calc_bounds(ir->start(), NULL); 30.96 + 30.97 + TRACE_RANGE_CHECK_ELIMINATION( 30.98 + tty->print_cr("Finished!") 30.99 + ); 30.100 +} 30.101 + 30.102 +// Instruction specific work for some instructions 30.103 +// Constant 30.104 +void RangeCheckEliminator::Visitor::do_Constant(Constant *c) { 30.105 + IntConstant *ic = c->type()->as_IntConstant(); 30.106 + if (ic != NULL) { 30.107 + int value = ic->value(); 30.108 + _bound = new Bound(value, NULL, value, NULL); 30.109 + } 30.110 +} 30.111 + 30.112 +// LogicOp 30.113 +void RangeCheckEliminator::Visitor::do_LogicOp(LogicOp *lo) { 30.114 + if (lo->type()->as_IntType() && lo->op() == Bytecodes::_iand && (lo->x()->as_Constant() || lo->y()->as_Constant())) { 30.115 + int constant = 0; 30.116 + Constant *c = lo->x()->as_Constant(); 30.117 + if (c != NULL) { 30.118 + constant = c->type()->as_IntConstant()->value(); 30.119 + } else { 30.120 + constant = lo->y()->as_Constant()->type()->as_IntConstant()->value(); 30.121 + } 30.122 + if (constant >= 0) { 30.123 + _bound = new Bound(0, NULL, constant, NULL); 30.124 + } 30.125 + } 30.126 +} 30.127 + 30.128 +// Phi 30.129 +void RangeCheckEliminator::Visitor::do_Phi(Phi *phi) { 30.130 + if (!phi->type()->as_IntType() && !phi->type()->as_ObjectType()) return; 30.131 + 30.132 + BlockBegin *block = phi->block(); 30.133 + int op_count = phi->operand_count(); 30.134 + bool has_upper = true; 30.135 + bool has_lower = true; 30.136 + assert(phi, "Phi must not be null"); 30.137 + Bound *bound = NULL; 30.138 + 30.139 + // TODO: support more difficult phis 30.140 + for (int i=0; i<op_count; i++) { 30.141 + Value v = phi->operand_at(i); 30.142 + 30.143 + if (v == phi) continue; 30.144 + 30.145 + // Check if instruction is connected with phi itself 30.146 + Op2 *op2 = v->as_Op2(); 30.147 + if (op2 != NULL) { 30.148 + Value x = op2->x(); 30.149 + Value y = op2->y(); 30.150 + if ((x == phi || y == phi)) { 30.151 + Value other = x; 30.152 + if (other == phi) { 30.153 + other = y; 30.154 + } 30.155 + ArithmeticOp *ao = v->as_ArithmeticOp(); 30.156 + if (ao != NULL && ao->op() == Bytecodes::_iadd) { 30.157 + assert(ao->op() == Bytecodes::_iadd, "Has to be add!"); 30.158 + if (ao->type()->as_IntType()) { 30.159 + Constant *c = other->as_Constant(); 30.160 + if (c != NULL) { 30.161 + assert(c->type()->as_IntConstant(), "Constant has to be of type integer"); 30.162 + int value = c->type()->as_IntConstant()->value(); 30.163 + if (value == 1) { 30.164 + has_upper = false; 30.165 + } else if (value > 1) { 30.166 + // Overflow not guaranteed 30.167 + has_upper = false; 30.168 + has_lower = false; 30.169 + } else if (value < 0) { 30.170 + has_lower = false; 30.171 + } 30.172 + continue; 30.173 + } 30.174 + } 30.175 + } 30.176 + } 30.177 + } 30.178 + 30.179 + // No connection -> new bound 30.180 + Bound *v_bound = _rce->get_bound(v); 30.181 + Bound *cur_bound; 30.182 + int cur_constant = 0; 30.183 + Value cur_value = v; 30.184 + 30.185 + if (v->type()->as_IntConstant()) { 30.186 + cur_constant = v->type()->as_IntConstant()->value(); 30.187 + cur_value = NULL; 30.188 + } 30.189 + if (!v_bound->has_upper() || !v_bound->has_lower()) { 30.190 + cur_bound = new Bound(cur_constant, cur_value, cur_constant, cur_value); 30.191 + } else { 30.192 + cur_bound = v_bound; 30.193 + } 30.194 + if (cur_bound) { 30.195 + if (!bound) { 30.196 + bound = cur_bound->copy(); 30.197 + } else { 30.198 + bound->or_op(cur_bound); 30.199 + } 30.200 + } else { 30.201 + // No bound! 30.202 + bound = NULL; 30.203 + break; 30.204 + } 30.205 + } 30.206 + 30.207 + if (bound) { 30.208 + if (!has_upper) { 30.209 + bound->remove_upper(); 30.210 + } 30.211 + if (!has_lower) { 30.212 + bound->remove_lower(); 30.213 + } 30.214 + _bound = bound; 30.215 + } else { 30.216 + _bound = new Bound(); 30.217 + } 30.218 +} 30.219 + 30.220 + 30.221 +// ArithmeticOp 30.222 +void RangeCheckEliminator::Visitor::do_ArithmeticOp(ArithmeticOp *ao) { 30.223 + Value x = ao->x(); 30.224 + Value y = ao->y(); 30.225 + 30.226 + if (ao->op() == Bytecodes::_irem) { 30.227 + Bound* x_bound = _rce->get_bound(x); 30.228 + Bound* y_bound = _rce->get_bound(y); 30.229 + if (x_bound->lower() >= 0 && x_bound->lower_instr() == NULL && y->as_ArrayLength() != NULL) { 30.230 + _bound = new Bound(0, NULL, -1, y); 30.231 + } else { 30.232 + _bound = new Bound(); 30.233 + } 30.234 + } else if (!x->as_Constant() || !y->as_Constant()) { 30.235 + assert(!x->as_Constant() || !y->as_Constant(), "One of the operands must be non-constant!"); 30.236 + if (((x->as_Constant() || y->as_Constant()) && (ao->op() == Bytecodes::_iadd)) || (y->as_Constant() && ao->op() == Bytecodes::_isub)) { 30.237 + assert(ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub, "Operand must be iadd or isub"); 30.238 + 30.239 + if (y->as_Constant()) { 30.240 + Value tmp = x; 30.241 + x = y; 30.242 + y = tmp; 30.243 + } 30.244 + assert(x->as_Constant()->type()->as_IntConstant(), "Constant must be int constant!"); 30.245 + 30.246 + // Constant now in x 30.247 + int const_value = x->as_Constant()->type()->as_IntConstant()->value(); 30.248 + if (ao->op() == Bytecodes::_iadd || const_value != min_jint) { 30.249 + if (ao->op() == Bytecodes::_isub) { 30.250 + const_value = -const_value; 30.251 + } 30.252 + 30.253 + Bound * bound = _rce->get_bound(y); 30.254 + if (bound->has_upper() && bound->has_lower()) { 30.255 + int new_lower = bound->lower() + const_value; 30.256 + jlong new_lowerl = ((jlong)bound->lower()) + const_value; 30.257 + int new_upper = bound->upper() + const_value; 30.258 + jlong new_upperl = ((jlong)bound->upper()) + const_value; 30.259 + 30.260 + if (((jlong)new_lower) == new_lowerl && ((jlong)new_upper == new_upperl)) { 30.261 + Bound *newBound = new Bound(new_lower, bound->lower_instr(), new_upper, bound->upper_instr()); 30.262 + _bound = newBound; 30.263 + } else { 30.264 + // overflow 30.265 + _bound = new Bound(); 30.266 + } 30.267 + } else { 30.268 + _bound = new Bound(); 30.269 + } 30.270 + } else { 30.271 + _bound = new Bound(); 30.272 + } 30.273 + } else { 30.274 + Bound *bound = _rce->get_bound(x); 30.275 + if (ao->op() == Bytecodes::_isub) { 30.276 + if (bound->lower_instr() == y) { 30.277 + _bound = new Bound(Instruction::geq, NULL, bound->lower()); 30.278 + } else { 30.279 + _bound = new Bound(); 30.280 + } 30.281 + } else { 30.282 + _bound = new Bound(); 30.283 + } 30.284 + } 30.285 + } 30.286 +} 30.287 + 30.288 +// IfOp 30.289 +void RangeCheckEliminator::Visitor::do_IfOp(IfOp *ifOp) 30.290 +{ 30.291 + if (ifOp->tval()->type()->as_IntConstant() && ifOp->fval()->type()->as_IntConstant()) { 30.292 + int min = ifOp->tval()->type()->as_IntConstant()->value(); 30.293 + int max = ifOp->fval()->type()->as_IntConstant()->value(); 30.294 + if (min > max) { 30.295 + // min ^= max ^= min ^= max; 30.296 + int tmp = min; 30.297 + min = max; 30.298 + max = tmp; 30.299 + } 30.300 + _bound = new Bound(min, NULL, max, NULL); 30.301 + } 30.302 +} 30.303 + 30.304 +// Get bound. Returns the current bound on Value v. Normally this is the topmost element on the bound stack. 30.305 +RangeCheckEliminator::Bound *RangeCheckEliminator::get_bound(Value v) { 30.306 + // Wrong type or NULL -> No bound 30.307 + if (!v || (!v->type()->as_IntType() && !v->type()->as_ObjectType())) return NULL; 30.308 + 30.309 + if (!_bounds[v->id()]) { 30.310 + // First (default) bound is calculated 30.311 + // Create BoundStack 30.312 + _bounds[v->id()] = new BoundStack(); 30.313 + _visitor.clear_bound(); 30.314 + Value visit_value = v; 30.315 + visit_value->visit(&_visitor); 30.316 + Bound *bound = _visitor.bound(); 30.317 + if (bound) { 30.318 + _bounds[v->id()]->push(bound); 30.319 + } 30.320 + if (_bounds[v->id()]->length() == 0) { 30.321 + assert(!(v->as_Constant() && v->type()->as_IntConstant()), "constants not handled here"); 30.322 + _bounds[v->id()]->push(new Bound()); 30.323 + } 30.324 + } else if (_bounds[v->id()]->length() == 0) { 30.325 + // To avoid endless loops, bound is currently in calculation -> nothing known about it 30.326 + return new Bound(); 30.327 + } 30.328 + 30.329 + // Return bound 30.330 + return _bounds[v->id()]->top(); 30.331 +} 30.332 + 30.333 +// Update bound 30.334 +void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant) { 30.335 + if (cond == Instruction::gtr) { 30.336 + cond = Instruction::geq; 30.337 + constant++; 30.338 + } else if (cond == Instruction::lss) { 30.339 + cond = Instruction::leq; 30.340 + constant--; 30.341 + } 30.342 + Bound *bound = new Bound(cond, value, constant); 30.343 + update_bound(pushed, v, bound); 30.344 +} 30.345 + 30.346 +// Checks for loop invariance. Returns true if the instruction is outside of the loop which is identified by loop_header. 30.347 +bool RangeCheckEliminator::loop_invariant(BlockBegin *loop_header, Instruction *instruction) { 30.348 + assert(loop_header, "Loop header must not be null!"); 30.349 + if (!instruction) return true; 30.350 + return instruction->dominator_depth() < loop_header->dominator_depth(); 30.351 +} 30.352 + 30.353 +// Update bound. Pushes a new bound onto the stack. Tries to do a conjunction with the current bound. 30.354 +void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Bound *bound) { 30.355 + if (v->as_Constant()) { 30.356 + // No bound update for constants 30.357 + return; 30.358 + } 30.359 + if (!_bounds[v->id()]) { 30.360 + get_bound(v); 30.361 + assert(_bounds[v->id()], "Now Stack must exist"); 30.362 + } 30.363 + Bound *top = NULL; 30.364 + if (_bounds[v->id()]->length() > 0) { 30.365 + top = _bounds[v->id()]->top(); 30.366 + } 30.367 + if (top) { 30.368 + bound->and_op(top); 30.369 + } 30.370 + _bounds[v->id()]->push(bound); 30.371 + pushed.append(v->id()); 30.372 +} 30.373 + 30.374 +// Add instruction + idx for in block motion 30.375 +void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int idx, Value instruction, AccessIndexed *ai) { 30.376 + int id = instruction->id(); 30.377 + AccessIndexedInfo *aii = _access_indexed_info[id]; 30.378 + if (aii == NULL) { 30.379 + aii = new AccessIndexedInfo(); 30.380 + _access_indexed_info[id] = aii; 30.381 + indices.append(instruction); 30.382 + aii->_min = idx; 30.383 + aii->_max = idx; 30.384 + aii->_list = new AccessIndexedList(); 30.385 + } else if (idx >= aii->_min && idx <= aii->_max) { 30.386 + remove_range_check(ai); 30.387 + return; 30.388 + } 30.389 + aii->_min = MIN2(aii->_min, idx); 30.390 + aii->_max = MAX2(aii->_max, idx); 30.391 + aii->_list->append(ai); 30.392 +} 30.393 + 30.394 +// In block motion. Tries to reorder checks in order to reduce some of them. 30.395 +// Example: 30.396 +// a[i] = 0; 30.397 +// a[i+2] = 0; 30.398 +// a[i+1] = 0; 30.399 +// In this example the check for a[i+1] would be considered as unnecessary during the first iteration. 30.400 +// After this i is only checked once for i >= 0 and i+2 < a.length before the first array access. If this 30.401 +// check fails, deoptimization is called. 30.402 +void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList &accessIndexed, InstructionList &arrays) { 30.403 + InstructionList indices; 30.404 + 30.405 + // Now iterate over all arrays 30.406 + for (int i=0; i<arrays.length(); i++) { 30.407 + int max_constant = -1; 30.408 + AccessIndexedList list_constant; 30.409 + Value array = arrays.at(i); 30.410 + 30.411 + // For all AccessIndexed-instructions in this block concerning the current array. 30.412 + for(int j=0; j<accessIndexed.length(); j++) { 30.413 + AccessIndexed *ai = accessIndexed.at(j); 30.414 + if (ai->array() != array || !ai->check_flag(Instruction::NeedsRangeCheckFlag)) continue; 30.415 + 30.416 + Value index = ai->index(); 30.417 + Constant *c = index->as_Constant(); 30.418 + if (c != NULL) { 30.419 + int constant_value = c->type()->as_IntConstant()->value(); 30.420 + if (constant_value >= 0) { 30.421 + if (constant_value <= max_constant) { 30.422 + // No range check needed for this 30.423 + remove_range_check(ai); 30.424 + } else { 30.425 + max_constant = constant_value; 30.426 + list_constant.append(ai); 30.427 + } 30.428 + } 30.429 + } else { 30.430 + int last_integer = 0; 30.431 + Instruction *last_instruction = index; 30.432 + int base = 0; 30.433 + ArithmeticOp *ao = index->as_ArithmeticOp(); 30.434 + 30.435 + while (ao != NULL && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) { 30.436 + c = ao->y()->as_Constant(); 30.437 + Instruction *other = ao->x(); 30.438 + if (!c && ao->op() == Bytecodes::_iadd) { 30.439 + c = ao->x()->as_Constant(); 30.440 + other = ao->y(); 30.441 + } 30.442 + 30.443 + if (c) { 30.444 + int value = c->type()->as_IntConstant()->value(); 30.445 + if (value != min_jint) { 30.446 + if (ao->op() == Bytecodes::_isub) { 30.447 + value = -value; 30.448 + } 30.449 + base += value; 30.450 + last_integer = base; 30.451 + last_instruction = other; 30.452 + } 30.453 + index = other; 30.454 + } else { 30.455 + break; 30.456 + } 30.457 + ao = index->as_ArithmeticOp(); 30.458 + } 30.459 + add_access_indexed_info(indices, last_integer, last_instruction, ai); 30.460 + } 30.461 + } 30.462 + 30.463 + // Iterate over all different indices 30.464 + if (_optimistic) { 30.465 + for (int i=0; i<indices.length(); i++) { 30.466 + Instruction *index_instruction = indices.at(i); 30.467 + AccessIndexedInfo *info = _access_indexed_info[index_instruction->id()]; 30.468 + assert(info != NULL, "Info must not be null"); 30.469 + 30.470 + // if idx < 0, max > 0, max + idx may fall between 0 and 30.471 + // length-1 and if min < 0, min + idx may overflow and be >= 30.472 + // 0. The predicate wouldn't trigger but some accesses could 30.473 + // be with a negative index. This test guarantees that for the 30.474 + // min and max value that are kept the predicate can't let 30.475 + // some incorrect accesses happen. 30.476 + bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min); 30.477 + 30.478 + // Generate code only if more than 2 range checks can be eliminated because of that. 30.479 + // 2 because at least 2 comparisons are done 30.480 + if (info->_list->length() > 2 && range_cond) { 30.481 + AccessIndexed *first = info->_list->at(0); 30.482 + Instruction *insert_position = first->prev(); 30.483 + assert(insert_position->next() == first, "prev was calculated"); 30.484 + ValueStack *state = first->state_before(); 30.485 + 30.486 + // Load min Constant 30.487 + Constant *min_constant = NULL; 30.488 + if (info->_min != 0) { 30.489 + min_constant = new Constant(new IntConstant(info->_min)); 30.490 + NOT_PRODUCT(min_constant->set_printable_bci(first->printable_bci())); 30.491 + insert_position = insert_position->insert_after(min_constant); 30.492 + } 30.493 + 30.494 + // Load max Constant 30.495 + Constant *max_constant = NULL; 30.496 + if (info->_max != 0) { 30.497 + max_constant = new Constant(new IntConstant(info->_max)); 30.498 + NOT_PRODUCT(max_constant->set_printable_bci(first->printable_bci())); 30.499 + insert_position = insert_position->insert_after(max_constant); 30.500 + } 30.501 + 30.502 + // Load array length 30.503 + Value length_instr = first->length(); 30.504 + if (!length_instr) { 30.505 + ArrayLength *length = new ArrayLength(array, first->state_before()->copy()); 30.506 + length->set_exception_state(length->state_before()); 30.507 + length->set_flag(Instruction::DeoptimizeOnException, true); 30.508 + insert_position = insert_position->insert_after_same_bci(length); 30.509 + length_instr = length; 30.510 + } 30.511 + 30.512 + // Calculate lower bound 30.513 + Instruction *lower_compare = index_instruction; 30.514 + if (min_constant) { 30.515 + ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, min_constant, lower_compare, false, NULL); 30.516 + insert_position = insert_position->insert_after_same_bci(ao); 30.517 + lower_compare = ao; 30.518 + } 30.519 + 30.520 + // Calculate upper bound 30.521 + Instruction *upper_compare = index_instruction; 30.522 + if (max_constant) { 30.523 + ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, max_constant, upper_compare, false, NULL); 30.524 + insert_position = insert_position->insert_after_same_bci(ao); 30.525 + upper_compare = ao; 30.526 + } 30.527 + 30.528 + // Trick with unsigned compare is done 30.529 + int bci = NOT_PRODUCT(first->printable_bci()) PRODUCT_ONLY(-1); 30.530 + insert_position = predicate(upper_compare, Instruction::aeq, length_instr, state, insert_position, bci); 30.531 + insert_position = predicate_cmp_with_const(lower_compare, Instruction::leq, -1, state, insert_position); 30.532 + for (int j = 0; j<info->_list->length(); j++) { 30.533 + AccessIndexed *ai = info->_list->at(j); 30.534 + remove_range_check(ai); 30.535 + } 30.536 + } 30.537 + _access_indexed_info[index_instruction->id()] = NULL; 30.538 + } 30.539 + indices.clear(); 30.540 + 30.541 + if (list_constant.length() > 1) { 30.542 + AccessIndexed *first = list_constant.at(0); 30.543 + Instruction *insert_position = first->prev(); 30.544 + ValueStack *state = first->state_before(); 30.545 + // Load max Constant 30.546 + Constant *constant = new Constant(new IntConstant(max_constant)); 30.547 + NOT_PRODUCT(constant->set_printable_bci(first->printable_bci())); 30.548 + insert_position = insert_position->insert_after(constant); 30.549 + Instruction *compare_instr = constant; 30.550 + Value length_instr = first->length(); 30.551 + if (!length_instr) { 30.552 + ArrayLength *length = new ArrayLength(array, state->copy()); 30.553 + length->set_exception_state(length->state_before()); 30.554 + length->set_flag(Instruction::DeoptimizeOnException, true); 30.555 + insert_position = insert_position->insert_after_same_bci(length); 30.556 + length_instr = length; 30.557 + } 30.558 + // Compare for greater or equal to array length 30.559 + insert_position = predicate(compare_instr, Instruction::geq, length_instr, state, insert_position); 30.560 + for (int j = 0; j<list_constant.length(); j++) { 30.561 + AccessIndexed *ai = list_constant.at(j); 30.562 + remove_range_check(ai); 30.563 + } 30.564 + } 30.565 + } 30.566 + } 30.567 +} 30.568 + 30.569 +bool RangeCheckEliminator::set_process_block_flags(BlockBegin *block) { 30.570 + Instruction *cur = block; 30.571 + bool process = false; 30.572 + 30.573 + while (cur) { 30.574 + process |= (cur->as_AccessIndexed() != NULL); 30.575 + cur = cur->next(); 30.576 + } 30.577 + 30.578 + BlockList *dominates = block->dominates(); 30.579 + for (int i=0; i<dominates->length(); i++) { 30.580 + BlockBegin *next = dominates->at(i); 30.581 + process |= set_process_block_flags(next); 30.582 + } 30.583 + 30.584 + if (!process) { 30.585 + block->set(BlockBegin::donot_eliminate_range_checks); 30.586 + } 30.587 + return process; 30.588 +} 30.589 + 30.590 +bool RangeCheckEliminator::is_ok_for_deoptimization(Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper) { 30.591 + bool upper_check = true; 30.592 + assert(lower_instr || lower >= 0, "If no lower_instr present, lower must be greater 0"); 30.593 + assert(!lower_instr || lower_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller"); 30.594 + assert(!upper_instr || upper_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller"); 30.595 + assert(array_instr, "Array instruction must exist"); 30.596 + assert(array_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller"); 30.597 + assert(!length_instr || length_instr->dominator_depth() <= insert_position->dominator_depth(), "Dominator depth must be smaller"); 30.598 + 30.599 + if (upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr) { 30.600 + // static check 30.601 + if (upper >= 0) return false; // would always trigger a deopt: 30.602 + // array_length + x >= array_length, x >= 0 is always true 30.603 + upper_check = false; 30.604 + } 30.605 + if (lower_instr && lower_instr->as_ArrayLength() && lower_instr->as_ArrayLength()->array() == array_instr) { 30.606 + if (lower > 0) return false; 30.607 + } 30.608 + // No upper check required -> skip 30.609 + if (upper_check && upper_instr && upper_instr->type()->as_ObjectType() && upper_instr == array_instr) { 30.610 + // upper_instr is object means that the upper bound is the length 30.611 + // of the upper_instr. 30.612 + return false; 30.613 + } 30.614 + return true; 30.615 +} 30.616 + 30.617 +Instruction* RangeCheckEliminator::insert_after(Instruction* insert_position, Instruction* instr, int bci) { 30.618 + if (bci != -1) { 30.619 + NOT_PRODUCT(instr->set_printable_bci(bci)); 30.620 + return insert_position->insert_after(instr); 30.621 + } else { 30.622 + return insert_position->insert_after_same_bci(instr); 30.623 + } 30.624 +} 30.625 + 30.626 +Instruction* RangeCheckEliminator::predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) { 30.627 + RangeCheckPredicate *deoptimize = new RangeCheckPredicate(left, cond, true, right, state->copy()); 30.628 + return insert_after(insert_position, deoptimize, bci); 30.629 +} 30.630 + 30.631 +Instruction* RangeCheckEliminator::predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) { 30.632 + Constant *const_instr = new Constant(new IntConstant(constant)); 30.633 + insert_position = insert_after(insert_position, const_instr, bci); 30.634 + return predicate(instr, cond, const_instr, state, insert_position); 30.635 +} 30.636 + 30.637 +Instruction* RangeCheckEliminator::predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) { 30.638 + Constant *constant = new Constant(new IntConstant(left_const)); 30.639 + insert_position = insert_after(insert_position, constant, bci); 30.640 + ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, left, false, NULL); 30.641 + insert_position = insert_position->insert_after_same_bci(ao); 30.642 + return predicate(ao, cond, right, state, insert_position); 30.643 +} 30.644 + 30.645 +Instruction* RangeCheckEliminator::predicate_add_cmp_with_const(Instruction* left, int left_const, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci) { 30.646 + Constant *const_instr = new Constant(new IntConstant(constant)); 30.647 + insert_position = insert_after(insert_position, const_instr, bci); 30.648 + return predicate_add(left, left_const, cond, const_instr, state, insert_position); 30.649 +} 30.650 + 30.651 +// Insert deoptimization, returns true if sucessful or false if range check should not be removed 30.652 +void RangeCheckEliminator::insert_deoptimization(ValueStack *state, Instruction *insert_position, Instruction *array_instr, Instruction *length_instr, Instruction *lower_instr, int lower, Instruction *upper_instr, int upper, AccessIndexed *ai) { 30.653 + assert(is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, lower, upper_instr, upper), "should have been tested before"); 30.654 + bool upper_check = !(upper_instr && upper_instr->as_ArrayLength() && upper_instr->as_ArrayLength()->array() == array_instr); 30.655 + 30.656 + int bci = NOT_PRODUCT(ai->printable_bci()) PRODUCT_ONLY(-1); 30.657 + if (lower_instr) { 30.658 + assert(!lower_instr->type()->as_ObjectType(), "Must not be object type"); 30.659 + if (lower == 0) { 30.660 + // Compare for less than 0 30.661 + insert_position = predicate_cmp_with_const(lower_instr, Instruction::lss, 0, state, insert_position, bci); 30.662 + } else if (lower > 0) { 30.663 + // Compare for smaller 0 30.664 + insert_position = predicate_add_cmp_with_const(lower_instr, lower, Instruction::lss, 0, state, insert_position, bci); 30.665 + } else { 30.666 + assert(lower < 0, ""); 30.667 + // Add 1 30.668 + lower++; 30.669 + lower = -lower; 30.670 + // Compare for smaller or equal 0 30.671 + insert_position = predicate_cmp_with_const(lower_instr, Instruction::leq, lower, state, insert_position, bci); 30.672 + } 30.673 + } 30.674 + 30.675 + // We need to know length of array 30.676 + if (!length_instr) { 30.677 + // Load length if necessary 30.678 + ArrayLength *length = new ArrayLength(array_instr, state->copy()); 30.679 + NOT_PRODUCT(length->set_printable_bci(ai->printable_bci())); 30.680 + length->set_exception_state(length->state_before()); 30.681 + length->set_flag(Instruction::DeoptimizeOnException, true); 30.682 + insert_position = insert_position->insert_after(length); 30.683 + length_instr = length; 30.684 + } 30.685 + 30.686 + // No upper check required -> skip 30.687 + if (!upper_check) return; 30.688 + 30.689 + if (!upper_instr) { 30.690 + // Compare for geq array.length 30.691 + insert_position = predicate_cmp_with_const(length_instr, Instruction::leq, upper, state, insert_position, bci); 30.692 + } else { 30.693 + if (upper_instr->type()->as_ObjectType()) { 30.694 + assert(state, "must not be null"); 30.695 + assert(upper_instr != array_instr, "should be"); 30.696 + ArrayLength *length = new ArrayLength(upper_instr, state->copy()); 30.697 + NOT_PRODUCT(length->set_printable_bci(ai->printable_bci())); 30.698 + length->set_flag(Instruction::DeoptimizeOnException, true); 30.699 + length->set_exception_state(length->state_before()); 30.700 + insert_position = insert_position->insert_after(length); 30.701 + upper_instr = length; 30.702 + } 30.703 + assert(upper_instr->type()->as_IntType(), "Must not be object type!"); 30.704 + 30.705 + if (upper == 0) { 30.706 + // Compare for geq array.length 30.707 + insert_position = predicate(upper_instr, Instruction::geq, length_instr, state, insert_position, bci); 30.708 + } else if (upper < 0) { 30.709 + // Compare for geq array.length 30.710 + insert_position = predicate_add(upper_instr, upper, Instruction::geq, length_instr, state, insert_position, bci); 30.711 + } else { 30.712 + assert(upper > 0, ""); 30.713 + upper = -upper; 30.714 + // Compare for geq array.length 30.715 + insert_position = predicate_add(length_instr, upper, Instruction::leq, upper_instr, state, insert_position, bci); 30.716 + } 30.717 + } 30.718 +} 30.719 + 30.720 +// Add if condition 30.721 +void RangeCheckEliminator::add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition) { 30.722 + if (y->as_Constant()) return; 30.723 + 30.724 + int const_value = 0; 30.725 + Value instr_value = x; 30.726 + Constant *c = x->as_Constant(); 30.727 + ArithmeticOp *ao = x->as_ArithmeticOp(); 30.728 + 30.729 + if (c != NULL) { 30.730 + const_value = c->type()->as_IntConstant()->value(); 30.731 + instr_value = NULL; 30.732 + } else if (ao != NULL && (!ao->x()->as_Constant() || !ao->y()->as_Constant()) && ((ao->op() == Bytecodes::_isub && ao->y()->as_Constant()) || ao->op() == Bytecodes::_iadd)) { 30.733 + assert(!ao->x()->as_Constant() || !ao->y()->as_Constant(), "At least one operator must be non-constant!"); 30.734 + assert(ao->op() == Bytecodes::_isub || ao->op() == Bytecodes::_iadd, "Operation has to be add or sub!"); 30.735 + c = ao->x()->as_Constant(); 30.736 + if (c != NULL) { 30.737 + const_value = c->type()->as_IntConstant()->value(); 30.738 + instr_value = ao->y(); 30.739 + } else { 30.740 + c = ao->y()->as_Constant(); 30.741 + if (c != NULL) { 30.742 + const_value = c->type()->as_IntConstant()->value(); 30.743 + instr_value = ao->x(); 30.744 + } 30.745 + } 30.746 + if (ao->op() == Bytecodes::_isub) { 30.747 + assert(ao->y()->as_Constant(), "1 - x not supported, only x - 1 is valid!"); 30.748 + if (const_value > min_jint) { 30.749 + const_value = -const_value; 30.750 + } else { 30.751 + const_value = 0; 30.752 + instr_value = x; 30.753 + } 30.754 + } 30.755 + } 30.756 + 30.757 + update_bound(pushed, y, condition, instr_value, const_value); 30.758 +} 30.759 + 30.760 +// Process If 30.761 +void RangeCheckEliminator::process_if(IntegerStack &pushed, BlockBegin *block, If *cond) { 30.762 + // Only if we are direct true / false successor and NOT both ! (even this may occur) 30.763 + if ((cond->tsux() == block || cond->fsux() == block) && cond->tsux() != cond->fsux()) { 30.764 + Instruction::Condition condition = cond->cond(); 30.765 + if (cond->fsux() == block) { 30.766 + condition = Instruction::negate(condition); 30.767 + } 30.768 + Value x = cond->x(); 30.769 + Value y = cond->y(); 30.770 + if (x->type()->as_IntType() && y->type()->as_IntType()) { 30.771 + add_if_condition(pushed, y, x, condition); 30.772 + add_if_condition(pushed, x, y, Instruction::mirror(condition)); 30.773 + } 30.774 + } 30.775 +} 30.776 + 30.777 +// Process access indexed 30.778 +void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai) { 30.779 + TRACE_RANGE_CHECK_ELIMINATION( 30.780 + tty->fill_to(block->dominator_depth()*2) 30.781 + ); 30.782 + TRACE_RANGE_CHECK_ELIMINATION( 30.783 + tty->print_cr("Access indexed: index=%d length=%d", ai->index()->id(), ai->length()->id()) 30.784 + ); 30.785 + 30.786 + if (ai->check_flag(Instruction::NeedsRangeCheckFlag)) { 30.787 + Bound *index_bound = get_bound(ai->index()); 30.788 + if (!index_bound->has_lower() || !index_bound->has_upper()) { 30.789 + TRACE_RANGE_CHECK_ELIMINATION( 30.790 + tty->fill_to(block->dominator_depth()*2); 30.791 + tty->print_cr("Index instruction %d has no lower and/or no upper bound!", ai->index()->id()) 30.792 + ); 30.793 + return; 30.794 + } 30.795 + 30.796 + Bound *array_bound; 30.797 + if (ai->length()) { 30.798 + array_bound = get_bound(ai->length()); 30.799 + } else { 30.800 + array_bound = get_bound(ai->array()); 30.801 + } 30.802 + 30.803 + if (in_array_bound(index_bound, ai->array()) || 30.804 + (index_bound && array_bound && index_bound->is_smaller(array_bound) && !index_bound->lower_instr() && index_bound->lower() >= 0)) { 30.805 + TRACE_RANGE_CHECK_ELIMINATION( 30.806 + tty->fill_to(block->dominator_depth()*2); 30.807 + tty->print_cr("Bounds check for instruction %d in block B%d can be fully eliminated!", ai->id(), ai->block()->block_id()) 30.808 + ); 30.809 + 30.810 + remove_range_check(ai); 30.811 + } else if (_optimistic && loop_header) { 30.812 + assert(ai->array(), "Array must not be null!"); 30.813 + assert(ai->index(), "Index must not be null!"); 30.814 + 30.815 + // Array instruction 30.816 + Instruction *array_instr = ai->array(); 30.817 + if (!loop_invariant(loop_header, array_instr)) { 30.818 + TRACE_RANGE_CHECK_ELIMINATION( 30.819 + tty->fill_to(block->dominator_depth()*2); 30.820 + tty->print_cr("Array %d is not loop invariant to header B%d", ai->array()->id(), loop_header->block_id()) 30.821 + ); 30.822 + return; 30.823 + } 30.824 + 30.825 + // Lower instruction 30.826 + Value index_instr = ai->index(); 30.827 + Value lower_instr = index_bound->lower_instr(); 30.828 + if (!loop_invariant(loop_header, lower_instr)) { 30.829 + TRACE_RANGE_CHECK_ELIMINATION( 30.830 + tty->fill_to(block->dominator_depth()*2); 30.831 + tty->print_cr("Lower instruction %d not loop invariant!", lower_instr->id()) 30.832 + ); 30.833 + return; 30.834 + } 30.835 + if (!lower_instr && index_bound->lower() < 0) { 30.836 + TRACE_RANGE_CHECK_ELIMINATION( 30.837 + tty->fill_to(block->dominator_depth()*2); 30.838 + tty->print_cr("Lower bound smaller than 0 (%d)!", index_bound->lower()) 30.839 + ); 30.840 + return; 30.841 + } 30.842 + 30.843 + // Upper instruction 30.844 + Value upper_instr = index_bound->upper_instr(); 30.845 + if (!loop_invariant(loop_header, upper_instr)) { 30.846 + TRACE_RANGE_CHECK_ELIMINATION( 30.847 + tty->fill_to(block->dominator_depth()*2); 30.848 + tty->print_cr("Upper instruction %d not loop invariant!", upper_instr->id()) 30.849 + ); 30.850 + return; 30.851 + } 30.852 + 30.853 + // Length instruction 30.854 + Value length_instr = ai->length(); 30.855 + if (!loop_invariant(loop_header, length_instr)) { 30.856 + // Generate length instruction yourself! 30.857 + length_instr = NULL; 30.858 + } 30.859 + 30.860 + TRACE_RANGE_CHECK_ELIMINATION( 30.861 + tty->fill_to(block->dominator_depth()*2); 30.862 + tty->print_cr("LOOP INVARIANT access indexed %d found in block B%d!", ai->id(), ai->block()->block_id()) 30.863 + ); 30.864 + 30.865 + BlockBegin *pred_block = loop_header->dominator(); 30.866 + assert(pred_block != NULL, "Every loop header has a dominator!"); 30.867 + BlockEnd *pred_block_end = pred_block->end(); 30.868 + Instruction *insert_position = pred_block_end->prev(); 30.869 + ValueStack *state = pred_block_end->state_before(); 30.870 + if (pred_block_end->as_Goto() && state == NULL) state = pred_block_end->state(); 30.871 + assert(state, "State must not be null"); 30.872 + 30.873 + // Add deoptimization to dominator of loop header 30.874 + TRACE_RANGE_CHECK_ELIMINATION( 30.875 + tty->fill_to(block->dominator_depth()*2); 30.876 + tty->print_cr("Inserting deopt at bci %d in block B%d!", state->bci(), insert_position->block()->block_id()) 30.877 + ); 30.878 + 30.879 + if (!is_ok_for_deoptimization(insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper())) { 30.880 + TRACE_RANGE_CHECK_ELIMINATION( 30.881 + tty->fill_to(block->dominator_depth()*2); 30.882 + tty->print_cr("Could not eliminate because of static analysis!") 30.883 + ); 30.884 + return; 30.885 + } 30.886 + 30.887 + insert_deoptimization(state, insert_position, array_instr, length_instr, lower_instr, index_bound->lower(), upper_instr, index_bound->upper(), ai); 30.888 + 30.889 + // Finally remove the range check! 30.890 + remove_range_check(ai); 30.891 + } 30.892 + } 30.893 +} 30.894 + 30.895 +void RangeCheckEliminator::remove_range_check(AccessIndexed *ai) { 30.896 + ai->set_flag(Instruction::NeedsRangeCheckFlag, false); 30.897 + // no range check, no need for the length instruction anymore 30.898 + ai->clear_length(); 30.899 + 30.900 + TRACE_RANGE_CHECK_ELIMINATION( 30.901 + tty->fill_to(ai->dominator_depth()*2); 30.902 + tty->print_cr("Range check for instruction %d eliminated!", ai->id()); 30.903 + ); 30.904 + 30.905 + ASSERT_RANGE_CHECK_ELIMINATION( 30.906 + Value array_length = ai->length(); 30.907 + if (!array_length) { 30.908 + array_length = ai->array(); 30.909 + assert(array_length->type()->as_ObjectType(), "Has to be object type!"); 30.910 + } 30.911 + int cur_constant = -1; 30.912 + Value cur_value = array_length; 30.913 + if (cur_value->type()->as_IntConstant()) { 30.914 + cur_constant += cur_value->type()->as_IntConstant()->value(); 30.915 + cur_value = NULL; 30.916 + } 30.917 + Bound *new_index_bound = new Bound(0, NULL, cur_constant, cur_value); 30.918 + add_assertions(new_index_bound, ai->index(), ai); 30.919 + ); 30.920 +} 30.921 + 30.922 +// Calculate bounds for instruction in this block and children blocks in the dominator tree 30.923 +void RangeCheckEliminator::calc_bounds(BlockBegin *block, BlockBegin *loop_header) { 30.924 + // Ensures a valid loop_header 30.925 + assert(!loop_header || loop_header->is_set(BlockBegin::linear_scan_loop_header_flag), "Loop header has to be real !"); 30.926 + 30.927 + // Tracing output 30.928 + TRACE_RANGE_CHECK_ELIMINATION( 30.929 + tty->fill_to(block->dominator_depth()*2); 30.930 + tty->print_cr("Block B%d", block->block_id()); 30.931 + ); 30.932 + 30.933 + // Pushed stack for conditions 30.934 + IntegerStack pushed; 30.935 + // Process If 30.936 + BlockBegin *parent = block->dominator(); 30.937 + if (parent != NULL) { 30.938 + If *cond = parent->end()->as_If(); 30.939 + if (cond != NULL) { 30.940 + process_if(pushed, block, cond); 30.941 + } 30.942 + } 30.943 + 30.944 + // Interate over current block 30.945 + InstructionList arrays; 30.946 + AccessIndexedList accessIndexed; 30.947 + Instruction *cur = block; 30.948 + 30.949 + while (cur) { 30.950 + // Ensure cur wasn't inserted during the elimination 30.951 + if (cur->id() < this->_bounds.length()) { 30.952 + // Process only if it is an access indexed instruction 30.953 + AccessIndexed *ai = cur->as_AccessIndexed(); 30.954 + if (ai != NULL) { 30.955 + process_access_indexed(loop_header, block, ai); 30.956 + accessIndexed.append(ai); 30.957 + if (!arrays.contains(ai->array())) { 30.958 + arrays.append(ai->array()); 30.959 + } 30.960 + Bound *b = get_bound(ai->index()); 30.961 + if (!b->lower_instr()) { 30.962 + // Lower bound is constant 30.963 + update_bound(pushed, ai->index(), Instruction::geq, NULL, 0); 30.964 + } 30.965 + if (!b->has_upper()) { 30.966 + if (ai->length() && ai->length()->type()->as_IntConstant()) { 30.967 + int value = ai->length()->type()->as_IntConstant()->value(); 30.968 + update_bound(pushed, ai->index(), Instruction::lss, NULL, value); 30.969 + } else { 30.970 + // Has no upper bound 30.971 + Instruction *instr = ai->length(); 30.972 + if (instr != NULL) instr = ai->array(); 30.973 + update_bound(pushed, ai->index(), Instruction::lss, instr, 0); 30.974 + } 30.975 + } 30.976 + } 30.977 + } 30.978 + cur = cur->next(); 30.979 + } 30.980 + 30.981 + // Output current condition stack 30.982 + TRACE_RANGE_CHECK_ELIMINATION(dump_condition_stack(block)); 30.983 + 30.984 + // Do in block motion of range checks 30.985 + in_block_motion(block, accessIndexed, arrays); 30.986 + 30.987 + // Call all dominated blocks 30.988 + for (int i=0; i<block->dominates()->length(); i++) { 30.989 + BlockBegin *next = block->dominates()->at(i); 30.990 + if (!next->is_set(BlockBegin::donot_eliminate_range_checks)) { 30.991 + // if current block is a loop header and: 30.992 + // - next block belongs to the same loop 30.993 + // or 30.994 + // - next block belongs to an inner loop 30.995 + // then current block is the loop header for next block 30.996 + if (block->is_set(BlockBegin::linear_scan_loop_header_flag) && (block->loop_index() == next->loop_index() || next->loop_depth() > block->loop_depth())) { 30.997 + calc_bounds(next, block); 30.998 + } else { 30.999 + calc_bounds(next, loop_header); 30.1000 + } 30.1001 + } 30.1002 + } 30.1003 + 30.1004 + // Reset stack 30.1005 + for (int i=0; i<pushed.length(); i++) { 30.1006 + _bounds[pushed[i]]->pop(); 30.1007 + } 30.1008 +} 30.1009 + 30.1010 +#ifndef PRODUCT 30.1011 +// Dump condition stack 30.1012 +void RangeCheckEliminator::dump_condition_stack(BlockBegin *block) { 30.1013 + for (int i=0; i<_ir->linear_scan_order()->length(); i++) { 30.1014 + BlockBegin *cur_block = _ir->linear_scan_order()->at(i); 30.1015 + Instruction *instr = cur_block; 30.1016 + for_each_phi_fun(cur_block, phi, 30.1017 + BoundStack *bound_stack = _bounds.at(phi->id()); 30.1018 + if (bound_stack && bound_stack->length() > 0) { 30.1019 + Bound *bound = bound_stack->top(); 30.1020 + if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != phi || bound->upper_instr() != phi || bound->lower() != 0 || bound->upper() != 0)) { 30.1021 + TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth()); 30.1022 + tty->print("i%d", phi->id()); 30.1023 + tty->print(": "); 30.1024 + bound->print(); 30.1025 + tty->print_cr(""); 30.1026 + ); 30.1027 + } 30.1028 + }); 30.1029 + 30.1030 + while (!instr->as_BlockEnd()) { 30.1031 + if (instr->id() < _bounds.length()) { 30.1032 + BoundStack *bound_stack = _bounds.at(instr->id()); 30.1033 + if (bound_stack && bound_stack->length() > 0) { 30.1034 + Bound *bound = bound_stack->top(); 30.1035 + if ((bound->has_lower() || bound->has_upper()) && (bound->lower_instr() != instr || bound->upper_instr() != instr || bound->lower() != 0 || bound->upper() != 0)) { 30.1036 + TRACE_RANGE_CHECK_ELIMINATION(tty->fill_to(2*block->dominator_depth()); 30.1037 + tty->print("i%d", instr->id()); 30.1038 + tty->print(": "); 30.1039 + bound->print(); 30.1040 + tty->print_cr(""); 30.1041 + ); 30.1042 + } 30.1043 + } 30.1044 + } 30.1045 + instr = instr->next(); 30.1046 + } 30.1047 + } 30.1048 +} 30.1049 +#endif 30.1050 + 30.1051 +// Verification or the IR 30.1052 +RangeCheckEliminator::Verification::Verification(IR *ir) : _used(BlockBegin::number_of_blocks(), false) { 30.1053 + this->_ir = ir; 30.1054 + ir->iterate_linear_scan_order(this); 30.1055 +} 30.1056 + 30.1057 +// Verify this block 30.1058 +void RangeCheckEliminator::Verification::block_do(BlockBegin *block) { 30.1059 + If *cond = block->end()->as_If(); 30.1060 + // Watch out: tsux and fsux can be the same! 30.1061 + if (block->number_of_sux() > 1) { 30.1062 + for (int i=0; i<block->number_of_sux(); i++) { 30.1063 + BlockBegin *sux = block->sux_at(i); 30.1064 + BlockBegin *pred = NULL; 30.1065 + for (int j=0; j<sux->number_of_preds(); j++) { 30.1066 + BlockBegin *cur = sux->pred_at(j); 30.1067 + assert(cur != NULL, "Predecessor must not be null"); 30.1068 + if (!pred) { 30.1069 + pred = cur; 30.1070 + } 30.1071 + assert(cur == pred, "Block must not have more than one predecessor if its predecessor has more than one successor"); 30.1072 + } 30.1073 + assert(sux->number_of_preds() >= 1, "Block must have at least one predecessor"); 30.1074 + assert(sux->pred_at(0) == block, "Wrong successor"); 30.1075 + } 30.1076 + } 30.1077 + 30.1078 + BlockBegin *dominator = block->dominator(); 30.1079 + if (dominator) { 30.1080 + assert(block != _ir->start(), "Start block must not have a dominator!"); 30.1081 + assert(can_reach(dominator, block), "Dominator can't reach his block !"); 30.1082 + assert(can_reach(_ir->start(), dominator), "Dominator is unreachable !"); 30.1083 + assert(!can_reach(_ir->start(), block, dominator), "Wrong dominator ! Block can be reached anyway !"); 30.1084 + BlockList *all_blocks = _ir->linear_scan_order(); 30.1085 + for (int i=0; i<all_blocks->length(); i++) { 30.1086 + BlockBegin *cur = all_blocks->at(i); 30.1087 + if (cur != dominator && cur != block) { 30.1088 + assert(can_reach(dominator, block, cur), "There has to be another dominator!"); 30.1089 + } 30.1090 + } 30.1091 + } else { 30.1092 + assert(block == _ir->start(), "Only start block must not have a dominator"); 30.1093 + } 30.1094 + 30.1095 + if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) { 30.1096 + int loop_index = block->loop_index(); 30.1097 + BlockList *all_blocks = _ir->linear_scan_order(); 30.1098 + assert(block->number_of_preds() >= 1, "Block must have at least one predecessor"); 30.1099 + assert(!block->is_set(BlockBegin::exception_entry_flag), "Loop header must not be exception handler!"); 30.1100 + // Sometimes, the backbranch comes from an exception handler. In 30.1101 + // this case, loop indexes/loop depths may not appear correct. 30.1102 + bool loop_through_xhandler = false; 30.1103 + for (int i = 0; i < block->number_of_exception_handlers(); i++) { 30.1104 + BlockBegin *xhandler = block->exception_handler_at(i); 30.1105 + for (int j = 0; j < block->number_of_preds(); j++) { 30.1106 + if (dominates(xhandler, block->pred_at(j)) || xhandler == block->pred_at(j)) { 30.1107 + loop_through_xhandler = true; 30.1108 + } 30.1109 + } 30.1110 + } 30.1111 + 30.1112 + for (int i=0; i<block->number_of_sux(); i++) { 30.1113 + BlockBegin *sux = block->sux_at(i); 30.1114 + assert(sux->loop_depth() != block->loop_depth() || sux->loop_index() == block->loop_index() || loop_through_xhandler, "Loop index has to be same"); 30.1115 + assert(sux->loop_depth() == block->loop_depth() || sux->loop_index() != block->loop_index(), "Loop index has to be different"); 30.1116 + } 30.1117 + 30.1118 + for (int i=0; i<all_blocks->length(); i++) { 30.1119 + BlockBegin *cur = all_blocks->at(i); 30.1120 + if (cur->loop_index() == loop_index && cur != block) { 30.1121 + assert(dominates(block->dominator(), cur), "Dominator of loop header must dominate all loop blocks"); 30.1122 + } 30.1123 + } 30.1124 + } 30.1125 + 30.1126 + Instruction *cur = block; 30.1127 + while (cur) { 30.1128 + assert(cur->block() == block, "Block begin has to be set correctly!"); 30.1129 + cur = cur->next(); 30.1130 + } 30.1131 +} 30.1132 + 30.1133 +// Loop header must dominate all loop blocks 30.1134 +bool RangeCheckEliminator::Verification::dominates(BlockBegin *dominator, BlockBegin *block) { 30.1135 + BlockBegin *cur = block->dominator(); 30.1136 + while (cur && cur != dominator) { 30.1137 + cur = cur->dominator(); 30.1138 + } 30.1139 + return cur == dominator; 30.1140 +} 30.1141 + 30.1142 +// Try to reach Block end beginning in Block start and not using Block dont_use 30.1143 +bool RangeCheckEliminator::Verification::can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use /* = NULL */) { 30.1144 + if (start == end) return start != dont_use; 30.1145 + // Simple BSF from start to end 30.1146 + // BlockBeginList _current; 30.1147 + for (int i=0; i<_used.length(); i++) { 30.1148 + _used[i] = false; 30.1149 + } 30.1150 + _current.truncate(0); 30.1151 + _successors.truncate(0); 30.1152 + if (start != dont_use) { 30.1153 + _current.push(start); 30.1154 + _used[start->block_id()] = true; 30.1155 + } 30.1156 + 30.1157 + // BlockBeginList _successors; 30.1158 + while (_current.length() > 0) { 30.1159 + BlockBegin *cur = _current.pop(); 30.1160 + // Add exception handlers to list 30.1161 + for (int i=0; i<cur->number_of_exception_handlers(); i++) { 30.1162 + BlockBegin *xhandler = cur->exception_handler_at(i); 30.1163 + _successors.push(xhandler); 30.1164 + // Add exception handlers of _successors to list 30.1165 + for (int j=0; j<xhandler->number_of_exception_handlers(); j++) { 30.1166 + BlockBegin *sux_xhandler = xhandler->exception_handler_at(j); 30.1167 + _successors.push(sux_xhandler); 30.1168 + } 30.1169 + } 30.1170 + // Add normal _successors to list 30.1171 + for (int i=0; i<cur->number_of_sux(); i++) { 30.1172 + BlockBegin *sux = cur->sux_at(i); 30.1173 + _successors.push(sux); 30.1174 + // Add exception handlers of _successors to list 30.1175 + for (int j=0; j<sux->number_of_exception_handlers(); j++) { 30.1176 + BlockBegin *xhandler = sux->exception_handler_at(j); 30.1177 + _successors.push(xhandler); 30.1178 + } 30.1179 + } 30.1180 + for (int i=0; i<_successors.length(); i++) { 30.1181 + BlockBegin *sux = _successors[i]; 30.1182 + assert(sux != NULL, "Successor must not be NULL!"); 30.1183 + if (sux == end) { 30.1184 + return true; 30.1185 + } 30.1186 + if (sux != dont_use && !_used[sux->block_id()]) { 30.1187 + _used[sux->block_id()] = true; 30.1188 + _current.push(sux); 30.1189 + } 30.1190 + } 30.1191 + _successors.truncate(0); 30.1192 + } 30.1193 + 30.1194 + return false; 30.1195 +} 30.1196 + 30.1197 +// Bound 30.1198 +RangeCheckEliminator::Bound::~Bound() { 30.1199 +} 30.1200 + 30.1201 +// Bound constructor 30.1202 +RangeCheckEliminator::Bound::Bound() { 30.1203 + init(); 30.1204 + this->_lower = min_jint; 30.1205 + this->_upper = max_jint; 30.1206 + this->_lower_instr = NULL; 30.1207 + this->_upper_instr = NULL; 30.1208 +} 30.1209 + 30.1210 +// Bound constructor 30.1211 +RangeCheckEliminator::Bound::Bound(int lower, Value lower_instr, int upper, Value upper_instr) { 30.1212 + init(); 30.1213 + assert(!lower_instr || !lower_instr->as_Constant() || !lower_instr->type()->as_IntConstant(), "Must not be constant!"); 30.1214 + assert(!upper_instr || !upper_instr->as_Constant() || !upper_instr->type()->as_IntConstant(), "Must not be constant!"); 30.1215 + this->_lower = lower; 30.1216 + this->_upper = upper; 30.1217 + this->_lower_instr = lower_instr; 30.1218 + this->_upper_instr = upper_instr; 30.1219 +} 30.1220 + 30.1221 +// Bound constructor 30.1222 +RangeCheckEliminator::Bound::Bound(Instruction::Condition cond, Value v, int constant) { 30.1223 + assert(!v || (v->type() && (v->type()->as_IntType() || v->type()->as_ObjectType())), "Type must be array or integer!"); 30.1224 + assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!"); 30.1225 + 30.1226 + init(); 30.1227 + if (cond == Instruction::eql) { 30.1228 + _lower = constant; 30.1229 + _lower_instr = v; 30.1230 + _upper = constant; 30.1231 + _upper_instr = v; 30.1232 + } else if (cond == Instruction::neq) { 30.1233 + _lower = min_jint; 30.1234 + _upper = max_jint; 30.1235 + _lower_instr = NULL; 30.1236 + _upper_instr = NULL; 30.1237 + if (v == NULL) { 30.1238 + if (constant == min_jint) { 30.1239 + _lower++; 30.1240 + } 30.1241 + if (constant == max_jint) { 30.1242 + _upper--; 30.1243 + } 30.1244 + } 30.1245 + } else if (cond == Instruction::geq) { 30.1246 + _lower = constant; 30.1247 + _lower_instr = v; 30.1248 + _upper = max_jint; 30.1249 + _upper_instr = NULL; 30.1250 + } else if (cond == Instruction::leq) { 30.1251 + _lower = min_jint; 30.1252 + _lower_instr = NULL; 30.1253 + _upper = constant; 30.1254 + _upper_instr = v; 30.1255 + } else { 30.1256 + ShouldNotReachHere(); 30.1257 + } 30.1258 +} 30.1259 + 30.1260 +// Set lower 30.1261 +void RangeCheckEliminator::Bound::set_lower(int value, Value v) { 30.1262 + assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!"); 30.1263 + this->_lower = value; 30.1264 + this->_lower_instr = v; 30.1265 +} 30.1266 + 30.1267 +// Set upper 30.1268 +void RangeCheckEliminator::Bound::set_upper(int value, Value v) { 30.1269 + assert(!v || !v->as_Constant() || !v->type()->as_IntConstant(), "Must not be constant!"); 30.1270 + this->_upper = value; 30.1271 + this->_upper_instr = v; 30.1272 +} 30.1273 + 30.1274 +// Add constant -> no overflow may occur 30.1275 +void RangeCheckEliminator::Bound::add_constant(int value) { 30.1276 + this->_lower += value; 30.1277 + this->_upper += value; 30.1278 +} 30.1279 + 30.1280 +// Init 30.1281 +void RangeCheckEliminator::Bound::init() { 30.1282 +} 30.1283 + 30.1284 +// or 30.1285 +void RangeCheckEliminator::Bound::or_op(Bound *b) { 30.1286 + // Watch out, bound is not guaranteed not to overflow! 30.1287 + // Update lower bound 30.1288 + if (_lower_instr != b->_lower_instr || (_lower_instr && _lower != b->_lower)) { 30.1289 + _lower_instr = NULL; 30.1290 + _lower = min_jint; 30.1291 + } else { 30.1292 + _lower = MIN2(_lower, b->_lower); 30.1293 + } 30.1294 + // Update upper bound 30.1295 + if (_upper_instr != b->_upper_instr || (_upper_instr && _upper != b->_upper)) { 30.1296 + _upper_instr = NULL; 30.1297 + _upper = max_jint; 30.1298 + } else { 30.1299 + _upper = MAX2(_upper, b->_upper); 30.1300 + } 30.1301 +} 30.1302 + 30.1303 +// and 30.1304 +void RangeCheckEliminator::Bound::and_op(Bound *b) { 30.1305 + // Update lower bound 30.1306 + if (_lower_instr == b->_lower_instr) { 30.1307 + _lower = MAX2(_lower, b->_lower); 30.1308 + } 30.1309 + if (b->has_lower()) { 30.1310 + bool set = true; 30.1311 + if (_lower_instr != NULL && b->_lower_instr != NULL) { 30.1312 + set = (_lower_instr->dominator_depth() > b->_lower_instr->dominator_depth()); 30.1313 + } 30.1314 + if (set) { 30.1315 + _lower = b->_lower; 30.1316 + _lower_instr = b->_lower_instr; 30.1317 + } 30.1318 + } 30.1319 + // Update upper bound 30.1320 + if (_upper_instr == b->_upper_instr) { 30.1321 + _upper = MIN2(_upper, b->_upper); 30.1322 + } 30.1323 + if (b->has_upper()) { 30.1324 + bool set = true; 30.1325 + if (_upper_instr != NULL && b->_upper_instr != NULL) { 30.1326 + set = (_upper_instr->dominator_depth() > b->_upper_instr->dominator_depth()); 30.1327 + } 30.1328 + if (set) { 30.1329 + _upper = b->_upper; 30.1330 + _upper_instr = b->_upper_instr; 30.1331 + } 30.1332 + } 30.1333 +} 30.1334 + 30.1335 +// has_upper 30.1336 +bool RangeCheckEliminator::Bound::has_upper() { 30.1337 + return _upper_instr != NULL || _upper < max_jint; 30.1338 +} 30.1339 + 30.1340 +// is_smaller 30.1341 +bool RangeCheckEliminator::Bound::is_smaller(Bound *b) { 30.1342 + if (b->_lower_instr != _upper_instr) { 30.1343 + return false; 30.1344 + } 30.1345 + return _upper < b->_lower; 30.1346 +} 30.1347 + 30.1348 +// has_lower 30.1349 +bool RangeCheckEliminator::Bound::has_lower() { 30.1350 + return _lower_instr != NULL || _lower > min_jint; 30.1351 +} 30.1352 + 30.1353 +// in_array_bound 30.1354 +bool RangeCheckEliminator::in_array_bound(Bound *bound, Value array){ 30.1355 + if (!bound) return false; 30.1356 + assert(array != NULL, "Must not be null!"); 30.1357 + assert(bound != NULL, "Must not be null!"); 30.1358 + if (bound->lower() >=0 && bound->lower_instr() == NULL && bound->upper() < 0 && bound->upper_instr() != NULL) { 30.1359 + ArrayLength *len = bound->upper_instr()->as_ArrayLength(); 30.1360 + if (bound->upper_instr() == array || (len != NULL && len->array() == array)) { 30.1361 + return true; 30.1362 + } 30.1363 + } 30.1364 + return false; 30.1365 +} 30.1366 + 30.1367 +// remove_lower 30.1368 +void RangeCheckEliminator::Bound::remove_lower() { 30.1369 + _lower = min_jint; 30.1370 + _lower_instr = NULL; 30.1371 +} 30.1372 + 30.1373 +// remove_upper 30.1374 +void RangeCheckEliminator::Bound::remove_upper() { 30.1375 + _upper = max_jint; 30.1376 + _upper_instr = NULL; 30.1377 +} 30.1378 + 30.1379 +// upper 30.1380 +int RangeCheckEliminator::Bound::upper() { 30.1381 + return _upper; 30.1382 +} 30.1383 + 30.1384 +// lower 30.1385 +int RangeCheckEliminator::Bound::lower() { 30.1386 + return _lower; 30.1387 +} 30.1388 + 30.1389 +// upper_instr 30.1390 +Value RangeCheckEliminator::Bound::upper_instr() { 30.1391 + return _upper_instr; 30.1392 +} 30.1393 + 30.1394 +// lower_instr 30.1395 +Value RangeCheckEliminator::Bound::lower_instr() { 30.1396 + return _lower_instr; 30.1397 +} 30.1398 + 30.1399 +// print 30.1400 +void RangeCheckEliminator::Bound::print() { 30.1401 + tty->print(""); 30.1402 + if (this->_lower_instr || this->_lower != min_jint) { 30.1403 + if (this->_lower_instr) { 30.1404 + tty->print("i%d", this->_lower_instr->id()); 30.1405 + if (this->_lower > 0) { 30.1406 + tty->print("+%d", _lower); 30.1407 + } 30.1408 + if (this->_lower < 0) { 30.1409 + tty->print("%d", _lower); 30.1410 + } 30.1411 + } else { 30.1412 + tty->print("%d", _lower); 30.1413 + } 30.1414 + tty->print(" <= "); 30.1415 + } 30.1416 + tty->print("x"); 30.1417 + if (this->_upper_instr || this->_upper != max_jint) { 30.1418 + tty->print(" <= "); 30.1419 + if (this->_upper_instr) { 30.1420 + tty->print("i%d", this->_upper_instr->id()); 30.1421 + if (this->_upper > 0) { 30.1422 + tty->print("+%d", _upper); 30.1423 + } 30.1424 + if (this->_upper < 0) { 30.1425 + tty->print("%d", _upper); 30.1426 + } 30.1427 + } else { 30.1428 + tty->print("%d", _upper); 30.1429 + } 30.1430 + } 30.1431 +} 30.1432 + 30.1433 +// Copy 30.1434 +RangeCheckEliminator::Bound *RangeCheckEliminator::Bound::copy() { 30.1435 + Bound *b = new Bound(); 30.1436 + b->_lower = _lower; 30.1437 + b->_lower_instr = _lower_instr; 30.1438 + b->_upper = _upper; 30.1439 + b->_upper_instr = _upper_instr; 30.1440 + return b; 30.1441 +} 30.1442 + 30.1443 +#ifdef ASSERT 30.1444 +// Add assertion 30.1445 +void RangeCheckEliminator::Bound::add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond) { 30.1446 + Instruction *result = position; 30.1447 + Instruction *compare_with = NULL; 30.1448 + ValueStack *state = position->state_before(); 30.1449 + if (position->as_BlockEnd() && !position->as_Goto()) { 30.1450 + state = position->as_BlockEnd()->state_before(); 30.1451 + } 30.1452 + Instruction *instruction_before = position->prev(); 30.1453 + if (position->as_Return() && Compilation::current()->method()->is_synchronized() && instruction_before->as_MonitorExit()) { 30.1454 + instruction_before = instruction_before->prev(); 30.1455 + } 30.1456 + result = instruction_before; 30.1457 + // Load constant only if needed 30.1458 + Constant *constant = NULL; 30.1459 + if (i != 0 || !instr) { 30.1460 + constant = new Constant(new IntConstant(i)); 30.1461 + NOT_PRODUCT(constant->set_printable_bci(position->printable_bci())); 30.1462 + result = result->insert_after(constant); 30.1463 + compare_with = constant; 30.1464 + } 30.1465 + 30.1466 + if (instr) { 30.1467 + assert(instr->type()->as_ObjectType() || instr->type()->as_IntType(), "Type must be array or integer!"); 30.1468 + compare_with = instr; 30.1469 + // Load array length if necessary 30.1470 + Instruction *op = instr; 30.1471 + if (instr->type()->as_ObjectType()) { 30.1472 + assert(state, "must not be null"); 30.1473 + ArrayLength *length = new ArrayLength(instr, state->copy()); 30.1474 + NOT_PRODUCT(length->set_printable_bci(position->printable_bci())); 30.1475 + length->set_exception_state(length->state_before()); 30.1476 + result = result->insert_after(length); 30.1477 + op = length; 30.1478 + compare_with = length; 30.1479 + } 30.1480 + // Add operation only if necessary 30.1481 + if (constant) { 30.1482 + ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, op, false, NULL); 30.1483 + NOT_PRODUCT(ao->set_printable_bci(position->printable_bci())); 30.1484 + result = result->insert_after(ao); 30.1485 + compare_with = ao; 30.1486 + // TODO: Check that add operation does not overflow! 30.1487 + } 30.1488 + } 30.1489 + assert(compare_with != NULL, "You have to compare with something!"); 30.1490 + assert(instruction != NULL, "Instruction must not be null!"); 30.1491 + 30.1492 + if (instruction->type()->as_ObjectType()) { 30.1493 + // Load array length if necessary 30.1494 + Instruction *op = instruction; 30.1495 + assert(state, "must not be null"); 30.1496 + ArrayLength *length = new ArrayLength(instruction, state->copy()); 30.1497 + length->set_exception_state(length->state_before()); 30.1498 + NOT_PRODUCT(length->set_printable_bci(position->printable_bci())); 30.1499 + result = result->insert_after(length); 30.1500 + instruction = length; 30.1501 + } 30.1502 + 30.1503 + Assert *assert = new Assert(instruction, cond, false, compare_with); 30.1504 + NOT_PRODUCT(assert->set_printable_bci(position->printable_bci())); 30.1505 + result->insert_after(assert); 30.1506 +} 30.1507 + 30.1508 +// Add assertions 30.1509 +void RangeCheckEliminator::add_assertions(Bound *bound, Instruction *instruction, Instruction *position) { 30.1510 + // Add lower bound assertion 30.1511 + if (bound->has_lower()) { 30.1512 + bound->add_assertion(instruction, position, bound->lower(), bound->lower_instr(), Instruction::geq); 30.1513 + } 30.1514 + // Add upper bound assertion 30.1515 + if (bound->has_upper()) { 30.1516 + bound->add_assertion(instruction, position, bound->upper(), bound->upper_instr(), Instruction::leq); 30.1517 + } 30.1518 +} 30.1519 +#endif 30.1520 +
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/src/share/vm/c1/c1_RangeCheckElimination.hpp Thu Mar 21 09:27:54 2013 +0100 31.3 @@ -0,0 +1,241 @@ 31.4 +/* 31.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.7 + * 31.8 + * This code is free software; you can redistribute it and/or modify it 31.9 + * under the terms of the GNU General Public License version 2 only, as 31.10 + * published by the Free Software Foundation. 31.11 + * 31.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 31.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 31.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31.15 + * version 2 for more details (a copy is included in the LICENSE file that 31.16 + * accompanied this code). 31.17 + * 31.18 + * You should have received a copy of the GNU General Public License version 31.19 + * 2 along with this work; if not, write to the Free Software Foundation, 31.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 31.21 + * 31.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 31.23 + * or visit www.oracle.com if you need additional information or have any 31.24 + * questions. 31.25 + * 31.26 + */ 31.27 + 31.28 +#ifndef SHARE_VM_C1_C1_RANGECHECKELIMINATION_HPP 31.29 +#define SHARE_VM_C1_C1_RANGECHECKELIMINATION_HPP 31.30 + 31.31 +#include "c1/c1_Instruction.hpp" 31.32 + 31.33 +// Base class for range check elimination 31.34 +class RangeCheckElimination : AllStatic { 31.35 +public: 31.36 + static void eliminate(IR *ir); 31.37 +}; 31.38 + 31.39 +// Implementation 31.40 +class RangeCheckEliminator VALUE_OBJ_CLASS_SPEC { 31.41 +private: 31.42 + int _number_of_instructions; 31.43 + bool _optimistic; // Insert predicates and deoptimize when they fail 31.44 + IR *_ir; 31.45 + 31.46 + define_array(BlockBeginArray, BlockBegin*) 31.47 + define_stack(BlockBeginList, BlockBeginArray) 31.48 + define_stack(IntegerStack, intArray) 31.49 + define_array(IntegerMap, IntegerStack*) 31.50 + 31.51 + class Verification : public _ValueObj /*VALUE_OBJ_CLASS_SPEC*/, public BlockClosure { 31.52 + private: 31.53 + IR *_ir; 31.54 + boolArray _used; 31.55 + BlockBeginList _current; 31.56 + BlockBeginList _successors; 31.57 + 31.58 + public: 31.59 + Verification(IR *ir); 31.60 + virtual void block_do(BlockBegin *block); 31.61 + bool can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use = NULL); 31.62 + bool dominates(BlockBegin *dominator, BlockBegin *block); 31.63 + }; 31.64 + 31.65 +public: 31.66 + // Bounds for an instruction in the form x + c which c integer 31.67 + // constant and x another instruction 31.68 + class Bound : public CompilationResourceObj { 31.69 + private: 31.70 + int _upper; 31.71 + Value _upper_instr; 31.72 + int _lower; 31.73 + Value _lower_instr; 31.74 + 31.75 + public: 31.76 + Bound(); 31.77 + Bound(Value v); 31.78 + Bound(Instruction::Condition cond, Value v, int constant = 0); 31.79 + Bound(int lower, Value lower_instr, int upper, Value upper_instr); 31.80 + ~Bound(); 31.81 + 31.82 +#ifdef ASSERT 31.83 + void add_assertion(Instruction *instruction, Instruction *position, int i, Value instr, Instruction::Condition cond); 31.84 +#endif 31.85 + int upper(); 31.86 + Value upper_instr(); 31.87 + int lower(); 31.88 + Value lower_instr(); 31.89 + void print(); 31.90 + bool check_no_overflow(int const_value); 31.91 + void or_op(Bound *b); 31.92 + void and_op(Bound *b); 31.93 + bool has_upper(); 31.94 + bool has_lower(); 31.95 + void set_upper(int upper, Value upper_instr); 31.96 + void set_lower(int lower, Value lower_instr); 31.97 + bool is_smaller(Bound *b); 31.98 + void remove_upper(); 31.99 + void remove_lower(); 31.100 + void add_constant(int value); 31.101 + Bound *copy(); 31.102 + 31.103 + private: 31.104 + void init(); 31.105 + }; 31.106 + 31.107 + 31.108 + class Visitor : public InstructionVisitor { 31.109 + private: 31.110 + Bound *_bound; 31.111 + RangeCheckEliminator *_rce; 31.112 + 31.113 + public: 31.114 + void set_range_check_eliminator(RangeCheckEliminator *rce) { _rce = rce; } 31.115 + Bound *bound() const { return _bound; } 31.116 + void clear_bound() { _bound = NULL; } 31.117 + 31.118 + protected: 31.119 + // visitor functions 31.120 + void do_Constant (Constant* x); 31.121 + void do_IfOp (IfOp* x); 31.122 + void do_LogicOp (LogicOp* x); 31.123 + void do_ArithmeticOp (ArithmeticOp* x); 31.124 + void do_Phi (Phi* x); 31.125 + 31.126 + void do_StoreField (StoreField* x) { /* nothing to do */ }; 31.127 + void do_StoreIndexed (StoreIndexed* x) { /* nothing to do */ }; 31.128 + void do_MonitorEnter (MonitorEnter* x) { /* nothing to do */ }; 31.129 + void do_MonitorExit (MonitorExit* x) { /* nothing to do */ }; 31.130 + void do_Invoke (Invoke* x) { /* nothing to do */ }; 31.131 + void do_UnsafePutRaw (UnsafePutRaw* x) { /* nothing to do */ }; 31.132 + void do_UnsafePutObject(UnsafePutObject* x) { /* nothing to do */ }; 31.133 + void do_Intrinsic (Intrinsic* x) { /* nothing to do */ }; 31.134 + void do_Local (Local* x) { /* nothing to do */ }; 31.135 + void do_LoadField (LoadField* x) { /* nothing to do */ }; 31.136 + void do_ArrayLength (ArrayLength* x) { /* nothing to do */ }; 31.137 + void do_LoadIndexed (LoadIndexed* x) { /* nothing to do */ }; 31.138 + void do_NegateOp (NegateOp* x) { /* nothing to do */ }; 31.139 + void do_ShiftOp (ShiftOp* x) { /* nothing to do */ }; 31.140 + void do_CompareOp (CompareOp* x) { /* nothing to do */ }; 31.141 + void do_Convert (Convert* x) { /* nothing to do */ }; 31.142 + void do_NullCheck (NullCheck* x) { /* nothing to do */ }; 31.143 + void do_TypeCast (TypeCast* x) { /* nothing to do */ }; 31.144 + void do_NewInstance (NewInstance* x) { /* nothing to do */ }; 31.145 + void do_NewTypeArray (NewTypeArray* x) { /* nothing to do */ }; 31.146 + void do_NewObjectArray (NewObjectArray* x) { /* nothing to do */ }; 31.147 + void do_NewMultiArray (NewMultiArray* x) { /* nothing to do */ }; 31.148 + void do_CheckCast (CheckCast* x) { /* nothing to do */ }; 31.149 + void do_InstanceOf (InstanceOf* x) { /* nothing to do */ }; 31.150 + void do_BlockBegin (BlockBegin* x) { /* nothing to do */ }; 31.151 + void do_Goto (Goto* x) { /* nothing to do */ }; 31.152 + void do_If (If* x) { /* nothing to do */ }; 31.153 + void do_IfInstanceOf (IfInstanceOf* x) { /* nothing to do */ }; 31.154 + void do_TableSwitch (TableSwitch* x) { /* nothing to do */ }; 31.155 + void do_LookupSwitch (LookupSwitch* x) { /* nothing to do */ }; 31.156 + void do_Return (Return* x) { /* nothing to do */ }; 31.157 + void do_Throw (Throw* x) { /* nothing to do */ }; 31.158 + void do_Base (Base* x) { /* nothing to do */ }; 31.159 + void do_OsrEntry (OsrEntry* x) { /* nothing to do */ }; 31.160 + void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }; 31.161 + void do_RoundFP (RoundFP* x) { /* nothing to do */ }; 31.162 + void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ }; 31.163 + void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }; 31.164 + void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { /* nothing to do */ }; 31.165 + void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ }; 31.166 + void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }; 31.167 + void do_ProfileCall (ProfileCall* x) { /* nothing to do */ }; 31.168 + void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; 31.169 + void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ }; 31.170 + void do_MemBar (MemBar* x) { /* nothing to do */ }; 31.171 + void do_RangeCheckPredicate(RangeCheckPredicate* x) { /* nothing to do */ }; 31.172 + void do_Assert (Assert* x) { /* nothing to do */ }; 31.173 + }; 31.174 + 31.175 +#ifdef ASSERT 31.176 + void add_assertions(Bound *bound, Instruction *instruction, Instruction *position); 31.177 +#endif 31.178 + 31.179 + define_array(BoundArray, Bound *) 31.180 + define_stack(BoundStack, BoundArray) 31.181 + define_array(BoundMap, BoundStack *) 31.182 + define_array(AccessIndexedArray, AccessIndexed *) 31.183 + define_stack(AccessIndexedList, AccessIndexedArray) 31.184 + define_array(InstructionArray, Instruction *) 31.185 + define_stack(InstructionList, InstructionArray) 31.186 + 31.187 + class AccessIndexedInfo : public CompilationResourceObj { 31.188 + public: 31.189 + AccessIndexedList *_list; 31.190 + int _min; 31.191 + int _max; 31.192 + }; 31.193 + 31.194 + define_array(AccessIndexedInfoArray, AccessIndexedInfo *) 31.195 + BoundMap _bounds; // Mapping from Instruction's id to current bound 31.196 + AccessIndexedInfoArray _access_indexed_info; // Mapping from Instruction's id to AccessIndexedInfo for in block motion 31.197 + Visitor _visitor; 31.198 + 31.199 +public: 31.200 + RangeCheckEliminator(IR *ir); 31.201 + 31.202 + IR *ir() const { return _ir; } 31.203 + 31.204 + // Pass over the dominator tree to identify blocks where there's an oppportunity for optimization 31.205 + bool set_process_block_flags(BlockBegin *block); 31.206 + // The core of the optimization work: pass over the dominator tree 31.207 + // to propagate bound information, insert predicate out of loops, 31.208 + // eliminate bound checks when possible and perform in block motion 31.209 + void calc_bounds(BlockBegin *block, BlockBegin *loop_header); 31.210 + // reorder bound checks within a block in order to eliminate some of them 31.211 + void in_block_motion(BlockBegin *block, AccessIndexedList &accessIndexed, InstructionList &arrays); 31.212 + 31.213 + // update/access current bound 31.214 + void update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant); 31.215 + void update_bound(IntegerStack &pushed, Value v, Bound *bound); 31.216 + Bound *get_bound(Value v); 31.217 + 31.218 + bool loop_invariant(BlockBegin *loop_header, Instruction *instruction); // check for loop invariance 31.219 + void add_access_indexed_info(InstructionList &indices, int i, Value instruction, AccessIndexed *ai); // record indexed access for in block motion 31.220 + void remove_range_check(AccessIndexed *ai); // Mark this instructions as not needing a range check 31.221 + void add_if_condition(IntegerStack &pushed, Value x, Value y, Instruction::Condition condition); // Update bound for an If 31.222 + bool in_array_bound(Bound *bound, Value array); // Check whether bound is known to fall within array 31.223 + 31.224 + // helper functions to work with predicates 31.225 + Instruction* insert_after(Instruction* insert_position, Instruction* instr, int bci); 31.226 + Instruction* predicate(Instruction* left, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci=-1); 31.227 + Instruction* predicate_cmp_with_const(Instruction* instr, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci=1); 31.228 + Instruction* predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci=-1); 31.229 + Instruction* predicate_add_cmp_with_const(Instruction* left, int left_const, Instruction::Condition cond, int constant, ValueStack* state, Instruction *insert_position, int bci=-1); 31.230 + 31.231 + void insert_deoptimization(ValueStack *state, Instruction *insert_position, Instruction *array_instr, // Add predicate 31.232 + Instruction *length_instruction, Instruction *lower_instr, int lower, 31.233 + Instruction *upper_instr, int upper, AccessIndexed *ai); 31.234 + bool is_ok_for_deoptimization(Instruction *insert_position, Instruction *array_instr, // Can we safely add a predicate? 31.235 + Instruction *length_instr, Instruction *lower_instr, 31.236 + int lower, Instruction *upper_instr, int upper); 31.237 + void process_if(IntegerStack &pushed, BlockBegin *block, If *cond); // process If Instruction 31.238 + void process_access_indexed(BlockBegin *loop_header, BlockBegin *block, AccessIndexed *ai); // process indexed access 31.239 + 31.240 + void dump_condition_stack(BlockBegin *cur_block); 31.241 + static void print_statistics(); 31.242 +}; 31.243 + 31.244 +#endif // SHARE_VM_C1_C1_RANGECHECKELIMINATION_HPP
32.1 --- a/src/share/vm/c1/c1_Runtime1.cpp Wed Mar 20 17:04:45 2013 -0700 32.2 +++ b/src/share/vm/c1/c1_Runtime1.cpp Thu Mar 21 09:27:54 2013 +0100 32.3 @@ -1330,6 +1330,50 @@ 32.4 return (k != NULL && obj != NULL && obj->is_a(k)) ? 1 : 0; 32.5 JRT_END 32.6 32.7 +JRT_ENTRY(void, Runtime1::predicate_failed_trap(JavaThread* thread)) 32.8 + ResourceMark rm; 32.9 + 32.10 + assert(!TieredCompilation, "incompatible with tiered compilation"); 32.11 + 32.12 + RegisterMap reg_map(thread, false); 32.13 + frame runtime_frame = thread->last_frame(); 32.14 + frame caller_frame = runtime_frame.sender(®_map); 32.15 + 32.16 + nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); 32.17 + assert (nm != NULL, "no more nmethod?"); 32.18 + nm->make_not_entrant(); 32.19 + 32.20 + methodHandle m(nm->method()); 32.21 + MethodData* mdo = m->method_data(); 32.22 + 32.23 + if (mdo == NULL && !HAS_PENDING_EXCEPTION) { 32.24 + // Build an MDO. Ignore errors like OutOfMemory; 32.25 + // that simply means we won't have an MDO to update. 32.26 + Method::build_interpreter_method_data(m, THREAD); 32.27 + if (HAS_PENDING_EXCEPTION) { 32.28 + assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); 32.29 + CLEAR_PENDING_EXCEPTION; 32.30 + } 32.31 + mdo = m->method_data(); 32.32 + } 32.33 + 32.34 + if (mdo != NULL) { 32.35 + mdo->inc_trap_count(Deoptimization::Reason_none); 32.36 + } 32.37 + 32.38 + if (TracePredicateFailedTraps) { 32.39 + stringStream ss1, ss2; 32.40 + vframeStream vfst(thread); 32.41 + methodHandle inlinee = methodHandle(vfst.method()); 32.42 + inlinee->print_short_name(&ss1); 32.43 + m->print_short_name(&ss2); 32.44 + tty->print_cr("Predicate failed trap in method %s at bci %d inlined in %s at pc %x", ss1.as_string(), vfst.bci(), ss2.as_string(), caller_frame.pc()); 32.45 + } 32.46 + 32.47 + 32.48 + Deoptimization::deoptimize_frame(thread, caller_frame.id()); 32.49 + 32.50 +JRT_END 32.51 32.52 #ifndef PRODUCT 32.53 void Runtime1::print_statistics() {
33.1 --- a/src/share/vm/c1/c1_Runtime1.hpp Wed Mar 20 17:04:45 2013 -0700 33.2 +++ b/src/share/vm/c1/c1_Runtime1.hpp Thu Mar 21 09:27:54 2013 +0100 33.3 @@ -71,6 +71,7 @@ 33.4 stub(g1_post_barrier_slow) \ 33.5 stub(fpu2long_stub) \ 33.6 stub(counter_overflow) \ 33.7 + stub(predicate_failed_trap) \ 33.8 last_entry(number_of_ids) 33.9 33.10 #define DECLARE_STUB_ID(x) x ## _id , 33.11 @@ -190,6 +191,8 @@ 33.12 static void oop_arraycopy(HeapWord* src, HeapWord* dst, int length); 33.13 static int is_instance_of(oopDesc* mirror, oopDesc* obj); 33.14 33.15 + static void predicate_failed_trap(JavaThread* thread); 33.16 + 33.17 static void print_statistics() PRODUCT_RETURN; 33.18 }; 33.19
34.1 --- a/src/share/vm/c1/c1_ValueMap.cpp Wed Mar 20 17:04:45 2013 -0700 34.2 +++ b/src/share/vm/c1/c1_ValueMap.cpp Thu Mar 21 09:27:54 2013 +0100 34.3 @@ -26,9 +26,9 @@ 34.4 #include "c1/c1_Canonicalizer.hpp" 34.5 #include "c1/c1_IR.hpp" 34.6 #include "c1/c1_ValueMap.hpp" 34.7 +#include "c1/c1_ValueStack.hpp" 34.8 #include "utilities/bitMap.inline.hpp" 34.9 34.10 - 34.11 #ifndef PRODUCT 34.12 34.13 int ValueMap::_number_of_finds = 0; 34.14 @@ -192,10 +192,6 @@ 34.15 && lf->field()->holder() == field->holder() \ 34.16 && (all_offsets || lf->field()->offset() == field->offset()); 34.17 34.18 -#define MUST_KILL_EXCEPTION(must_kill, entry, value) \ 34.19 - assert(entry->nesting() < nesting(), "must not find bigger nesting than current"); \ 34.20 - bool must_kill = (entry->nesting() == nesting() - 1); 34.21 - 34.22 34.23 void ValueMap::kill_memory() { 34.24 GENERIC_KILL_VALUE(MUST_KILL_MEMORY); 34.25 @@ -209,11 +205,6 @@ 34.26 GENERIC_KILL_VALUE(MUST_KILL_FIELD); 34.27 } 34.28 34.29 -void ValueMap::kill_exception() { 34.30 - GENERIC_KILL_VALUE(MUST_KILL_EXCEPTION); 34.31 -} 34.32 - 34.33 - 34.34 void ValueMap::kill_map(ValueMap* map) { 34.35 assert(is_global_value_numbering(), "only for global value numbering"); 34.36 _killed_values.set_union(&map->_killed_values); 34.37 @@ -274,6 +265,8 @@ 34.38 GlobalValueNumbering* _gvn; 34.39 BlockList _loop_blocks; 34.40 bool _too_complicated_loop; 34.41 + bool _has_field_store[T_ARRAY + 1]; 34.42 + bool _has_indexed_store[T_ARRAY + 1]; 34.43 34.44 // simplified access to methods of GlobalValueNumbering 34.45 ValueMap* current_map() { return _gvn->current_map(); } 34.46 @@ -281,8 +274,16 @@ 34.47 34.48 // implementation for abstract methods of ValueNumberingVisitor 34.49 void kill_memory() { _too_complicated_loop = true; } 34.50 - void kill_field(ciField* field, bool all_offsets) { current_map()->kill_field(field, all_offsets); }; 34.51 - void kill_array(ValueType* type) { current_map()->kill_array(type); }; 34.52 + void kill_field(ciField* field, bool all_offsets) { 34.53 + current_map()->kill_field(field, all_offsets); 34.54 + assert(field->type()->basic_type() >= 0 && field->type()->basic_type() <= T_ARRAY, "Invalid type"); 34.55 + _has_field_store[field->type()->basic_type()] = true; 34.56 + } 34.57 + void kill_array(ValueType* type) { 34.58 + current_map()->kill_array(type); 34.59 + BasicType basic_type = as_BasicType(type); assert(basic_type >= 0 && basic_type <= T_ARRAY, "Invalid type"); 34.60 + _has_indexed_store[basic_type] = true; 34.61 + } 34.62 34.63 public: 34.64 ShortLoopOptimizer(GlobalValueNumbering* gvn) 34.65 @@ -290,11 +291,141 @@ 34.66 , _loop_blocks(ValueMapMaxLoopSize) 34.67 , _too_complicated_loop(false) 34.68 { 34.69 + for (int i=0; i<= T_ARRAY; i++){ 34.70 + _has_field_store[i] = false; 34.71 + _has_indexed_store[i] = false; 34.72 + } 34.73 + } 34.74 + 34.75 + bool has_field_store(BasicType type) { 34.76 + assert(type >= 0 && type <= T_ARRAY, "Invalid type"); 34.77 + return _has_field_store[type]; 34.78 + } 34.79 + 34.80 + bool has_indexed_store(BasicType type) { 34.81 + assert(type >= 0 && type <= T_ARRAY, "Invalid type"); 34.82 + return _has_indexed_store[type]; 34.83 } 34.84 34.85 bool process(BlockBegin* loop_header); 34.86 }; 34.87 34.88 +class LoopInvariantCodeMotion : public StackObj { 34.89 + private: 34.90 + GlobalValueNumbering* _gvn; 34.91 + ShortLoopOptimizer* _short_loop_optimizer; 34.92 + Instruction* _insertion_point; 34.93 + ValueStack * _state; 34.94 + 34.95 + void set_invariant(Value v) const { _gvn->set_processed(v); } 34.96 + bool is_invariant(Value v) const { return _gvn->is_processed(v); } 34.97 + 34.98 + void process_block(BlockBegin* block); 34.99 + 34.100 + public: 34.101 + LoopInvariantCodeMotion(ShortLoopOptimizer *slo, GlobalValueNumbering* gvn, BlockBegin* loop_header, BlockList* loop_blocks); 34.102 +}; 34.103 + 34.104 +LoopInvariantCodeMotion::LoopInvariantCodeMotion(ShortLoopOptimizer *slo, GlobalValueNumbering* gvn, BlockBegin* loop_header, BlockList* loop_blocks) 34.105 + : _gvn(gvn), _short_loop_optimizer(slo) { 34.106 + 34.107 + TRACE_VALUE_NUMBERING(tty->print_cr("using loop invariant code motion loop_header = %d", loop_header->block_id())); 34.108 + TRACE_VALUE_NUMBERING(tty->print_cr("** loop invariant code motion for short loop B%d", loop_header->block_id())); 34.109 + 34.110 + BlockBegin* insertion_block = loop_header->dominator(); 34.111 + if (insertion_block->number_of_preds() == 0) { 34.112 + return; // only the entry block does not have a predecessor 34.113 + } 34.114 + 34.115 + assert(insertion_block->end()->as_Base() == NULL, "cannot insert into entry block"); 34.116 + _insertion_point = insertion_block->end()->prev(); 34.117 + 34.118 + BlockEnd *block_end = insertion_block->end(); 34.119 + _state = block_end->state_before(); 34.120 + 34.121 + if (!_state) { 34.122 + // If, TableSwitch and LookupSwitch always have state_before when 34.123 + // loop invariant code motion happens.. 34.124 + assert(block_end->as_Goto(), "Block has to be goto"); 34.125 + _state = block_end->state(); 34.126 + } 34.127 + 34.128 + // the loop_blocks are filled by going backward from the loop header, so this processing order is best 34.129 + assert(loop_blocks->at(0) == loop_header, "loop header must be first loop block"); 34.130 + process_block(loop_header); 34.131 + for (int i = loop_blocks->length() - 1; i >= 1; i--) { 34.132 + process_block(loop_blocks->at(i)); 34.133 + } 34.134 +} 34.135 + 34.136 +void LoopInvariantCodeMotion::process_block(BlockBegin* block) { 34.137 + TRACE_VALUE_NUMBERING(tty->print_cr("processing block B%d", block->block_id())); 34.138 + 34.139 + Instruction* prev = block; 34.140 + Instruction* cur = block->next(); 34.141 + 34.142 + while (cur != NULL) { 34.143 + 34.144 + // determine if cur instruction is loop invariant 34.145 + // only selected instruction types are processed here 34.146 + bool cur_invariant = false; 34.147 + 34.148 + if (cur->as_Constant() != NULL) { 34.149 + cur_invariant = !cur->can_trap(); 34.150 + } else if (cur->as_ArithmeticOp() != NULL || cur->as_LogicOp() != NULL || cur->as_ShiftOp() != NULL) { 34.151 + assert(cur->as_Op2() != NULL, "must be Op2"); 34.152 + Op2* op2 = (Op2*)cur; 34.153 + cur_invariant = !op2->can_trap() && is_invariant(op2->x()) && is_invariant(op2->y()); 34.154 + } else if (cur->as_LoadField() != NULL) { 34.155 + LoadField* lf = (LoadField*)cur; 34.156 + // deoptimizes on NullPointerException 34.157 + cur_invariant = !lf->needs_patching() && !lf->field()->is_volatile() && !_short_loop_optimizer->has_field_store(lf->field()->type()->basic_type()) && is_invariant(lf->obj()); 34.158 + } else if (cur->as_ArrayLength() != NULL) { 34.159 + ArrayLength *length = cur->as_ArrayLength(); 34.160 + cur_invariant = is_invariant(length->array()); 34.161 + } else if (cur->as_LoadIndexed() != NULL) { 34.162 + LoadIndexed *li = (LoadIndexed *)cur->as_LoadIndexed(); 34.163 + cur_invariant = !_short_loop_optimizer->has_indexed_store(as_BasicType(cur->type())) && is_invariant(li->array()) && is_invariant(li->index()); 34.164 + } 34.165 + 34.166 + if (cur_invariant) { 34.167 + // perform value numbering and mark instruction as loop-invariant 34.168 + _gvn->substitute(cur); 34.169 + 34.170 + if (cur->as_Constant() == NULL) { 34.171 + // ensure that code for non-constant instructions is always generated 34.172 + cur->pin(); 34.173 + } 34.174 + 34.175 + // remove cur instruction from loop block and append it to block before loop 34.176 + Instruction* next = cur->next(); 34.177 + Instruction* in = _insertion_point->next(); 34.178 + _insertion_point = _insertion_point->set_next(cur); 34.179 + cur->set_next(in); 34.180 + 34.181 + // Deoptimize on exception 34.182 + cur->set_flag(Instruction::DeoptimizeOnException, true); 34.183 + 34.184 + // Clear exception handlers 34.185 + cur->set_exception_handlers(NULL); 34.186 + 34.187 + TRACE_VALUE_NUMBERING(tty->print_cr("Instruction %c%d is loop invariant", cur->type()->tchar(), cur->id())); 34.188 + 34.189 + if (cur->state_before() != NULL) { 34.190 + cur->set_state_before(_state->copy()); 34.191 + } 34.192 + if (cur->exception_state() != NULL) { 34.193 + cur->set_exception_state(_state->copy()); 34.194 + } 34.195 + 34.196 + cur = prev->set_next(next); 34.197 + 34.198 + } else { 34.199 + prev = cur; 34.200 + cur = cur->next(); 34.201 + } 34.202 + } 34.203 +} 34.204 34.205 bool ShortLoopOptimizer::process(BlockBegin* loop_header) { 34.206 TRACE_VALUE_NUMBERING(tty->print_cr("** loop header block")); 34.207 @@ -316,6 +447,10 @@ 34.208 for (int j = block->number_of_preds() - 1; j >= 0; j--) { 34.209 BlockBegin* pred = block->pred_at(j); 34.210 34.211 + if (pred->is_set(BlockBegin::osr_entry_flag)) { 34.212 + return false; 34.213 + } 34.214 + 34.215 ValueMap* pred_map = value_map_of(pred); 34.216 if (pred_map != NULL) { 34.217 current_map()->kill_map(pred_map); 34.218 @@ -336,6 +471,12 @@ 34.219 } 34.220 } 34.221 34.222 + bool optimistic = this->_gvn->compilation()->is_optimistic(); 34.223 + 34.224 + if (UseLoopInvariantCodeMotion && optimistic) { 34.225 + LoopInvariantCodeMotion code_motion(this, _gvn, loop_header, &_loop_blocks); 34.226 + } 34.227 + 34.228 TRACE_VALUE_NUMBERING(tty->print_cr("** loop successfully optimized")); 34.229 return true; 34.230 } 34.231 @@ -344,11 +485,11 @@ 34.232 GlobalValueNumbering::GlobalValueNumbering(IR* ir) 34.233 : _current_map(NULL) 34.234 , _value_maps(ir->linear_scan_order()->length(), NULL) 34.235 + , _compilation(ir->compilation()) 34.236 { 34.237 TRACE_VALUE_NUMBERING(tty->print_cr("****** start of global value numbering")); 34.238 34.239 ShortLoopOptimizer short_loop_optimizer(this); 34.240 - int subst_count = 0; 34.241 34.242 BlockList* blocks = ir->linear_scan_order(); 34.243 int num_blocks = blocks->length(); 34.244 @@ -357,6 +498,12 @@ 34.245 assert(start_block == ir->start() && start_block->number_of_preds() == 0 && start_block->dominator() == NULL, "must be start block"); 34.246 assert(start_block->next()->as_Base() != NULL && start_block->next()->next() == NULL, "start block must not have instructions"); 34.247 34.248 + // method parameters are not linked in instructions list, so process them separateley 34.249 + for_each_state_value(start_block->state(), value, 34.250 + assert(value->as_Local() != NULL, "only method parameters allowed"); 34.251 + set_processed(value); 34.252 + ); 34.253 + 34.254 // initial, empty value map with nesting 0 34.255 set_value_map_of(start_block, new ValueMap()); 34.256 34.257 @@ -374,7 +521,7 @@ 34.258 // create new value map with increased nesting 34.259 _current_map = new ValueMap(value_map_of(dominator)); 34.260 34.261 - if (num_preds == 1) { 34.262 + if (num_preds == 1 && !block->is_set(BlockBegin::exception_entry_flag)) { 34.263 assert(dominator == block->pred_at(0), "dominator must be equal to predecessor"); 34.264 // nothing to do here 34.265 34.266 @@ -403,36 +550,41 @@ 34.267 } 34.268 } 34.269 34.270 - if (block->is_set(BlockBegin::exception_entry_flag)) { 34.271 - current_map()->kill_exception(); 34.272 - } 34.273 + // phi functions are not linked in instructions list, so process them separateley 34.274 + for_each_phi_fun(block, phi, 34.275 + set_processed(phi); 34.276 + ); 34.277 34.278 TRACE_VALUE_NUMBERING(tty->print("value map before processing block: "); current_map()->print()); 34.279 34.280 // visit all instructions of this block 34.281 for (Value instr = block->next(); instr != NULL; instr = instr->next()) { 34.282 - assert(!instr->has_subst(), "substitution already set"); 34.283 - 34.284 // check if instruction kills any values 34.285 instr->visit(this); 34.286 - 34.287 - if (instr->hash() != 0) { 34.288 - Value f = current_map()->find_insert(instr); 34.289 - if (f != instr) { 34.290 - assert(!f->has_subst(), "can't have a substitution"); 34.291 - instr->set_subst(f); 34.292 - subst_count++; 34.293 - } 34.294 - } 34.295 + // perform actual value numbering 34.296 + substitute(instr); 34.297 } 34.298 34.299 // remember value map for successors 34.300 set_value_map_of(block, current_map()); 34.301 } 34.302 34.303 - if (subst_count != 0) { 34.304 + if (_has_substitutions) { 34.305 SubstitutionResolver resolver(ir); 34.306 } 34.307 34.308 TRACE_VALUE_NUMBERING(tty->print("****** end of global value numbering. "); ValueMap::print_statistics()); 34.309 } 34.310 + 34.311 +void GlobalValueNumbering::substitute(Instruction* instr) { 34.312 + assert(!instr->has_subst(), "substitution already set"); 34.313 + Value subst = current_map()->find_insert(instr); 34.314 + if (subst != instr) { 34.315 + assert(!subst->has_subst(), "can't have a substitution"); 34.316 + 34.317 + TRACE_VALUE_NUMBERING(tty->print_cr("substitution for %d set to %d", instr->id(), subst->id())); 34.318 + instr->set_subst(subst); 34.319 + _has_substitutions = true; 34.320 + } 34.321 + set_processed(instr); 34.322 +}
35.1 --- a/src/share/vm/c1/c1_ValueMap.hpp Wed Mar 20 17:04:45 2013 -0700 35.2 +++ b/src/share/vm/c1/c1_ValueMap.hpp Thu Mar 21 09:27:54 2013 +0100 35.3 @@ -206,6 +206,8 @@ 35.4 void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; 35.5 void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ }; 35.6 void do_MemBar (MemBar* x) { /* nothing to do */ }; 35.7 + void do_RangeCheckPredicate(RangeCheckPredicate* x) { /* nothing to do */ }; 35.8 + void do_Assert (Assert* x) { /* nothing to do */ }; 35.9 }; 35.10 35.11 35.12 @@ -225,15 +227,22 @@ 35.13 35.14 class GlobalValueNumbering: public ValueNumberingVisitor { 35.15 private: 35.16 + Compilation* _compilation; // compilation data 35.17 ValueMap* _current_map; // value map of current block 35.18 ValueMapArray _value_maps; // list of value maps for all blocks 35.19 + ValueSet _processed_values; // marker for instructions that were already processed 35.20 + bool _has_substitutions; // set to true when substitutions must be resolved 35.21 35.22 public: 35.23 // accessors 35.24 + Compilation* compilation() const { return _compilation; } 35.25 ValueMap* current_map() { return _current_map; } 35.26 ValueMap* value_map_of(BlockBegin* block) { return _value_maps.at(block->linear_scan_number()); } 35.27 void set_value_map_of(BlockBegin* block, ValueMap* map) { assert(value_map_of(block) == NULL, ""); _value_maps.at_put(block->linear_scan_number(), map); } 35.28 35.29 + bool is_processed(Value v) { return _processed_values.contains(v); } 35.30 + void set_processed(Value v) { _processed_values.put(v); } 35.31 + 35.32 // implementation for abstract methods of ValueNumberingVisitor 35.33 void kill_memory() { current_map()->kill_memory(); } 35.34 void kill_field(ciField* field, bool all_offsets) { current_map()->kill_field(field, all_offsets); } 35.35 @@ -241,6 +250,7 @@ 35.36 35.37 // main entry point that performs global value numbering 35.38 GlobalValueNumbering(IR* ir); 35.39 + void substitute(Instruction* instr); // substitute instruction if it is contained in current value map 35.40 }; 35.41 35.42 #endif // SHARE_VM_C1_C1_VALUEMAP_HPP
36.1 --- a/src/share/vm/c1/c1_globals.hpp Wed Mar 20 17:04:45 2013 -0700 36.2 +++ b/src/share/vm/c1/c1_globals.hpp Thu Mar 21 09:27:54 2013 +0100 36.3 @@ -119,6 +119,24 @@ 36.4 develop(bool, UseGlobalValueNumbering, true, \ 36.5 "Use Global Value Numbering (separate phase)") \ 36.6 \ 36.7 + product(bool, UseLoopInvariantCodeMotion, true, \ 36.8 + "Simple loop invariant code motion for short loops during GVN") \ 36.9 + \ 36.10 + develop(bool, TracePredicateFailedTraps, false, \ 36.11 + "trace runtime traps caused by predicate failure") \ 36.12 + \ 36.13 + develop(bool, StressLoopInvariantCodeMotion, false, \ 36.14 + "stress loop invariant code motion") \ 36.15 + \ 36.16 + develop(bool, TraceRangeCheckElimination, false, \ 36.17 + "Trace Range Check Elimination") \ 36.18 + \ 36.19 + develop(bool, AssertRangeCheckElimination, false, \ 36.20 + "Assert Range Check Elimination") \ 36.21 + \ 36.22 + develop(bool, StressRangeCheckElimination, false, \ 36.23 + "stress Range Check Elimination") \ 36.24 + \ 36.25 develop(bool, PrintValueNumbering, false, \ 36.26 "Print Value Numbering") \ 36.27 \
37.1 --- a/src/share/vm/compiler/compileBroker.cpp Wed Mar 20 17:04:45 2013 -0700 37.2 +++ b/src/share/vm/compiler/compileBroker.cpp Thu Mar 21 09:27:54 2013 +0100 37.3 @@ -2166,6 +2166,9 @@ 37.4 comp->print_timers(); 37.5 } 37.6 tty->cr(); 37.7 + tty->print_cr(" Total compiled methods : %6d methods", CompileBroker::_total_compile_count); 37.8 + tty->print_cr(" Standard compilation : %6d methods", CompileBroker::_total_standard_compile_count); 37.9 + tty->print_cr(" On stack replacement : %6d methods", CompileBroker::_total_osr_compile_count); 37.10 int tcb = CompileBroker::_sum_osr_bytes_compiled + CompileBroker::_sum_standard_bytes_compiled; 37.11 tty->print_cr(" Total compiled bytecodes : %6d bytes", tcb); 37.12 tty->print_cr(" Standard compilation : %6d bytes", CompileBroker::_sum_standard_bytes_compiled);
38.1 --- a/src/share/vm/oops/instanceKlass.cpp Wed Mar 20 17:04:45 2013 -0700 38.2 +++ b/src/share/vm/oops/instanceKlass.cpp Thu Mar 21 09:27:54 2013 +0100 38.3 @@ -2228,8 +2228,6 @@ 38.4 } 38.5 38.6 void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) { 38.7 -#ifdef COMPILER2 38.8 - // Currently only used by C2. 38.9 for (int m = 0; m < methods()->length(); m++) { 38.10 MethodData* mdo = methods()->at(m)->method_data(); 38.11 if (mdo != NULL) { 38.12 @@ -2240,15 +2238,6 @@ 38.13 } 38.14 } 38.15 } 38.16 -#else 38.17 -#ifdef ASSERT 38.18 - // Verify that we haven't started to use MDOs for C1. 38.19 - for (int m = 0; m < methods()->length(); m++) { 38.20 - MethodData* mdo = methods()->at(m)->method_data(); 38.21 - assert(mdo == NULL, "Didn't expect C1 to use MDOs"); 38.22 - } 38.23 -#endif // ASSERT 38.24 -#endif // !COMPILER2 38.25 } 38.26 38.27
39.1 --- a/src/share/vm/oops/methodData.cpp Wed Mar 20 17:04:45 2013 -0700 39.2 +++ b/src/share/vm/oops/methodData.cpp Thu Mar 21 09:27:54 2013 +0100 39.3 @@ -392,6 +392,9 @@ 39.4 } 39.5 39.6 int MethodData::bytecode_cell_count(Bytecodes::Code code) { 39.7 +#if defined(COMPILER1) && !defined(COMPILER2) 39.8 + return no_profile_data; 39.9 +#else 39.10 switch (code) { 39.11 case Bytecodes::_checkcast: 39.12 case Bytecodes::_instanceof: 39.13 @@ -438,6 +441,7 @@ 39.14 return variable_cell_count; 39.15 } 39.16 return no_profile_data; 39.17 +#endif 39.18 } 39.19 39.20 // Compute the size of the profiling information corresponding to 39.21 @@ -509,6 +513,9 @@ 39.22 // the segment in bytes. 39.23 int MethodData::initialize_data(BytecodeStream* stream, 39.24 int data_index) { 39.25 +#if defined(COMPILER1) && !defined(COMPILER2) 39.26 + return 0; 39.27 +#else 39.28 int cell_count = -1; 39.29 int tag = DataLayout::no_tag; 39.30 DataLayout* data_layout = data_layout_at(data_index); 39.31 @@ -587,6 +594,7 @@ 39.32 assert(!bytecode_has_profile(c), "agree w/ !BHP"); 39.33 return 0; 39.34 } 39.35 +#endif 39.36 } 39.37 39.38 // Get the data at an arbitrary (sort of) data index.
40.1 --- a/src/share/vm/runtime/globals.hpp Wed Mar 20 17:04:45 2013 -0700 40.2 +++ b/src/share/vm/runtime/globals.hpp Thu Mar 21 09:27:54 2013 +0100 40.3 @@ -2515,7 +2515,7 @@ 40.4 "disable locking assertions (for speed)") \ 40.5 \ 40.6 product(bool, RangeCheckElimination, true, \ 40.7 - "Split loop iterations to eliminate range checks") \ 40.8 + "Eliminate range checks") \ 40.9 \ 40.10 develop_pd(bool, UncommonNullCast, \ 40.11 "track occurrences of null in casts; adjust compiler tactics") \