< prev index next >

src/share/vm/opto/ifnode.cpp

Print this page




   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  *
  23  */
  24 
  25 #include "precompiled.hpp"

  26 #include "memory/allocation.inline.hpp"
  27 #include "opto/addnode.hpp"
  28 #include "opto/castnode.hpp"
  29 #include "opto/cfgnode.hpp"
  30 #include "opto/connode.hpp"
  31 #include "opto/loopnode.hpp"
  32 #include "opto/phaseX.hpp"
  33 #include "opto/runtime.hpp"
  34 #include "opto/rootnode.hpp"
  35 #include "opto/subnode.hpp"
  36 
  37 // Portions of code courtesy of Clifford Click
  38 
  39 // Optimization - Graph Style
  40 
  41 
  42 extern int explicit_null_checks_elided;
  43 
  44 //=============================================================================
  45 //------------------------------Value------------------------------------------


 751       }
 752     }
 753   }
 754   return success != NULL && fail != NULL;
 755 }
 756 
 757 // Return projection that leads to an uncommon trap if any
 758 ProjNode* IfNode::uncommon_trap_proj(CallStaticJavaNode*& call) const {
 759   for (int i = 0; i < 2; i++) {
 760     call = proj_out(i)->is_uncommon_trap_proj(Deoptimization::Reason_none);
 761     if (call != NULL) {
 762       return proj_out(i);
 763     }
 764   }
 765   return NULL;
 766 }
 767 
 768 // Do this If and the dominating If both branch out to an uncommon trap
 769 bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn) {
 770   ProjNode* otherproj = proj->other_if_proj();
 771   CallStaticJavaNode* dom_unc = otherproj->is_uncommon_trap_proj(Deoptimization::Reason_none);

 772 
 773   if (otherproj->outcnt() == 1 && dom_unc != NULL) {
 774     CallStaticJavaNode* unc = NULL;
 775     ProjNode* unc_proj = uncommon_trap_proj(unc);
 776     if (unc_proj != NULL && unc_proj->outcnt() == 1) {
 777       if (dom_unc == unc) {
 778         // Allow the uncommon trap to be shared through a region
 779         RegionNode* r = unc->in(0)->as_Region();
 780         if (r->outcnt() != 2 || r->req() != 3 || r->find_edge(otherproj) == -1 || r->find_edge(unc_proj) == -1) {
 781           return false;
 782         }
 783         assert(r->has_phi() == NULL, "simple region shouldn't have a phi");
 784       } else if (dom_unc->in(0) != otherproj || unc->in(0) != unc_proj) {
 785         return false;
 786       }


























 787       // See merge_uncommon_traps: the reason of the uncommon trap
 788       // will be changed and the state of the dominating If will be
 789       // used. Checked that we didn't apply this transformation in a
 790       // previous compilation and it didn't cause too many traps
 791       if (!igvn->C->too_many_traps(dom_unc->jvms()->method(), dom_unc->jvms()->bci(), Deoptimization::Reason_unstable_fused_if) &&
 792           !igvn->C->too_many_traps(dom_unc->jvms()->method(), dom_unc->jvms()->bci(), Deoptimization::Reason_range_check)) {
 793         success = unc_proj;
 794         fail = unc_proj->other_if_proj();
 795         return true;
 796       }
 797     }
 798   }
 799   return false;
 800 }
 801 
 802 // Check that the 2 CmpI can be folded into as single CmpU and proceed with the folding
 803 bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn) {
 804   Node* this_cmp = in(1)->in(1);
 805   BoolNode* this_bool = in(1)->as_Bool();
 806   IfNode* dom_iff = proj->in(0)->as_If();
 807   BoolNode* dom_bool = dom_iff->in(1)->as_Bool();
 808   Node* lo = dom_iff->in(1)->in(1)->in(2);
 809   Node* hi = this_cmp->in(2);
 810   Node* n = this_cmp->in(1);
 811   ProjNode* otherproj = proj->other_if_proj();
 812 




   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  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "ci/ciTypeFlow.hpp"
  27 #include "memory/allocation.inline.hpp"
  28 #include "opto/addnode.hpp"
  29 #include "opto/castnode.hpp"
  30 #include "opto/cfgnode.hpp"
  31 #include "opto/connode.hpp"
  32 #include "opto/loopnode.hpp"
  33 #include "opto/phaseX.hpp"
  34 #include "opto/runtime.hpp"
  35 #include "opto/rootnode.hpp"
  36 #include "opto/subnode.hpp"
  37 
  38 // Portions of code courtesy of Clifford Click
  39 
  40 // Optimization - Graph Style
  41 
  42 
  43 extern int explicit_null_checks_elided;
  44 
  45 //=============================================================================
  46 //------------------------------Value------------------------------------------


 752       }
 753     }
 754   }
 755   return success != NULL && fail != NULL;
 756 }
 757 
 758 // Return projection that leads to an uncommon trap if any
 759 ProjNode* IfNode::uncommon_trap_proj(CallStaticJavaNode*& call) const {
 760   for (int i = 0; i < 2; i++) {
 761     call = proj_out(i)->is_uncommon_trap_proj(Deoptimization::Reason_none);
 762     if (call != NULL) {
 763       return proj_out(i);
 764     }
 765   }
 766   return NULL;
 767 }
 768 
 769 // Do this If and the dominating If both branch out to an uncommon trap
 770 bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn) {
 771   ProjNode* otherproj = proj->other_if_proj();
 772   // Dominating uncommon trap must have 'Reason_unstable_if' to ensure re-execution of folded Ifs
 773   CallStaticJavaNode* dom_unc = otherproj->is_uncommon_trap_proj(Deoptimization::Reason_unstable_if);
 774 
 775   if (otherproj->outcnt() == 1 && dom_unc != NULL) {
 776     CallStaticJavaNode* unc = NULL;
 777     ProjNode* unc_proj = uncommon_trap_proj(unc);
 778     if (unc_proj != NULL && unc_proj->outcnt() == 1) {
 779       if (dom_unc == unc) {
 780         // Allow the uncommon trap to be shared through a region
 781         RegionNode* r = unc->in(0)->as_Region();
 782         if (r->outcnt() != 2 || r->req() != 3 || r->find_edge(otherproj) == -1 || r->find_edge(unc_proj) == -1) {
 783           return false;
 784         }
 785         assert(r->has_phi() == NULL, "simple region shouldn't have a phi");
 786       } else if (dom_unc->in(0) != otherproj || unc->in(0) != unc_proj) {
 787         return false;
 788       }
 789 
 790       int dom_bci = dom_unc->jvms()->bci();
 791       ciMethod* dom_method = dom_unc->jvms()->method();
 792 
 793       // Get block that contains the dominating uncommon trap
 794       ciTypeFlow* flow = dom_method->get_flow_analysis();
 795       ciBlock* ciblk = dom_method->get_method_blocks()->block_containing(dom_bci);
 796       ciTypeFlow::JsrSet* jsr = new ciTypeFlow::JsrSet(NULL);
 797       ciTypeFlow::Block* block = flow->get_block_for(ciblk->index(), jsr, ciTypeFlow::no_create);
 798 
 799       // Check if the bci of the dominating uncommon trap dominates the bci
 800       // of the dominated uncommon trap. Otherwise we would not re-execute
 801       // the dominated check after deoptimization from the merged uncommon trap.
 802       int bci = unc->jvms()->bci();
 803       bool dominated = false;
 804       for (ciTypeFlow::SuccIter iter(block); !iter.done(); iter.next()) {
 805         ciTypeFlow::Block* succ = iter.succ();
 806         if (succ->start() <= bci && bci < succ->limit()) {
 807           dominated = true;
 808           break;
 809         }
 810       }
 811       if (!dominated) {
 812         return false;
 813       }
 814 
 815       // See merge_uncommon_traps: the reason of the uncommon trap
 816       // will be changed and the state of the dominating If will be
 817       // used. Checked that we didn't apply this transformation in a
 818       // previous compilation and it didn't cause too many traps
 819       if (!igvn->C->too_many_traps(dom_method, dom_bci, Deoptimization::Reason_unstable_fused_if) &&
 820           !igvn->C->too_many_traps(dom_method, dom_bci, Deoptimization::Reason_range_check)) {
 821         success = unc_proj;
 822         fail = unc_proj->other_if_proj();
 823         return true;
 824       }
 825     }
 826   }
 827   return false;
 828 }
 829 
 830 // Check that the 2 CmpI can be folded into as single CmpU and proceed with the folding
 831 bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn) {
 832   Node* this_cmp = in(1)->in(1);
 833   BoolNode* this_bool = in(1)->as_Bool();
 834   IfNode* dom_iff = proj->in(0)->as_If();
 835   BoolNode* dom_bool = dom_iff->in(1)->as_Bool();
 836   Node* lo = dom_iff->in(1)->in(1)->in(2);
 837   Node* hi = this_cmp->in(2);
 838   Node* n = this_cmp->in(1);
 839   ProjNode* otherproj = proj->other_if_proj();
 840 


< prev index next >