55 } |
55 } |
56 } |
56 } |
57 } |
57 } |
58 } |
58 } |
59 |
59 |
|
60 //----------------------------replace_block_proj_ctrl------------------------- |
|
61 // Nodes that have is_block_proj() nodes as their control need to use |
|
62 // the appropriate Region for their actual block as their control since |
|
63 // the projection will be in a predecessor block. |
|
64 void PhaseCFG::replace_block_proj_ctrl( Node *n ) { |
|
65 const Node *in0 = n->in(0); |
|
66 assert(in0 != NULL, "Only control-dependent"); |
|
67 const Node *p = in0->is_block_proj(); |
|
68 if (p != NULL && p != n) { // Control from a block projection? |
|
69 assert(!n->pinned() || n->is_SafePointScalarObject(), "only SafePointScalarObject pinned node is expected here"); |
|
70 // Find trailing Region |
|
71 Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block |
|
72 uint j = 0; |
|
73 if (pb->_num_succs != 1) { // More then 1 successor? |
|
74 // Search for successor |
|
75 uint max = pb->_nodes.size(); |
|
76 assert( max > 1, "" ); |
|
77 uint start = max - pb->_num_succs; |
|
78 // Find which output path belongs to projection |
|
79 for (j = start; j < max; j++) { |
|
80 if( pb->_nodes[j] == in0 ) |
|
81 break; |
|
82 } |
|
83 assert( j < max, "must find" ); |
|
84 // Change control to match head of successor basic block |
|
85 j -= start; |
|
86 } |
|
87 n->set_req(0, pb->_succs[j]->head()); |
|
88 } |
|
89 } |
|
90 |
60 |
91 |
61 //------------------------------schedule_pinned_nodes-------------------------- |
92 //------------------------------schedule_pinned_nodes-------------------------- |
62 // Set the basic block for Nodes pinned into blocks |
93 // Set the basic block for Nodes pinned into blocks |
63 void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) { |
94 void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) { |
64 // Allocate node stack of size C->unique()+8 to avoid frequent realloc |
95 // Allocate node stack of size C->unique()+8 to avoid frequent realloc |
66 spstack.push(_root); |
97 spstack.push(_root); |
67 while ( spstack.is_nonempty() ) { |
98 while ( spstack.is_nonempty() ) { |
68 Node *n = spstack.pop(); |
99 Node *n = spstack.pop(); |
69 if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited |
100 if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited |
70 if( n->pinned() && !_bbs.lookup(n->_idx) ) { // Pinned? Nail it down! |
101 if( n->pinned() && !_bbs.lookup(n->_idx) ) { // Pinned? Nail it down! |
|
102 assert( n->in(0), "pinned Node must have Control" ); |
|
103 // Before setting block replace block_proj control edge |
|
104 replace_block_proj_ctrl(n); |
71 Node *input = n->in(0); |
105 Node *input = n->in(0); |
72 assert( input, "pinned Node must have Control" ); |
|
73 while( !input->is_block_start() ) |
106 while( !input->is_block_start() ) |
74 input = input->in(0); |
107 input = input->in(0); |
75 Block *b = _bbs[input->_idx]; // Basic block of controlling input |
108 Block *b = _bbs[input->_idx]; // Basic block of controlling input |
76 schedule_node_into_block(n, b); |
109 schedule_node_into_block(n, b); |
77 } |
110 } |
156 // Get parent node and next input's index from stack's top. |
189 // Get parent node and next input's index from stack's top. |
157 Node *n = nstack_top_n; |
190 Node *n = nstack_top_n; |
158 uint i = nstack_top_i; |
191 uint i = nstack_top_i; |
159 |
192 |
160 if (i == 0) { |
193 if (i == 0) { |
161 // Special control input processing. |
194 // Fixup some control. Constants without control get attached |
162 // While I am here, go ahead and look for Nodes which are taking control |
195 // to root and nodes that use is_block_proj() nodes should be attached |
163 // from a is_block_proj Node. After I inserted RegionNodes to make proper |
196 // to the region that starts their block. |
164 // blocks, the control at a is_block_proj more properly comes from the |
|
165 // Region being controlled by the block_proj Node. |
|
166 const Node *in0 = n->in(0); |
197 const Node *in0 = n->in(0); |
167 if (in0 != NULL) { // Control-dependent? |
198 if (in0 != NULL) { // Control-dependent? |
168 const Node *p = in0->is_block_proj(); |
199 replace_block_proj_ctrl(n); |
169 if (p != NULL && p != n) { // Control from a block projection? |
|
170 // Find trailing Region |
|
171 Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block |
|
172 uint j = 0; |
|
173 if (pb->_num_succs != 1) { // More then 1 successor? |
|
174 // Search for successor |
|
175 uint max = pb->_nodes.size(); |
|
176 assert( max > 1, "" ); |
|
177 uint start = max - pb->_num_succs; |
|
178 // Find which output path belongs to projection |
|
179 for (j = start; j < max; j++) { |
|
180 if( pb->_nodes[j] == in0 ) |
|
181 break; |
|
182 } |
|
183 assert( j < max, "must find" ); |
|
184 // Change control to match head of successor basic block |
|
185 j -= start; |
|
186 } |
|
187 n->set_req(0, pb->_succs[j]->head()); |
|
188 } |
|
189 } else { // n->in(0) == NULL |
200 } else { // n->in(0) == NULL |
190 if (n->req() == 1) { // This guy is a constant with NO inputs? |
201 if (n->req() == 1) { // This guy is a constant with NO inputs? |
191 n->set_req(0, _root); |
202 n->set_req(0, _root); |
192 } |
203 } |
193 } |
204 } |
224 // Phi, Start, Return, and other control-dependent instructions and |
235 // Phi, Start, Return, and other control-dependent instructions and |
225 // any projections which depend on them. |
236 // any projections which depend on them. |
226 if (!n->pinned()) { |
237 if (!n->pinned()) { |
227 // Set earliest legal block. |
238 // Set earliest legal block. |
228 _bbs.map(n->_idx, find_deepest_input(n, _bbs)); |
239 _bbs.map(n->_idx, find_deepest_input(n, _bbs)); |
|
240 } else { |
|
241 assert(_bbs[n->_idx] == _bbs[n->in(0)->_idx], "Pinned Node should be at the same block as its control edge"); |
229 } |
242 } |
230 |
243 |
231 if (nstack.is_empty()) { |
244 if (nstack.is_empty()) { |
232 // Finished all nodes on stack. |
245 // Finished all nodes on stack. |
233 // Process next node on the worklist 'roots'. |
246 // Process next node on the worklist 'roots'. |