Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/compile.cpp @ 23872:94ec11846b18 jdk8u74-b32
6675699: need comprehensive fix for unconstrained ConvI2L with narrowed type
Summary: Emit CastII to make narrow ConvI2L dependent on the corresponding range check.
Reviewed-by: kvn, roland
author | thartmann |
---|---|
date | Wed, 27 Jan 2016 09:02:51 +0100 |
parents | c1091733abe6 |
children | c42cb5db3601 |
comparison
equal
deleted
inserted
replaced
23860:1c7a0413e1f3 | 23872:94ec11846b18 |
---|---|
410 Node* n = C->macro_node(i); | 410 Node* n = C->macro_node(i); |
411 if (!useful.member(n)) { | 411 if (!useful.member(n)) { |
412 remove_macro_node(n); | 412 remove_macro_node(n); |
413 } | 413 } |
414 } | 414 } |
415 // Remove useless CastII nodes with range check dependency | |
416 for (int i = range_check_cast_count() - 1; i >= 0; i--) { | |
417 Node* cast = range_check_cast_node(i); | |
418 if (!useful.member(cast)) { | |
419 remove_range_check_cast(cast); | |
420 } | |
421 } | |
415 // Remove useless expensive node | 422 // Remove useless expensive node |
416 for (int i = C->expensive_count()-1; i >= 0; i--) { | 423 for (int i = C->expensive_count()-1; i >= 0; i--) { |
417 Node* n = C->expensive_node(i); | 424 Node* n = C->expensive_node(i); |
418 if (!useful.member(n)) { | 425 if (!useful.member(n)) { |
419 remove_expensive_node(n); | 426 remove_expensive_node(n); |
1146 | 1153 |
1147 _intrinsics = NULL; | 1154 _intrinsics = NULL; |
1148 _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | 1155 _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
1149 _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | 1156 _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
1150 _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | 1157 _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
1158 _range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | |
1151 register_library_intrinsics(); | 1159 register_library_intrinsics(); |
1152 } | 1160 } |
1153 | 1161 |
1154 //---------------------------init_start---------------------------------------- | 1162 //---------------------------init_start---------------------------------------- |
1155 // Install the StartNode on this compile object. | 1163 // Install the StartNode on this compile object. |
1874 igvn.replace_node(n, n->in(1)); | 1882 igvn.replace_node(n, n->in(1)); |
1875 } | 1883 } |
1876 assert(predicate_count()==0, "should be clean!"); | 1884 assert(predicate_count()==0, "should be clean!"); |
1877 } | 1885 } |
1878 | 1886 |
1887 void Compile::add_range_check_cast(Node* n) { | |
1888 assert(n->isa_CastII()->has_range_check(), "CastII should have range check dependency"); | |
1889 assert(!_range_check_casts->contains(n), "duplicate entry in range check casts"); | |
1890 _range_check_casts->append(n); | |
1891 } | |
1892 | |
1893 // Remove all range check dependent CastIINodes. | |
1894 void Compile::remove_range_check_casts(PhaseIterGVN &igvn) { | |
1895 for (int i = range_check_cast_count(); i > 0; i--) { | |
1896 Node* cast = range_check_cast_node(i-1); | |
1897 assert(cast->isa_CastII()->has_range_check(), "CastII should have range check dependency"); | |
1898 igvn.replace_node(cast, cast->in(1)); | |
1899 } | |
1900 assert(range_check_cast_count() == 0, "should be empty"); | |
1901 } | |
1902 | |
1879 // StringOpts and late inlining of string methods | 1903 // StringOpts and late inlining of string methods |
1880 void Compile::inline_string_calls(bool parse_time) { | 1904 void Compile::inline_string_calls(bool parse_time) { |
1881 { | 1905 { |
1882 // remove useless nodes to make the usage analysis simpler | 1906 // remove useless nodes to make the usage analysis simpler |
1883 ResourceMark rm; | 1907 ResourceMark rm; |
2200 { | 2224 { |
2201 // Verify that all previous optimizations produced a valid graph | 2225 // Verify that all previous optimizations produced a valid graph |
2202 // at least to this point, even if no loop optimizations were done. | 2226 // at least to this point, even if no loop optimizations were done. |
2203 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) | 2227 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) |
2204 PhaseIdealLoop::verify(igvn); | 2228 PhaseIdealLoop::verify(igvn); |
2229 } | |
2230 | |
2231 if (range_check_cast_count() > 0) { | |
2232 // No more loop optimizations. Remove all range check dependent CastIINodes. | |
2233 C->remove_range_check_casts(igvn); | |
2234 igvn.optimize(); | |
2205 } | 2235 } |
2206 | 2236 |
2207 { | 2237 { |
2208 NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); ) | 2238 NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); ) |
2209 PhaseMacroExpand mex(igvn); | 2239 PhaseMacroExpand mex(igvn); |
2971 } | 3001 } |
2972 break; | 3002 break; |
2973 | 3003 |
2974 #endif | 3004 #endif |
2975 | 3005 |
3006 #ifdef ASSERT | |
3007 case Op_CastII: | |
3008 // Verify that all range check dependent CastII nodes were removed. | |
3009 if (n->isa_CastII()->has_range_check()) { | |
3010 n->dump(3); | |
3011 assert(false, "Range check dependent CastII node was not removed"); | |
3012 } | |
3013 break; | |
3014 #endif | |
3015 | |
2976 case Op_ModI: | 3016 case Op_ModI: |
2977 if (UseDivMod) { | 3017 if (UseDivMod) { |
2978 // Check if a%b and a/b both exist | 3018 // Check if a%b and a/b both exist |
2979 Node* d = n->find_similar(Op_DivI); | 3019 Node* d = n->find_similar(Op_DivI); |
2980 if (d) { | 3020 if (d) { |
4008 igvn.check_no_speculative_types(); | 4048 igvn.check_no_speculative_types(); |
4009 #endif | 4049 #endif |
4010 } | 4050 } |
4011 } | 4051 } |
4012 | 4052 |
4053 // Convert integer value to a narrowed long type dependent on ctrl (for example, a range check) | |
4054 Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl) { | |
4055 if (ctrl != NULL) { | |
4056 // Express control dependency by a CastII node with a narrow type. | |
4057 value = new (phase->C) CastIINode(value, itype, false, true /* range check dependency */); | |
4058 // Make the CastII node dependent on the control input to prevent the narrowed ConvI2L | |
4059 // node from floating above the range check during loop optimizations. Otherwise, the | |
4060 // ConvI2L node may be eliminated independently of the range check, causing the data path | |
4061 // to become TOP while the control path is still there (although it's unreachable). | |
4062 value->set_req(0, ctrl); | |
4063 // Save CastII node to remove it after loop optimizations. | |
4064 phase->C->add_range_check_cast(value); | |
4065 value = phase->transform(value); | |
4066 } | |
4067 const TypeLong* ltype = TypeLong::make(itype->_lo, itype->_hi, itype->_widen); | |
4068 return phase->transform(new (phase->C) ConvI2LNode(value, ltype)); | |
4069 } | |
4070 | |
4013 // Auxiliary method to support randomized stressing/fuzzing. | 4071 // Auxiliary method to support randomized stressing/fuzzing. |
4014 // | 4072 // |
4015 // This method can be called the arbitrary number of times, with current count | 4073 // This method can be called the arbitrary number of times, with current count |
4016 // as the argument. The logic allows selecting a single candidate from the | 4074 // as the argument. The logic allows selecting a single candidate from the |
4017 // running list of candidates as follows: | 4075 // running list of candidates as follows: |