156
157 // Add test to new "if" outside of loop
158 IfNode* invar_iff = proj_true->in(0)->as_If();
159 Node* invar_iff_c = invar_iff->in(0);
160 BoolNode* bol = unswitch_iff->in(1)->as_Bool();
161 invar_iff->set_req(1, bol);
162 invar_iff->_prob = unswitch_iff->_prob;
163
164 ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
165
166 // Hoist invariant casts out of each loop to the appropriate
167 // control projection.
168
169 Node_List worklist;
170
171 for (DUIterator_Fast imax, i = unswitch_iff->fast_outs(imax); i < imax; i++) {
172 ProjNode* proj= unswitch_iff->fast_out(i)->as_Proj();
173 // Copy to a worklist for easier manipulation
174 for (DUIterator_Fast jmax, j = proj->fast_outs(jmax); j < jmax; j++) {
175 Node* use = proj->fast_out(j);
176 if (use->Opcode() == Op_CheckCastPP && loop->is_invariant(use->in(1))) {
177 worklist.push(use);
178 }
179 }
180 ProjNode* invar_proj = invar_iff->proj_out(proj->_con)->as_Proj();
181 while (worklist.size() > 0) {
182 Node* use = worklist.pop();
183 Node* nuse = use->clone();
184 nuse->set_req(0, invar_proj);
185 _igvn.replace_input_of(use, 1, nuse);
186 register_new_node(nuse, invar_proj);
187 // Same for the clone
188 Node* use_clone = old_new[use->_idx];
189 _igvn.replace_input_of(use_clone, 1, nuse);
190 }
191 }
192
193 // Hardwire the control paths in the loops into if(true) and if(false)
194 _igvn.rehash_node_delayed(unswitch_iff);
195 short_circuit_if(unswitch_iff, proj_true);
196
206 _igvn._worklist.push(n_clone);
207 }
208
209 #ifndef PRODUCT
210 if (TraceLoopUnswitching) {
211 tty->print_cr("Loop unswitching orig: %d @ %d new: %d @ %d",
212 head->_idx, unswitch_iff->_idx,
213 old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
214 }
215 #endif
216
217 C->set_major_progress();
218 }
219
220 //-------------------------create_slow_version_of_loop------------------------
221 // Create a slow version of the loop by cloning the loop
222 // and inserting an if to select fast-slow versions.
223 // Return control projection of the entry to the fast version.
224 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
225 Node_List &old_new,
226 int opcode) {
227 LoopNode* head = loop->_head->as_Loop();
228 bool counted_loop = head->is_CountedLoop();
229 Node* entry = head->in(LoopNode::EntryControl);
230 _igvn.rehash_node_delayed(entry);
231 IdealLoopTree* outer_loop = loop->_parent;
232
233 Node *cont = _igvn.intcon(1);
234 set_ctrl(cont, C->root());
235 Node* opq = new Opaque1Node(C, cont);
236 register_node(opq, outer_loop, entry, dom_depth(entry));
237 Node *bol = new Conv2BNode(opq);
238 register_node(bol, outer_loop, entry, dom_depth(entry));
239 IfNode* iff = (opcode == Op_RangeCheck) ? new RangeCheckNode(entry, bol, PROB_MAX, COUNT_UNKNOWN) :
240 new IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
241 register_node(iff, outer_loop, entry, dom_depth(entry));
242 ProjNode* iffast = new IfTrueNode(iff);
243 register_node(iffast, outer_loop, iff, dom_depth(iff));
244 ProjNode* ifslow = new IfFalseNode(iff);
245 register_node(ifslow, outer_loop, iff, dom_depth(iff));
246
247 // Clone the loop body. The clone becomes the fast loop. The
248 // original pre-header will (illegally) have 3 control users
249 // (old & new loops & new if).
250 clone_loop(loop, old_new, dom_depth(head), iff);
251 assert(old_new[head->_idx]->is_Loop(), "" );
252
253 // Fast (true) control
254 Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
255 _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
256 set_idom(head, iffast_pred, dom_depth(head));
257
258 // Slow (false) control
259 Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
388 }
389
390 _lp = _lpt->_head->as_Loop();
391 _lp_reserved = _phase->create_reserve_version_of_loop(_lpt, this);
392
393 if (!_lp_reserved->is_CountedLoop()) {
394 return false;
395 }
396
397 Node* ifslow_pred = _lp_reserved->as_CountedLoop()->in(LoopNode::EntryControl);
398
399 if (!ifslow_pred->is_IfFalse()) {
400 return false;
401 }
402
403 Node* iff = ifslow_pred->in(0);
404 if (!iff->is_If() || iff != _iff) {
405 return false;
406 }
407
408 if (iff->in(1)->Opcode() != Op_ConI) {
409 return false;
410 }
411
412 return _has_reserved = true;
413 }
|
156
157 // Add test to new "if" outside of loop
158 IfNode* invar_iff = proj_true->in(0)->as_If();
159 Node* invar_iff_c = invar_iff->in(0);
160 BoolNode* bol = unswitch_iff->in(1)->as_Bool();
161 invar_iff->set_req(1, bol);
162 invar_iff->_prob = unswitch_iff->_prob;
163
164 ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
165
166 // Hoist invariant casts out of each loop to the appropriate
167 // control projection.
168
169 Node_List worklist;
170
171 for (DUIterator_Fast imax, i = unswitch_iff->fast_outs(imax); i < imax; i++) {
172 ProjNode* proj= unswitch_iff->fast_out(i)->as_Proj();
173 // Copy to a worklist for easier manipulation
174 for (DUIterator_Fast jmax, j = proj->fast_outs(jmax); j < jmax; j++) {
175 Node* use = proj->fast_out(j);
176 if (use->Opcode() == Opcodes::Op_CheckCastPP && loop->is_invariant(use->in(1))) {
177 worklist.push(use);
178 }
179 }
180 ProjNode* invar_proj = invar_iff->proj_out(proj->_con)->as_Proj();
181 while (worklist.size() > 0) {
182 Node* use = worklist.pop();
183 Node* nuse = use->clone();
184 nuse->set_req(0, invar_proj);
185 _igvn.replace_input_of(use, 1, nuse);
186 register_new_node(nuse, invar_proj);
187 // Same for the clone
188 Node* use_clone = old_new[use->_idx];
189 _igvn.replace_input_of(use_clone, 1, nuse);
190 }
191 }
192
193 // Hardwire the control paths in the loops into if(true) and if(false)
194 _igvn.rehash_node_delayed(unswitch_iff);
195 short_circuit_if(unswitch_iff, proj_true);
196
206 _igvn._worklist.push(n_clone);
207 }
208
209 #ifndef PRODUCT
210 if (TraceLoopUnswitching) {
211 tty->print_cr("Loop unswitching orig: %d @ %d new: %d @ %d",
212 head->_idx, unswitch_iff->_idx,
213 old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
214 }
215 #endif
216
217 C->set_major_progress();
218 }
219
220 //-------------------------create_slow_version_of_loop------------------------
221 // Create a slow version of the loop by cloning the loop
222 // and inserting an if to select fast-slow versions.
223 // Return control projection of the entry to the fast version.
224 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
225 Node_List &old_new,
226 Opcodes opcode) {
227 LoopNode* head = loop->_head->as_Loop();
228 bool counted_loop = head->is_CountedLoop();
229 Node* entry = head->in(LoopNode::EntryControl);
230 _igvn.rehash_node_delayed(entry);
231 IdealLoopTree* outer_loop = loop->_parent;
232
233 Node *cont = _igvn.intcon(1);
234 set_ctrl(cont, C->root());
235 Node* opq = new Opaque1Node(C, cont);
236 register_node(opq, outer_loop, entry, dom_depth(entry));
237 Node *bol = new Conv2BNode(opq);
238 register_node(bol, outer_loop, entry, dom_depth(entry));
239 IfNode* iff = (opcode == Opcodes::Op_RangeCheck) ? new RangeCheckNode(entry, bol, PROB_MAX, COUNT_UNKNOWN) :
240 new IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
241 register_node(iff, outer_loop, entry, dom_depth(entry));
242 ProjNode* iffast = new IfTrueNode(iff);
243 register_node(iffast, outer_loop, iff, dom_depth(iff));
244 ProjNode* ifslow = new IfFalseNode(iff);
245 register_node(ifslow, outer_loop, iff, dom_depth(iff));
246
247 // Clone the loop body. The clone becomes the fast loop. The
248 // original pre-header will (illegally) have 3 control users
249 // (old & new loops & new if).
250 clone_loop(loop, old_new, dom_depth(head), iff);
251 assert(old_new[head->_idx]->is_Loop(), "" );
252
253 // Fast (true) control
254 Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
255 _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
256 set_idom(head, iffast_pred, dom_depth(head));
257
258 // Slow (false) control
259 Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
388 }
389
390 _lp = _lpt->_head->as_Loop();
391 _lp_reserved = _phase->create_reserve_version_of_loop(_lpt, this);
392
393 if (!_lp_reserved->is_CountedLoop()) {
394 return false;
395 }
396
397 Node* ifslow_pred = _lp_reserved->as_CountedLoop()->in(LoopNode::EntryControl);
398
399 if (!ifslow_pred->is_IfFalse()) {
400 return false;
401 }
402
403 Node* iff = ifslow_pred->in(0);
404 if (!iff->is_If() || iff != _iff) {
405 return false;
406 }
407
408 if (iff->in(1)->Opcode() != Opcodes::Op_ConI) {
409 return false;
410 }
411
412 return _has_reserved = true;
413 }
|