8218874: C2: Unsafe to access PhaseIdealLoop outside of constructors
Reviewed-by: thartmann, kvn
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Thu Feb 14 15:27:12 2019 -0800
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Thu Feb 14 15:27:12 2019 -0800
@@ -130,7 +130,7 @@
ZBarrierSetC2State* s = bs->state();
if (s->load_barrier_count() >= 2) {
Compile::TracePhase tp("idealLoop", &C->timers[Phase::_t_idealLoop]);
- PhaseIdealLoop ideal_loop(igvn, LoopOptsLastRound);
+ PhaseIdealLoop::optimize(igvn, LoopOptsLastRound);
if (C->major_progress()) C->print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
}
}
--- a/src/hotspot/share/opto/compile.cpp Thu Feb 14 15:27:12 2019 -0800
+++ b/src/hotspot/share/opto/compile.cpp Thu Feb 14 15:27:12 2019 -0800
@@ -2112,7 +2112,7 @@
// PhaseIdealLoop is expensive so we only try it once we are
// out of live nodes and we only try it again if the previous
// helped got the number of nodes down significantly
- PhaseIdealLoop ideal_loop(igvn, LoopOptsNone);
+ PhaseIdealLoop::optimize(igvn, LoopOptsNone);
if (failing()) return;
low_live_nodes = live_nodes();
_major_progress = true;
@@ -2160,7 +2160,7 @@
while(major_progress() && (_loop_opts_cnt > 0)) {
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
assert( cnt++ < 40, "infinite cycle in loop optimization" );
- PhaseIdealLoop ideal_loop(igvn, mode);
+ PhaseIdealLoop::optimize(igvn, mode);
_loop_opts_cnt--;
if (failing()) return false;
if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
@@ -2282,7 +2282,7 @@
if (has_loops()) {
// Cleanup graph (remove dead nodes).
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
- PhaseIdealLoop ideal_loop(igvn, LoopOptsNone);
+ PhaseIdealLoop::optimize(igvn, LoopOptsNone);
if (major_progress()) print_method(PHASE_PHASEIDEAL_BEFORE_EA, 2);
if (failing()) return;
}
@@ -2316,7 +2316,7 @@
if((_loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) {
{
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
- PhaseIdealLoop ideal_loop(igvn, LoopOptsDefault);
+ PhaseIdealLoop::optimize(igvn, LoopOptsDefault);
_loop_opts_cnt--;
if (major_progress()) print_method(PHASE_PHASEIDEALLOOP1, 2);
if (failing()) return;
@@ -2324,7 +2324,7 @@
// Loop opts pass if partial peeling occurred in previous pass
if(PartialPeelLoop && major_progress() && (_loop_opts_cnt > 0)) {
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
- PhaseIdealLoop ideal_loop(igvn, LoopOptsSkipSplitIf);
+ PhaseIdealLoop::optimize(igvn, LoopOptsSkipSplitIf);
_loop_opts_cnt--;
if (major_progress()) print_method(PHASE_PHASEIDEALLOOP2, 2);
if (failing()) return;
@@ -2332,7 +2332,7 @@
// Loop opts pass for loop-unrolling before CCP
if(major_progress() && (_loop_opts_cnt > 0)) {
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
- PhaseIdealLoop ideal_loop(igvn, LoopOptsSkipSplitIf);
+ PhaseIdealLoop::optimize(igvn, LoopOptsSkipSplitIf);
_loop_opts_cnt--;
if (major_progress()) print_method(PHASE_PHASEIDEALLOOP3, 2);
}
--- a/src/hotspot/share/opto/loopnode.cpp Thu Feb 14 15:27:12 2019 -0800
+++ b/src/hotspot/share/opto/loopnode.cpp Thu Feb 14 15:27:12 2019 -0800
@@ -2712,8 +2712,6 @@
bool do_split_ifs = (mode == LoopOptsDefault || mode == LoopOptsLastRound);
bool skip_loop_opts = (mode == LoopOptsNone);
- ResourceMark rm;
-
int old_progress = C->major_progress();
uint orig_worklist_size = _igvn._worklist.size();
--- a/src/hotspot/share/opto/loopnode.hpp Thu Feb 14 15:27:12 2019 -0800
+++ b/src/hotspot/share/opto/loopnode.hpp Thu Feb 14 15:27:12 2019 -0800
@@ -880,6 +880,42 @@
uint *_dom_depth; // Used for fast LCA test
GrowableArray<uint>* _dom_stk; // For recomputation of dom depth
+ // Perform verification that the graph is valid.
+ PhaseIdealLoop( PhaseIterGVN &igvn) :
+ PhaseTransform(Ideal_Loop),
+ _igvn(igvn),
+ _verify_me(NULL),
+ _verify_only(true),
+ _dom_lca_tags(arena()) { // Thread::resource_area
+ build_and_optimize(LoopOptsVerify);
+ }
+
+ // build the loop tree and perform any requested optimizations
+ void build_and_optimize(LoopOptsMode mode);
+
+ // Dominators for the sea of nodes
+ void Dominators();
+
+ // Compute the Ideal Node to Loop mapping
+ PhaseIdealLoop(PhaseIterGVN &igvn, LoopOptsMode mode) :
+ PhaseTransform(Ideal_Loop),
+ _igvn(igvn),
+ _verify_me(NULL),
+ _verify_only(false),
+ _dom_lca_tags(arena()) { // Thread::resource_area
+ build_and_optimize(mode);
+ }
+
+ // Verify that verify_me made the same decisions as a fresh run.
+ PhaseIdealLoop(PhaseIterGVN &igvn, const PhaseIdealLoop *verify_me) :
+ PhaseTransform(Ideal_Loop),
+ _igvn(igvn),
+ _verify_me(verify_me),
+ _verify_only(false),
+ _dom_lca_tags(arena()) { // Thread::resource_area
+ build_and_optimize(LoopOptsVerify);
+ }
+
public:
Node* idom_no_update(Node* d) const {
return idom_no_update(d->_idx);
@@ -923,54 +959,27 @@
// Replace parallel induction variable (parallel to trip counter)
void replace_parallel_iv(IdealLoopTree *loop);
- // Perform verification that the graph is valid.
- PhaseIdealLoop( PhaseIterGVN &igvn) :
- PhaseTransform(Ideal_Loop),
- _igvn(igvn),
- _verify_me(NULL),
- _verify_only(true),
- _dom_lca_tags(arena()) { // Thread::resource_area
- build_and_optimize(LoopOptsVerify);
- }
-
- // build the loop tree and perform any requested optimizations
- void build_and_optimize(LoopOptsMode mode);
-
- // Dominators for the sea of nodes
- void Dominators();
Node *dom_lca( Node *n1, Node *n2 ) const {
return find_non_split_ctrl(dom_lca_internal(n1, n2));
}
Node *dom_lca_internal( Node *n1, Node *n2 ) const;
- // Compute the Ideal Node to Loop mapping
- PhaseIdealLoop(PhaseIterGVN &igvn, LoopOptsMode mode) :
- PhaseTransform(Ideal_Loop),
- _igvn(igvn),
- _verify_me(NULL),
- _verify_only(false),
- _dom_lca_tags(arena()) { // Thread::resource_area
- build_and_optimize(mode);
- }
-
- // Verify that verify_me made the same decisions as a fresh run.
- PhaseIdealLoop(PhaseIterGVN &igvn, const PhaseIdealLoop *verify_me) :
- PhaseTransform(Ideal_Loop),
- _igvn(igvn),
- _verify_me(verify_me),
- _verify_only(false),
- _dom_lca_tags(arena()) { // Thread::resource_area
- build_and_optimize(LoopOptsVerify);
- }
-
// Build and verify the loop tree without modifying the graph. This
// is useful to verify that all inputs properly dominate their uses.
static void verify(PhaseIterGVN& igvn) {
#ifdef ASSERT
+ ResourceMark rm;
PhaseIdealLoop v(igvn);
#endif
}
+ // Recommended way to use PhaseIdealLoop.
+ // Run PhaseIdealLoop in some mode and allocates a local scope for memory allocations.
+ static void optimize(PhaseIterGVN &igvn, LoopOptsMode mode) {
+ ResourceMark rm;
+ PhaseIdealLoop v(igvn, mode);
+ }
+
// True if the method has at least 1 irreducible loop
bool _has_irreducible_loops;