From e6b166f22d08d43c7edf4a0fbe17490597f68631 Mon Sep 17 00:00:00 2001 From: kvn Date: Thu, 6 Mar 2008 10:53:33 -0800 Subject: [PATCH] 6667612: (Escape Analysis) disable loop cloning if it has a scalar replaceable allocation Summary: Cloning an allocation will not allow scalar replacement since memory operations could not be associated with one allocation. Reviewed-by: rasbold --- src/share/vm/opto/callnode.cpp | 1 + src/share/vm/opto/callnode.hpp | 2 ++ src/share/vm/opto/escape.cpp | 5 +++++ src/share/vm/opto/loopTransform.cpp | 1 + src/share/vm/opto/loopnode.cpp | 10 ++++++++-- src/share/vm/opto/loopnode.hpp | 4 +++- 6 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/share/vm/opto/callnode.cpp b/src/share/vm/opto/callnode.cpp index 7fb600440..f32562de0 100644 --- a/src/share/vm/opto/callnode.cpp +++ b/src/share/vm/opto/callnode.cpp @@ -832,6 +832,7 @@ AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype, { init_class_id(Class_Allocate); init_flags(Flag_is_macro); + _is_scalar_replaceable = false; Node *topnode = C->top(); init_req( TypeFunc::Control , ctrl ); diff --git a/src/share/vm/opto/callnode.hpp b/src/share/vm/opto/callnode.hpp index c8315f94c..d07a4d78d 100644 --- a/src/share/vm/opto/callnode.hpp +++ b/src/share/vm/opto/callnode.hpp @@ -626,6 +626,8 @@ public: return TypeFunc::make(domain, range); } + bool _is_scalar_replaceable; // Result of Escape Analysis + virtual uint size_of() const; // Size is bigger AllocateNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio, Node *size, Node *klass_node, Node *initial_test); diff --git a/src/share/vm/opto/escape.cpp b/src/share/vm/opto/escape.cpp index d66dd3f98..7e2a18d85 100644 --- a/src/share/vm/opto/escape.cpp +++ b/src/share/vm/opto/escape.cpp @@ -601,6 +601,11 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) if (es != PointsToNode::NoEscape || !ptn._unique_type) { continue; // can't make a unique type } + if (alloc->is_Allocate()) { + // Set the scalar_replaceable flag before the next check. + alloc->as_Allocate()->_is_scalar_replaceable = true; + } + set_map(alloc->_idx, n); set_map(n->_idx, alloc); const TypeInstPtr *t = igvn->type(n)->isa_instptr(); diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp index 3de4e0cd7..de54863b5 100644 --- a/src/share/vm/opto/loopTransform.cpp +++ b/src/share/vm/opto/loopTransform.cpp @@ -1714,6 +1714,7 @@ void IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) // Gate unrolling, RCE and peeling efforts. if( !_child && // If not an inner loop, do not split !_irreducible && + _allow_optimizations && !tail()->is_top() ) { // Also ignore the occasional dead backedge if (!_has_call) { iteration_split_impl( phase, old_new ); diff --git a/src/share/vm/opto/loopnode.cpp b/src/share/vm/opto/loopnode.cpp index 96140fae5..3ae7a4114 100644 --- a/src/share/vm/opto/loopnode.cpp +++ b/src/share/vm/opto/loopnode.cpp @@ -1561,7 +1561,7 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify // on just their loop-phi's for this pass of loop opts if( SplitIfBlocks && do_split_ifs ) { if (lpt->policy_range_check(this)) { - lpt->_rce_candidate = true; + lpt->_rce_candidate = 1; // = true } } } @@ -2145,7 +2145,7 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) { // as well? If so, then I found another entry into the loop. while( is_postvisited(l->_head) ) { // found irreducible - l->_irreducible = true; + l->_irreducible = 1; // = true l = l->_parent; _has_irreducible_loops = true; // Check for bad CFG here to prevent crash, and bailout of compile @@ -2199,6 +2199,12 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) { (iff->as_If()->_prob >= 0.01) ) innermost->_has_call = 1; } + } else if( n->is_Allocate() && n->as_Allocate()->_is_scalar_replaceable ) { + // Disable loop optimizations if the loop has a scalar replaceable + // allocation. This disabling may cause a potential performance lost + // if the allocation is not eliminated for some reason. + innermost->_allow_optimizations = false; + innermost->_has_call = 1; // = true } } } diff --git a/src/share/vm/opto/loopnode.hpp b/src/share/vm/opto/loopnode.hpp index 60944afee..4bee9655d 100644 --- a/src/share/vm/opto/loopnode.hpp +++ b/src/share/vm/opto/loopnode.hpp @@ -289,13 +289,15 @@ public: _has_sfpt:1, // True if has non-call safepoint _rce_candidate:1; // True if candidate for range check elimination - Node_List* _required_safept; // A inner loop cannot delete these safepts; + Node_List* _required_safept; // A inner loop cannot delete these safepts; + bool _allow_optimizations; // Allow loop optimizations IdealLoopTree( PhaseIdealLoop* phase, Node *head, Node *tail ) : _parent(0), _next(0), _child(0), _head(head), _tail(tail), _phase(phase), _required_safept(NULL), + _allow_optimizations(true), _nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0) { } -- GitLab