Example #1
0
void PassUnroll::unrollIt (std::vector<Kernel*> &kernels, Kernel *outer, Kernel *kernel, int i, bool unroll, bool linkedKernel) const
{
	std::ostringstream oss;
	std::string comStr;
	Kernel *outer_copy = NULL;
	Kernel *copy = NULL;
	Kernel *tmp = NULL;

	//Create a copy of the outer
	outer_copy = dynamic_cast<Kernel*> (outer->copy ());

	//Paranoid
	assert (outer_copy != NULL);

	if (unroll == true)    
	{
		//Find the kernel
		copy = dynamic_cast<Kernel*> (outer_copy->findOrigin (kernel));

		//Paranoid
		assert (copy != NULL);

		//Now remove instructions
		copy->clearStatements ();
	}
	else 
	{
		tmp = dynamic_cast<Kernel*> (kernel->copy ());

		copy = kernel;

		//Paranoid
		assert (copy != NULL);

		copy->clearStatements ();
	}	    

	Comment *unrollCom = new Comment ("Unroll beginning");
	copy->addStatement (unrollCom);   	

	if (kernelContainsInstructions (kernel) == true)
	{
		std::ostringstream oss;
		oss << "Unrolled factor " << i;
		Comment *unrollCom = new Comment (oss.str ());
		copy->addStatement (unrollCom);   	
	}

	for (int j = 0; j < i; j++)
	{
		unsigned int nbr = copy->getNbrStatements ();

		oss.str("");
		comStr.clear ();
		oss << (j+1) << " out of "<< i;
		comStr = "Unrolling, iteration " + oss.str () ;
		Comment *unrollCom = new Comment (comStr);
		copy->addStatement (unrollCom);

		//Append first
		if (unroll)        
		{
			copy->append (kernel);
		}
		else 
		{
			copy->append (tmp);	
		}

		//Now inform we are unrolling the other instructions and which unrolled iteration they are
		for (unsigned int k = nbr; k < copy->getNbrStatements (); k++)
		{
			Statement *stmt = copy->getModifiableStatement (k);

			stmt->updateUnrollInformation (j);

			stmt->updateRegisterName (j);
		}
	}

	if (i > 1)
	{
		//Update Induction Unrolling
		copy->updateInductionUnrolling (i);

		//Update the actual unroll
		copy->setActualUnroll (i);
	}

	Comment *endInst = new Comment ("Unroll ending");
	copy->addStatement (endInst);

	if (unroll == true)	
	{		
		kernels.push_back (outer_copy);
	}   

	//Free them
	if (linkedKernel == true)
	{
		delete tmp, tmp = NULL;
		delete outer_copy, outer_copy = NULL;
	}
}