Exemplo n.º 1
0
bool ShortLoopOptimizer::process(BlockBegin* loop_header) {
  TRACE_VALUE_NUMBERING(tty->print_cr("** loop header block"));

  _too_complicated_loop = false;
  _loop_blocks.clear();
  _loop_blocks.append(loop_header);

  for (int i = 0; i < _loop_blocks.length(); i++) {
    BlockBegin* block = _loop_blocks.at(i);
    TRACE_VALUE_NUMBERING(tty->print_cr("processing loop block B%d", block->block_id()));

    if (block->is_set(BlockBegin::exception_entry_flag)) {
      // this would be too complicated
      return false;
    }

    // add predecessors to worklist
    for (int j = block->number_of_preds() - 1; j >= 0; j--) {
      BlockBegin* pred = block->pred_at(j);

      if (pred->is_set(BlockBegin::osr_entry_flag)) {
        return false;
      }

      ValueMap* pred_map = value_map_of(pred);
      if (pred_map != NULL) {
        current_map()->kill_map(pred_map);
      } else if (!_loop_blocks.contains(pred)) {
        if (_loop_blocks.length() >= ValueMapMaxLoopSize) {
          return false;
        }
        _loop_blocks.append(pred);
      }
    }

    // use the instruction visitor for killing values
    for (Value instr = block->next(); instr != NULL; instr = instr->next()) {
      instr->visit(this);
      if (_too_complicated_loop) {
        return false;
      }
    }
  }

  bool optimistic = this->_gvn->compilation()->is_optimistic();

  if (UseLoopInvariantCodeMotion && optimistic) {
    LoopInvariantCodeMotion code_motion(this, _gvn, loop_header, &_loop_blocks);
  }

  TRACE_VALUE_NUMBERING(tty->print_cr("** loop successfully optimized"));
  return true;
}
Exemplo n.º 2
0
 void          set_value_map_of(BlockBegin* block, ValueMap* map)   {
     assert(value_map_of(block) == NULL, "");
     _value_maps.at_put(block->linear_scan_number(), map);
 }
Exemplo n.º 3
0
GlobalValueNumbering::GlobalValueNumbering(IR* ir)
    : _current_map(NULL)
    , _value_maps(ir->linear_scan_order()->length(), NULL)
{
    TRACE_VALUE_NUMBERING(tty->print_cr("****** start of global value numbering"));

    ShortLoopOptimizer short_loop_optimizer(this);
    int subst_count = 0;

    BlockList* blocks = ir->linear_scan_order();
    int num_blocks = blocks->length();

    BlockBegin* start_block = blocks->at(0);
    assert(start_block == ir->start() && start_block->number_of_preds() == 0 && start_block->dominator() == NULL, "must be start block");
    assert(start_block->next()->as_Base() != NULL && start_block->next()->next() == NULL, "start block must not have instructions");

    // initial, empty value map with nesting 0
    set_value_map_of(start_block, new ValueMap());

    for (int i = 1; i < num_blocks; i++) {
        BlockBegin* block = blocks->at(i);
        TRACE_VALUE_NUMBERING(tty->print_cr("**** processing block B%d", block->block_id()));

        int num_preds = block->number_of_preds();
        assert(num_preds > 0, "block must have predecessors");

        BlockBegin* dominator = block->dominator();
        assert(dominator != NULL, "dominator must exist");
        assert(value_map_of(dominator) != NULL, "value map of dominator must exist");

        // create new value map with increased nesting
        _current_map = new ValueMap(value_map_of(dominator));

        if (num_preds == 1) {
            assert(dominator == block->pred_at(0), "dominator must be equal to predecessor");
            // nothing to do here

        } else if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) {
            // block has incoming backward branches -> try to optimize short loops
            if (!short_loop_optimizer.process(block)) {
                // loop is too complicated, so kill all memory loads because there might be
                // stores to them in the loop
                current_map()->kill_memory();
            }

        } else {
            // only incoming forward branches that are already processed
            for (int j = 0; j < num_preds; j++) {
                BlockBegin* pred = block->pred_at(j);
                ValueMap* pred_map = value_map_of(pred);

                if (pred_map != NULL) {
                    // propagate killed values of the predecessor to this block
                    current_map()->kill_map(value_map_of(pred));
                } else {
                    // kill all memory loads because predecessor not yet processed
                    // (this can happen with non-natural loops and OSR-compiles)
                    current_map()->kill_memory();
                }
            }
        }

        if (block->is_set(BlockBegin::exception_entry_flag)) {
            current_map()->kill_exception();
        }

        TRACE_VALUE_NUMBERING(tty->print("value map before processing block: "); current_map()->print());

        // visit all instructions of this block
        for (Value instr = block->next(); instr != NULL; instr = instr->next()) {
            assert(!instr->has_subst(), "substitution already set");

            // check if instruction kills any values
            instr->visit(this);

            if (instr->hash() != 0) {
                Value f = current_map()->find_insert(instr);
                if (f != instr) {
                    assert(!f->has_subst(), "can't have a substitution");
                    instr->set_subst(f);
                    subst_count++;
                }
            }
        }

        // remember value map for successors
        set_value_map_of(block, current_map());
    }

    if (subst_count != 0) {
        SubstitutionResolver resolver(ir);
    }

    TRACE_VALUE_NUMBERING(tty->print("****** end of global value numbering. "); ValueMap::print_statistics());
}