< prev index next >

src/share/vm/opto/gcm.cpp

Print this page




  24 
  25 #include "precompiled.hpp"
  26 #include "libadt/vectset.hpp"
  27 #include "memory/allocation.inline.hpp"
  28 #include "opto/block.hpp"
  29 #include "opto/c2compiler.hpp"
  30 #include "opto/callnode.hpp"
  31 #include "opto/cfgnode.hpp"
  32 #include "opto/machnode.hpp"
  33 #include "opto/opcodes.hpp"
  34 #include "opto/phaseX.hpp"
  35 #include "opto/rootnode.hpp"
  36 #include "opto/runtime.hpp"
  37 #include "runtime/deoptimization.hpp"
  38 #if defined AD_MD_HPP
  39 # include AD_MD_HPP
  40 #elif defined TARGET_ARCH_MODEL_x86_32
  41 # include "adfiles/ad_x86_32.hpp"
  42 #elif defined TARGET_ARCH_MODEL_x86_64
  43 # include "adfiles/ad_x86_64.hpp"


  44 #elif defined TARGET_ARCH_MODEL_sparc
  45 # include "adfiles/ad_sparc.hpp"
  46 #elif defined TARGET_ARCH_MODEL_zero
  47 # include "adfiles/ad_zero.hpp"
  48 #elif defined TARGET_ARCH_MODEL_ppc_64
  49 # include "adfiles/ad_ppc_64.hpp"
  50 #endif
  51 
  52 
  53 // Portions of code courtesy of Clifford Click
  54 
  55 // Optimization - Graph Style
  56 
  57 // To avoid float value underflow
  58 #define MIN_BLOCK_FREQUENCY 1.e-35f
  59 
  60 //----------------------------schedule_node_into_block-------------------------
  61 // Insert node n into block b. Look for projections of n and make sure they
  62 // are in b also.
  63 void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) {


  97     Block *pb = get_block_for_node(in0); // Block-projection already has basic block
  98     uint j = 0;
  99     if (pb->_num_succs != 1) {  // More then 1 successor?
 100       // Search for successor
 101       uint max = pb->number_of_nodes();
 102       assert( max > 1, "" );
 103       uint start = max - pb->_num_succs;
 104       // Find which output path belongs to projection
 105       for (j = start; j < max; j++) {
 106         if( pb->get_node(j) == in0 )
 107           break;
 108       }
 109       assert( j < max, "must find" );
 110       // Change control to match head of successor basic block
 111       j -= start;
 112     }
 113     n->set_req(0, pb->_succs[j]->head());
 114   }
 115 }
 116 



 117 
 118 //------------------------------schedule_pinned_nodes--------------------------
 119 // Set the basic block for Nodes pinned into blocks
 120 void PhaseCFG::schedule_pinned_nodes(VectorSet &visited) {
 121   // Allocate node stack of size C->live_nodes()+8 to avoid frequent realloc
 122   GrowableArray <Node *> spstack(C->live_nodes() + 8);
 123   spstack.push(_root);
 124   while (spstack.is_nonempty()) {
 125     Node* node = spstack.pop();
 126     if (!visited.test_set(node->_idx)) { // Test node and flag it as visited
 127       if (node->pinned() && !has_block(node)) {  // Pinned?  Nail it down!
 128         assert(node->in(0), "pinned Node must have Control");
 129         // Before setting block replace block_proj control edge
 130         replace_block_proj_ctrl(node);
 131         Node* input = node->in(0);
 132         while (!input->is_block_start()) {
 133           input = input->in(0);
 134         }
 135         Block* block = get_block_for_node(input); // Basic block of controlling input
 136         schedule_node_into_block(node, block);




































 137       }
 138 
 139       // process all inputs that are non NULL
 140       for (int i = node->req() - 1; i >= 0; --i) {
 141         if (node->in(i) != NULL) {
 142           spstack.push(node->in(i));
 143         }
 144       }
 145     }
 146   }
 147 }
 148 
 149 #ifdef ASSERT
 150 // Assert that new input b2 is dominated by all previous inputs.
 151 // Check this by by seeing that it is dominated by b1, the deepest
 152 // input observed until b2.
 153 static void assert_dom(Block* b1, Block* b2, Node* n, const PhaseCFG* cfg) {
 154   if (b1 == NULL)  return;
 155   assert(b1->_dom_depth < b2->_dom_depth, "sanity");
 156   Block* tmp = b2;




  24 
  25 #include "precompiled.hpp"
  26 #include "libadt/vectset.hpp"
  27 #include "memory/allocation.inline.hpp"
  28 #include "opto/block.hpp"
  29 #include "opto/c2compiler.hpp"
  30 #include "opto/callnode.hpp"
  31 #include "opto/cfgnode.hpp"
  32 #include "opto/machnode.hpp"
  33 #include "opto/opcodes.hpp"
  34 #include "opto/phaseX.hpp"
  35 #include "opto/rootnode.hpp"
  36 #include "opto/runtime.hpp"
  37 #include "runtime/deoptimization.hpp"
  38 #if defined AD_MD_HPP
  39 # include AD_MD_HPP
  40 #elif defined TARGET_ARCH_MODEL_x86_32
  41 # include "adfiles/ad_x86_32.hpp"
  42 #elif defined TARGET_ARCH_MODEL_x86_64
  43 # include "adfiles/ad_x86_64.hpp"
  44 #elif defined TARGET_ARCH_MODEL_aarch64
  45 # include "adfiles/ad_aarch64.hpp"
  46 #elif defined TARGET_ARCH_MODEL_sparc
  47 # include "adfiles/ad_sparc.hpp"
  48 #elif defined TARGET_ARCH_MODEL_zero
  49 # include "adfiles/ad_zero.hpp"
  50 #elif defined TARGET_ARCH_MODEL_ppc_64
  51 # include "adfiles/ad_ppc_64.hpp"
  52 #endif
  53 
  54 
  55 // Portions of code courtesy of Clifford Click
  56 
  57 // Optimization - Graph Style
  58 
  59 // To avoid float value underflow
  60 #define MIN_BLOCK_FREQUENCY 1.e-35f
  61 
  62 //----------------------------schedule_node_into_block-------------------------
  63 // Insert node n into block b. Look for projections of n and make sure they
  64 // are in b also.
  65 void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) {


  99     Block *pb = get_block_for_node(in0); // Block-projection already has basic block
 100     uint j = 0;
 101     if (pb->_num_succs != 1) {  // More then 1 successor?
 102       // Search for successor
 103       uint max = pb->number_of_nodes();
 104       assert( max > 1, "" );
 105       uint start = max - pb->_num_succs;
 106       // Find which output path belongs to projection
 107       for (j = start; j < max; j++) {
 108         if( pb->get_node(j) == in0 )
 109           break;
 110       }
 111       assert( j < max, "must find" );
 112       // Change control to match head of successor basic block
 113       j -= start;
 114     }
 115     n->set_req(0, pb->_succs[j]->head());
 116   }
 117 }
 118 
 119 static bool is_dominator(Block* d, Block* n) {
 120   return d->dom_lca(n) == d;
 121 }
 122 
 123 //------------------------------schedule_pinned_nodes--------------------------
 124 // Set the basic block for Nodes pinned into blocks
 125 void PhaseCFG::schedule_pinned_nodes(VectorSet &visited) {
 126   // Allocate node stack of size C->live_nodes()+8 to avoid frequent realloc
 127   GrowableArray <Node *> spstack(C->live_nodes() + 8);
 128   spstack.push(_root);
 129   while (spstack.is_nonempty()) {
 130     Node* node = spstack.pop();
 131     if (!visited.test_set(node->_idx)) { // Test node and flag it as visited
 132       if (node->pinned() && !has_block(node)) {  // Pinned?  Nail it down!
 133         assert(node->in(0), "pinned Node must have Control");
 134         // Before setting block replace block_proj control edge
 135         replace_block_proj_ctrl(node);
 136         Node* input = node->in(0);
 137         while (!input->is_block_start()) {
 138           input = input->in(0);
 139         }
 140         Block* block = get_block_for_node(input); // Basic block of controlling input
 141         schedule_node_into_block(node, block);
 142       }
 143 
 144       // If the node has precedence edges (added when CastPP nodes are
 145       // removed in final_graph_reshaping), fix the control of the
 146       // node to cover the precedence edges and remove the
 147       // dependencies.
 148       Node* n = NULL;
 149       for (uint i = node->len()-1; i >= node->req(); i--) {
 150         Node* m = node->in(i);
 151         if (m == NULL) continue;
 152         // Skip the precedence edge if the test that guarded a CastPP:
 153         // - was optimized out during escape analysis
 154         // (OptimizePtrCompare): the CastPP's control isn't an end of
 155         // block.
 156         // - is moved in the branch of a dominating If: the control of
 157         // the CastPP is then a Region.
 158         if (m->is_block_proj() || m->is_block_start()) {
 159           node->rm_prec(i);
 160           if (n == NULL) {
 161             n = m;
 162           } else {
 163             Block* bn = get_block_for_node(n);
 164             Block* bm = get_block_for_node(m);
 165             assert(is_dominator(bn, bm) || is_dominator(bm, bn), "one must dominate the other");
 166             n = is_dominator(bn, bm) ? m : n;
 167           }
 168         }
 169       }
 170       if (n != NULL) {
 171         assert(node->in(0), "control should have been set");
 172         Block* bn = get_block_for_node(n);
 173         Block* bnode = get_block_for_node(node->in(0));
 174         assert(is_dominator(bn, bnode) || is_dominator(bnode, bn), "one must dominate the other");
 175         if (!is_dominator(bn, bnode)) {
 176           node->set_req(0, n);
 177         }
 178       }
 179 
 180       // process all inputs that are non NULL
 181       for (int i = node->req() - 1; i >= 0; --i) {
 182         if (node->in(i) != NULL) {
 183           spstack.push(node->in(i));
 184         }
 185       }
 186     }
 187   }
 188 }
 189 
 190 #ifdef ASSERT
 191 // Assert that new input b2 is dominated by all previous inputs.
 192 // Check this by by seeing that it is dominated by b1, the deepest
 193 // input observed until b2.
 194 static void assert_dom(Block* b1, Block* b2, Node* n, const PhaseCFG* cfg) {
 195   if (b1 == NULL)  return;
 196   assert(b1->_dom_depth < b2->_dom_depth, "sanity");
 197   Block* tmp = b2;


< prev index next >