Mercurial > hg > graal-jvmci-8
diff src/share/vm/opto/compile.cpp @ 23890:445941ba41c0 jdk8u92-b31
Merge
author | asaha |
---|---|
date | Thu, 31 Mar 2016 14:23:12 -0700 |
parents | 70649f10b88c 94ec11846b18 |
children | a96cf90239c6 |
line wrap: on
line diff
--- a/src/share/vm/opto/compile.cpp Thu Mar 31 14:04:14 2016 -0700 +++ b/src/share/vm/opto/compile.cpp Thu Mar 31 14:23:12 2016 -0700 @@ -412,6 +412,13 @@ remove_macro_node(n); } } + // Remove useless CastII nodes with range check dependency + for (int i = range_check_cast_count() - 1; i >= 0; i--) { + Node* cast = range_check_cast_node(i); + if (!useful.member(cast)) { + remove_range_check_cast(cast); + } + } // Remove useless expensive node for (int i = C->expensive_count()-1; i >= 0; i--) { Node* n = C->expensive_node(i); @@ -1148,6 +1155,7 @@ _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); + _range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); register_library_intrinsics(); } @@ -1876,6 +1884,22 @@ assert(predicate_count()==0, "should be clean!"); } +void Compile::add_range_check_cast(Node* n) { + assert(n->isa_CastII()->has_range_check(), "CastII should have range check dependency"); + assert(!_range_check_casts->contains(n), "duplicate entry in range check casts"); + _range_check_casts->append(n); +} + +// Remove all range check dependent CastIINodes. +void Compile::remove_range_check_casts(PhaseIterGVN &igvn) { + for (int i = range_check_cast_count(); i > 0; i--) { + Node* cast = range_check_cast_node(i-1); + assert(cast->isa_CastII()->has_range_check(), "CastII should have range check dependency"); + igvn.replace_node(cast, cast->in(1)); + } + assert(range_check_cast_count() == 0, "should be empty"); +} + // StringOpts and late inlining of string methods void Compile::inline_string_calls(bool parse_time) { { @@ -2218,6 +2242,12 @@ PhaseIdealLoop::verify(igvn); } + if (range_check_cast_count() > 0) { + // No more loop optimizations. Remove all range check dependent CastIINodes. + C->remove_range_check_casts(igvn); + igvn.optimize(); + } + { NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); ) PhaseMacroExpand mex(igvn); @@ -2987,6 +3017,16 @@ #endif +#ifdef ASSERT + case Op_CastII: + // Verify that all range check dependent CastII nodes were removed. + if (n->isa_CastII()->has_range_check()) { + n->dump(3); + assert(false, "Range check dependent CastII node was not removed"); + } + break; +#endif + case Op_ModI: if (UseDivMod) { // Check if a%b and a/b both exist @@ -4024,6 +4064,24 @@ } } +// Convert integer value to a narrowed long type dependent on ctrl (for example, a range check) +Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl) { + if (ctrl != NULL) { + // Express control dependency by a CastII node with a narrow type. + value = new (phase->C) CastIINode(value, itype, false, true /* range check dependency */); + // Make the CastII node dependent on the control input to prevent the narrowed ConvI2L + // node from floating above the range check during loop optimizations. Otherwise, the + // ConvI2L node may be eliminated independently of the range check, causing the data path + // to become TOP while the control path is still there (although it's unreachable). + value->set_req(0, ctrl); + // Save CastII node to remove it after loop optimizations. + phase->C->add_range_check_cast(value); + value = phase->transform(value); + } + const TypeLong* ltype = TypeLong::make(itype->_lo, itype->_hi, itype->_widen); + return phase->transform(new (phase->C) ConvI2LNode(value, ltype)); +} + // Auxiliary method to support randomized stressing/fuzzing. // // This method can be called the arbitrary number of times, with current count