< prev index next >

src/hotspot/share/opto/loopnode.cpp

Print this page

        

@@ -38,10 +38,14 @@
 #include "opto/idealGraphPrinter.hpp"
 #include "opto/loopnode.hpp"
 #include "opto/mulnode.hpp"
 #include "opto/rootnode.hpp"
 #include "opto/superword.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
+#endif
 
 //=============================================================================
 //------------------------------is_loop_iv-------------------------------------
 // Determine if a node is Counted loop induction variable.
 // The method is declared in node.hpp.

@@ -2711,11 +2715,16 @@
 
 //=============================================================================
 //----------------------------build_and_optimize-------------------------------
 // Create a PhaseLoop.  Build the ideal Loop tree.  Map each Ideal Node to
 // its corresponding LoopNode.  If 'optimize' is true, do some loop cleanups.
-void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts, bool last_round) {
+void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
+  bool do_split_ifs = (mode == LoopOptsDefault || mode == LoopOptsZgcLastRound);
+  bool skip_loop_opts = (mode == LoopOptsNone) ;
+  bool shenandoah_opts = (mode == LoopOptsShenandoahExpand ||
+                          mode == LoopOptsShenandoahPostExpand);
+
   ResourceMark rm;
 
   int old_progress = C->major_progress();
   uint orig_worklist_size = _igvn._worklist.size();
 

@@ -2775,11 +2784,11 @@
     }
     return;
   }
 
   // Nothing to do, so get out
-  bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only;
+  bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only && !shenandoah_opts;
   bool do_expensive_nodes = C->should_optimize_expensive_nodes(_igvn);
   if (stop_early && !do_expensive_nodes) {
     _igvn.optimize();           // Cleanup NeverBranches
     return;
   }

@@ -2854,12 +2863,13 @@
   visited.set( C->top()->_idx ); // Set C->top() as visited now
   build_loop_early( visited, worklist, nstack );
 
   // Given early legal placement, try finding counted loops.  This placement
   // is good enough to discover most loop invariants.
-  if( !_verify_me && !_verify_only )
-    _ltree_root->counted_loop( this );
+  if (!_verify_me && !_verify_only && !shenandoah_opts) {
+    _ltree_root->counted_loop(this);
+  }
 
   // Find latest loop placement.  Find ideal loop placement.
   visited.Clear();
   init_dom_lca_tags();
   // Need C->root() on worklist when processing outs

@@ -2926,10 +2936,20 @@
       log_loop_tree(_ltree_root, _ltree_root, C->log());
     }
     return;
   }
 
+#if INCLUDE_SHENANDOAHGC
+  if (UseShenandoahGC && ((ShenandoahBarrierSetC2*) BarrierSet::barrier_set()->barrier_set_c2())->optimize_loops(this, mode, visited, nstack, worklist)) {
+    _igvn.optimize();
+    if (C->log() != NULL) {
+      log_loop_tree(_ltree_root, _ltree_root, C->log());
+    }
+    return;
+  }
+#endif
+
   if (ReassociateInvariants) {
     // Reassociate invariants and prep for split_thru_phi
     for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
       IdealLoopTree* lpt = iter.current();
       bool is_counted = lpt->is_counted();

@@ -2953,13 +2973,13 @@
 
   // Check for aggressive application of split-if and other transforms
   // that require basic-block info (like cloning through Phi's)
   if( SplitIfBlocks && do_split_ifs ) {
     visited.Clear();
-    split_if_with_blocks( visited, nstack, last_round );
+    split_if_with_blocks( visited, nstack, mode == LoopOptsZgcLastRound );
     NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); );
-    if (last_round) {
+    if (mode == LoopOptsZgcLastRound) {
       C->set_major_progress();
     }
   }
 
   if (!C->major_progress() && do_expensive_nodes && process_expensive_nodes()) {

@@ -3956,11 +3976,12 @@
       Node* s = mem->fast_out(i);
       worklist.push(s);
     }
     while(worklist.size() != 0 && LCA != early) {
       Node* s = worklist.pop();
-      if (s->is_Load() || s->Opcode() == Op_SafePoint) {
+      if (s->is_Load() || s->is_ShenandoahBarrier() || s->Opcode() == Op_SafePoint ||
+          (UseShenandoahGC && s->is_CallStaticJava() && s->as_CallStaticJava()->uncommon_trap_request() != 0)) {
         continue;
       } else if (s->is_MergeMem()) {
         for (DUIterator_Fast imax, i = s->fast_outs(imax); i < imax; i++) {
           Node* s1 = s->fast_out(i);
           worklist.push(s1);

@@ -4144,11 +4165,13 @@
   if (get_loop(least)->_nest == 0) {
     return;
   }
   IdealLoopTree* loop = get_loop(least);
   Node* head = loop->_head;
-  if (head->is_OuterStripMinedLoop()) {
+  if (head->is_OuterStripMinedLoop() &&
+      // Verification can't be applied to fully built strip mined loops
+      head->as_Loop()->outer_loop_end()->in(1)->find_int_con(-1) == 0) {
     Node* sfpt = head->as_Loop()->outer_safepoint();
     ResourceMark rm;
     Unique_Node_List wq;
     wq.push(sfpt);
     for (uint i = 0; i < wq.size(); i++) {

@@ -4224,10 +4247,13 @@
     case Op_StrIndexOfChar:
     case Op_AryEq:
     case Op_HasNegatives:
       pinned = false;
     }
+    if (UseShenandoahGC && n->is_CMove()) {
+      pinned = false;
+    }
     if( pinned ) {
       IdealLoopTree *chosen_loop = get_loop(n->is_CFG() ? n : get_ctrl(n));
       if( !chosen_loop->_child )       // Inner loop?
         chosen_loop->_body.push(n); // Collect inner loops
       return;

@@ -4488,10 +4514,11 @@
         }
       }
     }
   }
 }
+#endif
 
 // Collect a R-P-O for the whole CFG.
 // Result list is in post-order (scan backwards for RPO)
 void PhaseIdealLoop::rpo( Node *start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list ) const {
   stk.push(start, 0);

@@ -4510,11 +4537,10 @@
       rpo_list.push(m);
       stk.pop();
     }
   }
 }
-#endif
 
 
 //=============================================================================
 //------------------------------LoopTreeIterator-----------------------------------
 
< prev index next >