changeset 39:76256d272075

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
author kvn
date Thu, 06 Mar 2008 10:53:33 -0800
parents b789bcaf2dd9
children 7c1f32ae4a20
files src/share/vm/opto/callnode.cpp src/share/vm/opto/callnode.hpp src/share/vm/opto/escape.cpp src/share/vm/opto/loopTransform.cpp src/share/vm/opto/loopnode.cpp src/share/vm/opto/loopnode.hpp
diffstat 6 files changed, 20 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/callnode.cpp	Thu Mar 06 10:30:17 2008 -0800
+++ b/src/share/vm/opto/callnode.cpp	Thu Mar 06 10:53:33 2008 -0800
@@ -832,6 +832,7 @@
 {
   init_class_id(Class_Allocate);
   init_flags(Flag_is_macro);
+  _is_scalar_replaceable = false;
   Node *topnode = C->top();
 
   init_req( TypeFunc::Control  , ctrl );
--- a/src/share/vm/opto/callnode.hpp	Thu Mar 06 10:30:17 2008 -0800
+++ b/src/share/vm/opto/callnode.hpp	Thu Mar 06 10:53:33 2008 -0800
@@ -626,6 +626,8 @@
     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);
--- a/src/share/vm/opto/escape.cpp	Thu Mar 06 10:30:17 2008 -0800
+++ b/src/share/vm/opto/escape.cpp	Thu Mar 06 10:53:33 2008 -0800
@@ -601,6 +601,11 @@
       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();
--- a/src/share/vm/opto/loopTransform.cpp	Thu Mar 06 10:30:17 2008 -0800
+++ b/src/share/vm/opto/loopTransform.cpp	Thu Mar 06 10:53:33 2008 -0800
@@ -1714,6 +1714,7 @@
   // 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 );
--- a/src/share/vm/opto/loopnode.cpp	Thu Mar 06 10:30:17 2008 -0800
+++ b/src/share/vm/opto/loopnode.cpp	Thu Mar 06 10:53:33 2008 -0800
@@ -1561,7 +1561,7 @@
       // 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 @@
     // 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 @@
               (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
       }
     }
   }
--- a/src/share/vm/opto/loopnode.hpp	Thu Mar 06 10:30:17 2008 -0800
+++ b/src/share/vm/opto/loopnode.hpp	Thu Mar 06 10:53:33 2008 -0800
@@ -289,13 +289,15 @@
         _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)
   { }