Example #1
0
	void SubMatrix::subMatrixCreation2D(int** mtr,int xMin,int yMin,VectorQueue point,int ignValue)
	{

		int** sMatrix=new int* [xSize];
		for(int i=0;i<xSize;i++)
		{
			sMatrix[i]=new int[ySize];
			for(int j=0;j<ySize;j++)
				sMatrix[i][j]=ignValue;
		}
		while(!point.isEmpty())
		{
			sMatrix[point.x.front()-xPos+2*radius][point.y.front()-yPos+2*radius]=mtr[point.x.front()][point.y.front()];
			point.pop();
		}
		matrix2D=sMatrix;
		matrixAbs2D();
	}
Example #2
0
	VectorQueue neighbour2D(int** matrix,int ignValue, int radius, VectorQueue vctQ,int sizeX, int sizeY)
	{
		int xLimitSup,xLimitInf,yLimitSup,yLimitInf;
		VectorQueue tmpQ;
		tmpQ.push(vctQ.x.front(),vctQ.y.front(),0);
		while(!vctQ.isEmpty())
		{
			xLimitSup=vctQ.x.front()+2*radius+1;
			xLimitInf= vctQ.x.front()-2*radius-1;
			if(xLimitInf<1)xLimitInf=1;
			if (xLimitSup>=sizeX-1) xLimitSup=sizeX-1;
			for(int i=xLimitInf;i<=xLimitSup;i++)
			{
				yLimitSup=vctQ.y.front()+2*radius+1;
				yLimitInf= vctQ.y.front()-2*radius-1;
				if(yLimitInf<1) yLimitInf=1;
				yLimitSup=vctQ.y.front()+2*radius;
				if (yLimitSup>=sizeY-1) yLimitSup=sizeY-1;
				for(int j=yLimitInf;j<=yLimitSup;j++)
				{
					if((matrix[i][j]!=ignValue)&&(matrix[i][j]>0))
					{
						vctQ.push(i,j,0);
						tmpQ.push(i,j,0);
						matrix[i][j]-=2*matrix[i][j];
					}
				}
			}
			vctQ.pop();
		}

		return tmpQ;
	}
Example #3
0
	void SubMatrix::subMatrixCreation3D(int*** mtr,int sizeX,int sizeY,int sizeZ,int xMin,int yMin, int zMin,VectorQueue point,int ignValue, int radius)
	{

		int*** sMatrix=new int**[sizeX];
		for(int i=0;i<sizeX;i++)
		{
			sMatrix[i]=new int*[sizeY];
			for(int j=0;j<sizeY;j++)
			{
				sMatrix[i][j]=new int[sizeZ];
				for(int k=0;k<sizeZ;k++)
					sMatrix[i][j][k]=ignValue;
			}
		}
		while(!point.isEmpty())
		{
			sMatrix[point.x.front()-xMin+radius][point.y.front()-yMin+radius][point.z.front()-zMin+radius]=mtr[point.x.front()][point.y.front()][point.z.front()];
			point.pop();
		}
		matrix3D=sMatrix;
		matrixAbs3D();
	}
Example #4
0
	VectorQueue neighbour3D(int*** matrix,int ignValue, int radius, VectorQueue vctQ)
	{
		VectorQueue tmpQ;
		tmpQ.push(vctQ.x.front(),vctQ.y.front(),vctQ.z.front());
		while(!vctQ.isEmpty())
		{
			for(int k=vctQ.z.front()-radius;k<=vctQ.z.front()+radius;k++)
			{
				for(int i=vctQ.y.front()-radius;i<=vctQ.y.front()+radius;i++)
				{
					for(int j=vctQ.x.front()-radius;j<=vctQ.x.front()+radius;j++)
						if((matrix[j][i][k]!=ignValue)&&(matrix[j][i][k]>0))
						{
							vctQ.push(j,i,k);
							tmpQ.push(j,i,k);
							matrix[j][i][k]-=2*matrix[j][i][k];
						}
				}
			}
			vctQ.pop();
		}

		return tmpQ;
	}
