Exemplo n.º 1
0
GlobalValueNumbering::GlobalValueNumbering(IR* ir)
  : _current_map(NULL)
  , _value_maps(ir->linear_scan_order()->length(), NULL)
  , _compilation(ir->compilation())
{
  TRACE_VALUE_NUMBERING(tty->print_cr("****** start of global value numbering"));

  ShortLoopOptimizer short_loop_optimizer(this);

  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");

  // method parameters are not linked in instructions list, so process them separateley
  for_each_state_value(start_block->state(), value,
     assert(value->as_Local() != NULL, "only method parameters allowed");
     set_processed(value);
  );
Exemplo n.º 2
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());
}