< prev index next >

hotspot/src/share/vm/c1/c1_Optimizer.cpp

Print this page
rev 10453 : imported patch update dates
   1 /*
   2  * Copyright (c) 1999, 2015, 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  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "c1/c1_Canonicalizer.hpp"
  27 #include "c1/c1_Optimizer.hpp"
  28 #include "c1/c1_ValueMap.hpp"
  29 #include "c1/c1_ValueSet.hpp"
  30 #include "c1/c1_ValueStack.hpp"
  31 #include "utilities/bitMap.inline.hpp"
  32 #include "compiler/compileLog.hpp"
  33 
  34 define_array(ValueSetArray, ValueSet*);
  35 define_stack(ValueSetList, ValueSetArray);
  36 
  37 
  38 Optimizer::Optimizer(IR* ir) {
  39   assert(ir->is_valid(), "IR must be valid");
  40   _ir = ir;
  41 }
  42 
  43 class CE_Eliminator: public BlockClosure {
  44  private:
  45   IR* _hir;
  46   int _cee_count;                                // the number of CEs successfully eliminated
  47   int _ifop_count;                               // the number of IfOps successfully simplified
  48   int _has_substitution;
  49 
  50  public:
  51   CE_Eliminator(IR* hir) : _cee_count(0), _ifop_count(0), _hir(hir) {
  52     _has_substitution = false;
  53     _hir->iterate_preorder(this);
  54     if (_has_substitution) {
  55       // substituted some ifops/phis, so resolve the substitution
  56       SubstitutionResolver sr(_hir);


 566     assert(_visitable_instructions != NULL, "check");
 567     _visitable_instructions->clear();
 568   }
 569 
 570   ValueSet*         _set;                         // current state, propagated to subsequent BlockBegins
 571   ValueSetList      _block_states;                // BlockBegin null-check states for all processed blocks
 572   NullCheckVisitor  _visitor;
 573   NullCheck*        _last_explicit_null_check;
 574 
 575   bool set_contains(Value x)                      { assert(_set != NULL, "check"); return _set->contains(x); }
 576   void set_put     (Value x)                      { assert(_set != NULL, "check"); _set->put(x); }
 577   void set_remove  (Value x)                      { assert(_set != NULL, "check"); _set->remove(x); }
 578 
 579   BlockList* work_list()                          { return _work_list; }
 580 
 581   void iterate_all();
 582   void iterate_one(BlockBegin* block);
 583 
 584   ValueSet* state()                               { return _set; }
 585   void      set_state_from (ValueSet* state)      { _set->set_from(state); }
 586   ValueSet* state_for      (BlockBegin* block)    { return _block_states[block->block_id()]; }
 587   void      set_state_for  (BlockBegin* block, ValueSet* stack) { _block_states[block->block_id()] = stack; }
 588   // Returns true if caused a change in the block's state.
 589   bool      merge_state_for(BlockBegin* block,
 590                             ValueSet*   incoming_state);
 591 
 592  public:
 593   // constructor
 594   NullCheckEliminator(Optimizer* opt)
 595     : _opt(opt)
 596     , _set(new ValueSet())
 597     , _last_explicit_null_check(NULL)
 598     , _block_states(BlockBegin::number_of_blocks(), NULL)
 599     , _work_list(new BlockList()) {
 600     _visitable_instructions = new ValueSet();
 601     _visitor.set_eliminator(this);
 602     CompileLog* log = _opt->ir()->compilation()->log();
 603     if (log != NULL)
 604       log->set_context("optimize name='null_check_elimination'");
 605   }
 606 
 607   ~NullCheckEliminator() {
 608     CompileLog* log = _opt->ir()->compilation()->log();
 609     if (log != NULL)
 610       log->clear_context(); // skip marker if nothing was printed
 611   }
 612 
 613   Optimizer*  opt()                               { return _opt; }
 614   IR*         ir ()                               { return opt()->ir(); }
 615 
 616   // Process a graph
 617   void iterate(BlockBegin* root);
 618 


1147 
1148 void Optimizer::eliminate_null_checks() {
1149   ResourceMark rm;
1150 
1151   NullCheckEliminator nce(this);
1152 
1153   if (PrintNullCheckElimination) {
1154     tty->print_cr("Starting null check elimination for method %s::%s%s",
1155                   ir()->method()->holder()->name()->as_utf8(),
1156                   ir()->method()->name()->as_utf8(),
1157                   ir()->method()->signature()->as_symbol()->as_utf8());
1158   }
1159 
1160   // Apply to graph
1161   nce.iterate(ir()->start());
1162 
1163   // walk over the graph looking for exception
1164   // handlers and iterate over them as well
1165   int nblocks = BlockBegin::number_of_blocks();
1166   BlockList blocks(nblocks);
1167   boolArray visited_block(nblocks, false);
1168 
1169   blocks.push(ir()->start());
1170   visited_block[ir()->start()->block_id()] = true;
1171   for (int i = 0; i < blocks.length(); i++) {
1172     BlockBegin* b = blocks[i];
1173     // exception handlers need to be treated as additional roots
1174     for (int e = b->number_of_exception_handlers(); e-- > 0; ) {
1175       BlockBegin* excp = b->exception_handler_at(e);
1176       int id = excp->block_id();
1177       if (!visited_block[id]) {
1178         blocks.push(excp);
1179         visited_block[id] = true;
1180         nce.iterate(excp);
1181       }
1182     }
1183     // traverse successors
1184     BlockEnd *end = b->end();
1185     for (int s = end->number_of_sux(); s-- > 0; ) {
1186       BlockBegin* next = end->sux_at(s);
1187       int id = next->block_id();
1188       if (!visited_block[id]) {
1189         blocks.push(next);
1190         visited_block[id] = true;
1191       }
1192     }
1193   }
1194 
1195 
1196   if (PrintNullCheckElimination) {
1197     tty->print_cr("Done with null check elimination for method %s::%s%s",
1198                   ir()->method()->holder()->name()->as_utf8(),
1199                   ir()->method()->name()->as_utf8(),
1200                   ir()->method()->signature()->as_symbol()->as_utf8());
1201   }
1202 }
   1 /*
   2  * Copyright (c) 1999, 2016, 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  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "c1/c1_Canonicalizer.hpp"
  27 #include "c1/c1_Optimizer.hpp"
  28 #include "c1/c1_ValueMap.hpp"
  29 #include "c1/c1_ValueSet.hpp"
  30 #include "c1/c1_ValueStack.hpp"
  31 #include "utilities/bitMap.inline.hpp"
  32 #include "compiler/compileLog.hpp"
  33 
  34 typedef GrowableArray<ValueSet*> ValueSetList;


  35 
  36 Optimizer::Optimizer(IR* ir) {
  37   assert(ir->is_valid(), "IR must be valid");
  38   _ir = ir;
  39 }
  40 
  41 class CE_Eliminator: public BlockClosure {
  42  private:
  43   IR* _hir;
  44   int _cee_count;                                // the number of CEs successfully eliminated
  45   int _ifop_count;                               // the number of IfOps successfully simplified
  46   int _has_substitution;
  47 
  48  public:
  49   CE_Eliminator(IR* hir) : _cee_count(0), _ifop_count(0), _hir(hir) {
  50     _has_substitution = false;
  51     _hir->iterate_preorder(this);
  52     if (_has_substitution) {
  53       // substituted some ifops/phis, so resolve the substitution
  54       SubstitutionResolver sr(_hir);


 564     assert(_visitable_instructions != NULL, "check");
 565     _visitable_instructions->clear();
 566   }
 567 
 568   ValueSet*         _set;                         // current state, propagated to subsequent BlockBegins
 569   ValueSetList      _block_states;                // BlockBegin null-check states for all processed blocks
 570   NullCheckVisitor  _visitor;
 571   NullCheck*        _last_explicit_null_check;
 572 
 573   bool set_contains(Value x)                      { assert(_set != NULL, "check"); return _set->contains(x); }
 574   void set_put     (Value x)                      { assert(_set != NULL, "check"); _set->put(x); }
 575   void set_remove  (Value x)                      { assert(_set != NULL, "check"); _set->remove(x); }
 576 
 577   BlockList* work_list()                          { return _work_list; }
 578 
 579   void iterate_all();
 580   void iterate_one(BlockBegin* block);
 581 
 582   ValueSet* state()                               { return _set; }
 583   void      set_state_from (ValueSet* state)      { _set->set_from(state); }
 584   ValueSet* state_for      (BlockBegin* block)    { return _block_states.at(block->block_id()); }
 585   void      set_state_for  (BlockBegin* block, ValueSet* stack) { _block_states.at_put(block->block_id(), stack); }
 586   // Returns true if caused a change in the block's state.
 587   bool      merge_state_for(BlockBegin* block,
 588                             ValueSet*   incoming_state);
 589 
 590  public:
 591   // constructor
 592   NullCheckEliminator(Optimizer* opt)
 593     : _opt(opt)
 594     , _set(new ValueSet())
 595     , _last_explicit_null_check(NULL)
 596     , _block_states(BlockBegin::number_of_blocks(), BlockBegin::number_of_blocks(), NULL)
 597     , _work_list(new BlockList()) {
 598     _visitable_instructions = new ValueSet();
 599     _visitor.set_eliminator(this);
 600     CompileLog* log = _opt->ir()->compilation()->log();
 601     if (log != NULL)
 602       log->set_context("optimize name='null_check_elimination'");
 603   }
 604 
 605   ~NullCheckEliminator() {
 606     CompileLog* log = _opt->ir()->compilation()->log();
 607     if (log != NULL)
 608       log->clear_context(); // skip marker if nothing was printed
 609   }
 610 
 611   Optimizer*  opt()                               { return _opt; }
 612   IR*         ir ()                               { return opt()->ir(); }
 613 
 614   // Process a graph
 615   void iterate(BlockBegin* root);
 616 


1145 
1146 void Optimizer::eliminate_null_checks() {
1147   ResourceMark rm;
1148 
1149   NullCheckEliminator nce(this);
1150 
1151   if (PrintNullCheckElimination) {
1152     tty->print_cr("Starting null check elimination for method %s::%s%s",
1153                   ir()->method()->holder()->name()->as_utf8(),
1154                   ir()->method()->name()->as_utf8(),
1155                   ir()->method()->signature()->as_symbol()->as_utf8());
1156   }
1157 
1158   // Apply to graph
1159   nce.iterate(ir()->start());
1160 
1161   // walk over the graph looking for exception
1162   // handlers and iterate over them as well
1163   int nblocks = BlockBegin::number_of_blocks();
1164   BlockList blocks(nblocks);
1165   boolArray visited_block(nblocks, nblocks, false);
1166 
1167   blocks.push(ir()->start());
1168   visited_block.at_put(ir()->start()->block_id(), true);
1169   for (int i = 0; i < blocks.length(); i++) {
1170     BlockBegin* b = blocks.at(i);
1171     // exception handlers need to be treated as additional roots
1172     for (int e = b->number_of_exception_handlers(); e-- > 0; ) {
1173       BlockBegin* excp = b->exception_handler_at(e);
1174       int id = excp->block_id();
1175       if (!visited_block.at(id)) {
1176         blocks.push(excp);
1177         visited_block.at_put(id, true);
1178         nce.iterate(excp);
1179       }
1180     }
1181     // traverse successors
1182     BlockEnd *end = b->end();
1183     for (int s = end->number_of_sux(); s-- > 0; ) {
1184       BlockBegin* next = end->sux_at(s);
1185       int id = next->block_id();
1186       if (!visited_block.at(id)) {
1187         blocks.push(next);
1188         visited_block.at_put(id, true);
1189       }
1190     }
1191   }
1192 
1193 
1194   if (PrintNullCheckElimination) {
1195     tty->print_cr("Done with null check elimination for method %s::%s%s",
1196                   ir()->method()->holder()->name()->as_utf8(),
1197                   ir()->method()->name()->as_utf8(),
1198                   ir()->method()->signature()->as_symbol()->as_utf8());
1199   }
1200 }
< prev index next >