Example #5
0
void LoopUnroller::unroll(otawa::CFG *cfg, BasicBlock *header, VirtualCFG *vcfg) {
	VectorQueue<BasicBlock*> workList;
	VectorQueue<BasicBlock*> loopList;
	VectorQueue<BasicBlock*> virtualCallList;
	genstruct::Vector<BasicBlock*> doneList;
	typedef genstruct::Vector<Pair<VirtualBasicBlock*, Edge::kind_t> > BackEdgePairVector;
	BackEdgePairVector backEdges;
	bool dont_unroll = false;
	BasicBlock *unrolled_from;
	int start;

	/* Avoid unrolling loops with LOOP_COUNT of 0, since it would create a LOOP_COUNT of -1 for the non-unrolled part of the loop*/

	/*

	if (header && (ipet::LOOP_COUNT(header) == 0)) {
		dont_unroll = true;
	}

	*/
	//if (header) dont_unroll = true;
	start = dont_unroll ? 1 : 0;


	for (int i = start; ((i < 2) && header) || (i < 1); i++) {
		doneList.clear();
		ASSERT(workList.isEmpty());
		ASSERT(loopList.isEmpty());
		ASSERT(doneList.isEmpty());

		workList.put(header ? header : cfg->entry());
		doneList.add(header ? header : cfg->entry());

		genstruct::Vector<BasicBlock*> bbs;

		while (!workList.isEmpty()) {

			BasicBlock *current = workList.get();

			if (LOOP_HEADER(current) && (current != header)) {
				/* we enter another loop */

				loopList.put(current);

				/* add exit edges destinations to the worklist */

				for (genstruct::Vector<Edge*>::Iterator exitedge(**EXIT_LIST(current)); exitedge; exitedge++) {
					if (!doneList.contains(exitedge->target())) {
						workList.put(exitedge->target());
						doneList.add(exitedge->target());
					}
				}
			} else {
				VirtualBasicBlock *new_bb = 0;
				if ((!current->isEntry()) && (!current->isExit())) {
					/* Duplicate the current basic block */

					new_bb = new VirtualBasicBlock(current);
					new_bb->removeAllProp(&ENCLOSING_LOOP_HEADER);
					new_bb->removeAllProp(&EXIT_LIST);
					new_bb->removeAllProp(&REVERSE_DOM);
					new_bb->removeAllProp(&LOOP_EXIT_EDGE);
					new_bb->removeAllProp(&LOOP_HEADER);
					new_bb->removeAllProp(&ENTRY);

					/* Remember the call block so we can correct its destination when we have processed it */
					if (VIRTUAL_RETURN_BLOCK(new_bb))
						virtualCallList.put(new_bb);

					if ((current == header) && (!dont_unroll)) {
						if (i == 0) {
							unrolled_from = new_bb;
						} else {
							UNROLLED_FROM(new_bb) = unrolled_from;
						}
					}
					/*
					if (ipet::LOOP_COUNT(new_bb) != -1) {
						if (i == 0) {
							new_bb->removeAllProp(&ipet::LOOP_COUNT);
						}
						else {
							int old_count = ipet::LOOP_COUNT(new_bb);
							new_bb->removeAllProp(&ipet::LOOP_COUNT);
							ipet::LOOP_COUNT(new_bb) = old_count - (1 - start);
							ASSERT(ipet::LOOP_COUNT(new_bb) >= 0);

						}

					}
					*/
					INDEX(new_bb) = idx;
					idx++;
					vcfg->addBB(new_bb);


					bbs.add(current);

					map.put(current, new_bb);
				}


				/* add successors which are in loop (including possible sub-loop headers) */
				for (BasicBlock::OutIterator outedge(current); outedge; outedge++) {

					if (outedge->target() == cfg->exit())
						continue;
					if (outedge->kind() == Edge::CALL)
						continue;

					if (ENCLOSING_LOOP_HEADER(outedge->target()) == header) {
					//	cout << "Test for add: " << outedge->target()->number() << "\n";
						if (!doneList.contains(outedge->target())) {
							workList.put(outedge->target());
							doneList.add(outedge->target());
						}
					}
					if (LOOP_EXIT_EDGE(outedge)) {
						ASSERT(new_bb);
						/* Connect exit edge */
						VirtualBasicBlock *vdst = map.get(outedge->target());
						new Edge(new_bb, vdst, outedge->kind());
					}
				}

			}
		}

		while (!virtualCallList.isEmpty()) {
			BasicBlock *vcall = virtualCallList.get();
			BasicBlock *vreturn = map.get(VIRTUAL_RETURN_BLOCK(vcall), 0);

			ASSERT(vreturn != 0);
			VIRTUAL_RETURN_BLOCK(vcall) = vreturn;

		}


		while (!loopList.isEmpty()) {
			BasicBlock *loop = loopList.get();
			unroll(cfg, loop, vcfg);
		}



		/* Connect the internal edges for the current loop */
		for (genstruct::Vector<BasicBlock*>::Iterator bb(bbs); bb; bb++) {
			for (BasicBlock::OutIterator outedge(bb); outedge; outedge++) {
				if (LOOP_EXIT_EDGE(outedge))
					continue;
				if (LOOP_HEADER(outedge->target()) && (outedge->target() != header))
					continue;
				if (outedge->target() == cfg->exit())
					continue;

				VirtualBasicBlock *vsrc = map.get(*bb, 0);
				VirtualBasicBlock *vdst = map.get(outedge->target(), 0);

				if (outedge->kind() == Edge::CALL) {
					CFG *called_cfg = outedge->calledCFG();
					int called_idx = INDEX(called_cfg);
					CFG *called_vcfg = coll->get(called_idx);
					Edge *vedge = new Edge(vsrc, called_vcfg->entry(), Edge::CALL);
					CALLED_BY(called_vcfg).add(vedge);
					ENTRY(called_vcfg->entry()) = called_vcfg;
					CALLED_CFG(outedge) = called_vcfg; /* XXX:  ??!? */


				} else if ((outedge->target() != header) || ((i == 1) /* XXX && !dont_unroll XXX*/ )) {
					new Edge(vsrc, vdst, outedge->kind());
				} else {
					backEdges.add(pair(vsrc, outedge->kind()));
				}
			}
		}

		if (i == start) {
			/* Connect virtual entry edges */
			if (header) {
				for (BasicBlock::InIterator inedge(header); inedge; inedge++) {
					if (Dominance::dominates(header, inedge->source()))
						continue; /* skip back edges */
					if (inedge->source() == cfg->entry())
						continue;
					VirtualBasicBlock *vsrc = map.get(inedge->source());
					VirtualBasicBlock *vdst = map.get(header);
					new Edge(vsrc, vdst, inedge->kind());
				}
			}

		} else {
			/* Connect virtual backedges from the first to the other iterations */
			for (BackEdgePairVector::Iterator iter(backEdges); iter; iter++) {
				VirtualBasicBlock *vdst = map.get(header);
				new Edge((*iter).fst, vdst, (*iter).snd);
			}
		}
	}
	if (!header) {
		/* add main entry edges */
		for (BasicBlock::OutIterator outedge(cfg->entry()); outedge; outedge++) {
			VirtualBasicBlock *vdst = map.get(outedge->target());
			new Edge(vcfg->entry(), vdst, Edge::VIRTUAL_CALL);
		}
		/* add main exit edges */
		for (BasicBlock::InIterator inedge(cfg->exit()); inedge; inedge++) {
			VirtualBasicBlock *vsrc = map.get(inedge->source());
			new Edge(vsrc, vcfg->exit(), Edge::VIRTUAL_RETURN);
		}
	}

}
Example #6
0
/**
 * Scan the CFG for finding exit and builds virtual edges with entry and exit.
 * For memory-place and time purposes, this method is only called when the CFG
 * is used (call to an accessors method).
 */
