void TextDecoder::processWorkSpace(WorkSpace *fw) { // Decode the text Processor *decoder = fw->process()->decoder(); if(decoder) { if(logFor(LOG_DEPS)) log << "INFO: using loader plugin decoder.\n"; decoder->process(fw, *conf_props); } else { if(logFor(LOG_DEPS)) log << "INFO: no default decoder\n"; if(!fw->process()->instSize() || follow_paths) { if(logFor(LOG_DEPS)) log << "INFO: using VarTextDecoder\n"; VarTextDecoder decoder; decoder.process(fw, *conf_props); } else { if(logFor(LOG_DEPS)) log << "INFO: using FixedTextDecoder\n"; FixedTextDecoder decoder; decoder.process(fw, *conf_props); } } // Put the labels if(!LABELS_DONE(fw->process())) { for(Process::FileIter file(fw->process()); file; file++) for(File::SymIter sym(file); sym; sym++) { ProgItem *item = file->findItemAt(sym->address()); if(item) { Inst *inst = item->toInst(); if(inst) switch(sym->kind()) { case Symbol::FUNCTION: FUNCTION_LABEL(inst).add(sym->name()); break; case Symbol::LABEL: LABEL(inst).add(sym->name()); break; default: break; } } } LABELS_DONE(fw->process()) = true; } }
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; } } }
/** * See @ref CFGProcessor::processCFG() */ void BBProcessor::processCFG(WorkSpace *fw, CFG *cfg) { for(CFG::BBIterator bb(cfg); bb; bb++) { if(logFor(LOG_BB)) log << "\t\tprocess BB " << bb->number() << " (" << ot::address(bb->address()) << ")\n"; processBB(fw, cfg, bb); } }
void CFGCheckSummer::processCFG(WorkSpace *ws, CFG *cfg) { checksum::Fletcher sum; for(CFG::BBIterator bb(cfg); bb; bb++) if(!bb->isEnd()) { char buf[bb->size()]; ws->process()->get(bb->address(), buf, bb->size()); sum.put(buf, bb->size()); } CHECKSUM(cfg) = sum.sum(); if(logFor(LOG_PROC)) log << "\t\tchecksum = " << (void *)(unsigned long)CHECKSUM(cfg) << io::endl; }
virtual void processWorkSpace(WorkSpace *ws) { if(config) { CACHE_CONFIGURATION(ws) = config; if(logFor(LOG_DEPS)) log << "\tcustom cache configuration\n"; } else if(xml) { config = CacheConfiguration::load(xml); track(CACHE_CONFIGURATION_FEATURE, CACHE_CONFIGURATION(ws) = config); if(logFor(LOG_DEPS)) log << "\t cache configuration from XML element\n"; } else if(path) { if(logFor(LOG_DEPS)) log << "\t cache configuration from \"" << path << "\"\n"; config = CacheConfiguration::load(path); track(CACHE_CONFIGURATION_FEATURE, CACHE_CONFIGURATION(ws) = config); } else if(logFor(LOG_DEPS)) log << "\tno cache configuration\n"; }
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 CFGProcessor::processWorkSpace(WorkSpace *fw) { // Get the CFG collection const CFGCollection *cfgs = INVOLVED_CFGS(fw); ASSERT(cfgs); // Visit CFG int count = 0; for(CFGCollection::Iterator cfg(cfgs); cfg; cfg++) { if(logFor(LOG_CFG)) log << "\tprocess CFG " << cfg->label() << io::endl; _cfg = cfg; processCFG(fw, cfg); count++; } // Record stats if(recordsStats()) PROCESSED_CFG(stats) = count; }
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()); } } } } }