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