---- Copyright (c) 2009-2010, ERICSSON AB All rights reserved.-- -- Redistribution and use in source and binary forms, with or without-- modification, are permitted provided that the following conditions are met:-- -- * Redistributions of source code must retain the above copyright notice,-- this list of conditions and the following disclaimer.-- * Redistributions in binary form must reproduce the above copyright-- notice, this list of conditions and the following disclaimer in the-- documentation and/or other materials provided with the distribution.-- * Neither the name of the ERICSSON AB nor the names of its contributors-- may be used to endorse or promote products derived from this software-- without specific prior written permission.-- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS-- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF-- THE POSSIBILITY OF SUCH DAMAGE.--{-# LANGUAGE FlexibleInstances, TypeFamilies #-}moduleFeldspar.Compiler.Plugins.UnrollwhereimportFeldspar.Compiler.Imperative.RepresentationimportFeldspar.Compiler.OptionsimportPreludeimportFeldspar.Compiler.Imperative.SemanticsimportFeldspar.Compiler.PluginArchitectureinstancePluginUnrollPluginwheretypeExternalInfoUnrollPlugin=UnrollStrategyexecutePluginUnrollPlugineip=caseeiofNoUnroll->pUnrollunrollCount->fst$executeTransformationPhaseUnroll_2Nothing$fst$executeTransformationPhaseUnroll_1unrollCountpdataUnrollPlugin=UnrollPlugininstanceTransformationPhaseUnrollPluginwheretypeFromUnrollPlugin=()typeToUnrollPlugin=()typeDownwardsUnrollPlugin=()typeUpwardsUnrollPlugin=()dataUnroll_1=Unroll_1instanceTransformationPhaseUnroll_1wheretypeFromUnroll_1=()typeToUnroll_1=UnrollSemInftypeDownwardsUnroll_1=InttypeUpwardsUnroll_1=BoolupwardsParallelLoopProgramInProgram_____=TruetransformParallelLoopProgramInProgramUnroll_1dplu=trParLoop1dpludataUnroll_2=Unroll_2instanceTransformationPhaseUnroll_2wheretypeFromUnroll_2=UnrollSemInftypeToUnroll_2=()typeDownwardsUnroll_2=MaybeSemInfPrgtypeUpwardsUnroll_2=()downwardsProgramUnroll_2dp|programSemInfp==Nothing=d|otherwise=programSemInfptransformVariableUnroll_2dv=trVariabledvtransformVariableLeftValueInLeftValueUnroll_2dv=VariableLeftValue$trVariabled$vtransformLeftValueExpressionInExpressionUnroll_2dlvieu=trLVIEdlvieudataUnrollSemInf=UnrollSemInfinstanceSemanticInfoUnrollSemInfwheretypeProcedureInfoUnrollSemInf=()typeBlockInfoUnrollSemInf=()typeProgramInfoUnrollSemInf=MaybeSemInfPrgtypeEmptyInfoUnrollSemInf=MaybeSemInfPrgtypePrimitiveInfoUnrollSemInf=MaybeSemInfPrgtypeSequenceInfoUnrollSemInf=MaybeSemInfPrgtypeBranchInfoUnrollSemInf=()typeSequentialLoopInfoUnrollSemInf=()typeParallelLoopInfoUnrollSemInf=()typeFormalParameterInfoUnrollSemInf=()typeLocalDeclarationInfoUnrollSemInf=()typeExpressionInfoUnrollSemInf=()typeConstantInfoUnrollSemInf=()typeFunctionCallInfoUnrollSemInf=()typeLeftValueInfoUnrollSemInf=()typeArrayElemReferenceInfoUnrollSemInf=()typeInstructionInfoUnrollSemInf=()typeAssignmentInfoUnrollSemInf=()typeProcedureCallInfoUnrollSemInf=()typeActualParameterInfoUnrollSemInf=()typeIntConstantInfoUnrollSemInf=()typeFloatConstantInfoUnrollSemInf=()typeBoolConstantInfoUnrollSemInf=()typeArrayConstantInfoUnrollSemInf=()typeVariableInfoUnrollSemInf=()instanceCombineBoolwherecombine=(||)dataSemInfPrg=SemInfPrg{position::Int,varNames::[String],loopVar::String}deriving(Eq,Show)instanceDefault(MaybeSemInfPrg)wheredefaultValue=NothingtrLVIE::DownwardsUnroll_2->LeftValueUnrollSemInf->InfoFromLeftValuePartsUnroll_2->ExpressionData()trLVIEd(LeftValueleftValue_)u=casedofJustx->resultxotherwise->origwherename=caseleftValueofVariableLeftValued->Just$getVarNamedotherwise->Nothingresultx=casenameofJustn|n==loopVarx->FunctionCallExpression$FunctionCallInfixOp(NumericImpSignedS32)("+")([loopVarPar,plusPar])()|otherwise->origotherwise->origwhereloopVarPar=Expressionorig()num=positionxplusPar=Expression(ConstantExpression$Constant(IntConstant$IntConstantTypenum())())()orig=LeftValueExpression$LeftValue(recursivelyTransformedLeftValueDatau)()trVariabledv|d/=Nothing&&elementOf(varNames(valueFromJustd))(getVarNamev)=v{variableName=(variableNamev)++"_u"++(show$position$valueFromJustd),variableSemInf=()}|otherwise=v{variableSemInf=()}trParLoop1::DownwardsUnroll_1->ParallelLoop()->InfoFromParallelLoopPartsUnroll_1->ProgramConstructionUnrollSemInftrParLoop1dplu|(upwardsInfoFromParallelLoopCoreu)==False&&(unrollPossible||varInExpr)=ParallelLoopProgramnewParLoop|otherwise=ParallelLoopProgramtrPlwherenewParLoop=trPl{parallelLoopStep=unrollNum,parallelLoopCore=newLoopCore,parallelLoopSemInf=()}newLoopCore=origLoopCore{blockDeclarations=unrollDecls,blockInstructions=unrollPrg,blockSemInf=()}unrollPrg=Program(SequenceProgram$Sequenceprgs(Nothing))(Nothing)prgs=map(\(i,p)->writeSemInfToPrgp(Just$SemInfPrgivarNamesloopCounter))$zip[0,1..]replPrgwriteSemInfToPrgprgsemInf=prg{programSemInf=semInf}replPrg=replicateunrollNumorigPrgorigPrg=blockInstructions$origLoopCoreunrollDecls=concat$map(\(i,ds)->renameDeclsdsi)$zip[0,1..]replDeclsrenameDeclsdsi=map(\d->renameDeclarationd((getVarNameDecld)++"_u"++(showi)))dsreplDecls=replicateunrollNumorigDeclsorigDecls=blockDeclarations$origLoopCoreorigLoopCore=recursivelyTransformedParallelLoopCoreuiterExpr=recursivelyTransformedNumberOfIterationsuloopCounter'=recursivelyTransformedParallelLoopConditionVariableutrPl=ParallelLooploopCounter'iterExpr(parallelLoopSteppl)origLoopCore()unrollNum=dloopCounter=getVarName$recursivelyTransformedParallelLoopConditionVariableuvarNames=map(\d->getVarNameDecld)origDeclsiterTemp=iterNumFromExpriterExprorigIterNum=valueFromJustiterTempiterNumIsConstant=isJustiterTempunrollPossible=iterNumIsConstant&&(modorigIterNumd==0)varInExpr=not$isJustiterTemp-- helper functions : iterNumFromExpr(Expression(ConstantExpression(Constant(IntConstant(IntConstantTypei_))_))_)=JustiiterNumFromExpr_=NothingisJust(Justx)=TrueisJust_=FalsegetVarNameDecld=getVarName$localVariabledgetVarNamev=variableNamevvalueFromJust(Justv)=vvalueFromJustNothing=error"This was Nothing"renameDeclarationdn=d{localVariable=renameVariable(localVariabled)n}renameVariablevn=v{variableName=n}elementOfsss=(length$filter(\s'->s'==s)ss)>0