1.1 --- a/src/share/vm/opto/compile.cpp Mon Feb 22 13:39:47 2016 -0800 1.2 +++ b/src/share/vm/opto/compile.cpp Tue Mar 01 15:19:31 2016 -0800 1.3 @@ -412,6 +412,13 @@ 1.4 remove_macro_node(n); 1.5 } 1.6 } 1.7 + // Remove useless CastII nodes with range check dependency 1.8 + for (int i = range_check_cast_count() - 1; i >= 0; i--) { 1.9 + Node* cast = range_check_cast_node(i); 1.10 + if (!useful.member(cast)) { 1.11 + remove_range_check_cast(cast); 1.12 + } 1.13 + } 1.14 // Remove useless expensive node 1.15 for (int i = C->expensive_count()-1; i >= 0; i--) { 1.16 Node* n = C->expensive_node(i); 1.17 @@ -1148,6 +1155,7 @@ 1.18 _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); 1.19 _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); 1.20 _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); 1.21 + _range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); 1.22 register_library_intrinsics(); 1.23 } 1.24 1.25 @@ -1876,6 +1884,22 @@ 1.26 assert(predicate_count()==0, "should be clean!"); 1.27 } 1.28 1.29 +void Compile::add_range_check_cast(Node* n) { 1.30 + assert(n->isa_CastII()->has_range_check(), "CastII should have range check dependency"); 1.31 + assert(!_range_check_casts->contains(n), "duplicate entry in range check casts"); 1.32 + _range_check_casts->append(n); 1.33 +} 1.34 + 1.35 +// Remove all range check dependent CastIINodes. 1.36 +void Compile::remove_range_check_casts(PhaseIterGVN &igvn) { 1.37 + for (int i = range_check_cast_count(); i > 0; i--) { 1.38 + Node* cast = range_check_cast_node(i-1); 1.39 + assert(cast->isa_CastII()->has_range_check(), "CastII should have range check dependency"); 1.40 + igvn.replace_node(cast, cast->in(1)); 1.41 + } 1.42 + assert(range_check_cast_count() == 0, "should be empty"); 1.43 +} 1.44 + 1.45 // StringOpts and late inlining of string methods 1.46 void Compile::inline_string_calls(bool parse_time) { 1.47 { 1.48 @@ -2218,6 +2242,12 @@ 1.49 PhaseIdealLoop::verify(igvn); 1.50 } 1.51 1.52 + if (range_check_cast_count() > 0) { 1.53 + // No more loop optimizations. Remove all range check dependent CastIINodes. 1.54 + C->remove_range_check_casts(igvn); 1.55 + igvn.optimize(); 1.56 + } 1.57 + 1.58 { 1.59 NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); ) 1.60 PhaseMacroExpand mex(igvn); 1.61 @@ -2987,6 +3017,16 @@ 1.62 1.63 #endif 1.64 1.65 +#ifdef ASSERT 1.66 + case Op_CastII: 1.67 + // Verify that all range check dependent CastII nodes were removed. 1.68 + if (n->isa_CastII()->has_range_check()) { 1.69 + n->dump(3); 1.70 + assert(false, "Range check dependent CastII node was not removed"); 1.71 + } 1.72 + break; 1.73 +#endif 1.74 + 1.75 case Op_ModI: 1.76 if (UseDivMod) { 1.77 // Check if a%b and a/b both exist 1.78 @@ -4024,6 +4064,24 @@ 1.79 } 1.80 } 1.81 1.82 +// Convert integer value to a narrowed long type dependent on ctrl (for example, a range check) 1.83 +Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl) { 1.84 + if (ctrl != NULL) { 1.85 + // Express control dependency by a CastII node with a narrow type. 1.86 + value = new (phase->C) CastIINode(value, itype, false, true /* range check dependency */); 1.87 + // Make the CastII node dependent on the control input to prevent the narrowed ConvI2L 1.88 + // node from floating above the range check during loop optimizations. Otherwise, the 1.89 + // ConvI2L node may be eliminated independently of the range check, causing the data path 1.90 + // to become TOP while the control path is still there (although it's unreachable). 1.91 + value->set_req(0, ctrl); 1.92 + // Save CastII node to remove it after loop optimizations. 1.93 + phase->C->add_range_check_cast(value); 1.94 + value = phase->transform(value); 1.95 + } 1.96 + const TypeLong* ltype = TypeLong::make(itype->_lo, itype->_hi, itype->_widen); 1.97 + return phase->transform(new (phase->C) ConvI2LNode(value, ltype)); 1.98 +} 1.99 + 1.100 // Auxiliary method to support randomized stressing/fuzzing. 1.101 // 1.102 // This method can be called the arbitrary number of times, with current count