hotspot/src/share/vm/c1/c1_Optimizer.cpp
changeset 38031 e0b822facc03
parent 28954 7dda6c26cc98
child 38033 996ce936543f
equal deleted inserted replaced
38030:93f24e7b3c43 38031:e0b822facc03
     1 /*
     1 /*
     2  * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
     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.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    29 #include "c1/c1_ValueSet.hpp"
    29 #include "c1/c1_ValueSet.hpp"
    30 #include "c1/c1_ValueStack.hpp"
    30 #include "c1/c1_ValueStack.hpp"
    31 #include "utilities/bitMap.inline.hpp"
    31 #include "utilities/bitMap.inline.hpp"
    32 #include "compiler/compileLog.hpp"
    32 #include "compiler/compileLog.hpp"
    33 
    33 
    34 define_array(ValueSetArray, ValueSet*);
    34 typedef GrowableArray<ValueSet*> ValueSetList;
    35 define_stack(ValueSetList, ValueSetArray);
       
    36 
       
    37 
    35 
    38 Optimizer::Optimizer(IR* ir) {
    36 Optimizer::Optimizer(IR* ir) {
    39   assert(ir->is_valid(), "IR must be valid");
    37   assert(ir->is_valid(), "IR must be valid");
    40   _ir = ir;
    38   _ir = ir;
    41 }
    39 }
   581   void iterate_all();
   579   void iterate_all();
   582   void iterate_one(BlockBegin* block);
   580   void iterate_one(BlockBegin* block);
   583 
   581 
   584   ValueSet* state()                               { return _set; }
   582   ValueSet* state()                               { return _set; }
   585   void      set_state_from (ValueSet* state)      { _set->set_from(state); }
   583   void      set_state_from (ValueSet* state)      { _set->set_from(state); }
   586   ValueSet* state_for      (BlockBegin* block)    { return _block_states[block->block_id()]; }
   584   ValueSet* state_for      (BlockBegin* block)    { return _block_states.at(block->block_id()); }
   587   void      set_state_for  (BlockBegin* block, ValueSet* stack) { _block_states[block->block_id()] = stack; }
   585   void      set_state_for  (BlockBegin* block, ValueSet* stack) { _block_states.at_put(block->block_id(), stack); }
   588   // Returns true if caused a change in the block's state.
   586   // Returns true if caused a change in the block's state.
   589   bool      merge_state_for(BlockBegin* block,
   587   bool      merge_state_for(BlockBegin* block,
   590                             ValueSet*   incoming_state);
   588                             ValueSet*   incoming_state);
   591 
   589 
   592  public:
   590  public:
   593   // constructor
   591   // constructor
   594   NullCheckEliminator(Optimizer* opt)
   592   NullCheckEliminator(Optimizer* opt)
   595     : _opt(opt)
   593     : _opt(opt)
   596     , _set(new ValueSet())
   594     , _set(new ValueSet())
   597     , _last_explicit_null_check(NULL)
   595     , _last_explicit_null_check(NULL)
   598     , _block_states(BlockBegin::number_of_blocks(), NULL)
   596     , _block_states(BlockBegin::number_of_blocks(), BlockBegin::number_of_blocks(), NULL)
   599     , _work_list(new BlockList()) {
   597     , _work_list(new BlockList()) {
   600     _visitable_instructions = new ValueSet();
   598     _visitable_instructions = new ValueSet();
   601     _visitor.set_eliminator(this);
   599     _visitor.set_eliminator(this);
   602     CompileLog* log = _opt->ir()->compilation()->log();
   600     CompileLog* log = _opt->ir()->compilation()->log();
   603     if (log != NULL)
   601     if (log != NULL)
  1162 
  1160 
  1163   // walk over the graph looking for exception
  1161   // walk over the graph looking for exception
  1164   // handlers and iterate over them as well
  1162   // handlers and iterate over them as well
  1165   int nblocks = BlockBegin::number_of_blocks();
  1163   int nblocks = BlockBegin::number_of_blocks();
  1166   BlockList blocks(nblocks);
  1164   BlockList blocks(nblocks);
  1167   boolArray visited_block(nblocks, false);
  1165   boolArray visited_block(nblocks, nblocks, false);
  1168 
  1166 
  1169   blocks.push(ir()->start());
  1167   blocks.push(ir()->start());
  1170   visited_block[ir()->start()->block_id()] = true;
  1168   visited_block.at_put(ir()->start()->block_id(), true);
  1171   for (int i = 0; i < blocks.length(); i++) {
  1169   for (int i = 0; i < blocks.length(); i++) {
  1172     BlockBegin* b = blocks[i];
  1170     BlockBegin* b = blocks.at(i);
  1173     // exception handlers need to be treated as additional roots
  1171     // exception handlers need to be treated as additional roots
  1174     for (int e = b->number_of_exception_handlers(); e-- > 0; ) {
  1172     for (int e = b->number_of_exception_handlers(); e-- > 0; ) {
  1175       BlockBegin* excp = b->exception_handler_at(e);
  1173       BlockBegin* excp = b->exception_handler_at(e);
  1176       int id = excp->block_id();
  1174       int id = excp->block_id();
  1177       if (!visited_block[id]) {
  1175       if (!visited_block.at(id)) {
  1178         blocks.push(excp);
  1176         blocks.push(excp);
  1179         visited_block[id] = true;
  1177         visited_block.at_put(id, true);
  1180         nce.iterate(excp);
  1178         nce.iterate(excp);
  1181       }
  1179       }
  1182     }
  1180     }
  1183     // traverse successors
  1181     // traverse successors
  1184     BlockEnd *end = b->end();
  1182     BlockEnd *end = b->end();
  1185     for (int s = end->number_of_sux(); s-- > 0; ) {
  1183     for (int s = end->number_of_sux(); s-- > 0; ) {
  1186       BlockBegin* next = end->sux_at(s);
  1184       BlockBegin* next = end->sux_at(s);
  1187       int id = next->block_id();
  1185       int id = next->block_id();
  1188       if (!visited_block[id]) {
  1186       if (!visited_block.at(id)) {
  1189         blocks.push(next);
  1187         blocks.push(next);
  1190         visited_block[id] = true;
  1188         visited_block.at_put(id, true);
  1191       }
  1189       }
  1192     }
  1190     }
  1193   }
  1191   }
  1194 
  1192 
  1195 
  1193