< prev index next >

src/share/vm/opto/gcm.cpp

Print this page

        

@@ -39,10 +39,12 @@
 # include AD_MD_HPP
 #elif defined TARGET_ARCH_MODEL_x86_32
 # include "adfiles/ad_x86_32.hpp"
 #elif defined TARGET_ARCH_MODEL_x86_64
 # include "adfiles/ad_x86_64.hpp"
+#elif defined TARGET_ARCH_MODEL_aarch64
+# include "adfiles/ad_aarch64.hpp"
 #elif defined TARGET_ARCH_MODEL_sparc
 # include "adfiles/ad_sparc.hpp"
 #elif defined TARGET_ARCH_MODEL_zero
 # include "adfiles/ad_zero.hpp"
 #elif defined TARGET_ARCH_MODEL_ppc_64

@@ -112,10 +114,13 @@
     }
     n->set_req(0, pb->_succs[j]->head());
   }
 }
 
+static bool is_dominator(Block* d, Block* n) {
+  return d->dom_lca(n) == d;
+}
 
 //------------------------------schedule_pinned_nodes--------------------------
 // Set the basic block for Nodes pinned into blocks
 void PhaseCFG::schedule_pinned_nodes(VectorSet &visited) {
   // Allocate node stack of size C->live_nodes()+8 to avoid frequent realloc

@@ -134,10 +139,46 @@
         }
         Block* block = get_block_for_node(input); // Basic block of controlling input
         schedule_node_into_block(node, block);
       }
 
+      // If the node has precedence edges (added when CastPP nodes are
+      // removed in final_graph_reshaping), fix the control of the
+      // node to cover the precedence edges and remove the
+      // dependencies.
+      Node* n = NULL;
+      for (uint i = node->len()-1; i >= node->req(); i--) {
+        Node* m = node->in(i);
+        if (m == NULL) continue;
+        // Skip the precedence edge if the test that guarded a CastPP:
+        // - was optimized out during escape analysis
+        // (OptimizePtrCompare): the CastPP's control isn't an end of
+        // block.
+        // - is moved in the branch of a dominating If: the control of
+        // the CastPP is then a Region.
+        if (m->is_block_proj() || m->is_block_start()) {
+          node->rm_prec(i);
+          if (n == NULL) {
+            n = m;
+          } else {
+            Block* bn = get_block_for_node(n);
+            Block* bm = get_block_for_node(m);
+            assert(is_dominator(bn, bm) || is_dominator(bm, bn), "one must dominate the other");
+            n = is_dominator(bn, bm) ? m : n;
+          }
+        }
+      }
+      if (n != NULL) {
+        assert(node->in(0), "control should have been set");
+        Block* bn = get_block_for_node(n);
+        Block* bnode = get_block_for_node(node->in(0));
+        assert(is_dominator(bn, bnode) || is_dominator(bnode, bn), "one must dominate the other");
+        if (!is_dominator(bn, bnode)) {
+          node->set_req(0, n);
+        }
+      }
+
       // process all inputs that are non NULL
       for (int i = node->req() - 1; i >= 0; --i) {
         if (node->in(i) != NULL) {
           spstack.push(node->in(i));
         }

@@ -246,10 +287,11 @@
         }
 
         int is_visited = visited.test_set(in->_idx);
         if (!has_block(in)) {
           if (is_visited) {
+            assert(false, "graph should be schedulable");
             return false;
           }
           // Save parent node and next input's index.
           nstack.push(parent_node, input_index);
           // Process current input now.

@@ -1060,10 +1102,11 @@
   while (LCA != early) {
     LCA = LCA->_idom;         // Follow up the dominator tree
 
     if (LCA == NULL) {
       // Bailout without retry
+      assert(false, "graph should be schedulable");
       C->record_method_not_compilable("late schedule failed: LCA == NULL");
       return least;
     }
 
     // Don't hoist machine instructions to the root basic block

@@ -1214,10 +1257,11 @@
         // If this is the first failure, the sentinel string will "stick"
         // to the Compile object, and the C2Compiler will see it and retry.
         C->record_failure(C2Compiler::retry_no_subsuming_loads());
       } else {
         // Bailout without retry when (early->_dom_depth > LCA->_dom_depth)
+        assert(false, "graph should be schedulable");
         C->record_method_not_compilable("late schedule failed: incorrect graph");
       }
       return;
     }
 
< prev index next >