Example #1
0
void Builder::processLBlockSet(WorkSpace *fw, otawa::ccg::LBlockSet *lbset) {
	ASSERT(fw);
	ASSERT(lbset);
	const hard::Cache *cache = hard::CACHE_CONFIGURATION(fw)->instCache();

	// Create the CCG
	Collection *ccgs = Graph::GRAPHS(fw);
	if(!ccgs) {
		ccgs = new Collection(cache->rowCount());
		fw->addProp(new DeletableProperty<Collection *>(Graph::GRAPHS, ccgs));
	}
	Graph *ccg = new Graph;
	ccgs->ccgs[lbset->line()] = ccg;

	// Initialization
	for(LBlockSet::Iterator lblock(*lbset); lblock; lblock++) {
		Node *node = new Node(lblock);
		ccg->add(node);
		Graph::NODE(lblock) = node;
	}

	// Run the DFA
	Problem prob(lbset, lbset->count(), cache, fw);
	const CFGCollection *coll = INVOLVED_CFGS(fw);
	dfa::XCFGVisitor<Problem> visitor(*coll, prob);
	dfa::XIterativeDFA<dfa::XCFGVisitor<Problem> > engine(visitor);
	engine.process();

	// Add the annotations from the DFA result
	for (CFGCollection::Iterator cfg(coll); cfg; cfg++) {
		for (CFG::BBIterator block(*cfg); block; block++) {
			dfa::XCFGVisitor<Problem>::key_t pair(*cfg, *block);
			dfa::BitSet *bitset = engine.in(pair);
			block->addProp(new DeletableProperty<dfa::BitSet *>(IN, new dfa::BitSet(*bitset)));
		}
	}

	// Detecting the non conflict state of each lblock
	BasicBlock *BB;
	LBlock *line;
	int length = lbset->count();
	for(LBlockSet::Iterator lbloc(*lbset); lbloc; lbloc++)
		if(lbloc->id() != 0 && lbloc->id() != length - 1) {
			BB = lbloc->bb();
			dfa::BitSet *inid = IN(BB);
			for(dfa::BitSet::Iterator bit(*inid); bit; bit++)
				line = lbset->lblock(*bit);
				if(cache->block(line->address()) == cache->block(lbloc->address())
					&& BB != line->bb())
					NON_CONFLICT(lbloc) = true;

		}

	// Building the ccg edges using DFA
	length = lbset->count();
	address_t adinst;
	LBlock *aux;

	for (CFGCollection::Iterator cfg(coll); cfg; cfg++) {
		for (CFG::BBIterator bb(*cfg); bb; bb++) {
			if ((cfg != ENTRY_CFG(fw)) || (!bb->isEntry() && !bb->isExit())) {
				dfa::BitSet *info = IN(bb);
				ASSERT(info);
				bool test = false;
				bool visit;
				for(BasicBlock::InstIter inst(bb); inst; inst++) {
					visit = false;
					adinst = inst->address();
					for (LBlockSet::Iterator lbloc(*lbset); lbloc; lbloc++){
						address_t address = lbloc->address();
						// the first lblock in the BB it's a conflict
						if(adinst == address && !test && bb == lbloc->bb()) {
							for (int i = 0; i< length; i++)
								if (info->contains(i)) {
									LBlock *lblock = lbset->lblock(i);
									Node *node = Graph::NODE(lblock);
									new Edge (node, Graph::NODE(lbloc));
								}
							aux = lbloc;
							test = true;
							visit = true;
							break;
						}

						if(adinst == address && !visit && bb == lbloc->bb()) {
							new Edge(Graph::NODE(aux), Graph::NODE(lbloc));
							aux = lbloc;
							break;
						}
					}
				}
			}
		}
	}

	// build edge to LBlock end
	BasicBlock *exit = ENTRY_CFG(fw)->exit();
	LBlock *end = lbset->lblock(length-1);
	dfa::BitSet *info = IN(exit);
	for (int i = 0; i< length; i++)
		if (info->contains(i)) {
			LBlock *ccgnode1 = lbset->lblock(i);
			new Edge(Graph::NODE(ccgnode1), Graph::NODE(end));
		}

	// Build edge from 'S' till 'end'
	LBlock *s = lbset->lblock(0);
	new Edge(Graph::NODE(s), Graph::NODE(end));

	// Cleanup the DFA annotations
	for (CFGCollection::Iterator cfg(coll); cfg; cfg++)
		for (CFG::BBIterator block(cfg); block; block++)
			block->removeProp(&IN);
}