Exemplo n.º 1
0
  // recursively delete the stmts and subtrees
  ~TreeNode()
  {
    for (StmtMap::iterator sit = stmtMap.begin(); sit != stmtMap.end(); ++sit) {
      delete sit->second;
    }
    stmtMap.clear();

    for (LoopList::iterator lit = loopList.begin(); lit != loopList.end(); ++lit) {
      delete (*lit)->node;
    }
    loopList.clear();

    for (NodeMap::iterator nit = nodeMap.begin(); nit != nodeMap.end(); ++nit) {
      delete nit->second;
    }
    nodeMap.clear();
  }
Exemplo n.º 2
0
// Gather backedges of natural loops: an edge a -> b where b dominates a
LoopList* LoopFinder::find_backedges(boolArray* visited) {
  int i;
  LoopList* backedges = new LoopList();
  for (i = 0; i < max_blocks(); i++) {
    if (visited->at(i)) {
      BlockLoopInfo* bli = _info->at(i);
      BlockBegin*    bb  = bli->block();
      BlockEnd*      be  = bb->end();
      int n = be->number_of_sux();
      for (int i = 0; i < n; i++) {
        BlockBegin* sux = be->sux_at(i);
        if (bli->is_dom_block(sux->block_id())) {
          bli->mark_backedge_start();
          backedges->push(new Loop(sux, bb));
        }
      }
    }
  }

  // backedges contains single pairs of blocks which are a backedge.
  // some of these loops may share entry points, so walk over the backedges
  // and merge loops which have the same entry point
  if (backedges->length() > 1) {
    backedges->sort(sort_by_start_block);
    Loop* current_loop = backedges->at(0);
    for (i = 1; i < backedges->length();) {
      Loop* this_loop = backedges->at(i);
      if (current_loop->start() == this_loop->start()) {
        // same entry point
        assert(this_loop->ends()->length() == 1, "should only have one end at this point");
#ifndef PRODUCT
        if (PrintLoops && Verbose) {
          tty->print_cr("Merging loops with same start");
          current_loop->print();
          this_loop->print();
        }
#endif
        BlockBegin* e = this_loop->ends()->at(0);
        current_loop->add_end(e);
        backedges->remove(this_loop);
      } else {
        // start processing the next loop entry point
        i++;
      }
    }
  }

  return backedges;
}
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);
  }
}
Exemplo n.º 4
0
// Returns inner loops that have may or may not have calls
LoopList* LoopFinder::find_loops(LoopList* loops, bool call_free_only) {
  LoopList* inner = new LoopList();
  LoopList* outer = new LoopList();
  int lng = loops->length();
  // First step: find loops that have no calls and no backedges
  //             in the loop except its own
  int i;
  for (i = 0; i < lng; i++) {
    Loop* loop = loops->at(i);
    int k = loop->nof_blocks() - 1;
    bool is_outer = false;
    for (; k >= 0; k--) {
      BlockBegin* b = loop->block_no(k);
      // Is this innermost loop:
      // - no block, except end block, may be a back edge start,
      //   otherwise we have an outer loop
      if (!loop->is_end(b)) {
        BlockLoopInfo* bli = get_block_info(b);
        if (bli->is_backedge_start()) {
          if (WantsLargerLoops) {
            is_outer = true;
          } else {
            loop = NULL;
          }
          break;
        }
      }
    }

    if (loop != NULL) {
      ScanBlocks scan(loop->blocks());
      ScanResult scan_result;
      scan.scan(&scan_result);
      if (!call_free_only || (!scan_result.has_calls() && !scan_result.has_slow_cases())) {
        if (is_outer) {
          outer->append(loop);
        } else {
          inner->append(loop);
        }
      } else {
#ifndef PRODUCT
        if (PrintLoops && Verbose) {
          tty->print("Discarding loop with calls: ");
          loop->print();
        }
#endif // PRODUCT
      }
    }
  }
  // find all surviving outer loops and delete any inner loops contained inside them
  if (inner->length() > 0) {
    for (i = 0; i < outer->length() ; i++) {
      Loop* loop = outer->at(i);
      int k = loop->nof_blocks() - 1;
      for (; k >= 0; k--) {
        BlockBegin* b = loop->block_no(k);
        if (!loop->is_end(b)) {
          BlockLoopInfo* bli = get_block_info(b);
          if (bli->is_backedge_start()) {
            // find the loop contained inside this loop
            int j;
            for (j = 0; j < inner->length(); j++) {
              Loop* inner_loop = inner->at(j);
              if (inner_loop->is_end(b)) {
                inner->remove(inner_loop);
                break;
              }
            }
            for (j = 0; j < outer->length(); j++) {
              Loop* outer_loop = outer->at(j);
              if (outer_loop == loop) {
                continue;
              }

              if (outer_loop->is_end(b)) {
                outer->remove(outer_loop);
                break;
              }
            }
          }
        }
      }
    }
    inner->appendAll(outer);
  }


  // Second step: if several loops have the same loop-end, select the one
  //              with fewer blocks.
  //              if several loops have the same loop-start, select the one
  //              with fewer blocks
  // now check for loops that have the same header and eliminate one
  for (i = 0; i < inner->length() ; i++) {
    Loop* current_loop = inner->at(i);
    BlockBegin* header = current_loop->start();
    for (int n = i + 1; n < inner->length(); n++) {
      Loop*  test_loop = inner->at(n);
      BlockBegin* test = test_loop->start();
      Loop* discarded = NULL;
      bool same_end = false;
      for (int e = 0; e < current_loop->ends()->length(); e++) {
        if (test_loop->is_end(current_loop->ends()->at(e))) {
          same_end = true;
        }
      }
      if (header == test_loop->start() || same_end) {
        // discard loop with fewer blocks
        if (test_loop->nof_blocks() > current_loop->nof_blocks()) {
          if (WantsLargerLoops) {
            discarded = current_loop;
          } else {
            discarded = test_loop;
          }
        } else {
          if (WantsLargerLoops) {
            discarded = test_loop;
          } else {
            discarded = current_loop;
          }
        }
        inner->remove(discarded);
#ifndef PRODUCT
        if (PrintLoops && Verbose && discarded) {
          tty->print("Discarding overlapping loop: ");
          discarded->print();
        }
#endif // PRODUCT
        // restart the computation
        i = -1;
        break;
      }
    }
  }

  if (inner->length() == 0) {
    // we removed all the loops
    if (PrintLoops && Verbose) {
      tty->print_cr("*** deleted all loops in %s", __FILE__);
    }
    set_not_ok();
    return NULL;
  } else {
    return inner;
  }
}
Exemplo n.º 5
0
 TreeNode()
 {
   nodeMap.clear();
   stmtMap.clear();
   loopList.clear();
 }