void CATBuilder::cleanup(WorkSpace *ws) { static cstring cat_names[] = { "INV", "AH", "FH", "FM", "AM", "NC" }; if(!logFor(LOG_BB)) return; const CFGCollection *cfgs = INVOLVED_CFGS(ws); ASSERT(cfgs); for(int i = 0; i < cfgs->count(); i++) for(CFG::BBIterator bb(cfgs->get(i)); bb; bb++) { cerr << "\tBB " << bb->number() << " (" << bb->address() << ")\n"; Pair<int, BlockAccess *> ab = DATA_BLOCKS(bb); for(int j = 0; j < ab.fst; j++) { BlockAccess& b = ab.snd[j]; cerr << "\t\t" << b << " -> " << cat_names[dcache::CATEGORY(b)] << io::endl; } } }
void CATBuilder::cleanup(WorkSpace *ws) { static cstring cat_names[] = { "INV", "AH", "FH", "PE", "AM", "NC" }; if(!logFor(LOG_BB)) return; int stats[cache::NOT_CLASSIFIED + 1], total = 0; array::set(stats, NOT_CLASSIFIED + 1, 0); const CFGCollection *cfgs = INVOLVED_CFGS(ws); ASSERT(cfgs); for(int i = 0; i < cfgs->count(); i++) for(CFG::BBIterator bb(cfgs->get(i)); bb; bb++) { cerr << "\tBB " << bb->number() << " (" << bb->address() << ")\n"; Pair<int, BlockAccess *> ab = DATA_BLOCKS(bb); for(int j = 0; j < ab.fst; j++) { BlockAccess& b = ab.snd[j]; cerr << "\t\t" << b << " -> " << cat_names[dcache::CATEGORY(b)] << io::endl; stats[dcache::CATEGORY(b)]++; total++; } } if(logFor(LOG_FUN)) { for(int i = cache::ALWAYS_HIT; i <= cache::NOT_CLASSIFIED; i++) cerr << cat_names[i] << " : " << io::fmt(stats[i]).width(5).right() << " (" << io::fmt(double(stats[i] * 100) / total).width(5, 2).right() << "%)\n"; cerr << "total: " << total << io::endl; } }
void CATBuilder::processLBlockSet(WorkSpace *ws, const BlockCollection& coll, const hard::Cache *cache) { if(coll.count() == 0) return; // prepare problem int line = coll.cacheSet(); MUSTPERS prob(&coll, ws, cache); MUSTPERS::Domain dom = prob.bottom(); acs_stack_t empty_stack; if(logFor(LOG_FUN)) log << "\tSET " << line << io::endl; const CFGCollection *cfgs = INVOLVED_CFGS(ws); ASSERT(cfgs); for(int i = 0; i < cfgs->count(); i++) { if(logFor(LOG_BB)) log << "\t\tCFG " << cfgs->get(i) << io::endl; for(CFG::BBIterator bb(cfgs->get(i)); bb; bb++) { if(logFor(LOG_BB)) log << "\t\t\t" << *bb << io::endl; // get the input domain acs_table_t *ins = MUST_ACS(bb); prob.setMust(dom, *ins->get(line)); acs_table_t *pers = PERS_ACS(bb); bool has_pers = pers; if(!has_pers) prob.emptyPers(dom); else { acs_stack_t *stack; acs_stack_table_t *stack_table = LEVEL_PERS_ACS(bb); if(stack_table) stack = &stack_table->item(line); else stack = &empty_stack; prob.setPers(dom, *pers->get(line), *stack); } // explore the adresses Pair<int, BlockAccess *> ab = DATA_BLOCKS(bb); for(int j = 0; j < ab.fst; j++) { BlockAccess& b = ab.snd[j]; if(b.kind() != BlockAccess::BLOCK) { CATEGORY(b) = cache::NOT_CLASSIFIED; prob.ageAll(dom); } else if(b.block().set() == line) { // initialization bool done = false; CATEGORY(b) = cache::NOT_CLASSIFIED; ACS *may = 0; if(MAY_ACS(bb) != 0) may = MAY_ACS(bb)->get(line); // in MUST ? if(dom.getMust().contains(b.block().index())) CATEGORY(b) = cache::ALWAYS_HIT; // persistent ? else if(has_pers) { // find the initial header BasicBlock *header; if (LOOP_HEADER(bb)) header = bb; else header = ENCLOSING_LOOP_HEADER(bb); // look in the different levels for(int k = dom.getPers().length() - 1; k >= 0 && header; k--) { if(dom.getPers().isPersistent(b.block().index(), k)) { CATEGORY(b) = cache::FIRST_MISS; CATEGORY_HEADER(b) = header; done = true; break; } header = ENCLOSING_LOOP_HEADER(header); } } // out of MAY ? if(!done && may && !may->contains(b.block().index())) CATEGORY(b) = cache::ALWAYS_MISS; // update state prob.inject(dom, b.block().index()); } } } } }
inline void update(Domain& out, const Domain& in, BasicBlock* bb) { Pair<int, BlockAccess *> blocks = DATA_BLOCKS(bb); man.set(out, in); for(int i = 0; i < blocks.fst; i++) man.update(out, blocks.snd[i]); }