< prev index next >

src/hotspot/share/opto/loopUnswitch.cpp

Print this page


   1 /*
   2  * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  62     return false;
  63   }
  64 
  65   // If nodes are depleted, some transform has miscalculated its needs.
  66   assert(!phase->exceeding_node_budget(), "sanity");
  67 
  68   // check for vectorized loops, any unswitching was already applied
  69   if (_head->is_CountedLoop() && _head->as_CountedLoop()->is_unroll_only()) {
  70     return false;
  71   }
  72 
  73   LoopNode* head = _head->as_Loop();
  74   if (head->unswitch_count() + 1 > head->unswitch_max()) {
  75     return false;
  76   }
  77   if (phase->find_unswitching_candidate(this) == NULL) {
  78     return false;
  79   }
  80 
  81   // Too speculative if running low on nodes.
  82   return phase->may_require_nodes(est_loop_clone_sz(2));
  83 }
  84 
  85 //------------------------------find_unswitching_candidate-----------------------------
  86 // Find candidate "if" for unswitching
  87 IfNode* PhaseIdealLoop::find_unswitching_candidate(const IdealLoopTree *loop) const {
  88 
  89   // Find first invariant test that doesn't exit the loop
  90   LoopNode *head = loop->_head->as_Loop();
  91   IfNode* unswitch_iff = NULL;
  92   Node* n = head->in(LoopNode::LoopBackControl);
  93   while (n != head) {
  94     Node* n_dom = idom(n);
  95     if (n->is_Region()) {
  96       if (n_dom->is_If()) {
  97         IfNode* iff = n_dom->as_If();
  98         if (iff->in(1)->is_Bool()) {
  99           BoolNode* bol = iff->in(1)->as_Bool();
 100           if (bol->in(1)->is_Cmp()) {
 101             // If condition is invariant and not a loop exit,
 102             // then found reason to unswitch.
 103             if (loop->is_invariant(bol) && !loop->is_loop_exit(iff)) {
 104               unswitch_iff = iff;
 105             }
 106           }
 107         }
 108       }
 109     }
 110     n = n_dom;
 111   }
 112   return unswitch_iff;
 113 }
 114 
 115 //------------------------------do_unswitching-----------------------------
 116 // Clone loop with an invariant test (that does not exit) and
 117 // insert a clone of the test that selects which version to
 118 // execute.
 119 void PhaseIdealLoop::do_unswitching(IdealLoopTree *loop, Node_List &old_new) {
 120 
 121   // Find first invariant test that doesn't exit the loop
 122   LoopNode *head = loop->_head->as_Loop();
 123 
 124   IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop);
 125   assert(unswitch_iff != NULL, "should be at least one");
 126 
 127 #ifndef PRODUCT
 128   if (TraceLoopOpts) {
 129     tty->print("Unswitch   %d ", head->unswitch_count()+1);
 130     loop->dump_head();
 131   }
 132 #endif
 133 
 134   // Need to revert back to normal loop
 135   if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
 136     head->as_CountedLoop()->set_normal_loop();
 137   }
 138 
 139   ProjNode* proj_true = create_slow_version_of_loop(loop, old_new, unswitch_iff->Opcode(), CloneIncludesStripMined);


   1 /*
   2  * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  62     return false;
  63   }
  64 
  65   // If nodes are depleted, some transform has miscalculated its needs.
  66   assert(!phase->exceeding_node_budget(), "sanity");
  67 
  68   // check for vectorized loops, any unswitching was already applied
  69   if (_head->is_CountedLoop() && _head->as_CountedLoop()->is_unroll_only()) {
  70     return false;
  71   }
  72 
  73   LoopNode* head = _head->as_Loop();
  74   if (head->unswitch_count() + 1 > head->unswitch_max()) {
  75     return false;
  76   }
  77   if (phase->find_unswitching_candidate(this) == NULL) {
  78     return false;
  79   }
  80 
  81   // Too speculative if running low on nodes.
  82   return phase->may_require_nodes(est_loop_clone_sz(3, _body.size()));
  83 }
  84 
  85 //------------------------------find_unswitching_candidate-----------------------------
  86 // Find candidate "if" for unswitching
  87 IfNode* PhaseIdealLoop::find_unswitching_candidate(const IdealLoopTree *loop) const {
  88 
  89   // Find first invariant test that doesn't exit the loop
  90   LoopNode *head = loop->_head->as_Loop();
  91   IfNode* unswitch_iff = NULL;
  92   Node* n = head->in(LoopNode::LoopBackControl);
  93   while (n != head) {
  94     Node* n_dom = idom(n);
  95     if (n->is_Region()) {
  96       if (n_dom->is_If()) {
  97         IfNode* iff = n_dom->as_If();
  98         if (iff->in(1)->is_Bool()) {
  99           BoolNode* bol = iff->in(1)->as_Bool();
 100           if (bol->in(1)->is_Cmp()) {
 101             // If condition is invariant and not a loop exit,
 102             // then found reason to unswitch.
 103             if (loop->is_invariant(bol) && !loop->is_loop_exit(iff)) {
 104               unswitch_iff = iff;
 105             }
 106           }
 107         }
 108       }
 109     }
 110     n = n_dom;
 111   }
 112   return unswitch_iff;
 113 }
 114 
 115 //------------------------------do_unswitching-----------------------------
 116 // Clone loop with an invariant test (that does not exit) and
 117 // insert a clone of the test that selects which version to
 118 // execute.
 119 void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
 120 
 121   // Find first invariant test that doesn't exit the loop
 122   LoopNode *head = loop->_head->as_Loop();
 123 
 124   IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop);
 125   assert(unswitch_iff != NULL, "should be at least one");
 126 
 127 #ifndef PRODUCT
 128   if (TraceLoopOpts) {
 129     tty->print("Unswitch   %d ", head->unswitch_count()+1);
 130     loop->dump_head();
 131   }
 132 #endif
 133 
 134   // Need to revert back to normal loop
 135   if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
 136     head->as_CountedLoop()->set_normal_loop();
 137   }
 138 
 139   ProjNode* proj_true = create_slow_version_of_loop(loop, old_new, unswitch_iff->Opcode(), CloneIncludesStripMined);


< prev index next >