diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs index 9029dbb..a6b68f3 100644 --- a/backends/GenerateC.hs +++ b/backends/GenerateC.hs @@ -17,7 +17,7 @@ with this program. If not, see . -} -- | Generate C code from the mangled AST. -module GenerateC (cgenOps, cintroduceSpec, fget, genComma, genCPasses, generate, generateC, genLeftB, genMeta, genName, genRightB, GenOps(..), indexOfFreeDimensions, seqComma, withIf ) where +module GenerateC (cgenOps, cintroduceSpec, cPreReq, fget, genComma, genCPasses, generate, generateC, genLeftB, genMeta, genName, genRightB, GenOps(..), indexOfFreeDimensions, seqComma, withIf ) where import Data.Char import Data.Generics @@ -39,6 +39,7 @@ import EvalLiterals import GenerateCBased import Metadata import Pass +import qualified Properties as Prop import ShowCode import TLP import Types @@ -46,12 +47,15 @@ import Utils --{{{ passes related to C generation genCPasses :: [Pass] -genCPasses = makePasses' ((== BackendC) . csBackend) - [ ("Identify parallel processes", identifyParProcs) - ,("Transform wait for guards into wait until guards", transformWaitFor) +genCPasses = makePassesDep' ((== BackendC) . csBackend) + [ ("Identify parallel processes", identifyParProcs, [Prop.parsWrapped], []) + ,("Transform wait for guards into wait until guards", transformWaitFor, [], [Prop.waitForRemoved]) ] --}}} +cPreReq :: [Property] +cPreReq = cCppCommonPreReq ++ [Prop.parsIdentified, Prop.waitForRemoved] + -- | Operations for the C backend. cgenOps :: GenOps cgenOps = GenOps { diff --git a/backends/GenerateCBased.hs b/backends/GenerateCBased.hs index 9992cc1..1a6f593 100644 --- a/backends/GenerateCBased.hs +++ b/backends/GenerateCBased.hs @@ -29,8 +29,29 @@ import CompState import Errors import Metadata import Pass +import qualified Properties as Prop import TLP +cCppCommonPreReq :: [Property] +cCppCommonPreReq = + [Prop.afterRemoved + ,Prop.arrayLiteralsExpanded + ,Prop.assignFlattened + ,Prop.assignParRemoved + ,Prop.freeNamesToArgs + ,Prop.functionCallsRemoved + ,Prop.functionsRemoved + ,Prop.inputCaseRemoved + ,Prop.mainTagged + ,Prop.nestedPulled + ,Prop.outExpressionRemoved + ,Prop.parsWrapped + ,Prop.parUsageChecked + ,Prop.subscriptsPulledUp + ,Prop.typesResolvedInAST + ,Prop.typesResolvedInState + ] + --{{{ monad definition type CGen' = WriterT [String] PassM diff --git a/backends/GenerateCPPCSP.hs b/backends/GenerateCPPCSP.hs index 5925d8d..40ca3ff 100644 --- a/backends/GenerateCPPCSP.hs +++ b/backends/GenerateCPPCSP.hs @@ -68,7 +68,7 @@ as well. May be worth changing in future. Channels of direction 'A.DirUnknown' are passed around as pointers to a One2OneChannel\<\> object. To read I use the reader() function and to write I use the writer() function. For channels of direction 'A.DirInput' or 'A.DirOutput' I actually pass the Chanin\<\> and Chanout\<\> objects as you would expect. -} -module GenerateCPPCSP (generateCPPCSP, cppgenOps, genCPPCSPPasses) where +module GenerateCPPCSP (cppcspPrereq, cppgenOps, generateCPPCSP, genCPPCSPPasses) where import Control.Monad.State import Control.Monad.Writer @@ -84,6 +84,7 @@ import GenerateC import GenerateCBased import Metadata import Pass +import qualified Properties as Prop import ShowCode import TLP import Types @@ -134,8 +135,8 @@ cppgenOps = cgenOps { --}}} genCPPCSPPasses :: [Pass] -genCPPCSPPasses = makePasses' ((== BackendCPPCSP) . csBackend) - [ ("Transform channels to ANY", chansToAny) +genCPPCSPPasses = makePassesDep' ((== BackendCPPCSP) . csBackend) + [ ("Transform channels to ANY", chansToAny, [Prop.processTypesChecked], [Prop.allChansToAnyOrProtocol]) ] chansToAny :: Data t => t -> PassM t @@ -162,6 +163,10 @@ chansToAny x = do st <- get generateCPPCSP :: A.AST -> PassM String generateCPPCSP = generate cppgenOps +cppcspPrereq :: [Property] +cppcspPrereq = cCppCommonPreReq ++ [Prop.allChansToAnyOrProtocol] + + -- | Generates the top-level code for an AST. cppgenTopLevel :: A.AST -> CGen () cppgenTopLevel s diff --git a/common/PassList.hs b/common/PassList.hs index 4b90e0a..b2a2bda 100644 --- a/common/PassList.hs +++ b/common/PassList.hs @@ -43,11 +43,17 @@ import Utils commonPasses :: CompState -> [Pass] commonPasses opts = concat $ [ simplifyTypes - , makePasses' csUsageChecking [("Usage checking", runPassR usageCheckPass)] + , makePassesDep' csUsageChecking [("Usage checking", runPassR usageCheckPass, Prop.agg_namesDone, [Prop.parUsageChecked])] + -- If usage checking is turned off, the pass list will break unless we insert this dummy item: + , makePassesDep' (not . csUsageChecking) [("Usage checking turned OFF", return, Prop.agg_namesDone, [Prop.parUsageChecked])] , simplifyExprs , simplifyProcs , unnest , simplifyComms + -- The occam frontend does a lot of work for us, so I represent that here: + ,makePassesDep' ((== FrontendOccam) . csFrontend) [("Null occam pass", return, [], + Prop.agg_namesDone ++ [Prop.constantsFolded, Prop.expressionTypesChecked, Prop.inferredTypesRecorded, Prop.mainTagged, Prop.processTypesChecked] + )] ] filterPasses :: CompState -> [Pass] -> [Pass] diff --git a/frontends/RainPasses.hs b/frontends/RainPasses.hs index b3e095c..39e5ba6 100644 --- a/frontends/RainPasses.hs +++ b/frontends/RainPasses.hs @@ -30,42 +30,46 @@ import Errors import Metadata import Pass import Pattern +import qualified Properties as Prop import RainTypes import TreeUtils import Types + -- | An ordered list of the Rain-specific passes to be run. rainPasses :: [Pass] -rainPasses = makePasses' ((== FrontendRain) . csFrontend) - [ ("AST Validity check, Rain #1", excludeNonRainFeatures) - ,("Resolve Int -> Int64",transformInt) - ,("Uniquify variable declarations, record declared types and resolve variable names",uniquifyAndResolveVars) --depends on transformInt +rainPasses = makePassesDep' ((== FrontendRain) . csFrontend) + [ ("AST Validity check, Rain #1", excludeNonRainFeatures, [], []) -- TODO work out some dependencies + ,("Resolve Int -> Int64", transformInt, [], [Prop.noInt]) + ,("Uniquify variable declarations, record declared types and resolve variable names", + uniquifyAndResolveVars, [Prop.noInt], namesDone) + + ,("Fold all constant expressions", constantFoldPass, [Prop.noInt] ++ namesDone, [Prop.constantsFolded]) + ,("Annotate integer literal types", annnotateIntLiteralTypes, [Prop.noInt] ++ namesDone, [Prop.intLiteralsInBounds]) - ,("Fold all constant expressions",constantFoldPass) -- depends on transformInt and possibly depends on uniquifyAndResolveVars, not sure - ,("Annotate integer literal types",annnotateIntLiteralTypes) --depends on transformInt and constantFoldPass + ,("Record inferred name types in dictionary", recordInfNameTypes, namesDone ++ [Prop.intLiteralsInBounds], [Prop.inferredTypesRecorded]) - ,("Record inferred name types in dictionary",recordInfNameTypes) --depends on uniquifyAndResolveVars and annnotateIntLiteralTypes + ,("Check types in expressions",checkExpressionTypes, namesDone ++ [Prop.noInt, Prop.constantsFolded, Prop.intLiteralsInBounds, Prop.inferredTypesRecorded], [Prop.expressionTypesChecked]) + ,("Check types in assignments", checkAssignmentTypes, typesDone ++ [Prop.expressionTypesChecked], [Prop.processTypesChecked]) + ,("Check types in if/while conditions",checkConditionalTypes, typesDone ++ [Prop.expressionTypesChecked], [Prop.processTypesChecked]) + ,("Check types in input/output",checkCommTypes, typesDone ++ [Prop.expressionTypesChecked], [Prop.processTypesChecked]) + ,("Check types in now statements",checkGetTimeTypes, typesDone, [Prop.processTypesChecked]) + ,("Check parameters in process calls", matchParamPass, typesDone, [Prop.processTypesChecked]) - ,("Check types in expressions",checkExpressionTypes) - --depends on transformInt, uniquifyAndResolveVars, constantFoldPass, annnotateIntLiteralTypes, recordInfNameTypes - ,("Check types in assignments",checkAssignmentTypes) --depends on uniquifyAndResolveVars, recordInfNameTypes, checkExpressionTypes - ,("Check types in if/while conditions",checkConditionalTypes) --depends on uniquifyAndResolveVars, recordInfNameTypes, checkExpressionTypes - ,("Check types in input/output",checkCommTypes) --depends on uniquifyAndResolveVars, recordInfNameTypes, checkExpressionTypes - ,("Check types in now statements",checkGetTimeTypes) --depends on uniquifyAndResolveVars, recordInfNameTypes - - ,("Find and tag the main function",findMain) --depends on uniquifyAndResolveVars - ,("Check parameters in process calls",matchParamPass) --depends on uniquifyAndResolveVars and recordInfNameTypes and checkExpressionTypes - ,("Convert seqeach/pareach loops over ranges into simple replicated SEQ/PAR",transformEachRange) - --depends on uniquifyAndResolveVars and recordInfNameTypes - ,("Convert seqeach/pareach loops into classic replicated SEQ/PAR",transformEach) - --depends on uniquifyAndResolveVars and recordInfNameTypes, and should be done after transformEachRange - ,("Convert simple Rain range constructors into more general array constructors",transformRangeRep) - --must be done after transformEachRange - ,("Transform Rain functions into the occam form",transformFunction) - --must be done after transformEach, depends on uniquifyAndResolveVars and recordInfNameTypes - ,("Pull up par declarations", pullUpParDeclarations) --doesn't depend on anything - ,("AST Validity check, Rain #2", (\x -> excludeNonRainFeatures x >>= excludeTransformedRainFeatures)) + ,("Find and tag the main function", findMain, namesDone, [Prop.mainTagged]) + ,("Convert seqeach/pareach loops over ranges into simple replicated SEQ/PAR",transformEachRange, typesDone, [Prop.eachRangeTransformed]) + ,("Convert seqeach/pareach loops into classic replicated SEQ/PAR",transformEach, typesDone ++ [Prop.eachRangeTransformed], [Prop.eachTransformed]) + ,("Convert simple Rain range constructors into more general array constructors",transformRangeRep, typesDone ++ [Prop.eachRangeTransformed], [Prop.rangeTransformed]) + ,("Transform Rain functions into the occam form",transformFunction, typesDone ++ [Prop.eachTransformed], []) -- TODO need to sort out functions anyway + ,("Pull up par declarations", pullUpParDeclarations, [], [Prop.rainParDeclarationsPulledUp]) ] + where + namesDone :: [Property] + namesDone = [Prop.declaredNamesResolved, Prop.declarationTypesRecorded, Prop.declarationsUnique] + + typesDone :: [Property] + typesDone = namesDone ++ [Prop.inferredTypesRecorded] + -- | A pass that transforms all instances of 'A.Int' into 'A.Int64' transformInt :: Data t => t -> PassM t @@ -282,15 +286,6 @@ pullUpParDeclarations = everywhereM (mkM pullUpParDeclarations') Just (trans,inner') -> Just ( (A.Spec m spec) . trans,inner') chaseSpecs _ = Nothing --- | All the items that should have been removed at the end of the Rain passes. -excludeTransformedRainFeatures :: (Data t, CSMR m) => t -> m t -excludeTransformedRainFeatures = excludeConstr - [ con0 A.Int - ,con0 A.Any - ,con3 A.RangeConstr - ,con3 A.ForEach - ] - -- | All the items that should not occur in an AST that comes from Rain (up until it goes into the shared passes). excludeNonRainFeatures :: (Data t, CSMR m) => t -> m t excludeNonRainFeatures = excludeConstr diff --git a/transformations/SimplifyComms.hs b/transformations/SimplifyComms.hs index 980c7cf..d63b1a6 100644 --- a/transformations/SimplifyComms.hs +++ b/transformations/SimplifyComms.hs @@ -27,13 +27,14 @@ import qualified AST as A import CompState import Metadata import Pass +import qualified Properties as Prop import Types import Utils simplifyComms :: [Pass] -simplifyComms = makePasses - [ ("Define temporary variables for outputting expressions", outExprs) - ,("Transform ? CASE statements/guards into plain CASE", transformInputCase) +simplifyComms = makePassesDep + [ ("Define temporary variables for outputting expressions", outExprs, Prop.agg_namesDone ++ Prop.agg_typesDone, [Prop.outExpressionRemoved]) + ,("Transform ? CASE statements/guards into plain CASE", transformInputCase, Prop.agg_namesDone ++ Prop.agg_typesDone, [Prop.inputCaseRemoved]) ] outExprs :: Data t => t -> PassM t diff --git a/transformations/SimplifyExprs.hs b/transformations/SimplifyExprs.hs index 0ed2bb4..4319492 100644 --- a/transformations/SimplifyExprs.hs +++ b/transformations/SimplifyExprs.hs @@ -28,15 +28,16 @@ import CompState import Errors import Metadata import Pass +import qualified Properties as Prop import Types simplifyExprs :: [Pass] -simplifyExprs = makePasses - [ ("Convert FUNCTIONs to PROCs", functionsToProcs) - , ("Convert AFTER to MINUS", removeAfter) - , ("Expand array literals", expandArrayLiterals) - , ("Pull up definitions", pullUp) - , ("Transform array constructors into initialisation code", transformConstr) +simplifyExprs = makePassesDep + [ ("Convert FUNCTIONs to PROCs", functionsToProcs, Prop.agg_namesDone ++ [Prop.parUsageChecked], [Prop.functionsRemoved]) + , ("Convert AFTER to MINUS", removeAfter, [Prop.expressionTypesChecked], [Prop.afterRemoved]) + , ("Expand array literals", expandArrayLiterals, [Prop.expressionTypesChecked, Prop.processTypesChecked], [Prop.arrayLiteralsExpanded]) + , ("Pull up definitions", pullUp, Prop.agg_namesDone ++ [Prop.expressionTypesChecked, Prop.functionsRemoved, Prop.processTypesChecked], [Prop.functionCallsRemoved, Prop.subscriptsPulledUp]) + , ("Transform array constructors into initialisation code", transformConstr, Prop.agg_namesDone ++ Prop.agg_typesDone, []) ] -- | Convert FUNCTION declarations to PROCs. diff --git a/transformations/SimplifyProcs.hs b/transformations/SimplifyProcs.hs index f3d3c53..2eb76ad 100644 --- a/transformations/SimplifyProcs.hs +++ b/transformations/SimplifyProcs.hs @@ -25,14 +25,15 @@ import Data.Generics import qualified AST as A import CompState import Metadata -import Types import Pass +import qualified Properties as Prop +import Types simplifyProcs :: [Pass] -simplifyProcs = makePasses - [ ("Wrap PAR subprocesses in PROCs", parsToProcs) - , ("Remove parallel assignment", removeParAssign) - , ("Flatten assignment", flattenAssign) +simplifyProcs = makePassesDep + [ ("Wrap PAR subprocesses in PROCs", parsToProcs, [Prop.parUsageChecked], [Prop.parsWrapped]) + , ("Remove parallel assignment", removeParAssign, [Prop.parUsageChecked], [Prop.assignParRemoved]) + , ("Flatten assignment", flattenAssign, [Prop.assignParRemoved], [Prop.assignFlattened]) ] -- | Wrap the subprocesses of PARs in no-arg PROCs. diff --git a/transformations/SimplifyTypes.hs b/transformations/SimplifyTypes.hs index eeb06da..9716efe 100644 --- a/transformations/SimplifyTypes.hs +++ b/transformations/SimplifyTypes.hs @@ -25,12 +25,13 @@ import Data.Generics import qualified AST as A import Metadata import Pass +import qualified Properties as Prop import Types simplifyTypes :: [Pass] -simplifyTypes = makePasses - [ ("Resolve types in AST", resolveNamedTypes) - , ("Resolve types in state", rntState) +simplifyTypes = makePassesDep + [ ("Resolve types in AST", resolveNamedTypes, Prop.agg_namesDone, [Prop.typesResolvedInAST]) + , ("Resolve types in state", rntState, Prop.agg_namesDone, [Prop.typesResolvedInState]) ] -- | Turn named data types into their underlying types. diff --git a/transformations/Unnest.hs b/transformations/Unnest.hs index 4dd071a..98f937d 100644 --- a/transformations/Unnest.hs +++ b/transformations/Unnest.hs @@ -30,12 +30,13 @@ import Errors import EvalConstants import Metadata import Pass +import qualified Properties as Prop import Types unnest :: [Pass] -unnest = makePasses - [ ("Convert free names to arguments", removeFreeNames) - , ("Pull nested definitions to top level", removeNesting) +unnest = makePassesDep + [ ("Convert free names to arguments", removeFreeNames, [Prop.mainTagged, Prop.parsWrapped], [Prop.freeNamesToArgs]) + , ("Pull nested definitions to top level", removeNesting, [Prop.freeNamesToArgs], [Prop.nestedPulled]) ] type NameMap = Map.Map String A.Name