void CFG::scan(void) {

	// Prepare data
	typedef HashTable<BasicBlock *, BasicBlock *> map_t;
	map_t map;
	VectorQueue<BasicBlock *> todo;
	todo.put(ent);

	// Find all BB
	_bbs.add(&_entry);
	while(todo) {
		BasicBlock *bb = todo.get();
		ASSERT(bb);

		// second case : calling jump to a function
		if(map.exists(bb) || (bb != ent && ENTRY(bb)))
			continue;

		// build the virtual BB
		BasicBlock *vbb = new VirtualBasicBlock(bb);
		_bbs.add(vbb);
		map.put(bb, vbb);
		ASSERTP(map.exists(bb), "not for " << bb->address());

		// resolve targets
		for(BasicBlock::OutIterator edge(bb); edge; edge++) {
			ASSERT(edge->target());
			if(edge->kind() != Edge::CALL)
				todo.put(edge->target());
		}
	}

	// Relink the BB
	BasicBlock *vent = map.get(ent, 0);
	ASSERT(vent);
	new Edge(&_entry, vent, Edge::VIRTUAL);
	for(bbs_t::Iterator vbb(_bbs); vbb; vbb++) {
		if(vbb->isEnd())
			continue;
		BasicBlock *bb = ((VirtualBasicBlock *)*vbb)->bb();
		if(bb->isReturn())
			new Edge(vbb, &_exit, Edge::VIRTUAL);

		for(BasicBlock::OutIterator edge(bb); edge; edge++) {

			// A call
			if(edge->kind() == Edge::CALL) {
				Edge *vedge = new Edge(vbb, edge->target(), Edge::CALL);
				vedge->toCall();
			}

			// Pending edge
			else if(!edge->target()) {
				new Edge(vbb, 0, edge->kind());
			}

			// Possibly a not explicit call
			else {
				ASSERT(edge->target());
				BasicBlock *vtarget = map.get(edge->target(), 0);
				if(vtarget)
					new Edge(vbb, vtarget, edge->kind());
				else {		// calling jump to a function
					Edge *nedge = new Edge(vbb, edge->target(), Edge::CALL);
					vbb->flags |= BasicBlock::FLAG_Call;
					new Edge(vbb, &_exit, Edge::VIRTUAL);
				}
			}

		}
	}
	_bbs.add(&_exit);

	// Number the BB
	for(int i = 0; i < _bbs.length(); i++) {
		INDEX(_bbs[i]) = i;
		_bbs[i]->_cfg = this;
	}
	flags |= FLAG_Scanned;

}