示例#1
0
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;
    }
}
示例#2
0
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;
			}
		}
}
示例#3
0
/**
 * 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);
	}
}
示例#4
0
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";
	}
示例#6
0
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;
	}
}
示例#7
0
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;	
}
示例#8
0
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());
				}
			}
		}
	}
}