Exemplo n.º 1
0
void LoopFinder::find_loop_exits(BlockBegin* bb, Loop* loop) {
  BlockLoopInfo* bli = get_block_info(bb);
  int loop_index = bb->loop_index();
  // search all successors and locate the ones that do not have the same loop_index
  BlockEnd* be = bb->end();
  int n = be->number_of_sux() - 1;
  for(; n >= 0; n--) {
    BlockBegin* sux = be->sux_at(n);
    BlockLoopInfo* sux_bli = get_block_info(sux);
    if (sux->loop_index() != loop_index) {
      loop->append_loop_exit(bb, sux);
    }
  }
}
void LIR_LocalCaching::cache_locals() {
  LoopList* loops = ir()->loops();
  BlockList* all_blocks = ir()->code();
  WordSizeList* local_name_to_offset_map = ir()->local_name_to_offset_map();

  if (loops == NULL) {
    // collect global scan information
    BlockListScanInfo gsi(ir()->code());
    RegisterManager* global_scan_info = gsi.info();

    // just cache registers globally.
    LocalMappingSetter setter(cache_locals_for_blocks(all_blocks, global_scan_info));
    all_blocks->iterate_forward(&setter);
  } else {
    assert(loops->length() != 0, "should be at least one loop");
    int i;

    // collect all the blocks that are outside of the loops
    BlockList* non_loop_blocks = new BlockList;
    for (i = 0; i < all_blocks->length(); i++) {
      BlockBegin* b = all_blocks->at(i);
      if (b->loop_index() == -1 && b->next()->as_CachingChange() == NULL) {
        non_loop_blocks->append(b);
      }
    }

    RegisterManager* global_scan_info = new RegisterManager();

    // scan each of the loops and the remaining blocks recording register usage
    // so we know what registers are free.
    RegisterManagerArray scan_infos(loops->length() + 1);
    for (i = 0; i < loops->length(); i++) {
      Loop* loop = loops->at(i);

      BlockListScanInfo lsi(loop->blocks());
      scan_infos.at_put(i, lsi.info());
      // accumulate the global state
      global_scan_info->merge(lsi.info());
    }

    BlockListScanInfo lsi(non_loop_blocks);
    scan_infos.at_put(loops->length(), lsi.info());
    // accumulate the global state
    global_scan_info->merge(lsi.info());
    
    // use the global mapping as a guide in the rest of the register selection process.
    LocalMapping* global = cache_locals_for_blocks(all_blocks, global_scan_info, true);
    LocalMapping* pref = new LocalMapping(local_name_to_offset_map);
    pref->merge(global);
    pref->merge(_preferred);
    _preferred = pref;

    for (i = 0; i < loops->length(); i++) {
      if (i < LIRCacheLoopStart || (uint)i >= (uint)LIRCacheLoopStop) {
        continue;
      }

      Loop* loop = loops->at(i);

      LocalMapping* mapping = cache_locals_for_blocks(loop->blocks(), scan_infos.at(i));
      LocalMappingSetter setter(mapping);
      loop->blocks()->iterate_forward(&setter);
      _preferred->merge(mapping);
      mapping->join(global);
    }

    LocalMapping* mapping = cache_locals_for_blocks(non_loop_blocks, scan_infos.at(loops->length()));
    mapping->join(global);
    LocalMappingSetter setter(mapping);
    non_loop_blocks->iterate_forward(&setter);
  }
}