-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | An optimising compiler for a functional, array-oriented language. -- -- Futhark is a small programming language designed to be compiled to -- efficient parallel code. It is a statically typed, data-parallel, and -- purely functional array language in the ML family, and comes with a -- heavily optimising ahead-of-time compiler that presently generates GPU -- code via CUDA and OpenCL, although the language itself is -- hardware-agnostic. -- -- For more information, see the website at -- https://futhark-lang.org -- -- For introductionary information about hacking on the Futhark compiler, -- see the hacking guide. Regarding the internal design of the -- compiler, the following modules make good starting points: -- -- -- @package futhark @version 0.18.2 -- | This module defines a generator for getopt_long based command -- line argument parsing. Each option is associated with arbitrary C code -- that will perform side effects, usually by setting some global -- variables. module Futhark.CodeGen.Backends.GenericC.Options -- | Specification if a single command line option. The option must have a -- long name, and may also have a short name. -- -- In the action, the option argument (if any) is stored as in the -- char*-typed variable optarg. data Option Option :: String -> Maybe Char -> OptionArgument -> String -> Stm -> Option [optionLongName] :: Option -> String [optionShortName] :: Option -> Maybe Char [optionArgument] :: Option -> OptionArgument [optionDescription] :: Option -> String [optionAction] :: Option -> Stm -- | Whether an option accepts an argument. data OptionArgument NoArgument :: OptionArgument -- | The String becomes part of the help text. RequiredArgument :: String -> OptionArgument OptionalArgument :: OptionArgument -- | Generate an option parser as a function of the given name, that -- accepts the given command line options. The result is a function that -- should be called with argc and argv. The function -- returns the number of argv elements that have been processed. -- -- If option parsing fails for any reason, the entire process will -- terminate with error code 1. generateOptionParser :: String -> [Option] -> Func module Futhark.CodeGen.Backends.GenericPython.Definitions pyFunctions :: String pyUtility :: String pyValues :: String pyPanic :: String pyTuning :: String -- | Types (and a few other simple definitions) for futhark-pkg. module Futhark.Pkg.Types -- | A package path is a unique identifier for a package, for example -- github.comuserfoo. type PkgPath = Text -- | Turn a package path (which always uses forward slashes) into a file -- path in the local file system (which might use different slashes). pkgPathFilePath :: PkgPath -> FilePath -- | The dependencies of a (revision of a) package is a mapping from -- package paths to minimum versions (and an optional hash pinning). newtype PkgRevDeps PkgRevDeps :: Map PkgPath (SemVer, Maybe Text) -> PkgRevDeps -- | Convert a SemVer back to its textual representation. prettySemVer :: SemVer -> Text -- | An (Ideal) version number that conforms to Semantic Versioning. This -- is a prescriptive parser, meaning it follows the SemVer -- standard. -- -- Legal semvers are of the form: MAJOR.MINOR.PATCH-PREREL+META -- -- Example: 1.2.3-r1+commithash -- -- Extra Rules: -- --
    --
  1. Pre-release versions have lower precedence than normal -- versions.
  2. --
  3. Build metadata does not affect version precedence.
  4. --
  5. PREREL and META strings may only contain ASCII alphanumerics.
  6. --
-- -- For more information, see http://semver.org data SemVer SemVer :: !Word -> !Word -> !Word -> ![VChunk] -> ![VChunk] -> SemVer [_svMajor] :: SemVer -> !Word [_svMinor] :: SemVer -> !Word [_svPatch] :: SemVer -> !Word [_svPreRel] :: SemVer -> ![VChunk] [_svMeta] :: SemVer -> ![VChunk] -- | A single unit of a Version. May be digits or a string of characters. -- Groups of these are called VChunks, and are the identifiers -- separated by periods in the source. data VUnit Digits :: Word -> VUnit Str :: Text -> VUnit -- | commitVersion timestamp commit constructs a commit version. commitVersion :: Text -> Text -> SemVer -- | Versions of the form (0,0,0)-timestamp+hash are treated specially, as -- a reference to the commit identified uniquely with hash -- (typically the Git commit ID). This function detects such versions. isCommitVersion :: SemVer -> Maybe Text -- | Unfortunately, Data.Versions has a buggy semver parser that collapses -- consecutive zeroes in the metadata field. So, we define our own parser -- here. It's a little simpler too, since we don't need full semver. parseVersion :: Text -> Either (ParseErrorBundle Text Void) SemVer -- | A structure corresponding to a futhark.pkg file, including -- comments. It is an invariant that duplicate required packages do not -- occcur (the parser will verify this). data PkgManifest PkgManifest :: Commented (Maybe PkgPath) -> Commented [Either Comment Required] -> [Comment] -> PkgManifest -- | The name of the package. [manifestPkgPath] :: PkgManifest -> Commented (Maybe PkgPath) [manifestRequire] :: PkgManifest -> Commented [Either Comment Required] [manifestEndComments] :: PkgManifest -> [Comment] -- | Possibly given a package path, construct an otherwise-empty manifest -- file. newPkgManifest :: Maybe PkgPath -> PkgManifest -- | The required packages listed in a package manifest. pkgRevDeps :: PkgManifest -> PkgRevDeps -- | Where in the corresponding repository archive we can expect to find -- the package files. pkgDir :: PkgManifest -> Maybe FilePath -- | Add new required package to the package manifest. If the package was -- already present, return the old version. addRequiredToManifest :: Required -> PkgManifest -> (PkgManifest, Maybe Required) -- | Remove a required package from the manifest. Returns Nothing if -- the package was not found in the manifest, and otherwise the new -- manifest and the Required that was present. removeRequiredFromManifest :: PkgPath -> PkgManifest -> Maybe (PkgManifest, Required) -- | Prettyprint a package manifest such that it can be written to a -- futhark.pkg file. prettyPkgManifest :: PkgManifest -> Text -- | A line comment. type Comment = Text -- | Wraps a value with an annotation of preceding line comments. This is -- important to our goal of being able to programmatically modify the -- futhark.pkg file while keeping comments intact. data Commented a Commented :: [Comment] -> a -> Commented a [comments] :: Commented a -> [Comment] [commented] :: Commented a -> a -- | An entry in the required section of a futhark.pkg -- file. data Required Required :: PkgPath -> SemVer -> Maybe Text -> Required -- | Name of the required package. [requiredPkg] :: Required -> PkgPath -- | The minimum revision. [requiredPkgRev] :: Required -> SemVer -- | An optional hash indicating what this revision looked like the last -- time we saw it. Used for integrity checking. [requiredHash] :: Required -> Maybe Text -- | The name of the file containing the futhark-pkg manifest. futharkPkg :: FilePath -- | Parse a text as a PkgManifest. The FilePath is used for -- any error messages. parsePkgManifest :: FilePath -> Text -> Either (ParseErrorBundle Text Void) PkgManifest -- | Read contents of file and pass it to parsePkgManifest. parsePkgManifestFromFile :: FilePath -> IO PkgManifest -- | Pretty-print a ParseErrorBundle. All ParseErrors in the -- bundle will be pretty-printed in order together with the corresponding -- offending lines by doing a single efficient pass over the input -- stream. The rendered String always ends with a newline. errorBundlePretty :: (VisualStream s, TraversableStream s, ShowErrorComponent e) => ParseErrorBundle s e -> String -- | A mapping from package paths to their chosen revisions. This is the -- result of the version solver. newtype BuildList BuildList :: Map PkgPath SemVer -> BuildList [unBuildList] :: BuildList -> Map PkgPath SemVer -- | Prettyprint a build list; one package per line and newline-terminated. prettyBuildList :: BuildList -> Text instance GHC.Show.Show Futhark.Pkg.Types.PkgRevDeps instance GHC.Classes.Eq a => GHC.Classes.Eq (Futhark.Pkg.Types.Commented a) instance GHC.Show.Show a => GHC.Show.Show (Futhark.Pkg.Types.Commented a) instance GHC.Classes.Eq Futhark.Pkg.Types.Required instance GHC.Show.Show Futhark.Pkg.Types.Required instance GHC.Classes.Eq Futhark.Pkg.Types.PkgManifest instance GHC.Show.Show Futhark.Pkg.Types.PkgManifest instance GHC.Show.Show Futhark.Pkg.Types.BuildList instance GHC.Classes.Eq Futhark.Pkg.Types.BuildList instance GHC.Base.Functor Futhark.Pkg.Types.Commented instance Data.Foldable.Foldable Futhark.Pkg.Types.Commented instance Data.Traversable.Traversable Futhark.Pkg.Types.Commented instance GHC.Base.Semigroup Futhark.Pkg.Types.PkgRevDeps instance GHC.Base.Monoid Futhark.Pkg.Types.PkgRevDeps -- | Non-Futhark-specific utilities. If you find yourself writing general -- functions on generic data structures, consider putting them here. -- -- Sometimes it is also preferable to copy a small function rather than -- introducing a large dependency. In this case, make sure to note where -- you got it from (and make sure that the license is compatible). module Futhark.Util -- | Like nub, but without the quadratic runtime. nubOrd :: Ord a => [a] -> [a] -- | Like mapAccumL, but monadic. mapAccumLM :: Monad m => (acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y]) -- | Like maximum, but returns zero for an empty list. maxinum :: (Num a, Ord a, Foldable f) => f a -> a -- | chunk n a splits a into n-size-chunks. If -- the length of a is not divisible by n, the last -- chunk will have fewer than n elements (but it will never be -- empty). chunk :: Int -> [a] -> [[a]] -- | chunks ns a splits a into chunks determined by the -- elements of ns. It must hold that sum ns == length -- a, or the resulting list may contain too few chunks, or not all -- elements of a. chunks :: [Int] -> [a] -> [[a]] -- | dropAt i n drops n elements starting at element -- i. dropAt :: Int -> Int -> [a] -> [a] -- | takeLast n l takes the last n elements of -- l. takeLast :: Int -> [a] -> [a] -- | dropLast n l drops the last n elements of -- l. dropLast :: Int -> [a] -> [a] -- | A combination of map and partitionEithers. mapEither :: (a -> Either b c) -> [a] -> ([b], [c]) -- | Return the list element at the given index, if the index is valid. maybeNth :: Integral int => int -> [a] -> Maybe a -- | Return the first element of the list, if it exists. maybeHead :: [a] -> Maybe a -- | Like splitAt, but from the end. splitFromEnd :: Int -> [a] -> ([a], [a]) -- | Like splitAt, but produces three lists. splitAt3 :: Int -> Int -> [a] -> ([a], [a], [a]) -- | Return the list element at the given index, if the index is valid, -- along with the elements before and after. focusNth :: Integral int => int -> [a] -> Maybe ([a], a, [a]) -- | The Unix environment when the Futhark compiler started. unixEnvironment :: [(String, String)] -- | Is an environment variable set to 0 or 1? If 0, return False; if 1, -- True; otherwise the default value. isEnvVarSet :: String -> Bool -> Bool -- | Are we running in a terminal capable of fancy commands and -- visualisation? fancyTerminal :: Bool -- | Like readProcessWithExitCode, but also wraps exceptions when -- the indicated binary cannot be launched, or some other exception is -- thrown. Also does shenanigans to handle improperly encoded outputs. runProgramWithExitCode :: FilePath -> [String] -> ByteString -> IO (Either IOException (ExitCode, String, String)) -- | Every non-directory file contained in a directory tree. directoryContents :: FilePath -> IO [FilePath] -- | Round a single-precision floating point number correctly. roundFloat :: Float -> Float -- | Round a single-precision floating point number upwards correctly. ceilFloat :: Float -> Float -- | Round a single-precision floating point number downwards correctly. floorFloat :: Float -> Float -- | Round a double-precision floating point number correctly. roundDouble :: Double -> Double -- | Round a double-precision floating point number upwards correctly. ceilDouble :: Double -> Double -- | Round a double-precision floating point number downwards correctly. floorDouble :: Double -> Double -- | The system-level lgamma() function. lgamma :: Double -> Double -- | The system-level lgammaf() function. lgammaf :: Float -> Float -- | The system-level tgamma() function. tgamma :: Double -> Double -- | The system-level tgammaf() function. tgammaf :: Float -> Float -- | Some bad operating systems do not use forward slash as directory -- separator - this is where we convert Futhark includes (which always -- use forward slash) to native paths. fromPOSIX :: FilePath -> FilePath -- | Turn a POSIX filepath into a filepath for the native system. toPOSIX :: FilePath -> FilePath -- | Remove leading and trailing whitespace from a string. Not an efficient -- implementation! trim :: String -> String -- | Run various IO actions concurrently, possibly with a bound on -- the number of threads. The list must be finite. The ordering of the -- result list is not deterministic - add your own sorting if needed. If -- any of the actions throw an exception, then that exception is -- propagated to this function. pmapIO :: Maybe Int -> (a -> IO b) -> [a] -> IO [b] -- | As the user typed it. type UserString = String -- | Encoded form. type EncodedString = String -- | Z-encode a string using a slightly simplified variant of GHC -- Z-encoding. The encoded string is a valid identifier in most -- programming languages. zEncodeString :: UserString -> EncodedString -- | A rearrangement is a generalisation of transposition, where the -- dimensions are arbitrarily permuted. module Futhark.IR.Prop.Rearrange -- | Calculate the given permutation of the list. It is an error if the -- permutation goes out of bounds. rearrangeShape :: [Int] -> [a] -> [a] -- | Produce the inverse permutation. rearrangeInverse :: [Int] -> [Int] -- | Return the first dimension not affected by the permutation. For -- example, the permutation [1,0,2] would return 2. rearrangeReach :: [Int] -> Int -- | Compose two permutations, with the second given permutation being -- applied first. rearrangeCompose :: [Int] -> [Int] -> [Int] -- | Check whether the first list is a permutation of the second, and if -- so, return the permutation. This will also find identity permutations -- (i.e. the lists are the same) The implementation is naive and slow. isPermutationOf :: Eq a => [a] -> [a] -> Maybe [Int] -- | If l is an index into the array a, then -- transposeIndex k n l is an index to the same element in the -- array transposeArray k n a. transposeIndex :: Int -> Int -> [a] -> [a] -- | If perm is conceptually a map of a transposition, -- isMapTranspose perm returns the number of dimensions being -- mapped and the number dimension being transposed. For example, we can -- consider the permutation [0,1,4,5,2,3] as a map of a -- transpose, by considering dimensions [0,1], [4,5], -- and [2,3] as single dimensions each. -- -- If the input is not a valid permutation, then the result is undefined. isMapTranspose :: [Int] -> Maybe (Int, Int, Int) -- | Some utility functions for working with pretty console output. module Futhark.Util.Console -- | Surround the given string with the given start/end colour codes. color :: [SGR] -> String -> String -- | Make the string red. inRed :: String -> String -- | Make the string green. inGreen :: String -> String -- | Make the string bold. inBold :: String -> String -- | It is occasionally useful to define generic functions that can not -- only compute their result as an integer, but also as a symbolic -- expression in the form of an AST. -- -- There are some Haskell hacks for this - it is for example not hard to -- define an instance of Num that constructs an AST. However, this -- falls down for some other interesting classes, like Integral, -- which requires both the problematic method fromInteger, and -- also that the type is an instance of Enum. -- -- We can always just define hobbled instances that call error for -- those methods that are impractical, but this is ugly. -- -- Hence, this module defines similes to standard Haskell numeric -- typeclasses that have been modified to make generic functions slightly -- easier to write. module Futhark.Util.IntegralExp -- | A twist on the Integral type class that is more friendly to -- symbolic representations. class Num e => IntegralExp e quot :: IntegralExp e => e -> e -> e rem :: IntegralExp e => e -> e -> e div :: IntegralExp e => e -> e -> e mod :: IntegralExp e => e -> e -> e sgn :: IntegralExp e => e -> Maybe Int -- | Like div, but rounds towards positive infinity. divUp :: IntegralExp e => e -> e -> e -- | This wrapper allows you to use a type that is an instance of the true -- class whenever the simile class is required. newtype Wrapped a Wrapped :: a -> Wrapped a [wrappedValue] :: Wrapped a -> a instance GHC.Show.Show a => GHC.Show.Show (Futhark.Util.IntegralExp.Wrapped a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Futhark.Util.IntegralExp.Wrapped a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Futhark.Util.IntegralExp.Wrapped a) instance GHC.Num.Num a => GHC.Num.Num (Futhark.Util.IntegralExp.Wrapped a) instance GHC.Real.Integral a => Futhark.Util.IntegralExp.IntegralExp (Futhark.Util.IntegralExp.Wrapped a) -- | A Safe Haskell-trusted re-export of the srcloc package. module Futhark.Util.Loc -- | Opaque type for an operations log that provides fast O(1) appends. module Futhark.Util.Log -- | An efficiently catenable sequence of log entries. data Log -- | Transform a log into text. Every log entry becomes its own line (or -- possibly more, in case of multi-line entries). toText :: Log -> Text -- | Typeclass for things that can be turned into a single-entry log. class ToLog a toLog :: ToLog a => a -> Log -- | Typeclass for monads that support logging. class (Applicative m, Monad m) => MonadLogger m -- | Add one log entry. logMsg :: (MonadLogger m, ToLog a) => a -> m () -- | Append an entire log. addLog :: MonadLogger m => Log -> m () instance (GHC.Base.Applicative m, GHC.Base.Monad m) => Futhark.Util.Log.MonadLogger (Control.Monad.Trans.Writer.Lazy.WriterT Futhark.Util.Log.Log m) instance (GHC.Base.Applicative m, GHC.Base.Monad m) => Futhark.Util.Log.MonadLogger (Control.Monad.Trans.RWS.Lazy.RWST r Futhark.Util.Log.Log s m) instance (GHC.Base.Applicative m, GHC.Base.Monad m) => Futhark.Util.Log.MonadLogger (Control.Monad.Trans.RWS.Strict.RWST r Futhark.Util.Log.Log s m) instance Futhark.Util.Log.ToLog GHC.Base.String instance Futhark.Util.Log.ToLog Data.Text.Internal.Text instance GHC.Base.Semigroup Futhark.Util.Log.Log instance GHC.Base.Monoid Futhark.Util.Log.Log -- | Obtaining information about packages over THE INTERNET! module Futhark.Pkg.Info -- | Information about a package. The name of the package is stored -- separately. data PkgInfo m PkgInfo :: Map SemVer (PkgRevInfo m) -> (Maybe Text -> m (PkgRevInfo m)) -> PkgInfo m [pkgVersions] :: PkgInfo m -> Map SemVer (PkgRevInfo m) -- | Look up information about a specific commit, or HEAD in case of -- Nothing. [pkgLookupCommit] :: PkgInfo m -> Maybe Text -> m (PkgRevInfo m) -- | Lookup information about a given version of a package. lookupPkgRev :: SemVer -> PkgInfo m -> Maybe (PkgRevInfo m) -- | Retrieve information about a package based on its package path. This -- uses Semantic Import Versioning when interacting with repositories. -- For example, a package github.comuserrepo will match -- version 0.* or 1.* tags only, a package -- github.comuserrepo/v2 will match 2.* tags, and so -- forth.. pkgInfo :: (MonadIO m, MonadLogger m, MonadFail m) => PkgPath -> m (Either Text (PkgInfo m)) -- | Information about a version of a single package. The version number is -- stored separately. data PkgRevInfo m PkgRevInfo :: Text -> FilePath -> Text -> GetManifest m -> UTCTime -> PkgRevInfo m [pkgRevZipballUrl] :: PkgRevInfo m -> Text -- | The directory inside the zipball containing the lib -- directory, in which the package files themselves are stored (Based on -- the package path). [pkgRevZipballDir] :: PkgRevInfo m -> FilePath -- | The commit ID can be used for verification ("freezing"), by storing -- what it was at the time this version was last selected. [pkgRevCommit] :: PkgRevInfo m -> Text [pkgRevGetManifest] :: PkgRevInfo m -> GetManifest m -- | Timestamp for when the revision was made (rarely used). [pkgRevTime] :: PkgRevInfo m -> UTCTime -- | The manifest is stored as a monadic action, because we want to fetch -- them on-demand. It would be a waste to fetch it information for every -- version of every package if we only actually need a small subset of -- them. data GetManifest m -- | Download the zip archive corresponding to a specific package version. downloadZipball :: (MonadLogger m, MonadIO m, MonadFail m) => PkgRevInfo m -> m Archive -- | A package registry is a mapping from package paths to information -- about the package. It is unlikely that any given registry is global; -- rather small registries are constructed on-demand based on the package -- paths referenced by the user, and may also be combined monoidically. -- In essence, the PkgRegistry is just a cache. data PkgRegistry m -- | Monads that support a stateful package registry. These are also -- required to be instances of MonadIO because most package -- registry operations involve network operations. class (MonadIO m, MonadLogger m, MonadFail m) => MonadPkgRegistry m getPkgRegistry :: MonadPkgRegistry m => m (PkgRegistry m) putPkgRegistry :: MonadPkgRegistry m => PkgRegistry m -> m () modifyPkgRegistry :: MonadPkgRegistry m => (PkgRegistry m -> PkgRegistry m) -> m () -- | Given a package path, look up information about that package. lookupPackage :: MonadPkgRegistry m => PkgPath -> m (PkgInfo m) -- | Look up information about a specific version of a package. lookupPackageRev :: MonadPkgRegistry m => PkgPath -> SemVer -> m (PkgRevInfo m) -- | Find the newest version of a package. lookupNewestRev :: MonadPkgRegistry m => PkgPath -> m SemVer instance GHC.Show.Show (Futhark.Pkg.Info.PkgRevInfo m) instance GHC.Classes.Eq (Futhark.Pkg.Info.PkgRevInfo m) instance GHC.Base.Semigroup (Futhark.Pkg.Info.PkgRegistry m) instance GHC.Base.Monoid (Futhark.Pkg.Info.PkgRegistry m) instance GHC.Show.Show (Futhark.Pkg.Info.GetManifest m) instance GHC.Classes.Eq (Futhark.Pkg.Info.GetManifest m) -- | Dependency solver -- -- This is a relatively simple problem due to the choice of the Minimum -- Package Version algorithm. In fact, the only failure mode is -- referencing an unknown package or revision. module Futhark.Pkg.Solve -- | Run the solver, producing both a package registry containing a cache -- of the lookups performed, as well as a build list. solveDeps :: MonadPkgRegistry m => PkgRevDeps -> m BuildList -- | Perform package resolution with only pre-known information. This is -- useful for testing. solveDepsPure :: PkgRevDepInfo -> PkgRevDeps -> Either Text BuildList -- | A mapping of package revisions to the dependencies of that package. -- Can be considered a PkgRegistry without the option of obtaining -- more information from the Internet. Probably useful only for testing -- the solver. type PkgRevDepInfo = Map (PkgPath, SemVer) PkgRevDeps instance GHC.Show.Show Futhark.Pkg.Solve.RoughBuildList instance GHC.Base.Functor Futhark.Pkg.Solve.PkgOp -- | A re-export of the prettyprinting library, along with some convenience -- functions. module Futhark.Util.Pretty -- | Render a document with a width of 80 and print it to the specified -- handle, followed by a newline. hPutDocLn :: Handle -> Doc -> IO () -- | Render a document with a width of 80 and print it to the specified -- handle. hPutDoc :: Handle -> Doc -> IO () -- | Render a document with a width of 80 and print it to standard output, -- followed by a newline. putDocLn :: Doc -> IO () -- | Render a document with a width of 80 and print it to standard output. putDoc :: Doc -> IO () -- | Render and convert a document to Text with #line pragmas. Uses -- a builder. prettyPragmaLazyText :: Int -> Doc -> Text -- | Display a rendered document with #line pragmas as Text. Uses a -- builder. displayPragmaLazyText :: RDoc -> Text -- | Render and display a document as Text. Uses a builder. prettyLazyText :: Int -> Doc -> Text -- | Display a rendered document as Text. Uses a builder. displayLazyText :: RDoc -> Text -- | Render and convert a document to a String with #line pragmas. -- --
--   > let loc = Loc (Pos "filename" 3 5 7) (Pos "filename" 5 7 9)
--   > in  putStrLn $ prettyPragma 80 $ srcloc loc <> text "foo" </> text "bar" </> text "baz"
--   
-- -- will be printed as -- --
--   foo
--   #line 3 "filename"
--   bar
--   baz
--   
prettyPragma :: Int -> Doc -> String -- | Render and display a document with #line pragmas. prettyPragmaS :: Int -> Doc -> ShowS -- | Display a rendered document with #line pragmas. displayPragmaS :: RDoc -> ShowS -- | Render and convert a document to a String compactly. prettyCompact :: Doc -> String -- | Render and display a document compactly. prettyCompactS :: Doc -> ShowS -- | Render and display a document. prettyS :: Int -> Doc -> ShowS -- | Display a rendered document. displayS :: RDoc -> ShowS -- | Render a document without indentation on infinitely long lines. Since -- no 'pretty' printing is involved, this renderer is fast. The resulting -- output contains fewer characters. renderCompact :: Doc -> RDoc -- | Render a document given a maximum width. render :: Int -> Doc -> RDoc -- | Equivalent of error, but with a document instead of a string. errordoc :: Doc -> a -- | Equivalent of fail, but with a document instead of a string. faildoc :: MonadFail m => Doc -> m a -- | The document fillbreak i d renders document -- d, appending spaces until the width is equal -- to i. If the width of d is already greater than -- i, the nesting level is increased by i and a -- line is appended. fillbreak :: Int -> Doc -> Doc -- | The document fill i d renders document x, -- appending spaces until the width is equal to i. If -- the width of d is already greater than i, nothing is -- appended. fill :: Int -> Doc -> Doc -- | The document width d f is produced by concatenating -- d with the result of calling f with the width of the -- document d. width :: Doc -> (Int -> Doc) -> Doc -- | The document column f is produced by calling -- f with the current nesting level. nesting :: (Int -> Doc) -> Doc -- | The document column f is produced by calling -- f with the current column. column :: (Int -> Doc) -> Doc -- | The document nest i d renders the document d -- with the current indentation level increased by i. nest :: Int -> Doc -> Doc -- | The document indent i d renders d with a -- nesting level set to the current column plus i, -- including the first line. indent :: Int -> Doc -> Doc -- | The document hang i d renders d with a -- nesting level set to the current column plus i, not -- including the first line. hang :: Int -> Doc -> Doc -- | The document align d renders d with a nesting -- level set to the current column. align :: Doc -> Doc -- | The document list ds separates ds with commas -- and encloses them with brackets. list :: [Doc] -> Doc -- | The document tuple ds separates ds with -- commas and encloses them with parentheses. tuple :: [Doc] -> Doc -- | The document enclosesep l r p ds separates ds -- with the punctuation p and encloses the result using -- l and r. When wrapped, punctuation appears at the -- end of the line. The enclosed portion of the document is aligned one -- column to the right of the opening document. -- --
--   > ws = map text (words "The quick brown fox jumps over the lazy dog")
--   > test = pretty 15 (enclosesep lparen rparen comma ws)
--   
-- -- will be layed out as: -- --
--   (The, quick,
--    brown, fox,
--    jumps, over,
--    the, lazy,
--    dog)
--   
enclosesep :: Doc -> Doc -> Doc -> [Doc] -> Doc -- | The document semisep ds semicolon-space separates -- ds, aligning the resulting document to the current nesting -- level. semisep :: [Doc] -> Doc -- | The document commasep ds comma-space separates -- ds, aligning the resulting document to the current nesting -- level. commasep :: [Doc] -> Doc -- | The document punctuate p ds obeys the law: -- --
--   punctuate p [d1, d2, ..., dn] = [d1 <> p, d2 <> p, ..., dn]
--   
punctuate :: Doc -> [Doc] -> [Doc] -- | The document sep ds concatenates the documents -- ds with the space document as long as there is room, -- and uses line when there isn't. sep :: [Doc] -> Doc -- | The document cat ds concatenates the documents -- ds with the empty document as long as there is room, -- and uses line when there isn't. cat :: [Doc] -> Doc -- | The document stack ds concatenates the documents -- ds with line. stack :: [Doc] -> Doc -- | The document spread ds concatenates the documents -- ds with space. spread :: [Doc] -> Doc -- | The document folddoc f ds obeys the laws: -- -- folddoc :: (Doc -> Doc -> Doc) -> [Doc] -> Doc -- | The document parensIf p d encloses the document -- d in parenthesis if p is True, and -- otherwise yields just d. parensIf :: Bool -> Doc -> Doc -- | The document parens d encloses the aligned document -- d in (...). parens :: Doc -> Doc -- | The document brackets d encloses the aligned document -- d in [...]. brackets :: Doc -> Doc -- | The document braces d encloses the aligned document -- d in {...}. braces :: Doc -> Doc -- | The document backquotes d encloses the aligned -- document d in `...`. backquotes :: Doc -> Doc -- | The document angles d encloses the aligned document -- d in <...>. angles :: Doc -> Doc -- | The document dquotes d encloses the aligned document -- d in "...". dquotes :: Doc -> Doc -- | The document squotes d encloses the alinged document -- d in '...'. squotes :: Doc -> Doc -- | The document enclose l r d encloses the document -- d between the documents l and r using -- <>. It obeys the law -- --
--   enclose l r d = l <> d <> r
--   
enclose :: Doc -> Doc -> Doc -> Doc -- | The document flatten d will flatten d to -- one line. flatten :: Doc -> Doc -- | The document group d will flatten d to -- one line if there is room for it, otherwise the original -- d. group :: Doc -> Doc -- | Provide alternative layouts of the same content. Invariant: both -- arguments must flatten to the same document. (<|>) :: Doc -> Doc -> Doc infixl 3 <|> -- | Concatenates two documents with a softbreak in between. () :: Doc -> Doc -> Doc infixr 5 -- | Concatenates two documents with a softline in between, with -- identity empty. (<+/>) :: Doc -> Doc -> Doc infixr 5 <+/> -- | Concatenates two documents with a line in between, with -- identity empty. () :: Doc -> Doc -> Doc infixr 5 -- | Concatenates two documents with a space in between, with -- identity empty. (<+>) :: Doc -> Doc -> Doc infixr 6 <+> -- | Becomes empty if there is room, otherwise line. softbreak :: Doc -- | Becomes space if there is room, otherwise line. -- --
--   pretty 11 $ text "foo" <+/> text "bar" <+/> text "baz" =="foo bar baz"
--   pretty  7 $ text "foo" <+/> text "bar" <+/> text "baz" == "foo bar\nbaz"
--   pretty  6 $ text "foo" <+/> text "bar" <+/> text "baz" == "foo\nbar\nbaz"
--   
softline :: Doc -- | The document line advances to the next line and -- indents to the current indentation level. When undone by group, -- it behaves like space. line :: Doc -- | The document srcloc x tags the current line with -- locOf x. Only shown when running prettyPragma -- and friends. srcloc :: Located a => a -> Doc -- | The empty document. empty :: Doc -- | The document rparen consists of a right brace, ")". rparen :: Doc -- | The document lparen consists of a right brace, "(". lparen :: Doc -- | The document rbracket consists of a right brace, -- "]". rbracket :: Doc -- | The document lbracket consists of a right brace, -- "[". lbracket :: Doc -- | The document rbrace consists of a right brace, "}". rbrace :: Doc -- | The document lbrace consists of a left brace, "{". lbrace :: Doc -- | The document rangle consists of a greater-than sign, -- ">". rangle :: Doc -- | The document langle consists of a less-than sign, -- "<". langle :: Doc -- | The document dquote consists of a double quote, -- "\"". dquote :: Doc -- | The document squote consists of a single quote, -- "\'". squote :: Doc -- | The document backquote consists of a backquote, "`". backquote :: Doc -- | The document space n consists of n spaces. spaces :: Int -> Doc -- | The document space consists of a space, " ". space :: Doc -- | The document semi consists of a semicolon, ";". semi :: Doc -- | The document equals consists of an equals sign, "=". equals :: Doc -- | The document dot consists of a period, ".". dot :: Doc -- | The document comma consists of a comma, ",". comma :: Doc -- | The document colon consists of a colon, ":". colon :: Doc -- | The document star consists of an asterisk, "*". star :: Doc -- | The document lazyText s consists of the Text -- s, which should not contain any newlines. lazyText :: Text -> Doc -- | The document strictText s consists of the Text -- s, which should not contain any newlines. strictText :: Text -> Doc -- | The document rational r is equivalent to text (show -- r). rational :: Rational -> Doc -- | The document double d is equivalent to text (show -- d). double :: Double -> Doc -- | The document float f is equivalent to text (show f). float :: Float -> Doc -- | The document integer i is equivalent to text (show -- i). text. integer :: Integer -> Doc -- | The document int i is equivalent to text (show i). int :: Int -> Doc -- | The document string s consists of all the characters -- in s but with newlines replaced by line. string :: String -> Doc -- | The document char c consists the single character -- c. char :: Char -> Doc -- | The document bool b is equivalent to text (show b). bool :: Bool -> Doc -- | The document text s consists of the string s, -- which should not contain any newlines. For a string that may include -- newlines, use string. text :: String -> Doc -- | The abstract type of documents. data Doc -- | A rendered document. data RDoc -- | The empty document REmpty :: RDoc -- | A single character RChar :: {-# UNPACK #-} !Char -> RDoc -> RDoc -- | String with associated length (to avoid recomputation) RString :: {-# UNPACK #-} !Int -> String -> RDoc -> RDoc -- | Text RText :: Text -> RDoc -> RDoc -- | Text RLazyText :: Text -> RDoc -> RDoc -- | Tag output with source location RPos :: Pos -> RDoc -> RDoc -- | A newline with the indentation of the subsequent line. If this is -- followed by a RPos, output an appropriate #line pragma -- before the newline. RLine :: {-# UNPACK #-} !Int -> RDoc -> RDoc -- | Prettyprint a value, wrapped to 80 characters. pretty :: Pretty a => a -> String -- | Re-export of pretty. prettyDoc :: Int -> Doc -> String -- | Prettyprint a list enclosed in curly braces. prettyTuple :: Pretty a => [a] -> String -- | Prettyprint a value to a Text, wrapped to 80 characters. prettyText :: Pretty a => a -> Text -- | Prettyprint a value without any width restriction. prettyOneLine :: Pretty a => a -> String -- | The document apply ds separates ds with -- commas and encloses them with parentheses. apply :: [Doc] -> Doc -- | Make sure that the given document is printed on just a single line. oneLine :: Doc -> Doc -- | Stack and prepend a list of Docs to another Doc, -- separated by a linebreak. If the list is empty, the second Doc -- will be returned without a preceding linebreak. annot :: [Doc] -> Doc -> Doc -- | Surround the given document with enclosers and add linebreaks and -- indents. nestedBlock :: String -> String -> Doc -> Doc -- | Like text, but splits the string into words and permits line -- breaks between all of them. textwrap :: String -> Doc -- | Prettyprint on a single line up to at most some appropriate number of -- characters, with trailing ... if necessary. Used for error messages. shorten :: Pretty a => a -> Doc -- | Definitions of primitive types, the values that inhabit these types, -- and operations on these values. A primitive value can also be called a -- scalar. -- -- Essentially, this module describes the subset of the (internal) -- Futhark language that operates on primitive types. module Futhark.IR.Primitive -- | An integer type, ordered by size. Note that signedness is not a -- property of the type, but a property of the operations performed on -- values of these types. data IntType Int8 :: IntType Int16 :: IntType Int32 :: IntType Int64 :: IntType -- | A list of all integer types. allIntTypes :: [IntType] -- | A floating point type. data FloatType Float32 :: FloatType Float64 :: FloatType -- | A list of all floating-point types. allFloatTypes :: [FloatType] -- | Low-level primitive types. data PrimType IntType :: IntType -> PrimType FloatType :: FloatType -> PrimType Bool :: PrimType Cert :: PrimType -- | A list of all primitive types. allPrimTypes :: [PrimType] -- | 8-bit signed integer type data Int8 -- | 16-bit signed integer type data Int16 -- | 32-bit signed integer type data Int32 -- | 64-bit signed integer type data Int64 -- | An integer value. data IntValue Int8Value :: !Int8 -> IntValue Int16Value :: !Int16 -> IntValue Int32Value :: !Int32 -> IntValue Int64Value :: !Int64 -> IntValue -- | Create an IntValue from a type and an Integer. intValue :: Integral int => IntType -> int -> IntValue -- | The type of an integer value. intValueType :: IntValue -> IntType -- | Convert an IntValue to any Integral type. valueIntegral :: Integral int => IntValue -> int -- | A floating-point value. data FloatValue Float32Value :: !Float -> FloatValue Float64Value :: !Double -> FloatValue -- | Create a FloatValue from a type and a Rational. floatValue :: Real num => FloatType -> num -> FloatValue -- | The type of a floating-point value. floatValueType :: FloatValue -> FloatType -- | Non-array values. data PrimValue IntValue :: !IntValue -> PrimValue FloatValue :: !FloatValue -> PrimValue BoolValue :: !Bool -> PrimValue -- | The only value of type cert. Checked :: PrimValue -- | The type of a basic value. primValueType :: PrimValue -> PrimType -- | A "blank" value of the given primitive type - this is zero, or -- whatever is close to it. Don't depend on this value, but use it for -- e.g. creating arrays to be populated by do-loops. blankPrimValue :: PrimType -> PrimValue -- | What to do in case of arithmetic overflow. Futhark's semantics are -- that overflow does wraparound, but for generated code (like address -- arithmetic), it can be beneficial for overflow to be undefined -- behaviour, as it allows better optimisation of things such as GPU -- kernels. -- -- Note that all values of this type are considered equal for Eq -- and Ord. data Overflow OverflowWrap :: Overflow OverflowUndef :: Overflow -- | Whether something is safe or unsafe (mostly function calls, and in the -- context of whether operations are dynamically checked). When we inline -- an Unsafe function, we remove all safety checks in its body. -- The Ord instance picks Unsafe as being less than -- Safe. -- -- For operations like integer division, a safe division will not explode -- the computer in case of division by zero, but instead return some -- unspecified value. This always involves a run-time check, so generally -- the unsafe variant is what the compiler will insert, but guarded by an -- explicit assertion elsewhere. Safe operations are useful when the -- optimiser wants to move e.g. a division to a location where the -- divisor may be zero, but where the result will only be used when it is -- non-zero (so it doesn't matter what result is provided with a zero -- divisor, as long as the program keeps running). data Safety Unsafe :: Safety Safe :: Safety -- | Various unary operators. It is a bit ad-hoc what is a unary operator -- and what is a built-in function. Perhaps these should all go away -- eventually. data UnOp -- | E.g., ! True == False. Not :: UnOp -- | E.g., ~(~1) = 1. Complement :: IntType -> UnOp -- | abs(-2) = 2. Abs :: IntType -> UnOp -- | fabs(-2.0) = 2.0. FAbs :: FloatType -> UnOp -- | Signed sign function: ssignum(-2) = -1. SSignum :: IntType -> UnOp -- | Unsigned sign function: usignum(2) = 1. USignum :: IntType -> UnOp -- | A list of all unary operators for all types. allUnOps :: [UnOp] -- | Binary operators. These correspond closely to the binary operators in -- LLVM. Most are parametrised by their expected input and output types. data BinOp -- | Integer addition. Add :: IntType -> Overflow -> BinOp -- | Floating-point addition. FAdd :: FloatType -> BinOp -- | Integer subtraction. Sub :: IntType -> Overflow -> BinOp -- | Floating-point subtraction. FSub :: FloatType -> BinOp -- | Integer multiplication. Mul :: IntType -> Overflow -> BinOp -- | Floating-point multiplication. FMul :: FloatType -> BinOp -- | Unsigned integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. UDiv :: IntType -> Safety -> BinOp -- | Unsigned integer division. Rounds towards positive infinity. UDivUp :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. SDiv :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards positive infinity. SDivUp :: IntType -> Safety -> BinOp -- | Floating-point division. FDiv :: FloatType -> BinOp -- | Floating-point modulus. FMod :: FloatType -> BinOp -- | Unsigned integer modulus; the countepart to UDiv. UMod :: IntType -> Safety -> BinOp -- | Signed integer modulus; the countepart to SDiv. SMod :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- sdiv instruction in LLVM and integer division in C. SQuot :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- srem instruction in LLVM and integer modulo in C. SRem :: IntType -> Safety -> BinOp -- | Returns the smallest of two signed integers. SMin :: IntType -> BinOp -- | Returns the smallest of two unsigned integers. UMin :: IntType -> BinOp -- | Returns the smallest of two floating-point numbers. FMin :: FloatType -> BinOp -- | Returns the greatest of two signed integers. SMax :: IntType -> BinOp -- | Returns the greatest of two unsigned integers. UMax :: IntType -> BinOp -- | Returns the greatest of two floating-point numbers. FMax :: FloatType -> BinOp -- | Left-shift. Shl :: IntType -> BinOp -- | Logical right-shift, zero-extended. LShr :: IntType -> BinOp -- | Arithmetic right-shift, sign-extended. AShr :: IntType -> BinOp -- | Bitwise and. And :: IntType -> BinOp -- | Bitwise or. Or :: IntType -> BinOp -- | Bitwise exclusive-or. Xor :: IntType -> BinOp -- | Integer exponentiation. Pow :: IntType -> BinOp -- | Floating-point exponentiation. FPow :: FloatType -> BinOp -- | Boolean and - not short-circuiting. LogAnd :: BinOp -- | Boolean or - not short-circuiting. LogOr :: BinOp -- | A list of all binary operators for all types. allBinOps :: [BinOp] -- | Conversion operators try to generalise the from t0 x to t1 -- instructions from LLVM. data ConvOp -- | Zero-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. ZExt :: IntType -> IntType -> ConvOp -- | Sign-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. SExt :: IntType -> IntType -> ConvOp -- | Convert value of the former floating-point type to the latter. If the -- new type is smaller, the result is a truncation. FPConv :: FloatType -> FloatType -> ConvOp -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). FPToUI :: FloatType -> IntType -> ConvOp -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). FPToSI :: FloatType -> IntType -> ConvOp -- | Convert an unsigned integer to a floating-point value. UIToFP :: IntType -> FloatType -> ConvOp -- | Convert a signed integer to a floating-point value. SIToFP :: IntType -> FloatType -> ConvOp -- | Convert an integer to a boolean value. Zero becomes false; anything -- else is true. IToB :: IntType -> ConvOp -- | Convert a boolean to an integer. True is converted to 1 and False to -- 0. BToI :: IntType -> ConvOp -- | A list of all conversion operators for all types. allConvOps :: [ConvOp] -- | Comparison operators are like BinOps, but they always return a -- boolean value. The somewhat ugly constructor names are straight out of -- LLVM. data CmpOp -- | All types equality. CmpEq :: PrimType -> CmpOp -- | Unsigned less than. CmpUlt :: IntType -> CmpOp -- | Unsigned less than or equal. CmpUle :: IntType -> CmpOp -- | Signed less than. CmpSlt :: IntType -> CmpOp -- | Signed less than or equal. CmpSle :: IntType -> CmpOp -- | Floating-point less than. FCmpLt :: FloatType -> CmpOp -- | Floating-point less than or equal. FCmpLe :: FloatType -> CmpOp -- | Boolean less than. CmpLlt :: CmpOp -- | Boolean less than or equal. CmpLle :: CmpOp -- | A list of all comparison operators for all types. allCmpOps :: [CmpOp] -- | Apply an UnOp to an operand. Returns Nothing if the -- application is mistyped. doUnOp :: UnOp -> PrimValue -> Maybe PrimValue -- | E.g., ~(~1) = 1. doComplement :: IntValue -> IntValue -- | abs(-2) = 2. doAbs :: IntValue -> IntValue -- | abs(-2.0) = 2.0. doFAbs :: FloatValue -> FloatValue -- | ssignum(-2) = -1. doSSignum :: IntValue -> IntValue -- | usignum(-2) = -1. doUSignum :: IntValue -> IntValue -- | Apply a BinOp to an operand. Returns Nothing if the -- application is mistyped, or outside the domain (e.g. division by -- zero). doBinOp :: BinOp -> PrimValue -> PrimValue -> Maybe PrimValue -- | Integer addition. doAdd :: IntValue -> IntValue -> IntValue -- | Integer multiplication. doMul :: IntValue -> IntValue -> IntValue -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. doSDiv :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer modulus; the countepart to SDiv. doSMod :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer exponentatation. doPow :: IntValue -> IntValue -> Maybe IntValue -- | Apply a ConvOp to an operand. Returns Nothing if the -- application is mistyped. doConvOp :: ConvOp -> PrimValue -> Maybe PrimValue -- | Zero-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doZExt :: IntValue -> IntType -> IntValue -- | Sign-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doSExt :: IntValue -> IntType -> IntValue -- | Convert the former floating-point type to the latter. doFPConv :: FloatValue -> FloatType -> FloatValue -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). doFPToUI :: FloatValue -> IntType -> IntValue -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). doFPToSI :: FloatValue -> IntType -> IntValue -- | Convert an unsigned integer to a floating-point value. doUIToFP :: IntValue -> FloatType -> FloatValue -- | Convert a signed integer to a floating-point value. doSIToFP :: IntValue -> FloatType -> FloatValue -- | Translate an IntValue to Int64. This is guaranteed to -- fit. intToInt64 :: IntValue -> Int64 -- | Translate an IntValue to Word64. This is guaranteed to -- fit. intToWord64 :: IntValue -> Word64 -- | Apply a CmpOp to an operand. Returns Nothing if the -- application is mistyped. doCmpOp :: CmpOp -> PrimValue -> PrimValue -> Maybe Bool -- | Compare any two primtive values for exact equality. doCmpEq :: PrimValue -> PrimValue -> Bool -- | Unsigned less than. doCmpUlt :: IntValue -> IntValue -> Bool -- | Unsigned less than or equal. doCmpUle :: IntValue -> IntValue -> Bool -- | Signed less than. doCmpSlt :: IntValue -> IntValue -> Bool -- | Signed less than or equal. doCmpSle :: IntValue -> IntValue -> Bool -- | Floating-point less than. doFCmpLt :: FloatValue -> FloatValue -> Bool -- | Floating-point less than or equal. doFCmpLe :: FloatValue -> FloatValue -> Bool -- | The result type of a binary operator. binOpType :: BinOp -> PrimType -- | The operand and result type of a unary operator. unOpType :: UnOp -> PrimType -- | The operand types of a comparison operator. cmpOpType :: CmpOp -> PrimType -- | The input and output types of a conversion operator. convOpType :: ConvOp -> (PrimType, PrimType) -- | A mapping from names of primitive functions to their parameter types, -- their result type, and a function for evaluating them. primFuns :: Map String ([PrimType], PrimType, [PrimValue] -> Maybe PrimValue) -- | Is the given value kind of zero? zeroIsh :: PrimValue -> Bool -- | Is the given integer value kind of zero? zeroIshInt :: IntValue -> Bool -- | Is the given value kind of one? oneIsh :: PrimValue -> Bool -- | Is the given integer value kind of one? oneIshInt :: IntValue -> Bool -- | Is the given value kind of negative? negativeIsh :: PrimValue -> Bool -- | The size of a value of a given primitive type in bites. primBitSize :: PrimType -> Int -- | The size of a value of a given primitive type in eight-bit bytes. primByteSize :: Num a => PrimType -> a -- | The size of a value of a given integer type in eight-bit bytes. intByteSize :: Num a => IntType -> a -- | The size of a value of a given floating-point type in eight-bit bytes. floatByteSize :: Num a => FloatType -> a -- | True if the given binary operator is commutative. commutativeBinOp :: BinOp -> Bool -- | The human-readable name for a ConvOp. This is used to expose -- the ConvOp in the intrinsics module of a Futhark -- program. convOpFun :: ConvOp -> String -- | True if signed. Only makes a difference for integer types. prettySigned :: Bool -> PrimType -> String instance GHC.Generics.Generic Futhark.IR.Primitive.IntType instance GHC.Enum.Bounded Futhark.IR.Primitive.IntType instance GHC.Enum.Enum Futhark.IR.Primitive.IntType instance GHC.Show.Show Futhark.IR.Primitive.IntType instance GHC.Classes.Ord Futhark.IR.Primitive.IntType instance GHC.Classes.Eq Futhark.IR.Primitive.IntType instance GHC.Generics.Generic Futhark.IR.Primitive.FloatType instance GHC.Enum.Bounded Futhark.IR.Primitive.FloatType instance GHC.Enum.Enum Futhark.IR.Primitive.FloatType instance GHC.Show.Show Futhark.IR.Primitive.FloatType instance GHC.Classes.Ord Futhark.IR.Primitive.FloatType instance GHC.Classes.Eq Futhark.IR.Primitive.FloatType instance GHC.Generics.Generic Futhark.IR.Primitive.PrimType instance GHC.Show.Show Futhark.IR.Primitive.PrimType instance GHC.Classes.Ord Futhark.IR.Primitive.PrimType instance GHC.Classes.Eq Futhark.IR.Primitive.PrimType instance GHC.Generics.Generic Futhark.IR.Primitive.IntValue instance GHC.Show.Show Futhark.IR.Primitive.IntValue instance GHC.Classes.Ord Futhark.IR.Primitive.IntValue instance GHC.Classes.Eq Futhark.IR.Primitive.IntValue instance GHC.Generics.Generic Futhark.IR.Primitive.FloatValue instance GHC.Show.Show Futhark.IR.Primitive.FloatValue instance GHC.Generics.Generic Futhark.IR.Primitive.PrimValue instance GHC.Show.Show Futhark.IR.Primitive.PrimValue instance GHC.Classes.Ord Futhark.IR.Primitive.PrimValue instance GHC.Classes.Eq Futhark.IR.Primitive.PrimValue instance GHC.Generics.Generic Futhark.IR.Primitive.UnOp instance GHC.Show.Show Futhark.IR.Primitive.UnOp instance GHC.Classes.Ord Futhark.IR.Primitive.UnOp instance GHC.Classes.Eq Futhark.IR.Primitive.UnOp instance GHC.Generics.Generic Futhark.IR.Primitive.Overflow instance GHC.Show.Show Futhark.IR.Primitive.Overflow instance GHC.Generics.Generic Futhark.IR.Primitive.Safety instance GHC.Show.Show Futhark.IR.Primitive.Safety instance GHC.Classes.Ord Futhark.IR.Primitive.Safety instance GHC.Classes.Eq Futhark.IR.Primitive.Safety instance GHC.Generics.Generic Futhark.IR.Primitive.BinOp instance GHC.Show.Show Futhark.IR.Primitive.BinOp instance GHC.Classes.Ord Futhark.IR.Primitive.BinOp instance GHC.Classes.Eq Futhark.IR.Primitive.BinOp instance GHC.Generics.Generic Futhark.IR.Primitive.CmpOp instance GHC.Show.Show Futhark.IR.Primitive.CmpOp instance GHC.Classes.Ord Futhark.IR.Primitive.CmpOp instance GHC.Classes.Eq Futhark.IR.Primitive.CmpOp instance GHC.Generics.Generic Futhark.IR.Primitive.ConvOp instance GHC.Show.Show Futhark.IR.Primitive.ConvOp instance GHC.Classes.Ord Futhark.IR.Primitive.ConvOp instance GHC.Classes.Eq Futhark.IR.Primitive.ConvOp instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.ConvOp instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.ConvOp instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.CmpOp instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.CmpOp instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.BinOp instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.BinOp instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.Safety instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.Overflow instance GHC.Classes.Eq Futhark.IR.Primitive.Overflow instance GHC.Classes.Ord Futhark.IR.Primitive.Overflow instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.UnOp instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.UnOp instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.PrimValue instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.PrimValue instance GHC.Classes.Eq Futhark.IR.Primitive.FloatValue instance GHC.Classes.Ord Futhark.IR.Primitive.FloatValue instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.FloatValue instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.FloatValue instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.IntValue instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.IntValue instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.PrimType instance GHC.Enum.Enum Futhark.IR.Primitive.PrimType instance GHC.Enum.Bounded Futhark.IR.Primitive.PrimType instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.PrimType instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.FloatType instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.FloatType instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Primitive.IntType instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Primitive.IntType -- | Futhark error definitions. module Futhark.Error -- | A compiler error. data CompilerError -- | An error that happened due to something the user did, such as provide -- incorrect code or options. ExternalError :: Doc -> CompilerError -- | An internal compiler error. The second text is extra data for -- debugging, which can be written to a file. InternalError :: Text -> Text -> ErrorClass -> CompilerError -- | There are two classes of internal errors: actual bugs, and -- implementation limitations. The latter are already known and need not -- be reported. data ErrorClass CompilerBug :: ErrorClass CompilerLimitation :: ErrorClass -- | Raise an ExternalError based on a prettyprinting result. externalError :: MonadError CompilerError m => Doc -> m a -- | Raise an ExternalError based on a string. externalErrorS :: MonadError CompilerError m => String -> m a -- | An error that is not the users fault, but a bug (or limitation) in the -- compiler. Compiler passes should only ever report this error - any -- problems after the type checker are *our* fault, not the users. These -- are generally thrown as IO exceptions, and caught at the top level. data InternalError Error :: ErrorClass -> Text -> InternalError -- | Throw an InternalError that is a CompilerBug. compilerBug :: Text -> a -- | Like compilerBug, but with a String. compilerBugS :: String -> a -- | Throw an InternalError that is a CompilerLimitation. compilerLimitation :: Text -> a -- | Like compilerLimitation, but with a String. compilerLimitationS :: String -> a -- | Raise an InternalError based on a prettyprinting result. internalErrorS :: MonadError CompilerError m => String -> Doc -> m a instance GHC.Show.Show Futhark.Error.ErrorClass instance GHC.Classes.Ord Futhark.Error.ErrorClass instance GHC.Classes.Eq Futhark.Error.ErrorClass instance GHC.Show.Show Futhark.Error.InternalError instance GHC.Exception.Type.Exception Futhark.Error.InternalError instance GHC.Show.Show Futhark.Error.CompilerError -- | Basic table building for prettier futhark-test output. module Futhark.Util.Table -- | Builds a table from a list of entries and a padding amount that -- determines padding from the right side of the widest entry in each -- column. buildTable :: [[Entry]] -> Int -> String -- | Makes a table entry with the default SGR mode. mkEntry :: String -> (String, [SGR]) -- | A table entry. Consists of the content as well a list of SGR commands -- to color/stylelize the entry. type Entry = (String, [SGR]) instance GHC.Show.Show Futhark.Util.Table.RowTemplate -- | This module contains very basic definitions for Futhark - so basic, -- that they can be shared between the internal and external -- representation. module Language.Futhark.Core -- | The uniqueness attribute of a type. This essentially indicates whether -- or not in-place modifications are acceptable. With respect to -- ordering, Unique is greater than Nonunique. data Uniqueness -- | May have references outside current function. Nonunique :: Uniqueness -- | No references outside current function. Unique :: Uniqueness -- | Whether some operator is commutative or not. The Monoid -- instance returns the least commutative of its arguments. data Commutativity Noncommutative :: Commutativity Commutative :: Commutativity -- | Source location type. Source location are all equal, which allows AST -- nodes to be compared modulo location information. data SrcLoc -- | Location type, consisting of a beginning position and an end position. data Loc -- | Located values have a location. class Located a locOf :: Located a => a -> Loc locOfList :: Located a => [a] -> Loc -- | The SrcLoc of a Located value. srclocOf :: Located a => a -> SrcLoc -- | A human-readable location string, of the form -- filename:lineno:columnno. This follows the GNU coding -- standards for error messages: -- https://www.gnu.org/prep/standards/html_node/Errors.html -- -- This function assumes that both start and end position is in the same -- file (it is not clear what the alternative would even mean). locStr :: Located a => a -> String -- | Like locStr, but locStrRel prev now prints the -- location now with the file name left out if the same as -- prev. This is useful when printing messages that are all in -- the context of some initially printed location (e.g. the first mention -- contains the file name; the rest just line and column name). locStrRel :: (Located a, Located b) => a -> b -> String -- | Given a list of strings representing entries in the stack trace and -- the index of the frame to highlight, produce a final -- newline-terminated string for showing to the user. This string should -- also be preceded by a newline. The most recent stack frame must come -- first in the list. prettyStacktrace :: Int -> [String] -> String -- | The abstract (not really) type representing names in the Futhark -- compiler. Strings, being lists of characters, are very slow, -- while Texts are based on byte-arrays. data Name -- | Convert a name to the corresponding list of characters. nameToString :: Name -> String -- | Convert a list of characters to the corresponding name. nameFromString :: String -> Name -- | Convert a name to the corresponding Text. nameToText :: Name -> Text -- | Convert a Text to the corresponding name. nameFromText :: Text -> Name -- | A name tagged with some integer. Only the integer is used in -- comparisons, no matter the type of vn. data VName VName :: !Name -> !Int -> VName -- | Return the tag contained in the VName. baseTag :: VName -> Int -- | Return the name contained in the VName. baseName :: VName -> Name -- | Return the base Name converted to a string. baseString :: VName -> String -- | Prettyprint a value, wrapped to 80 characters. pretty :: Pretty a => a -> String -- | Enclose a string in the prefered quotes used in error messages. These -- are picked to not collide with characters permitted in identifiers. quote :: String -> String -- | As quote, but works on prettyprinted representation. pquote :: Doc -> Doc -- | The name of the default program entry point (main). defaultEntryPoint :: Name -- | 8-bit signed integer type data Int8 -- | 16-bit signed integer type data Int16 -- | 32-bit signed integer type data Int32 -- | 64-bit signed integer type data Int64 -- | 8-bit unsigned integer type data Word8 -- | 16-bit unsigned integer type data Word16 -- | 32-bit unsigned integer type data Word32 -- | 64-bit unsigned integer type data Word64 instance GHC.Generics.Generic Language.Futhark.Core.Uniqueness instance GHC.Show.Show Language.Futhark.Core.Uniqueness instance GHC.Classes.Ord Language.Futhark.Core.Uniqueness instance GHC.Classes.Eq Language.Futhark.Core.Uniqueness instance GHC.Generics.Generic Language.Futhark.Core.Commutativity instance GHC.Show.Show Language.Futhark.Core.Commutativity instance GHC.Classes.Ord Language.Futhark.Core.Commutativity instance GHC.Classes.Eq Language.Futhark.Core.Commutativity instance GHC.Generics.Generic Language.Futhark.Core.Name instance GHC.Base.Semigroup Language.Futhark.Core.Name instance Data.String.IsString Language.Futhark.Core.Name instance GHC.Classes.Ord Language.Futhark.Core.Name instance GHC.Classes.Eq Language.Futhark.Core.Name instance GHC.Show.Show Language.Futhark.Core.Name instance GHC.Generics.Generic Language.Futhark.Core.VName instance GHC.Show.Show Language.Futhark.Core.VName instance Language.SexpGrammar.Class.SexpIso Language.Futhark.Core.VName instance GHC.Classes.Eq Language.Futhark.Core.VName instance GHC.Classes.Ord Language.Futhark.Core.VName instance Language.SexpGrammar.Class.SexpIso Language.Futhark.Core.Name instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Core.Name instance Language.SexpGrammar.Class.SexpIso Language.Futhark.Core.Commutativity instance GHC.Base.Semigroup Language.Futhark.Core.Commutativity instance GHC.Base.Monoid Language.Futhark.Core.Commutativity instance Language.SexpGrammar.Class.SexpIso Language.Futhark.Core.Uniqueness instance GHC.Base.Semigroup Language.Futhark.Core.Uniqueness instance GHC.Base.Monoid Language.Futhark.Core.Uniqueness instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Core.Uniqueness -- | The most primitive ("core") aspects of the AST. Split out of -- Futhark.IR.Syntax in order for Futhark.IR.Decorations to -- use these definitions. This module is re-exported from -- Futhark.IR.Syntax and there should be no reason to include it -- explicitly. module Futhark.IR.Syntax.Core -- | The uniqueness attribute of a type. This essentially indicates whether -- or not in-place modifications are acceptable. With respect to -- ordering, Unique is greater than Nonunique. data Uniqueness -- | May have references outside current function. Nonunique :: Uniqueness -- | No references outside current function. Unique :: Uniqueness -- | A fancier name for () - encodes no uniqueness information. data NoUniqueness NoUniqueness :: NoUniqueness -- | The size of an array type as a list of its dimension sizes, with the -- type of sizes being parametric. newtype ShapeBase d Shape :: [d] -> ShapeBase d [shapeDims] :: ShapeBase d -> [d] -- | The size of an array as a list of subexpressions. If a variable, that -- variable must be in scope where this array is used. type Shape = ShapeBase SubExp -- | Something that may be existential. data Ext a Ext :: Int -> Ext a Free :: a -> Ext a -- | The size of this dimension. type ExtSize = Ext SubExp -- | Like Shape but some of its elements may be bound in a local -- environment instead. These are denoted with integral indices. type ExtShape = ShapeBase ExtSize -- | The size of an array type as merely the number of dimensions, with no -- further information. newtype Rank Rank :: Int -> Rank -- | A class encompassing types containing array shape information. class (Monoid a, Eq a, Ord a) => ArrayShape a -- | Return the rank of an array with the given size. shapeRank :: ArrayShape a => a -> Int -- | stripDims n shape strips the outer n dimensions from -- shape. stripDims :: ArrayShape a => Int -> a -> a -- | Check whether one shape if a subset of another shape. subShapeOf :: ArrayShape a => a -> a -> Bool -- | The memory space of a block. If DefaultSpace, this is the -- "default" space, whatever that is. The exact meaning of the -- SpaceId depends on the backend used. In GPU kernels, for -- example, this is used to distinguish between constant, global and -- shared memory spaces. In GPU-enabled host code, it is used to -- distinguish between host memory (DefaultSpace) and GPU space. data Space DefaultSpace :: Space Space :: SpaceId -> Space -- | A special kind of memory that is a statically sized array of some -- primitive type. Used for private memory on GPUs. ScalarSpace :: [SubExp] -> PrimType -> Space -- | A string representing a specific non-default memory space. type SpaceId = String -- | A Futhark type is either an array or an element type. When comparing -- types for equality with ==, shapes must match. data TypeBase shape u Prim :: PrimType -> TypeBase shape u Array :: PrimType -> shape -> u -> TypeBase shape u Mem :: Space -> TypeBase shape u -- | A type with shape information, used for describing the type of -- variables. type Type = TypeBase Shape NoUniqueness -- | A type with existentially quantified shapes - used as part of function -- (and function-like) return types. Generally only makes sense when used -- in a list. type ExtType = TypeBase ExtShape NoUniqueness -- | A type with shape and uniqueness information, used declaring return- -- and parameters types. type DeclType = TypeBase Shape Uniqueness -- | An ExtType with uniqueness information, used for function -- return types. type DeclExtType = TypeBase ExtShape Uniqueness -- | Information about which parts of a value/type are consumed. For -- example, we might say that a function taking three arguments of types -- ([int], *[int], [int]) has diet [Observe, Consume, -- Observe]. data Diet -- | Consumes this value. Consume :: Diet -- | Only observes value in this position, does not consume. A result may -- alias this. Observe :: Diet -- | As Observe, but the result will not alias, because the -- parameter does not carry aliases. ObservePrim :: Diet -- | An error message is a list of error parts, which are concatenated to -- form the final message. newtype ErrorMsg a ErrorMsg :: [ErrorMsgPart a] -> ErrorMsg a -- | A part of an error message. data ErrorMsgPart a -- | A literal string. ErrorString :: String -> ErrorMsgPart a -- | A run-time integer value. ErrorInt32 :: a -> ErrorMsgPart a -- | A bigger run-time integer value. ErrorInt64 :: a -> ErrorMsgPart a -- | How many non-constant parts does the error message have, and what is -- their type? errorMsgArgTypes :: ErrorMsg a -> [PrimType] -- | Non-array values. data PrimValue IntValue :: !IntValue -> PrimValue FloatValue :: !FloatValue -> PrimValue BoolValue :: !Bool -> PrimValue -- | The only value of type cert. Checked :: PrimValue -- | An identifier consists of its name and the type of the value bound to -- the identifier. data Ident Ident :: VName -> Type -> Ident [identName] :: Ident -> VName [identType] :: Ident -> Type -- | A list of names used for certificates in some expressions. newtype Certificates Certificates :: [VName] -> Certificates [unCertificates] :: Certificates -> [VName] -- | A subexpression is either a scalar constant or a variable. One -- important property is that evaluation of a subexpression is guaranteed -- to complete in constant time. data SubExp Constant :: PrimValue -> SubExp Var :: VName -> SubExp -- | A function or lambda parameter. data Param dec Param :: VName -> dec -> Param dec -- | Name of the parameter. [paramName] :: Param dec -> VName -- | Function parameter decoration. [paramDec] :: Param dec -> dec -- | How to index a single dimension of an array. data DimIndex d -- | Fix index in this dimension. DimFix :: d -> DimIndex d -- | DimSlice start_offset num_elems stride. DimSlice :: d -> d -> d -> DimIndex d -- | A list of DimFixs, indicating how an array should be sliced. -- Whenever a function accepts a Slice, that slice should be -- total, i.e, cover all dimensions of the array. Deviators should be -- indicated by taking a list of DimIndexes instead. type Slice d = [DimIndex d] -- | If the argument is a DimFix, return its component. dimFix :: DimIndex d -> Maybe d -- | If the slice is all DimFixs, return the components. sliceIndices :: Slice d -> Maybe [d] -- | The dimensions of the array produced by this slice. sliceDims :: Slice d -> [d] -- | A slice with a stride of one. unitSlice :: Num d => d -> d -> DimIndex d -- | Fix the DimSlices of a slice. The number of indexes must equal -- the length of sliceDims for the slice. fixSlice :: Num d => Slice d -> [d] -> [d] -- | Further slice the DimSlices of a slice. The number of slices -- must equal the length of sliceDims for the slice. sliceSlice :: Num d => Slice d -> Slice d -> Slice d -- | An element of a pattern - consisting of a name and an addditional -- parametric decoration. This decoration is what is expected to contain -- the type of the resulting variable. data PatElemT dec PatElem :: VName -> dec -> PatElemT dec -- | The name being bound. [patElemName] :: PatElemT dec -> VName -- | Pattern element decoration. [patElemDec] :: PatElemT dec -> dec instance GHC.Generics.Generic (Futhark.IR.Syntax.Core.ShapeBase d) instance GHC.Show.Show d => GHC.Show.Show (Futhark.IR.Syntax.Core.ShapeBase d) instance GHC.Classes.Ord d => GHC.Classes.Ord (Futhark.IR.Syntax.Core.ShapeBase d) instance GHC.Classes.Eq d => GHC.Classes.Eq (Futhark.IR.Syntax.Core.ShapeBase d) instance GHC.Generics.Generic (Futhark.IR.Syntax.Core.Ext a) instance GHC.Show.Show a => GHC.Show.Show (Futhark.IR.Syntax.Core.Ext a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Futhark.IR.Syntax.Core.Ext a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Futhark.IR.Syntax.Core.Ext a) instance GHC.Generics.Generic Futhark.IR.Syntax.Core.Rank instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Rank instance GHC.Classes.Eq Futhark.IR.Syntax.Core.Rank instance GHC.Show.Show Futhark.IR.Syntax.Core.Rank instance GHC.Generics.Generic Futhark.IR.Syntax.Core.NoUniqueness instance GHC.Show.Show Futhark.IR.Syntax.Core.NoUniqueness instance GHC.Classes.Ord Futhark.IR.Syntax.Core.NoUniqueness instance GHC.Classes.Eq Futhark.IR.Syntax.Core.NoUniqueness instance GHC.Generics.Generic Futhark.IR.Syntax.Core.Diet instance GHC.Show.Show Futhark.IR.Syntax.Core.Diet instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Diet instance GHC.Classes.Eq Futhark.IR.Syntax.Core.Diet instance GHC.Generics.Generic Futhark.IR.Syntax.Core.Certificates instance GHC.Show.Show Futhark.IR.Syntax.Core.Certificates instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Certificates instance GHC.Classes.Eq Futhark.IR.Syntax.Core.Certificates instance GHC.Generics.Generic Futhark.IR.Syntax.Core.SubExp instance GHC.Classes.Ord Futhark.IR.Syntax.Core.SubExp instance GHC.Classes.Eq Futhark.IR.Syntax.Core.SubExp instance GHC.Show.Show Futhark.IR.Syntax.Core.SubExp instance GHC.Generics.Generic Futhark.IR.Syntax.Core.Space instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Space instance GHC.Classes.Eq Futhark.IR.Syntax.Core.Space instance GHC.Show.Show Futhark.IR.Syntax.Core.Space instance GHC.Generics.Generic (Futhark.IR.Syntax.Core.TypeBase shape u) instance (GHC.Classes.Ord shape, GHC.Classes.Ord u) => GHC.Classes.Ord (Futhark.IR.Syntax.Core.TypeBase shape u) instance (GHC.Classes.Eq shape, GHC.Classes.Eq u) => GHC.Classes.Eq (Futhark.IR.Syntax.Core.TypeBase shape u) instance (GHC.Show.Show shape, GHC.Show.Show u) => GHC.Show.Show (Futhark.IR.Syntax.Core.TypeBase shape u) instance GHC.Generics.Generic Futhark.IR.Syntax.Core.Ident instance GHC.Show.Show Futhark.IR.Syntax.Core.Ident instance GHC.Generics.Generic (Futhark.IR.Syntax.Core.Param dec) instance GHC.Classes.Eq dec => GHC.Classes.Eq (Futhark.IR.Syntax.Core.Param dec) instance GHC.Show.Show dec => GHC.Show.Show (Futhark.IR.Syntax.Core.Param dec) instance GHC.Classes.Ord dec => GHC.Classes.Ord (Futhark.IR.Syntax.Core.Param dec) instance GHC.Generics.Generic (Futhark.IR.Syntax.Core.DimIndex d) instance GHC.Show.Show d => GHC.Show.Show (Futhark.IR.Syntax.Core.DimIndex d) instance GHC.Classes.Ord d => GHC.Classes.Ord (Futhark.IR.Syntax.Core.DimIndex d) instance GHC.Classes.Eq d => GHC.Classes.Eq (Futhark.IR.Syntax.Core.DimIndex d) instance GHC.Generics.Generic (Futhark.IR.Syntax.Core.PatElemT dec) instance GHC.Classes.Eq dec => GHC.Classes.Eq (Futhark.IR.Syntax.Core.PatElemT dec) instance GHC.Show.Show dec => GHC.Show.Show (Futhark.IR.Syntax.Core.PatElemT dec) instance GHC.Classes.Ord dec => GHC.Classes.Ord (Futhark.IR.Syntax.Core.PatElemT dec) instance GHC.Generics.Generic (Futhark.IR.Syntax.Core.ErrorMsgPart a) instance GHC.Show.Show a => GHC.Show.Show (Futhark.IR.Syntax.Core.ErrorMsgPart a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Futhark.IR.Syntax.Core.ErrorMsgPart a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Futhark.IR.Syntax.Core.ErrorMsgPart a) instance GHC.Generics.Generic (Futhark.IR.Syntax.Core.ErrorMsg a) instance GHC.Show.Show a => GHC.Show.Show (Futhark.IR.Syntax.Core.ErrorMsg a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Futhark.IR.Syntax.Core.ErrorMsg a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Futhark.IR.Syntax.Core.ErrorMsg a) instance Language.SexpGrammar.Class.SexpIso a => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Core.ErrorMsg a) instance Data.String.IsString (Futhark.IR.Syntax.Core.ErrorMsg a) instance GHC.Base.Functor Futhark.IR.Syntax.Core.ErrorMsg instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.ErrorMsg instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.ErrorMsg instance Language.SexpGrammar.Class.SexpIso a => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Core.ErrorMsgPart a) instance Data.String.IsString (Futhark.IR.Syntax.Core.ErrorMsgPart a) instance GHC.Base.Functor Futhark.IR.Syntax.Core.ErrorMsgPart instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.ErrorMsgPart instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.ErrorMsgPart instance Language.SexpGrammar.Class.SexpIso dec => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Core.PatElemT dec) instance GHC.Base.Functor Futhark.IR.Syntax.Core.PatElemT instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.PatElemT instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.PatElemT instance Language.SexpGrammar.Class.SexpIso d => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Core.DimIndex d) instance GHC.Base.Functor Futhark.IR.Syntax.Core.DimIndex instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.DimIndex instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.DimIndex instance Language.SexpGrammar.Class.SexpIso dec => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Core.Param dec) instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.Param instance GHC.Base.Functor Futhark.IR.Syntax.Core.Param instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.Param instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.Core.Ident instance GHC.Classes.Eq Futhark.IR.Syntax.Core.Ident instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Ident instance Futhark.IR.Syntax.Core.ArrayShape (Futhark.IR.Syntax.Core.ShapeBase Futhark.IR.Syntax.Core.ExtSize) instance Data.Bitraversable.Bitraversable Futhark.IR.Syntax.Core.TypeBase instance Data.Bifunctor.Bifunctor Futhark.IR.Syntax.Core.TypeBase instance Data.Bifoldable.Bifoldable Futhark.IR.Syntax.Core.TypeBase instance (Language.SexpGrammar.Class.SexpIso shape, Language.SexpGrammar.Class.SexpIso u) => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Core.TypeBase shape u) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.Core.Space instance Futhark.IR.Syntax.Core.ArrayShape (Futhark.IR.Syntax.Core.ShapeBase Futhark.IR.Syntax.Core.SubExp) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.Core.SubExp instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.Core.Certificates instance GHC.Base.Semigroup Futhark.IR.Syntax.Core.Certificates instance GHC.Base.Monoid Futhark.IR.Syntax.Core.Certificates instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.Core.Diet instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.Core.NoUniqueness instance Futhark.IR.Syntax.Core.ArrayShape Futhark.IR.Syntax.Core.Rank instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.Core.Rank instance GHC.Base.Semigroup Futhark.IR.Syntax.Core.Rank instance GHC.Base.Monoid Futhark.IR.Syntax.Core.Rank instance Language.SexpGrammar.Class.SexpIso a => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Core.Ext a) instance GHC.Base.Functor Futhark.IR.Syntax.Core.Ext instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.Ext instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.Ext instance Language.SexpGrammar.Class.SexpIso d => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Core.ShapeBase d) instance GHC.Base.Functor Futhark.IR.Syntax.Core.ShapeBase instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.ShapeBase instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.ShapeBase instance GHC.Base.Semigroup (Futhark.IR.Syntax.Core.ShapeBase d) instance GHC.Base.Monoid (Futhark.IR.Syntax.Core.ShapeBase d) -- | Possibly convenient facilities for constructing constants. module Futhark.IR.Prop.Constants -- | If a Haskell type is an instance of IsValue, it means that a -- value of that type can be converted to a Futhark PrimValue. -- This is intended to cut down on boilerplate when writing compiler code -- - for example, you'll quickly grow tired of writing Constant -- (LogVal True) loc. class IsValue a value :: IsValue a => a -> PrimValue -- | Create a Constant SubExp containing the given value. constant :: IsValue v => v -> SubExp -- | Utility definition for reasons of type ambiguity. intConst :: IntType -> Integer -> SubExp -- | Utility definition for reasons of type ambiguity. floatConst :: FloatType -> Double -> SubExp instance Futhark.IR.Prop.Constants.IsValue GHC.Int.Int8 instance Futhark.IR.Prop.Constants.IsValue GHC.Int.Int16 instance Futhark.IR.Prop.Constants.IsValue GHC.Int.Int32 instance Futhark.IR.Prop.Constants.IsValue GHC.Int.Int64 instance Futhark.IR.Prop.Constants.IsValue GHC.Word.Word8 instance Futhark.IR.Prop.Constants.IsValue GHC.Word.Word16 instance Futhark.IR.Prop.Constants.IsValue GHC.Word.Word32 instance Futhark.IR.Prop.Constants.IsValue GHC.Word.Word64 instance Futhark.IR.Prop.Constants.IsValue GHC.Types.Double instance Futhark.IR.Prop.Constants.IsValue GHC.Types.Float instance Futhark.IR.Prop.Constants.IsValue GHC.Types.Bool instance Futhark.IR.Prop.Constants.IsValue Futhark.IR.Primitive.PrimValue instance Futhark.IR.Prop.Constants.IsValue Futhark.IR.Primitive.IntValue instance Futhark.IR.Prop.Constants.IsValue Futhark.IR.Primitive.FloatValue -- | Functions for inspecting and constructing various types. module Futhark.IR.Prop.Types -- | Remove shape information from a type. rankShaped :: ArrayShape shape => TypeBase shape u -> TypeBase Rank u -- | Return the dimensionality of a type. For non-arrays, this is zero. For -- a one-dimensional array it is one, for a two-dimensional it is two, -- and so forth. arrayRank :: ArrayShape shape => TypeBase shape u -> Int -- | Return the shape of a type - for non-arrays, this is the -- mempty. arrayShape :: ArrayShape shape => TypeBase shape u -> shape -- | Set the shape of an array. If the given type is not an array, return -- the type unchanged. setArrayShape :: ArrayShape newshape => TypeBase oldshape u -> newshape -> TypeBase newshape u -- | True if the given type has a dimension that is existentially sized. existential :: ExtType -> Bool -- | Return the uniqueness of a type. uniqueness :: TypeBase shape Uniqueness -> Uniqueness -- | unique t is True if the type of the argument is -- unique. unique :: TypeBase shape Uniqueness -> Bool -- | Convert types with non-existential shapes to types with -- non-existential shapes. Only the representation is changed, so all the -- shapes will be Free. staticShapes :: [TypeBase Shape u] -> [TypeBase ExtShape u] -- | As staticShapes, but on a single type. staticShapes1 :: TypeBase Shape u -> TypeBase ExtShape u -- | A type is a primitive type if it is not an array or memory block. primType :: TypeBase shape u -> Bool -- | arrayOf t s u constructs an array type. The convenience -- compared to using the Array constructor directly is that -- t can itself be an array. If t is an -- n-dimensional array, and s is a list of length -- n, the resulting type is of an n+m dimensions. The -- uniqueness of the new array will be u, no matter the -- uniqueness of t. If the shape s has rank 0, then the -- t will be returned, although if it is an array, with the -- uniqueness changed to u. arrayOf :: ArrayShape shape => TypeBase shape u_unused -> shape -> u -> TypeBase shape u -- | Construct an array whose rows are the given type, and the outer size -- is the given dimension. This is just a convenient wrapper around -- arrayOf. arrayOfRow :: ArrayShape (ShapeBase d) => TypeBase (ShapeBase d) NoUniqueness -> d -> TypeBase (ShapeBase d) NoUniqueness -- | Construct an array whose rows are the given type, and the outer size -- is the given Shape. This is just a convenient wrapper around -- arrayOf. arrayOfShape :: Type -> Shape -> Type -- | Replace the size of the outermost dimension of an array. If the given -- type is not an array, it is returned unchanged. setOuterSize :: ArrayShape (ShapeBase d) => TypeBase (ShapeBase d) u -> d -> TypeBase (ShapeBase d) u -- | Replace the size of the given dimension of an array. If the given type -- is not an array, it is returned unchanged. setDimSize :: ArrayShape (ShapeBase d) => Int -> TypeBase (ShapeBase d) u -> d -> TypeBase (ShapeBase d) u -- | Replace the outermost dimension of an array shape. setOuterDim :: ShapeBase d -> d -> ShapeBase d -- | Replace the specified dimension of an array shape. setDim :: Int -> ShapeBase d -> d -> ShapeBase d -- | Set the dimensions of an array. If the given type is not an array, -- return the type unchanged. setArrayDims :: TypeBase oldshape u -> [SubExp] -> TypeBase Shape u -- | peelArray n t returns the type resulting from peeling the -- first n array dimensions from t. Returns -- Nothing if t has less than n dimensions. peelArray :: ArrayShape shape => Int -> TypeBase shape u -> Maybe (TypeBase shape u) -- | stripArray n t removes the n outermost layers of the -- array. Essentially, it is the type of indexing an array of type -- t with n indexes. stripArray :: ArrayShape shape => Int -> TypeBase shape u -> TypeBase shape u -- | Return the dimensions of a type - for non-arrays, this is the empty -- list. arrayDims :: TypeBase Shape u -> [SubExp] -- | Return the existential dimensions of a type - for non-arrays, this is -- the empty list. arrayExtDims :: TypeBase ExtShape u -> [ExtSize] -- | Return the size of the given dimension. If the dimension does not -- exist, the zero constant is returned. shapeSize :: Int -> Shape -> SubExp -- | Return the size of the given dimension. If the dimension does not -- exist, the zero constant is returned. arraySize :: Int -> TypeBase Shape u -> SubExp -- | Return the size of the given dimension in the first element of the -- given type list. If the dimension does not exist, or no types are -- given, the zero constant is returned. arraysSize :: Int -> [TypeBase Shape u] -> SubExp -- | Return the immediate row-type of an array. For [[int]], this -- would be [int]. rowType :: ArrayShape shape => TypeBase shape u -> TypeBase shape u -- | Returns the bottommost type of an array. For [[int]], this -- would be int. If the given type is not an array, it is -- returned. elemType :: TypeBase shape u -> PrimType -- | Swap the two outer dimensions of the type. transposeType :: Type -> Type -- | Rearrange the dimensions of the type. If the length of the permutation -- does not match the rank of the type, the permutation will be extended -- with identity. rearrangeType :: [Int] -> Type -> Type -- | Transform any SubExps in the type. mapOnExtType :: Monad m => (SubExp -> m SubExp) -> TypeBase ExtShape u -> m (TypeBase ExtShape u) -- | Transform any SubExps in the type. mapOnType :: Monad m => (SubExp -> m SubExp) -> TypeBase Shape u -> m (TypeBase Shape u) -- | diet t returns a description of how a function parameter of -- type t might consume its argument. diet :: TypeBase shape Uniqueness -> Diet -- | x `subtypeOf` y is true if x is a subtype of -- y (or equal to y), meaning x is valid -- whenever y is. subtypeOf :: (Ord u, ArrayShape shape) => TypeBase shape u -> TypeBase shape u -> Bool -- | xs `subtypesOf` ys is true if xs is the same size as -- ys, and each element in xs is a subtype of the -- corresponding element in ys.. subtypesOf :: (Ord u, ArrayShape shape) => [TypeBase shape u] -> [TypeBase shape u] -> Bool -- | Add the given uniqueness information to the types. toDecl :: TypeBase shape NoUniqueness -> Uniqueness -> TypeBase shape Uniqueness -- | Remove uniqueness information from the type. fromDecl :: TypeBase shape Uniqueness -> TypeBase shape NoUniqueness -- | If an existential, then return its existential index. isExt :: Ext a -> Maybe Int -- | If a known size, then return that size. isFree :: Ext a -> Maybe a -- | Given the existential return type of a function, and the shapes of the -- values returned by the function, return the existential shape context. -- That is, those sizes that are existential in the return type. extractShapeContext :: [TypeBase ExtShape u] -> [[a]] -> [a] -- | The set of identifiers used for the shape context in the given -- ExtTypes. shapeContext :: [TypeBase ExtShape u] -> Set Int -- | If all dimensions of the given ExtShape are statically known, -- change to the corresponding Shape. hasStaticShape :: TypeBase ExtShape u -> Maybe (TypeBase Shape u) -- | Given two lists of ExtTypes of the same length, return a list -- of ExtTypes that is a subtype of the two operands. generaliseExtTypes :: [TypeBase ExtShape u] -> [TypeBase ExtShape u] -> [TypeBase ExtShape u] -- | Given a list of ExtTypes and a list of "forbidden" names, -- modify the dimensions of the ExtTypes such that they are -- Ext where they were previously Free with a variable in -- the set of forbidden names. existentialiseExtTypes :: [VName] -> [ExtType] -> [ExtType] -- | Produce a mapping for the dimensions context. shapeExtMapping :: [TypeBase ExtShape u] -> [TypeBase Shape u1] -> Map Int SubExp -- |
--   IntType Int8
--   
int8 :: PrimType -- |
--   IntType Int16
--   
int16 :: PrimType -- |
--   IntType Int32
--   
int32 :: PrimType -- |
--   IntType Int64
--   
int64 :: PrimType -- |
--   FloatType Float32
--   
float32 :: PrimType -- |
--   FloatType Float64
--   
float64 :: PrimType -- | Typeclass for things that contain Types. class Typed t typeOf :: Typed t => t -> Type -- | Typeclass for things that contain DeclTypes. class DeclTyped t declTypeOf :: DeclTyped t => t -> DeclType -- | Typeclass for things that contain ExtTypes. class FixExt t => ExtTyped t extTypeOf :: ExtTyped t => t -> ExtType -- | Typeclass for things that contain DeclExtTypes. class FixExt t => DeclExtTyped t declExtTypeOf :: DeclExtTyped t => t -> DeclExtType -- | Typeclass for things whose type can be changed. class Typed a => SetType a setType :: SetType a => a -> Type -> a -- | Something with an existential context that can be (partially) fixed. class FixExt t -- | Fix the given existentional variable to the indicated free value. fixExt :: FixExt t => Int -> SubExp -> t -> t instance Futhark.IR.Prop.Types.ExtTyped Futhark.IR.Syntax.Core.ExtType instance Futhark.IR.Prop.Types.DeclExtTyped Futhark.IR.Syntax.Core.DeclExtType instance (Futhark.IR.Prop.Types.FixExt shape, Futhark.IR.Syntax.Core.ArrayShape shape) => Futhark.IR.Prop.Types.FixExt (Futhark.IR.Syntax.Core.TypeBase shape u) instance Futhark.IR.Prop.Types.FixExt d => Futhark.IR.Prop.Types.FixExt (Futhark.IR.Syntax.Core.ShapeBase d) instance Futhark.IR.Prop.Types.FixExt a => Futhark.IR.Prop.Types.FixExt [a] instance Futhark.IR.Prop.Types.FixExt Futhark.IR.Syntax.Core.ExtSize instance Futhark.IR.Prop.Types.FixExt () instance Futhark.IR.Prop.Types.SetType Futhark.IR.Syntax.Core.Type instance Futhark.IR.Prop.Types.SetType b => Futhark.IR.Prop.Types.SetType (a, b) instance Futhark.IR.Prop.Types.SetType dec => Futhark.IR.Prop.Types.SetType (Futhark.IR.Syntax.Core.PatElemT dec) instance Futhark.IR.Prop.Types.DeclTyped Futhark.IR.Syntax.Core.DeclType instance Futhark.IR.Prop.Types.DeclTyped dec => Futhark.IR.Prop.Types.DeclTyped (Futhark.IR.Syntax.Core.Param dec) instance Futhark.IR.Prop.Types.Typed Futhark.IR.Syntax.Core.Type instance Futhark.IR.Prop.Types.Typed Futhark.IR.Syntax.Core.DeclType instance Futhark.IR.Prop.Types.Typed Futhark.IR.Syntax.Core.Ident instance Futhark.IR.Prop.Types.Typed dec => Futhark.IR.Prop.Types.Typed (Futhark.IR.Syntax.Core.Param dec) instance Futhark.IR.Prop.Types.Typed dec => Futhark.IR.Prop.Types.Typed (Futhark.IR.Syntax.Core.PatElemT dec) instance Futhark.IR.Prop.Types.Typed b => Futhark.IR.Prop.Types.Typed (a, b) -- | This module exports a type class covering representations of function -- return types. module Futhark.IR.RetType -- | A type representing the return type of a body. It should contain at -- least the information contained in a list of ExtTypes, but may -- have more, notably an existential context. class (Show rt, Eq rt, Ord rt, ExtTyped rt) => IsBodyType rt -- | Construct a body type from a primitive type. primBodyType :: IsBodyType rt => PrimType -> rt -- | A type representing the return type of a function. In practice, a list -- of these will be used. It should contain at least the information -- contained in an ExtType, but may have more, notably an -- existential context. class (Show rt, Eq rt, Ord rt, DeclExtTyped rt) => IsRetType rt -- | Contruct a return type from a primitive type. primRetType :: IsRetType rt => PrimType -> rt -- | Given a function return type, the parameters of the function, and the -- arguments for a concrete call, return the instantiated return type for -- the concrete call, if valid. applyRetType :: (IsRetType rt, Typed dec) => [rt] -> [Param dec] -> [(SubExp, Type)] -> Maybe [rt] -- | Given shape parameter names and value parameter types, produce the -- types of arguments accepted. expectedTypes :: Typed t => [VName] -> [t] -> [SubExp] -> [Type] instance Futhark.IR.RetType.IsRetType Futhark.IR.Syntax.Core.DeclExtType instance Futhark.IR.RetType.IsBodyType Futhark.IR.Syntax.Core.ExtType -- | The core Futhark AST is parameterised by a lore type -- parameter, which is then used to invoke the type families defined -- here. module Futhark.IR.Decorations -- | A collection of type families, along with constraints specifying that -- the types they map to should satisfy some minimal requirements. class (Show (LetDec l), Show (ExpDec l), Show (BodyDec l), Show (FParamInfo l), Show (LParamInfo l), Show (RetType l), Show (BranchType l), Show (Op l), Eq (LetDec l), Eq (ExpDec l), Eq (BodyDec l), Eq (FParamInfo l), Eq (LParamInfo l), Eq (RetType l), Eq (BranchType l), Eq (Op l), Ord (LetDec l), Ord (ExpDec l), Ord (BodyDec l), Ord (FParamInfo l), Ord (LParamInfo l), Ord (RetType l), Ord (BranchType l), Ord (Op l), IsRetType (RetType l), IsBodyType (BranchType l), Typed (FParamInfo l), Typed (LParamInfo l), Typed (LetDec l), DeclTyped (FParamInfo l), SexpIso (LetDec l), SexpIso (ExpDec l), SexpIso (BodyDec l), SexpIso (FParamInfo l), SexpIso (LParamInfo l), SexpIso (RetType l), SexpIso (BranchType l), SexpIso (Op l)) => Decorations l where { -- | Decoration for every let-pattern element. type family LetDec l :: Type; -- | Decoration for every expression. type family ExpDec l :: Type; -- | Decoration for every body. type family BodyDec l :: Type; -- | Decoration for every (non-lambda) function parameter. type family FParamInfo l :: Type; -- | Decoration for every lambda function parameter. type family LParamInfo l :: Type; -- | The return type decoration of function calls. type family RetType l :: Type; -- | The return type decoration of branches. type family BranchType l :: Type; -- | Extensible operation. type family Op l :: Type; type LetDec l = Type; type ExpDec l = (); type BodyDec l = (); type FParamInfo l = DeclType; type LParamInfo l = Type; type RetType l = DeclExtType; type BranchType l = ExtType; type Op l = (); } -- |

Definition of the Futhark core language IR

-- -- For actually constructing ASTs, see Futhark.Construct. -- --

Types and values

-- -- The core language type system is much more restricted than the core -- language. This is a theme that repeats often. The only types that are -- supported in the core language are various primitive types -- PrimType which can be combined in arrays (ignore Mem for -- now). Types are represented as TypeBase, which is parameterised -- by the shape of the array and whether we keep uniqueness information. -- The Type alias, which is the most commonly used, uses -- Shape and NoUniqueness. -- -- This means that the records, tuples, and sum types of the source -- language are represented merely as collections of primitives and -- arrays. This is implemented in Futhark.Internalise, but the -- specifics are not important for writing passes on the core language. -- What is important is that many constructs that conceptually -- return tuples instead return multiple values. This is not -- merely syntactic sugar for a tuple: each of those values are -- eventually bound to distinct variables. The prettyprinter for the IR -- will typically print such collections of values or types in curly -- braces. -- -- The system of primitive types is interesting in itself. See -- Futhark.IR.Primitive. -- --

Overall AST design

-- -- Internally, the Futhark compiler core intermediate representation -- resembles a traditional compiler for an imperative language more than -- it resembles, say, a Haskell or ML compiler. All functions are -- monomorphic (except for sizes), first-order, and defined at the top -- level. Notably, the IR does not use continuation-passing style -- (CPS) at any time. Instead it uses Administrative Normal Form (ANF), -- where all subexpressions SubExp are either constants -- PrimValue or variables VName. Variables are represented -- as a human-readable Name (which doesn't matter to the compiler) -- as well as a numeric tag, which is what the compiler actually -- looks at. All variable names when prettyprinted are of the form -- foo_123. Function names are just Names, though. -- -- The body of a function (FunDef) is a Body, which -- consists of a sequence of statements (Stms) and a -- Result. Execution of a Body consists of executing all of -- the statements, then returning the values of the variables indicated -- by the result. -- -- A statement (Stm) consists of a Pattern alongside an -- expression ExpT. A pattern contains a "context" part and a -- "value" part. The context is used for things like the size of arrays -- in the value part whose size is existential. -- -- For example, the source language expression let z = x + y - 1 in -- z would in the core language be represented (in prettyprinted -- form) as something like: -- --
--   let {a_12} = x_10 + y_11
--   let {b_13} = a_12 - 1
--   in {b_13}
--   
-- --

Lores

-- -- Most AST types (Stm, ExpT, Prog, etc) are -- parameterised by a type parameter with the somewhat silly name -- lore. The lore specifies how to fill out various polymorphic -- parts of the AST. For example, ExpT has a constructor Op -- whose payload depends on lore, via the use of a type family -- called Op (a kind of type-level function) which is applied to -- the lore. The SOACS representation (Futhark.IR.SOACS) -- thus uses a lore called SOACS, and defines that Op -- SOACS is a SOAC, while the Kernels representation -- (Futhark.IR.Kernels) defines Op Kernels as some kind -- of kernel construct. Similarly, various other decorations (e.g. what -- information we store in a PatElemT) are also type families. -- -- The full list of possible decorations is defined as part of the type -- class Decorations (although other type families are also used -- elsewhere in the compiler on an ad hoc basis). -- -- Essentially, the lore type parameter functions as a kind of -- proxy, saving us from having to parameterise the AST type with all the -- different forms of decorations that we desire (it would easily become -- a type with a dozen type parameters). -- -- Defining a new representation (or lore) thus requires you to -- define an empty datatype and implement a handful of type class -- instances for it. See the source of Futhark.IR.Seq for what is -- likely the simplest example. module Futhark.IR.Syntax -- | The uniqueness attribute of a type. This essentially indicates whether -- or not in-place modifications are acceptable. With respect to -- ordering, Unique is greater than Nonunique. data Uniqueness -- | May have references outside current function. Nonunique :: Uniqueness -- | No references outside current function. Unique :: Uniqueness -- | A fancier name for () - encodes no uniqueness information. data NoUniqueness NoUniqueness :: NoUniqueness -- | The size of an array type as merely the number of dimensions, with no -- further information. newtype Rank Rank :: Int -> Rank -- | A class encompassing types containing array shape information. class (Monoid a, Eq a, Ord a) => ArrayShape a -- | Return the rank of an array with the given size. shapeRank :: ArrayShape a => a -> Int -- | stripDims n shape strips the outer n dimensions from -- shape. stripDims :: ArrayShape a => Int -> a -> a -- | Check whether one shape if a subset of another shape. subShapeOf :: ArrayShape a => a -> a -> Bool -- | The memory space of a block. If DefaultSpace, this is the -- "default" space, whatever that is. The exact meaning of the -- SpaceId depends on the backend used. In GPU kernels, for -- example, this is used to distinguish between constant, global and -- shared memory spaces. In GPU-enabled host code, it is used to -- distinguish between host memory (DefaultSpace) and GPU space. data Space DefaultSpace :: Space Space :: SpaceId -> Space -- | A special kind of memory that is a statically sized array of some -- primitive type. Used for private memory on GPUs. ScalarSpace :: [SubExp] -> PrimType -> Space -- | A Futhark type is either an array or an element type. When comparing -- types for equality with ==, shapes must match. data TypeBase shape u Prim :: PrimType -> TypeBase shape u Array :: PrimType -> shape -> u -> TypeBase shape u Mem :: Space -> TypeBase shape u -- | Information about which parts of a value/type are consumed. For -- example, we might say that a function taking three arguments of types -- ([int], *[int], [int]) has diet [Observe, Consume, -- Observe]. data Diet -- | Consumes this value. Consume :: Diet -- | Only observes value in this position, does not consume. A result may -- alias this. Observe :: Diet -- | As Observe, but the result will not alias, because the -- parameter does not carry aliases. ObservePrim :: Diet -- | A single attribute. data Attr AttrAtom :: Name -> Attr AttrComp :: Name -> [Attr] -> Attr -- | Every statement is associated with a set of attributes, which can have -- various effects throughout the compiler. newtype Attrs Attrs :: Set Attr -> Attrs [unAttrs] :: Attrs -> Set Attr -- | Construct Attrs from a single Attr. oneAttr :: Attr -> Attrs -- | Is the given attribute to be found in the attribute set? inAttrs :: Attr -> Attrs -> Bool -- | x withoutAttrs y gives x except for any -- attributes also in y. withoutAttrs :: Attrs -> Attrs -> Attrs -- | An identifier consists of its name and the type of the value bound to -- the identifier. data Ident Ident :: VName -> Type -> Ident [identName] :: Ident -> VName [identType] :: Ident -> Type -- | A subexpression is either a scalar constant or a variable. One -- important property is that evaluation of a subexpression is guaranteed -- to complete in constant time. data SubExp Constant :: PrimValue -> SubExp Var :: VName -> SubExp -- | A type alias for namespace control. type PatElem lore = PatElemT (LetDec lore) -- | An element of a pattern - consisting of a name and an addditional -- parametric decoration. This decoration is what is expected to contain -- the type of the resulting variable. data PatElemT dec PatElem :: VName -> dec -> PatElemT dec -- | The name being bound. [patElemName] :: PatElemT dec -> VName -- | Pattern element decoration. [patElemDec] :: PatElemT dec -> dec -- | A pattern is conceptually just a list of names and their types. data PatternT dec Pattern :: [PatElemT dec] -> [PatElemT dec] -> PatternT dec -- | existential context (sizes and memory blocks) [patternContextElements] :: PatternT dec -> [PatElemT dec] -- | "real" values [patternValueElements] :: PatternT dec -> [PatElemT dec] -- | A type alias for namespace control. type Pattern lore = PatternT (LetDec lore) -- | Auxilliary Information associated with a statement. data StmAux dec StmAux :: !Certificates -> Attrs -> dec -> StmAux dec [stmAuxCerts] :: StmAux dec -> !Certificates [stmAuxAttrs] :: StmAux dec -> Attrs [stmAuxDec] :: StmAux dec -> dec -- | A local variable binding. data Stm lore Let :: Pattern lore -> StmAux (ExpDec lore) -> Exp lore -> Stm lore -- | Pattern. [stmPattern] :: Stm lore -> Pattern lore -- | Auxiliary information statement. [stmAux] :: Stm lore -> StmAux (ExpDec lore) -- | Expression. [stmExp] :: Stm lore -> Exp lore -- | A sequence of statements. type Stms lore = Seq (Stm lore) -- | The result of a body is a sequence of subexpressions. type Result = [SubExp] -- | A body consists of a number of bindings, terminating in a result -- (essentially a tuple literal). data BodyT lore Body :: BodyDec lore -> Stms lore -> Result -> BodyT lore [bodyDec] :: BodyT lore -> BodyDec lore [bodyStms] :: BodyT lore -> Stms lore [bodyResult] :: BodyT lore -> Result -- | Type alias for namespace reasons. type Body = BodyT -- | A primitive operation that returns something of known size and does -- not itself contain any bindings. data BasicOp -- | A variable or constant. SubExp :: SubExp -> BasicOp -- | Semantically and operationally just identity, but is -- invisible/impenetrable to optimisations (hopefully). This is just a -- hack to avoid optimisation (so, to work around compiler limitations). Opaque :: SubExp -> BasicOp -- | Array literals, e.g., [ [1+x, 3], [2, 1+4] ]. Second arg is -- the element type of the rows of the array. Scalar operations ArrayLit :: [SubExp] -> Type -> BasicOp -- | Unary operation. UnOp :: UnOp -> SubExp -> BasicOp -- | Binary operation. BinOp :: BinOp -> SubExp -> SubExp -> BasicOp -- | Comparison - result type is always boolean. CmpOp :: CmpOp -> SubExp -> SubExp -> BasicOp -- | Conversion "casting". ConvOp :: ConvOp -> SubExp -> BasicOp -- | Turn a boolean into a certificate, halting the program with the given -- error message if the boolean is false. Assert :: SubExp -> ErrorMsg SubExp -> (SrcLoc, [SrcLoc]) -> BasicOp -- | The certificates for bounds-checking are part of the Stm. Index :: VName -> Slice SubExp -> BasicOp -- | An in-place update of the given array at the given position. Consumes -- the array. Update :: VName -> Slice SubExp -> SubExp -> BasicOp -- | concat0([1],[2, 3, 4]) = [1, 2, 3, 4]@. Concat :: Int -> VName -> [VName] -> SubExp -> BasicOp -- | Copy the given array. The result will not alias anything. Copy :: VName -> BasicOp -- | Manifest an array with dimensions represented in the given order. The -- result will not alias anything. Manifest :: [Int] -> VName -> BasicOp -- | iota(n, x, s) = [x,x+s,..,x+(n-1)*s]. -- -- The IntType indicates the type of the array returned and the -- offset/stride arguments, but not the length argument. Iota :: SubExp -> SubExp -> SubExp -> IntType -> BasicOp -- |
--   replicate([3][2],1) = [[1,1], [1,1], [1,1]]
--   
Replicate :: Shape -> SubExp -> BasicOp -- | Create array of given type and shape, with undefined elements. Scratch :: PrimType -> [SubExp] -> BasicOp -- | 1st arg is the new shape, 2nd arg is the input array *) Reshape :: ShapeChange SubExp -> VName -> BasicOp -- | Permute the dimensions of the input array. The list of integers is a -- list of dimensions (0-indexed), which must be a permutation of -- [0,n-1], where n is the number of dimensions in the -- input array. Rearrange :: [Int] -> VName -> BasicOp -- | Rotate the dimensions of the input array. The list of subexpressions -- specify how much each dimension is rotated. The length of this list -- must be equal to the rank of the array. Rotate :: [SubExp] -> VName -> BasicOp -- | Various unary operators. It is a bit ad-hoc what is a unary operator -- and what is a built-in function. Perhaps these should all go away -- eventually. data UnOp -- | E.g., ! True == False. Not :: UnOp -- | E.g., ~(~1) = 1. Complement :: IntType -> UnOp -- | abs(-2) = 2. Abs :: IntType -> UnOp -- | fabs(-2.0) = 2.0. FAbs :: FloatType -> UnOp -- | Signed sign function: ssignum(-2) = -1. SSignum :: IntType -> UnOp -- | Unsigned sign function: usignum(2) = 1. USignum :: IntType -> UnOp -- | Binary operators. These correspond closely to the binary operators in -- LLVM. Most are parametrised by their expected input and output types. data BinOp -- | Integer addition. Add :: IntType -> Overflow -> BinOp -- | Floating-point addition. FAdd :: FloatType -> BinOp -- | Integer subtraction. Sub :: IntType -> Overflow -> BinOp -- | Floating-point subtraction. FSub :: FloatType -> BinOp -- | Integer multiplication. Mul :: IntType -> Overflow -> BinOp -- | Floating-point multiplication. FMul :: FloatType -> BinOp -- | Unsigned integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. UDiv :: IntType -> Safety -> BinOp -- | Unsigned integer division. Rounds towards positive infinity. UDivUp :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. SDiv :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards positive infinity. SDivUp :: IntType -> Safety -> BinOp -- | Floating-point division. FDiv :: FloatType -> BinOp -- | Floating-point modulus. FMod :: FloatType -> BinOp -- | Unsigned integer modulus; the countepart to UDiv. UMod :: IntType -> Safety -> BinOp -- | Signed integer modulus; the countepart to SDiv. SMod :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- sdiv instruction in LLVM and integer division in C. SQuot :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- srem instruction in LLVM and integer modulo in C. SRem :: IntType -> Safety -> BinOp -- | Returns the smallest of two signed integers. SMin :: IntType -> BinOp -- | Returns the smallest of two unsigned integers. UMin :: IntType -> BinOp -- | Returns the smallest of two floating-point numbers. FMin :: FloatType -> BinOp -- | Returns the greatest of two signed integers. SMax :: IntType -> BinOp -- | Returns the greatest of two unsigned integers. UMax :: IntType -> BinOp -- | Returns the greatest of two floating-point numbers. FMax :: FloatType -> BinOp -- | Left-shift. Shl :: IntType -> BinOp -- | Logical right-shift, zero-extended. LShr :: IntType -> BinOp -- | Arithmetic right-shift, sign-extended. AShr :: IntType -> BinOp -- | Bitwise and. And :: IntType -> BinOp -- | Bitwise or. Or :: IntType -> BinOp -- | Bitwise exclusive-or. Xor :: IntType -> BinOp -- | Integer exponentiation. Pow :: IntType -> BinOp -- | Floating-point exponentiation. FPow :: FloatType -> BinOp -- | Boolean and - not short-circuiting. LogAnd :: BinOp -- | Boolean or - not short-circuiting. LogOr :: BinOp -- | Comparison operators are like BinOps, but they always return a -- boolean value. The somewhat ugly constructor names are straight out of -- LLVM. data CmpOp -- | All types equality. CmpEq :: PrimType -> CmpOp -- | Unsigned less than. CmpUlt :: IntType -> CmpOp -- | Unsigned less than or equal. CmpUle :: IntType -> CmpOp -- | Signed less than. CmpSlt :: IntType -> CmpOp -- | Signed less than or equal. CmpSle :: IntType -> CmpOp -- | Floating-point less than. FCmpLt :: FloatType -> CmpOp -- | Floating-point less than or equal. FCmpLe :: FloatType -> CmpOp -- | Boolean less than. CmpLlt :: CmpOp -- | Boolean less than or equal. CmpLle :: CmpOp -- | Conversion operators try to generalise the from t0 x to t1 -- instructions from LLVM. data ConvOp -- | Zero-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. ZExt :: IntType -> IntType -> ConvOp -- | Sign-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. SExt :: IntType -> IntType -> ConvOp -- | Convert value of the former floating-point type to the latter. If the -- new type is smaller, the result is a truncation. FPConv :: FloatType -> FloatType -> ConvOp -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). FPToUI :: FloatType -> IntType -> ConvOp -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). FPToSI :: FloatType -> IntType -> ConvOp -- | Convert an unsigned integer to a floating-point value. UIToFP :: IntType -> FloatType -> ConvOp -- | Convert a signed integer to a floating-point value. SIToFP :: IntType -> FloatType -> ConvOp -- | Convert an integer to a boolean value. Zero becomes false; anything -- else is true. IToB :: IntType -> ConvOp -- | Convert a boolean to an integer. True is converted to 1 and False to -- 0. BToI :: IntType -> ConvOp -- | The new dimension in a Reshape-like operation. This allows us -- to disambiguate "real" reshapes, that change the actual shape of the -- array, from type coercions that are just present to make the types -- work out. The two constructors are considered equal for purposes of -- Eq. data DimChange d -- | The new dimension is guaranteed to be numerically equal to the old -- one. DimCoercion :: d -> DimChange d -- | The new dimension is not necessarily numerically equal to the old one. DimNew :: d -> DimChange d -- | A list of DimChanges, indicating the new dimensions of an -- array. type ShapeChange d = [DimChange d] -- | The root Futhark expression type. The Op constructor contains a -- lore-specific operation. Do-loops, branches and function calls are -- special. Everything else is a simple BasicOp. data ExpT lore -- | A simple (non-recursive) operation. BasicOp :: BasicOp -> ExpT lore Apply :: Name -> [(SubExp, Diet)] -> [RetType lore] -> (Safety, SrcLoc, [SrcLoc]) -> ExpT lore If :: SubExp -> BodyT lore -> BodyT lore -> IfDec (BranchType lore) -> ExpT lore -- | loop {a} = {v} (for i < n|while b) do b. The merge -- parameters are divided into context and value part. DoLoop :: [(FParam lore, SubExp)] -> [(FParam lore, SubExp)] -> LoopForm lore -> BodyT lore -> ExpT lore Op :: Op lore -> ExpT lore -- | A type alias for namespace control. type Exp = ExpT -- | For-loop or while-loop? data LoopForm lore ForLoop :: VName -> IntType -> SubExp -> [(LParam lore, VName)] -> LoopForm lore WhileLoop :: VName -> LoopForm lore -- | Data associated with a branch. data IfDec rt IfDec :: [rt] -> IfSort -> IfDec rt [ifReturns] :: IfDec rt -> [rt] [ifSort] :: IfDec rt -> IfSort -- | What kind of branch is this? This has no semantic meaning, but -- provides hints to simplifications. data IfSort -- | An ordinary branch. IfNormal :: IfSort -- | A branch where the "true" case is what we are actually interested in, -- and the "false" case is only present as a fallback for when the true -- case cannot be safely evaluated. The compiler is permitted to optimise -- away the branch if the true case contains only safe statements. IfFallback :: IfSort -- | Both of these branches are semantically equivalent, and it is fine to -- eliminate one if it turns out to have problems (e.g. contain things we -- cannot generate code for). IfEquiv :: IfSort -- | Whether something is safe or unsafe (mostly function calls, and in the -- context of whether operations are dynamically checked). When we inline -- an Unsafe function, we remove all safety checks in its body. -- The Ord instance picks Unsafe as being less than -- Safe. -- -- For operations like integer division, a safe division will not explode -- the computer in case of division by zero, but instead return some -- unspecified value. This always involves a run-time check, so generally -- the unsafe variant is what the compiler will insert, but guarded by an -- explicit assertion elsewhere. Safe operations are useful when the -- optimiser wants to move e.g. a division to a location where the -- divisor may be zero, but where the result will only be used when it is -- non-zero (so it doesn't matter what result is provided with a zero -- divisor, as long as the program keeps running). data Safety Unsafe :: Safety Safe :: Safety -- | Anonymous function for use in a SOAC. data LambdaT lore Lambda :: [LParam lore] -> BodyT lore -> [Type] -> LambdaT lore [lambdaParams] :: LambdaT lore -> [LParam lore] [lambdaBody] :: LambdaT lore -> BodyT lore [lambdaReturnType] :: LambdaT lore -> [Type] -- | Type alias for namespacing reasons. type Lambda = LambdaT -- | A function or lambda parameter. data Param dec Param :: VName -> dec -> Param dec -- | Name of the parameter. [paramName] :: Param dec -> VName -- | Function parameter decoration. [paramDec] :: Param dec -> dec -- | A function and loop parameter. type FParam lore = Param (FParamInfo lore) -- | A lambda parameter. type LParam lore = Param (LParamInfo lore) -- | Function Declarations data FunDef lore FunDef :: Maybe EntryPoint -> Attrs -> Name -> [RetType lore] -> [FParam lore] -> BodyT lore -> FunDef lore -- | Contains a value if this function is an entry point. [funDefEntryPoint] :: FunDef lore -> Maybe EntryPoint [funDefAttrs] :: FunDef lore -> Attrs [funDefName] :: FunDef lore -> Name [funDefRetType] :: FunDef lore -> [RetType lore] [funDefParams] :: FunDef lore -> [FParam lore] [funDefBody] :: FunDef lore -> BodyT lore -- | Information about the parameters and return value of an entry point. -- The first element is for parameters, the second for return value. type EntryPoint = ([EntryPointType], [EntryPointType]) -- | Every entry point argument and return value has an annotation -- indicating how it maps to the original source program type. data EntryPointType -- | Is an unsigned integer or array of unsigned integers. TypeUnsigned :: EntryPointType -- | A black box type comprising this many core values. The string is a -- human-readable description with no other semantics. TypeOpaque :: String -> Int -> EntryPointType -- | Maps directly. TypeDirect :: EntryPointType -- | An entire Futhark program. data Prog lore Prog :: Stms lore -> [FunDef lore] -> Prog lore -- | Top-level constants that are computed at program startup, and which -- are in scope inside all functions. [progConsts] :: Prog lore -> Stms lore -- | The functions comprising the program. All funtions are also available -- in scope in the definitions of the constants, so be careful not to -- introduce circular dependencies (not currently checked). [progFuns] :: Prog lore -> [FunDef lore] -- | A single statement. oneStm :: Stm lore -> Stms lore -- | Convert a statement list to a statement sequence. stmsFromList :: [Stm lore] -> Stms lore -- | Convert a statement sequence to a statement list. stmsToList :: Stms lore -> [Stm lore] -- | The first statement in the sequence, if any. stmsHead :: Stms lore -> Maybe (Stm lore, Stms lore) instance GHC.Generics.Generic Futhark.IR.Syntax.Attr instance GHC.Classes.Eq Futhark.IR.Syntax.Attr instance GHC.Show.Show Futhark.IR.Syntax.Attr instance GHC.Classes.Ord Futhark.IR.Syntax.Attr instance GHC.Generics.Generic Futhark.IR.Syntax.Attrs instance GHC.Base.Semigroup Futhark.IR.Syntax.Attrs instance GHC.Base.Monoid Futhark.IR.Syntax.Attrs instance GHC.Classes.Eq Futhark.IR.Syntax.Attrs instance GHC.Show.Show Futhark.IR.Syntax.Attrs instance GHC.Classes.Ord Futhark.IR.Syntax.Attrs instance GHC.Generics.Generic (Futhark.IR.Syntax.PatternT dec) instance GHC.Classes.Eq dec => GHC.Classes.Eq (Futhark.IR.Syntax.PatternT dec) instance GHC.Show.Show dec => GHC.Show.Show (Futhark.IR.Syntax.PatternT dec) instance GHC.Classes.Ord dec => GHC.Classes.Ord (Futhark.IR.Syntax.PatternT dec) instance GHC.Generics.Generic (Futhark.IR.Syntax.StmAux dec) instance GHC.Classes.Eq dec => GHC.Classes.Eq (Futhark.IR.Syntax.StmAux dec) instance GHC.Show.Show dec => GHC.Show.Show (Futhark.IR.Syntax.StmAux dec) instance GHC.Classes.Ord dec => GHC.Classes.Ord (Futhark.IR.Syntax.StmAux dec) instance GHC.Generics.Generic (Futhark.IR.Syntax.DimChange d) instance GHC.Show.Show d => GHC.Show.Show (Futhark.IR.Syntax.DimChange d) instance GHC.Classes.Ord d => GHC.Classes.Ord (Futhark.IR.Syntax.DimChange d) instance GHC.Generics.Generic Futhark.IR.Syntax.BasicOp instance GHC.Show.Show Futhark.IR.Syntax.BasicOp instance GHC.Classes.Ord Futhark.IR.Syntax.BasicOp instance GHC.Classes.Eq Futhark.IR.Syntax.BasicOp instance GHC.Generics.Generic Futhark.IR.Syntax.IfSort instance GHC.Classes.Ord Futhark.IR.Syntax.IfSort instance GHC.Show.Show Futhark.IR.Syntax.IfSort instance GHC.Classes.Eq Futhark.IR.Syntax.IfSort instance GHC.Generics.Generic (Futhark.IR.Syntax.IfDec rt) instance GHC.Classes.Ord rt => GHC.Classes.Ord (Futhark.IR.Syntax.IfDec rt) instance GHC.Show.Show rt => GHC.Show.Show (Futhark.IR.Syntax.IfDec rt) instance GHC.Classes.Eq rt => GHC.Classes.Eq (Futhark.IR.Syntax.IfDec rt) instance GHC.Generics.Generic (Futhark.IR.Syntax.LoopForm lore) instance GHC.Generics.Generic (Futhark.IR.Syntax.Stm lore) instance GHC.Generics.Generic (Futhark.IR.Syntax.BodyT lore) instance GHC.Generics.Generic (Futhark.IR.Syntax.ExpT lore) instance GHC.Generics.Generic (Futhark.IR.Syntax.LambdaT lore) instance GHC.Generics.Generic Futhark.IR.Syntax.EntryPointType instance GHC.Classes.Ord Futhark.IR.Syntax.EntryPointType instance GHC.Show.Show Futhark.IR.Syntax.EntryPointType instance GHC.Classes.Eq Futhark.IR.Syntax.EntryPointType instance GHC.Generics.Generic (Futhark.IR.Syntax.FunDef lore) instance GHC.Generics.Generic (Futhark.IR.Syntax.Prog lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.Syntax.Prog lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.Syntax.Prog lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.Syntax.Prog lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.Syntax.Stm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.Syntax.Stm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.Syntax.Stm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.Syntax.BodyT lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.Syntax.BodyT lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.Syntax.BodyT lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.Syntax.ExpT lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.Syntax.ExpT lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.Syntax.ExpT lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.Syntax.LoopForm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.Syntax.LoopForm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.Syntax.LoopForm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.Syntax.LambdaT lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.Syntax.LambdaT lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.Syntax.LambdaT lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.Syntax.FunDef lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.Syntax.FunDef lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.Syntax.FunDef lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Prog lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.FunDef lore) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.EntryPointType instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.LambdaT lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Stm lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.Stms lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.BodyT lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.ExpT lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.LoopForm lore) instance Language.SexpGrammar.Class.SexpIso rt => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.IfDec rt) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.IfSort instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.BasicOp instance Language.SexpGrammar.Class.SexpIso d => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.DimChange d) instance GHC.Classes.Eq d => GHC.Classes.Eq (Futhark.IR.Syntax.DimChange d) instance GHC.Base.Functor Futhark.IR.Syntax.DimChange instance Data.Foldable.Foldable Futhark.IR.Syntax.DimChange instance Data.Traversable.Traversable Futhark.IR.Syntax.DimChange instance Language.SexpGrammar.Class.SexpIso dec => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.StmAux dec) instance GHC.Base.Semigroup dec => GHC.Base.Semigroup (Futhark.IR.Syntax.StmAux dec) instance Language.SexpGrammar.Class.SexpIso dec => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Syntax.PatternT dec) instance GHC.Base.Semigroup (Futhark.IR.Syntax.PatternT dec) instance GHC.Base.Monoid (Futhark.IR.Syntax.PatternT dec) instance GHC.Base.Functor Futhark.IR.Syntax.PatternT instance Data.Foldable.Foldable Futhark.IR.Syntax.PatternT instance Data.Traversable.Traversable Futhark.IR.Syntax.PatternT instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.Attrs instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Syntax.Attr instance Data.String.IsString Futhark.IR.Syntax.Attr -- | Facilities for creating, inspecting, and simplifying reshape and -- coercion operations. module Futhark.IR.Prop.Reshape -- | The new dimension. newDim :: DimChange d -> d -- | The new dimensions resulting from a reshape operation. newDims :: ShapeChange d -> [d] -- | The new shape resulting from a reshape operation. newShape :: ShapeChange SubExp -> Shape -- | Construct a Reshape where all dimension changes are -- DimCoercions. shapeCoerce :: [SubExp] -> VName -> Exp lore -- | reshapeOuter newshape n oldshape returns a Reshape -- expression that replaces the outer n dimensions of -- oldshape with newshape. reshapeOuter :: ShapeChange SubExp -> Int -> Shape -> ShapeChange SubExp -- | reshapeInner newshape n oldshape returns a Reshape -- expression that replaces the inner m-n dimensions (where -- m is the rank of oldshape) of src with -- newshape. reshapeInner :: ShapeChange SubExp -> Int -> Shape -> ShapeChange SubExp -- | If the shape change is nothing but shape coercions, return the new -- dimensions. Otherwise, return Nothing. shapeCoercion :: ShapeChange d -> Maybe [d] -- | fuseReshape s1 s2 creates a new ShapeChange that is -- semantically the same as first applying s1 and then -- s2. This may take advantage of properties of -- DimCoercion versus DimNew to preserve information. fuseReshape :: Eq d => ShapeChange d -> ShapeChange d -> ShapeChange d -- | Given concrete information about the shape of the source array, -- convert some DimNews into DimCoercions. informReshape :: Eq d => [d] -> ShapeChange d -> ShapeChange d -- | reshapeIndex to_dims from_dims is transforms the index list -- is (which is into an array of shape from_dims) into -- an index list is', which is into an array of shape -- to_dims. is must have the same length as -- from_dims, and is' will have the same length as -- to_dims. reshapeIndex :: IntegralExp num => [num] -> [num] -> [num] -> [num] -- | flattenIndex dims is computes the flat index of is -- into an array with dimensions dims. The length of -- dims and is must be the same. flattenIndex :: IntegralExp num => [num] -> [num] -> num -- | unflattenIndex dims i computes a list of indices into an -- array with dimension dims given the flat index i. -- The resulting list will have the same size as dims. unflattenIndex :: IntegralExp num => [num] -> num -> [num] -- | Given a length n list of dimensions dims, -- sizeSizes dims will compute a length n+1 list of the -- size of each possible array slice. The first element of this list will -- be the product of dims, and the last element will be 1. sliceSizes :: IntegralExp num => [num] -> [num] -- | Inspecing and modifying Patterns, function parameters and -- pattern elements. module Futhark.IR.Prop.Patterns -- | An Ident corresponding to a parameter. paramIdent :: Typed dec => Param dec -> Ident -- | The Type of a parameter. paramType :: Typed dec => Param dec -> Type -- | The DeclType of a parameter. paramDeclType :: DeclTyped dec => Param dec -> DeclType -- | An Ident corresponding to a pattern element. patElemIdent :: Typed dec => PatElemT dec -> Ident -- | The type of a name bound by a PatElem. patElemType :: Typed dec => PatElemT dec -> Type -- | Set the lore of a PatElem. setPatElemLore :: PatElemT oldattr -> newattr -> PatElemT newattr -- | All pattern elements in the pattern - context first, then values. patternElements :: PatternT dec -> [PatElemT dec] -- | Return a list of the Idents bound by the Pattern. patternIdents :: Typed dec => PatternT dec -> [Ident] -- | Return a list of the context Idents bound by the -- Pattern. patternContextIdents :: Typed dec => PatternT dec -> [Ident] -- | Return a list of the value Idents bound by the Pattern. patternValueIdents :: Typed dec => PatternT dec -> [Ident] -- | Return a list of the Names bound by the Pattern. patternNames :: PatternT dec -> [VName] -- | Return a list of the Names bound by the value part of the -- Pattern. patternValueNames :: PatternT dec -> [VName] -- | Return a list of the Names bound by the context part of the -- Pattern. patternContextNames :: PatternT dec -> [VName] -- | Return a list of the typess bound by the pattern. patternTypes :: Typed dec => PatternT dec -> [Type] -- | Return a list of the typess bound by the value part of the pattern. patternValueTypes :: Typed dec => PatternT dec -> [Type] -- | Return the number of names bound by the pattern. patternSize :: PatternT dec -> Int -- | Create a pattern using Type as the attribute. basicPattern :: [Ident] -> [Ident] -> PatternT Type -- | Futhark prettyprinter. This module defines Pretty instances for -- the AST defined in Futhark.IR.Syntax, but also a number of -- convenience functions if you don't want to use the interface from -- Pretty. module Futhark.IR.Pretty -- | Prettyprint a list enclosed in curly braces. prettyTuple :: Pretty a => [a] -> String -- | Prettyprint a value, wrapped to 80 characters. pretty :: Pretty a => a -> String -- | Class for values that may have some prettyprinted annotation. class PrettyAnnot a ppAnnot :: PrettyAnnot a => a -> Maybe Doc -- | The class of lores whose annotations can be prettyprinted. class (Decorations lore, Pretty (RetType lore), Pretty (BranchType lore), Pretty (Param (FParamInfo lore)), Pretty (Param (LParamInfo lore)), Pretty (PatElemT (LetDec lore)), PrettyAnnot (PatElem lore), PrettyAnnot (FParam lore), PrettyAnnot (LParam lore), Pretty (Op lore)) => PrettyLore lore ppExpLore :: PrettyLore lore => ExpDec lore -> Exp lore -> Maybe Doc -- | Like prettyTuple, but produces a Doc. ppTuple' :: Pretty a => [a] -> Doc instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Stms lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Body lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Stm lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Exp lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Lambda lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.FunDef lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Prog lore) instance Futhark.IR.Pretty.PrettyAnnot (Futhark.IR.Syntax.Core.PatElemT (Futhark.IR.Syntax.Core.TypeBase shape u)) instance Futhark.IR.Pretty.PrettyAnnot (Futhark.IR.Syntax.Core.Param (Futhark.IR.Syntax.Core.TypeBase shape u)) instance Futhark.IR.Pretty.PrettyAnnot () instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Core.VName instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Syntax.Core.NoUniqueness instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Core.Commutativity instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Syntax.Core.Shape instance Text.PrettyPrint.Mainland.Class.Pretty a => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.Ext a) instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Syntax.Core.ExtShape instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Syntax.Core.Space instance Text.PrettyPrint.Mainland.Class.Pretty u => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.TypeBase Futhark.IR.Syntax.Core.Shape u) instance Text.PrettyPrint.Mainland.Class.Pretty u => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.TypeBase Futhark.IR.Syntax.Core.ExtShape u) instance Text.PrettyPrint.Mainland.Class.Pretty u => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.TypeBase Futhark.IR.Syntax.Core.Rank u) instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Syntax.Core.Ident instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Syntax.Core.SubExp instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Syntax.Core.Certificates instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Syntax.Attr instance Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.PatElemT dec) => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.PatternT dec) instance Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.PatElemT b) => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.PatElemT (a, b)) instance Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.PatElemT Futhark.IR.Syntax.Core.Type) instance Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.Param b) => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.Param (a, b)) instance Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.Param Futhark.IR.Syntax.Core.DeclType) instance Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.Param Futhark.IR.Syntax.Core.Type) instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Syntax.BasicOp instance Text.PrettyPrint.Mainland.Class.Pretty a => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.ErrorMsg a) instance Text.PrettyPrint.Mainland.Class.Pretty d => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.DimChange d) instance Text.PrettyPrint.Mainland.Class.Pretty d => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.DimIndex d) -- | The core Futhark AST does not contain type information when we use a -- variable. Therefore, most transformations expect to be able to access -- some kind of symbol table that maps names to their types. -- -- This module defines the concept of a type environment as a mapping -- from variable names to NameInfos. Convenience facilities are -- also provided to communicate that some monad or applicative functor -- maintains type information. module Futhark.IR.Prop.Scope -- | The class of applicative functors (or more common in practice: monads) -- that permit the lookup of variable types. A default method for -- lookupType exists, which is sufficient (if not always maximally -- efficient, and using error to fail) when askScope is -- defined. class (Applicative m, Decorations lore) => HasScope lore m | m -> lore -- | Return the type of the given variable, or fail if it is not in the -- type environment. lookupType :: HasScope lore m => VName -> m Type -- | Return the info of the given variable, or fail if it is not in the -- type environment. lookupInfo :: HasScope lore m => VName -> m (NameInfo lore) -- | Return the type environment contained in the applicative functor. askScope :: HasScope lore m => m (Scope lore) -- | Return the result of applying some function to the type environment. asksScope :: HasScope lore m => (Scope lore -> a) -> m a -- | How some name in scope was bound. data NameInfo lore LetName :: LetDec lore -> NameInfo lore FParamName :: FParamInfo lore -> NameInfo lore LParamName :: LParamInfo lore -> NameInfo lore IndexName :: IntType -> NameInfo lore -- | The class of monads that not only provide a Scope, but also the -- ability to locally extend it. A Reader containing a -- Scope is the prototypical example of such a monad. class (HasScope lore m, Monad m) => LocalScope lore m -- | Run a computation with an extended type environment. Note that this is -- intended to *add* to the current type environment, it does not replace -- it. localScope :: LocalScope lore m => Scope lore -> m a -> m a -- | A scope is a mapping from variable names to information about that -- name. type Scope lore = Map VName (NameInfo lore) -- | The class of things that can provide a scope. There is no overarching -- rule for what this means. For a Stm, it is the corresponding -- pattern. For a Lambda, is is the parameters. class Scoped lore a | a -> lore scopeOf :: Scoped lore a => a -> Scope lore -- | Extend the monadic scope with the scopeOf the given value. inScopeOf :: (Scoped lore a, LocalScope lore m) => a -> m b -> m b -- | The scope of some lambda parameters. scopeOfLParams :: LParamInfo lore ~ dec => [Param dec] -> Scope lore -- | The scope of some function or loop parameters. scopeOfFParams :: FParamInfo lore ~ dec => [Param dec] -> Scope lore -- | The scope of a pattern. scopeOfPattern :: LetDec lore ~ dec => PatternT dec -> Scope lore -- | The scope of a pattern element. scopeOfPatElem :: LetDec lore ~ dec => PatElemT dec -> Scope lore -- | A constraint that indicates two lores have the same NameInfo -- representation. type SameScope lore1 lore2 = (LetDec lore1 ~ LetDec lore2, FParamInfo lore1 ~ FParamInfo lore2, LParamInfo lore1 ~ LParamInfo lore2) -- | If two scopes are really the same, then you can convert one to the -- other. castScope :: SameScope fromlore tolore => Scope fromlore -> Scope tolore -- | A monad transformer that carries around an extended Scope. Its -- lookupType method will first look in the extended Scope, -- and then use the lookupType method of the underlying monad. data ExtendedScope lore m a -- | Run a computation in the extended type environment. extendedScope :: ExtendedScope lore m a -> Scope lore -> m a instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (Futhark.IR.Prop.Scope.Scope lore) (Futhark.IR.Prop.Scope.ExtendedScope lore m) instance GHC.Base.Monad m => GHC.Base.Monad (Futhark.IR.Prop.Scope.ExtendedScope lore m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Futhark.IR.Prop.Scope.ExtendedScope lore m) instance GHC.Base.Functor m => GHC.Base.Functor (Futhark.IR.Prop.Scope.ExtendedScope lore m) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.Prop.Scope.NameInfo lore) instance (Futhark.IR.Prop.Scope.HasScope lore m, GHC.Base.Monad m) => Futhark.IR.Prop.Scope.HasScope lore (Futhark.IR.Prop.Scope.ExtendedScope lore m) instance Futhark.IR.Prop.Scope.Scoped lore a => Futhark.IR.Prop.Scope.Scoped lore [a] instance Futhark.IR.Prop.Scope.Scoped lore (Futhark.IR.Syntax.Stms lore) instance Futhark.IR.Prop.Scope.Scoped lore (Futhark.IR.Syntax.Stm lore) instance Futhark.IR.Prop.Scope.Scoped lore (Futhark.IR.Syntax.FunDef lore) instance Futhark.IR.Prop.Scope.Scoped lore (Language.Futhark.Core.VName, Futhark.IR.Prop.Scope.NameInfo lore) instance Futhark.IR.Prop.Scope.Scoped lore (Futhark.IR.Syntax.LoopForm lore) instance Futhark.IR.Prop.Scope.Scoped lore (Futhark.IR.Syntax.Lambda lore) instance (GHC.Base.Monad m, Futhark.IR.Prop.Scope.LocalScope lore m) => Futhark.IR.Prop.Scope.LocalScope lore (Control.Monad.Trans.Except.ExceptT e m) instance (GHC.Base.Applicative m, GHC.Base.Monad m, Futhark.IR.Decorations.Decorations lore) => Futhark.IR.Prop.Scope.LocalScope lore (Control.Monad.Trans.Reader.ReaderT (Futhark.IR.Prop.Scope.Scope lore) m) instance (GHC.Base.Applicative m, GHC.Base.Monad m, GHC.Base.Monoid w, Futhark.IR.Decorations.Decorations lore) => Futhark.IR.Prop.Scope.LocalScope lore (Control.Monad.Trans.RWS.Strict.RWST (Futhark.IR.Prop.Scope.Scope lore) w s m) instance (GHC.Base.Applicative m, GHC.Base.Monad m, GHC.Base.Monoid w, Futhark.IR.Decorations.Decorations lore) => Futhark.IR.Prop.Scope.LocalScope lore (Control.Monad.Trans.RWS.Lazy.RWST (Futhark.IR.Prop.Scope.Scope lore) w s m) instance (GHC.Base.Applicative m, GHC.Base.Monad m, Futhark.IR.Decorations.Decorations lore) => Futhark.IR.Prop.Scope.HasScope lore (Control.Monad.Trans.Reader.ReaderT (Futhark.IR.Prop.Scope.Scope lore) m) instance (GHC.Base.Monad m, Futhark.IR.Prop.Scope.HasScope lore m) => Futhark.IR.Prop.Scope.HasScope lore (Control.Monad.Trans.Except.ExceptT e m) instance (GHC.Base.Applicative m, GHC.Base.Monad m, GHC.Base.Monoid w, Futhark.IR.Decorations.Decorations lore) => Futhark.IR.Prop.Scope.HasScope lore (Control.Monad.Trans.RWS.Strict.RWST (Futhark.IR.Prop.Scope.Scope lore) w s m) instance (GHC.Base.Applicative m, GHC.Base.Monad m, GHC.Base.Monoid w, Futhark.IR.Decorations.Decorations lore) => Futhark.IR.Prop.Scope.HasScope lore (Control.Monad.Trans.RWS.Lazy.RWST (Futhark.IR.Prop.Scope.Scope lore) w s m) instance Futhark.IR.Decorations.Decorations lore => Futhark.IR.Prop.Types.Typed (Futhark.IR.Prop.Scope.NameInfo lore) -- | Functions for generic traversals across Futhark syntax trees. The -- motivation for this module came from dissatisfaction with rewriting -- the same trivial tree recursions for every module. A possible -- alternative would be to use normal "Scrap your -- boilerplate"-techniques, but these are rejected for two reasons: -- -- -- -- Instead, this module defines various traversals of the Futhark syntax -- tree. The implementation is rather tedious, but the interface is easy -- to use. -- -- A traversal of the Futhark syntax tree is expressed as a record of -- functions expressing the operations to be performed on the various -- types of nodes. -- -- The Futhark.Transform.Rename module is a simple example of how -- to use this facility. module Futhark.IR.Traversals -- | Express a monad mapping operation on a syntax node. Each element of -- this structure expresses the operation to be performed on a given -- child. data Mapper flore tlore m Mapper :: (SubExp -> m SubExp) -> (Scope tlore -> Body flore -> m (Body tlore)) -> (VName -> m VName) -> (RetType flore -> m (RetType tlore)) -> (BranchType flore -> m (BranchType tlore)) -> (FParam flore -> m (FParam tlore)) -> (LParam flore -> m (LParam tlore)) -> (Op flore -> m (Op tlore)) -> Mapper flore tlore m [mapOnSubExp] :: Mapper flore tlore m -> SubExp -> m SubExp -- | Most bodies are enclosed in a scope, which is passed along for -- convenience. [mapOnBody] :: Mapper flore tlore m -> Scope tlore -> Body flore -> m (Body tlore) [mapOnVName] :: Mapper flore tlore m -> VName -> m VName [mapOnRetType] :: Mapper flore tlore m -> RetType flore -> m (RetType tlore) [mapOnBranchType] :: Mapper flore tlore m -> BranchType flore -> m (BranchType tlore) [mapOnFParam] :: Mapper flore tlore m -> FParam flore -> m (FParam tlore) [mapOnLParam] :: Mapper flore tlore m -> LParam flore -> m (LParam tlore) [mapOnOp] :: Mapper flore tlore m -> Op flore -> m (Op tlore) -- | A mapper that simply returns the tree verbatim. identityMapper :: Monad m => Mapper lore lore m -- | Map a monadic action across the immediate children of an expression. -- Importantly, the mapping does not descend recursively into -- subexpressions. The mapping is done left-to-right. mapExpM :: (Applicative m, Monad m) => Mapper flore tlore m -> Exp flore -> m (Exp tlore) -- | Like mapExpM, but in the Identity monad. mapExp :: Mapper flore tlore Identity -> Exp flore -> Exp tlore -- | Express a monad expression on a syntax node. Each element of this -- structure expresses the action to be performed on a given child. data Walker lore m Walker :: (SubExp -> m ()) -> (Scope lore -> Body lore -> m ()) -> (VName -> m ()) -> (RetType lore -> m ()) -> (BranchType lore -> m ()) -> (FParam lore -> m ()) -> (LParam lore -> m ()) -> (Op lore -> m ()) -> Walker lore m [walkOnSubExp] :: Walker lore m -> SubExp -> m () [walkOnBody] :: Walker lore m -> Scope lore -> Body lore -> m () [walkOnVName] :: Walker lore m -> VName -> m () [walkOnRetType] :: Walker lore m -> RetType lore -> m () [walkOnBranchType] :: Walker lore m -> BranchType lore -> m () [walkOnFParam] :: Walker lore m -> FParam lore -> m () [walkOnLParam] :: Walker lore m -> LParam lore -> m () [walkOnOp] :: Walker lore m -> Op lore -> m () -- | A no-op traversal. identityWalker :: Monad m => Walker lore m -- | As mapExpM, but do not construct a result AST. walkExpM :: Monad m => Walker lore m -> Exp lore -> m () -- | This module provides facilities for obtaining the types of various -- Futhark constructs. Typically, you will need to execute these in a -- context where type information is available as a Scope; usually -- by using a monad that is an instance of HasScope. The -- information is returned as a list of ExtType values - one for -- each of the values the Futhark construct returns. Some constructs -- (such as subexpressions) can produce only a single value, and their -- typing functions hence do not return a list. -- -- Some representations may have more specialised facilities enabling -- even more information - for example, Futhark.IR.Mem exposes -- functionality for also obtaining information about the storage -- location of results. module Futhark.IR.Prop.TypeOf -- | The type of an expression. expExtType :: (HasScope lore m, TypedOp (Op lore)) => Exp lore -> m [ExtType] -- | The number of values returned by an expression. expExtTypeSize :: (Decorations lore, TypedOp (Op lore)) => Exp lore -> Int -- | The type of a subexpression. subExpType :: HasScope t m => SubExp -> m Type -- | The type of a primitive operation. primOpType :: HasScope lore m => BasicOp -> m [Type] -- | mapType f arrts wraps each element in the return type of -- f in an array with size equal to the outermost dimension of -- the first element of arrts. mapType :: SubExp -> Lambda lore -> [Type] -- | Any operation must define an instance of this class, which describes -- the type of the operation (at the value level). class TypedOp op opType :: (TypedOp op, HasScope t m) => op -> m [ExtType] instance Futhark.IR.Prop.TypeOf.TypedOp () instance GHC.Base.Functor (Futhark.IR.Prop.TypeOf.FeelBad lore) instance GHC.Base.Applicative (Futhark.IR.Prop.TypeOf.FeelBad lore) instance Futhark.IR.Decorations.Decorations lore => Futhark.IR.Prop.Scope.HasScope lore (Futhark.IR.Prop.TypeOf.FeelBad lore) -- | Facilities for determining which names are used in some syntactic -- construct. The most important interface is the FreeIn class and -- its instances, but for reasons related to the Haskell type system, -- some constructs have specialised functions. module Futhark.IR.Prop.Names -- | A set of names. Note that the Ord instance is a dummy that -- treats everything as EQ if ==, and otherwise LT. data Names -- | Retrieve the data structure underlying the names representation. namesIntMap :: Names -> IntMap VName -- | Does the set of names contain this name? nameIn :: VName -> Names -> Bool -- | Construct a name set from a single name. oneName :: VName -> Names -- | Construct a name set from a list. Slow. namesFromList :: [VName] -> Names -- | Turn a name set into a list of names. Slow. namesToList :: Names -> [VName] -- | The intersection of two name sets. namesIntersection :: Names -> Names -> Names -- | Do the two name sets intersect? namesIntersect :: Names -> Names -> Bool -- | Subtract the latter name set from the former. namesSubtract :: Names -> Names -> Names -- | Map over the names in a set. mapNames :: (VName -> VName) -> Names -> Names -- | A class indicating that we can obtain free variable information from -- values of this type. class FreeIn a freeIn' :: FreeIn a => a -> FV -- | The free variables of some syntactic construct. freeIn :: FreeIn a => a -> Names -- | Return the set of variable names that are free in the given statements -- and result. Filters away the names that are bound by the statements. freeInStmsAndRes :: (FreeIn (Op lore), FreeIn (LetDec lore), FreeIn (LParamInfo lore), FreeIn (FParamInfo lore), FreeDec (BodyDec lore), FreeDec (ExpDec lore)) => Stms lore -> Result -> FV -- | The names bound by the bindings immediately in a Body. boundInBody :: Body lore -> Names -- | The names bound by a binding. boundByStm :: Stm lore -> Names -- | The names bound by the bindings. boundByStms :: Stms lore -> Names -- | The names of the lambda parameters plus the index parameter. boundByLambda :: Lambda lore -> [VName] -- | Either return precomputed free names stored in the attribute, or the -- freshly computed names. Relies on lazy evaluation to avoid the work. class FreeIn dec => FreeDec dec precomputed :: FreeDec dec => dec -> FV -> FV -- | A computation to build a free variable set. data FV -- | Consider a variable to be bound in the given FV computation. fvBind :: Names -> FV -> FV -- | Take note of a variable reference. fvName :: VName -> FV -- | Take note of a set of variable references. fvNames :: Names -> FV instance GHC.Generics.Generic Futhark.IR.Prop.Names.Names instance GHC.Show.Show Futhark.IR.Prop.Names.Names instance GHC.Classes.Eq Futhark.IR.Prop.Names.Names instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.ExpDec lore), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.BodyDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.FParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LetDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.RetType lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.FunDef lore) instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.ExpDec lore), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.BodyDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.FParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LetDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Lambda lore) instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.ExpDec lore), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.BodyDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.FParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LetDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Body lore) instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.ExpDec lore), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.BodyDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.FParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LetDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Exp lore) instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.ExpDec lore), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Decorations.BodyDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.FParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LParamInfo lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LetDec lore), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Stm lore) instance Futhark.IR.Prop.Names.FreeDec () instance (Futhark.IR.Prop.Names.FreeDec a, Futhark.IR.Prop.Names.FreeIn b) => Futhark.IR.Prop.Names.FreeDec (a, b) instance Futhark.IR.Prop.Names.FreeDec a => Futhark.IR.Prop.Names.FreeDec [a] instance Futhark.IR.Prop.Names.FreeDec a => Futhark.IR.Prop.Names.FreeDec (GHC.Maybe.Maybe a) instance Futhark.IR.Prop.Names.FreeDec Futhark.IR.Prop.Names.Names instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Prop.Names.FV instance Futhark.IR.Prop.Names.FreeIn () instance Futhark.IR.Prop.Names.FreeIn GHC.Types.Int instance (Futhark.IR.Prop.Names.FreeIn a, Futhark.IR.Prop.Names.FreeIn b) => Futhark.IR.Prop.Names.FreeIn (a, b) instance (Futhark.IR.Prop.Names.FreeIn a, Futhark.IR.Prop.Names.FreeIn b, Futhark.IR.Prop.Names.FreeIn c) => Futhark.IR.Prop.Names.FreeIn (a, b, c) instance Futhark.IR.Prop.Names.FreeIn a => Futhark.IR.Prop.Names.FreeIn [a] instance Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Stm lore) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Stms lore) instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Prop.Names.Names instance Futhark.IR.Prop.Names.FreeIn GHC.Types.Bool instance Futhark.IR.Prop.Names.FreeIn a => Futhark.IR.Prop.Names.FreeIn (GHC.Maybe.Maybe a) instance Futhark.IR.Prop.Names.FreeIn Language.Futhark.Core.VName instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Syntax.Core.Ident instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Syntax.Core.SubExp instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Syntax.Core.Space instance Futhark.IR.Prop.Names.FreeIn d => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.ShapeBase d) instance Futhark.IR.Prop.Names.FreeIn d => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.Ext d) instance Futhark.IR.Prop.Names.FreeIn shape => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.TypeBase shape u) instance Futhark.IR.Prop.Names.FreeIn dec => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.Param dec) instance Futhark.IR.Prop.Names.FreeIn dec => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.PatElemT dec) instance Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LParamInfo lore) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.LoopForm lore) instance Futhark.IR.Prop.Names.FreeIn d => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.DimChange d) instance Futhark.IR.Prop.Names.FreeIn d => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.DimIndex d) instance Futhark.IR.Prop.Names.FreeIn dec => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.PatternT dec) instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Syntax.Core.Certificates instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Syntax.Attrs instance Futhark.IR.Prop.Names.FreeIn dec => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.StmAux dec) instance Futhark.IR.Prop.Names.FreeIn a => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.IfDec a) instance GHC.Base.Monoid Futhark.IR.Prop.Names.FV instance GHC.Base.Semigroup Futhark.IR.Prop.Names.FV instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Prop.Names.Names instance GHC.Classes.Ord Futhark.IR.Prop.Names.Names instance GHC.Base.Semigroup Futhark.IR.Prop.Names.Names instance GHC.Base.Monoid Futhark.IR.Prop.Names.Names instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Prop.Names.Names -- | A primitive expression is an expression where the non-leaves are -- primitive operators. Our representation does not guarantee that the -- expression is type-correct. module Futhark.Analysis.PrimExp -- | A primitive expression parametrised over the representation of free -- variables. Note that the Functor, Traversable, and -- Num instances perform automatic (but simple) constant folding. -- -- Note also that the Num instance assumes OverflowUndef -- semantics! data PrimExp v LeafExp :: v -> PrimType -> PrimExp v ValueExp :: PrimValue -> PrimExp v BinOpExp :: BinOp -> PrimExp v -> PrimExp v -> PrimExp v CmpOpExp :: CmpOp -> PrimExp v -> PrimExp v -> PrimExp v UnOpExp :: UnOp -> PrimExp v -> PrimExp v ConvOpExp :: ConvOp -> PrimExp v -> PrimExp v FunExp :: String -> [PrimExp v] -> PrimType -> PrimExp v -- | A PrimExp tagged with a phantom type used to provide type-safe -- construction. Does not guarantee that the underlying expression is -- actually type correct. newtype TPrimExp t v TPrimExp :: PrimExp v -> TPrimExp t v [untyped] :: TPrimExp t v -> PrimExp v -- | This expression is of type Int8. isInt8 :: PrimExp v -> TPrimExp Int8 v -- | This expression is of type Int16. isInt16 :: PrimExp v -> TPrimExp Int16 v -- | This expression is of type Int32. isInt32 :: PrimExp v -> TPrimExp Int32 v -- | This expression is of type Int64. isInt64 :: PrimExp v -> TPrimExp Int64 v -- | This is a boolean expression. isBool :: PrimExp v -> TPrimExp Bool v -- | This expression is of type Float. isF32 :: PrimExp v -> TPrimExp Float v -- | This expression is of type Double. isF64 :: PrimExp v -> TPrimExp Double v -- | Evaluate a PrimExp in the given monad. Invokes fail on -- type errors. evalPrimExp :: (Pretty v, MonadFail m) => (v -> m PrimValue) -> PrimExp v -> m PrimValue -- | The type of values returned by a PrimExp. This function -- returning does not imply that the PrimExp is type-correct. primExpType :: PrimExp v -> PrimType -- | True if the PrimExp has at least this many nodes. This can be -- much more efficient than comparing with length for large -- PrimExps, as this function is lazy. primExpSizeAtLeast :: Int -> PrimExp v -> Bool -- | If the given PrimExp is a constant of the wrong integer type, -- coerce it to the given integer type. This is a workaround for an issue -- in the Num instance. coerceIntPrimExp :: IntType -> PrimExp v -> PrimExp v -- | Produce a mapping from the leaves of the PrimExp to their -- designated types. leafExpTypes :: Ord a => PrimExp a -> Set (a, PrimType) -- | Boolean-valued PrimExps. true :: TPrimExp Bool v -- | Boolean-valued PrimExps. false :: TPrimExp Bool v -- | Perform quick and dirty constant folding on the top level of a -- PrimExp. This is necessary because we want to consider e.g. equality -- modulo constant folding. constFoldPrimExp :: PrimExp v -> PrimExp v -- | The class of numeric types that can be used for constructing -- TPrimExps. class NumExp t -- | Construct a typed expression from an integer. fromInteger' :: NumExp t => Integer -> TPrimExp t v -- | The class of integer types that can be used for constructing -- TPrimExps. class NumExp t => IntExp t -- | The class of floating-point types that can be used for constructing -- TPrimExps. class NumExp t => FloatExp t -- | Construct a typed expression from a rational. fromRational' :: FloatExp t => Rational -> TPrimExp t v -- | Untyped smart constructor for sign extension that does a bit of -- constant folding. sExt :: IntType -> PrimExp v -> PrimExp v -- | Untyped smart constructor for zero extension that does a bit of -- constant folding. zExt :: IntType -> PrimExp v -> PrimExp v -- | Lifted logical conjunction. (.&&.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 3 .&&. -- | Lifted logical conjunction. (.||.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 2 .||. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<=. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>=. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.==.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .==. -- | Lifted bitwise operators. (.&.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.|.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.^.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Boolean negation smart constructor. bNot :: TPrimExp Bool v -> TPrimExp Bool v -- | SMax on 32-bit integers. sMax32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMin on 32-bit integers. sMin32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMax on 64-bit integers. sMax64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | SMin on 64-bit integers. sMin64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | Sign-extend to 32 bit integer. sExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Sign-extend to 64 bit integer. sExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | Zero-extend to 32 bit integer. zExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Zero-extend to 64 bit integer. zExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | 64-bit float minimum. fMin64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v -- | 64-bit float maximum. fMax64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v instance GHC.Generics.Generic (Futhark.Analysis.PrimExp.PrimExp v) instance GHC.Show.Show v => GHC.Show.Show (Futhark.Analysis.PrimExp.PrimExp v) instance GHC.Classes.Ord v => GHC.Classes.Ord (Futhark.Analysis.PrimExp.PrimExp v) instance GHC.Classes.Eq v => GHC.Classes.Eq (Futhark.Analysis.PrimExp.PrimExp v) instance GHC.Generics.Generic (Futhark.Analysis.PrimExp.TPrimExp t v) instance GHC.Show.Show v => GHC.Show.Show (Futhark.Analysis.PrimExp.TPrimExp t v) instance GHC.Classes.Ord v => GHC.Classes.Ord (Futhark.Analysis.PrimExp.TPrimExp t v) instance GHC.Classes.Eq v => GHC.Classes.Eq (Futhark.Analysis.PrimExp.TPrimExp t v) instance Futhark.Analysis.PrimExp.FloatExp GHC.Types.Float instance Futhark.Analysis.PrimExp.FloatExp GHC.Types.Double instance (Futhark.Analysis.PrimExp.FloatExp t, Text.PrettyPrint.Mainland.Class.Pretty v) => GHC.Real.Fractional (Futhark.Analysis.PrimExp.TPrimExp t v) instance Futhark.Analysis.PrimExp.IntExp GHC.Int.Int8 instance Futhark.Analysis.PrimExp.IntExp GHC.Int.Int16 instance Futhark.Analysis.PrimExp.IntExp GHC.Int.Int32 instance Futhark.Analysis.PrimExp.IntExp GHC.Int.Int64 instance (Futhark.Analysis.PrimExp.IntExp t, Text.PrettyPrint.Mainland.Class.Pretty v) => Futhark.Util.IntegralExp.IntegralExp (Futhark.Analysis.PrimExp.TPrimExp t v) instance Futhark.Analysis.PrimExp.NumExp GHC.Int.Int8 instance Futhark.Analysis.PrimExp.NumExp GHC.Int.Int16 instance Futhark.Analysis.PrimExp.NumExp GHC.Int.Int32 instance Futhark.Analysis.PrimExp.NumExp GHC.Int.Int64 instance Futhark.Analysis.PrimExp.NumExp GHC.Types.Float instance Futhark.Analysis.PrimExp.NumExp GHC.Types.Double instance (Futhark.Analysis.PrimExp.NumExp t, Text.PrettyPrint.Mainland.Class.Pretty v) => GHC.Num.Num (Futhark.Analysis.PrimExp.TPrimExp t v) instance Language.SexpGrammar.Class.SexpIso v => Language.SexpGrammar.Class.SexpIso (Futhark.Analysis.PrimExp.TPrimExp t v) instance GHC.Base.Functor (Futhark.Analysis.PrimExp.TPrimExp t) instance Data.Foldable.Foldable (Futhark.Analysis.PrimExp.TPrimExp t) instance Data.Traversable.Traversable (Futhark.Analysis.PrimExp.TPrimExp t) instance Futhark.IR.Prop.Names.FreeIn v => Futhark.IR.Prop.Names.FreeIn (Futhark.Analysis.PrimExp.TPrimExp t v) instance Text.PrettyPrint.Mainland.Class.Pretty v => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.Analysis.PrimExp.TPrimExp t v) instance Language.SexpGrammar.Class.SexpIso v => Language.SexpGrammar.Class.SexpIso (Futhark.Analysis.PrimExp.PrimExp v) instance GHC.Base.Functor Futhark.Analysis.PrimExp.PrimExp instance Data.Foldable.Foldable Futhark.Analysis.PrimExp.PrimExp instance Data.Traversable.Traversable Futhark.Analysis.PrimExp.PrimExp instance Futhark.IR.Prop.Names.FreeIn v => Futhark.IR.Prop.Names.FreeIn (Futhark.Analysis.PrimExp.PrimExp v) instance Text.PrettyPrint.Mainland.Class.Pretty v => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.Analysis.PrimExp.PrimExp v) -- | This module contains facilities for replacing variable names in -- syntactic constructs. module Futhark.Transform.Substitute -- | The substitutions to be made are given by a mapping from names to -- names. type Substitutions = Map VName VName -- | A type that is an instance of this class supports substitution of any -- names contained within. class Substitute a -- | substituteNames m e replaces the variable names in e -- with new names, based on the mapping in m. It is assumed that -- all names in e are unique, i.e. there is no shadowing. substituteNames :: Substitute a => Map VName VName -> a -> a -- | Lores in which all annotations support name substitution. type Substitutable lore = (Decorations lore, Substitute (ExpDec lore), Substitute (BodyDec lore), Substitute (LetDec lore), Substitute (FParamInfo lore), Substitute (LParamInfo lore), Substitute (RetType lore), Substitute (BranchType lore), Substitute (Op lore)) instance Futhark.Transform.Substitute.Substitutable lore => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Exp lore) instance Futhark.Transform.Substitute.Substitutable lore => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Stm lore) instance Futhark.Transform.Substitute.Substitutable lore => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Body lore) instance Futhark.Transform.Substitute.Substitutable lore => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Lambda lore) instance Futhark.Transform.Substitute.Substitutable lore => Futhark.Transform.Substitute.Substitute (Futhark.IR.Prop.Scope.NameInfo lore) instance Futhark.Transform.Substitute.Substitute a => Futhark.Transform.Substitute.Substitute [a] instance Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Stm lore) => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Stms lore) instance (Futhark.Transform.Substitute.Substitute a, Futhark.Transform.Substitute.Substitute b) => Futhark.Transform.Substitute.Substitute (a, b) instance (Futhark.Transform.Substitute.Substitute a, Futhark.Transform.Substitute.Substitute b, Futhark.Transform.Substitute.Substitute c) => Futhark.Transform.Substitute.Substitute (a, b, c) instance (Futhark.Transform.Substitute.Substitute a, Futhark.Transform.Substitute.Substitute b, Futhark.Transform.Substitute.Substitute c, Futhark.Transform.Substitute.Substitute d) => Futhark.Transform.Substitute.Substitute (a, b, c, d) instance Futhark.Transform.Substitute.Substitute a => Futhark.Transform.Substitute.Substitute (GHC.Maybe.Maybe a) instance Futhark.Transform.Substitute.Substitute GHC.Types.Bool instance Futhark.Transform.Substitute.Substitute Language.Futhark.Core.VName instance Futhark.Transform.Substitute.Substitute Futhark.IR.Syntax.Core.SubExp instance Futhark.Transform.Substitute.Substitute dec => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Core.PatElemT dec) instance Futhark.Transform.Substitute.Substitute Futhark.IR.Syntax.Attrs instance Futhark.Transform.Substitute.Substitute dec => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.StmAux dec) instance Futhark.Transform.Substitute.Substitute dec => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Core.Param dec) instance Futhark.Transform.Substitute.Substitute dec => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.PatternT dec) instance Futhark.Transform.Substitute.Substitute Futhark.IR.Syntax.Core.Certificates instance Futhark.Transform.Substitute.Substitute Futhark.IR.Syntax.Core.Rank instance Futhark.Transform.Substitute.Substitute () instance Futhark.Transform.Substitute.Substitute d => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Core.ShapeBase d) instance Futhark.Transform.Substitute.Substitute d => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Core.Ext d) instance Futhark.Transform.Substitute.Substitute Futhark.IR.Prop.Names.Names instance Futhark.Transform.Substitute.Substitute shape => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Core.TypeBase shape u) instance Futhark.Transform.Substitute.Substitute Futhark.IR.Syntax.Core.Ident instance Futhark.Transform.Substitute.Substitute d => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.DimChange d) instance Futhark.Transform.Substitute.Substitute d => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Core.DimIndex d) instance Futhark.Transform.Substitute.Substitute v => Futhark.Transform.Substitute.Substitute (Futhark.Analysis.PrimExp.PrimExp v) instance Futhark.Transform.Substitute.Substitute v => Futhark.Transform.Substitute.Substitute (Futhark.Analysis.PrimExp.TPrimExp t v) instance Futhark.Transform.Substitute.Substitute Futhark.IR.Prop.Names.FV -- | Some OpenCL platforms have a SIMDwarpwavefront-based execution -- model that execute groups of threads in lockstep, permitting us to -- perform cross-thread synchronisation within each such group without -- the use of barriers. Unfortunately, there seems to be no reliable way -- to query these sizes at runtime. Instead, we use builtin tables to -- figure out which size we should use for a specific platform and -- device. If nothing matches here, the wave size should be set to one. -- -- We also use this to select reasonable default group sizes and group -- counts. module Futhark.CodeGen.OpenCL.Heuristics -- | A heuristic for setting the default value for something. data SizeHeuristic SizeHeuristic :: String -> DeviceType -> WhichSize -> TPrimExp Int32 DeviceInfo -> SizeHeuristic [platformName] :: SizeHeuristic -> String [deviceType] :: SizeHeuristic -> DeviceType [heuristicSize] :: SizeHeuristic -> WhichSize [heuristicValue] :: SizeHeuristic -> TPrimExp Int32 DeviceInfo -- | The type of OpenCL device that this heuristic applies to. data DeviceType DeviceCPU :: DeviceType DeviceGPU :: DeviceType -- | A size that can be assigned a default. data WhichSize LockstepWidth :: WhichSize NumGroups :: WhichSize GroupSize :: WhichSize TileSize :: WhichSize Threshold :: WhichSize -- | The value supplies by a heuristic can depend on some device -- information. This will be translated into a call to -- clGetDeviceInfo(). Make sure to only request info that can be -- casted to a scalar type. newtype DeviceInfo DeviceInfo :: String -> DeviceInfo -- | All of our heuristics. sizeHeuristicsTable :: [SizeHeuristic] instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.OpenCL.Heuristics.DeviceInfo -- | Generalization (anti-unification) of PrimExps. module Futhark.Analysis.PrimExp.Generalize -- | Generalize two PrimExps of the the same type. leastGeneralGeneralization :: Eq v => [(PrimExp v, PrimExp v)] -> PrimExp v -> PrimExp v -> (PrimExp (Ext v), [(PrimExp v, PrimExp v)]) -- | In the context of this module, a "size" is any kind of tunable -- (run-time) constant. module Futhark.IR.Kernels.Sizes -- | The class of some kind of configurable size. Each class may impose -- constraints on the valid values. data SizeClass -- | A threshold with an optional default. SizeThreshold :: KernelPath -> Maybe Int64 -> SizeClass SizeGroup :: SizeClass SizeNumGroups :: SizeClass SizeTile :: SizeClass -- | Likely not useful on its own, but querying the maximum can be handy. SizeLocalMemory :: SizeClass -- | A bespoke size with a default. SizeBespoke :: Name -> Int64 -> SizeClass -- | The default value for the size. If Nothing, that means the -- backend gets to decide. sizeDefault :: SizeClass -> Maybe Int64 -- | An indication of which comparisons have been performed to get to this -- point, as well as the result of each comparison. type KernelPath = [(Name, Bool)] -- | A wrapper supporting a phantom type for indicating what we are -- counting. newtype Count u e Count :: e -> Count u e [unCount] :: Count u e -> e -- | Phantom type for the number of groups of some kernel. data NumGroups -- | Phantom type for the group size of some kernel. data GroupSize -- | Phantom type for number of threads. data NumThreads instance GHC.Generics.Generic Futhark.IR.Kernels.Sizes.SizeClass instance GHC.Show.Show Futhark.IR.Kernels.Sizes.SizeClass instance GHC.Classes.Ord Futhark.IR.Kernels.Sizes.SizeClass instance GHC.Classes.Eq Futhark.IR.Kernels.Sizes.SizeClass instance GHC.Generics.Generic (Futhark.IR.Kernels.Sizes.Count u e) instance Futhark.Transform.Substitute.Substitute e => Futhark.Transform.Substitute.Substitute (Futhark.IR.Kernels.Sizes.Count u e) instance Text.PrettyPrint.Mainland.Class.Pretty e => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Kernels.Sizes.Count u e) instance Futhark.IR.Prop.Names.FreeIn e => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Kernels.Sizes.Count u e) instance Futhark.Util.IntegralExp.IntegralExp e => Futhark.Util.IntegralExp.IntegralExp (Futhark.IR.Kernels.Sizes.Count u e) instance GHC.Num.Num e => GHC.Num.Num (Futhark.IR.Kernels.Sizes.Count u e) instance GHC.Show.Show e => GHC.Show.Show (Futhark.IR.Kernels.Sizes.Count u e) instance GHC.Classes.Ord e => GHC.Classes.Ord (Futhark.IR.Kernels.Sizes.Count u e) instance GHC.Classes.Eq e => GHC.Classes.Eq (Futhark.IR.Kernels.Sizes.Count u e) instance Language.SexpGrammar.Class.SexpIso e => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Kernels.Sizes.Count u e) instance GHC.Base.Functor (Futhark.IR.Kernels.Sizes.Count u) instance Data.Foldable.Foldable (Futhark.IR.Kernels.Sizes.Count u) instance Data.Traversable.Traversable (Futhark.IR.Kernels.Sizes.Count u) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Kernels.Sizes.SizeClass instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Kernels.Sizes.SizeClass -- | This module provides facilities for generating unique names. module Futhark.FreshNames -- | A name source is conceptually an infinite sequence of names with no -- repeating entries. In practice, when asked for a name, the name source -- will return the name along with a new name source, which should then -- be used in place of the original. -- -- The Ord instance is based on how many names have been extracted -- from the name source. data VNameSource -- | A blank name source. blankNameSource :: VNameSource -- | A new name source that starts counting from the given number. newNameSource :: Int -> VNameSource -- | Produce a fresh name, using the given name as a template. newName :: VNameSource -> VName -> (VName, VNameSource) instance GHC.Classes.Ord Futhark.FreshNames.VNameSource instance GHC.Classes.Eq Futhark.FreshNames.VNameSource instance Language.Haskell.TH.Syntax.Lift Futhark.FreshNames.VNameSource instance GHC.Base.Semigroup Futhark.FreshNames.VNameSource instance GHC.Base.Monoid Futhark.FreshNames.VNameSource -- | This module provides a monadic facility similar (and built on top of) -- Futhark.FreshNames. The removes the need for a (small) amount -- of boilerplate, at the cost of using some GHC extensions. The idea is -- that if your compiler pass runs in a monad that is an instance of -- MonadFreshNames, you can automatically use the name generation -- functions exported by this module. module Futhark.MonadFreshNames -- | A monad that stores a name source. The following is a good instance -- for a monad in which the only state is a NameSource vn: -- --
--   instance MonadFreshNames vn MyMonad where
--     getNameSource = get
--     putNameSource = put
--   
class (Applicative m, Monad m) => MonadFreshNames m getNameSource :: MonadFreshNames m => m VNameSource putNameSource :: MonadFreshNames m => VNameSource -> m () -- | Run a computation needing a fresh name source and returning a new one, -- using getNameSource and putNameSource before and after -- the computation. modifyNameSource :: MonadFreshNames m => (VNameSource -> (a, VNameSource)) -> m a -- | Produce a fresh name, using the given name as a template. newName :: MonadFreshNames m => VName -> m VName -- | As newName, but takes a String for the name template. newNameFromString :: MonadFreshNames m => String -> m VName -- | Produce a fresh VName, using the given base name as a template. newVName :: MonadFreshNames m => String -> m VName -- | Produce a fresh Ident, using the given name as a template. newIdent :: MonadFreshNames m => String -> Type -> m Ident -- | Produce a fresh Ident, using the given Ident as a -- template, but possibly modifying the name. newIdent' :: MonadFreshNames m => (String -> String) -> Ident -> m Ident -- | Produce a fresh Param, using the given name as a template. newParam :: MonadFreshNames m => String -> dec -> m (Param dec) -- | A name source is conceptually an infinite sequence of names with no -- repeating entries. In practice, when asked for a name, the name source -- will return the name along with a new name source, which should then -- be used in place of the original. -- -- The Ord instance is based on how many names have been extracted -- from the name source. data VNameSource -- | A blank name source. blankNameSource :: VNameSource -- | A new name source that starts counting from the given number. newNameSource :: Int -> VNameSource instance (GHC.Base.Applicative im, GHC.Base.Monad im) => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.State.Lazy.StateT Futhark.FreshNames.VNameSource im) instance (GHC.Base.Applicative im, GHC.Base.Monad im) => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.State.Strict.StateT Futhark.FreshNames.VNameSource im) instance (GHC.Base.Applicative im, GHC.Base.Monad im, GHC.Base.Monoid w) => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.RWS.Lazy.RWST r w Futhark.FreshNames.VNameSource im) instance (GHC.Base.Applicative im, GHC.Base.Monad im, GHC.Base.Monoid w) => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.RWS.Strict.RWST r w Futhark.FreshNames.VNameSource im) instance Futhark.MonadFreshNames.MonadFreshNames m => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.Reader.ReaderT s m) instance (Futhark.MonadFreshNames.MonadFreshNames m, GHC.Base.Monoid s) => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.Writer.Lazy.WriterT s m) instance (Futhark.MonadFreshNames.MonadFreshNames m, GHC.Base.Monoid s) => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.Writer.Strict.WriterT s m) instance Futhark.MonadFreshNames.MonadFreshNames m => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.Maybe.MaybeT m) instance Futhark.MonadFreshNames.MonadFreshNames m => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.Except.ExceptT e m) -- | This module provides facilities for transforming Futhark programs such -- that names are unique, via the renameProg function. module Futhark.Transform.Rename -- | Rename variables such that each is unique. The semantics of the -- program are unaffected, under the assumption that the program was -- correct to begin with. In particular, the renaming may make an invalid -- program valid. renameProg :: (Renameable lore, MonadFreshNames m) => Prog lore -> m (Prog lore) -- | Rename bound variables such that each is unique. The semantics of the -- expression is unaffected, under the assumption that the expression was -- correct to begin with. Any free variables are left untouched. renameExp :: (Renameable lore, MonadFreshNames m) => Exp lore -> m (Exp lore) -- | Rename bound variables such that each is unique. The semantics of the -- binding is unaffected, under the assumption that the binding was -- correct to begin with. Any free variables are left untouched, as are -- the names in the pattern of the binding. renameStm :: (Renameable lore, MonadFreshNames m) => Stm lore -> m (Stm lore) -- | Rename bound variables such that each is unique. The semantics of the -- body is unaffected, under the assumption that the body was correct to -- begin with. Any free variables are left untouched. renameBody :: (Renameable lore, MonadFreshNames m) => Body lore -> m (Body lore) -- | Rename bound variables such that each is unique. The semantics of the -- lambda is unaffected, under the assumption that the body was correct -- to begin with. Any free variables are left untouched. Note in -- particular that the parameters of the lambda are renamed. renameLambda :: (Renameable lore, MonadFreshNames m) => Lambda lore -> m (Lambda lore) -- | Produce an equivalent pattern but with each pattern element given a -- new name. renamePattern :: (Rename dec, MonadFreshNames m) => PatternT dec -> m (PatternT dec) -- | Rename the bound variables in something (does not affect free -- variables). renameSomething :: (Rename a, MonadFreshNames m) => a -> m a -- | The monad in which renaming is performed. data RenameM a -- | Perform a renaming using the Substitute instance. This only -- works if the argument does not itself perform any name binding, but it -- can save on boilerplate for simple types. substituteRename :: Substitute a => a -> RenameM a -- | Rename some statements, then execute an action with the name -- substitutions induced by the statements active. renamingStms :: Renameable lore => Stms lore -> (Stms lore -> RenameM a) -> RenameM a -- | Members of class Rename can be uniquely renamed. class Rename a -- | Rename the given value such that it does not contain shadowing, and -- has incorporated any substitutions present in the RenameM -- environment. rename :: Rename a => a -> RenameM a -- | Lores in which all annotations are renameable. type Renameable lore = (Rename (LetDec lore), Rename (ExpDec lore), Rename (BodyDec lore), Rename (FParamInfo lore), Rename (LParamInfo lore), Rename (RetType lore), Rename (BranchType lore), Rename (Op lore)) instance Control.Monad.Reader.Class.MonadReader Futhark.Transform.Rename.RenameEnv Futhark.Transform.Rename.RenameM instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Transform.Rename.RenameM instance GHC.Base.Monad Futhark.Transform.Rename.RenameM instance GHC.Base.Applicative Futhark.Transform.Rename.RenameM instance GHC.Base.Functor Futhark.Transform.Rename.RenameM instance Futhark.Transform.Rename.Renameable lore => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.FunDef lore) instance Futhark.Transform.Rename.Renameable lore => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Body lore) instance Futhark.Transform.Rename.Renameable lore => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Stm lore) instance Futhark.Transform.Rename.Renameable lore => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Exp lore) instance Futhark.Transform.Rename.Renameable lore => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Lambda lore) instance Futhark.Transform.Rename.Rename Language.Futhark.Core.VName instance Futhark.Transform.Rename.Rename a => Futhark.Transform.Rename.Rename [a] instance (Futhark.Transform.Rename.Rename a, Futhark.Transform.Rename.Rename b) => Futhark.Transform.Rename.Rename (a, b) instance (Futhark.Transform.Rename.Rename a, Futhark.Transform.Rename.Rename b, Futhark.Transform.Rename.Rename c) => Futhark.Transform.Rename.Rename (a, b, c) instance Futhark.Transform.Rename.Rename a => Futhark.Transform.Rename.Rename (GHC.Maybe.Maybe a) instance Futhark.Transform.Rename.Rename GHC.Types.Bool instance Futhark.Transform.Rename.Rename Futhark.IR.Syntax.Core.Ident instance Futhark.Transform.Rename.Rename Futhark.IR.Syntax.Core.SubExp instance Futhark.Transform.Rename.Rename dec => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Core.Param dec) instance Futhark.Transform.Rename.Rename dec => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.PatternT dec) instance Futhark.Transform.Rename.Rename dec => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Core.PatElemT dec) instance Futhark.Transform.Rename.Rename Futhark.IR.Syntax.Core.Certificates instance Futhark.Transform.Rename.Rename Futhark.IR.Syntax.Attrs instance Futhark.Transform.Rename.Rename dec => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.StmAux dec) instance Futhark.Transform.Rename.Rename shape => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Core.TypeBase shape u) instance Futhark.Transform.Rename.Rename Futhark.IR.Prop.Names.Names instance Futhark.Transform.Rename.Rename Futhark.IR.Syntax.Core.Rank instance Futhark.Transform.Rename.Rename d => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Core.ShapeBase d) instance Futhark.Transform.Rename.Rename Futhark.IR.Syntax.Core.ExtSize instance Futhark.Transform.Rename.Rename () instance Futhark.Transform.Rename.Rename d => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Core.DimIndex d) -- | This module provides various simple ways to query and manipulate -- fundamental Futhark terms, such as types and values. The intent is to -- keep Futhark.IRrsentation.AST.Syntax simple, and put whatever -- embellishments we need here. This is an internal, desugared -- representation. module Futhark.IR.Prop -- | isBuiltInFunction k is True if k is an -- element of builtInFunctions. isBuiltInFunction :: Name -> Bool -- | A map of all built-in functions and their types. builtInFunctions :: Map Name (PrimType, [PrimType]) -- | If the expression is a BasicOp, return it, otherwise -- Nothing. asBasicOp :: Exp lore -> Maybe BasicOp -- | An expression is safe if it is always well-defined (assuming that any -- required certificates have been checked) in any context. For example, -- array indexing is not safe, as the index may be out of bounds. On the -- other hand, adding two numbers cannot fail. safeExp :: IsOp (Op lore) => Exp lore -> Bool -- | Return the variable names used in Var subexpressions. May -- contain duplicates. subExpVars :: [SubExp] -> [VName] -- | If the SubExp is a Var return the variable name. subExpVar :: SubExp -> Maybe VName -- | Return the variable dimension sizes. May contain duplicates. shapeVars :: Shape -> [VName] -- | Does the given lambda represent a known commutative function? Based on -- pattern matching and checking whether the lambda represents a known -- arithmetic operator; don't expect anything clever here. commutativeLambda :: Lambda lore -> Bool -- | How many value parameters are accepted by this entry point? This is -- used to determine which of the function parameters correspond to the -- parameters of the original function (they must all come at the end). entryPointSize :: EntryPointType -> Int -- | A StmAux with empty Certificates. defAux :: dec -> StmAux dec -- | The certificates associated with a statement. stmCerts :: Stm lore -> Certificates -- | Add certificates to a statement. certify :: Certificates -> Stm lore -> Stm lore -- | Construct the type of an expression that would match the pattern. expExtTypesFromPattern :: Typed dec => PatternT dec -> [ExtType] -- | Keep only those attributes that are relevant for Assert -- expressions. attrsForAssert :: Attrs -> Attrs -- | A handy shorthand for properties that we usually want to things we -- stuff into ASTs. type ASTConstraints a = (Eq a, Ord a, Show a, Rename a, Substitute a, FreeIn a, Pretty a, SexpIso a) -- | A type class for operations. class (ASTConstraints op, TypedOp op) => IsOp op -- | Like safeExp, but for arbitrary ops. safeOp :: IsOp op => op -> Bool -- | Should we try to hoist this out of branches? cheapOp :: IsOp op => op -> Bool -- | Lore-specific attributes; also means the lore supports some basic -- facilities. class (Decorations lore, PrettyLore lore, Renameable lore, Substitutable lore, FreeDec (ExpDec lore), FreeIn (LetDec lore), FreeDec (BodyDec lore), FreeIn (FParamInfo lore), FreeIn (LParamInfo lore), FreeIn (RetType lore), FreeIn (BranchType lore), IsOp (Op lore)) => ASTLore lore -- | Given a pattern, construct the type of a body that would match it. An -- implementation for many lores would be expExtTypesFromPattern. expTypesFromPattern :: (ASTLore lore, HasScope lore m, Monad m) => Pattern lore -> m [BranchType lore] instance Futhark.IR.Prop.IsOp () -- | The IR tracks aliases, mostly to ensure the soundness of in-place -- updates, but it can also be used for other things (such as memory -- optimisations). This module contains the raw building blocks for -- determining the aliases of the values produced by expressions. It also -- contains some building blocks for inspecting consumption. -- -- One important caveat is that all aliases computed here are -- local. Thus, they do not take aliases-of-aliases into account. -- See Futhark.Analysis.Alias if this is not what you want. module Futhark.IR.Prop.Aliases -- | The alises of a subexpression. subExpAliases :: SubExp -> Names -- | The aliases of an expression, one per non-context value returned. expAliases :: Aliased lore => Exp lore -> [Names] -- | The aliases of each pattern element (including the context). patternAliases :: AliasesOf dec => PatternT dec -> [Names] -- | Also includes the name itself. lookupAliases :: AliasesOf (LetDec lore) => VName -> Scope lore -> Names -- | The class of lores that contain aliasing information. class (Decorations lore, AliasedOp (Op lore), AliasesOf (LetDec lore)) => Aliased lore -- | The aliases of the body results. bodyAliases :: Aliased lore => Body lore -> [Names] -- | The variables consumed in the body. consumedInBody :: Aliased lore => Body lore -> Names -- | Something that contains alias information. class AliasesOf a -- | The alias of the argument element. aliasesOf :: AliasesOf a => a -> Names -- | The variables consumed in this statement. consumedInStm :: Aliased lore => Stm lore -> Names -- | The variables consumed in this expression. consumedInExp :: Aliased lore => Exp lore -> Names -- | The variables consumed by this lambda. consumedByLambda :: Aliased lore => Lambda lore -> Names -- | The class of operations that can produce aliasing and consumption -- information. class IsOp op => AliasedOp op opAliases :: AliasedOp op => op -> [Names] consumedInOp :: AliasedOp op => op -> Names -- | The class of operations that can be given aliasing information. This -- is a somewhat subtle concept that is only used in the simplifier and -- when using "lore adapters". class AliasedOp (OpWithAliases op) => CanBeAliased op where { -- | The op that results when we add aliases to this op. type family OpWithAliases op :: Type; } -- | Remove aliases from this op. removeOpAliases :: CanBeAliased op => OpWithAliases op -> op -- | Add aliases to this op. addOpAliases :: CanBeAliased op => op -> OpWithAliases op instance Futhark.IR.Prop.Aliases.CanBeAliased () instance Futhark.IR.Prop.Aliases.AliasedOp () instance Futhark.IR.Prop.Aliases.AliasesOf Futhark.IR.Prop.Names.Names instance Futhark.IR.Prop.Aliases.AliasesOf dec => Futhark.IR.Prop.Aliases.AliasesOf (Futhark.IR.Syntax.Core.PatElemT dec) -- | A convenient re-export of basic AST modules. Note that -- Futhark.IR.Lore is not exported, as this would cause name -- clashes. You are advised to use a qualified import of the lore module, -- if you need it. module Futhark.IR -- | A usage-table is sort of a bottom-up symbol table, describing how (and -- if) a variable is used. module Futhark.Analysis.UsageTable -- | A usage table. data UsageTable -- | Remove these entries from the usage table. without :: UsageTable -> [VName] -> UsageTable -- | Look up a variable in the usage table. lookup :: VName -> UsageTable -> Maybe Usages -- | Is the variable present in the usage table? That is, has it been used? used :: VName -> UsageTable -> Bool -- | Expand the usage table based on aliasing information. expand :: (VName -> Names) -> UsageTable -> UsageTable -- | Has the variable been consumed? isConsumed :: VName -> UsageTable -> Bool -- | Has the variable been used in the Result of a body? isInResult :: VName -> UsageTable -> Bool -- | Has the given name been used directly (i.e. could we rename it or -- remove it without anyone noticing?) isUsedDirectly :: VName -> UsageTable -> Bool -- | Is this name used as the size of something (array or memory block)? isSize :: VName -> UsageTable -> Bool -- | Construct a usage table reflecting that these variables have been -- used. usages :: Names -> UsageTable -- | Construct a usage table where the given variable has been used in this -- specific way. usage :: VName -> Usages -> UsageTable -- | Construct a usage table where the given variable has been consumed. consumedUsage :: VName -> UsageTable -- | Construct a usage table where the given variable has been used in the -- Result of a body. inResultUsage :: VName -> UsageTable -- | Construct a usage table where the given variable has been used as an -- array or memory size. sizeUsage :: VName -> UsageTable -- | Construct a usage table where the given names have been used as an -- array or memory size. sizeUsages :: Names -> UsageTable -- | A description of how a single variable has been used. data Usages -- | Produce a usage table reflecting the use of the free variables in a -- single statement. usageInStm :: (ASTLore lore, Aliased lore) => Stm lore -> UsageTable instance GHC.Show.Show Futhark.Analysis.UsageTable.Usages instance GHC.Classes.Ord Futhark.Analysis.UsageTable.Usages instance GHC.Classes.Eq Futhark.Analysis.UsageTable.Usages instance GHC.Show.Show Futhark.Analysis.UsageTable.UsageTable instance GHC.Classes.Eq Futhark.Analysis.UsageTable.UsageTable instance GHC.Base.Semigroup Futhark.Analysis.UsageTable.UsageTable instance GHC.Base.Monoid Futhark.Analysis.UsageTable.UsageTable instance GHC.Base.Semigroup Futhark.Analysis.UsageTable.Usages instance GHC.Base.Monoid Futhark.Analysis.UsageTable.Usages -- | Facilities for changing the lore of some fragment, with no context. We -- call this "rephrasing", for no deep reason. module Futhark.Analysis.Rephrase -- | Rephrase an entire program. rephraseProg :: Monad m => Rephraser m from to -> Prog from -> m (Prog to) -- | Rephrase a function definition. rephraseFunDef :: Monad m => Rephraser m from to -> FunDef from -> m (FunDef to) -- | Rephrase an expression. rephraseExp :: Monad m => Rephraser m from to -> Exp from -> m (Exp to) -- | Rephrase a body. rephraseBody :: Monad m => Rephraser m from to -> Body from -> m (Body to) -- | Rephrase a statement. rephraseStm :: Monad m => Rephraser m from to -> Stm from -> m (Stm to) -- | Rephrase a lambda. rephraseLambda :: Monad m => Rephraser m from to -> Lambda from -> m (Lambda to) -- | Rephrase a pattern. rephrasePattern :: Monad m => (from -> m to) -> PatternT from -> m (PatternT to) -- | Rephrase a pattern element. rephrasePatElem :: Monad m => (from -> m to) -> PatElemT from -> m (PatElemT to) -- | A collection of functions that together allow us to rephrase some IR -- fragment, in some monad m. If we let m be the -- Maybe monad, we can conveniently do rephrasing that might fail. -- This is useful if you want to see if some IR in e.g. the -- Kernels lore actually uses any Kernels-specific -- operations. data Rephraser m from to Rephraser :: (ExpDec from -> m (ExpDec to)) -> (LetDec from -> m (LetDec to)) -> (FParamInfo from -> m (FParamInfo to)) -> (LParamInfo from -> m (LParamInfo to)) -> (BodyDec from -> m (BodyDec to)) -> (RetType from -> m (RetType to)) -> (BranchType from -> m (BranchType to)) -> (Op from -> m (Op to)) -> Rephraser m from to [rephraseExpLore] :: Rephraser m from to -> ExpDec from -> m (ExpDec to) [rephraseLetBoundLore] :: Rephraser m from to -> LetDec from -> m (LetDec to) [rephraseFParamLore] :: Rephraser m from to -> FParamInfo from -> m (FParamInfo to) [rephraseLParamLore] :: Rephraser m from to -> LParamInfo from -> m (LParamInfo to) [rephraseBodyLore] :: Rephraser m from to -> BodyDec from -> m (BodyDec to) [rephraseRetType] :: Rephraser m from to -> RetType from -> m (RetType to) [rephraseBranchType] :: Rephraser m from to -> BranchType from -> m (BranchType to) [rephraseOp] :: Rephraser m from to -> Op from -> m (Op to) -- | Abstract Syntax Tree metrics. This is used in the futhark -- test program, for the structure stanzas. module Futhark.Analysis.Metrics -- | AST metrics are simply a collection from identifiable node names to -- the number of times that node appears. newtype AstMetrics AstMetrics :: Map Text Int -> AstMetrics -- | Compute the metrics for a program. progMetrics :: OpMetrics (Op lore) => Prog lore -> AstMetrics -- | Compute the metrics for some operation. class OpMetrics op opMetrics :: OpMetrics op => op -> MetricsM () -- | Add this node to the current tally. seen :: Text -> MetricsM () -- | Enclose a metrics counting operation. Most importantly, this prefixes -- the name of the context to all the metrics computed in the enclosed -- operation. inside :: Text -> MetricsM () -> MetricsM () -- | This monad is used for computing metrics. It internally keeps track of -- what we've seen so far. Use seen to add more stuff. data MetricsM a -- | Compute metrics for this statement. stmMetrics :: OpMetrics (Op lore) => Stm lore -> MetricsM () -- | Compute metrics for this lambda. lambdaMetrics :: OpMetrics (Op lore) => Lambda lore -> MetricsM () instance Control.Monad.Writer.Class.MonadWriter Futhark.Analysis.Metrics.CountMetrics Futhark.Analysis.Metrics.MetricsM instance GHC.Base.Functor Futhark.Analysis.Metrics.MetricsM instance GHC.Base.Applicative Futhark.Analysis.Metrics.MetricsM instance GHC.Base.Monad Futhark.Analysis.Metrics.MetricsM instance Futhark.Analysis.Metrics.OpMetrics a => Futhark.Analysis.Metrics.OpMetrics (GHC.Maybe.Maybe a) instance Futhark.Analysis.Metrics.OpMetrics () instance GHC.Base.Semigroup Futhark.Analysis.Metrics.CountMetrics instance GHC.Base.Monoid Futhark.Analysis.Metrics.CountMetrics instance GHC.Show.Show Futhark.Analysis.Metrics.AstMetrics instance GHC.Read.Read Futhark.Analysis.Metrics.AstMetrics -- | Facilities for inspecting the data dependencies of a program. module Futhark.Analysis.DataDependencies -- | A mapping from a variable name v, to those variables on which -- the value of v is dependent. The intuition is that we could -- remove all other variables, and v would still be computable. -- This also includes names bound in loops or by lambdas. type Dependencies = Map VName Names -- | Compute the data dependencies for an entire body. dataDependencies :: ASTLore lore => Body lore -> Dependencies -- | findNecessaryForReturned p merge deps computes which of the -- loop parameters (merge) are necessary for the result of the -- loop, where p given a loop parameter indicates whether the -- final value of that parameter is live after the loop. deps is -- the data dependencies of the loop body. This is computed by -- straightforward fixpoint iteration. findNecessaryForReturned :: (Param dec -> Bool) -> [(Param dec, SubExp)] -> Map VName Names -> Names -- | Definition of a polymorphic (generic) pass that can work with programs -- of any lore. module Futhark.Pass -- | The monad in which passes execute. data PassM a -- | Execute a PassM action, yielding logging information and either -- an error text or a result. runPassM :: MonadFreshNames m => PassM a -> m (a, Log) -- | Turn an Either computation into a PassM. If the -- Either is Left, the result is a CompilerBug. liftEither :: Show err => Either err a -> PassM a -- | Turn an Either monadic computation into a PassM. If the -- Either is Left, the result is an exception. liftEitherM :: Show err => PassM (Either err a) -> PassM a -- | A compiler pass transforming a Prog of a given lore to a -- Prog of another lore. data Pass fromlore tolore Pass :: String -> String -> (Prog fromlore -> PassM (Prog tolore)) -> Pass fromlore tolore -- | Name of the pass. Keep this short and simple. It will be used to -- automatically generate a command-line option name via -- passLongOption. [passName] :: Pass fromlore tolore -> String -- | A slightly longer description, which will show up in the command-line -- help text. [passDescription] :: Pass fromlore tolore -> String [passFunction] :: Pass fromlore tolore -> Prog fromlore -> PassM (Prog tolore) -- | Take the name of the pass, turn spaces into dashes, and make all -- characters lowercase. passLongOption :: Pass fromlore tolore -> String -- | Apply a PassM operation in parallel to multiple elements, -- joining together the name sources and logs, and propagating any error -- properly. parPass :: (a -> PassM b) -> [a] -> PassM [b] -- | Like intraproceduralTransformationWithConsts, but do not change -- the top-level constants, and simply pass along their Scope. intraproceduralTransformation :: (Scope lore -> Stms lore -> PassM (Stms lore)) -> Prog lore -> PassM (Prog lore) -- | Apply some operation to the top-level constants. Then applies an -- operation to all the function function definitions, which are also -- given the transformed constants so they can be brought into scope. The -- function definition transformations are run in parallel (with -- parPass), since they cannot affect each other. intraproceduralTransformationWithConsts :: (Stms fromlore -> PassM (Stms tolore)) -> (Stms tolore -> FunDef fromlore -> PassM (FunDef tolore)) -> Prog fromlore -> PassM (Prog tolore) instance GHC.Base.Monad Futhark.Pass.PassM instance GHC.Base.Applicative Futhark.Pass.PassM instance GHC.Base.Functor Futhark.Pass.PassM instance Futhark.Util.Log.MonadLogger Futhark.Pass.PassM instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Pass.PassM -- | This module defines a convenience typeclass for creating normalised -- programs. -- -- See Futhark.Construct for a high-level description. module Futhark.Binder.Class -- | The class of lores that can be constructed solely from an expression, -- within some monad. Very important: the methods should not have any -- significant side effects! They may be called more often than you -- think, and the results thrown away. If used exclusively within a -- MonadBinder instance, it is acceptable for them to create new -- bindings, however. class (ASTLore lore, FParamInfo lore ~ DeclType, LParamInfo lore ~ Type, RetType lore ~ DeclExtType, BranchType lore ~ ExtType, SetType (LetDec lore)) => Bindable lore mkExpPat :: Bindable lore => [Ident] -> [Ident] -> Exp lore -> Pattern lore mkExpDec :: Bindable lore => Pattern lore -> Exp lore -> ExpDec lore mkBody :: Bindable lore => Stms lore -> Result -> Body lore mkLetNames :: (Bindable lore, MonadFreshNames m, HasScope lore m) => [VName] -> Exp lore -> m (Stm lore) -- | Construct a Stm from identifiers for the context- and value -- part of the pattern, as well as the expression. mkLet :: Bindable lore => [Ident] -> [Ident] -> Exp lore -> Stm lore -- | Like mkLet, but also take attributes and certificates from the given -- StmAux. mkLet' :: Bindable lore => [Ident] -> [Ident] -> StmAux a -> Exp lore -> Stm lore -- | A monad that supports the creation of bindings from expressions and -- bodies from bindings, with a specific lore. This is the main typeclass -- that a monad must implement in order for it to be useful for -- generating or modifying Futhark code. Most importantly maintains a -- current state of Stms (as well as a Scope) that have -- been added with addStm. -- -- Very important: the methods should not have any significant side -- effects! They may be called more often than you think, and the results -- thrown away. It is acceptable for them to create new bindings, -- however. class (ASTLore (Lore m), MonadFreshNames m, Applicative m, Monad m, LocalScope (Lore m) m) => MonadBinder m where { type family Lore m :: Type; } mkExpDecM :: MonadBinder m => Pattern (Lore m) -> Exp (Lore m) -> m (ExpDec (Lore m)) mkBodyM :: MonadBinder m => Stms (Lore m) -> Result -> m (Body (Lore m)) mkLetNamesM :: MonadBinder m => [VName] -> Exp (Lore m) -> m (Stm (Lore m)) -- | Add a statement to the Stms under construction. addStm :: MonadBinder m => Stm (Lore m) -> m () -- | Add multiple statements to the Stms under construction. addStms :: MonadBinder m => Stms (Lore m) -> m () -- | Obtain the statements constructed during a monadic action, instead of -- adding them to the state. collectStms :: MonadBinder m => m a -> m (a, Stms (Lore m)) -- | Add the provided certificates to any statements added during execution -- of the action. certifying :: MonadBinder m => Certificates -> m a -> m a -- | Add several bindings at the outermost level of a Body. insertStms :: Bindable lore => Stms lore -> Body lore -> Body lore -- | Add a single binding at the outermost level of a Body. insertStm :: Bindable lore => Stm lore -> Body lore -> Body lore -- | Add a statement with the given pattern and expression. letBind :: MonadBinder m => Pattern (Lore m) -> Exp (Lore m) -> m () -- | Add a statement with the given pattern element names and expression. letBindNames :: MonadBinder m => [VName] -> Exp (Lore m) -> m () -- | As collectStms, but throw away the ordinary result. collectStms_ :: MonadBinder m => m a -> m (Stms (Lore m)) -- | Add the statements of the body, then return the body result. bodyBind :: MonadBinder m => Body (Lore m) -> m [SubExp] -- | Add the given attributes to any statements added by this action. attributing :: MonadBinder m => Attrs -> m a -> m a -- | Add the certificates and attributes to any statements added by this -- action. auxing :: MonadBinder m => StmAux anylore -> m a -> m a -- | This module defines a convenience monad/typeclass for creating -- normalised programs. The fundamental building block is BinderT -- and its execution functions, but it is usually easier to use -- Binder. -- -- See Futhark.Construct for a high-level description. module Futhark.Binder -- | A monad transformer that tracks statements and provides a -- MonadBinder instance, assuming that the underlying monad -- provides a name source. In almost all cases, this is what you will use -- for constructing statements (possibly as part of a larger monad -- stack). If you find yourself needing to implement MonadBinder -- from scratch, then it is likely that you are making a mistake. data BinderT lore m a -- | Run a binder action given an initial scope, returning a value and the -- statements added (addStm) during the action. runBinderT :: MonadFreshNames m => BinderT lore m a -> Scope lore -> m (a, Stms lore) -- | Like runBinderT, but return only the statements. runBinderT_ :: MonadFreshNames m => BinderT lore m () -> Scope lore -> m (Stms lore) -- | Like runBinderT, but get the initial scope from the current -- monad. runBinderT' :: (MonadFreshNames m, HasScope somelore m, SameScope somelore lore) => BinderT lore m a -> m (a, Stms lore) -- | Like runBinderT_, but get the initial scope from the current -- monad. runBinderT'_ :: (MonadFreshNames m, HasScope somelore m, SameScope somelore lore) => BinderT lore m a -> m (Stms lore) -- | A BinderT (and by extension, a Binder) is only an -- instance of MonadBinder for lores that implement this type -- class, which contains methods for constructing statements. class ASTLore lore => BinderOps lore mkExpDecB :: (BinderOps lore, MonadBinder m, Lore m ~ lore) => Pattern lore -> Exp lore -> m (ExpDec lore) mkBodyB :: (BinderOps lore, MonadBinder m, Lore m ~ lore) => Stms lore -> Result -> m (Body lore) mkLetNamesB :: (BinderOps lore, MonadBinder m, Lore m ~ lore) => [VName] -> Exp lore -> m (Stm lore) mkExpDecB :: (BinderOps lore, MonadBinder m, Bindable lore) => Pattern lore -> Exp lore -> m (ExpDec lore) mkBodyB :: (BinderOps lore, MonadBinder m, Bindable lore) => Stms lore -> Result -> m (Body lore) mkLetNamesB :: (BinderOps lore, MonadBinder m, Lore m ~ lore, Bindable lore) => [VName] -> Exp lore -> m (Stm lore) -- | The most commonly used binder monad. type Binder lore = BinderT lore (State VNameSource) -- | Run a binder action, returning a value and the statements added -- (addStm) during the action. Assumes that the current monad -- provides initial scope and name source. runBinder :: (MonadFreshNames m, HasScope somelore m, SameScope somelore lore) => Binder lore a -> m (a, Stms lore) -- | Like runBinder, but throw away the result and just return the -- added statements. runBinder_ :: (MonadFreshNames m, HasScope somelore m, SameScope somelore lore) => Binder lore a -> m (Stms lore) -- | Run a binder that produces a Body, and prefix that Body -- by the statements produced during execution of the action. runBodyBinder :: (Bindable lore, MonadFreshNames m, HasScope somelore m, SameScope somelore lore) => Binder lore (Body lore) -> m (Body lore) instance GHC.Base.Monad m => GHC.Base.Applicative (Futhark.Binder.BinderT lore m) instance GHC.Base.Monad m => GHC.Base.Monad (Futhark.Binder.BinderT lore m) instance GHC.Base.Functor m => GHC.Base.Functor (Futhark.Binder.BinderT lore m) instance Control.Monad.Trans.Class.MonadTrans (Futhark.Binder.BinderT lore) instance Futhark.MonadFreshNames.MonadFreshNames m => Futhark.MonadFreshNames.MonadFreshNames (Futhark.Binder.BinderT lore m) instance (Futhark.IR.Prop.ASTLore lore, GHC.Base.Monad m) => Futhark.IR.Prop.Scope.HasScope lore (Futhark.Binder.BinderT lore m) instance (Futhark.IR.Prop.ASTLore lore, GHC.Base.Monad m) => Futhark.IR.Prop.Scope.LocalScope lore (Futhark.Binder.BinderT lore m) instance (Futhark.IR.Prop.ASTLore lore, Futhark.MonadFreshNames.MonadFreshNames m, Futhark.Binder.BinderOps lore) => Futhark.Binder.Class.MonadBinder (Futhark.Binder.BinderT lore m) instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Futhark.Binder.BinderT lore m) instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Futhark.Binder.BinderT lore m) instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Futhark.Binder.BinderT lore m) instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Futhark.Binder.BinderT lore m) -- | A representation where all bindings are annotated with aliasing -- information. module Futhark.IR.Aliases -- | The lore for the basic representation. data Aliases lore -- | A wrapper around 'AliasDec to get around the fact that we need an -- Ord instance, which 'AliasDec does not have. newtype AliasDec AliasDec :: Names -> AliasDec [unAliases] :: AliasDec -> Names -- | The aliases of the let-bound variable. type VarAliases = AliasDec -- | Everything consumed in the expression. type ConsumedInExp = AliasDec -- | The aliases of what is returned by the Body, and what is -- consumed inside of it. type BodyAliasing = ([VarAliases], ConsumedInExp) addAliasesToPattern :: (ASTLore lore, CanBeAliased (Op lore), Typed dec) => PatternT dec -> Exp (Aliases lore) -> PatternT (VarAliases, dec) mkAliasedLetStm :: (ASTLore lore, CanBeAliased (Op lore)) => Pattern lore -> StmAux (ExpDec lore) -> Exp (Aliases lore) -> Stm (Aliases lore) mkAliasedBody :: (ASTLore lore, CanBeAliased (Op lore)) => BodyDec lore -> Stms (Aliases lore) -> Result -> Body (Aliases lore) mkPatternAliases :: (Aliased lore, Typed dec) => PatternT dec -> Exp lore -> ([PatElemT (VarAliases, dec)], [PatElemT (VarAliases, dec)]) mkBodyAliases :: Aliased lore => Stms lore -> Result -> BodyAliasing removeProgAliases :: CanBeAliased (Op lore) => Prog (Aliases lore) -> Prog lore removeFunDefAliases :: CanBeAliased (Op lore) => FunDef (Aliases lore) -> FunDef lore removeExpAliases :: CanBeAliased (Op lore) => Exp (Aliases lore) -> Exp lore removeStmAliases :: CanBeAliased (Op lore) => Stm (Aliases lore) -> Stm lore removeLambdaAliases :: CanBeAliased (Op lore) => Lambda (Aliases lore) -> Lambda lore removePatternAliases :: PatternT (AliasDec, a) -> PatternT a removeScopeAliases :: Scope (Aliases lore) -> Scope lore type AliasesAndConsumed = (Map VName Names, Names) trackAliases :: Aliased lore => AliasesAndConsumed -> Stm lore -> AliasesAndConsumed -- | Everything consumed in the given statements and result (even -- transitively). consumedInStms :: Aliased lore => Stms lore -> Names instance GHC.Generics.Generic Futhark.IR.Aliases.AliasDec instance GHC.Show.Show Futhark.IR.Aliases.AliasDec instance (Futhark.IR.Decorations.Decorations lore, Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Decorations.Decorations (Futhark.IR.Aliases.Aliases lore) instance Futhark.IR.Prop.Aliases.AliasesOf (Futhark.IR.Aliases.VarAliases, dec) instance Futhark.IR.Pretty.PrettyAnnot (Futhark.IR.Syntax.Core.PatElemT dec) => Futhark.IR.Pretty.PrettyAnnot (Futhark.IR.Syntax.Core.PatElemT (Futhark.IR.Aliases.VarAliases, dec)) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Aliases.AliasDec instance GHC.Base.Semigroup Futhark.IR.Aliases.AliasDec instance GHC.Base.Monoid Futhark.IR.Aliases.AliasDec instance GHC.Classes.Eq Futhark.IR.Aliases.AliasDec instance GHC.Classes.Ord Futhark.IR.Aliases.AliasDec instance Futhark.Transform.Rename.Rename Futhark.IR.Aliases.AliasDec instance Futhark.Transform.Substitute.Substitute Futhark.IR.Aliases.AliasDec instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Aliases.AliasDec instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Aliases.AliasDec instance Futhark.IR.Prop.Names.FreeDec Futhark.IR.Aliases.AliasDec instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.Aliases.Aliased (Futhark.IR.Aliases.Aliases lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Pretty.PrettyLore (Futhark.IR.Aliases.Aliases lore) instance (Futhark.Binder.Class.Bindable lore, Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore)) => Futhark.Binder.Class.Bindable (Futhark.IR.Aliases.Aliases lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.ASTLore (Futhark.IR.Aliases.Aliases lore) instance (Futhark.IR.Prop.ASTLore (Futhark.IR.Aliases.Aliases lore), Futhark.Binder.Class.Bindable (Futhark.IR.Aliases.Aliases lore)) => Futhark.Binder.BinderOps (Futhark.IR.Aliases.Aliases lore) -- | Definition of the lore used by the simplification engine. module Futhark.Optimise.Simplify.Lore data Wise lore -- | The wisdom of the let-bound variable. newtype VarWisdom VarWisdom :: VarAliases -> VarWisdom [varWisdomAliases] :: VarWisdom -> VarAliases -- | Wisdom about an expression. data ExpWisdom removeStmWisdom :: CanBeWise (Op lore) => Stm (Wise lore) -> Stm lore removeLambdaWisdom :: CanBeWise (Op lore) => Lambda (Wise lore) -> Lambda lore removeFunDefWisdom :: CanBeWise (Op lore) => FunDef (Wise lore) -> FunDef lore removeExpWisdom :: CanBeWise (Op lore) => Exp (Wise lore) -> Exp lore removePatternWisdom :: PatternT (VarWisdom, a) -> PatternT a removeBodyWisdom :: CanBeWise (Op lore) => Body (Wise lore) -> Body lore removeScopeWisdom :: Scope (Wise lore) -> Scope lore addScopeWisdom :: Scope lore -> Scope (Wise lore) addWisdomToPattern :: (ASTLore lore, CanBeWise (Op lore)) => Pattern lore -> Exp (Wise lore) -> Pattern (Wise lore) mkWiseBody :: (ASTLore lore, CanBeWise (Op lore)) => BodyDec lore -> Stms (Wise lore) -> Result -> Body (Wise lore) mkWiseLetStm :: (ASTLore lore, CanBeWise (Op lore)) => Pattern lore -> StmAux (ExpDec lore) -> Exp (Wise lore) -> Stm (Wise lore) mkWiseExpDec :: (ASTLore lore, CanBeWise (Op lore)) => Pattern (Wise lore) -> ExpDec lore -> Exp (Wise lore) -> ExpDec (Wise lore) class (AliasedOp (OpWithWisdom op), IsOp (OpWithWisdom op)) => CanBeWise op where { type family OpWithWisdom op :: Type; } removeOpWisdom :: CanBeWise op => OpWithWisdom op -> op instance GHC.Generics.Generic Futhark.Optimise.Simplify.Lore.VarWisdom instance GHC.Show.Show Futhark.Optimise.Simplify.Lore.VarWisdom instance GHC.Classes.Ord Futhark.Optimise.Simplify.Lore.VarWisdom instance GHC.Classes.Eq Futhark.Optimise.Simplify.Lore.VarWisdom instance GHC.Generics.Generic Futhark.Optimise.Simplify.Lore.ExpWisdom instance GHC.Show.Show Futhark.Optimise.Simplify.Lore.ExpWisdom instance GHC.Classes.Ord Futhark.Optimise.Simplify.Lore.ExpWisdom instance GHC.Classes.Eq Futhark.Optimise.Simplify.Lore.ExpWisdom instance GHC.Generics.Generic Futhark.Optimise.Simplify.Lore.BodyWisdom instance GHC.Show.Show Futhark.Optimise.Simplify.Lore.BodyWisdom instance GHC.Classes.Ord Futhark.Optimise.Simplify.Lore.BodyWisdom instance GHC.Classes.Eq Futhark.Optimise.Simplify.Lore.BodyWisdom instance (Futhark.IR.Decorations.Decorations lore, Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Decorations.Decorations (Futhark.Optimise.Simplify.Lore.Wise lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.ASTLore (Futhark.Optimise.Simplify.Lore.Wise lore) instance (Futhark.IR.Pretty.PrettyLore lore, Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Pretty.PrettyLore (Futhark.Optimise.Simplify.Lore.Wise lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.Aliases.Aliased (Futhark.Optimise.Simplify.Lore.Wise lore) instance (Futhark.Binder.Class.Bindable lore, Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Decorations.Op lore)) => Futhark.Binder.Class.Bindable (Futhark.Optimise.Simplify.Lore.Wise lore) instance Futhark.Optimise.Simplify.Lore.CanBeWise () instance Language.SexpGrammar.Class.SexpIso Futhark.Optimise.Simplify.Lore.BodyWisdom instance Futhark.Transform.Rename.Rename Futhark.Optimise.Simplify.Lore.BodyWisdom instance Futhark.Transform.Substitute.Substitute Futhark.Optimise.Simplify.Lore.BodyWisdom instance Futhark.IR.Prop.Names.FreeIn Futhark.Optimise.Simplify.Lore.BodyWisdom instance Futhark.IR.Prop.Names.FreeDec Futhark.Optimise.Simplify.Lore.BodyWisdom instance Language.SexpGrammar.Class.SexpIso Futhark.Optimise.Simplify.Lore.ExpWisdom instance Futhark.IR.Prop.Names.FreeIn Futhark.Optimise.Simplify.Lore.ExpWisdom instance Futhark.IR.Prop.Names.FreeDec Futhark.Optimise.Simplify.Lore.ExpWisdom instance Futhark.Transform.Substitute.Substitute Futhark.Optimise.Simplify.Lore.ExpWisdom instance Futhark.Transform.Rename.Rename Futhark.Optimise.Simplify.Lore.ExpWisdom instance Language.SexpGrammar.Class.SexpIso Futhark.Optimise.Simplify.Lore.VarWisdom instance Futhark.Transform.Rename.Rename Futhark.Optimise.Simplify.Lore.VarWisdom instance Futhark.Transform.Substitute.Substitute Futhark.Optimise.Simplify.Lore.VarWisdom instance Futhark.IR.Prop.Names.FreeIn Futhark.Optimise.Simplify.Lore.VarWisdom instance Futhark.IR.Pretty.PrettyAnnot (Futhark.IR.Syntax.Core.PatElemT dec) => Futhark.IR.Pretty.PrettyAnnot (Futhark.IR.Syntax.Core.PatElemT (Futhark.Optimise.Simplify.Lore.VarWisdom, dec)) instance Futhark.IR.Prop.Aliases.AliasesOf (Futhark.Optimise.Simplify.Lore.VarWisdom, dec) -- | Alias analysis of a full Futhark program. Takes as input a program -- with an arbitrary lore and produces one with aliases. This module does -- not implement the aliasing logic itself, and derives its information -- from definitions in Futhark.IR.Prop.Aliases and -- Futhark.IR.Aliases. The alias information computed here will -- include transitive aliases (note that this is not what the building -- blocks do). module Futhark.Analysis.Alias -- | Perform alias analysis on a Futhark program. aliasAnalysis :: (ASTLore lore, CanBeAliased (Op lore)) => Prog lore -> Prog (Aliases lore) -- | Pre-existing aliases for variables. Used to add transitive aliases. type AliasTable = Map VName Names analyseFun :: (ASTLore lore, CanBeAliased (Op lore)) => FunDef lore -> FunDef (Aliases lore) analyseStms :: (ASTLore lore, CanBeAliased (Op lore)) => AliasTable -> Stms lore -> (Stms (Aliases lore), AliasesAndConsumed) analyseExp :: (ASTLore lore, CanBeAliased (Op lore)) => AliasTable -> Exp lore -> Exp (Aliases lore) analyseBody :: (ASTLore lore, CanBeAliased (Op lore)) => AliasTable -> Body lore -> Body (Aliases lore) analyseLambda :: (ASTLore lore, CanBeAliased (Op lore)) => Lambda lore -> Lambda (Aliases lore) -- |

Constructing Futhark ASTs

-- -- This module re-exports and defines a bunch of building blocks for -- constructing fragments of Futhark ASTs. More importantly, it also -- contains a basic introduction on how to use them. -- -- The Futhark.IR.Syntax module contains the core AST definition. -- One important invariant is that all bound names in a Futhark program -- must be globally unique. In principle, you could use the -- facilities from Futhark.MonadFreshNames (or your own bespoke -- source of unique names) to manually construct expressions, statements, -- and entire ASTs. In practice, this would be very tedious. Instead, we -- have defined a collection of building blocks (centered around the -- MonadBinder type class) that permits a more abstract way of -- generating code. -- -- Constructing ASTs with these building blocks requires you to ensure -- that all free variables are in scope. See -- Futhark.IR.Prop.Scope. -- --

MonadBinder

-- -- A monad that implements MonadBinder tracks the statements added -- so far, the current names in scope, and allows you to add additional -- statements with addStm. Any monad that implements -- MonadBinder also implements the Lore type family, which -- indicates which lore it works with. Inside a MonadBinder we can -- use collectStms to gather up the Stms added with -- addStm in some nested computation. -- -- The BinderT monad (and its convenient Binder version) -- provides the simplest implementation of MonadBinder. -- --

Higher-level building blocks

-- -- On top of the raw facilities provided by MonadBinder, we have -- more convenient facilities. For example, letSubExp lets us -- conveniently create a Stm for an Exp that produces a -- single value, and returns the (fresh) name for the resulting -- variable: -- --
--   z <- letExp "z" $ BasicOp $ BinOp (Add Int32) (Var x) (Var y)
--   
-- --

Examples

-- -- The Futhark.Transform.FirstOrderTransform module is a -- (relatively) simple example of how to use these components. As are -- some of the high-level building blocks in this very module. module Futhark.Construct letSubExp :: MonadBinder m => String -> Exp (Lore m) -> m SubExp letSubExps :: MonadBinder m => String -> [Exp (Lore m)] -> m [SubExp] letExp :: MonadBinder m => String -> Exp (Lore m) -> m VName letTupExp :: MonadBinder m => String -> Exp (Lore m) -> m [VName] letTupExp' :: MonadBinder m => String -> Exp (Lore m) -> m [SubExp] letInPlace :: MonadBinder m => String -> VName -> Slice SubExp -> Exp (Lore m) -> m VName eSubExp :: MonadBinder m => SubExp -> m (Exp (Lore m)) eIf :: (MonadBinder m, BranchType (Lore m) ~ ExtType) => m (Exp (Lore m)) -> m (Body (Lore m)) -> m (Body (Lore m)) -> m (Exp (Lore m)) -- | As eIf, but an IfSort can be given. eIf' :: (MonadBinder m, BranchType (Lore m) ~ ExtType) => m (Exp (Lore m)) -> m (Body (Lore m)) -> m (Body (Lore m)) -> IfSort -> m (Exp (Lore m)) eBinOp :: MonadBinder m => BinOp -> m (Exp (Lore m)) -> m (Exp (Lore m)) -> m (Exp (Lore m)) eCmpOp :: MonadBinder m => CmpOp -> m (Exp (Lore m)) -> m (Exp (Lore m)) -> m (Exp (Lore m)) eConvOp :: MonadBinder m => ConvOp -> m (Exp (Lore m)) -> m (Exp (Lore m)) eSignum :: MonadBinder m => m (Exp (Lore m)) -> m (Exp (Lore m)) eCopy :: MonadBinder m => m (Exp (Lore m)) -> m (Exp (Lore m)) eAssert :: MonadBinder m => m (Exp (Lore m)) -> ErrorMsg SubExp -> SrcLoc -> m (Exp (Lore m)) eBody :: MonadBinder m => [m (Exp (Lore m))] -> m (Body (Lore m)) eLambda :: MonadBinder m => Lambda (Lore m) -> [m (Exp (Lore m))] -> m [SubExp] eRoundToMultipleOf :: MonadBinder m => IntType -> m (Exp (Lore m)) -> m (Exp (Lore m)) -> m (Exp (Lore m)) -- | Construct an Index expressions that slices an array with unit -- stride. eSliceArray :: MonadBinder m => Int -> VName -> m (Exp (Lore m)) -> m (Exp (Lore m)) -> m (Exp (Lore m)) -- | Construct an unspecified value of the given type. eBlank :: MonadBinder m => Type -> m (Exp (Lore m)) -- | True if all operands are true. eAll :: MonadBinder m => [SubExp] -> m (Exp (Lore m)) -- | Are these indexes out-of-bounds for the array? eOutOfBounds :: MonadBinder m => VName -> [m (Exp (Lore m))] -> m (Exp (Lore m)) -- | Write to an index of the array, if within bounds. Otherwise, nothing. -- Produces the updated array. eWriteArray :: (MonadBinder m, BranchType (Lore m) ~ ExtType) => VName -> [m (Exp (Lore m))] -> m (Exp (Lore m)) -> m (Exp (Lore m)) -- | Zero-extend to the given integer type. asIntZ :: MonadBinder m => IntType -> SubExp -> m SubExp -- | Sign-extend to the given integer type. asIntS :: MonadBinder m => IntType -> SubExp -> m SubExp -- | Conveniently construct a body that contains no bindings. resultBody :: Bindable lore => [SubExp] -> Body lore -- | Conveniently construct a body that contains no bindings - but this -- time, monadically! resultBodyM :: MonadBinder m => [SubExp] -> m (Body (Lore m)) -- | Evaluate the action, producing a body, then wrap it in all the -- bindings it created using addStm. insertStmsM :: MonadBinder m => m (Body (Lore m)) -> m (Body (Lore m)) -- | Change that result where evaluation of the body would stop. Also -- change type annotations at branches. mapResult :: Bindable lore => (Result -> Body lore) -> Body lore -> Body lore -- | Apply a binary operator to several subexpressions. A left-fold. foldBinOp :: MonadBinder m => BinOp -> SubExp -> [SubExp] -> m (Exp (Lore m)) -- | Create a two-parameter lambda whose body applies the given binary -- operation to its arguments. It is assumed that both argument and -- result types are the same. (This assumption should be fixed at some -- point.) binOpLambda :: (MonadBinder m, Bindable (Lore m)) => BinOp -> PrimType -> m (Lambda (Lore m)) -- | As binOpLambda, but for CmpOps. cmpOpLambda :: (MonadBinder m, Bindable (Lore m)) => CmpOp -> m (Lambda (Lore m)) -- | Slice a full dimension of the given size. sliceDim :: SubExp -> DimIndex SubExp -- | fullSlice t slice returns slice, but with -- DimSlices of entire dimensions appended to the full -- dimensionality of t. This function is used to turn incomplete -- indexing complete, as required by Index. fullSlice :: Type -> [DimIndex SubExp] -> Slice SubExp -- | Like fullSlice, but the dimensions are simply numeric. fullSliceNum :: Num d => [d] -> [DimIndex d] -> Slice d -- | Does the slice describe the full size of the array? The most obvious -- such slice is one that DimSlices the full span of every -- dimension, but also one that fixes all unit dimensions. isFullSlice :: Shape -> Slice SubExp -> Bool -- | sliceAt t n slice returns slice but with -- DimSlices of the outer n dimensions prepended, and as -- many appended as to make it a full slice. This is a generalisation of -- fullSlice. sliceAt :: Type -> Int -> [DimIndex SubExp] -> Slice SubExp ifCommon :: [Type] -> IfDec ExtType -- | Instantiate all existential parts dimensions of the given type, using -- a monadic action to create the necessary SubExps. You should -- call this function within some monad that allows you to collect the -- actions performed (say, Writer). instantiateShapes :: Monad m => (Int -> m SubExp) -> [TypeBase ExtShape u] -> m [TypeBase Shape u] instantiateShapes' :: MonadFreshNames m => [TypeBase ExtShape u] -> m ([TypeBase Shape u], [Ident]) removeExistentials :: ExtType -> Type -> Type -- | Can be used as the definition of mkLetNames for a -- Bindable instance for simple representations. simpleMkLetNames :: (ExpDec lore ~ (), LetDec lore ~ Type, MonadFreshNames m, TypedOp (Op lore), HasScope lore m) => [VName] -> Exp lore -> m (Stm lore) -- | Instances of this class can be converted to Futhark expressions within -- a MonadBinder. class ToExp a toExp :: (ToExp a, MonadBinder m) => a -> m (Exp (Lore m)) -- | A convenient composition of letSubExp and toExp. toSubExp :: (MonadBinder m, ToExp a) => String -> a -> m SubExp instance Futhark.Construct.ToExp Futhark.IR.Syntax.Core.SubExp instance Futhark.Construct.ToExp Language.Futhark.Core.VName -- | The type checker checks whether the program is type-consistent. module Futhark.TypeCheck -- | Type check a program containing arbitrary type information, yielding -- either a type error or a program with complete type information. checkProg :: Checkable lore => Prog (Aliases lore) -> Either (TypeError lore) () -- | A type error. data TypeError lore Error :: [String] -> ErrorCase lore -> TypeError lore -- | Information about an error during type checking. The Show -- instance for this type produces a human-readable description. data ErrorCase lore TypeError :: String -> ErrorCase lore UnexpectedType :: Exp lore -> Type -> [Type] -> ErrorCase lore ReturnTypeError :: Name -> [ExtType] -> [ExtType] -> ErrorCase lore DupDefinitionError :: Name -> ErrorCase lore DupParamError :: Name -> VName -> ErrorCase lore DupPatternError :: VName -> ErrorCase lore InvalidPatternError :: Pattern (Aliases lore) -> [ExtType] -> Maybe String -> ErrorCase lore UnknownVariableError :: VName -> ErrorCase lore UnknownFunctionError :: Name -> ErrorCase lore ParameterMismatch :: Maybe Name -> [Type] -> [Type] -> ErrorCase lore SlicingError :: Int -> Int -> ErrorCase lore BadAnnotation :: String -> Type -> Type -> ErrorCase lore ReturnAliased :: Name -> VName -> ErrorCase lore UniqueReturnAliased :: Name -> ErrorCase lore NotAnArray :: VName -> Type -> ErrorCase lore PermutationError :: [Int] -> Int -> Maybe VName -> ErrorCase lore -- | The type checker runs in this monad. data TypeM lore a bad :: ErrorCase lore -> TypeM lore a -- | Add information about what is being type-checked to the current -- context. Liberal use of this combinator makes it easier to track type -- errors, as the strings are added to type errors signalled via -- bad. context :: String -> TypeM lore a -> TypeM lore a message :: Pretty a => String -> a -> String -- | The class of lores that can be type-checked. class (ASTLore lore, CanBeAliased (Op lore), CheckableOp lore) => Checkable lore checkExpLore :: Checkable lore => ExpDec lore -> TypeM lore () checkBodyLore :: Checkable lore => BodyDec lore -> TypeM lore () checkFParamLore :: Checkable lore => VName -> FParamInfo lore -> TypeM lore () checkLParamLore :: Checkable lore => VName -> LParamInfo lore -> TypeM lore () checkLetBoundLore :: Checkable lore => VName -> LetDec lore -> TypeM lore () checkRetType :: Checkable lore => [RetType lore] -> TypeM lore () matchPattern :: Checkable lore => Pattern (Aliases lore) -> Exp (Aliases lore) -> TypeM lore () primFParam :: Checkable lore => VName -> PrimType -> TypeM lore (FParam (Aliases lore)) matchReturnType :: Checkable lore => [RetType lore] -> Result -> TypeM lore () matchBranchType :: Checkable lore => [BranchType lore] -> Body (Aliases lore) -> TypeM lore () matchLoopResult :: Checkable lore => [FParam (Aliases lore)] -> [FParam (Aliases lore)] -> [SubExp] -> TypeM lore () checkExpLore :: (Checkable lore, ExpDec lore ~ ()) => ExpDec lore -> TypeM lore () checkBodyLore :: (Checkable lore, BodyDec lore ~ ()) => BodyDec lore -> TypeM lore () checkFParamLore :: (Checkable lore, FParamInfo lore ~ DeclType) => VName -> FParamInfo lore -> TypeM lore () checkLParamLore :: (Checkable lore, LParamInfo lore ~ Type) => VName -> LParamInfo lore -> TypeM lore () checkLetBoundLore :: (Checkable lore, LetDec lore ~ Type) => VName -> LetDec lore -> TypeM lore () checkRetType :: (Checkable lore, RetType lore ~ DeclExtType) => [RetType lore] -> TypeM lore () matchPattern :: Checkable lore => Pattern (Aliases lore) -> Exp (Aliases lore) -> TypeM lore () primFParam :: (Checkable lore, FParamInfo lore ~ DeclType) => VName -> PrimType -> TypeM lore (FParam (Aliases lore)) matchReturnType :: (Checkable lore, RetType lore ~ DeclExtType) => [RetType lore] -> Result -> TypeM lore () matchBranchType :: (Checkable lore, BranchType lore ~ ExtType) => [BranchType lore] -> Body (Aliases lore) -> TypeM lore () matchLoopResult :: (Checkable lore, FParamInfo lore ~ DeclType) => [FParam (Aliases lore)] -> [FParam (Aliases lore)] -> [SubExp] -> TypeM lore () class ASTLore lore => CheckableOp lore -- | Used at top level; can be locally changed with checkOpWith. checkOp :: CheckableOp lore => OpWithAliases (Op lore) -> TypeM lore () lookupVar :: VName -> TypeM lore (NameInfo (Aliases lore)) lookupAliases :: Checkable lore => VName -> TypeM lore Names checkOpWith :: (OpWithAliases (Op lore) -> TypeM lore ()) -> TypeM lore a -> TypeM lore a -- | require ts se causes a '(TypeError vn)' if the type of -- se is not a subtype of one of the types in ts. require :: Checkable lore => [Type] -> SubExp -> TypeM lore () -- | Variant of require working on variable names. requireI :: Checkable lore => [Type] -> VName -> TypeM lore () requirePrimExp :: Checkable lore => PrimType -> PrimExp VName -> TypeM lore () checkSubExp :: Checkable lore => SubExp -> TypeM lore Type checkExp :: Checkable lore => Exp (Aliases lore) -> TypeM lore () checkStms :: Checkable lore => Stms (Aliases lore) -> TypeM lore a -> TypeM lore a checkStm :: Checkable lore => Stm (Aliases lore) -> TypeM lore a -> TypeM lore a checkType :: Checkable lore => TypeBase Shape u -> TypeM lore () checkExtType :: Checkable lore => TypeBase ExtShape u -> TypeM lore () matchExtPattern :: Checkable lore => Pattern (Aliases lore) -> [ExtType] -> TypeM lore () matchExtBranchType :: Checkable lore => [ExtType] -> Body (Aliases lore) -> TypeM lore () argType :: Arg -> Type -- | Remove all aliases from the Arg. argAliases :: Arg -> Names noArgAliases :: Arg -> Arg checkArg :: Checkable lore => SubExp -> TypeM lore Arg checkSOACArrayArgs :: Checkable lore => SubExp -> [VName] -> TypeM lore [Arg] checkLambda :: Checkable lore => Lambda (Aliases lore) -> [Arg] -> TypeM lore () checkBody :: Checkable lore => Body (Aliases lore) -> TypeM lore [Names] -- | Proclaim that we have written to the given variables. consume :: Checkable lore => Names -> TypeM lore () -- | Permit consumption of only the specified names. If one of these names -- is consumed, the consumption will be rewritten to be a consumption of -- the corresponding alias set. Consumption of anything else will result -- in a type error. consumeOnlyParams :: [(VName, Names)] -> TypeM lore a -> TypeM lore a binding :: Checkable lore => Scope (Aliases lore) -> TypeM lore a -> TypeM lore a alternative :: TypeM lore a -> TypeM lore b -> TypeM lore (a, b) instance GHC.Show.Show Futhark.TypeCheck.Usage instance GHC.Classes.Ord Futhark.TypeCheck.Usage instance GHC.Classes.Eq Futhark.TypeCheck.Usage instance GHC.Show.Show Futhark.TypeCheck.Occurence instance GHC.Classes.Eq Futhark.TypeCheck.Occurence instance GHC.Show.Show Futhark.TypeCheck.Consumption instance Control.Monad.State.Class.MonadState Futhark.IR.Prop.Names.Names (Futhark.TypeCheck.TypeM lore) instance Control.Monad.Writer.Class.MonadWriter Futhark.TypeCheck.Consumption (Futhark.TypeCheck.TypeM lore) instance Control.Monad.Reader.Class.MonadReader (Futhark.TypeCheck.Env lore) (Futhark.TypeCheck.TypeM lore) instance GHC.Base.Applicative (Futhark.TypeCheck.TypeM lore) instance GHC.Base.Functor (Futhark.TypeCheck.TypeM lore) instance GHC.Base.Monad (Futhark.TypeCheck.TypeM lore) instance Futhark.TypeCheck.Checkable lore => GHC.Show.Show (Futhark.TypeCheck.ErrorCase lore) instance Futhark.TypeCheck.Checkable lore => GHC.Show.Show (Futhark.TypeCheck.TypeError lore) instance Futhark.TypeCheck.Checkable lore => Futhark.IR.Prop.Scope.HasScope (Futhark.IR.Aliases.Aliases lore) (Futhark.TypeCheck.TypeM lore) instance GHC.Base.Semigroup Futhark.TypeCheck.Consumption instance GHC.Base.Monoid Futhark.TypeCheck.Consumption -- | Definition of the core compiler driver building blocks. The spine of -- the compiler is the FutharkM monad, although note that -- individual passes are pure functions, and do not use the -- FutharkM monad (see Futhark.Pass). -- -- Running the compiler involves producing an initial IR program (see -- Futhark.Compiler.Program), running a Pipeline to produce -- a final program (still in IR), then running an Action, which is -- usually a code generator. module Futhark.Pipeline -- | A compiler pipeline is conceptually a function from programs to -- programs, where the actual representation may change. Pipelines can be -- composed using their Category instance. data Pipeline fromlore tolore -- | Configuration object for running a compiler pipeline. data PipelineConfig PipelineConfig :: Bool -> Bool -> PipelineConfig [pipelineVerbose] :: PipelineConfig -> Bool [pipelineValidate] :: PipelineConfig -> Bool -- | A compilation always ends with some kind of action. data Action lore Action :: String -> String -> (Prog lore -> FutharkM ()) -> Action lore [actionName] :: Action lore -> String [actionDescription] :: Action lore -> String [actionProcedure] :: Action lore -> Prog lore -> FutharkM () -- | The main Futhark compiler driver monad - basically some state tracking -- on top if IO. data FutharkM a -- | Run a FutharkM action. runFutharkM :: FutharkM a -> Verbosity -> IO (Either CompilerError a) -- | How much information to print to stderr while the compiler is running. data Verbosity -- | Silence is golden. NotVerbose :: Verbosity -- | Print messages about which pass is running. Verbose :: Verbosity -- | Also print logs from individual passes. VeryVerbose :: Verbosity -- | Construct a pipeline from a single compiler pass. onePass :: Checkable tolore => Pass fromlore tolore -> Pipeline fromlore tolore -- | Create a pipeline from a list of passes. passes :: Checkable lore => [Pass lore lore] -> Pipeline lore lore -- | Run the pipeline on the given program. runPipeline :: Pipeline fromlore tolore -> PipelineConfig -> Prog fromlore -> FutharkM (Prog tolore) instance GHC.Classes.Ord Futhark.Pipeline.Verbosity instance GHC.Classes.Eq Futhark.Pipeline.Verbosity instance Control.Monad.IO.Class.MonadIO Futhark.Pipeline.FutharkM instance Control.Monad.Reader.Class.MonadReader Futhark.Pipeline.FutharkEnv Futhark.Pipeline.FutharkM instance Control.Monad.State.Class.MonadState Futhark.Pipeline.FutharkState Futhark.Pipeline.FutharkM instance Control.Monad.Error.Class.MonadError Futhark.Error.CompilerError Futhark.Pipeline.FutharkM instance GHC.Base.Monad Futhark.Pipeline.FutharkM instance GHC.Base.Functor Futhark.Pipeline.FutharkM instance GHC.Base.Applicative Futhark.Pipeline.FutharkM instance Control.Category.Category Futhark.Pipeline.Pipeline instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Pipeline.FutharkM instance Futhark.Util.Log.MonadLogger Futhark.Pipeline.FutharkM -- | This module exports facilities for transforming array accesses in a -- list of Stms (intended to be the bindings in a body). The idea -- is that you can state that some variable x is in fact an -- array indexing v[i0,i1,...]. module Futhark.Optimise.InPlaceLowering.SubstituteIndices -- | Perform the substitution. substituteIndices :: (MonadFreshNames m, BinderOps lore, Bindable lore, Aliased lore, LetDec lore ~ dec) => IndexSubstitutions dec -> Stms lore -> m (IndexSubstitutions dec, Stms lore) type IndexSubstitution dec = (Certificates, VName, dec, Slice SubExp) type IndexSubstitutions dec = [(VName, IndexSubstitution dec)] -- | Converting back and forth between PrimExps. Use the -- ToExp instance to convert to Futhark expressions. module Futhark.Analysis.PrimExp.Convert -- | Convert an expression to a PrimExp. The provided function is -- used to convert expressions that are not trivially PrimExps. -- This includes constants and variable names, which are passed as -- SubExps. primExpFromExp :: (MonadFail m, Decorations lore) => (VName -> m (PrimExp v)) -> Exp lore -> m (PrimExp v) -- | Convert SubExps of a given type. primExpFromSubExp :: PrimType -> SubExp -> PrimExp VName -- | Shorthand for constructing a TPrimExp of type Int32. pe32 :: SubExp -> TPrimExp Int32 VName -- | Shorthand for constructing a TPrimExp of type Int32, -- from a leaf. le32 :: a -> TPrimExp Int32 a -- | Shorthand for constructing a TPrimExp of type Int64. pe64 :: SubExp -> TPrimExp Int64 VName -- | Shorthand for constructing a TPrimExp of type Int64, -- from a leaf. le64 :: a -> TPrimExp Int64 a -- | Like primExpFromExp, but for a SubExp. primExpFromSubExpM :: Applicative m => (VName -> m (PrimExp v)) -> SubExp -> m (PrimExp v) -- | As replaceInPrimExpM, but in the identity monad. replaceInPrimExp :: (a -> PrimType -> PrimExp b) -> PrimExp a -> PrimExp b -- | Applying a monadic transformation to the leaves in a PrimExp. replaceInPrimExpM :: Monad m => (a -> PrimType -> m (PrimExp b)) -> PrimExp a -> m (PrimExp b) -- | Substituting names in a PrimExp with other PrimExps substituteInPrimExp :: Ord v => Map v (PrimExp v) -> PrimExp v -> PrimExp v -- | Convert a SubExp slice to a PrimExp slice. primExpSlice :: Slice SubExp -> Slice (TPrimExp Int64 VName) -- | Convert a PrimExp slice to a SubExp slice. subExpSlice :: MonadBinder m => Slice (TPrimExp Int64 VName) -> m (Slice SubExp) instance Futhark.Construct.ToExp v => Futhark.Construct.ToExp (Futhark.Analysis.PrimExp.PrimExp v) instance Futhark.Construct.ToExp v => Futhark.Construct.ToExp (Futhark.Analysis.PrimExp.TPrimExp t v) -- | This module contains a representation for the index function based on -- linear-memory accessor descriptors; see Zhu, Hoeflinger and David -- work. module Futhark.IR.Mem.IxFun -- | An index function is a mapping from a multidimensional array index -- space (the domain) to a one-dimensional memory index space. -- Essentially, it explains where the element at position -- [i,j,p] of some array is stored inside the flat -- one-dimensional array that constitutes its memory. For example, we can -- use this to distinguish row-major and column-major representations. -- -- An index function is represented as a sequence of LMADs. data IxFun num IxFun :: NonEmpty (LMAD num) -> Shape num -> Bool -> IxFun num [ixfunLMADs] :: IxFun num -> NonEmpty (LMAD num) [base] :: IxFun num -> Shape num -- | ignoring permutations, is the index function contiguous? [ixfunContig] :: IxFun num -> Bool -- | Compute the flat memory index for a complete set inds of -- array indices and a certain element size elem_size. index :: (IntegralExp num, Eq num) => IxFun num -> Indices num -> num -- | iota. iota :: IntegralExp num => Shape num -> IxFun num -- | Permute dimensions. permute :: IntegralExp num => IxFun num -> Permutation -> IxFun num -- | Rotate an index function. rotate :: (Eq num, IntegralExp num) => IxFun num -> Indices num -> IxFun num -- | Reshape an index function. reshape :: (Eq num, IntegralExp num) => IxFun num -> ShapeChange num -> IxFun num -- | Slice an index function. slice :: (Eq num, IntegralExp num) => IxFun num -> Slice num -> IxFun num -- | Rebase an index function on top of a new base. rebase :: (Eq num, IntegralExp num) => IxFun num -> IxFun num -> IxFun num -- | Shape of an index function. shape :: (Eq num, IntegralExp num) => IxFun num -> Shape num -- | The number of dimensions in the domain of the input function. rank :: IntegralExp num => IxFun num -> Int -- | If the memory support of the index function is contiguous and -- row-major (i.e., no transpositions, repetitions, rotates, etc.), then -- this should return the offset from which the memory-support of this -- index function starts. linearWithOffset :: (Eq num, IntegralExp num) => IxFun num -> num -> Maybe num -- | Similar restrictions to linearWithOffset except for -- transpositions, which are returned together with the offset. rearrangeWithOffset :: (Eq num, IntegralExp num) => IxFun num -> num -> Maybe (num, [(Int, num)]) -- | Is this is a row-major array? isDirect :: (Eq num, IntegralExp num) => IxFun num -> Bool -- | Is this a row-major array starting at offset zero? isLinear :: (Eq num, IntegralExp num) => IxFun num -> Bool -- | Substitute a name with a PrimExp in an index function. substituteInIxFun :: Ord a => Map a (TPrimExp t a) -> IxFun (TPrimExp t a) -> IxFun (TPrimExp t a) -- | Generalization (anti-unification) -- -- Anti-unification of two index functions is supported under the -- following conditions: 0. Both index functions are represented by ONE -- lmad (assumed common case!) 1. The support array of the two indexfuns -- have the same dimensionality (we can relax this condition if we use a -- 1D support, as we probably should!) 2. The contiguous property and the -- per-dimension monotonicity are the same (otherwise we might loose -- important information; this can be relaxed!) 3. Most importantly, both -- index functions correspond to the same permutation (since the -- permutation is represented by INTs, this restriction cannot be -- relaxed, unless we move to a gated-LMAD representation!) leastGeneralGeneralization :: Eq v => IxFun (PrimExp v) -> IxFun (PrimExp v) -> Maybe (IxFun (PrimExp (Ext v)), [(PrimExp v, PrimExp v)]) existentialize :: (IntExp t, Eq v, Pretty v) => IxFun (TPrimExp t v) -> State [TPrimExp t v] (Maybe (IxFun (TPrimExp t (Ext v)))) -- | When comparing index functions as part of the type check in -- KernelsMem, we may run into problems caused by the simplifier. As -- index functions can be generalized over if-then-else expressions, the -- simplifier might hoist some of the code from inside the if-then-else -- (computing the offset of an array, for instance), but now the type -- checker cannot verify that the generalized index function is valid, -- because some of the existentials are computed somewhere else. To Work -- around this, we've had to relax the KernelsMem type-checker a bit, -- specifically, we've introduced this function to verify whether two -- index functions are "close enough" that we can assume that they match. -- We use this instead of `ixfun1 == ixfun2` and hope that it's good -- enough. closeEnough :: IxFun num -> IxFun num -> Bool instance GHC.Generics.Generic Futhark.IR.Mem.IxFun.Monotonicity instance GHC.Classes.Eq Futhark.IR.Mem.IxFun.Monotonicity instance GHC.Show.Show Futhark.IR.Mem.IxFun.Monotonicity instance GHC.Generics.Generic (Futhark.IR.Mem.IxFun.LMADDim num) instance GHC.Classes.Eq num => GHC.Classes.Eq (Futhark.IR.Mem.IxFun.LMADDim num) instance GHC.Show.Show num => GHC.Show.Show (Futhark.IR.Mem.IxFun.LMADDim num) instance GHC.Generics.Generic (Futhark.IR.Mem.IxFun.LMAD num) instance GHC.Classes.Eq num => GHC.Classes.Eq (Futhark.IR.Mem.IxFun.LMAD num) instance GHC.Show.Show num => GHC.Show.Show (Futhark.IR.Mem.IxFun.LMAD num) instance GHC.Generics.Generic (Futhark.IR.Mem.IxFun.IxFun num) instance GHC.Classes.Eq num => GHC.Classes.Eq (Futhark.IR.Mem.IxFun.IxFun num) instance GHC.Show.Show num => GHC.Show.Show (Futhark.IR.Mem.IxFun.IxFun num) instance Language.SexpGrammar.Class.SexpIso num => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Mem.IxFun.IxFun num) instance Text.PrettyPrint.Mainland.Class.Pretty num => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Mem.IxFun.IxFun num) instance Futhark.Transform.Substitute.Substitute num => Futhark.Transform.Substitute.Substitute (Futhark.IR.Mem.IxFun.IxFun num) instance Futhark.Transform.Substitute.Substitute num => Futhark.Transform.Rename.Rename (Futhark.IR.Mem.IxFun.IxFun num) instance Futhark.IR.Prop.Names.FreeIn num => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Mem.IxFun.IxFun num) instance GHC.Base.Functor Futhark.IR.Mem.IxFun.IxFun instance Data.Foldable.Foldable Futhark.IR.Mem.IxFun.IxFun instance Data.Traversable.Traversable Futhark.IR.Mem.IxFun.IxFun instance Language.SexpGrammar.Class.SexpIso num => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Mem.IxFun.LMAD num) instance Text.PrettyPrint.Mainland.Class.Pretty num => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Mem.IxFun.LMAD num) instance Futhark.Transform.Substitute.Substitute num => Futhark.Transform.Substitute.Substitute (Futhark.IR.Mem.IxFun.LMAD num) instance Futhark.Transform.Substitute.Substitute num => Futhark.Transform.Rename.Rename (Futhark.IR.Mem.IxFun.LMAD num) instance Futhark.IR.Prop.Names.FreeIn num => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Mem.IxFun.LMAD num) instance GHC.Base.Functor Futhark.IR.Mem.IxFun.LMAD instance Data.Foldable.Foldable Futhark.IR.Mem.IxFun.LMAD instance Data.Traversable.Traversable Futhark.IR.Mem.IxFun.LMAD instance Language.SexpGrammar.Class.SexpIso num => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Mem.IxFun.LMADDim num) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Mem.IxFun.Monotonicity instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Mem.IxFun.Monotonicity module Futhark.Analysis.SymbolTable data SymbolTable lore empty :: SymbolTable lore fromScope :: ASTLore lore => Scope lore -> SymbolTable lore toScope :: SymbolTable lore -> Scope lore data Entry lore deepen :: SymbolTable lore -> SymbolTable lore entryDepth :: Entry lore -> Int entryLetBoundDec :: Entry lore -> Maybe (LetDec lore) -- | True if this name has been used as an array size, implying that it is -- non-negative. entryIsSize :: Entry lore -> Bool elem :: VName -> SymbolTable lore -> Bool lookup :: VName -> SymbolTable lore -> Maybe (Entry lore) lookupStm :: VName -> SymbolTable lore -> Maybe (Stm lore) lookupExp :: VName -> SymbolTable lore -> Maybe (Exp lore, Certificates) lookupBasicOp :: VName -> SymbolTable lore -> Maybe (BasicOp, Certificates) lookupType :: ASTLore lore => VName -> SymbolTable lore -> Maybe Type lookupSubExp :: VName -> SymbolTable lore -> Maybe (SubExp, Certificates) lookupAliases :: VName -> SymbolTable lore -> Names -- | If the given variable name is the name of a ForLoop parameter, -- then return the bound of that loop. lookupLoopVar :: VName -> SymbolTable lore -> Maybe SubExp lookupLoopParam :: VName -> SymbolTable lore -> Maybe (SubExp, SubExp) -- | In symbol table and not consumed. available :: VName -> SymbolTable lore -> Bool consume :: VName -> SymbolTable lore -> SymbolTable lore index :: ASTLore lore => VName -> [SubExp] -> SymbolTable lore -> Maybe Indexed index' :: VName -> [TPrimExp Int64 VName] -> SymbolTable lore -> Maybe Indexed -- | The result of indexing a delayed array. data Indexed -- | A PrimExp based on the indexes (that is, without accessing any actual -- array). Indexed :: Certificates -> PrimExp VName -> Indexed -- | The indexing corresponds to another (perhaps more advantageous) array. IndexedArray :: Certificates -> VName -> [TPrimExp Int64 VName] -> Indexed indexedAddCerts :: Certificates -> Indexed -> Indexed class IndexOp op indexOp :: (IndexOp op, ASTLore lore, IndexOp (Op lore)) => SymbolTable lore -> Int -> op -> [TPrimExp Int64 VName] -> Maybe Indexed insertStm :: (ASTLore lore, IndexOp (Op lore), Aliased lore) => Stm lore -> SymbolTable lore -> SymbolTable lore insertStms :: (ASTLore lore, IndexOp (Op lore), Aliased lore) => Stms lore -> SymbolTable lore -> SymbolTable lore insertFParams :: ASTLore lore => [FParam lore] -> SymbolTable lore -> SymbolTable lore insertLParam :: ASTLore lore => LParam lore -> SymbolTable lore -> SymbolTable lore insertLoopVar :: ASTLore lore => VName -> IntType -> SubExp -> SymbolTable lore -> SymbolTable lore -- | Insert entries corresponding to the parameters of a loop (not -- distinguishing contect and value part). Apart from the parameter -- itself, we also insert the initial value and the subexpression -- providing the final value. Note that the latter is likely not in scope -- in the symbol at this point. This is OK, and can still be used to help -- some loop optimisations detect invariant loop parameters. insertLoopMerge :: ASTLore lore => [(FParam lore, SubExp, SubExp)] -> SymbolTable lore -> SymbolTable lore -- | Hide these definitions, if they are protected by certificates in the -- set of names. hideCertified :: Names -> SymbolTable lore -> SymbolTable lore instance Futhark.Analysis.SymbolTable.IndexOp () instance GHC.Base.Semigroup (Futhark.Analysis.SymbolTable.SymbolTable lore) instance GHC.Base.Monoid (Futhark.Analysis.SymbolTable.SymbolTable lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.IR.Prop.Types.Typed (Futhark.Analysis.SymbolTable.Entry lore) instance Futhark.IR.Prop.Names.FreeIn Futhark.Analysis.SymbolTable.Indexed -- | This module defines the concept of a simplification rule for bindings. -- The intent is that you pass some context (such as symbol table) and a -- binding, and is given back a sequence of bindings that compute the -- same result, but are "better" in some sense. -- -- These rewrite rules are "local", in that they do not maintain any -- state or look at the program as a whole. Compare this to the fusion -- algorithm in Futhark.Optimise.Fusion.Fusion, which must be -- implemented as its own pass. module Futhark.Optimise.Simplify.Rule -- | The monad in which simplification rules are evaluated. data RuleM lore a cannotSimplify :: RuleM lore a liftMaybe :: Maybe a -> RuleM lore a -- | An efficient way of encoding whether a simplification rule should even -- be attempted. data Rule lore -- | Give it a shot. Simplify :: RuleM lore () -> Rule lore -- | Don't bother. Skip :: Rule lore -- | A simplification rule takes some argument and a statement, and tries -- to simplify the statement. data SimplificationRule lore a RuleGeneric :: RuleGeneric lore a -> SimplificationRule lore a RuleBasicOp :: RuleBasicOp lore a -> SimplificationRule lore a RuleIf :: RuleIf lore a -> SimplificationRule lore a RuleDoLoop :: RuleDoLoop lore a -> SimplificationRule lore a RuleOp :: RuleOp lore a -> SimplificationRule lore a type RuleGeneric lore a = a -> Stm lore -> Rule lore type RuleBasicOp lore a = (a -> Pattern lore -> StmAux (ExpDec lore) -> BasicOp -> Rule lore) type RuleIf lore a = a -> Pattern lore -> StmAux (ExpDec lore) -> (SubExp, BodyT lore, BodyT lore, IfDec (BranchType lore)) -> Rule lore type RuleDoLoop lore a = a -> Pattern lore -> StmAux (ExpDec lore) -> ([(FParam lore, SubExp)], [(FParam lore, SubExp)], LoopForm lore, BodyT lore) -> Rule lore -- | Context for a rule applied during top-down traversal of the program. -- Takes a symbol table as argument. type TopDown lore = SymbolTable lore type TopDownRule lore = SimplificationRule lore (TopDown lore) type TopDownRuleGeneric lore = RuleGeneric lore (TopDown lore) type TopDownRuleBasicOp lore = RuleBasicOp lore (TopDown lore) type TopDownRuleIf lore = RuleIf lore (TopDown lore) type TopDownRuleDoLoop lore = RuleDoLoop lore (TopDown lore) type TopDownRuleOp lore = RuleOp lore (TopDown lore) -- | Context for a rule applied during bottom-up traversal of the program. -- Takes a symbol table and usage table as arguments. type BottomUp lore = (SymbolTable lore, UsageTable) type BottomUpRule lore = SimplificationRule lore (BottomUp lore) type BottomUpRuleGeneric lore = RuleGeneric lore (BottomUp lore) type BottomUpRuleBasicOp lore = RuleBasicOp lore (BottomUp lore) type BottomUpRuleIf lore = RuleIf lore (BottomUp lore) type BottomUpRuleDoLoop lore = RuleDoLoop lore (BottomUp lore) type BottomUpRuleOp lore = RuleOp lore (BottomUp lore) -- | A collection of both top-down and bottom-up rules. data RuleBook lore -- | Construct a rule book from a collection of rules. ruleBook :: [TopDownRule m] -> [BottomUpRule m] -> RuleBook m -- | simplifyStm lookup bnd performs simplification of the binding -- bnd. If simplification is possible, a replacement list of -- bindings is returned, that bind at least the same names as the -- original binding (and possibly more, for intermediate results). topDownSimplifyStm :: (MonadFreshNames m, HasScope lore m) => RuleBook lore -> SymbolTable lore -> Stm lore -> m (Maybe (Stms lore)) -- | simplifyStm uses bnd performs simplification of the binding -- bnd. If simplification is possible, a replacement list of -- bindings is returned, that bind at least the same names as the -- original binding (and possibly more, for intermediate results). The -- first argument is the set of names used after this binding. bottomUpSimplifyStm :: (MonadFreshNames m, HasScope lore m) => RuleBook lore -> (SymbolTable lore, UsageTable) -> Stm lore -> m (Maybe (Stms lore)) instance Futhark.IR.Prop.ASTLore lore => Futhark.IR.Prop.Scope.LocalScope lore (Futhark.Optimise.Simplify.Rule.RuleM lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.IR.Prop.Scope.HasScope lore (Futhark.Optimise.Simplify.Rule.RuleM lore) instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Optimise.Simplify.Rule.RuleM lore) instance GHC.Base.Monad (Futhark.Optimise.Simplify.Rule.RuleM lore) instance GHC.Base.Applicative (Futhark.Optimise.Simplify.Rule.RuleM lore) instance GHC.Base.Functor (Futhark.Optimise.Simplify.Rule.RuleM lore) instance GHC.Base.Semigroup (Futhark.Optimise.Simplify.Rule.RuleBook lore) instance GHC.Base.Monoid (Futhark.Optimise.Simplify.Rule.RuleBook lore) instance GHC.Base.Semigroup (Futhark.Optimise.Simplify.Rule.Rules lore a) instance GHC.Base.Monoid (Futhark.Optimise.Simplify.Rule.Rules lore a) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Binder.BinderOps lore) => Futhark.Binder.Class.MonadBinder (Futhark.Optimise.Simplify.Rule.RuleM lore) -- | This module implements facilities for determining whether a reduction -- or fold can be expressed in a closed form (i.e. not as a SOAC). -- -- Right now, the module can detect only trivial cases. In the future, we -- would like to make it more powerful, as well as possibly also being -- able to analyse sequential loops. module Futhark.Optimise.Simplify.ClosedForm -- | foldClosedForm look foldfun accargs arrargs determines -- whether each of the results of foldfun can be expressed in a -- closed form. foldClosedForm :: (ASTLore lore, BinderOps lore) => VarLookup lore -> Pattern lore -> Lambda lore -> [SubExp] -> [VName] -> RuleM lore () -- | loopClosedForm pat respat merge bound bodys determines -- whether the do-loop can be expressed in a closed form. loopClosedForm :: (ASTLore lore, BinderOps lore) => Pattern lore -> [(FParam lore, SubExp)] -> Names -> IntType -> SubExp -> Body lore -> RuleM lore () -- | A function that, given a variable name, returns its definition. type VarLookup lore = VName -> Maybe (Exp lore, Certificates) -- | This module defines a collection of simplification rules, as per -- Futhark.Optimise.Simplify.Rule. They are used in the -- simplifier. -- -- For performance reasons, many sufficiently simple logically separate -- rules are merged into single "super-rules", like ruleIf and -- ruleBasicOp. This is because it is relatively expensive to activate a -- rule just to determine that it does not apply. Thus, it is more -- efficient to have a few very fat rules than a lot of small rules. This -- does not affect the compiler result in any way; it is purely an -- optimisation to speed up compilation. module Futhark.Optimise.Simplify.Rules -- | A set of standard simplification rules. These assume pure functional -- semantics, and so probably should not be applied after memory block -- merging. standardRules :: (BinderOps lore, Aliased lore) => RuleBook lore -- | Turn copy(x) into x iff x is not used after -- this copy statement and it can be consumed. -- -- This simplistic rule is only valid before we introduce memory. removeUnnecessaryCopy :: BinderOps lore => BottomUpRuleBasicOp lore -- | Perform general rule-based simplification based on data dependency -- information. This module will: -- -- -- -- If you just want to run the simplifier as simply as possible, you may -- prefer to use the Futhark.Optimise.Simplify module. module Futhark.Optimise.Simplify.Engine data SimpleM lore a runSimpleM :: SimpleM lore a -> SimpleOps lore -> Env lore -> VNameSource -> ((a, Bool), VNameSource) data SimpleOps lore SimpleOps :: (SymbolTable (Wise lore) -> Pattern (Wise lore) -> Exp (Wise lore) -> SimpleM lore (ExpDec (Wise lore))) -> (SymbolTable (Wise lore) -> Stms (Wise lore) -> Result -> SimpleM lore (Body (Wise lore))) -> Protect (Binder (Wise lore)) -> (Op (Wise lore) -> UsageTable) -> SimplifyOp lore (Op lore) -> SimpleOps lore [mkExpDecS] :: SimpleOps lore -> SymbolTable (Wise lore) -> Pattern (Wise lore) -> Exp (Wise lore) -> SimpleM lore (ExpDec (Wise lore)) [mkBodyS] :: SimpleOps lore -> SymbolTable (Wise lore) -> Stms (Wise lore) -> Result -> SimpleM lore (Body (Wise lore)) -- | Make a hoisted Op safe. The SubExp is a boolean that is true when the -- value of the statement will actually be used. [protectHoistedOpS] :: SimpleOps lore -> Protect (Binder (Wise lore)) [opUsageS] :: SimpleOps lore -> Op (Wise lore) -> UsageTable [simplifyOpS] :: SimpleOps lore -> SimplifyOp lore (Op lore) type SimplifyOp lore op = op -> SimpleM lore (OpWithWisdom op, Stms (Wise lore)) bindableSimpleOps :: (SimplifiableLore lore, Bindable lore) => SimplifyOp lore (Op lore) -> SimpleOps lore data Env lore emptyEnv :: RuleBook (Wise lore) -> HoistBlockers lore -> Env lore data HoistBlockers lore HoistBlockers :: BlockPred (Wise lore) -> BlockPred (Wise lore) -> BlockPred (Wise lore) -> (Stm (Wise lore) -> Bool) -> HoistBlockers lore -- | Blocker for hoisting out of parallel loops. [blockHoistPar] :: HoistBlockers lore -> BlockPred (Wise lore) -- | Blocker for hoisting out of sequential loops. [blockHoistSeq] :: HoistBlockers lore -> BlockPred (Wise lore) -- | Blocker for hoisting out of branches. [blockHoistBranch] :: HoistBlockers lore -> BlockPred (Wise lore) [isAllocation] :: HoistBlockers lore -> Stm (Wise lore) -> Bool neverBlocks :: BlockPred lore noExtraHoistBlockers :: HoistBlockers lore neverHoist :: HoistBlockers lore type BlockPred lore = SymbolTable lore -> UsageTable -> Stm lore -> Bool orIf :: BlockPred lore -> BlockPred lore -> BlockPred lore hasFree :: ASTLore lore => Names -> BlockPred lore isConsumed :: BlockPred lore isFalse :: Bool -> BlockPred lore isOp :: BlockPred lore isNotSafe :: ASTLore lore => BlockPred lore asksEngineEnv :: (Env lore -> a) -> SimpleM lore a askVtable :: SimpleM lore (SymbolTable (Wise lore)) localVtable :: (SymbolTable (Wise lore) -> SymbolTable (Wise lore)) -> SimpleM lore a -> SimpleM lore a type SimplifiableLore lore = (ASTLore lore, Simplifiable (LetDec lore), Simplifiable (FParamInfo lore), Simplifiable (LParamInfo lore), Simplifiable (RetType lore), Simplifiable (BranchType lore), CanBeWise (Op lore), IndexOp (OpWithWisdom (Op lore)), BinderOps (Wise lore), IsOp (Op lore)) class Simplifiable e simplify :: (Simplifiable e, SimplifiableLore lore) => e -> SimpleM lore e simplifyStms :: SimplifiableLore lore => Stms lore -> SimpleM lore (a, Stms (Wise lore)) -> SimpleM lore (a, Stms (Wise lore)) simplifyFun :: SimplifiableLore lore => FunDef lore -> SimpleM lore (FunDef (Wise lore)) simplifyLambda :: SimplifiableLore lore => Lambda lore -> SimpleM lore (Lambda (Wise lore), Stms (Wise lore)) simplifyLambdaNoHoisting :: SimplifiableLore lore => Lambda lore -> SimpleM lore (Lambda (Wise lore)) bindLParams :: SimplifiableLore lore => [LParam (Wise lore)] -> SimpleM lore a -> SimpleM lore a -- | Simplify a single body. The [Diet] only covers the value -- elements, because the context cannot be consumed. simplifyBody :: SimplifiableLore lore => [Diet] -> Body lore -> SimpleM lore (SimplifiedBody lore Result) type SimplifiedBody lore a = ((a, UsageTable), Stms (Wise lore)) data SymbolTable lore hoistStms :: SimplifiableLore lore => RuleBook (Wise lore) -> BlockPred (Wise lore) -> SymbolTable (Wise lore) -> UsageTable -> Stms (Wise lore) -> SimpleM lore (Stms (Wise lore), Stms (Wise lore)) blockIf :: SimplifiableLore lore => BlockPred (Wise lore) -> SimpleM lore (SimplifiedBody lore a) -> SimpleM lore ((Stms (Wise lore), a), Stms (Wise lore)) instance Control.Monad.State.Class.MonadState (Futhark.FreshNames.VNameSource, GHC.Types.Bool, Futhark.IR.Syntax.Core.Certificates) (Futhark.Optimise.Simplify.Engine.SimpleM lore) instance Control.Monad.Reader.Class.MonadReader (Futhark.Optimise.Simplify.Engine.SimpleOps lore, Futhark.Optimise.Simplify.Engine.Env lore) (Futhark.Optimise.Simplify.Engine.SimpleM lore) instance GHC.Base.Monad (Futhark.Optimise.Simplify.Engine.SimpleM lore) instance GHC.Base.Functor (Futhark.Optimise.Simplify.Engine.SimpleM lore) instance GHC.Base.Applicative (Futhark.Optimise.Simplify.Engine.SimpleM lore) instance Futhark.Optimise.Simplify.Engine.SimplifiableLore lore => Futhark.IR.Prop.Scope.HasScope (Futhark.Optimise.Simplify.Lore.Wise lore) (Futhark.Optimise.Simplify.Engine.SimpleM lore) instance Futhark.Optimise.Simplify.Engine.SimplifiableLore lore => Futhark.IR.Prop.Scope.LocalScope (Futhark.Optimise.Simplify.Lore.Wise lore) (Futhark.Optimise.Simplify.Engine.SimpleM lore) instance (Futhark.Optimise.Simplify.Engine.Simplifiable a, Futhark.Optimise.Simplify.Engine.Simplifiable b) => Futhark.Optimise.Simplify.Engine.Simplifiable (a, b) instance (Futhark.Optimise.Simplify.Engine.Simplifiable a, Futhark.Optimise.Simplify.Engine.Simplifiable b, Futhark.Optimise.Simplify.Engine.Simplifiable c) => Futhark.Optimise.Simplify.Engine.Simplifiable (a, b, c) instance Futhark.Optimise.Simplify.Engine.Simplifiable GHC.Types.Int instance Futhark.Optimise.Simplify.Engine.Simplifiable a => Futhark.Optimise.Simplify.Engine.Simplifiable (GHC.Maybe.Maybe a) instance Futhark.Optimise.Simplify.Engine.Simplifiable a => Futhark.Optimise.Simplify.Engine.Simplifiable [a] instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.Syntax.Core.SubExp instance Futhark.Optimise.Simplify.Engine.Simplifiable () instance Futhark.Optimise.Simplify.Engine.Simplifiable Language.Futhark.Core.VName instance Futhark.Optimise.Simplify.Engine.Simplifiable d => Futhark.Optimise.Simplify.Engine.Simplifiable (Futhark.IR.Syntax.Core.ShapeBase d) instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.Syntax.Core.ExtSize instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.Syntax.Core.Space instance Futhark.Optimise.Simplify.Engine.Simplifiable shape => Futhark.Optimise.Simplify.Engine.Simplifiable (Futhark.IR.Syntax.Core.TypeBase shape u) instance Futhark.Optimise.Simplify.Engine.Simplifiable d => Futhark.Optimise.Simplify.Engine.Simplifiable (Futhark.IR.Syntax.Core.DimIndex d) instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.Syntax.Core.Certificates instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Optimise.Simplify.Engine.SimpleM lore) -- | Defines simplification functions for PrimExps. module Futhark.Analysis.PrimExp.Simplify -- | Simplify a PrimExp, including copy propagation. If a -- LeafExp refers to a name that is a Constant, the node -- turns into a ValueExp. simplifyPrimExp :: SimplifiableLore lore => PrimExp VName -> SimpleM lore (PrimExp VName) -- | Like simplifyPrimExp, but where leaves may be Exts. simplifyExtPrimExp :: SimplifiableLore lore => PrimExp (Ext VName) -> SimpleM lore (PrimExp (Ext VName)) module Futhark.Optimise.Simplify -- | Simplify the given program. Even if the output differs from the -- output, meaningful simplification may not have taken place - the order -- of bindings may simply have been rearranged. simplifyProg :: SimplifiableLore lore => SimpleOps lore -> RuleBook (Wise lore) -> HoistBlockers lore -> Prog lore -> PassM (Prog lore) -- | Run a simplification operation to convergence. simplifySomething :: (MonadFreshNames m, SimplifiableLore lore) => (a -> SimpleM lore b) -> (b -> a) -> SimpleOps lore -> RuleBook (Wise lore) -> HoistBlockers lore -> SymbolTable (Wise lore) -> a -> m a -- | Simplify the given function. Even if the output differs from the -- output, meaningful simplification may not have taken place - the order -- of bindings may simply have been rearranged. Runs in a loop until -- convergence. simplifyFun :: (MonadFreshNames m, SimplifiableLore lore) => SimpleOps lore -> RuleBook (Wise lore) -> HoistBlockers lore -> SymbolTable (Wise lore) -> FunDef lore -> m (FunDef lore) -- | Simplify just a single Lambda. simplifyLambda :: (MonadFreshNames m, HasScope lore m, SimplifiableLore lore) => SimpleOps lore -> RuleBook (Wise lore) -> HoistBlockers lore -> Lambda lore -> m (Lambda lore) -- | Simplify a sequence of Stms. simplifyStms :: (MonadFreshNames m, SimplifiableLore lore) => SimpleOps lore -> RuleBook (Wise lore) -> HoistBlockers lore -> Scope lore -> Stms lore -> m (SymbolTable (Wise lore), Stms lore) data SimpleOps lore SimpleOps :: (SymbolTable (Wise lore) -> Pattern (Wise lore) -> Exp (Wise lore) -> SimpleM lore (ExpDec (Wise lore))) -> (SymbolTable (Wise lore) -> Stms (Wise lore) -> Result -> SimpleM lore (Body (Wise lore))) -> Protect (Binder (Wise lore)) -> (Op (Wise lore) -> UsageTable) -> SimplifyOp lore (Op lore) -> SimpleOps lore [mkExpDecS] :: SimpleOps lore -> SymbolTable (Wise lore) -> Pattern (Wise lore) -> Exp (Wise lore) -> SimpleM lore (ExpDec (Wise lore)) [mkBodyS] :: SimpleOps lore -> SymbolTable (Wise lore) -> Stms (Wise lore) -> Result -> SimpleM lore (Body (Wise lore)) -- | Make a hoisted Op safe. The SubExp is a boolean that is true when the -- value of the statement will actually be used. [protectHoistedOpS] :: SimpleOps lore -> Protect (Binder (Wise lore)) [opUsageS] :: SimpleOps lore -> Op (Wise lore) -> UsageTable [simplifyOpS] :: SimpleOps lore -> SimplifyOp lore (Op lore) data SimpleM lore a type SimplifyOp lore op = op -> SimpleM lore (OpWithWisdom op, Stms (Wise lore)) bindableSimpleOps :: (SimplifiableLore lore, Bindable lore) => SimplifyOp lore (Op lore) -> SimpleOps lore noExtraHoistBlockers :: HoistBlockers lore neverHoist :: HoistBlockers lore type SimplifiableLore lore = (ASTLore lore, Simplifiable (LetDec lore), Simplifiable (FParamInfo lore), Simplifiable (LParamInfo lore), Simplifiable (RetType lore), Simplifiable (BranchType lore), CanBeWise (Op lore), IndexOp (OpWithWisdom (Op lore)), BinderOps (Wise lore), IsOp (Op lore)) data HoistBlockers lore -- | A collection of both top-down and bottom-up rules. data RuleBook lore -- | Perform copy propagation. This is done by invoking the simplifier with -- no rules, so hoisting and dead-code elimination may also take place. module Futhark.Transform.CopyPropagate -- | Run copy propagation on an entire program. copyPropagateInProg :: SimplifiableLore lore => SimpleOps lore -> Prog lore -> PassM (Prog lore) -- | Run copy propagation on some statements. copyPropagateInStms :: (MonadFreshNames m, SimplifiableLore lore) => SimpleOps lore -> Scope lore -> Stms lore -> m (SymbolTable (Wise lore), Stms lore) -- | Run copy propagation on a function. copyPropagateInFun :: (MonadFreshNames m, SimplifiableLore lore) => SimpleOps lore -> SymbolTable (Wise lore) -> FunDef lore -> m (FunDef lore) -- | A sequential representation. module Futhark.IR.Seq -- | The phantom type for the Seq representation. data Seq -- | Simplify a sequential program. simplifyProg :: Prog Seq -> PassM (Prog Seq) instance Futhark.IR.Decorations.Decorations Futhark.IR.Seq.Seq instance Futhark.IR.Prop.ASTLore Futhark.IR.Seq.Seq instance Futhark.TypeCheck.CheckableOp Futhark.IR.Seq.Seq instance Futhark.TypeCheck.Checkable Futhark.IR.Seq.Seq instance Futhark.Binder.Class.Bindable Futhark.IR.Seq.Seq instance Futhark.Binder.BinderOps Futhark.IR.Seq.Seq instance Futhark.IR.Pretty.PrettyLore Futhark.IR.Seq.Seq instance Futhark.Binder.BinderOps (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.Seq.Seq) -- | Definition of Second-Order Array Combinators (SOACs), which are -- the main form of parallelism in the early stages of the compiler. module Futhark.IR.SOACS.SOAC -- | A second-order array combinator (SOAC). data SOAC lore Stream :: SubExp -> StreamForm lore -> Lambda lore -> [VName] -> SOAC lore -- |
--   Scatter cs length lambda index and value arrays
--   
-- -- <input/output arrays along with their sizes and number of values to -- write for that array> -- -- length is the length of each index array and value array, since -- they all must be the same length for any fusion to make sense. If you -- have a list of index-value array pairs of different sizes, you need to -- use multiple writes instead. -- -- The lambda body returns the output in this manner: -- -- -- -- This must be consistent along all Scatter-related optimisations. Scatter :: SubExp -> Lambda lore -> [VName] -> [(SubExp, Int, VName)] -> SOAC lore -- |
--   Hist length dest-arrays-and-ops fun arrays
--   
-- -- The first SubExp is the length of the input arrays. The first list -- describes the operations to perform. The Lambda is the bucket -- function. Finally comes the input images. Hist :: SubExp -> [HistOp lore] -> Lambda lore -> [VName] -> SOAC lore -- | A combination of scan, reduction, and map. The first SubExp is -- the size of the input arrays. Screma :: SubExp -> ScremaForm lore -> [VName] -> SOAC lore -- | Is the stream chunk required to correspond to a contiguous subsequence -- of the original input (InOrder) or not? Disorder streams -- can be more efficient, but not all algorithms work with this. data StreamOrd InOrder :: StreamOrd Disorder :: StreamOrd -- | What kind of stream is this? data StreamForm lore Parallel :: StreamOrd -> Commutativity -> Lambda lore -> [SubExp] -> StreamForm lore Sequential :: [SubExp] -> StreamForm lore -- | The essential parts of a Screma factored out (everything except -- the input arrays). data ScremaForm lore ScremaForm :: [Scan lore] -> [Reduce lore] -> Lambda lore -> ScremaForm lore -- | Information about computing a single histogram. data HistOp lore HistOp :: SubExp -> SubExp -> [VName] -> [SubExp] -> Lambda lore -> HistOp lore [histWidth] :: HistOp lore -> SubExp -- | Race factor RF means that only 1/RF bins are used. [histRaceFactor] :: HistOp lore -> SubExp [histDest] :: HistOp lore -> [VName] [histNeutral] :: HistOp lore -> [SubExp] [histOp] :: HistOp lore -> Lambda lore -- | How to compute a single scan result. data Scan lore Scan :: Lambda lore -> [SubExp] -> Scan lore [scanLambda] :: Scan lore -> Lambda lore [scanNeutral] :: Scan lore -> [SubExp] -- | How many reduction results are produced by these Scans? scanResults :: [Scan lore] -> Int -- | Combine multiple scan operators to a single operator. singleScan :: Bindable lore => [Scan lore] -> Scan lore -- | How to compute a single reduction result. data Reduce lore Reduce :: Commutativity -> Lambda lore -> [SubExp] -> Reduce lore [redComm] :: Reduce lore -> Commutativity [redLambda] :: Reduce lore -> Lambda lore [redNeutral] :: Reduce lore -> [SubExp] -- | How many reduction results are produced by these Reduces? redResults :: [Reduce lore] -> Int -- | Combine multiple reduction operators to a single operator. singleReduce :: Bindable lore => [Reduce lore] -> Reduce lore -- | Get Stream's accumulators as a sub-expression list getStreamAccums :: StreamForm lore -> [SubExp] -- | The types produced by a single Screma, given the size of the -- input array. scremaType :: SubExp -> ScremaForm lore -> [Type] -- | The type of a SOAC. soacType :: SOAC lore -> [Type] -- | Type-check a SOAC. typeCheckSOAC :: Checkable lore => SOAC (Aliases lore) -> TypeM lore () -- | Construct a lambda that takes parameters of the given types and simply -- returns them unchanged. mkIdentityLambda :: (Bindable lore, MonadFreshNames m) => [Type] -> m (Lambda lore) -- | Is the given lambda an identity lambda? isIdentityLambda :: Lambda lore -> Bool -- | A lambda with no parameters that returns no values. nilFn :: Bindable lore => Lambda lore -- | Construct a Screma with possibly multiple scans, and the given map -- function. scanomapSOAC :: [Scan lore] -> Lambda lore -> ScremaForm lore -- | Construct a Screma with possibly multiple reductions, and the given -- map function. redomapSOAC :: [Reduce lore] -> Lambda lore -> ScremaForm lore -- | Construct a Screma with possibly multiple scans, and identity map -- function. scanSOAC :: (Bindable lore, MonadFreshNames m) => [Scan lore] -> m (ScremaForm lore) -- | Construct a Screma with possibly multiple reductions, and identity map -- function. reduceSOAC :: (Bindable lore, MonadFreshNames m) => [Reduce lore] -> m (ScremaForm lore) -- | Construct a Screma corresponding to a map. mapSOAC :: Lambda lore -> ScremaForm lore -- | Does this Screma correspond to a scan-map composition? isScanomapSOAC :: ScremaForm lore -> Maybe ([Scan lore], Lambda lore) -- | Does this Screma correspond to a reduce-map composition? isRedomapSOAC :: ScremaForm lore -> Maybe ([Reduce lore], Lambda lore) -- | Does this Screma correspond to pure scan? isScanSOAC :: ScremaForm lore -> Maybe [Scan lore] -- | Does this Screma correspond to a pure reduce? isReduceSOAC :: ScremaForm lore -> Maybe [Reduce lore] -- | Does this Screma correspond to a simple map, without any reduction or -- scan results? isMapSOAC :: ScremaForm lore -> Maybe (Lambda lore) -- | Prettyprint the given Screma. ppScrema :: (PrettyLore lore, Pretty inp) => SubExp -> ScremaForm lore -> [inp] -> Doc -- | Prettyprint the given histogram operation. ppHist :: (PrettyLore lore, Pretty inp) => SubExp -> [HistOp lore] -> Lambda lore -> [inp] -> Doc -- | Like Mapper, but just for SOACs. data SOACMapper flore tlore m SOACMapper :: (SubExp -> m SubExp) -> (Lambda flore -> m (Lambda tlore)) -> (VName -> m VName) -> SOACMapper flore tlore m [mapOnSOACSubExp] :: SOACMapper flore tlore m -> SubExp -> m SubExp [mapOnSOACLambda] :: SOACMapper flore tlore m -> Lambda flore -> m (Lambda tlore) [mapOnSOACVName] :: SOACMapper flore tlore m -> VName -> m VName -- | A mapper that simply returns the SOAC verbatim. identitySOACMapper :: Monad m => SOACMapper lore lore m -- | Map a monadic action across the immediate children of a SOAC. The -- mapping does not descend recursively into subexpressions and is done -- left-to-right. mapSOACM :: (Applicative m, Monad m) => SOACMapper flore tlore m -> SOAC flore -> m (SOAC tlore) instance GHC.Generics.Generic (Futhark.IR.SOACS.SOAC.HistOp lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.SOACS.SOAC.HistOp lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.HistOp lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.HistOp lore) instance GHC.Generics.Generic Futhark.IR.SOACS.SOAC.StreamOrd instance GHC.Show.Show Futhark.IR.SOACS.SOAC.StreamOrd instance GHC.Classes.Ord Futhark.IR.SOACS.SOAC.StreamOrd instance GHC.Classes.Eq Futhark.IR.SOACS.SOAC.StreamOrd instance GHC.Generics.Generic (Futhark.IR.SOACS.SOAC.StreamForm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.SOACS.SOAC.StreamForm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.StreamForm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.StreamForm lore) instance GHC.Generics.Generic (Futhark.IR.SOACS.SOAC.Scan lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.SOACS.SOAC.Scan lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.Scan lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.Scan lore) instance GHC.Generics.Generic (Futhark.IR.SOACS.SOAC.Reduce lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.SOACS.SOAC.Reduce lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.Reduce lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.Reduce lore) instance GHC.Generics.Generic (Futhark.IR.SOACS.SOAC.ScremaForm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.SOACS.SOAC.ScremaForm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.ScremaForm lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.ScremaForm lore) instance GHC.Generics.Generic (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.Transform.Substitute.Substitute (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.Transform.Rename.Rename (Futhark.IR.SOACS.SOAC.SOAC lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.ASTLore (Futhark.IR.Aliases.Aliases lore), Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore)) => Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.SOACS.SOAC.SOAC lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Decorations.Op lore)) => Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Prop.TypeOf.TypedOp (Futhark.IR.SOACS.SOAC.SOAC lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Aliases.Aliased lore) => Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.IR.Prop.IsOp (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Decorations.Decorations lore => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Decorations.Op lore) => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.SOACS.SOAC.SOAC lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SOACS.SOAC.ScremaForm lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SOACS.SOAC.Reduce lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.SOACS.SOAC.Reduce lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SOACS.SOAC.Scan lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.SOACS.SOAC.Scan lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SOACS.SOAC.StreamForm lore) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.SOACS.SOAC.StreamOrd instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SOACS.SOAC.HistOp lore) -- | An unstructured grab-bag of various tools and inspection functions -- that didn't really fit anywhere else. module Futhark.Tools -- | Turns a binding of a redomap into two seperate bindings, a -- map binding and a reduce binding (returned in that -- order). -- -- Reuses the original pattern for the reduce, and creates a new -- pattern with new Idents for the result of the map. -- -- Only handles a pattern with an empty patternContextElements. redomapToMapAndReduce :: (MonadFreshNames m, Bindable lore, ExpDec lore ~ (), Op lore ~ SOAC lore) => Pattern lore -> (SubExp, Commutativity, LambdaT lore, LambdaT lore, [SubExp], [VName]) -> m (Stm lore, Stm lore) -- | Turn a Screma into a Scanomap (possibly with mapout parts) and a -- Redomap. This is used to handle Scremas that are so complicated that -- we cannot directly generate efficient parallel code for them. In -- essense, what happens is the opposite of horisontal fusion. dissectScrema :: (MonadBinder m, Op (Lore m) ~ SOAC (Lore m), Bindable (Lore m)) => Pattern (Lore m) -> SubExp -> ScremaForm (Lore m) -> [VName] -> m () -- | Turn a stream SOAC into statements that apply the stream lambda to the -- entire input. sequentialStreamWholeArray :: (MonadBinder m, Bindable (Lore m)) => Pattern (Lore m) -> SubExp -> [SubExp] -> LambdaT (Lore m) -> [VName] -> m () -- | Split the parameters of a stream reduction lambda into the chunk size -- parameter, the accumulator parameters, and the input chunk parameters. -- The integer argument is how many accumulators are used. partitionChunkedFoldParameters :: Int -> [Param dec] -> (Param dec, [Param dec], [Param dec]) -- | A simple representation with SOACs and nested parallelism. module Futhark.IR.SOACS -- | The lore for the basic representation. data SOACS type Body = Body SOACS type Stm = Stm SOACS type Pattern = Pattern SOACS type Exp = Exp SOACS type Lambda = Lambda SOACS type FParam = FParam SOACS type LParam = LParam SOACS type RetType = RetType SOACS type PatElem = PatElem SOACS -- | 8-bit signed integer type data Int8 -- | 16-bit signed integer type data Int16 -- | 32-bit signed integer type data Int32 -- | 64-bit signed integer type data Int64 -- | 8-bit unsigned integer type data Word8 -- | 16-bit unsigned integer type data Word16 -- | 32-bit unsigned integer type data Word32 -- | 64-bit unsigned integer type data Word64 -- | The SrcLoc of a Located value. srclocOf :: Located a => a -> SrcLoc -- | Location type, consisting of a beginning position and an end position. data Loc -- | Source location type. Source location are all equal, which allows AST -- nodes to be compared modulo location information. data SrcLoc -- | Located values have a location. class Located a locOf :: Located a => a -> Loc locOfList :: Located a => [a] -> Loc -- | Prettyprint a value, wrapped to 80 characters. pretty :: Pretty a => a -> String -- | Conversion operators try to generalise the from t0 x to t1 -- instructions from LLVM. data ConvOp -- | Zero-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. ZExt :: IntType -> IntType -> ConvOp -- | Sign-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. SExt :: IntType -> IntType -> ConvOp -- | Convert value of the former floating-point type to the latter. If the -- new type is smaller, the result is a truncation. FPConv :: FloatType -> FloatType -> ConvOp -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). FPToUI :: FloatType -> IntType -> ConvOp -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). FPToSI :: FloatType -> IntType -> ConvOp -- | Convert an unsigned integer to a floating-point value. UIToFP :: IntType -> FloatType -> ConvOp -- | Convert a signed integer to a floating-point value. SIToFP :: IntType -> FloatType -> ConvOp -- | Convert an integer to a boolean value. Zero becomes false; anything -- else is true. IToB :: IntType -> ConvOp -- | Convert a boolean to an integer. True is converted to 1 and False to -- 0. BToI :: IntType -> ConvOp -- | Comparison operators are like BinOps, but they always return a -- boolean value. The somewhat ugly constructor names are straight out of -- LLVM. data CmpOp -- | All types equality. CmpEq :: PrimType -> CmpOp -- | Unsigned less than. CmpUlt :: IntType -> CmpOp -- | Unsigned less than or equal. CmpUle :: IntType -> CmpOp -- | Signed less than. CmpSlt :: IntType -> CmpOp -- | Signed less than or equal. CmpSle :: IntType -> CmpOp -- | Floating-point less than. FCmpLt :: FloatType -> CmpOp -- | Floating-point less than or equal. FCmpLe :: FloatType -> CmpOp -- | Boolean less than. CmpLlt :: CmpOp -- | Boolean less than or equal. CmpLle :: CmpOp -- | Binary operators. These correspond closely to the binary operators in -- LLVM. Most are parametrised by their expected input and output types. data BinOp -- | Integer addition. Add :: IntType -> Overflow -> BinOp -- | Floating-point addition. FAdd :: FloatType -> BinOp -- | Integer subtraction. Sub :: IntType -> Overflow -> BinOp -- | Floating-point subtraction. FSub :: FloatType -> BinOp -- | Integer multiplication. Mul :: IntType -> Overflow -> BinOp -- | Floating-point multiplication. FMul :: FloatType -> BinOp -- | Unsigned integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. UDiv :: IntType -> Safety -> BinOp -- | Unsigned integer division. Rounds towards positive infinity. UDivUp :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. SDiv :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards positive infinity. SDivUp :: IntType -> Safety -> BinOp -- | Floating-point division. FDiv :: FloatType -> BinOp -- | Floating-point modulus. FMod :: FloatType -> BinOp -- | Unsigned integer modulus; the countepart to UDiv. UMod :: IntType -> Safety -> BinOp -- | Signed integer modulus; the countepart to SDiv. SMod :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- sdiv instruction in LLVM and integer division in C. SQuot :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- srem instruction in LLVM and integer modulo in C. SRem :: IntType -> Safety -> BinOp -- | Returns the smallest of two signed integers. SMin :: IntType -> BinOp -- | Returns the smallest of two unsigned integers. UMin :: IntType -> BinOp -- | Returns the smallest of two floating-point numbers. FMin :: FloatType -> BinOp -- | Returns the greatest of two signed integers. SMax :: IntType -> BinOp -- | Returns the greatest of two unsigned integers. UMax :: IntType -> BinOp -- | Returns the greatest of two floating-point numbers. FMax :: FloatType -> BinOp -- | Left-shift. Shl :: IntType -> BinOp -- | Logical right-shift, zero-extended. LShr :: IntType -> BinOp -- | Arithmetic right-shift, sign-extended. AShr :: IntType -> BinOp -- | Bitwise and. And :: IntType -> BinOp -- | Bitwise or. Or :: IntType -> BinOp -- | Bitwise exclusive-or. Xor :: IntType -> BinOp -- | Integer exponentiation. Pow :: IntType -> BinOp -- | Floating-point exponentiation. FPow :: FloatType -> BinOp -- | Boolean and - not short-circuiting. LogAnd :: BinOp -- | Boolean or - not short-circuiting. LogOr :: BinOp -- | Whether something is safe or unsafe (mostly function calls, and in the -- context of whether operations are dynamically checked). When we inline -- an Unsafe function, we remove all safety checks in its body. -- The Ord instance picks Unsafe as being less than -- Safe. -- -- For operations like integer division, a safe division will not explode -- the computer in case of division by zero, but instead return some -- unspecified value. This always involves a run-time check, so generally -- the unsafe variant is what the compiler will insert, but guarded by an -- explicit assertion elsewhere. Safe operations are useful when the -- optimiser wants to move e.g. a division to a location where the -- divisor may be zero, but where the result will only be used when it is -- non-zero (so it doesn't matter what result is provided with a zero -- divisor, as long as the program keeps running). data Safety Unsafe :: Safety Safe :: Safety -- | What to do in case of arithmetic overflow. Futhark's semantics are -- that overflow does wraparound, but for generated code (like address -- arithmetic), it can be beneficial for overflow to be undefined -- behaviour, as it allows better optimisation of things such as GPU -- kernels. -- -- Note that all values of this type are considered equal for Eq -- and Ord. data Overflow OverflowWrap :: Overflow OverflowUndef :: Overflow -- | Various unary operators. It is a bit ad-hoc what is a unary operator -- and what is a built-in function. Perhaps these should all go away -- eventually. data UnOp -- | E.g., ! True == False. Not :: UnOp -- | E.g., ~(~1) = 1. Complement :: IntType -> UnOp -- | abs(-2) = 2. Abs :: IntType -> UnOp -- | fabs(-2.0) = 2.0. FAbs :: FloatType -> UnOp -- | Signed sign function: ssignum(-2) = -1. SSignum :: IntType -> UnOp -- | Unsigned sign function: usignum(2) = 1. USignum :: IntType -> UnOp -- | Non-array values. data PrimValue IntValue :: !IntValue -> PrimValue FloatValue :: !FloatValue -> PrimValue BoolValue :: !Bool -> PrimValue -- | The only value of type cert. Checked :: PrimValue -- | A floating-point value. data FloatValue Float32Value :: !Float -> FloatValue Float64Value :: !Double -> FloatValue -- | An integer value. data IntValue Int8Value :: !Int8 -> IntValue Int16Value :: !Int16 -> IntValue Int32Value :: !Int32 -> IntValue Int64Value :: !Int64 -> IntValue -- | Low-level primitive types. data PrimType IntType :: IntType -> PrimType FloatType :: FloatType -> PrimType Bool :: PrimType Cert :: PrimType -- | A floating point type. data FloatType Float32 :: FloatType Float64 :: FloatType -- | An integer type, ordered by size. Note that signedness is not a -- property of the type, but a property of the operations performed on -- values of these types. data IntType Int8 :: IntType Int16 :: IntType Int32 :: IntType Int64 :: IntType -- | A list of all integer types. allIntTypes :: [IntType] -- | A list of all floating-point types. allFloatTypes :: [FloatType] -- | A list of all primitive types. allPrimTypes :: [PrimType] -- | Create an IntValue from a type and an Integer. intValue :: Integral int => IntType -> int -> IntValue -- | The type of an integer value. intValueType :: IntValue -> IntType -- | Convert an IntValue to any Integral type. valueIntegral :: Integral int => IntValue -> int -- | Create a FloatValue from a type and a Rational. floatValue :: Real num => FloatType -> num -> FloatValue -- | The type of a floating-point value. floatValueType :: FloatValue -> FloatType -- | The type of a basic value. primValueType :: PrimValue -> PrimType -- | A "blank" value of the given primitive type - this is zero, or -- whatever is close to it. Don't depend on this value, but use it for -- e.g. creating arrays to be populated by do-loops. blankPrimValue :: PrimType -> PrimValue -- | A list of all unary operators for all types. allUnOps :: [UnOp] -- | A list of all binary operators for all types. allBinOps :: [BinOp] -- | A list of all comparison operators for all types. allCmpOps :: [CmpOp] -- | A list of all conversion operators for all types. allConvOps :: [ConvOp] -- | Apply an UnOp to an operand. Returns Nothing if the -- application is mistyped. doUnOp :: UnOp -> PrimValue -> Maybe PrimValue -- | E.g., ~(~1) = 1. doComplement :: IntValue -> IntValue -- | abs(-2) = 2. doAbs :: IntValue -> IntValue -- | abs(-2.0) = 2.0. doFAbs :: FloatValue -> FloatValue -- | ssignum(-2) = -1. doSSignum :: IntValue -> IntValue -- | usignum(-2) = -1. doUSignum :: IntValue -> IntValue -- | Apply a BinOp to an operand. Returns Nothing if the -- application is mistyped, or outside the domain (e.g. division by -- zero). doBinOp :: BinOp -> PrimValue -> PrimValue -> Maybe PrimValue -- | Integer addition. doAdd :: IntValue -> IntValue -> IntValue -- | Integer multiplication. doMul :: IntValue -> IntValue -> IntValue -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. doSDiv :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer modulus; the countepart to SDiv. doSMod :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer exponentatation. doPow :: IntValue -> IntValue -> Maybe IntValue -- | Apply a ConvOp to an operand. Returns Nothing if the -- application is mistyped. doConvOp :: ConvOp -> PrimValue -> Maybe PrimValue -- | Zero-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doZExt :: IntValue -> IntType -> IntValue -- | Sign-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doSExt :: IntValue -> IntType -> IntValue -- | Convert the former floating-point type to the latter. doFPConv :: FloatValue -> FloatType -> FloatValue -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). doFPToUI :: FloatValue -> IntType -> IntValue -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). doFPToSI :: FloatValue -> IntType -> IntValue -- | Convert an unsigned integer to a floating-point value. doUIToFP :: IntValue -> FloatType -> FloatValue -- | Convert a signed integer to a floating-point value. doSIToFP :: IntValue -> FloatType -> FloatValue -- | Apply a CmpOp to an operand. Returns Nothing if the -- application is mistyped. doCmpOp :: CmpOp -> PrimValue -> PrimValue -> Maybe Bool -- | Compare any two primtive values for exact equality. doCmpEq :: PrimValue -> PrimValue -> Bool -- | Unsigned less than. doCmpUlt :: IntValue -> IntValue -> Bool -- | Unsigned less than or equal. doCmpUle :: IntValue -> IntValue -> Bool -- | Signed less than. doCmpSlt :: IntValue -> IntValue -> Bool -- | Signed less than or equal. doCmpSle :: IntValue -> IntValue -> Bool -- | Floating-point less than. doFCmpLt :: FloatValue -> FloatValue -> Bool -- | Floating-point less than or equal. doFCmpLe :: FloatValue -> FloatValue -> Bool -- | Translate an IntValue to Word64. This is guaranteed to -- fit. intToWord64 :: IntValue -> Word64 -- | Translate an IntValue to Int64. This is guaranteed to -- fit. intToInt64 :: IntValue -> Int64 -- | The result type of a binary operator. binOpType :: BinOp -> PrimType -- | The operand types of a comparison operator. cmpOpType :: CmpOp -> PrimType -- | The operand and result type of a unary operator. unOpType :: UnOp -> PrimType -- | The input and output types of a conversion operator. convOpType :: ConvOp -> (PrimType, PrimType) -- | A mapping from names of primitive functions to their parameter types, -- their result type, and a function for evaluating them. primFuns :: Map String ([PrimType], PrimType, [PrimValue] -> Maybe PrimValue) -- | Is the given value kind of zero? zeroIsh :: PrimValue -> Bool -- | Is the given value kind of one? oneIsh :: PrimValue -> Bool -- | Is the given value kind of negative? negativeIsh :: PrimValue -> Bool -- | Is the given integer value kind of zero? zeroIshInt :: IntValue -> Bool -- | Is the given integer value kind of one? oneIshInt :: IntValue -> Bool -- | The size of a value of a given primitive type in bites. primBitSize :: PrimType -> Int -- | The size of a value of a given primitive type in eight-bit bytes. primByteSize :: Num a => PrimType -> a -- | The size of a value of a given integer type in eight-bit bytes. intByteSize :: Num a => IntType -> a -- | The size of a value of a given floating-point type in eight-bit bytes. floatByteSize :: Num a => FloatType -> a -- | True if the given binary operator is commutative. commutativeBinOp :: BinOp -> Bool -- | The human-readable name for a ConvOp. This is used to expose -- the ConvOp in the intrinsics module of a Futhark -- program. convOpFun :: ConvOp -> String -- | True if signed. Only makes a difference for integer types. prettySigned :: Bool -> PrimType -> String -- | A name tagged with some integer. Only the integer is used in -- comparisons, no matter the type of vn. data VName VName :: !Name -> !Int -> VName -- | The abstract (not really) type representing names in the Futhark -- compiler. Strings, being lists of characters, are very slow, -- while Texts are based on byte-arrays. data Name -- | Whether some operator is commutative or not. The Monoid -- instance returns the least commutative of its arguments. data Commutativity Noncommutative :: Commutativity Commutative :: Commutativity -- | The uniqueness attribute of a type. This essentially indicates whether -- or not in-place modifications are acceptable. With respect to -- ordering, Unique is greater than Nonunique. data Uniqueness -- | May have references outside current function. Nonunique :: Uniqueness -- | No references outside current function. Unique :: Uniqueness -- | The name of the default program entry point (main). defaultEntryPoint :: Name -- | Convert a name to the corresponding list of characters. nameToString :: Name -> String -- | Convert a list of characters to the corresponding name. nameFromString :: String -> Name -- | Convert a name to the corresponding Text. nameToText :: Name -> Text -- | Convert a Text to the corresponding name. nameFromText :: Text -> Name -- | A human-readable location string, of the form -- filename:lineno:columnno. This follows the GNU coding -- standards for error messages: -- https://www.gnu.org/prep/standards/html_node/Errors.html -- -- This function assumes that both start and end position is in the same -- file (it is not clear what the alternative would even mean). locStr :: Located a => a -> String -- | Like locStr, but locStrRel prev now prints the -- location now with the file name left out if the same as -- prev. This is useful when printing messages that are all in -- the context of some initially printed location (e.g. the first mention -- contains the file name; the rest just line and column name). locStrRel :: (Located a, Located b) => a -> b -> String -- | Given a list of strings representing entries in the stack trace and -- the index of the frame to highlight, produce a final -- newline-terminated string for showing to the user. This string should -- also be preceded by a newline. The most recent stack frame must come -- first in the list. prettyStacktrace :: Int -> [String] -> String -- | Return the tag contained in the VName. baseTag :: VName -> Int -- | Return the name contained in the VName. baseName :: VName -> Name -- | Return the base Name converted to a string. baseString :: VName -> String -- | Enclose a string in the prefered quotes used in error messages. These -- are picked to not collide with characters permitted in identifiers. quote :: String -> String -- | As quote, but works on prettyprinted representation. pquote :: Doc -> Doc -- | A part of an error message. data ErrorMsgPart a -- | A literal string. ErrorString :: String -> ErrorMsgPart a -- | A run-time integer value. ErrorInt32 :: a -> ErrorMsgPart a -- | A bigger run-time integer value. ErrorInt64 :: a -> ErrorMsgPart a -- | An error message is a list of error parts, which are concatenated to -- form the final message. newtype ErrorMsg a ErrorMsg :: [ErrorMsgPart a] -> ErrorMsg a -- | An element of a pattern - consisting of a name and an addditional -- parametric decoration. This decoration is what is expected to contain -- the type of the resulting variable. data PatElemT dec -- | A list of DimFixs, indicating how an array should be sliced. -- Whenever a function accepts a Slice, that slice should be -- total, i.e, cover all dimensions of the array. Deviators should be -- indicated by taking a list of DimIndexes instead. type Slice d = [DimIndex d] -- | How to index a single dimension of an array. data DimIndex d -- | Fix index in this dimension. DimFix :: d -> DimIndex d -- | DimSlice start_offset num_elems stride. DimSlice :: d -> d -> d -> DimIndex d -- | A function or lambda parameter. data Param dec Param :: VName -> dec -> Param dec -- | Name of the parameter. [paramName] :: Param dec -> VName -- | Function parameter decoration. [paramDec] :: Param dec -> dec -- | A subexpression is either a scalar constant or a variable. One -- important property is that evaluation of a subexpression is guaranteed -- to complete in constant time. data SubExp Constant :: PrimValue -> SubExp Var :: VName -> SubExp -- | A list of names used for certificates in some expressions. newtype Certificates Certificates :: [VName] -> Certificates [unCertificates] :: Certificates -> [VName] -- | An identifier consists of its name and the type of the value bound to -- the identifier. data Ident Ident :: VName -> Type -> Ident [identName] :: Ident -> VName [identType] :: Ident -> Type -- | Information about which parts of a value/type are consumed. For -- example, we might say that a function taking three arguments of types -- ([int], *[int], [int]) has diet [Observe, Consume, -- Observe]. data Diet -- | Consumes this value. Consume :: Diet -- | Only observes value in this position, does not consume. A result may -- alias this. Observe :: Diet -- | As Observe, but the result will not alias, because the -- parameter does not carry aliases. ObservePrim :: Diet -- | An ExtType with uniqueness information, used for function -- return types. type DeclExtType = TypeBase ExtShape Uniqueness -- | A type with shape and uniqueness information, used declaring return- -- and parameters types. type DeclType = TypeBase Shape Uniqueness -- | A type with existentially quantified shapes - used as part of function -- (and function-like) return types. Generally only makes sense when used -- in a list. type ExtType = TypeBase ExtShape NoUniqueness -- | A type with shape information, used for describing the type of -- variables. type Type = TypeBase Shape NoUniqueness -- | A Futhark type is either an array or an element type. When comparing -- types for equality with ==, shapes must match. data TypeBase shape u Prim :: PrimType -> TypeBase shape u Array :: PrimType -> shape -> u -> TypeBase shape u Mem :: Space -> TypeBase shape u -- | A fancier name for () - encodes no uniqueness information. data NoUniqueness NoUniqueness :: NoUniqueness -- | A string representing a specific non-default memory space. type SpaceId = String -- | The memory space of a block. If DefaultSpace, this is the -- "default" space, whatever that is. The exact meaning of the -- SpaceId depends on the backend used. In GPU kernels, for -- example, this is used to distinguish between constant, global and -- shared memory spaces. In GPU-enabled host code, it is used to -- distinguish between host memory (DefaultSpace) and GPU space. data Space DefaultSpace :: Space Space :: SpaceId -> Space -- | A special kind of memory that is a statically sized array of some -- primitive type. Used for private memory on GPUs. ScalarSpace :: [SubExp] -> PrimType -> Space -- | A class encompassing types containing array shape information. class (Monoid a, Eq a, Ord a) => ArrayShape a -- | Return the rank of an array with the given size. shapeRank :: ArrayShape a => a -> Int -- | stripDims n shape strips the outer n dimensions from -- shape. stripDims :: ArrayShape a => Int -> a -> a -- | Check whether one shape if a subset of another shape. subShapeOf :: ArrayShape a => a -> a -> Bool -- | The size of an array type as merely the number of dimensions, with no -- further information. newtype Rank Rank :: Int -> Rank -- | Like Shape but some of its elements may be bound in a local -- environment instead. These are denoted with integral indices. type ExtShape = ShapeBase ExtSize -- | The size of this dimension. type ExtSize = Ext SubExp -- | Something that may be existential. data Ext a Ext :: Int -> Ext a Free :: a -> Ext a -- | The size of an array as a list of subexpressions. If a variable, that -- variable must be in scope where this array is used. type Shape = ShapeBase SubExp -- | The size of an array type as a list of its dimension sizes, with the -- type of sizes being parametric. newtype ShapeBase d Shape :: [d] -> ShapeBase d [shapeDims] :: ShapeBase d -> [d] -- | If the argument is a DimFix, return its component. dimFix :: DimIndex d -> Maybe d -- | If the slice is all DimFixs, return the components. sliceIndices :: Slice d -> Maybe [d] -- | The dimensions of the array produced by this slice. sliceDims :: Slice d -> [d] -- | A slice with a stride of one. unitSlice :: Num d => d -> d -> DimIndex d -- | Fix the DimSlices of a slice. The number of indexes must equal -- the length of sliceDims for the slice. fixSlice :: Num d => Slice d -> [d] -> [d] -- | Further slice the DimSlices of a slice. The number of slices -- must equal the length of sliceDims for the slice. sliceSlice :: Num d => Slice d -> Slice d -> Slice d -- | How many non-constant parts does the error message have, and what is -- their type? errorMsgArgTypes :: ErrorMsg a -> [PrimType] -- | A type representing the return type of a function. In practice, a list -- of these will be used. It should contain at least the information -- contained in an ExtType, but may have more, notably an -- existential context. class (Show rt, Eq rt, Ord rt, DeclExtTyped rt) => IsRetType rt -- | Contruct a return type from a primitive type. primRetType :: IsRetType rt => PrimType -> rt -- | Given a function return type, the parameters of the function, and the -- arguments for a concrete call, return the instantiated return type for -- the concrete call, if valid. applyRetType :: (IsRetType rt, Typed dec) => [rt] -> [Param dec] -> [(SubExp, Type)] -> Maybe [rt] -- | A type representing the return type of a body. It should contain at -- least the information contained in a list of ExtTypes, but may -- have more, notably an existential context. class (Show rt, Eq rt, Ord rt, ExtTyped rt) => IsBodyType rt -- | Construct a body type from a primitive type. primBodyType :: IsBodyType rt => PrimType -> rt -- | Given shape parameter names and value parameter types, produce the -- types of arguments accepted. expectedTypes :: Typed t => [VName] -> [t] -> [SubExp] -> [Type] -- | A collection of type families, along with constraints specifying that -- the types they map to should satisfy some minimal requirements. class (Show (LetDec l), Show (ExpDec l), Show (BodyDec l), Show (FParamInfo l), Show (LParamInfo l), Show (RetType l), Show (BranchType l), Show (Op l), Eq (LetDec l), Eq (ExpDec l), Eq (BodyDec l), Eq (FParamInfo l), Eq (LParamInfo l), Eq (RetType l), Eq (BranchType l), Eq (Op l), Ord (LetDec l), Ord (ExpDec l), Ord (BodyDec l), Ord (FParamInfo l), Ord (LParamInfo l), Ord (RetType l), Ord (BranchType l), Ord (Op l), IsRetType (RetType l), IsBodyType (BranchType l), Typed (FParamInfo l), Typed (LParamInfo l), Typed (LetDec l), DeclTyped (FParamInfo l), SexpIso (LetDec l), SexpIso (ExpDec l), SexpIso (BodyDec l), SexpIso (FParamInfo l), SexpIso (LParamInfo l), SexpIso (RetType l), SexpIso (BranchType l), SexpIso (Op l)) => Decorations l where { -- | Decoration for every let-pattern element. type family LetDec l :: Type; -- | Decoration for every expression. type family ExpDec l :: Type; -- | Decoration for every body. type family BodyDec l :: Type; -- | Decoration for every (non-lambda) function parameter. type family FParamInfo l :: Type; -- | Decoration for every lambda function parameter. type family LParamInfo l :: Type; -- | The return type decoration of branches. type family BranchType l :: Type; -- | Extensible operation. type family Op l :: Type; type LetDec l = Type; type ExpDec l = (); type BodyDec l = (); type FParamInfo l = DeclType; type LParamInfo l = Type; type RetType l = DeclExtType; type BranchType l = ExtType; type Op l = (); } -- | An entire Futhark program. data Prog lore Prog :: Stms lore -> [FunDef lore] -> Prog lore -- | Top-level constants that are computed at program startup, and which -- are in scope inside all functions. [progConsts] :: Prog lore -> Stms lore -- | The functions comprising the program. All funtions are also available -- in scope in the definitions of the constants, so be careful not to -- introduce circular dependencies (not currently checked). [progFuns] :: Prog lore -> [FunDef lore] -- | Every entry point argument and return value has an annotation -- indicating how it maps to the original source program type. data EntryPointType -- | Is an unsigned integer or array of unsigned integers. TypeUnsigned :: EntryPointType -- | A black box type comprising this many core values. The string is a -- human-readable description with no other semantics. TypeOpaque :: String -> Int -> EntryPointType -- | Maps directly. TypeDirect :: EntryPointType -- | Information about the parameters and return value of an entry point. -- The first element is for parameters, the second for return value. type EntryPoint = ([EntryPointType], [EntryPointType]) -- | Function Declarations data FunDef lore FunDef :: Maybe EntryPoint -> Attrs -> Name -> [RetType lore] -> [FParam lore] -> BodyT lore -> FunDef lore -- | Contains a value if this function is an entry point. [funDefEntryPoint] :: FunDef lore -> Maybe EntryPoint [funDefAttrs] :: FunDef lore -> Attrs [funDefName] :: FunDef lore -> Name [funDefRetType] :: FunDef lore -> [RetType lore] [funDefParams] :: FunDef lore -> [FParam lore] [funDefBody] :: FunDef lore -> BodyT lore -- | Anonymous function for use in a SOAC. data LambdaT lore -- | What kind of branch is this? This has no semantic meaning, but -- provides hints to simplifications. data IfSort -- | An ordinary branch. IfNormal :: IfSort -- | A branch where the "true" case is what we are actually interested in, -- and the "false" case is only present as a fallback for when the true -- case cannot be safely evaluated. The compiler is permitted to optimise -- away the branch if the true case contains only safe statements. IfFallback :: IfSort -- | Both of these branches are semantically equivalent, and it is fine to -- eliminate one if it turns out to have problems (e.g. contain things we -- cannot generate code for). IfEquiv :: IfSort -- | Data associated with a branch. data IfDec rt IfDec :: [rt] -> IfSort -> IfDec rt [ifReturns] :: IfDec rt -> [rt] [ifSort] :: IfDec rt -> IfSort -- | For-loop or while-loop? data LoopForm lore ForLoop :: VName -> IntType -> SubExp -> [(LParam lore, VName)] -> LoopForm lore WhileLoop :: VName -> LoopForm lore -- | The root Futhark expression type. The Op constructor contains a -- lore-specific operation. Do-loops, branches and function calls are -- special. Everything else is a simple BasicOp. data ExpT lore -- | A simple (non-recursive) operation. BasicOp :: BasicOp -> ExpT lore Apply :: Name -> [(SubExp, Diet)] -> [RetType lore] -> (Safety, SrcLoc, [SrcLoc]) -> ExpT lore If :: SubExp -> BodyT lore -> BodyT lore -> IfDec (BranchType lore) -> ExpT lore -- | loop {a} = {v} (for i < n|while b) do b. The merge -- parameters are divided into context and value part. DoLoop :: [(FParam lore, SubExp)] -> [(FParam lore, SubExp)] -> LoopForm lore -> BodyT lore -> ExpT lore Op :: Op lore -> ExpT lore -- | A primitive operation that returns something of known size and does -- not itself contain any bindings. data BasicOp -- | A variable or constant. SubExp :: SubExp -> BasicOp -- | Semantically and operationally just identity, but is -- invisible/impenetrable to optimisations (hopefully). This is just a -- hack to avoid optimisation (so, to work around compiler limitations). Opaque :: SubExp -> BasicOp -- | Array literals, e.g., [ [1+x, 3], [2, 1+4] ]. Second arg is -- the element type of the rows of the array. Scalar operations ArrayLit :: [SubExp] -> Type -> BasicOp -- | Unary operation. UnOp :: UnOp -> SubExp -> BasicOp -- | Binary operation. BinOp :: BinOp -> SubExp -> SubExp -> BasicOp -- | Comparison - result type is always boolean. CmpOp :: CmpOp -> SubExp -> SubExp -> BasicOp -- | Conversion "casting". ConvOp :: ConvOp -> SubExp -> BasicOp -- | Turn a boolean into a certificate, halting the program with the given -- error message if the boolean is false. Assert :: SubExp -> ErrorMsg SubExp -> (SrcLoc, [SrcLoc]) -> BasicOp -- | The certificates for bounds-checking are part of the Stm. Index :: VName -> Slice SubExp -> BasicOp -- | An in-place update of the given array at the given position. Consumes -- the array. Update :: VName -> Slice SubExp -> SubExp -> BasicOp -- | concat0([1],[2, 3, 4]) = [1, 2, 3, 4]@. Concat :: Int -> VName -> [VName] -> SubExp -> BasicOp -- | Copy the given array. The result will not alias anything. Copy :: VName -> BasicOp -- | Manifest an array with dimensions represented in the given order. The -- result will not alias anything. Manifest :: [Int] -> VName -> BasicOp -- | iota(n, x, s) = [x,x+s,..,x+(n-1)*s]. -- -- The IntType indicates the type of the array returned and the -- offset/stride arguments, but not the length argument. Iota :: SubExp -> SubExp -> SubExp -> IntType -> BasicOp -- |
--   replicate([3][2],1) = [[1,1], [1,1], [1,1]]
--   
Replicate :: Shape -> SubExp -> BasicOp -- | Create array of given type and shape, with undefined elements. Scratch :: PrimType -> [SubExp] -> BasicOp -- | 1st arg is the new shape, 2nd arg is the input array *) Reshape :: ShapeChange SubExp -> VName -> BasicOp -- | Permute the dimensions of the input array. The list of integers is a -- list of dimensions (0-indexed), which must be a permutation of -- [0,n-1], where n is the number of dimensions in the -- input array. Rearrange :: [Int] -> VName -> BasicOp -- | Rotate the dimensions of the input array. The list of subexpressions -- specify how much each dimension is rotated. The length of this list -- must be equal to the rank of the array. Rotate :: [SubExp] -> VName -> BasicOp -- | A list of DimChanges, indicating the new dimensions of an -- array. type ShapeChange d = [DimChange d] -- | The new dimension in a Reshape-like operation. This allows us -- to disambiguate "real" reshapes, that change the actual shape of the -- array, from type coercions that are just present to make the types -- work out. The two constructors are considered equal for purposes of -- Eq. data DimChange d -- | The new dimension is guaranteed to be numerically equal to the old -- one. DimCoercion :: d -> DimChange d -- | The new dimension is not necessarily numerically equal to the old one. DimNew :: d -> DimChange d -- | A body consists of a number of bindings, terminating in a result -- (essentially a tuple literal). data BodyT lore -- | The result of a body is a sequence of subexpressions. type Result = [SubExp] -- | A sequence of statements. type Stms lore = Seq (Stm lore) pattern Let :: () => Pattern lore -> StmAux (ExpDec lore) -> Exp lore -> Stm lore -- | Expression. stmExp :: Stm lore -> Exp lore -- | Pattern. stmPattern :: Stm lore -> Pattern lore -- | Auxiliary information statement. stmAux :: Stm lore -> StmAux (ExpDec lore) -- | Auxilliary Information associated with a statement. data StmAux dec StmAux :: !Certificates -> Attrs -> dec -> StmAux dec [stmAuxCerts] :: StmAux dec -> !Certificates [stmAuxAttrs] :: StmAux dec -> Attrs [stmAuxDec] :: StmAux dec -> dec -- | A pattern is conceptually just a list of names and their types. data PatternT dec -- | Every statement is associated with a set of attributes, which can have -- various effects throughout the compiler. newtype Attrs Attrs :: Set Attr -> Attrs [unAttrs] :: Attrs -> Set Attr -- | A single attribute. data Attr AttrAtom :: Name -> Attr AttrComp :: Name -> [Attr] -> Attr -- | Construct Attrs from a single Attr. oneAttr :: Attr -> Attrs -- | Is the given attribute to be found in the attribute set? inAttrs :: Attr -> Attrs -> Bool -- | x withoutAttrs y gives x except for any -- attributes also in y. withoutAttrs :: Attrs -> Attrs -> Attrs -- | A single statement. oneStm :: Stm lore -> Stms lore -- | Convert a statement list to a statement sequence. stmsFromList :: [Stm lore] -> Stms lore -- | Convert a statement sequence to a statement list. stmsToList :: Stms lore -> [Stm lore] -- | The first statement in the sequence, if any. stmsHead :: Stms lore -> Maybe (Stm lore, Stms lore) -- | Anonymous function for use in a SOAC. data LambdaT lore Lambda :: [LParam lore] -> BodyT lore -> [Type] -> LambdaT lore -- | A body consists of a number of bindings, terminating in a result -- (essentially a tuple literal). data BodyT lore Body :: BodyDec lore -> Stms lore -> Result -> BodyT lore -- | A pattern is conceptually just a list of names and their types. data PatternT dec Pattern :: [PatElemT dec] -> [PatElemT dec] -> PatternT dec -- | An element of a pattern - consisting of a name and an addditional -- parametric decoration. This decoration is what is expected to contain -- the type of the resulting variable. data PatElemT dec PatElem :: VName -> dec -> PatElemT dec instance Futhark.IR.Decorations.Decorations Futhark.IR.SOACS.SOACS instance Futhark.IR.Prop.ASTLore Futhark.IR.SOACS.SOACS instance Futhark.TypeCheck.CheckableOp Futhark.IR.SOACS.SOACS instance Futhark.TypeCheck.Checkable Futhark.IR.SOACS.SOACS instance Futhark.Binder.Class.Bindable Futhark.IR.SOACS.SOACS instance Futhark.Binder.BinderOps Futhark.IR.SOACS.SOACS instance Futhark.IR.Pretty.PrettyLore Futhark.IR.SOACS.SOACS -- | The code generator cannot handle the array combinators (map -- and friends), so this module was written to transform them into the -- equivalent do-loops. The transformation is currently rather naive, and -- - it's certainly worth considering when we can express such -- transformations in-place. module Futhark.Transform.FirstOrderTransform -- | First-order-transform a single function, with the given scope provided -- by top-level constants. transformFunDef :: (MonadFreshNames m, FirstOrderLore tolore) => Scope tolore -> FunDef SOACS -> m (FunDef tolore) -- | First-order-transform these top-level constants. transformConsts :: (MonadFreshNames m, FirstOrderLore tolore) => Stms SOACS -> m (Stms tolore) -- | The constraints that must hold for a lore in order to be the target of -- first-order transformation. type FirstOrderLore lore = (Bindable lore, BinderOps lore, LetDec SOACS ~ LetDec lore, LParamInfo SOACS ~ LParamInfo lore) -- | The constraints that a monad must uphold in order to be used for -- first-order transformation. type Transformer m = (MonadBinder m, LocalScope (Lore m) m, Bindable (Lore m), BinderOps (Lore m), LParamInfo SOACS ~ LParamInfo (Lore m)) -- | First transform any nested Body or Lambda elements, then -- apply transformSOAC if the expression is a SOAC. transformStmRecursively :: (Transformer m, LetDec (Lore m) ~ LetDec SOACS) => Stm -> m () -- | Recursively first-order-transform a lambda. transformLambda :: (MonadFreshNames m, Bindable lore, BinderOps lore, LocalScope somelore m, SameScope somelore lore, LetDec lore ~ LetDec SOACS) => Lambda -> m (Lambda lore) -- | Transform a single SOAC into a do-loop. The body of the lambda -- is untouched, and may or may not contain further SOACs -- depending on the given lore. transformSOAC :: Transformer m => Pattern (Lore m) -> SOAC (Lore m) -> m () -- | Transform any SOACs to for-loops. -- -- Example: -- --
--   let ys = map (x -> x + 2) xs
--   
-- -- becomes something like: -- --
--   let out = scratch n i32
--   let ys =
--     loop (ys' = out) for i < n do
--       let x = xs[i]
--       let y = x + 2
--       let ys'[i] = y
--       in ys'
--   
module Futhark.Pass.FirstOrderTransform -- | The first-order transformation pass. firstOrderTransform :: FirstOrderLore lore => Pass SOACS lore -- | Interchanging scans with inner maps. module Futhark.Pass.ExtractKernels.ISRWIM -- | Interchange Scan With Inner Map. Tries to turn a scan(map) -- into a @map(scan) iswim :: (MonadBinder m, Lore m ~ SOACS) => Pattern -> SubExp -> Lambda -> [(SubExp, VName)] -> Maybe (m ()) -- | Interchange Reduce With Inner Map. Tries to turn a -- reduce(map) into a @map(reduce) irwim :: (MonadBinder m, Lore m ~ SOACS) => Pattern -> SubExp -> Commutativity -> Lambda -> [(SubExp, VName)] -> Maybe (m ()) -- | Does this reduce operator contain an inner map, and if so, what does -- that map look like? rwimPossible :: Lambda -> Maybe (Pattern, Certificates, SubExp, Lambda) module Futhark.Internalise.Monad data InternaliseM a runInternaliseM :: MonadFreshNames m => Bool -> InternaliseM () -> m (Stms SOACS, [FunDef SOACS]) -- | Is used within a monadic computation to begin exception processing. throwError :: MonadError e m => e -> m a -- | A mapping from external variable names to the corresponding -- internalised subexpressions. type VarSubstitutions = Map VName [SubExp] data InternaliseEnv InternaliseEnv :: VarSubstitutions -> Bool -> Bool -> Attrs -> InternaliseEnv [envSubsts] :: InternaliseEnv -> VarSubstitutions [envDoBoundsChecks] :: InternaliseEnv -> Bool [envSafe] :: InternaliseEnv -> Bool [envAttrs] :: InternaliseEnv -> Attrs -- | Extra parameters to pass when calling this function. This corresponds -- to the closure of a locally defined function. type Closure = [VName] type FunInfo = (Name, Closure, [VName], [DeclType], [FParam], [(SubExp, Type)] -> Maybe [DeclExtType]) substitutingVars :: VarSubstitutions -> InternaliseM a -> InternaliseM a lookupSubst :: VName -> InternaliseM (Maybe [SubExp]) -- | Add a function definition to the program being constructed. addFunDef :: FunDef SOACS -> InternaliseM () lookupFunction :: VName -> InternaliseM FunInfo lookupFunction' :: VName -> InternaliseM (Maybe FunInfo) lookupConst :: VName -> InternaliseM (Maybe [SubExp]) allConsts :: InternaliseM Names bindFunction :: VName -> FunDef SOACS -> FunInfo -> InternaliseM () bindConstant :: VName -> FunDef SOACS -> InternaliseM () localConstsScope :: InternaliseM a -> InternaliseM a -- | Construct an Assert statement, but taking attributes into -- account. Always use this function, and never construct Assert -- directly in the internaliser! assert :: String -> SubExp -> ErrorMsg SubExp -> SrcLoc -> InternaliseM Certificates instance Futhark.IR.Prop.Scope.LocalScope Futhark.IR.SOACS.SOACS Futhark.Internalise.Monad.InternaliseM instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.SOACS.SOACS Futhark.Internalise.Monad.InternaliseM instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Internalise.Monad.InternaliseM instance Control.Monad.State.Class.MonadState Futhark.Internalise.Monad.InternaliseState Futhark.Internalise.Monad.InternaliseM instance Control.Monad.Reader.Class.MonadReader Futhark.Internalise.Monad.InternaliseEnv Futhark.Internalise.Monad.InternaliseM instance GHC.Base.Monad Futhark.Internalise.Monad.InternaliseM instance GHC.Base.Applicative Futhark.Internalise.Monad.InternaliseM instance GHC.Base.Functor Futhark.Internalise.Monad.InternaliseM instance Futhark.Binder.Class.MonadBinder Futhark.Internalise.Monad.InternaliseM instance GHC.Base.Semigroup Futhark.Internalise.Monad.InternaliseResult instance GHC.Base.Monoid Futhark.Internalise.Monad.InternaliseResult instance (GHC.Base.Monoid w, GHC.Base.Monad m) => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.RWS.Lazy.RWST r w Futhark.Internalise.Monad.InternaliseState m) module Futhark.Internalise.AccurateSizes argShapes :: (HasScope SOACS m, Monad m) => [VName] -> [FParam] -> [Type] -> m [SubExp] ensureResultShape :: ErrorMsg SubExp -> SrcLoc -> [Type] -> Body -> InternaliseM Body ensureResultExtShape :: ErrorMsg SubExp -> SrcLoc -> [ExtType] -> Body -> InternaliseM Body ensureExtShape :: ErrorMsg SubExp -> SrcLoc -> ExtType -> String -> SubExp -> InternaliseM SubExp ensureShape :: ErrorMsg SubExp -> SrcLoc -> Type -> String -> SubExp -> InternaliseM SubExp -- | Reshape the arguments to a function so that they fit the expected -- shape declarations. Not used to change rank of arguments. Assumes -- everything is otherwise type-correct. ensureArgShapes :: Typed (TypeBase Shape u) => ErrorMsg SubExp -> SrcLoc -> [VName] -> [TypeBase Shape u] -> [SubExp] -> InternaliseM [SubExp] module Futhark.IR.SOACS.Simplify simplifySOACS :: Prog SOACS -> PassM (Prog SOACS) simplifyLambda :: (HasScope SOACS m, MonadFreshNames m) => Lambda -> m Lambda simplifyFun :: MonadFreshNames m => SymbolTable (Wise SOACS) -> FunDef SOACS -> m (FunDef SOACS) simplifyStms :: (HasScope SOACS m, MonadFreshNames m) => Stms SOACS -> m (SymbolTable (Wise SOACS), Stms SOACS) simplifyConsts :: MonadFreshNames m => Stms SOACS -> m (SymbolTable (Wise SOACS), Stms SOACS) simpleSOACS :: SimpleOps SOACS simplifySOAC :: SimplifiableLore lore => SimplifyOp lore (SOAC lore) soacRules :: RuleBook (Wise SOACS) -- | Does this lore contain SOACs in its Ops? A lore must be -- an instance of this class for the simplification rules to work. class HasSOAC lore asSOAC :: HasSOAC lore => Op lore -> Maybe (SOAC lore) soacOp :: HasSOAC lore => SOAC lore -> Op lore simplifyKnownIterationSOAC :: (Bindable lore, SimplifiableLore lore, HasSOAC (Wise lore)) => TopDownRuleOp (Wise lore) -- | Remove all arguments to the map that are simply replicates. These can -- be turned into free variables instead. removeReplicateMapping :: (Bindable lore, SimplifiableLore lore, HasSOAC (Wise lore)) => TopDownRuleOp (Wise lore) liftIdentityMapping :: forall lore. (Bindable lore, SimplifiableLore lore, HasSOAC (Wise lore)) => BottomUpRuleOp (Wise lore) -- | The lore for the basic representation. data SOACS instance GHC.Show.Show Futhark.IR.SOACS.Simplify.ArrayOp instance GHC.Classes.Ord Futhark.IR.SOACS.Simplify.ArrayOp instance GHC.Classes.Eq Futhark.IR.SOACS.Simplify.ArrayOp instance Futhark.IR.SOACS.Simplify.HasSOAC (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.SOACS.SOACS) instance Futhark.Binder.BinderOps (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.SOACS.SOACS) -- | This module exports functionality for generating a call graph of an -- Futhark program. module Futhark.Analysis.CallGraph -- | The call graph is a mapping from a function name, i.e., the caller, to -- a set of the names of functions called *directly* (not transitively!) -- by the function. -- -- We keep track separately of the functions called by constants. data CallGraph -- | buildCallGraph prog build the program's call graph. buildCallGraph :: Prog SOACS -> CallGraph -- | Is the given function known to the call graph? isFunInCallGraph :: Name -> CallGraph -> Bool -- | Does the first function call the second? calls :: Name -> Name -> CallGraph -> Bool -- | Is the function called in any of the constants? calledByConsts :: Name -> CallGraph -> Bool -- | All functions called by this function. allCalledBy :: Name -> CallGraph -> Set Name -- | The set of all functions that are called noinline somewhere, or have a -- noinline attribute on their definition. findNoninlined :: Prog SOACS -> Set Name -- | Building blocks for defining representations where every array is -- given information about which memory block is it based in, and how -- array elements map to memory block offsets. -- -- There are two primary concepts you will need to understand: -- --
    --
  1. Memory blocks, which are Futhark values of type Mem -- (parametrized with their size). These correspond to arbitrary blocks -- of memory, and are created using the Alloc operation.
  2. --
  3. Index functions, which describe a mapping from the index space of -- an array (eg. a two-dimensional space for an array of type -- [[int]]) to a one-dimensional offset into a memory block. -- Thus, index functions describe how arbitrary-dimensional arrays are -- mapped to the single-dimensional world of memory.
  4. --
-- -- At a conceptual level, imagine that we have a two-dimensional array -- a of 32-bit integers, consisting of n rows of -- m elements each. This array could be represented in classic -- row-major format with an index function like the following: -- --
--   f(i,j) = i * m + j
--   
-- -- When we want to know the location of element a[2,3], we -- simply call the index function as f(2,3) and obtain -- 2*m+3. We could also have chosen another index function, one -- that represents the array in column-major (or "transposed") format: -- --
--   f(i,j) = j * n + i
--   
-- -- Index functions are not Futhark-level functions, but a special -- construct that the final code generator will eventually use to -- generate concrete access code. By modifying the index functions we can -- change how an array is represented in memory, which can permit memory -- access pattern optimisations. -- -- Every time we bind an array, whether in a let-binding, -- loop merge parameter, or lambda parameter, we have -- an annotation specifying a memory block and an index function. In some -- cases, such as let-bindings for many expressions, we are free -- to specify an arbitrary index function and memory block - for example, -- we get to decide where Copy stores its result - but in other -- cases the type rules of the expression chooses for us. For example, -- Index always produces an array in the same memory block as its -- input, and with the same index function, except with some indices -- fixed. module Futhark.IR.Mem type LetDecMem = MemInfo SubExp NoUniqueness MemBind type FParamMem = MemInfo SubExp Uniqueness MemBind type LParamMem = MemInfo SubExp NoUniqueness MemBind type RetTypeMem = FunReturns type BranchTypeMem = BodyReturns data MemOp inner -- | Allocate a memory block. This really should not be an expression, but -- what are you gonna do... Alloc :: SubExp -> Space -> MemOp inner Inner :: inner -> MemOp inner -- | A summary of the memory information for every let-bound identifier, -- function parameter, and return value. Parameterisered over uniqueness, -- dimension, and auxiliary array information. data MemInfo d u ret -- | A primitive value. MemPrim :: PrimType -> MemInfo d u ret -- | A memory block. MemMem :: Space -> MemInfo d u ret -- | The array is stored in the named memory block, and with the given -- index function. The index function maps indices in the array to -- element offset, not byte offsets! To translate to byte -- offsets, multiply the offset with the size of the array element type. MemArray :: PrimType -> ShapeBase d -> u -> ret -> MemInfo d u ret type MemBound u = MemInfo SubExp u MemBind -- | Memory information for an array bound somewhere in the program. data MemBind -- | Located in this memory block with this index function. ArrayIn :: VName -> IxFun -> MemBind -- | A description of the memory properties of an array being returned by -- an operation. data MemReturn -- | The array is located in a memory block that is already in scope. ReturnsInBlock :: VName -> ExtIxFun -> MemReturn -- | The operation returns a new (existential) memory block. ReturnsNewBlock :: Space -> Int -> ExtIxFun -> MemReturn -- | The index function representation used for memory annotations. type IxFun = IxFun (TPrimExp Int64 VName) -- | An index function that may contain existential variables. type ExtIxFun = IxFun (TPrimExp Int64 (Ext VName)) isStaticIxFun :: ExtIxFun -> Maybe IxFun -- | The memory return of an expression. An array is annotated with -- Maybe MemReturn, which can be interpreted as the expression -- either dictating exactly where the array is located when it is -- returned (if Just), or able to put it whereever the binding -- prefers (if Nothing). -- -- This is necessary to capture the difference between an expression that -- is just an array-typed variable, in which the array being "returned" -- is located where it already is, and a copy expression, whose -- entire purpose is to store an existing array in some arbitrary -- location. This is a consequence of the design decision never to have -- implicit memory copies. type ExpReturns = MemInfo ExtSize NoUniqueness (Maybe MemReturn) -- | The return of a body, which must always indicate where returned arrays -- are located. type BodyReturns = MemInfo ExtSize NoUniqueness MemReturn -- | The memory return of a function, which must always indicate where -- returned arrays are located. type FunReturns = MemInfo ExtSize Uniqueness MemReturn noUniquenessReturns :: MemInfo d u r -> MemInfo d NoUniqueness r bodyReturnsToExpReturns :: BodyReturns -> ExpReturns type Mem lore = (AllocOp (Op lore), FParamInfo lore ~ FParamMem, LParamInfo lore ~ LParamMem, LetDec lore ~ LetDecMem, RetType lore ~ RetTypeMem, BranchType lore ~ BranchTypeMem, ASTLore lore, Decorations lore, OpReturns lore) -- | The class of ops that have memory allocation. class AllocOp op allocOp :: AllocOp op => SubExp -> Space -> op class TypedOp (Op lore) => OpReturns lore opReturns :: (OpReturns lore, Monad m, HasScope lore m) => Op lore -> m [ExpReturns] varReturns :: (HasScope lore m, Monad m, Mem lore) => VName -> m ExpReturns -- | The return information of an expression. This can be seen as the -- "return type with memory annotations" of the expression. expReturns :: (Monad m, HasScope lore m, Mem lore) => Exp lore -> m [ExpReturns] extReturns :: [ExtType] -> [ExpReturns] lookupMemInfo :: (HasScope lore m, Mem lore) => VName -> m (MemInfo SubExp NoUniqueness MemBind) subExpMemInfo :: (HasScope lore m, Monad m, Mem lore) => SubExp -> m (MemInfo SubExp NoUniqueness MemBind) lookupArraySummary :: (Mem lore, HasScope lore m, Monad m) => VName -> m (VName, IxFun (TPrimExp Int64 VName)) existentialiseIxFun :: [VName] -> IxFun -> ExtIxFun matchBranchReturnType :: (Mem lore, Checkable lore) => [BodyReturns] -> Body (Aliases lore) -> TypeM lore () matchPatternToExp :: (Mem lore, Checkable lore) => Pattern (Aliases lore) -> Exp (Aliases lore) -> TypeM lore () matchFunctionReturnType :: (Mem lore, Checkable lore) => [FunReturns] -> Result -> TypeM lore () matchLoopResultMem :: (Mem lore, Checkable lore) => [FParam (Aliases lore)] -> [FParam (Aliases lore)] -> [SubExp] -> TypeM lore () bodyReturnsFromPattern :: PatternT (MemBound NoUniqueness) -> ([(VName, BodyReturns)], [(VName, BodyReturns)]) checkMemInfo :: Checkable lore => VName -> MemInfo SubExp u MemBind -> TypeM lore () instance GHC.Generics.Generic (Futhark.IR.Mem.MemOp inner) instance GHC.Show.Show inner => GHC.Show.Show (Futhark.IR.Mem.MemOp inner) instance GHC.Classes.Ord inner => GHC.Classes.Ord (Futhark.IR.Mem.MemOp inner) instance GHC.Classes.Eq inner => GHC.Classes.Eq (Futhark.IR.Mem.MemOp inner) instance GHC.Generics.Generic (Futhark.IR.Mem.MemInfo d u ret) instance (GHC.Classes.Ord d, GHC.Classes.Ord u, GHC.Classes.Ord ret) => GHC.Classes.Ord (Futhark.IR.Mem.MemInfo d u ret) instance (GHC.Show.Show d, GHC.Show.Show u, GHC.Show.Show ret) => GHC.Show.Show (Futhark.IR.Mem.MemInfo d u ret) instance (GHC.Classes.Eq d, GHC.Classes.Eq u, GHC.Classes.Eq ret) => GHC.Classes.Eq (Futhark.IR.Mem.MemInfo d u ret) instance GHC.Generics.Generic Futhark.IR.Mem.MemBind instance GHC.Show.Show Futhark.IR.Mem.MemBind instance GHC.Generics.Generic Futhark.IR.Mem.MemReturn instance GHC.Show.Show Futhark.IR.Mem.MemReturn instance Futhark.IR.RetType.IsRetType Futhark.IR.Mem.FunReturns instance Futhark.Optimise.Simplify.Engine.Simplifiable [Futhark.IR.Mem.FunReturns] instance Futhark.IR.RetType.IsBodyType Futhark.IR.Mem.BodyReturns instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Mem.MemReturn instance GHC.Classes.Eq Futhark.IR.Mem.MemReturn instance GHC.Classes.Ord Futhark.IR.Mem.MemReturn instance Futhark.Transform.Rename.Rename Futhark.IR.Mem.MemReturn instance Futhark.Transform.Substitute.Substitute Futhark.IR.Mem.MemReturn instance Futhark.IR.Prop.Types.FixExt Futhark.IR.Mem.MemReturn instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Mem.MemReturn instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Mem.MemReturn instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.Mem.MemReturn instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Mem.MemBind instance GHC.Classes.Eq Futhark.IR.Mem.MemBind instance GHC.Classes.Ord Futhark.IR.Mem.MemBind instance Futhark.Transform.Rename.Rename Futhark.IR.Mem.MemBind instance Futhark.Transform.Substitute.Substitute Futhark.IR.Mem.MemBind instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Mem.MemBind instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Mem.MemBind instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.Mem.MemBind instance (Language.SexpGrammar.Class.SexpIso d, Language.SexpGrammar.Class.SexpIso u, Language.SexpGrammar.Class.SexpIso ret) => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Mem.MemInfo d u ret) instance Futhark.IR.Prop.Types.FixExt ret => Futhark.IR.Prop.Types.DeclExtTyped (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.ExtSize Language.Futhark.Core.Uniqueness ret) instance Futhark.IR.Prop.Types.FixExt ret => Futhark.IR.Prop.Types.ExtTyped (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.ExtSize Futhark.IR.Syntax.Core.NoUniqueness ret) instance Futhark.IR.Prop.Types.FixExt ret => Futhark.IR.Prop.Types.FixExt (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.ExtSize u ret) instance Futhark.IR.Prop.Types.Typed (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.SubExp Language.Futhark.Core.Uniqueness ret) instance Futhark.IR.Prop.Types.Typed (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.SubExp Futhark.IR.Syntax.Core.NoUniqueness ret) instance Futhark.IR.Prop.Types.DeclTyped (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.SubExp Language.Futhark.Core.Uniqueness ret) instance (Futhark.IR.Prop.Names.FreeIn d, Futhark.IR.Prop.Names.FreeIn ret) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Mem.MemInfo d u ret) instance (Futhark.Transform.Substitute.Substitute d, Futhark.Transform.Substitute.Substitute ret) => Futhark.Transform.Substitute.Substitute (Futhark.IR.Mem.MemInfo d u ret) instance (Futhark.Transform.Substitute.Substitute d, Futhark.Transform.Substitute.Substitute ret) => Futhark.Transform.Rename.Rename (Futhark.IR.Mem.MemInfo d u ret) instance (Futhark.Optimise.Simplify.Engine.Simplifiable d, Futhark.Optimise.Simplify.Engine.Simplifiable ret) => Futhark.Optimise.Simplify.Engine.Simplifiable (Futhark.IR.Mem.MemInfo d u ret) instance (Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.TypeBase (Futhark.IR.Syntax.Core.ShapeBase d) u), Text.PrettyPrint.Mainland.Class.Pretty d, Text.PrettyPrint.Mainland.Class.Pretty u, Text.PrettyPrint.Mainland.Class.Pretty ret) => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Mem.MemInfo d u ret) instance Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.Param (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.SubExp Language.Futhark.Core.Uniqueness ret)) instance Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.Param (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.SubExp Futhark.IR.Syntax.Core.NoUniqueness ret)) instance Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Syntax.Core.PatElemT (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.SubExp Futhark.IR.Syntax.Core.NoUniqueness ret)) instance (Text.PrettyPrint.Mainland.Class.Pretty u, Text.PrettyPrint.Mainland.Class.Pretty r) => Futhark.IR.Pretty.PrettyAnnot (Futhark.IR.Syntax.Core.PatElemT (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.SubExp u r)) instance (Text.PrettyPrint.Mainland.Class.Pretty u, Text.PrettyPrint.Mainland.Class.Pretty r) => Futhark.IR.Pretty.PrettyAnnot (Futhark.IR.Syntax.Core.Param (Futhark.IR.Mem.MemInfo Futhark.IR.Syntax.Core.SubExp u r)) instance Language.SexpGrammar.Class.SexpIso inner => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Mem.MemOp inner) instance Futhark.IR.Mem.AllocOp (Futhark.IR.Mem.MemOp inner) instance Futhark.IR.Prop.Names.FreeIn inner => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Mem.MemOp inner) instance Futhark.IR.Prop.TypeOf.TypedOp inner => Futhark.IR.Prop.TypeOf.TypedOp (Futhark.IR.Mem.MemOp inner) instance Futhark.IR.Prop.Aliases.AliasedOp inner => Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Mem.MemOp inner) instance Futhark.IR.Prop.Aliases.CanBeAliased inner => Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Mem.MemOp inner) instance Futhark.Transform.Rename.Rename inner => Futhark.Transform.Rename.Rename (Futhark.IR.Mem.MemOp inner) instance Futhark.Transform.Substitute.Substitute inner => Futhark.Transform.Substitute.Substitute (Futhark.IR.Mem.MemOp inner) instance Text.PrettyPrint.Mainland.Class.Pretty inner => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Mem.MemOp inner) instance Futhark.Analysis.Metrics.OpMetrics inner => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Mem.MemOp inner) instance Futhark.IR.Prop.IsOp inner => Futhark.IR.Prop.IsOp (Futhark.IR.Mem.MemOp inner) instance Futhark.Optimise.Simplify.Lore.CanBeWise inner => Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Mem.MemOp inner) instance Futhark.Analysis.SymbolTable.IndexOp inner => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.Mem.MemOp inner) -- | A generic transformation for adding memory allocations to a Futhark -- program. Specialised by specific representations in submodules. module Futhark.Pass.ExplicitAllocations explicitAllocationsGeneric :: (Allocable fromlore tolore, Allocator tolore (AllocM fromlore tolore)) => (Op fromlore -> AllocM fromlore tolore (Op tolore)) -> (Exp tolore -> AllocM fromlore tolore [ExpHint]) -> Pass fromlore tolore explicitAllocationsInStmsGeneric :: (MonadFreshNames m, HasScope tolore m, Allocable fromlore tolore) => (Op fromlore -> AllocM fromlore tolore (Op tolore)) -> (Exp tolore -> AllocM fromlore tolore [ExpHint]) -> Stms fromlore -> m (Stms tolore) data ExpHint NoHint :: ExpHint Hint :: IxFun -> Space -> ExpHint defaultExpHints :: (Monad m, ASTLore lore) => Exp lore -> m [ExpHint] type Allocable fromlore tolore = (PrettyLore fromlore, PrettyLore tolore, Mem tolore, FParamInfo fromlore ~ DeclType, LParamInfo fromlore ~ Type, BranchType fromlore ~ ExtType, RetType fromlore ~ DeclExtType, BodyDec fromlore ~ (), BodyDec tolore ~ (), ExpDec tolore ~ (), SizeSubst (Op tolore), BinderOps tolore) class (MonadFreshNames m, HasScope lore m, Mem lore) => Allocator lore m addAllocStm :: Allocator lore m => AllocStm -> m () askDefaultSpace :: Allocator lore m => m Space addAllocStm :: (Allocator lore m, Allocable fromlore lore, m ~ AllocM fromlore lore) => AllocStm -> m () -- | The subexpression giving the number of elements we should allocate -- space for. See ChunkMap comment. dimAllocationSize :: Allocator lore m => SubExp -> m SubExp -- | The subexpression giving the number of elements we should allocate -- space for. See ChunkMap comment. dimAllocationSize :: (Allocator lore m, m ~ AllocM fromlore lore) => SubExp -> m SubExp -- | Get those names that are known to be constants at run-time. askConsts :: Allocator lore m => m (Set VName) expHints :: Allocator lore m => Exp lore -> m [ExpHint] -- | Monad for adding allocations to an entire program. data AllocM fromlore tolore a data AllocEnv fromlore tolore AllocEnv :: ChunkMap -> Bool -> Space -> Set VName -> (Op fromlore -> AllocM fromlore tolore (Op tolore)) -> (Exp tolore -> AllocM fromlore tolore [ExpHint]) -> AllocEnv fromlore tolore [chunkMap] :: AllocEnv fromlore tolore -> ChunkMap -- | Aggressively try to reuse memory in do-loops - should be True inside -- kernels, False outside. [aggressiveReuse] :: AllocEnv fromlore tolore -> Bool -- | When allocating memory, put it in this memory space. This is primarily -- used to ensure that group-wide statements store their results in local -- memory. [allocSpace] :: AllocEnv fromlore tolore -> Space -- | The set of names that are known to be constants at kernel compile -- time. [envConsts] :: AllocEnv fromlore tolore -> Set VName [allocInOp] :: AllocEnv fromlore tolore -> Op fromlore -> AllocM fromlore tolore (Op tolore) [envExpHints] :: AllocEnv fromlore tolore -> Exp tolore -> AllocM fromlore tolore [ExpHint] class SizeSubst op opSizeSubst :: SizeSubst op => PatternT dec -> op -> ChunkMap opIsConst :: SizeSubst op => op -> Bool allocInStms :: Allocable fromlore tolore => Stms fromlore -> (Stms tolore -> AllocM fromlore tolore a) -> AllocM fromlore tolore a -- | Allocate memory for a value of the given type. allocForArray :: Allocator lore m => Type -> Space -> m VName simplifiable :: (SimplifiableLore lore, ExpDec lore ~ (), BodyDec lore ~ (), Op lore ~ MemOp inner, Allocator lore (PatAllocM lore)) => (OpWithWisdom inner -> UsageTable) -> (inner -> SimpleM lore (OpWithWisdom inner, Stms (Wise lore))) -> SimpleOps lore arraySizeInBytesExp :: Type -> PrimExp VName mkLetNamesB' :: (Op (Lore m) ~ MemOp inner, MonadBinder m, ExpDec (Lore m) ~ (), Allocator (Lore m) (PatAllocM (Lore m))) => ExpDec (Lore m) -> [VName] -> Exp (Lore m) -> m (Stm (Lore m)) mkLetNamesB'' :: (Op (Lore m) ~ MemOp inner, ExpDec lore ~ (), HasScope (Wise lore) m, Allocator lore (PatAllocM lore), MonadBinder m, CanBeWise (Op lore)) => [VName] -> Exp (Wise lore) -> m (Stm (Wise lore)) instance GHC.Show.Show Futhark.Pass.ExplicitAllocations.AllocStm instance GHC.Classes.Ord Futhark.Pass.ExplicitAllocations.AllocStm instance GHC.Classes.Eq Futhark.Pass.ExplicitAllocations.AllocStm instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Pass.ExplicitAllocations.PatAllocM lore) instance Control.Monad.Writer.Class.MonadWriter [Futhark.Pass.ExplicitAllocations.AllocStm] (Futhark.Pass.ExplicitAllocations.PatAllocM lore) instance Futhark.IR.Decorations.Decorations lore => Futhark.IR.Prop.Scope.HasScope lore (Futhark.Pass.ExplicitAllocations.PatAllocM lore) instance GHC.Base.Monad (Futhark.Pass.ExplicitAllocations.PatAllocM lore) instance GHC.Base.Functor (Futhark.Pass.ExplicitAllocations.PatAllocM lore) instance GHC.Base.Applicative (Futhark.Pass.ExplicitAllocations.PatAllocM lore) instance Control.Monad.Reader.Class.MonadReader (Futhark.Pass.ExplicitAllocations.AllocEnv fromlore tolore) (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore) instance Futhark.IR.Prop.ASTLore tolore => Futhark.IR.Prop.Scope.LocalScope tolore (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore) instance Futhark.IR.Prop.ASTLore tolore => Futhark.IR.Prop.Scope.HasScope tolore (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore) instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore) instance GHC.Base.Monad (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore) instance GHC.Base.Functor (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore) instance GHC.Base.Applicative (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore) instance (Futhark.Pass.ExplicitAllocations.Allocable fromlore tolore, Futhark.Pass.ExplicitAllocations.Allocator tolore (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore)) => Futhark.Binder.Class.MonadBinder (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore) instance Futhark.Pass.ExplicitAllocations.Allocable fromlore tolore => Futhark.Pass.ExplicitAllocations.Allocator tolore (Futhark.Pass.ExplicitAllocations.AllocM fromlore tolore) instance Futhark.IR.Mem.Mem lore => Futhark.Pass.ExplicitAllocations.Allocator lore (Futhark.Pass.ExplicitAllocations.PatAllocM lore) instance Futhark.Pass.ExplicitAllocations.SizeSubst () instance Futhark.Pass.ExplicitAllocations.SizeSubst op => Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.IR.Mem.MemOp op) -- | Segmented operations. These correspond to perfect map nests -- on top of something, except that the maps are -- conceptually only over iotas (so there will be explicit -- indexing inside them). module Futhark.IR.SegOp -- | A SegOp is semantically a perfectly nested stack of maps, on -- top of some bottommost computation (scalar computation, reduction, -- scan, or histogram). The SegSpace encodes the original map -- structure. -- -- All SegOps are parameterised by the representation of their -- body, as well as a *level*. The *level* is a representation-specific -- bit of information. For example, in GPU backends, it is used to -- indicate whether the SegOp is expected to run at the -- thread-level or the group-level. data SegOp lvl lore SegMap :: lvl -> SegSpace -> [Type] -> KernelBody lore -> SegOp lvl lore -- | The KernelSpace must always have at least two dimensions, implying -- that the result of a SegRed is always an array. SegRed :: lvl -> SegSpace -> [SegBinOp lore] -> [Type] -> KernelBody lore -> SegOp lvl lore SegScan :: lvl -> SegSpace -> [SegBinOp lore] -> [Type] -> KernelBody lore -> SegOp lvl lore SegHist :: lvl -> SegSpace -> [HistOp lore] -> [Type] -> KernelBody lore -> SegOp lvl lore -- | Do we need group-virtualisation when generating code for the segmented -- operation? In most cases, we do, but for some simple kernels, we -- compute the full number of groups in advance, and then virtualisation -- is an unnecessary (but generally very small) overhead. This only -- really matters for fairly trivial but very wide map kernels -- where each thread performs constant-time work on scalars. data SegVirt SegVirt :: SegVirt SegNoVirt :: SegVirt -- | Not only do we not need virtualisation, but we _guarantee_ that all -- physical threads participate in the work. This can save some checks in -- code generation. SegNoVirtFull :: SegVirt -- | The level of a SegOp. segLevel :: SegOp lvl lore -> lvl -- | The space of a SegOp. segSpace :: SegOp lvl lore -> SegSpace -- | Type check a SegOp, given a checker for its level. typeCheckSegOp :: Checkable lore => (lvl -> TypeM lore ()) -> SegOp lvl (Aliases lore) -> TypeM lore () -- | Index space of a SegOp. data SegSpace SegSpace :: VName -> [(VName, SubExp)] -> SegSpace -- | Flat physical index corresponding to the dimensions (at code -- generation used for a thread ID or similar). [segFlat] :: SegSpace -> VName [unSegSpace] :: SegSpace -> [(VName, SubExp)] -- | A Scope containing all the identifiers brought into scope by -- this SegSpace. scopeOfSegSpace :: SegSpace -> Scope lore -- | The sizes spanned by the indexes of the SegSpace. segSpaceDims :: SegSpace -> [SubExp] -- | An operator for SegHist. data HistOp lore HistOp :: SubExp -> SubExp -> [VName] -> [SubExp] -> Shape -> Lambda lore -> HistOp lore [histWidth] :: HistOp lore -> SubExp [histRaceFactor] :: HistOp lore -> SubExp [histDest] :: HistOp lore -> [VName] [histNeutral] :: HistOp lore -> [SubExp] -- | In case this operator is semantically a vectorised operator -- (corresponding to a perfect map nest in the SOACS representation), -- these are the logical "dimensions". This is used to generate more -- efficient code. [histShape] :: HistOp lore -> Shape [histOp] :: HistOp lore -> Lambda lore -- | The type of a histogram produced by a HistOp. This can be -- different from the type of the histDests in case we are dealing -- with a segmented histogram. histType :: HistOp lore -> [Type] -- | An operator for SegScan and SegRed. data SegBinOp lore SegBinOp :: Commutativity -> Lambda lore -> [SubExp] -> Shape -> SegBinOp lore [segBinOpComm] :: SegBinOp lore -> Commutativity [segBinOpLambda] :: SegBinOp lore -> Lambda lore [segBinOpNeutral] :: SegBinOp lore -> [SubExp] -- | In case this operator is semantically a vectorised operator -- (corresponding to a perfect map nest in the SOACS representation), -- these are the logical "dimensions". This is used to generate more -- efficient code. [segBinOpShape] :: SegBinOp lore -> Shape -- | How many reduction results are produced by these SegBinOps? segBinOpResults :: [SegBinOp lore] -> Int -- | Split some list into chunks equal to the number of values returned by -- each SegBinOp segBinOpChunks :: [SegBinOp lore] -> [a] -> [[a]] -- | The body of a SegOp. data KernelBody lore KernelBody :: BodyDec lore -> Stms lore -> [KernelResult] -> KernelBody lore [kernelBodyLore] :: KernelBody lore -> BodyDec lore [kernelBodyStms] :: KernelBody lore -> Stms lore [kernelBodyResult] :: KernelBody lore -> [KernelResult] -- | Perform alias analysis on a KernelBody. aliasAnalyseKernelBody :: (ASTLore lore, CanBeAliased (Op lore)) => KernelBody lore -> KernelBody (Aliases lore) -- | The variables consumed in the kernel body. consumedInKernelBody :: Aliased lore => KernelBody lore -> Names -- | Metadata about whether there is a subtle point to this -- KernelResult. This is used to protect things like tiling, which -- might otherwise be removed by the simplifier because they're -- semantically redundant. This has no semantic effect and can be ignored -- at code generation. data ResultManifest -- | Don't simplify this one! ResultNoSimplify :: ResultManifest -- | Go nuts. ResultMaySimplify :: ResultManifest -- | The results produced are only used within the same physical thread -- later on, and can thus be kept in registers. ResultPrivate :: ResultManifest -- | A KernelBody does not return an ordinary Result. -- Instead, it returns a list of these. data KernelResult -- | Each "worker" in the kernel returns this. Whether this is a -- result-per-thread or a result-per-group depends on where the -- SegOp occurs. Returns :: ResultManifest -> SubExp -> KernelResult WriteReturns :: [SubExp] -> VName -> [(Slice SubExp, SubExp)] -> KernelResult ConcatReturns :: SplitOrdering -> SubExp -> SubExp -> VName -> KernelResult TileReturns :: [(SubExp, SubExp)] -> VName -> KernelResult -- | Get the root SubExp corresponding values for a -- KernelResult. kernelResultSubExp :: KernelResult -> SubExp -- | How an array is split into chunks. data SplitOrdering SplitContiguous :: SplitOrdering SplitStrided :: SubExp -> SplitOrdering -- | Like Mapper, but just for SegOps. data SegOpMapper lvl flore tlore m SegOpMapper :: (SubExp -> m SubExp) -> (Lambda flore -> m (Lambda tlore)) -> (KernelBody flore -> m (KernelBody tlore)) -> (VName -> m VName) -> (lvl -> m lvl) -> SegOpMapper lvl flore tlore m [mapOnSegOpSubExp] :: SegOpMapper lvl flore tlore m -> SubExp -> m SubExp [mapOnSegOpLambda] :: SegOpMapper lvl flore tlore m -> Lambda flore -> m (Lambda tlore) [mapOnSegOpBody] :: SegOpMapper lvl flore tlore m -> KernelBody flore -> m (KernelBody tlore) [mapOnSegOpVName] :: SegOpMapper lvl flore tlore m -> VName -> m VName [mapOnSegOpLevel] :: SegOpMapper lvl flore tlore m -> lvl -> m lvl -- | A mapper that simply returns the SegOp verbatim. identitySegOpMapper :: Monad m => SegOpMapper lvl lore lore m -- | Apply a SegOpMapper to the given SegOp. mapSegOpM :: (Applicative m, Monad m) => SegOpMapper lvl flore tlore m -> SegOp lvl flore -> m (SegOp lvl tlore) -- | Simplify the given SegOp. simplifySegOp :: (SimplifiableLore lore, BodyDec lore ~ (), Simplifiable lvl) => SegOp lvl lore -> SimpleM lore (SegOp lvl (Wise lore), Stms (Wise lore)) -- | Does this lore contain SegOps in its Ops? A lore must be -- an instance of this class for the simplification rules to work. class HasSegOp lore where { type family SegOpLevel lore; } asSegOp :: HasSegOp lore => Op lore -> Maybe (SegOp (SegOpLevel lore) lore) segOp :: HasSegOp lore => SegOp (SegOpLevel lore) lore -> Op lore -- | Simplification rules for simplifying SegOps. segOpRules :: (HasSegOp lore, BinderOps lore, Bindable lore) => RuleBook lore -- | Like segOpType, but for memory representations. segOpReturns :: (Mem lore, Monad m, HasScope lore m) => SegOp lvl lore -> m [ExpReturns] instance GHC.Generics.Generic Futhark.IR.SegOp.SplitOrdering instance GHC.Show.Show Futhark.IR.SegOp.SplitOrdering instance GHC.Classes.Ord Futhark.IR.SegOp.SplitOrdering instance GHC.Classes.Eq Futhark.IR.SegOp.SplitOrdering instance GHC.Generics.Generic (Futhark.IR.SegOp.HistOp lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.SegOp.HistOp lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.SegOp.HistOp lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.SegOp.HistOp lore) instance GHC.Generics.Generic (Futhark.IR.SegOp.SegBinOp lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.SegOp.SegBinOp lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.SegOp.SegBinOp lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.SegOp.SegBinOp lore) instance GHC.Generics.Generic Futhark.IR.SegOp.ResultManifest instance GHC.Classes.Ord Futhark.IR.SegOp.ResultManifest instance GHC.Show.Show Futhark.IR.SegOp.ResultManifest instance GHC.Classes.Eq Futhark.IR.SegOp.ResultManifest instance GHC.Generics.Generic Futhark.IR.SegOp.KernelResult instance GHC.Classes.Ord Futhark.IR.SegOp.KernelResult instance GHC.Show.Show Futhark.IR.SegOp.KernelResult instance GHC.Classes.Eq Futhark.IR.SegOp.KernelResult instance GHC.Generics.Generic (Futhark.IR.SegOp.KernelBody lore) instance GHC.Generics.Generic Futhark.IR.SegOp.SegVirt instance GHC.Show.Show Futhark.IR.SegOp.SegVirt instance GHC.Classes.Ord Futhark.IR.SegOp.SegVirt instance GHC.Classes.Eq Futhark.IR.SegOp.SegVirt instance GHC.Generics.Generic Futhark.IR.SegOp.SegSpace instance GHC.Show.Show Futhark.IR.SegOp.SegSpace instance GHC.Classes.Ord Futhark.IR.SegOp.SegSpace instance GHC.Classes.Eq Futhark.IR.SegOp.SegSpace instance GHC.Generics.Generic (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.IR.Decorations.Decorations lore, GHC.Show.Show lvl) => GHC.Show.Show (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.IR.Decorations.Decorations lore, GHC.Classes.Ord lvl) => GHC.Classes.Ord (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.IR.Decorations.Decorations lore, GHC.Classes.Eq lvl) => GHC.Classes.Eq (Futhark.IR.SegOp.SegOp lvl lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Ord (Futhark.IR.SegOp.KernelBody lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.IR.SegOp.KernelBody lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.IR.SegOp.KernelBody lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Transform.Substitute.Substitute lvl) => Futhark.Transform.Substitute.Substitute (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.ASTConstraints lvl) => Futhark.Transform.Rename.Rename (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Decorations.LParamInfo lore), Futhark.IR.Prop.Names.FreeIn lvl) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.ASTLore (Futhark.IR.Aliases.Aliases lore), Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore), Futhark.IR.Prop.ASTConstraints lvl) => Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Decorations.Op lore), Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.ASTConstraints lvl) => Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.SegOp.SegOp lvl lore) instance (Language.SexpGrammar.Class.SexpIso lvl, Futhark.IR.Decorations.Decorations lore) => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SegOp.SegOp lvl lore) instance Futhark.IR.Prop.TypeOf.TypedOp (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Aliases.Aliased lore, Futhark.IR.Prop.ASTConstraints lvl) => Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.SegOp.SegOp lvl lore) instance Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Decorations.Op lore) => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.IR.Pretty.PrettyLore lore, Text.PrettyPrint.Mainland.Class.Pretty lvl) => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.SegOp.SegOp lvl lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.SegOp.SegOp lvl lore) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.ASTConstraints lvl) => Futhark.IR.Prop.IsOp (Futhark.IR.SegOp.SegOp lvl lore) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.SegOp.SegSpace instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.SegOp.SegSpace instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.SegOp.SegSpace instance Language.SexpGrammar.Class.SexpIso Futhark.IR.SegOp.SegVirt instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SegOp.KernelBody lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SegOp.KernelBody lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.Transform.Substitute.Substitute (Futhark.IR.SegOp.KernelBody lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.Transform.Rename.Rename (Futhark.IR.SegOp.KernelBody lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.SegOp.KernelBody lore) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.SegOp.KernelResult instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.SegOp.KernelResult instance Futhark.Transform.Substitute.Substitute Futhark.IR.SegOp.KernelResult instance Futhark.Transform.Rename.Rename Futhark.IR.SegOp.KernelResult instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.SegOp.KernelResult instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.SegOp.KernelResult instance Language.SexpGrammar.Class.SexpIso Futhark.IR.SegOp.ResultManifest instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SegOp.SegBinOp lore) instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.SegOp.SegBinOp lore) instance Futhark.IR.Decorations.Decorations lore => Language.SexpGrammar.Class.SexpIso (Futhark.IR.SegOp.HistOp lore) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.SegOp.SplitOrdering instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.SegOp.SplitOrdering instance Futhark.Transform.Substitute.Substitute Futhark.IR.SegOp.SplitOrdering instance Futhark.Transform.Rename.Rename Futhark.IR.SegOp.SplitOrdering instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.SegOp.SplitOrdering module Futhark.Pass.ExtractKernels.BlockedKernel -- | Constraints pertinent to performing distribution/flattening. type DistLore lore = (Bindable lore, HasSegOp lore, BinderOps lore, LetDec lore ~ Type, ExpDec lore ~ (), BodyDec lore ~ ()) type MkSegLevel lore m = [SubExp] -> String -> ThreadRecommendation -> BinderT lore m (SegOpLevel lore) data ThreadRecommendation ManyThreads :: ThreadRecommendation NoRecommendation :: SegVirt -> ThreadRecommendation segRed :: (MonadFreshNames m, DistLore lore, HasScope lore m) => SegOpLevel lore -> Pattern lore -> SubExp -> [SegBinOp lore] -> Lambda lore -> [VName] -> [(VName, SubExp)] -> [KernelInput] -> m (Stms lore) nonSegRed :: (MonadFreshNames m, DistLore lore, HasScope lore m) => SegOpLevel lore -> Pattern lore -> SubExp -> [SegBinOp lore] -> Lambda lore -> [VName] -> m (Stms lore) segScan :: (MonadFreshNames m, DistLore lore, HasScope lore m) => SegOpLevel lore -> Pattern lore -> SubExp -> [SegBinOp lore] -> Lambda lore -> [VName] -> [(VName, SubExp)] -> [KernelInput] -> m (Stms lore) segHist :: (DistLore lore, MonadFreshNames m, HasScope lore m) => SegOpLevel lore -> Pattern lore -> SubExp -> [(VName, SubExp)] -> [KernelInput] -> [HistOp lore] -> Lambda lore -> [VName] -> m (Stms lore) segMap :: (MonadFreshNames m, DistLore lore, HasScope lore m) => SegOpLevel lore -> Pattern lore -> SubExp -> Lambda lore -> [VName] -> [(VName, SubExp)] -> [KernelInput] -> m (Stms lore) mapKernel :: (DistLore lore, HasScope lore m, MonadFreshNames m) => MkSegLevel lore m -> [(VName, SubExp)] -> [KernelInput] -> [Type] -> KernelBody lore -> m (SegOp (SegOpLevel lore) lore, Stms lore) data KernelInput KernelInput :: VName -> Type -> VName -> [SubExp] -> KernelInput [kernelInputName] :: KernelInput -> VName [kernelInputType] :: KernelInput -> Type [kernelInputArray] :: KernelInput -> VName [kernelInputIndices] :: KernelInput -> [SubExp] readKernelInput :: (DistLore (Lore m), MonadBinder m) => KernelInput -> m () mkSegSpace :: MonadFreshNames m => [(VName, SubExp)] -> m SegSpace dummyDim :: (MonadFreshNames m, MonadBinder m, DistLore (Lore m)) => Pattern (Lore m) -> m (Pattern (Lore m), [(VName, SubExp)], m ()) instance GHC.Show.Show Futhark.Pass.ExtractKernels.BlockedKernel.KernelInput module Futhark.Pass.ExtractKernels.Distribution type Target = (PatternT Type, Result) -- | First pair element is the very innermost ("current") target. In the -- list, the outermost target comes first. Invariant: Every element of a -- pattern must be present as the result of the immediately enclosing -- target. This is ensured by pushInnerTarget by removing unused -- pattern elements. data Targets ppTargets :: Targets -> String singleTarget :: Target -> Targets outerTarget :: Targets -> Target innerTarget :: Targets -> Target pushInnerTarget :: Target -> Targets -> Targets popInnerTarget :: Targets -> Maybe (Target, Targets) targetsScope :: DistLore lore => Targets -> Scope lore data LoopNesting MapNesting :: PatternT Type -> StmAux () -> SubExp -> [(Param Type, VName)] -> LoopNesting [loopNestingPattern] :: LoopNesting -> PatternT Type [loopNestingAux] :: LoopNesting -> StmAux () [loopNestingWidth] :: LoopNesting -> SubExp [loopNestingParamsAndArrs] :: LoopNesting -> [(Param Type, VName)] ppLoopNesting :: LoopNesting -> String scopeOfLoopNesting :: DistLore lore => LoopNesting -> Scope lore data Nesting Nesting :: Names -> LoopNesting -> Nesting [nestingLetBound] :: Nesting -> Names [nestingLoop] :: Nesting -> LoopNesting type Nestings = (Nesting, [Nesting]) ppNestings :: Nestings -> String letBindInInnerNesting :: Names -> Nestings -> Nestings singleNesting :: Nesting -> Nestings pushInnerNesting :: Nesting -> Nestings -> Nestings -- | Note: first element is *outermost* nesting. This is different from the -- similar types elsewhere! type KernelNest = (LoopNesting, [LoopNesting]) ppKernelNest :: KernelNest -> String newKernel :: LoopNesting -> KernelNest -- | Retrieve the innermost kernel nesting. innermostKernelNesting :: KernelNest -> LoopNesting -- | Add new outermost nesting, pushing the current outermost to the list, -- also taking care to swap patterns if necessary. pushKernelNesting :: Target -> LoopNesting -> KernelNest -> KernelNest -- | Add new innermost nesting, pushing the current outermost to the list. -- It is important that the Target has the right order -- (non-permuted compared to what is expected by the outer nests). pushInnerKernelNesting :: Target -> LoopNesting -> KernelNest -> KernelNest kernelNestLoops :: KernelNest -> [LoopNesting] kernelNestWidths :: KernelNest -> [SubExp] boundInKernelNest :: KernelNest -> Names boundInKernelNests :: KernelNest -> [Names] -- | Flatten a kernel nesting to: -- --
    --
  1. The index space.
  2. --
  3. The kernel inputs - note that some of these may be unused.
  4. --
flatKernel :: MonadFreshNames m => KernelNest -> m ([(VName, SubExp)], [KernelInput]) constructKernel :: (DistLore lore, MonadFreshNames m, LocalScope lore m) => MkSegLevel lore m -> KernelNest -> Body lore -> m (Stm lore, Stms lore) tryDistribute :: (DistLore lore, MonadFreshNames m, LocalScope lore m, MonadLogger m) => MkSegLevel lore m -> Nestings -> Targets -> Stms lore -> m (Maybe (Targets, Stms lore)) tryDistributeStm :: (MonadFreshNames m, HasScope t m, ASTLore lore) => Nestings -> Targets -> Stm lore -> m (Maybe (Result, Targets, KernelNest)) instance GHC.Show.Show Futhark.Pass.ExtractKernels.Distribution.LoopNesting instance GHC.Show.Show Futhark.Pass.ExtractKernels.Distribution.Nesting instance Futhark.IR.Prop.Names.FreeIn Futhark.Pass.ExtractKernels.Distribution.LoopNesting -- | It is well known that fully parallel loops can always be interchanged -- inwards with a sequential loop. This module implements that -- transformation. -- -- This is also where we implement loop-switching (for branches), which -- is semantically similar to interchange. module Futhark.Pass.ExtractKernels.Interchange -- | An encoding of a sequential do-loop with no existential context, -- alongside its result pattern. data SeqLoop SeqLoop :: [Int] -> Pattern -> [(FParam, SubExp)] -> LoopForm SOACS -> Body -> SeqLoop -- | Given a (parallel) map nesting and an inner sequential loop, move the -- maps inside the sequential loop. The result is several statements - -- one of these will be the loop, which will then contain statements with -- map expressions. interchangeLoops :: (MonadFreshNames m, HasScope SOACS m) => KernelNest -> SeqLoop -> m (Stms SOACS) data Branch Branch :: [Int] -> Pattern -> SubExp -> Body -> Body -> IfDec (BranchType SOACS) -> Branch interchangeBranch :: (MonadFreshNames m, HasScope SOACS m) => KernelNest -> Branch -> m (Stms SOACS) module Futhark.Pass.ExtractKernels.DistributeNests data MapLoop MapLoop :: Pattern -> StmAux () -> SubExp -> Lambda -> [VName] -> MapLoop mapLoopStm :: MapLoop -> Stm SOACS bodyContainsParallelism :: Body SOACS -> Bool lambdaContainsParallelism :: Lambda SOACS -> Bool determineReduceOp :: (MonadBinder m, Lore m ~ lore) => Lambda SOACS -> [SubExp] -> m (Lambda SOACS, [SubExp], Shape) histKernel :: (MonadBinder m, DistLore (Lore m)) => (Lambda SOACS -> m (Lambda (Lore m))) -> SegOpLevel (Lore m) -> PatternT Type -> [(VName, SubExp)] -> [KernelInput] -> Certificates -> SubExp -> [HistOp SOACS] -> Lambda (Lore m) -> [VName] -> m (Stms (Lore m)) data DistEnv lore m DistEnv :: Nestings -> Scope lore -> (Stms SOACS -> DistNestT lore m (Stms lore)) -> (MapLoop -> DistAcc lore -> DistNestT lore m (DistAcc lore)) -> (Stm SOACS -> Binder lore (Stms lore)) -> (Lambda SOACS -> Binder lore (Lambda lore)) -> MkSegLevel lore m -> DistEnv lore m [distNest] :: DistEnv lore m -> Nestings [distScope] :: DistEnv lore m -> Scope lore [distOnTopLevelStms] :: DistEnv lore m -> Stms SOACS -> DistNestT lore m (Stms lore) [distOnInnerMap] :: DistEnv lore m -> MapLoop -> DistAcc lore -> DistNestT lore m (DistAcc lore) [distOnSOACSStms] :: DistEnv lore m -> Stm SOACS -> Binder lore (Stms lore) [distOnSOACSLambda] :: DistEnv lore m -> Lambda SOACS -> Binder lore (Lambda lore) [distSegLevel] :: DistEnv lore m -> MkSegLevel lore m data DistAcc lore DistAcc :: Targets -> Stms lore -> DistAcc lore [distTargets] :: DistAcc lore -> Targets [distStms] :: DistAcc lore -> Stms lore runDistNestT :: (MonadLogger m, DistLore lore) => DistEnv lore m -> DistNestT lore m (DistAcc lore) -> m (Stms lore) data DistNestT lore m a liftInner :: (LocalScope lore m, DistLore lore) => m a -> DistNestT lore m a distributeMap :: (MonadFreshNames m, LocalScope lore m, DistLore lore) => MapLoop -> DistAcc lore -> DistNestT lore m (DistAcc lore) distribute :: (MonadFreshNames m, LocalScope lore m, DistLore lore) => DistAcc lore -> DistNestT lore m (DistAcc lore) distributeSingleStm :: (MonadFreshNames m, LocalScope lore m, DistLore lore) => DistAcc lore -> Stm SOACS -> DistNestT lore m (Maybe (PostStms lore, Result, KernelNest, DistAcc lore)) distributeMapBodyStms :: (MonadFreshNames m, LocalScope lore m, DistLore lore) => DistAcc lore -> Stms SOACS -> DistNestT lore m (DistAcc lore) addStmsToAcc :: Stms lore -> DistAcc lore -> DistAcc lore addStmToAcc :: (MonadFreshNames m, DistLore lore) => Stm SOACS -> DistAcc lore -> DistNestT lore m (DistAcc lore) permutationAndMissing :: PatternT Type -> [SubExp] -> Maybe ([Int], [PatElemT Type]) addPostStms :: Monad m => PostStms lore -> DistNestT lore m () postStm :: Monad m => Stms lore -> DistNestT lore m () inNesting :: (Monad m, DistLore lore) => KernelNest -> DistNestT lore m a -> DistNestT lore m a instance GHC.Base.Monad m => Control.Monad.Writer.Class.MonadWriter (Futhark.Pass.ExtractKernels.DistributeNests.DistRes lore) (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT lore m) instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (Futhark.Pass.ExtractKernels.DistributeNests.DistEnv lore m) (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT lore m) instance GHC.Base.Monad m => GHC.Base.Monad (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT lore m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT lore m) instance GHC.Base.Functor m => GHC.Base.Functor (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT lore m) instance Futhark.MonadFreshNames.MonadFreshNames m => Futhark.MonadFreshNames.MonadFreshNames (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT lore m) instance (GHC.Base.Monad m, Futhark.IR.Prop.ASTLore lore) => Futhark.IR.Prop.Scope.HasScope lore (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT lore m) instance (GHC.Base.Monad m, Futhark.IR.Prop.ASTLore lore) => Futhark.IR.Prop.Scope.LocalScope lore (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT lore m) instance GHC.Base.Monad m => Futhark.Util.Log.MonadLogger (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT lore m) instance GHC.Base.Semigroup (Futhark.Pass.ExtractKernels.DistributeNests.DistRes lore) instance GHC.Base.Monoid (Futhark.Pass.ExtractKernels.DistributeNests.DistRes lore) instance GHC.Base.Semigroup (Futhark.Pass.ExtractKernels.DistributeNests.PostStms lore) instance GHC.Base.Monoid (Futhark.Pass.ExtractKernels.DistributeNests.PostStms lore) module Futhark.IR.Mem.Simplify simplifyProgGeneric :: (SimplifyMemory lore, Op lore ~ MemOp inner) => SimpleOps lore -> Prog lore -> PassM (Prog lore) simplifyStmsGeneric :: (HasScope lore m, MonadFreshNames m, SimplifyMemory lore, Op lore ~ MemOp inner) => SimpleOps lore -> Stms lore -> m (SymbolTable (Wise lore), Stms lore) simpleGeneric :: (SimplifyMemory lore, Op lore ~ MemOp inner) => (OpWithWisdom inner -> UsageTable) -> SimplifyOp lore inner -> SimpleOps lore -- | Some constraints that must hold for the simplification rules to work. type SimplifyMemory lore = (SimplifiableLore lore, ExpDec lore ~ (), BodyDec lore ~ (), AllocOp (Op (Wise lore)), CanBeWise (Op lore), BinderOps (Wise lore), Mem lore) -- | Definitions for multicore operations. -- -- Most of the interesting stuff is in Futhark.IR.SegOp, which is -- also re-exported from here. module Futhark.IR.MC.Op -- | An operation for the multicore representation. Feel free to extend -- this on an ad hoc basis as needed. Parameterised with some other -- operation. data MCOp lore op -- | The first SegOp (if it exists) contains nested parallelism, -- while the second one has a fully sequential body. They are -- semantically fully equivalent. ParOp :: Maybe (SegOp () lore) -> SegOp () lore -> MCOp lore op -- | Something else (in practice often a SOAC). OtherOp :: op -> MCOp lore op typeCheckMCOp :: Checkable lore => (op -> TypeM lore ()) -> MCOp (Aliases lore) op -> TypeM lore () simplifyMCOp :: (SimplifiableLore lore, BodyDec lore ~ ()) => SimplifyOp lore op -> MCOp lore op -> SimpleM lore (MCOp (Wise lore) (OpWithWisdom op), Stms (Wise lore)) instance GHC.Generics.Generic (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Decorations.Decorations lore, GHC.Show.Show op) => GHC.Show.Show (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Decorations.Decorations lore, GHC.Classes.Ord op) => GHC.Classes.Ord (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Decorations.Decorations lore, GHC.Classes.Eq op) => GHC.Classes.Eq (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Decorations.Decorations lore, Language.SexpGrammar.Class.SexpIso op) => Language.SexpGrammar.Class.SexpIso (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Transform.Substitute.Substitute op) => Futhark.Transform.Substitute.Substitute (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Transform.Rename.Rename op) => Futhark.Transform.Rename.Rename (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Names.FreeIn op) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.IsOp op) => Futhark.IR.Prop.IsOp (Futhark.IR.MC.Op.MCOp lore op) instance Futhark.IR.Prop.TypeOf.TypedOp op => Futhark.IR.Prop.TypeOf.TypedOp (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Prop.Aliases.Aliased lore, Futhark.IR.Prop.Aliases.AliasedOp op, Futhark.IR.Prop.ASTLore lore) => Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore), Futhark.IR.Prop.Aliases.CanBeAliased op, Futhark.IR.Prop.ASTLore lore) => Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Decorations.Op lore), Futhark.Optimise.Simplify.Lore.CanBeWise op, Futhark.IR.Prop.ASTLore lore) => Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Analysis.SymbolTable.IndexOp op) => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Pretty.PrettyLore lore, Text.PrettyPrint.Mainland.Class.Pretty op) => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Decorations.Op lore), Futhark.Analysis.Metrics.OpMetrics op) => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.MC.Op.MCOp lore op) module Futhark.IR.MCMem data MCMem simplifyProg :: Prog MCMem -> PassM (Prog MCMem) instance Futhark.IR.Decorations.Decorations Futhark.IR.MCMem.MCMem instance Futhark.IR.Prop.ASTLore Futhark.IR.MCMem.MCMem instance Futhark.IR.Mem.OpReturns Futhark.IR.MCMem.MCMem instance Futhark.IR.Pretty.PrettyLore Futhark.IR.MCMem.MCMem instance Futhark.TypeCheck.CheckableOp Futhark.IR.MCMem.MCMem instance Futhark.TypeCheck.Checkable Futhark.IR.MCMem.MCMem instance Futhark.Binder.BinderOps Futhark.IR.MCMem.MCMem instance Futhark.Binder.BinderOps (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.MCMem.MCMem) -- | A representation for multicore CPU parallelism. module Futhark.IR.MC data MC simplifyProg :: Prog MC -> PassM (Prog MC) -- | Like Mapper, but just for SOACs. data SOACMapper flore tlore m SOACMapper :: (SubExp -> m SubExp) -> (Lambda flore -> m (Lambda tlore)) -> (VName -> m VName) -> SOACMapper flore tlore m [mapOnSOACSubExp] :: SOACMapper flore tlore m -> SubExp -> m SubExp [mapOnSOACLambda] :: SOACMapper flore tlore m -> Lambda flore -> m (Lambda tlore) [mapOnSOACVName] :: SOACMapper flore tlore m -> VName -> m VName -- | How to compute a single reduction result. data Reduce lore Reduce :: Commutativity -> Lambda lore -> [SubExp] -> Reduce lore [redComm] :: Reduce lore -> Commutativity [redLambda] :: Reduce lore -> Lambda lore [redNeutral] :: Reduce lore -> [SubExp] -- | How to compute a single scan result. data Scan lore Scan :: Lambda lore -> [SubExp] -> Scan lore [scanLambda] :: Scan lore -> Lambda lore [scanNeutral] :: Scan lore -> [SubExp] -- | The essential parts of a Screma factored out (everything except -- the input arrays). data ScremaForm lore ScremaForm :: [Scan lore] -> [Reduce lore] -> Lambda lore -> ScremaForm lore -- | What kind of stream is this? data StreamForm lore Parallel :: StreamOrd -> Commutativity -> Lambda lore -> [SubExp] -> StreamForm lore Sequential :: [SubExp] -> StreamForm lore -- | Is the stream chunk required to correspond to a contiguous subsequence -- of the original input (InOrder) or not? Disorder streams -- can be more efficient, but not all algorithms work with this. data StreamOrd InOrder :: StreamOrd Disorder :: StreamOrd -- | A second-order array combinator (SOAC). data SOAC lore Stream :: SubExp -> StreamForm lore -> Lambda lore -> [VName] -> SOAC lore -- |
--   Scatter cs length lambda index and value arrays
--   
-- -- <input/output arrays along with their sizes and number of values to -- write for that array> -- -- length is the length of each index array and value array, since -- they all must be the same length for any fusion to make sense. If you -- have a list of index-value array pairs of different sizes, you need to -- use multiple writes instead. -- -- The lambda body returns the output in this manner: -- -- -- -- This must be consistent along all Scatter-related optimisations. Scatter :: SubExp -> Lambda lore -> [VName] -> [(SubExp, Int, VName)] -> SOAC lore -- |
--   Hist length dest-arrays-and-ops fun arrays
--   
-- -- The first SubExp is the length of the input arrays. The first list -- describes the operations to perform. The Lambda is the bucket -- function. Finally comes the input images. Hist :: SubExp -> [HistOp lore] -> Lambda lore -> [VName] -> SOAC lore -- | A combination of scan, reduction, and map. The first SubExp is -- the size of the input arrays. Screma :: SubExp -> ScremaForm lore -> [VName] -> SOAC lore -- | How many reduction results are produced by these Scans? scanResults :: [Scan lore] -> Int -- | Combine multiple scan operators to a single operator. singleScan :: Bindable lore => [Scan lore] -> Scan lore -- | How many reduction results are produced by these Reduces? redResults :: [Reduce lore] -> Int -- | Combine multiple reduction operators to a single operator. singleReduce :: Bindable lore => [Reduce lore] -> Reduce lore -- | The types produced by a single Screma, given the size of the -- input array. scremaType :: SubExp -> ScremaForm lore -> [Type] -- | Construct a lambda that takes parameters of the given types and simply -- returns them unchanged. mkIdentityLambda :: (Bindable lore, MonadFreshNames m) => [Type] -> m (Lambda lore) -- | Is the given lambda an identity lambda? isIdentityLambda :: Lambda lore -> Bool -- | A lambda with no parameters that returns no values. nilFn :: Bindable lore => Lambda lore -- | Construct a Screma with possibly multiple scans, and the given map -- function. scanomapSOAC :: [Scan lore] -> Lambda lore -> ScremaForm lore -- | Construct a Screma with possibly multiple reductions, and the given -- map function. redomapSOAC :: [Reduce lore] -> Lambda lore -> ScremaForm lore -- | Construct a Screma with possibly multiple scans, and identity map -- function. scanSOAC :: (Bindable lore, MonadFreshNames m) => [Scan lore] -> m (ScremaForm lore) -- | Construct a Screma with possibly multiple reductions, and identity map -- function. reduceSOAC :: (Bindable lore, MonadFreshNames m) => [Reduce lore] -> m (ScremaForm lore) -- | Construct a Screma corresponding to a map. mapSOAC :: Lambda lore -> ScremaForm lore -- | Does this Screma correspond to a scan-map composition? isScanomapSOAC :: ScremaForm lore -> Maybe ([Scan lore], Lambda lore) -- | Does this Screma correspond to pure scan? isScanSOAC :: ScremaForm lore -> Maybe [Scan lore] -- | Does this Screma correspond to a reduce-map composition? isRedomapSOAC :: ScremaForm lore -> Maybe ([Reduce lore], Lambda lore) -- | Does this Screma correspond to a pure reduce? isReduceSOAC :: ScremaForm lore -> Maybe [Reduce lore] -- | Does this Screma correspond to a simple map, without any reduction or -- scan results? isMapSOAC :: ScremaForm lore -> Maybe (Lambda lore) -- | A mapper that simply returns the SOAC verbatim. identitySOACMapper :: Monad m => SOACMapper lore lore m -- | Map a monadic action across the immediate children of a SOAC. The -- mapping does not descend recursively into subexpressions and is done -- left-to-right. mapSOACM :: (Applicative m, Monad m) => SOACMapper flore tlore m -> SOAC flore -> m (SOAC tlore) -- | The type of a SOAC. soacType :: SOAC lore -> [Type] -- | Type-check a SOAC. typeCheckSOAC :: Checkable lore => SOAC (Aliases lore) -> TypeM lore () -- | Get Stream's accumulators as a sub-expression list getStreamAccums :: StreamForm lore -> [SubExp] -- | Prettyprint the given Screma. ppScrema :: (PrettyLore lore, Pretty inp) => SubExp -> ScremaForm lore -> [inp] -> Doc -- | Prettyprint the given histogram operation. ppHist :: (PrettyLore lore, Pretty inp) => SubExp -> [HistOp lore] -> Lambda lore -> [inp] -> Doc instance Futhark.IR.Decorations.Decorations Futhark.IR.MC.MC instance Futhark.IR.Prop.ASTLore Futhark.IR.MC.MC instance Futhark.TypeCheck.CheckableOp Futhark.IR.MC.MC instance Futhark.TypeCheck.Checkable Futhark.IR.MC.MC instance Futhark.Binder.Class.Bindable Futhark.IR.MC.MC instance Futhark.Binder.BinderOps Futhark.IR.MC.MC instance Futhark.Binder.BinderOps (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.MC.MC) instance Futhark.IR.Pretty.PrettyLore Futhark.IR.MC.MC instance Futhark.IR.SegOp.HasSegOp Futhark.IR.MC.MC instance Futhark.IR.SegOp.HasSegOp (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.MC.MC) module Futhark.IR.Kernels.Kernel -- | A simple size-level query or computation. data SizeOp -- | SplitSpace o w i elems_per_thread. -- -- Computes how to divide array elements to threads in a kernel. Returns -- the number of elements in the chunk that the current thread should -- take. -- -- w is the length of the outer dimension in the array. -- i is the current thread index. Each thread takes at most -- elems_per_thread elements. -- -- If the order o is SplitContiguous, thread with index -- i should receive elements i*elems_per_tread, -- i*elems_per_thread + 1, ..., i*elems_per_thread + -- (elems_per_thread-1). -- -- If the order o is SplitStrided stride, the -- thread will receive elements i, i+stride, i+2*stride, ..., -- i+(elems_per_thread-1)*stride. SplitSpace :: SplitOrdering -> SubExp -> SubExp -> SubExp -> SizeOp -- | Produce some runtime-configurable size. GetSize :: Name -> SizeClass -> SizeOp -- | The maximum size of some class. GetSizeMax :: SizeClass -> SizeOp -- | Compare size (likely a threshold) with some integer value. CmpSizeLe :: Name -> SizeClass -> SubExp -> SizeOp -- | CalcNumGroups w max_num_groups group_size calculates the -- number of GPU workgroups to use for an input of the given size. The -- Name is a size name. Note that w is an i64 to avoid -- overflow issues. CalcNumGroups :: SubExp -> Name -> SubExp -> SizeOp -- | A host-level operation; parameterised by what else it can do. data HostOp lore op -- | A segmented operation. SegOp :: SegOp SegLevel lore -> HostOp lore op SizeOp :: SizeOp -> HostOp lore op OtherOp :: op -> HostOp lore op typeCheckHostOp :: Checkable lore => (SegLevel -> OpWithAliases (Op lore) -> TypeM lore ()) -> Maybe SegLevel -> (op -> TypeM lore ()) -> HostOp (Aliases lore) op -> TypeM lore () -- | At which level the *body* of a SegOp executes. data SegLevel SegThread :: Count NumGroups SubExp -> Count GroupSize SubExp -> SegVirt -> SegLevel [segNumGroups] :: SegLevel -> Count NumGroups SubExp [segGroupSize] :: SegLevel -> Count GroupSize SubExp [segVirt] :: SegLevel -> SegVirt SegGroup :: Count NumGroups SubExp -> Count GroupSize SubExp -> SegVirt -> SegLevel [segNumGroups] :: SegLevel -> Count NumGroups SubExp [segGroupSize] :: SegLevel -> Count GroupSize SubExp [segVirt] :: SegLevel -> SegVirt instance GHC.Generics.Generic Futhark.IR.Kernels.Kernel.SegLevel instance GHC.Show.Show Futhark.IR.Kernels.Kernel.SegLevel instance GHC.Classes.Ord Futhark.IR.Kernels.Kernel.SegLevel instance GHC.Classes.Eq Futhark.IR.Kernels.Kernel.SegLevel instance GHC.Generics.Generic Futhark.IR.Kernels.Kernel.SizeOp instance GHC.Show.Show Futhark.IR.Kernels.Kernel.SizeOp instance GHC.Classes.Ord Futhark.IR.Kernels.Kernel.SizeOp instance GHC.Classes.Eq Futhark.IR.Kernels.Kernel.SizeOp instance GHC.Generics.Generic (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Decorations.Decorations lore, GHC.Show.Show op) => GHC.Show.Show (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Decorations.Decorations lore, GHC.Classes.Ord op) => GHC.Classes.Ord (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Decorations.Decorations lore, GHC.Classes.Eq op) => GHC.Classes.Eq (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Language.SexpGrammar.Class.SexpIso op, Futhark.IR.Decorations.Decorations lore) => Language.SexpGrammar.Class.SexpIso (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Transform.Substitute.Substitute op) => Futhark.Transform.Substitute.Substitute (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Transform.Rename.Rename op) => Futhark.Transform.Rename.Rename (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.IsOp op) => Futhark.IR.Prop.IsOp (Futhark.IR.Kernels.Kernel.HostOp lore op) instance Futhark.IR.Prop.TypeOf.TypedOp op => Futhark.IR.Prop.TypeOf.TypedOp (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Prop.Aliases.Aliased lore, Futhark.IR.Prop.Aliases.AliasedOp op, Futhark.IR.Prop.ASTLore lore) => Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Names.FreeIn op) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore), Futhark.IR.Prop.Aliases.CanBeAliased op, Futhark.IR.Prop.ASTLore lore) => Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Decorations.Op lore), Futhark.Optimise.Simplify.Lore.CanBeWise op, Futhark.IR.Prop.ASTLore lore) => Futhark.Optimise.Simplify.Lore.CanBeWise (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.Analysis.SymbolTable.IndexOp op) => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Pretty.PrettyLore lore, Text.PrettyPrint.Mainland.Class.Pretty op) => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Decorations.Op lore), Futhark.Analysis.Metrics.OpMetrics op) => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Kernels.Kernel.HostOp lore op) instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Kernels.Kernel.SizeOp instance Futhark.Transform.Substitute.Substitute Futhark.IR.Kernels.Kernel.SizeOp instance Futhark.Transform.Rename.Rename Futhark.IR.Kernels.Kernel.SizeOp instance Futhark.IR.Prop.IsOp Futhark.IR.Kernels.Kernel.SizeOp instance Futhark.IR.Prop.TypeOf.TypedOp Futhark.IR.Kernels.Kernel.SizeOp instance Futhark.IR.Prop.Aliases.AliasedOp Futhark.IR.Kernels.Kernel.SizeOp instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Kernels.Kernel.SizeOp instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Kernels.Kernel.SizeOp instance Futhark.Analysis.Metrics.OpMetrics Futhark.IR.Kernels.Kernel.SizeOp instance Language.SexpGrammar.Class.SexpIso Futhark.IR.Kernels.Kernel.SegLevel instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.IR.Kernels.Kernel.SegLevel instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.Kernels.Kernel.SegLevel instance Futhark.Transform.Substitute.Substitute Futhark.IR.Kernels.Kernel.SegLevel instance Futhark.Transform.Rename.Rename Futhark.IR.Kernels.Kernel.SegLevel instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Kernels.Kernel.SegLevel -- | This module implements common-subexpression elimination. This module -- does not actually remove the duplicate, but only replaces one with a -- diference to the other. E.g: -- --
--   let a = x + y
--   let b = x + y
--   
-- -- becomes: -- --
--   let a = x + y
--   let b = a
--   
-- -- After which copy propagation in the simplifier will actually remove -- the definition of b. -- -- Our CSE is still rather stupid. No normalisation is performed, so the -- expressions x+y and y+x will be considered distinct. -- Furthermore, no expression with its own binding will be considered -- equal to any other, since the variable names will be distinct. This -- affects SOACs in particular. module Futhark.Optimise.CSE -- | Perform CSE on every function in a program. -- -- If the boolean argument is false, the pass will not perform CSE on -- expressions producing arrays. This should be disabled when the lore -- has memory information, since at that point arrays have identity -- beyond their value. performCSE :: (ASTLore lore, CanBeAliased (Op lore), CSEInOp (OpWithAliases (Op lore))) => Bool -> Pass lore lore -- | Perform CSE on a single function. -- -- If the boolean argument is false, the pass will not perform CSE on -- expressions producing arrays. This should be disabled when the lore -- has memory information, since at that point arrays have identity -- beyond their value. performCSEOnFunDef :: (ASTLore lore, CanBeAliased (Op lore), CSEInOp (OpWithAliases (Op lore))) => Bool -> FunDef lore -> FunDef lore -- | Perform CSE on some statements. -- -- If the boolean argument is false, the pass will not perform CSE on -- expressions producing arrays. This should be disabled when the lore -- has memory information, since at that point arrays have identity -- beyond their value. performCSEOnStms :: (ASTLore lore, CanBeAliased (Op lore), CSEInOp (OpWithAliases (Op lore))) => Bool -> Stms lore -> Stms lore -- | The operations that permit CSE. class CSEInOp op instance Futhark.Optimise.CSE.CSEInOp () instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Aliases.Aliased lore, Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Decorations.Op lore), Futhark.Optimise.CSE.CSEInOp op) => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Kernels.Kernel.HostOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Aliases.Aliased lore, Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Decorations.Op lore), Futhark.Optimise.CSE.CSEInOp op) => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.MC.Op.MCOp lore op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Aliases.Aliased lore, Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Decorations.Op lore)) => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.SegOp.SegOp lvl lore) instance Futhark.Optimise.CSE.CSEInOp op => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Mem.MemOp op) instance (Futhark.IR.Prop.ASTLore lore, Futhark.IR.Prop.Aliases.CanBeAliased (Futhark.IR.Decorations.Op lore), Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Prop.Aliases.OpWithAliases (Futhark.IR.Decorations.Op lore))) => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.SOACS.SOAC.SOAC (Futhark.IR.Aliases.Aliases lore)) -- | This module implements a compiler pass for inlining functions, then -- removing those that have become dead. module Futhark.Optimise.InliningDeadFun -- | Inline all functions and remove the resulting dead functions. inlineFunctions :: Pass SOACS SOACS -- | removeDeadFunctions prog removes the functions that are -- unreachable from the main function from the program. removeDeadFunctions :: Pass SOACS SOACS module Futhark.IR.SeqMem data SeqMem simplifyProg :: Prog SeqMem -> PassM (Prog SeqMem) simpleSeqMem :: SimpleOps SeqMem instance Futhark.IR.Decorations.Decorations Futhark.IR.SeqMem.SeqMem instance Futhark.IR.Prop.ASTLore Futhark.IR.SeqMem.SeqMem instance Futhark.IR.Mem.OpReturns Futhark.IR.SeqMem.SeqMem instance Futhark.IR.Pretty.PrettyLore Futhark.IR.SeqMem.SeqMem instance Futhark.TypeCheck.CheckableOp Futhark.IR.SeqMem.SeqMem instance Futhark.TypeCheck.Checkable Futhark.IR.SeqMem.SeqMem instance Futhark.Binder.BinderOps Futhark.IR.SeqMem.SeqMem instance Futhark.Binder.BinderOps (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.SeqMem.SeqMem) module Futhark.Pass.ExplicitAllocations.Seq explicitAllocations :: Pass Seq SeqMem simplifiable :: (SimplifiableLore lore, ExpDec lore ~ (), BodyDec lore ~ (), Op lore ~ MemOp inner, Allocator lore (PatAllocM lore)) => (OpWithWisdom inner -> UsageTable) -> (inner -> SimpleM lore (OpWithWisdom inner, Stms (Wise lore))) -> SimpleOps lore -- | A representation with flat parallelism via GPU-oriented kernels. module Futhark.IR.Kernels -- | The phantom data type for the kernels representation. data Kernels -- | Like Mapper, but just for SOACs. data SOACMapper flore tlore m SOACMapper :: (SubExp -> m SubExp) -> (Lambda flore -> m (Lambda tlore)) -> (VName -> m VName) -> SOACMapper flore tlore m [mapOnSOACSubExp] :: SOACMapper flore tlore m -> SubExp -> m SubExp [mapOnSOACLambda] :: SOACMapper flore tlore m -> Lambda flore -> m (Lambda tlore) [mapOnSOACVName] :: SOACMapper flore tlore m -> VName -> m VName -- | How to compute a single reduction result. data Reduce lore Reduce :: Commutativity -> Lambda lore -> [SubExp] -> Reduce lore [redComm] :: Reduce lore -> Commutativity [redLambda] :: Reduce lore -> Lambda lore [redNeutral] :: Reduce lore -> [SubExp] -- | How to compute a single scan result. data Scan lore Scan :: Lambda lore -> [SubExp] -> Scan lore [scanLambda] :: Scan lore -> Lambda lore [scanNeutral] :: Scan lore -> [SubExp] -- | The essential parts of a Screma factored out (everything except -- the input arrays). data ScremaForm lore ScremaForm :: [Scan lore] -> [Reduce lore] -> Lambda lore -> ScremaForm lore -- | What kind of stream is this? data StreamForm lore Parallel :: StreamOrd -> Commutativity -> Lambda lore -> [SubExp] -> StreamForm lore Sequential :: [SubExp] -> StreamForm lore -- | Is the stream chunk required to correspond to a contiguous subsequence -- of the original input (InOrder) or not? Disorder streams -- can be more efficient, but not all algorithms work with this. data StreamOrd InOrder :: StreamOrd Disorder :: StreamOrd -- | A second-order array combinator (SOAC). data SOAC lore Stream :: SubExp -> StreamForm lore -> Lambda lore -> [VName] -> SOAC lore -- |
--   Scatter cs length lambda index and value arrays
--   
-- -- <input/output arrays along with their sizes and number of values to -- write for that array> -- -- length is the length of each index array and value array, since -- they all must be the same length for any fusion to make sense. If you -- have a list of index-value array pairs of different sizes, you need to -- use multiple writes instead. -- -- The lambda body returns the output in this manner: -- -- -- -- This must be consistent along all Scatter-related optimisations. Scatter :: SubExp -> Lambda lore -> [VName] -> [(SubExp, Int, VName)] -> SOAC lore -- |
--   Hist length dest-arrays-and-ops fun arrays
--   
-- -- The first SubExp is the length of the input arrays. The first list -- describes the operations to perform. The Lambda is the bucket -- function. Finally comes the input images. Hist :: SubExp -> [HistOp lore] -> Lambda lore -> [VName] -> SOAC lore -- | A combination of scan, reduction, and map. The first SubExp is -- the size of the input arrays. Screma :: SubExp -> ScremaForm lore -> [VName] -> SOAC lore -- | How many reduction results are produced by these Scans? scanResults :: [Scan lore] -> Int -- | Combine multiple scan operators to a single operator. singleScan :: Bindable lore => [Scan lore] -> Scan lore -- | How many reduction results are produced by these Reduces? redResults :: [Reduce lore] -> Int -- | Combine multiple reduction operators to a single operator. singleReduce :: Bindable lore => [Reduce lore] -> Reduce lore -- | The types produced by a single Screma, given the size of the -- input array. scremaType :: SubExp -> ScremaForm lore -> [Type] -- | Construct a lambda that takes parameters of the given types and simply -- returns them unchanged. mkIdentityLambda :: (Bindable lore, MonadFreshNames m) => [Type] -> m (Lambda lore) -- | Is the given lambda an identity lambda? isIdentityLambda :: Lambda lore -> Bool -- | A lambda with no parameters that returns no values. nilFn :: Bindable lore => Lambda lore -- | Construct a Screma with possibly multiple scans, and the given map -- function. scanomapSOAC :: [Scan lore] -> Lambda lore -> ScremaForm lore -- | Construct a Screma with possibly multiple reductions, and the given -- map function. redomapSOAC :: [Reduce lore] -> Lambda lore -> ScremaForm lore -- | Construct a Screma with possibly multiple scans, and identity map -- function. scanSOAC :: (Bindable lore, MonadFreshNames m) => [Scan lore] -> m (ScremaForm lore) -- | Construct a Screma with possibly multiple reductions, and identity map -- function. reduceSOAC :: (Bindable lore, MonadFreshNames m) => [Reduce lore] -> m (ScremaForm lore) -- | Construct a Screma corresponding to a map. mapSOAC :: Lambda lore -> ScremaForm lore -- | Does this Screma correspond to a scan-map composition? isScanomapSOAC :: ScremaForm lore -> Maybe ([Scan lore], Lambda lore) -- | Does this Screma correspond to pure scan? isScanSOAC :: ScremaForm lore -> Maybe [Scan lore] -- | Does this Screma correspond to a reduce-map composition? isRedomapSOAC :: ScremaForm lore -> Maybe ([Reduce lore], Lambda lore) -- | Does this Screma correspond to a pure reduce? isReduceSOAC :: ScremaForm lore -> Maybe [Reduce lore] -- | Does this Screma correspond to a simple map, without any reduction or -- scan results? isMapSOAC :: ScremaForm lore -> Maybe (Lambda lore) -- | A mapper that simply returns the SOAC verbatim. identitySOACMapper :: Monad m => SOACMapper lore lore m -- | Map a monadic action across the immediate children of a SOAC. The -- mapping does not descend recursively into subexpressions and is done -- left-to-right. mapSOACM :: (Applicative m, Monad m) => SOACMapper flore tlore m -> SOAC flore -> m (SOAC tlore) -- | The type of a SOAC. soacType :: SOAC lore -> [Type] -- | Type-check a SOAC. typeCheckSOAC :: Checkable lore => SOAC (Aliases lore) -> TypeM lore () -- | Get Stream's accumulators as a sub-expression list getStreamAccums :: StreamForm lore -> [SubExp] -- | Prettyprint the given Screma. ppScrema :: (PrettyLore lore, Pretty inp) => SubExp -> ScremaForm lore -> [inp] -> Doc -- | Prettyprint the given histogram operation. ppHist :: (PrettyLore lore, Pretty inp) => SubExp -> [HistOp lore] -> Lambda lore -> [inp] -> Doc instance Futhark.IR.Decorations.Decorations Futhark.IR.Kernels.Kernels instance Futhark.IR.Prop.ASTLore Futhark.IR.Kernels.Kernels instance Futhark.TypeCheck.CheckableOp Futhark.IR.Kernels.Kernels instance Futhark.TypeCheck.Checkable Futhark.IR.Kernels.Kernels instance Futhark.Binder.Class.Bindable Futhark.IR.Kernels.Kernels instance Futhark.Binder.BinderOps Futhark.IR.Kernels.Kernels instance Futhark.IR.Pretty.PrettyLore Futhark.IR.Kernels.Kernels instance Futhark.IR.SegOp.HasSegOp Futhark.IR.Kernels.Kernels -- | Do various kernel optimisations - mostly related to coalescing. module Futhark.Pass.KernelBabysitting -- | The pass definition. babysitKernels :: Pass Kernels Kernels module Futhark.Pass.ExtractKernels.ToKernels getSize :: (MonadBinder m, Op (Lore m) ~ HostOp (Lore m) inner) => String -> SizeClass -> m SubExp segThread :: (MonadBinder m, Op (Lore m) ~ HostOp (Lore m) inner) => String -> m SegLevel soacsLambdaToKernels :: Lambda SOACS -> Lambda Kernels soacsStmToKernels :: Stm SOACS -> Stm Kernels scopeForKernels :: Scope SOACS -> Scope Kernels scopeForSOACs :: Scope Kernels -> Scope SOACS injectSOACS :: (Monad m, SameScope from to, ExpDec from ~ ExpDec to, BodyDec from ~ BodyDec to, RetType from ~ RetType to, BranchType from ~ BranchType to, Op from ~ SOAC from) => (SOAC to -> Op to) -> Rephraser m from to module Futhark.Pass.ExtractMulticore extractMulticore :: Pass SOACS MC instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Pass.ExtractMulticore.ExtractM instance Futhark.IR.Prop.Scope.LocalScope Futhark.IR.MC.MC Futhark.Pass.ExtractMulticore.ExtractM instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.MC.MC Futhark.Pass.ExtractMulticore.ExtractM instance GHC.Base.Monad Futhark.Pass.ExtractMulticore.ExtractM instance GHC.Base.Applicative Futhark.Pass.ExtractMulticore.ExtractM instance GHC.Base.Functor Futhark.Pass.ExtractMulticore.ExtractM instance Futhark.Util.Log.MonadLogger Futhark.Pass.ExtractMulticore.ExtractM module Futhark.Pass.ExtractKernels.StreamKernel -- | Like segThread, but cap the thread count to the input size. -- This is more efficient for small kernels, e.g. summing a small array. segThreadCapped :: MonadFreshNames m => MkSegLevel Kernels m streamRed :: (MonadFreshNames m, HasScope Kernels m) => MkSegLevel Kernels m -> Pattern Kernels -> SubExp -> Commutativity -> Lambda Kernels -> Lambda Kernels -> [SubExp] -> [VName] -> m (Stms Kernels) streamMap :: (MonadFreshNames m, HasScope Kernels m) => MkSegLevel Kernels m -> [String] -> [PatElem Kernels] -> SubExp -> Commutativity -> Lambda Kernels -> [SubExp] -> [VName] -> m ((SubExp, [VName]), Stms Kernels) instance GHC.Show.Show Futhark.Pass.ExtractKernels.StreamKernel.KernelSize instance GHC.Classes.Ord Futhark.Pass.ExtractKernels.StreamKernel.KernelSize instance GHC.Classes.Eq Futhark.Pass.ExtractKernels.StreamKernel.KernelSize -- | Extract limited nested parallelism for execution inside individual -- kernel workgroups. module Futhark.Pass.ExtractKernels.Intragroup -- | Convert the statements inside a map nest to kernel statements, -- attempting to parallelise any remaining (top-level) parallel -- statements. Anything that is not a map, scan or reduction will simply -- be sequentialised. This includes sequential loops that contain maps, -- scans or reduction. In the future, we could probably do something more -- clever. Make sure that the amount of parallelism to be exploited does -- not exceed the group size. Further, as a hack we also consider the -- size of all intermediate arrays as "parallelism to be exploited" to -- avoid exploding local memory. -- -- We distinguish between "minimum group size" and "maximum exploitable -- parallelism". intraGroupParallelise :: (MonadFreshNames m, LocalScope Kernels m) => KernelNest -> Lambda -> m (Maybe ((SubExp, SubExp), SubExp, Log, Stms Kernels, Stms Kernels)) instance Futhark.Util.Log.MonadLogger Futhark.Pass.ExtractKernels.Intragroup.IntraGroupM instance GHC.Base.Semigroup Futhark.Pass.ExtractKernels.Intragroup.Acc instance GHC.Base.Monoid Futhark.Pass.ExtractKernels.Intragroup.Acc -- | Kernel extraction. -- -- In the following, I will use the term "width" to denote the amount of -- immediate parallelism in a map - that is, the outer size of the -- array(s) being used as input. -- --

Basic Idea

-- -- If we have: -- --
--   map
--     map(f)
--     bnds_a...
--     map(g)
--   
-- -- Then we want to distribute to: -- --
--   map
--     map(f)
--   map
--     bnds_a
--   map
--     map(g)
--   
-- -- But for now only if -- --
    --
  1. it can be done without creating irregular arrays. Specifically, -- the size of the arrays created by map(f), by map(g) -- and whatever is created by bnds_a that is also used in -- map(g), must be invariant to the outermost loop.
  2. --
  3. the maps are _balanced_. That is, the functions f and -- g must do the same amount of work for every iteration.
  4. --
-- -- The advantage is that the map-nests containing map(f) and -- map(g) can now be trivially flattened at no cost, thus -- exposing more parallelism. Note that the bnds_a map -- constitutes array expansion, which requires additional storage. -- --

Distributing Sequential Loops

-- -- As a starting point, sequential loops are treated like scalar -- expressions. That is, not distributed. However, sometimes it can be -- worthwhile to distribute if they contain a map: -- --
--   map
--     loop
--       map
--     map
--   
-- -- If we distribute the loop and interchange the outer map into the loop, -- we get this: -- --
--   loop
--     map
--       map
--   map
--     map
--   
-- -- Now more parallelism may be available. -- --

Unbalanced Maps

-- -- Unbalanced maps will as a rule be sequentialised, but sometimes, there -- is another way. Assume we find this: -- --
--   map
--     map(f)
--       map(g)
--     map
--   
-- -- Presume that map(f) is unbalanced. By the simple rule above, -- we would then fully sequentialise it, resulting in this: -- --
--   map
--     loop
--   map
--     map
--   
-- --

Balancing by Loop Interchange

-- -- The above is not ideal, as we cannot flatten the map-loop -- nest, and we are thus limited in the amount of parallelism available. -- -- But assume now that the width of map(g) is invariant to the -- outer loop. Then if possible, we can interchange map(f) and -- map(g), sequentialise map(f) and distribute, -- interchanging the outer parallel loop into the sequential loop: -- --
--   loop(f)
--     map
--       map(g)
--   map
--     map
--   
-- -- After flattening the two nests we can obtain more parallelism. -- -- When distributing a map, we also need to distribute everything that -- the map depends on - possibly as its own map. When distributing a set -- of scalar bindings, we will need to know which of the binding results -- are used afterwards. Hence, we will need to compute usage information. -- --

Redomap

-- -- Redomap can be handled much like map. Distributed loops are -- distributed as maps, with the parameters corresponding to the neutral -- elements added to their bodies. The remaining loop will remain a -- redomap. Example: -- --
--   redomap(op,
--           fn (v) =>
--             map(f)
--             map(g),
--           e,a)
--   
-- -- distributes to -- --
--   let b = map(fn v =>
--                 let acc = e
--                 map(f),
--                 a)
--   redomap(op,
--           fn (v,dist) =>
--             map(g),
--           e,a,b)
--   
-- -- Note that there may be further kernel extraction opportunities inside -- the map(f). The downside of this approach is that the -- intermediate array (b above) must be written to main memory. -- An often better approach is to just turn the entire redomap -- into a single kernel. module Futhark.Pass.ExtractKernels -- | Transform a program using SOACs to a program using explicit kernels, -- using the kernel extraction transformation. extractKernels :: Pass SOACS Kernels instance Futhark.Util.Log.MonadLogger Futhark.Pass.ExtractKernels.DistribM instance Control.Monad.State.Class.MonadState Futhark.Pass.ExtractKernels.State Futhark.Pass.ExtractKernels.DistribM instance Futhark.IR.Prop.Scope.LocalScope Futhark.IR.Kernels.Kernels Futhark.Pass.ExtractKernels.DistribM instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.Kernels.Kernels Futhark.Pass.ExtractKernels.DistribM instance GHC.Base.Monad Futhark.Pass.ExtractKernels.DistribM instance GHC.Base.Applicative Futhark.Pass.ExtractKernels.DistribM instance GHC.Base.Functor Futhark.Pass.ExtractKernels.DistribM instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Pass.ExtractKernels.DistribM -- | Perform a restricted form of loop tiling within SegMaps. We only tile -- primitive types, to avoid excessive local memory use. module Futhark.Optimise.TileLoops -- | The pass definition. tileLoops :: Pass Kernels Kernels instance GHC.Base.Semigroup Futhark.Optimise.TileLoops.PrivStms instance GHC.Base.Monoid Futhark.Optimise.TileLoops.PrivStms -- | Sinking is conceptually the opposite of hoisting. The idea is -- to take code that looks like this: -- --
--   x = xs[i]
--   y = ys[i]
--   if x != 0 then {
--     y
--   } else {
--     0
--   }
--   
-- -- and turn it into -- --
--   x = xs[i]
--   if x != 0 then {
--     y = ys[i]
--     y
--   } else {
--     0
--   }
--   
-- -- The idea is to delay loads from memory until (if) they are actually -- needed. Code patterns like the above is particularly common in code -- that makes use of pattern matching on sum types. -- -- We are currently quite conservative about when we do this. In -- particular, if any consumption is going on in a body, we don't do -- anything. This is far too conservative. Also, we are careful never to -- duplicate work. -- -- This pass redundantly computes free-variable information a lot. If you -- ever see this pass as being a compilation speed bottleneck, start by -- caching that a bit. -- -- This pass is defined on the Kernels representation. This is not -- because we do anything kernel-specific here, but simply because more -- explicit indexing is going on after SOACs are gone. module Futhark.Optimise.Sink -- | Sinking in GPU kernels. sinkKernels :: Pass Kernels Kernels -- | Sinking for multicore. sinkMC :: Pass MC MC module Futhark.Optimise.InPlaceLowering.LowerIntoStm lowerUpdateKernels :: MonadFreshNames m => LowerUpdate Kernels m lowerUpdate :: (MonadFreshNames m, Bindable lore, LetDec lore ~ Type, CanBeAliased (Op lore)) => LowerUpdate lore m type LowerUpdate lore m = Scope (Aliases lore) -> Stm (Aliases lore) -> [DesiredUpdate (LetDec (Aliases lore))] -> Maybe (m [Stm (Aliases lore)]) data DesiredUpdate dec DesiredUpdate :: VName -> dec -> Certificates -> VName -> Slice SubExp -> VName -> DesiredUpdate dec -- | Name of result. [updateName] :: DesiredUpdate dec -> VName -- | Type of result. [updateType] :: DesiredUpdate dec -> dec [updateCertificates] :: DesiredUpdate dec -> Certificates [updateSource] :: DesiredUpdate dec -> VName [updateIndices] :: DesiredUpdate dec -> Slice SubExp [updateValue] :: DesiredUpdate dec -> VName instance GHC.Show.Show dec => GHC.Show.Show (Futhark.Optimise.InPlaceLowering.LowerIntoStm.DesiredUpdate dec) instance GHC.Show.Show dec => GHC.Show.Show (Futhark.Optimise.InPlaceLowering.LowerIntoStm.LoopResultSummary dec) instance GHC.Base.Functor Futhark.Optimise.InPlaceLowering.LowerIntoStm.DesiredUpdate -- | This module implements an optimisation that moves in-place updates -- into/before loops where possible, with the end goal of minimising -- memory copies. As an example, consider this program: -- --
--   let r =
--     loop (r1 = r0) = for i < n do
--       let a = r1[i]
--       let r1[i] = a * i
--       in r1
--   ...
--   let x = y with [k] <- r in
--   ...
--   
-- -- We want to turn this into the following: -- --
--   let x0 = y with [k] <- r0
--   loop (x = x0) = for i < n do
--     let a = a[k,i]
--     let x[k,i] = a * i
--     in x
--   let r = x[k] in
--   ...
--   
-- -- The intent is that we are also going to optimise the new data movement -- (in the x0-binding), possibly by changing how r0 is -- defined. For the above transformation to be valid, a number of -- conditions must be fulfilled: -- --
    --
  1. r must not be consumed after the original in-place -- update.
  2. --
  3. k and y must be available at the beginning of -- the loop.
  4. --
  5. x must be visible whenever r is visible. (This -- means that both x and r must be bound in the same -- Body.)
  6. --
  7. If x is consumed at a point after the loop, r -- must not be used after that point.
  8. --
  9. The size of r1 is invariant inside the loop.
  10. --
  11. The value r must come from something that we can actually -- optimise (e.g. not a function parameter).
  12. --
  13. y (or its aliases) may not be used inside the body of the -- loop.
  14. --
  15. The result of the loop may not alias the merge parameter -- r1.
  16. --
-- -- FIXME: the implementation is not finished yet. Specifically, not all -- of the above conditions are checked. module Futhark.Optimise.InPlaceLowering -- | Apply the in-place lowering optimisation to the given program. inPlaceLoweringKernels :: Pass Kernels Kernels -- | Apply the in-place lowering optimisation to the given program. inPlaceLoweringSeq :: Pass Seq Seq -- | Apply the in-place lowering optimisation to the given program. inPlaceLoweringMC :: Pass MC MC instance Control.Monad.State.Class.MonadState Futhark.FreshNames.VNameSource (Futhark.Optimise.InPlaceLowering.ForwardingM lore) instance Control.Monad.Writer.Class.MonadWriter (Futhark.Optimise.InPlaceLowering.BottomUp lore) (Futhark.Optimise.InPlaceLowering.ForwardingM lore) instance Control.Monad.Reader.Class.MonadReader (Futhark.Optimise.InPlaceLowering.TopDown lore) (Futhark.Optimise.InPlaceLowering.ForwardingM lore) instance GHC.Base.Functor (Futhark.Optimise.InPlaceLowering.ForwardingM lore) instance GHC.Base.Applicative (Futhark.Optimise.InPlaceLowering.ForwardingM lore) instance GHC.Base.Monad (Futhark.Optimise.InPlaceLowering.ForwardingM lore) instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Optimise.InPlaceLowering.ForwardingM lore) instance Futhark.Optimise.InPlaceLowering.Constraints lore => Futhark.IR.Prop.Scope.HasScope (Futhark.IR.Aliases.Aliases lore) (Futhark.Optimise.InPlaceLowering.ForwardingM lore) instance GHC.Base.Semigroup (Futhark.Optimise.InPlaceLowering.BottomUp lore) instance GHC.Base.Monoid (Futhark.Optimise.InPlaceLowering.BottomUp lore) module Futhark.IR.Kernels.Simplify simplifyKernels :: Prog Kernels -> PassM (Prog Kernels) simplifyLambda :: (HasScope Kernels m, MonadFreshNames m) => Lambda Kernels -> m (Lambda Kernels) -- | The phantom data type for the kernels representation. data Kernels simplifyKernelOp :: (SimplifiableLore lore, BodyDec lore ~ ()) => SimplifyOp lore op -> HostOp lore op -> SimpleM lore (HostOp (Wise lore) (OpWithWisdom op), Stms (Wise lore)) instance Futhark.Binder.BinderOps (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.Kernels.Kernels) instance Futhark.IR.SegOp.HasSegOp (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.Kernels.Kernels) instance Futhark.IR.SOACS.Simplify.HasSOAC (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.Kernels.Kernels) -- | Sequentialise any remaining SOACs. It is very important that this is -- run *after* any access-pattern-related optimisation, because this pass -- will destroy information. -- -- This pass conceptually contains three subpasses: -- --
    --
  1. Sequentialise Stream operations, leaving other SOACs -- intact.
  2. --
  3. Apply whole-program simplification.
  4. --
  5. Sequentialise remaining SOACs.
  6. --
-- -- This is because sequentialisation of streams creates many SOACs -- operating on single-element arrays, which can be efficiently -- simplified away, but only *before* they are turned into loops. In -- principle this pass could be split into multiple, but for now it is -- kept together. module Futhark.Optimise.Unstream -- | The pass for GPU kernels. unstreamKernels :: Pass Kernels Kernels -- | The pass for multicore. unstreamMC :: Pass MC MC module Futhark.IR.KernelsMem data KernelsMem simplifyProg :: Prog KernelsMem -> PassM (Prog KernelsMem) simplifyStms :: (HasScope KernelsMem m, MonadFreshNames m) => Stms KernelsMem -> m (SymbolTable (Wise KernelsMem), Stms KernelsMem) simpleKernelsMem :: SimpleOps KernelsMem instance Futhark.IR.Decorations.Decorations Futhark.IR.KernelsMem.KernelsMem instance Futhark.IR.Prop.ASTLore Futhark.IR.KernelsMem.KernelsMem instance Futhark.IR.Mem.OpReturns Futhark.IR.KernelsMem.KernelsMem instance Futhark.IR.Pretty.PrettyLore Futhark.IR.KernelsMem.KernelsMem instance Futhark.TypeCheck.CheckableOp Futhark.IR.KernelsMem.KernelsMem instance Futhark.TypeCheck.Checkable Futhark.IR.KernelsMem.KernelsMem instance Futhark.Binder.BinderOps Futhark.IR.KernelsMem.KernelsMem instance Futhark.Binder.BinderOps (Futhark.Optimise.Simplify.Lore.Wise Futhark.IR.KernelsMem.KernelsMem) module Futhark.Pass.Simplify simplify :: (Prog lore -> PassM (Prog lore)) -> Pass lore lore simplifySOACS :: Pass SOACS SOACS simplifySeq :: Pass Seq Seq simplifyMC :: Pass MC MC simplifyKernels :: Pass Kernels Kernels simplifyKernelsMem :: Pass KernelsMem KernelsMem simplifySeqMem :: Pass SeqMem SeqMem simplifyMCMem :: Pass MCMem MCMem module Futhark.Pass.ExplicitAllocations.SegOp allocInKernelBody :: Allocable fromlore tolore => KernelBody fromlore -> AllocM fromlore tolore (KernelBody tolore) allocInBinOpLambda :: Allocable fromlore tolore => SubExp -> SegSpace -> Lambda fromlore -> AllocM fromlore tolore (Lambda tolore) instance Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.IR.SegOp.SegOp lvl lore) module Futhark.Pass.ExplicitAllocations.MC explicitAllocations :: Pass MC MCMem instance Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.IR.MC.Op.MCOp lore op) -- | Facilities for converting a Kernels program to -- KernelsMem. module Futhark.Pass.ExplicitAllocations.Kernels -- | The pass from Kernels to KernelsMem. explicitAllocations :: Pass Kernels KernelsMem -- | Convert some Kernels stms to KernelsMem. explicitAllocationsInStms :: (MonadFreshNames m, HasScope KernelsMem m) => Stms Kernels -> m (Stms KernelsMem) instance Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.IR.Kernels.Kernel.HostOp lore op) -- | Expand allocations inside of maps when possible. module Futhark.Pass.ExpandAllocations -- | The memory expansion pass definition. expandAllocations :: Pass KernelsMem KernelsMem instance Control.Monad.Error.Class.MonadError GHC.Base.String Futhark.Pass.ExpandAllocations.OffsetM instance Futhark.IR.Prop.Scope.LocalScope Futhark.IR.KernelsMem.KernelsMem Futhark.Pass.ExpandAllocations.OffsetM instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.KernelsMem.KernelsMem Futhark.Pass.ExpandAllocations.OffsetM instance GHC.Base.Monad Futhark.Pass.ExpandAllocations.OffsetM instance GHC.Base.Functor Futhark.Pass.ExpandAllocations.OffsetM instance GHC.Base.Applicative Futhark.Pass.ExpandAllocations.OffsetM -- | The simplification engine is only willing to hoist allocations out of -- loops if the memory block resulting from the allocation is dead at the -- end of the loop. If it is not, we may cause data hazards. -- -- This module rewrites loops with memory block merge parameters such -- that each memory block is copied at the end of the iteration, thus -- ensuring that any allocation inside the loop is dead at the end of the -- loop. This is only possible for allocations whose size is -- loop-invariant, although the initial size may differ from the size -- produced by the loop result. -- -- Additionally, inside parallel kernels we also copy the initial value. -- This has the effect of making the memory block returned by the array -- non-existential, which is important for later memory expansion to -- work. module Futhark.Optimise.DoubleBuffer -- | The pass for GPU kernels. doubleBufferKernels :: Pass KernelsMem KernelsMem -- | The pass for multicore doubleBufferMC :: Pass MCMem MCMem instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Optimise.DoubleBuffer.DoubleBufferM lore) instance Control.Monad.Reader.Class.MonadReader (Futhark.Optimise.DoubleBuffer.Env lore) (Futhark.Optimise.DoubleBuffer.DoubleBufferM lore) instance GHC.Base.Monad (Futhark.Optimise.DoubleBuffer.DoubleBufferM lore) instance GHC.Base.Applicative (Futhark.Optimise.DoubleBuffer.DoubleBufferM lore) instance GHC.Base.Functor (Futhark.Optimise.DoubleBuffer.DoubleBufferM lore) instance GHC.Show.Show Futhark.Optimise.DoubleBuffer.DoubleBuffer instance Futhark.IR.Prop.ASTLore lore => Futhark.IR.Prop.Scope.HasScope lore (Futhark.Optimise.DoubleBuffer.DoubleBufferM lore) instance Futhark.IR.Prop.ASTLore lore => Futhark.IR.Prop.Scope.LocalScope lore (Futhark.Optimise.DoubleBuffer.DoubleBufferM lore) -- | High-level representation of SOACs. When performing -- SOAC-transformations, operating on normal Exp values is -- somewhat of a nuisance, as they can represent terms that are not -- proper SOACs. In contrast, this module exposes a SOAC representation -- that does not enable invalid representations (except for type errors). -- -- Furthermore, while standard normalised Futhark requires that the -- inputs to a SOAC are variables or constants, the representation in -- this module also supports various index-space transformations, like -- replicate or rearrange. This is also very convenient -- when implementing transformations. -- -- The names exported by this module conflict with the standard Futhark -- syntax tree constructors, so you are advised to use a qualified -- import: -- --
--   import Futhark.Analysis.HORep.SOAC (SOAC)
--   import qualified Futhark.Analysis.HORep.SOAC as SOAC
--   
module Futhark.Analysis.HORep.SOAC -- | A definite representation of a SOAC expression. data SOAC lore Stream :: SubExp -> StreamForm lore -> Lambda lore -> [Input] -> SOAC lore Scatter :: SubExp -> Lambda lore -> [Input] -> [(SubExp, Int, VName)] -> SOAC lore Screma :: SubExp -> ScremaForm lore -> [Input] -> SOAC lore Hist :: SubExp -> [HistOp lore] -> Lambda lore -> [Input] -> SOAC lore -- | The essential parts of a Screma factored out (everything except -- the input arrays). data ScremaForm lore ScremaForm :: [Scan lore] -> [Reduce lore] -> Lambda lore -> ScremaForm lore -- | Returns the inputs used in a SOAC. inputs :: SOAC lore -> [Input] -- | Set the inputs to a SOAC. setInputs :: [Input] -> SOAC lore -> SOAC lore -- | The lambda used in a given SOAC. lambda :: SOAC lore -> Lambda lore -- | Set the lambda used in the SOAC. setLambda :: Lambda lore -> SOAC lore -> SOAC lore -- | The return type of a SOAC. typeOf :: SOAC lore -> [Type] -- | The "width" of a SOAC is the expected outer size of its array inputs -- _after_ input-transforms have been carried out. width :: SOAC lore -> SubExp -- | The reason why some expression cannot be converted to a SOAC -- value. data NotSOAC -- | The expression is not a (tuple-)SOAC at all. NotSOAC :: NotSOAC -- | Either convert an expression to the normalised SOAC representation, or -- a reason why the expression does not have the valid form. fromExp :: (Op lore ~ SOAC lore, HasScope lore m) => Exp lore -> m (Either NotSOAC (SOAC lore)) -- | Convert a SOAC to the corresponding expression. toExp :: (MonadBinder m, Op (Lore m) ~ SOAC (Lore m)) => SOAC (Lore m) -> m (Exp (Lore m)) -- | Convert a SOAC to a Futhark-level SOAC. toSOAC :: MonadBinder m => SOAC (Lore m) -> m (SOAC (Lore m)) -- | One array input to a SOAC - a SOAC may have multiple inputs, but all -- are of this form. Only the array inputs are expressed with this type; -- other arguments, such as initial accumulator values, are plain -- expressions. The transforms are done left-to-right, that is, the first -- element of the ArrayTransform list is applied first. data Input Input :: ArrayTransforms -> VName -> Type -> Input -- | Create a plain array variable input with no transformations. varInput :: HasScope t f => VName -> f Input -- | Create a plain array variable input with no transformations, from an -- Ident. identInput :: Ident -> Input -- | If the given input is a plain variable input, with no transforms, -- return the variable. isVarInput :: Input -> Maybe VName -- | If the given input is a plain variable input, with no non-vacuous -- transforms, return the variable. isVarishInput :: Input -> Maybe VName -- | Add a transformation to the end of the transformation list. addTransform :: ArrayTransform -> Input -> Input -- | Add several transformations to the start of the transformation list. addInitialTransforms :: ArrayTransforms -> Input -> Input -- | Return the array name of the input. inputArray :: Input -> VName -- | Return the array rank (dimensionality) of an input. Just a convenient -- alias. inputRank :: Input -> Int -- | Return the type of an input. inputType :: Input -> Type -- | Return the row type of an input. Just a convenient alias. inputRowType :: Input -> Type -- | Apply the transformations to every row of the input. transformRows :: ArrayTransforms -> Input -> Input -- | Add to the input a Rearrange transform that performs an -- (k,n) transposition. The new transform will be at the end of -- the current transformation list. transposeInput :: Int -> Int -> Input -> Input -- | A sequence of array transformations, heavily inspired by -- Data.Seq. You can decompose it using viewf and -- viewl, and grow it by using |> and <|. -- These correspond closely to the similar operations for sequences, -- except that appending will try to normalise and simplify the -- transformation sequence. -- -- The data type is opaque in order to enforce normalisation invariants. -- Basically, when you grow the sequence, the implementation will try to -- coalesce neighboring permutations, for example by composing -- permutations and removing identity transformations. data ArrayTransforms -- | The empty transformation list. noTransforms :: ArrayTransforms -- | Is it an empty transformation list? nullTransforms :: ArrayTransforms -> Bool -- | Add a transform to the end of the transformation list. (|>) :: ArrayTransforms -> ArrayTransform -> ArrayTransforms -- | Add a transform at the beginning of the transformation list. (<|) :: ArrayTransform -> ArrayTransforms -> ArrayTransforms -- | Decompose the input-end of the transformation sequence. viewf :: ArrayTransforms -> ViewF -- | A view of the first transformation to be applied. data ViewF EmptyF :: ViewF (:<) :: ArrayTransform -> ArrayTransforms -> ViewF -- | Decompose the output-end of the transformation sequence. viewl :: ArrayTransforms -> ViewL -- | A view of the last transformation to be applied. data ViewL EmptyL :: ViewL (:>) :: ArrayTransforms -> ArrayTransform -> ViewL -- | A single, simple transformation. If you want several, don't just -- create a list, use ArrayTransforms instead. data ArrayTransform -- | A permutation of an otherwise valid input. Rearrange :: Certificates -> [Int] -> ArrayTransform -- | A reshaping of an otherwise valid input. Reshape :: Certificates -> ShapeChange SubExp -> ArrayTransform -- | A reshaping of the outer dimension. ReshapeOuter :: Certificates -> ShapeChange SubExp -> ArrayTransform -- | A reshaping of everything but the outer dimension. ReshapeInner :: Certificates -> ShapeChange SubExp -> ArrayTransform -- | Replicate the rows of the array a number of times. Replicate :: Certificates -> Shape -> ArrayTransform -- | Given an expression, determine whether the expression represents an -- input transformation of an array variable. If so, return the variable -- and the transformation. Only Rearrange and Reshape are -- possible to express this way. transformFromExp :: Certificates -> Exp lore -> Maybe (VName, ArrayTransform) -- | To-Stream translation of SOACs. Returns the Stream SOAC and the -- extra-accumulator body-result ident if any. soacToStream :: (MonadFreshNames m, Bindable lore, Op lore ~ SOAC lore) => SOAC lore -> m (SOAC lore, [Ident]) instance GHC.Classes.Ord Futhark.Analysis.HORep.SOAC.ArrayTransform instance GHC.Classes.Eq Futhark.Analysis.HORep.SOAC.ArrayTransform instance GHC.Show.Show Futhark.Analysis.HORep.SOAC.ArrayTransform instance GHC.Show.Show Futhark.Analysis.HORep.SOAC.ArrayTransforms instance GHC.Classes.Ord Futhark.Analysis.HORep.SOAC.ArrayTransforms instance GHC.Classes.Eq Futhark.Analysis.HORep.SOAC.ArrayTransforms instance GHC.Classes.Ord Futhark.Analysis.HORep.SOAC.Input instance GHC.Classes.Eq Futhark.Analysis.HORep.SOAC.Input instance GHC.Show.Show Futhark.Analysis.HORep.SOAC.Input instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.Analysis.HORep.SOAC.SOAC lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Classes.Eq (Futhark.Analysis.HORep.SOAC.SOAC lore) instance GHC.Show.Show Futhark.Analysis.HORep.SOAC.NotSOAC instance Futhark.IR.Pretty.PrettyLore lore => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.Analysis.HORep.SOAC.SOAC lore) instance Futhark.Transform.Substitute.Substitute Futhark.Analysis.HORep.SOAC.Input instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.Analysis.HORep.SOAC.Input instance GHC.Base.Semigroup Futhark.Analysis.HORep.SOAC.ArrayTransforms instance GHC.Base.Monoid Futhark.Analysis.HORep.SOAC.ArrayTransforms instance Futhark.Transform.Substitute.Substitute Futhark.Analysis.HORep.SOAC.ArrayTransforms instance Futhark.Transform.Substitute.Substitute Futhark.Analysis.HORep.SOAC.ArrayTransform -- | Facilities for composing SOAC functions. Mostly intended for use by -- the fusion module, but factored into a separate module for ease of -- testing, debugging and development. Of course, there is nothing -- preventing you from using the exported functions whereever you want. -- -- Important: this module is "dumb" in the sense that it does not check -- the validity of its inputs, and does not have any functionality for -- massaging SOACs to be fusible. It is assumed that the given SOACs are -- immediately compatible. -- -- The module will, however, remove duplicate inputs after fusion. module Futhark.Optimise.Fusion.Composing -- | fuseMaps lam1 inp1 out1 lam2 inp2 fuses the function -- lam1 into lam2. Both functions must be mapping -- functions, although lam2 may have leading reduction -- parameters. inp1 and inp2 are the array inputs to -- the SOACs containing lam1 and lam2 respectively. -- out1 are the identifiers to which the output of the SOAC -- containing lam1 is bound. It is nonsensical to call this -- function unless the intersection of out1 and inp2 is -- non-empty. -- -- If lam2 accepts more parameters than there are elements in -- inp2, it is assumed that the surplus (which are positioned at -- the beginning of the parameter list) are reduction (accumulator) -- parameters, that do not correspond to array elements, and they are -- thus not modified. -- -- The result is the fused function, and a list of the array inputs -- expected by the SOAC containing the fused function. fuseMaps :: Bindable lore => Names -> Lambda lore -> [Input] -> [(VName, Ident)] -> Lambda lore -> [Input] -> (Lambda lore, [Input]) fuseRedomap :: Bindable lore => Names -> [VName] -> Lambda lore -> [SubExp] -> [SubExp] -> [Input] -> [(VName, Ident)] -> Lambda lore -> [SubExp] -> [SubExp] -> [Input] -> (Lambda lore, [Input]) mergeReduceOps :: Lambda lore -> Lambda lore -> Lambda lore module Futhark.Analysis.HORep.MapNest data Nesting lore Nesting :: [VName] -> [VName] -> [Type] -> SubExp -> Nesting lore [nestingParamNames] :: Nesting lore -> [VName] [nestingResult] :: Nesting lore -> [VName] [nestingReturnType] :: Nesting lore -> [Type] [nestingWidth] :: Nesting lore -> SubExp data MapNest lore MapNest :: SubExp -> Lambda lore -> [Nesting lore] -> [Input] -> MapNest lore typeOf :: MapNest lore -> [Type] params :: MapNest lore -> [VName] inputs :: MapNest lore -> [Input] setInputs :: [Input] -> MapNest lore -> MapNest lore fromSOAC :: (Bindable lore, MonadFreshNames m, LocalScope lore m, Op lore ~ SOAC lore) => SOAC lore -> m (Maybe (MapNest lore)) toSOAC :: (MonadFreshNames m, HasScope lore m, Bindable lore, BinderOps lore, Op lore ~ SOAC lore) => MapNest lore -> m (SOAC lore) instance GHC.Show.Show (Futhark.Analysis.HORep.MapNest.Nesting lore) instance GHC.Classes.Ord (Futhark.Analysis.HORep.MapNest.Nesting lore) instance GHC.Classes.Eq (Futhark.Analysis.HORep.MapNest.Nesting lore) instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.Analysis.HORep.MapNest.MapNest lore) module Futhark.Optimise.Fusion.LoopKernel data FusedKer FusedKer :: SOAC -> Names -> [VName] -> Names -> Scope SOACS -> ArrayTransforms -> [VName] -> StmAux () -> FusedKer -- | the SOAC expression, e.g., mapT( f(a,b), x, y ) [fsoac] :: FusedKer -> SOAC -- | Variables used in in-place updates in the kernel itself, as well as on -- the path to the kernel from the current position. This is used to -- avoid fusion that would violate in-place restrictions. [inplace] :: FusedKer -> Names -- | whether at least a fusion has been performed. [fusedVars] :: FusedKer -> [VName] -- | The set of variables that were consumed by the SOACs contributing to -- this kernel. Note that, by the type rules, the final SOAC may actually -- consume _more_ than its original contributors, which implies the need -- for Copy expressions. [fusedConsumed] :: FusedKer -> Names -- | The names in scope at the kernel. [kernelScope] :: FusedKer -> Scope SOACS [outputTransform] :: FusedKer -> ArrayTransforms [outNames] :: FusedKer -> [VName] [kerAux] :: FusedKer -> StmAux () newKernel :: StmAux () -> SOAC -> Names -> [VName] -> Scope SOACS -> FusedKer inputs :: FusedKer -> [Input] setInputs :: [Input] -> FusedKer -> FusedKer arrInputs :: FusedKer -> Set VName transformOutput :: ArrayTransforms -> [VName] -> [Ident] -> Binder SOACS () attemptFusion :: MonadFreshNames m => Names -> [VName] -> SOAC -> Names -> FusedKer -> m (Maybe FusedKer) type SOAC = SOAC SOACS type MapNest = MapNest SOACS instance Futhark.IR.Prop.Scope.LocalScope Futhark.IR.SOACS.SOACS Futhark.Optimise.Fusion.LoopKernel.TryFusion instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.SOACS.SOACS Futhark.Optimise.Fusion.LoopKernel.TryFusion instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Optimise.Fusion.LoopKernel.TryFusion instance Control.Monad.Fail.MonadFail Futhark.Optimise.Fusion.LoopKernel.TryFusion instance GHC.Base.Monad Futhark.Optimise.Fusion.LoopKernel.TryFusion instance GHC.Base.Alternative Futhark.Optimise.Fusion.LoopKernel.TryFusion instance GHC.Base.Applicative Futhark.Optimise.Fusion.LoopKernel.TryFusion instance GHC.Base.Functor Futhark.Optimise.Fusion.LoopKernel.TryFusion instance GHC.Show.Show Futhark.Optimise.Fusion.LoopKernel.FusedKer -- | Perform horizontal and vertical fusion of SOACs. See the paper A T2 -- Graph-Reduction Approach To Fusion for the basic idea (some -- extensions discussed in /Design and GPGPU Performance of Futhark’s -- Redomap Construct/). module Futhark.Optimise.Fusion -- | The pass definition. fuseSOACs :: Pass SOACS SOACS instance GHC.Show.Show Futhark.Optimise.Fusion.KernName instance GHC.Classes.Ord Futhark.Optimise.Fusion.KernName instance GHC.Classes.Eq Futhark.Optimise.Fusion.KernName instance Control.Monad.Reader.Class.MonadReader Futhark.Optimise.Fusion.FusionGEnv Futhark.Optimise.Fusion.FusionGM instance Control.Monad.State.Class.MonadState Futhark.FreshNames.VNameSource Futhark.Optimise.Fusion.FusionGM instance Control.Monad.Error.Class.MonadError Futhark.Optimise.Fusion.Error Futhark.Optimise.Fusion.FusionGM instance GHC.Base.Functor Futhark.Optimise.Fusion.FusionGM instance GHC.Base.Applicative Futhark.Optimise.Fusion.FusionGM instance GHC.Base.Monad Futhark.Optimise.Fusion.FusionGM instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Optimise.Fusion.FusionGM instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.SOACS.SOACS Futhark.Optimise.Fusion.FusionGM instance GHC.Base.Semigroup Futhark.Optimise.Fusion.FusedRes instance GHC.Base.Monoid Futhark.Optimise.Fusion.FusedRes instance GHC.Show.Show Futhark.Optimise.Fusion.Error -- | Optimisation pipelines. module Futhark.Passes standardPipeline :: Pipeline SOACS SOACS sequentialPipeline :: Pipeline SOACS Seq kernelsPipeline :: Pipeline SOACS Kernels sequentialCpuPipeline :: Pipeline SOACS SeqMem gpuPipeline :: Pipeline SOACS KernelsMem mcPipeline :: Pipeline SOACS MC multicorePipeline :: Pipeline SOACS MCMem -- | Imperative intermediate language used as a stepping stone in code -- generation. -- -- This is a generic representation parametrised on an extensible -- arbitrary operation. -- -- Originally inspired by the paper "Defunctionalizing Push Arrays" (FHPC -- '14). module Futhark.CodeGen.ImpCode -- | A collection of imperative functions and constants. data Definitions a Definitions :: Constants a -> Functions a -> Definitions a [defConsts] :: Definitions a -> Constants a [defFuns] :: Definitions a -> Functions a -- | A collection of imperative functions. newtype Functions a Functions :: [(Name, Function a)] -> Functions a -- | Type alias for namespace control. type Function = FunctionT -- | A imperative function, containing the body as well as its low-level -- inputs and outputs, as well as its high-level arguments and results. -- The latter are only used if the function is an entry point. data FunctionT a Function :: Bool -> [Param] -> [Param] -> Code a -> [ExternalValue] -> [ExternalValue] -> FunctionT a [functionEntry] :: FunctionT a -> Bool [functionOutput] :: FunctionT a -> [Param] [functionInput] :: FunctionT a -> [Param] [functionBody] :: FunctionT a -> Code a [functionResult] :: FunctionT a -> [ExternalValue] [functionArgs] :: FunctionT a -> [ExternalValue] -- | A collection of imperative constants. data Constants a Constants :: [Param] -> Code a -> Constants a -- | The constants that are made available to the functions. [constsDecl] :: Constants a -> [Param] -- | Setting the value of the constants. Note that this must not contain -- declarations of the names defined in constsDecl. [constsInit] :: Constants a -> Code a -- | A description of an externally meaningful value. data ValueDesc -- | An array with memory block, memory block size, memory space, element -- type, signedness of element type (if applicable), and shape. ArrayValue :: VName -> Space -> PrimType -> Signedness -> [DimSize] -> ValueDesc -- | A scalar value with signedness if applicable. ScalarValue :: PrimType -> Signedness -> VName -> ValueDesc -- | Since the core language does not care for signedness, but the source -- language does, entry point input/output information has metadata for -- integer types (and arrays containing these) that indicate whether they -- are really unsigned integers. data Signedness TypeUnsigned :: Signedness TypeDirect :: Signedness -- | ^ An externally visible value. This can be an opaque value (covering -- several physical internal values), or a single value that can be used -- externally. data ExternalValue -- | The string is a human-readable description with no other semantics. OpaqueValue :: String -> [ValueDesc] -> ExternalValue TransparentValue :: ValueDesc -> ExternalValue -- | An ImpCode function parameter. data Param MemParam :: VName -> Space -> Param ScalarParam :: VName -> PrimType -> Param -- | The name of a parameter. paramName :: Param -> VName -- | A subexpression is either a scalar constant or a variable. One -- important property is that evaluation of a subexpression is guaranteed -- to complete in constant time. data SubExp Constant :: PrimValue -> SubExp Var :: VName -> SubExp -- | The size of a memory block. type MemSize = SubExp -- | The size of an array. type DimSize = SubExp -- | The memory space of a block. If DefaultSpace, this is the -- "default" space, whatever that is. The exact meaning of the -- SpaceId depends on the backend used. In GPU kernels, for -- example, this is used to distinguish between constant, global and -- shared memory spaces. In GPU-enabled host code, it is used to -- distinguish between host memory (DefaultSpace) and GPU space. data Space DefaultSpace :: Space Space :: SpaceId -> Space -- | A special kind of memory that is a statically sized array of some -- primitive type. Used for private memory on GPUs. ScalarSpace :: [SubExp] -> PrimType -> Space -- | A string representing a specific non-default memory space. type SpaceId = String -- | A block of imperative code. Parameterised by an Op, which -- allows extensibility. Concrete uses of this type will instantiate the -- type parameter with e.g. a construct for launching GPU kernels. data Code a -- | No-op. Crucial for the Monoid instance. Skip :: Code a -- | Statement composition. Crucial for the Semigroup instance. (:>>:) :: Code a -> Code a -> Code a -- | A for-loop iterating the given number of times. The loop parameter -- starts counting from zero and will have the same (integer) type as the -- bound. The bound is evaluated just once, before the loop is entered. For :: VName -> Exp -> Code a -> Code a -- | While loop. The conditional is (of course) re-evaluated before every -- iteration of the loop. While :: TExp Bool -> Code a -> Code a -- | Declare a memory block variable that will point to memory in the given -- memory space. Note that this is distinct from allocation. The memory -- block must be the target of either an Allocate or a -- SetMem before it can be used for reading or writing. DeclareMem :: VName -> Space -> Code a -- | Declare a scalar variable with an initially undefined value. DeclareScalar :: VName -> Volatility -> PrimType -> Code a -- | Create an array containing the given values. The lifetime of the array -- will be the entire application. This is mostly used for constant -- arrays, but also for some bookkeeping data, like the synchronisation -- counts used to implement reduction. DeclareArray :: VName -> Space -> PrimType -> ArrayContents -> Code a -- | Memory space must match the corresponding DeclareMem. Allocate :: VName -> Count Bytes (TExp Int64) -> Space -> Code a -- | Indicate that some memory block will never again be referenced via the -- indicated variable. However, it may still be accessed through aliases. -- It is only safe to actually deallocate the memory block if this is the -- last reference. There is no guarantee that all memory blocks will be -- freed with this statement. Backends are free to ignore it entirely. Free :: VName -> Space -> Code a -- | Destination, offset in destination, destination space, source, offset -- in source, offset space, number of bytes. Copy :: VName -> Count Bytes (TExp Int64) -> Space -> VName -> Count Bytes (TExp Int64) -> Space -> Count Bytes (TExp Int64) -> Code a -- | Write mem i t space vol v writes the value v to -- mem offset by i elements of type t. The -- Space argument is the memory space of mem (technically -- redundant, but convenient). Note that reading is done with an -- Exp (Index). Write :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp -> Code a -- | Set a scalar variable. SetScalar :: VName -> Exp -> Code a -- | Must be in same space. SetMem :: VName -> VName -> Space -> Code a -- | Function call. The results are written to the provided VName -- variables. Call :: [VName] -> Name -> [Arg] -> Code a -- | Conditional execution. If :: TExp Bool -> Code a -> Code a -> Code a -- | Assert that something must be true. Should it turn out not to be true, -- then report a failure along with the given error message. Assert :: Exp -> ErrorMsg Exp -> (SrcLoc, [SrcLoc]) -> Code a -- | Has the same semantics as the contained code, but the comment should -- show up in generated code for ease of inspection. Comment :: String -> Code a -> Code a -- | Print the given value to the screen, somehow annotated with the given -- string as a description. If no type/value pair, just print the string. -- This has no semantic meaning, but is used entirely for debugging. Code -- generators are free to ignore this statement. DebugPrint :: String -> Maybe Exp -> Code a -- | Perform an extensible operation. Op :: a -> Code a -- | Non-array values. data PrimValue IntValue :: !IntValue -> PrimValue FloatValue :: !FloatValue -> PrimValue BoolValue :: !Bool -> PrimValue -- | The only value of type cert. Checked :: PrimValue -- | The leaves of an Exp. data ExpLeaf -- | A scalar variable. The type is stored in the LeafExp -- constructor itself. ScalarVar :: VName -> ExpLeaf -- | The size of a primitive type. SizeOf :: PrimType -> ExpLeaf -- | Reading a value from memory. The arguments have the same meaning as -- with Write. Index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> ExpLeaf -- | A side-effect free expression whose execution will produce a single -- primitive value. type Exp = PrimExp ExpLeaf -- | Like Exp, but with a required/known type. type TExp t = TPrimExp t ExpLeaf -- | The volatility of a memory access or variable. Feel free to ignore -- this for backends where it makes no sense (anything but C and similar -- low-level things) data Volatility Volatile :: Volatility Nonvolatile :: Volatility -- | A function call argument. data Arg ExpArg :: Exp -> Arg MemArg :: VName -> Arg -- | Turn a VName into a ScalarVar. var :: VName -> PrimType -> Exp -- | Turn a VName into a Int32 ScalarVar. vi32 :: VName -> TExp Int32 -- | Turn a VName into a Int64 ScalarVar. vi64 :: VName -> TExp Int64 -- | Concise wrapper for using Index. index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp -- | An error message is a list of error parts, which are concatenated to -- form the final message. newtype ErrorMsg a ErrorMsg :: [ErrorMsgPart a] -> ErrorMsg a -- | A part of an error message. data ErrorMsgPart a -- | A literal string. ErrorString :: String -> ErrorMsgPart a -- | A run-time integer value. ErrorInt32 :: a -> ErrorMsgPart a -- | A bigger run-time integer value. ErrorInt64 :: a -> ErrorMsgPart a -- | How many non-constant parts does the error message have, and what is -- their type? errorMsgArgTypes :: ErrorMsg a -> [PrimType] -- | The contents of a statically declared constant array. Such arrays are -- always unidimensional, and reshaped if necessary in the code that uses -- them. data ArrayContents -- | Precisely these values. ArrayValues :: [PrimValue] -> ArrayContents -- | This many zeroes. ArrayZeros :: Int -> ArrayContents declaredIn :: Code a -> Names -- | Find those memory blocks that are used only lexically. That is, are -- not used as the source or target of a SetMem, or are the result -- of the function, nor passed as arguments to other functions. This is -- interesting because such memory blocks do not need reference counting, -- but can be managed in a purely stack-like fashion. -- -- We do not look inside any Ops. We assume that no Op is -- going to SetMem a memory block declared outside it. lexicalMemoryUsage :: Function a -> Map VName Space -- | The set of functions that are called by this code. Assumes there are -- no function calls in Ops. calledFuncs :: Code a -> Set Name -- | Phantom type for a count of bytes. data Bytes -- | Phantom type for a count of elements. data Elements -- | This expression counts elements. elements :: a -> Count Elements a -- | This expression counts bytes. bytes :: a -> Count Bytes a -- | Convert a count of elements into a count of bytes, given the -- per-element size. withElemType :: Count Elements (TExp Int64) -> PrimType -> Count Bytes (TExp Int64) -- | A wrapper supporting a phantom type for indicating what we are -- counting. newtype Count u e Count :: e -> Count u e [unCount] :: Count u e -> e instance GHC.Show.Show Futhark.CodeGen.ImpCode.Param instance GHC.Show.Show Futhark.CodeGen.ImpCode.Signedness instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.Signedness instance GHC.Show.Show Futhark.CodeGen.ImpCode.ValueDesc instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.ValueDesc instance GHC.Show.Show Futhark.CodeGen.ImpCode.ExternalValue instance GHC.Show.Show Futhark.CodeGen.ImpCode.ArrayContents instance GHC.Show.Show Futhark.CodeGen.ImpCode.Volatility instance GHC.Classes.Ord Futhark.CodeGen.ImpCode.Volatility instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.Volatility instance GHC.Show.Show Futhark.CodeGen.ImpCode.ExpLeaf instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.ExpLeaf instance GHC.Show.Show Futhark.CodeGen.ImpCode.Arg instance GHC.Show.Show a => GHC.Show.Show (Futhark.CodeGen.ImpCode.Code a) instance GHC.Show.Show a => GHC.Show.Show (Futhark.CodeGen.ImpCode.FunctionT a) instance Text.PrettyPrint.Mainland.Class.Pretty op => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.CodeGen.ImpCode.Definitions op) instance Text.PrettyPrint.Mainland.Class.Pretty op => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.CodeGen.ImpCode.Constants op) instance GHC.Base.Semigroup (Futhark.CodeGen.ImpCode.Functions a) instance GHC.Base.Monoid (Futhark.CodeGen.ImpCode.Functions a) instance Text.PrettyPrint.Mainland.Class.Pretty op => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.CodeGen.ImpCode.Functions op) instance GHC.Base.Functor Futhark.CodeGen.ImpCode.Functions instance Data.Foldable.Foldable Futhark.CodeGen.ImpCode.Functions instance Data.Traversable.Traversable Futhark.CodeGen.ImpCode.Functions instance Futhark.IR.Prop.Names.FreeIn a => Futhark.IR.Prop.Names.FreeIn (Futhark.CodeGen.ImpCode.Functions a) instance Text.PrettyPrint.Mainland.Class.Pretty op => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.CodeGen.ImpCode.FunctionT op) instance GHC.Base.Functor Futhark.CodeGen.ImpCode.FunctionT instance Data.Foldable.Foldable Futhark.CodeGen.ImpCode.FunctionT instance Data.Traversable.Traversable Futhark.CodeGen.ImpCode.FunctionT instance GHC.Base.Semigroup (Futhark.CodeGen.ImpCode.Code a) instance GHC.Base.Monoid (Futhark.CodeGen.ImpCode.Code a) instance Text.PrettyPrint.Mainland.Class.Pretty op => Text.PrettyPrint.Mainland.Class.Pretty (Futhark.CodeGen.ImpCode.Code op) instance GHC.Base.Functor Futhark.CodeGen.ImpCode.Code instance Data.Foldable.Foldable Futhark.CodeGen.ImpCode.Code instance Data.Traversable.Traversable Futhark.CodeGen.ImpCode.Code instance Futhark.IR.Prop.Names.FreeIn a => Futhark.IR.Prop.Names.FreeIn (Futhark.CodeGen.ImpCode.Code a) instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Arg instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Arg instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.ExpLeaf instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.ExpLeaf instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.ArrayContents instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.ExternalValue instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.ValueDesc instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Param -- | Change DefaultSpace in a program to some other memory space. -- This is needed because the GPU backends use DefaultSpace to -- refer to GPU memory for most of the pipeline, but final code -- generation assumes that DefaultSpace is CPU memory. module Futhark.CodeGen.SetDefaultSpace -- | Set all uses of DefaultSpace in the given definitions to -- another memory space. setDefaultSpace :: Space -> Definitions op -> Definitions op -- | A cache-oblivious sequential transposition for CPU execution. -- Generates a recursive function. module Futhark.CodeGen.ImpGen.Transpose -- | We need to know the name of the function we are generating, as this -- function is recursive. mapTransposeFunction :: Name -> PrimType -> Function op -- | Take well-typed arguments to the transpose function and produce the -- actual argument list. transposeArgs :: PrimType -> VName -> Count Bytes (TExp Int64) -> VName -> Count Bytes (TExp Int64) -> TExp Int64 -> TExp Int64 -> TExp Int64 -> [Arg] -- | Sequential imperative code. module Futhark.CodeGen.ImpCode.Sequential -- | An imperative program. type Program = Definitions Sequential -- | An imperative function. type Function = Function Sequential -- | A imperative function, containing the body as well as its low-level -- inputs and outputs, as well as its high-level arguments and results. -- The latter are only used if the function is an entry point. data FunctionT a Function :: Bool -> [Param] -> [Param] -> Code a -> [ExternalValue] -> [ExternalValue] -> FunctionT a -- | A piece of imperative code. type Code = Code Sequential -- | Phantom type for identifying sequential imperative code. data Sequential -- | 8-bit signed integer type data Int8 -- | 16-bit signed integer type data Int16 -- | 32-bit signed integer type data Int32 -- | 64-bit signed integer type data Int64 -- | 8-bit unsigned integer type data Word8 -- | 16-bit unsigned integer type data Word16 -- | 32-bit unsigned integer type data Word32 -- | 64-bit unsigned integer type data Word64 -- | The SrcLoc of a Located value. srclocOf :: Located a => a -> SrcLoc -- | Location type, consisting of a beginning position and an end position. data Loc -- | Source location type. Source location are all equal, which allows AST -- nodes to be compared modulo location information. data SrcLoc -- | Located values have a location. class Located a locOf :: Located a => a -> Loc locOfList :: Located a => [a] -> Loc -- | Prettyprint a value, wrapped to 80 characters. pretty :: Pretty a => a -> String -- | Conversion operators try to generalise the from t0 x to t1 -- instructions from LLVM. data ConvOp -- | Zero-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. ZExt :: IntType -> IntType -> ConvOp -- | Sign-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. SExt :: IntType -> IntType -> ConvOp -- | Convert value of the former floating-point type to the latter. If the -- new type is smaller, the result is a truncation. FPConv :: FloatType -> FloatType -> ConvOp -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). FPToUI :: FloatType -> IntType -> ConvOp -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). FPToSI :: FloatType -> IntType -> ConvOp -- | Convert an unsigned integer to a floating-point value. UIToFP :: IntType -> FloatType -> ConvOp -- | Convert a signed integer to a floating-point value. SIToFP :: IntType -> FloatType -> ConvOp -- | Convert an integer to a boolean value. Zero becomes false; anything -- else is true. IToB :: IntType -> ConvOp -- | Convert a boolean to an integer. True is converted to 1 and False to -- 0. BToI :: IntType -> ConvOp -- | Comparison operators are like BinOps, but they always return a -- boolean value. The somewhat ugly constructor names are straight out of -- LLVM. data CmpOp -- | All types equality. CmpEq :: PrimType -> CmpOp -- | Unsigned less than. CmpUlt :: IntType -> CmpOp -- | Unsigned less than or equal. CmpUle :: IntType -> CmpOp -- | Signed less than. CmpSlt :: IntType -> CmpOp -- | Signed less than or equal. CmpSle :: IntType -> CmpOp -- | Floating-point less than. FCmpLt :: FloatType -> CmpOp -- | Floating-point less than or equal. FCmpLe :: FloatType -> CmpOp -- | Boolean less than. CmpLlt :: CmpOp -- | Boolean less than or equal. CmpLle :: CmpOp -- | Binary operators. These correspond closely to the binary operators in -- LLVM. Most are parametrised by their expected input and output types. data BinOp -- | Integer addition. Add :: IntType -> Overflow -> BinOp -- | Floating-point addition. FAdd :: FloatType -> BinOp -- | Integer subtraction. Sub :: IntType -> Overflow -> BinOp -- | Floating-point subtraction. FSub :: FloatType -> BinOp -- | Integer multiplication. Mul :: IntType -> Overflow -> BinOp -- | Floating-point multiplication. FMul :: FloatType -> BinOp -- | Unsigned integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. UDiv :: IntType -> Safety -> BinOp -- | Unsigned integer division. Rounds towards positive infinity. UDivUp :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. SDiv :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards positive infinity. SDivUp :: IntType -> Safety -> BinOp -- | Floating-point division. FDiv :: FloatType -> BinOp -- | Floating-point modulus. FMod :: FloatType -> BinOp -- | Unsigned integer modulus; the countepart to UDiv. UMod :: IntType -> Safety -> BinOp -- | Signed integer modulus; the countepart to SDiv. SMod :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- sdiv instruction in LLVM and integer division in C. SQuot :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- srem instruction in LLVM and integer modulo in C. SRem :: IntType -> Safety -> BinOp -- | Returns the smallest of two signed integers. SMin :: IntType -> BinOp -- | Returns the smallest of two unsigned integers. UMin :: IntType -> BinOp -- | Returns the smallest of two floating-point numbers. FMin :: FloatType -> BinOp -- | Returns the greatest of two signed integers. SMax :: IntType -> BinOp -- | Returns the greatest of two unsigned integers. UMax :: IntType -> BinOp -- | Returns the greatest of two floating-point numbers. FMax :: FloatType -> BinOp -- | Left-shift. Shl :: IntType -> BinOp -- | Logical right-shift, zero-extended. LShr :: IntType -> BinOp -- | Arithmetic right-shift, sign-extended. AShr :: IntType -> BinOp -- | Bitwise and. And :: IntType -> BinOp -- | Bitwise or. Or :: IntType -> BinOp -- | Bitwise exclusive-or. Xor :: IntType -> BinOp -- | Integer exponentiation. Pow :: IntType -> BinOp -- | Floating-point exponentiation. FPow :: FloatType -> BinOp -- | Boolean and - not short-circuiting. LogAnd :: BinOp -- | Boolean or - not short-circuiting. LogOr :: BinOp -- | Whether something is safe or unsafe (mostly function calls, and in the -- context of whether operations are dynamically checked). When we inline -- an Unsafe function, we remove all safety checks in its body. -- The Ord instance picks Unsafe as being less than -- Safe. -- -- For operations like integer division, a safe division will not explode -- the computer in case of division by zero, but instead return some -- unspecified value. This always involves a run-time check, so generally -- the unsafe variant is what the compiler will insert, but guarded by an -- explicit assertion elsewhere. Safe operations are useful when the -- optimiser wants to move e.g. a division to a location where the -- divisor may be zero, but where the result will only be used when it is -- non-zero (so it doesn't matter what result is provided with a zero -- divisor, as long as the program keeps running). data Safety Unsafe :: Safety Safe :: Safety -- | What to do in case of arithmetic overflow. Futhark's semantics are -- that overflow does wraparound, but for generated code (like address -- arithmetic), it can be beneficial for overflow to be undefined -- behaviour, as it allows better optimisation of things such as GPU -- kernels. -- -- Note that all values of this type are considered equal for Eq -- and Ord. data Overflow OverflowWrap :: Overflow OverflowUndef :: Overflow -- | Various unary operators. It is a bit ad-hoc what is a unary operator -- and what is a built-in function. Perhaps these should all go away -- eventually. data UnOp -- | E.g., ! True == False. Not :: UnOp -- | E.g., ~(~1) = 1. Complement :: IntType -> UnOp -- | abs(-2) = 2. Abs :: IntType -> UnOp -- | fabs(-2.0) = 2.0. FAbs :: FloatType -> UnOp -- | Signed sign function: ssignum(-2) = -1. SSignum :: IntType -> UnOp -- | Unsigned sign function: usignum(2) = 1. USignum :: IntType -> UnOp -- | Non-array values. data PrimValue IntValue :: !IntValue -> PrimValue FloatValue :: !FloatValue -> PrimValue BoolValue :: !Bool -> PrimValue -- | The only value of type cert. Checked :: PrimValue -- | A floating-point value. data FloatValue Float32Value :: !Float -> FloatValue Float64Value :: !Double -> FloatValue -- | An integer value. data IntValue Int8Value :: !Int8 -> IntValue Int16Value :: !Int16 -> IntValue Int32Value :: !Int32 -> IntValue Int64Value :: !Int64 -> IntValue -- | Low-level primitive types. data PrimType IntType :: IntType -> PrimType FloatType :: FloatType -> PrimType Bool :: PrimType Cert :: PrimType -- | A floating point type. data FloatType Float32 :: FloatType Float64 :: FloatType -- | An integer type, ordered by size. Note that signedness is not a -- property of the type, but a property of the operations performed on -- values of these types. data IntType Int8 :: IntType Int16 :: IntType Int32 :: IntType Int64 :: IntType -- | A list of all integer types. allIntTypes :: [IntType] -- | A list of all floating-point types. allFloatTypes :: [FloatType] -- | A list of all primitive types. allPrimTypes :: [PrimType] -- | Create an IntValue from a type and an Integer. intValue :: Integral int => IntType -> int -> IntValue -- | The type of an integer value. intValueType :: IntValue -> IntType -- | Convert an IntValue to any Integral type. valueIntegral :: Integral int => IntValue -> int -- | Create a FloatValue from a type and a Rational. floatValue :: Real num => FloatType -> num -> FloatValue -- | The type of a floating-point value. floatValueType :: FloatValue -> FloatType -- | The type of a basic value. primValueType :: PrimValue -> PrimType -- | A "blank" value of the given primitive type - this is zero, or -- whatever is close to it. Don't depend on this value, but use it for -- e.g. creating arrays to be populated by do-loops. blankPrimValue :: PrimType -> PrimValue -- | A list of all unary operators for all types. allUnOps :: [UnOp] -- | A list of all binary operators for all types. allBinOps :: [BinOp] -- | A list of all comparison operators for all types. allCmpOps :: [CmpOp] -- | A list of all conversion operators for all types. allConvOps :: [ConvOp] -- | Apply an UnOp to an operand. Returns Nothing if the -- application is mistyped. doUnOp :: UnOp -> PrimValue -> Maybe PrimValue -- | E.g., ~(~1) = 1. doComplement :: IntValue -> IntValue -- | abs(-2) = 2. doAbs :: IntValue -> IntValue -- | abs(-2.0) = 2.0. doFAbs :: FloatValue -> FloatValue -- | ssignum(-2) = -1. doSSignum :: IntValue -> IntValue -- | usignum(-2) = -1. doUSignum :: IntValue -> IntValue -- | Apply a BinOp to an operand. Returns Nothing if the -- application is mistyped, or outside the domain (e.g. division by -- zero). doBinOp :: BinOp -> PrimValue -> PrimValue -> Maybe PrimValue -- | Integer addition. doAdd :: IntValue -> IntValue -> IntValue -- | Integer multiplication. doMul :: IntValue -> IntValue -> IntValue -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. doSDiv :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer modulus; the countepart to SDiv. doSMod :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer exponentatation. doPow :: IntValue -> IntValue -> Maybe IntValue -- | Apply a ConvOp to an operand. Returns Nothing if the -- application is mistyped. doConvOp :: ConvOp -> PrimValue -> Maybe PrimValue -- | Zero-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doZExt :: IntValue -> IntType -> IntValue -- | Sign-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doSExt :: IntValue -> IntType -> IntValue -- | Convert the former floating-point type to the latter. doFPConv :: FloatValue -> FloatType -> FloatValue -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). doFPToUI :: FloatValue -> IntType -> IntValue -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). doFPToSI :: FloatValue -> IntType -> IntValue -- | Convert an unsigned integer to a floating-point value. doUIToFP :: IntValue -> FloatType -> FloatValue -- | Convert a signed integer to a floating-point value. doSIToFP :: IntValue -> FloatType -> FloatValue -- | Apply a CmpOp to an operand. Returns Nothing if the -- application is mistyped. doCmpOp :: CmpOp -> PrimValue -> PrimValue -> Maybe Bool -- | Compare any two primtive values for exact equality. doCmpEq :: PrimValue -> PrimValue -> Bool -- | Unsigned less than. doCmpUlt :: IntValue -> IntValue -> Bool -- | Unsigned less than or equal. doCmpUle :: IntValue -> IntValue -> Bool -- | Signed less than. doCmpSlt :: IntValue -> IntValue -> Bool -- | Signed less than or equal. doCmpSle :: IntValue -> IntValue -> Bool -- | Floating-point less than. doFCmpLt :: FloatValue -> FloatValue -> Bool -- | Floating-point less than or equal. doFCmpLe :: FloatValue -> FloatValue -> Bool -- | Translate an IntValue to Word64. This is guaranteed to -- fit. intToWord64 :: IntValue -> Word64 -- | Translate an IntValue to Int64. This is guaranteed to -- fit. intToInt64 :: IntValue -> Int64 -- | The result type of a binary operator. binOpType :: BinOp -> PrimType -- | The operand types of a comparison operator. cmpOpType :: CmpOp -> PrimType -- | The operand and result type of a unary operator. unOpType :: UnOp -> PrimType -- | The input and output types of a conversion operator. convOpType :: ConvOp -> (PrimType, PrimType) -- | A mapping from names of primitive functions to their parameter types, -- their result type, and a function for evaluating them. primFuns :: Map String ([PrimType], PrimType, [PrimValue] -> Maybe PrimValue) -- | Is the given value kind of zero? zeroIsh :: PrimValue -> Bool -- | Is the given value kind of one? oneIsh :: PrimValue -> Bool -- | Is the given value kind of negative? negativeIsh :: PrimValue -> Bool -- | Is the given integer value kind of zero? zeroIshInt :: IntValue -> Bool -- | Is the given integer value kind of one? oneIshInt :: IntValue -> Bool -- | The size of a value of a given primitive type in bites. primBitSize :: PrimType -> Int -- | The size of a value of a given primitive type in eight-bit bytes. primByteSize :: Num a => PrimType -> a -- | The size of a value of a given integer type in eight-bit bytes. intByteSize :: Num a => IntType -> a -- | The size of a value of a given floating-point type in eight-bit bytes. floatByteSize :: Num a => FloatType -> a -- | True if the given binary operator is commutative. commutativeBinOp :: BinOp -> Bool -- | The human-readable name for a ConvOp. This is used to expose -- the ConvOp in the intrinsics module of a Futhark -- program. convOpFun :: ConvOp -> String -- | True if signed. Only makes a difference for integer types. prettySigned :: Bool -> PrimType -> String -- | A name tagged with some integer. Only the integer is used in -- comparisons, no matter the type of vn. data VName VName :: !Name -> !Int -> VName -- | The abstract (not really) type representing names in the Futhark -- compiler. Strings, being lists of characters, are very slow, -- while Texts are based on byte-arrays. data Name -- | Whether some operator is commutative or not. The Monoid -- instance returns the least commutative of its arguments. data Commutativity Noncommutative :: Commutativity Commutative :: Commutativity -- | The uniqueness attribute of a type. This essentially indicates whether -- or not in-place modifications are acceptable. With respect to -- ordering, Unique is greater than Nonunique. data Uniqueness -- | May have references outside current function. Nonunique :: Uniqueness -- | No references outside current function. Unique :: Uniqueness -- | The name of the default program entry point (main). defaultEntryPoint :: Name -- | Convert a name to the corresponding list of characters. nameToString :: Name -> String -- | Convert a list of characters to the corresponding name. nameFromString :: String -> Name -- | Convert a name to the corresponding Text. nameToText :: Name -> Text -- | Convert a Text to the corresponding name. nameFromText :: Text -> Name -- | A human-readable location string, of the form -- filename:lineno:columnno. This follows the GNU coding -- standards for error messages: -- https://www.gnu.org/prep/standards/html_node/Errors.html -- -- This function assumes that both start and end position is in the same -- file (it is not clear what the alternative would even mean). locStr :: Located a => a -> String -- | Like locStr, but locStrRel prev now prints the -- location now with the file name left out if the same as -- prev. This is useful when printing messages that are all in -- the context of some initially printed location (e.g. the first mention -- contains the file name; the rest just line and column name). locStrRel :: (Located a, Located b) => a -> b -> String -- | Given a list of strings representing entries in the stack trace and -- the index of the frame to highlight, produce a final -- newline-terminated string for showing to the user. This string should -- also be preceded by a newline. The most recent stack frame must come -- first in the list. prettyStacktrace :: Int -> [String] -> String -- | Return the tag contained in the VName. baseTag :: VName -> Int -- | Return the name contained in the VName. baseName :: VName -> Name -- | Return the base Name converted to a string. baseString :: VName -> String -- | Enclose a string in the prefered quotes used in error messages. These -- are picked to not collide with characters permitted in identifiers. quote :: String -> String -- | As quote, but works on prettyprinted representation. pquote :: Doc -> Doc -- | A part of an error message. data ErrorMsgPart a -- | A literal string. ErrorString :: String -> ErrorMsgPart a -- | A run-time integer value. ErrorInt32 :: a -> ErrorMsgPart a -- | A bigger run-time integer value. ErrorInt64 :: a -> ErrorMsgPart a -- | An error message is a list of error parts, which are concatenated to -- form the final message. newtype ErrorMsg a ErrorMsg :: [ErrorMsgPart a] -> ErrorMsg a -- | A subexpression is either a scalar constant or a variable. One -- important property is that evaluation of a subexpression is guaranteed -- to complete in constant time. data SubExp Constant :: PrimValue -> SubExp Var :: VName -> SubExp -- | A string representing a specific non-default memory space. type SpaceId = String -- | The memory space of a block. If DefaultSpace, this is the -- "default" space, whatever that is. The exact meaning of the -- SpaceId depends on the backend used. In GPU kernels, for -- example, this is used to distinguish between constant, global and -- shared memory spaces. In GPU-enabled host code, it is used to -- distinguish between host memory (DefaultSpace) and GPU space. data Space DefaultSpace :: Space Space :: SpaceId -> Space -- | A special kind of memory that is a statically sized array of some -- primitive type. Used for private memory on GPUs. ScalarSpace :: [SubExp] -> PrimType -> Space -- | How many non-constant parts does the error message have, and what is -- their type? errorMsgArgTypes :: ErrorMsg a -> [PrimType] -- | Either return precomputed free names stored in the attribute, or the -- freshly computed names. Relies on lazy evaluation to avoid the work. class FreeIn dec => FreeDec dec precomputed :: FreeDec dec => dec -> FV -> FV -- | A class indicating that we can obtain free variable information from -- values of this type. class FreeIn a freeIn' :: FreeIn a => a -> FV -- | A computation to build a free variable set. data FV -- | A set of names. Note that the Ord instance is a dummy that -- treats everything as EQ if ==, and otherwise LT. data Names -- | Retrieve the data structure underlying the names representation. namesIntMap :: Names -> IntMap VName -- | Does the set of names contain this name? nameIn :: VName -> Names -> Bool -- | Construct a name set from a list. Slow. namesFromList :: [VName] -> Names -- | Turn a name set into a list of names. Slow. namesToList :: Names -> [VName] -- | Construct a name set from a single name. oneName :: VName -> Names -- | The intersection of two name sets. namesIntersection :: Names -> Names -> Names -- | Do the two name sets intersect? namesIntersect :: Names -> Names -> Bool -- | Subtract the latter name set from the former. namesSubtract :: Names -> Names -> Names -- | Map over the names in a set. mapNames :: (VName -> VName) -> Names -> Names -- | Consider a variable to be bound in the given FV computation. fvBind :: Names -> FV -> FV -- | Take note of a variable reference. fvName :: VName -> FV -- | Take note of a set of variable references. fvNames :: Names -> FV -- | Return the set of variable names that are free in the given statements -- and result. Filters away the names that are bound by the statements. freeInStmsAndRes :: (FreeIn (Op lore), FreeIn (LetDec lore), FreeIn (LParamInfo lore), FreeIn (FParamInfo lore), FreeDec (BodyDec lore), FreeDec (ExpDec lore)) => Stms lore -> Result -> FV -- | The free variables of some syntactic construct. freeIn :: FreeIn a => a -> Names -- | The names bound by the bindings immediately in a Body. boundInBody :: Body lore -> Names -- | The names bound by a binding. boundByStm :: Stm lore -> Names -- | The names bound by the bindings. boundByStms :: Stms lore -> Names -- | The names of the lambda parameters plus the index parameter. boundByLambda :: Lambda lore -> [VName] -- | The class of floating-point types that can be used for constructing -- TPrimExps. class NumExp t => FloatExp t -- | Construct a typed expression from a rational. fromRational' :: FloatExp t => Rational -> TPrimExp t v -- | The class of integer types that can be used for constructing -- TPrimExps. class NumExp t => IntExp t -- | The class of numeric types that can be used for constructing -- TPrimExps. class NumExp t -- | Construct a typed expression from an integer. fromInteger' :: NumExp t => Integer -> TPrimExp t v -- | A PrimExp tagged with a phantom type used to provide type-safe -- construction. Does not guarantee that the underlying expression is -- actually type correct. newtype TPrimExp t v TPrimExp :: PrimExp v -> TPrimExp t v [untyped] :: TPrimExp t v -> PrimExp v -- | A primitive expression parametrised over the representation of free -- variables. Note that the Functor, Traversable, and -- Num instances perform automatic (but simple) constant folding. -- -- Note also that the Num instance assumes OverflowUndef -- semantics! data PrimExp v LeafExp :: v -> PrimType -> PrimExp v ValueExp :: PrimValue -> PrimExp v BinOpExp :: BinOp -> PrimExp v -> PrimExp v -> PrimExp v CmpOpExp :: CmpOp -> PrimExp v -> PrimExp v -> PrimExp v UnOpExp :: UnOp -> PrimExp v -> PrimExp v ConvOpExp :: ConvOp -> PrimExp v -> PrimExp v FunExp :: String -> [PrimExp v] -> PrimType -> PrimExp v -- | This expression is of type Int8. isInt8 :: PrimExp v -> TPrimExp Int8 v -- | This expression is of type Int16. isInt16 :: PrimExp v -> TPrimExp Int16 v -- | This expression is of type Int32. isInt32 :: PrimExp v -> TPrimExp Int32 v -- | This expression is of type Int64. isInt64 :: PrimExp v -> TPrimExp Int64 v -- | This is a boolean expression. isBool :: PrimExp v -> TPrimExp Bool v -- | This expression is of type Float. isF32 :: PrimExp v -> TPrimExp Float v -- | This expression is of type Double. isF64 :: PrimExp v -> TPrimExp Double v -- | True if the PrimExp has at least this many nodes. This can be -- much more efficient than comparing with length for large -- PrimExps, as this function is lazy. primExpSizeAtLeast :: Int -> PrimExp v -> Bool -- | Perform quick and dirty constant folding on the top level of a -- PrimExp. This is necessary because we want to consider e.g. equality -- modulo constant folding. constFoldPrimExp :: PrimExp v -> PrimExp v -- | Lifted logical conjunction. (.&&.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 3 .&&. -- | Lifted logical conjunction. (.||.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 2 .||. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<=. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.==.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .==. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>=. -- | Lifted bitwise operators. (.&.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.|.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.^.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Untyped smart constructor for sign extension that does a bit of -- constant folding. sExt :: IntType -> PrimExp v -> PrimExp v -- | Untyped smart constructor for zero extension that does a bit of -- constant folding. zExt :: IntType -> PrimExp v -> PrimExp v -- | Evaluate a PrimExp in the given monad. Invokes fail on -- type errors. evalPrimExp :: (Pretty v, MonadFail m) => (v -> m PrimValue) -> PrimExp v -> m PrimValue -- | The type of values returned by a PrimExp. This function -- returning does not imply that the PrimExp is type-correct. primExpType :: PrimExp v -> PrimType -- | If the given PrimExp is a constant of the wrong integer type, -- coerce it to the given integer type. This is a workaround for an issue -- in the Num instance. coerceIntPrimExp :: IntType -> PrimExp v -> PrimExp v -- | Boolean-valued PrimExps. true :: TPrimExp Bool v -- | Boolean-valued PrimExps. false :: TPrimExp Bool v -- | Boolean negation smart constructor. bNot :: TPrimExp Bool v -> TPrimExp Bool v -- | SMax on 32-bit integers. sMax32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMin on 32-bit integers. sMin32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMax on 64-bit integers. sMax64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | SMin on 64-bit integers. sMin64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | Sign-extend to 32 bit integer. sExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Sign-extend to 64 bit integer. sExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | Zero-extend to 32 bit integer. zExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Zero-extend to 64 bit integer. zExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | 64-bit float minimum. fMin64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v -- | 64-bit float maximum. fMax64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v -- | Produce a mapping from the leaves of the PrimExp to their -- designated types. leafExpTypes :: Ord a => PrimExp a -> Set (a, PrimType) -- | A wrapper supporting a phantom type for indicating what we are -- counting. newtype Count u e Count :: e -> Count u e [unCount] :: Count u e -> e -- | Phantom type for a count of bytes. data Bytes -- | Phantom type for a count of elements. data Elements -- | A function call argument. data Arg ExpArg :: Exp -> Arg MemArg :: VName -> Arg -- | Like Exp, but with a required/known type. type TExp t = TPrimExp t ExpLeaf -- | A side-effect free expression whose execution will produce a single -- primitive value. type Exp = PrimExp ExpLeaf -- | The leaves of an Exp. data ExpLeaf -- | A scalar variable. The type is stored in the LeafExp -- constructor itself. ScalarVar :: VName -> ExpLeaf -- | The size of a primitive type. SizeOf :: PrimType -> ExpLeaf -- | Reading a value from memory. The arguments have the same meaning as -- with Write. Index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> ExpLeaf -- | The volatility of a memory access or variable. Feel free to ignore -- this for backends where it makes no sense (anything but C and similar -- low-level things) data Volatility Volatile :: Volatility Nonvolatile :: Volatility -- | Print the given value to the screen, somehow annotated with the given -- string as a description. If no type/value pair, just print the string. -- This has no semantic meaning, but is used entirely for debugging. Code -- generators are free to ignore this statement. pattern DebugPrint :: () => String -> Maybe Exp -> Code a -- | Function call. The results are written to the provided VName -- variables. pattern Call :: () => [VName] -> Name -> [Arg] -> Code a -- | Must be in same space. pattern SetMem :: () => VName -> VName -> Space -> Code a -- | Set a scalar variable. pattern SetScalar :: () => VName -> Exp -> Code a -- | Create an array containing the given values. The lifetime of the array -- will be the entire application. This is mostly used for constant -- arrays, but also for some bookkeeping data, like the synchronisation -- counts used to implement reduction. pattern DeclareArray :: () => VName -> Space -> PrimType -> ArrayContents -> Code a -- | Declare a scalar variable with an initially undefined value. pattern DeclareScalar :: () => VName -> Volatility -> PrimType -> Code a -- | Declare a memory block variable that will point to memory in the given -- memory space. Note that this is distinct from allocation. The memory -- block must be the target of either an Allocate or a -- SetMem before it can be used for reading or writing. pattern DeclareMem :: () => VName -> Space -> Code a -- | Statement composition. Crucial for the Semigroup instance. pattern (:>>:) :: () => Code a -> Code a -> Code a -- | Assert that something must be true. Should it turn out not to be true, -- then report a failure along with the given error message. pattern Assert :: () => Exp -> ErrorMsg Exp -> (SrcLoc, [SrcLoc]) -> Code a -- | Destination, offset in destination, destination space, source, offset -- in source, offset space, number of bytes. pattern Copy :: () => VName -> Count Bytes (TExp Int64) -> Space -> VName -> Count Bytes (TExp Int64) -> Space -> Count Bytes (TExp Int64) -> Code a -- | Memory space must match the corresponding DeclareMem. pattern Allocate :: () => VName -> Count Bytes (TExp Int64) -> Space -> Code a -- | No-op. Crucial for the Monoid instance. pattern Skip :: () => Code a -- | A for-loop iterating the given number of times. The loop parameter -- starts counting from zero and will have the same (integer) type as the -- bound. The bound is evaluated just once, before the loop is entered. pattern For :: () => VName -> Exp -> Code a -> Code a -- | While loop. The conditional is (of course) re-evaluated before every -- iteration of the loop. pattern While :: () => TExp Bool -> Code a -> Code a -- | Indicate that some memory block will never again be referenced via the -- indicated variable. However, it may still be accessed through aliases. -- It is only safe to actually deallocate the memory block if this is the -- last reference. There is no guarantee that all memory blocks will be -- freed with this statement. Backends are free to ignore it entirely. pattern Free :: () => VName -> Space -> Code a -- | Has the same semantics as the contained code, but the comment should -- show up in generated code for ease of inspection. pattern Comment :: () => String -> Code a -> Code a -- | Write mem i t space vol v writes the value v to -- mem offset by i elements of type t. The -- Space argument is the memory space of mem (technically -- redundant, but convenient). Note that reading is done with an -- Exp (Index). pattern Write :: () => VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp -> Code a -- | Conditional execution. pattern If :: () => TExp Bool -> Code a -> Code a -> Code a -- | Perform an extensible operation. pattern Op :: () => a -> Code a -- | The contents of a statically declared constant array. Such arrays are -- always unidimensional, and reshaped if necessary in the code that uses -- them. data ArrayContents -- | Precisely these values. ArrayValues :: [PrimValue] -> ArrayContents -- | This many zeroes. ArrayZeros :: Int -> ArrayContents -- | A imperative function, containing the body as well as its low-level -- inputs and outputs, as well as its high-level arguments and results. -- The latter are only used if the function is an entry point. data FunctionT a -- | ^ An externally visible value. This can be an opaque value (covering -- several physical internal values), or a single value that can be used -- externally. data ExternalValue -- | The string is a human-readable description with no other semantics. OpaqueValue :: String -> [ValueDesc] -> ExternalValue TransparentValue :: ValueDesc -> ExternalValue -- | A description of an externally meaningful value. data ValueDesc -- | An array with memory block, memory block size, memory space, element -- type, signedness of element type (if applicable), and shape. ArrayValue :: VName -> Space -> PrimType -> Signedness -> [DimSize] -> ValueDesc -- | A scalar value with signedness if applicable. ScalarValue :: PrimType -> Signedness -> VName -> ValueDesc -- | Since the core language does not care for signedness, but the source -- language does, entry point input/output information has metadata for -- integer types (and arrays containing these) that indicate whether they -- are really unsigned integers. data Signedness TypeUnsigned :: Signedness TypeDirect :: Signedness -- | A collection of imperative constants. data Constants a Constants :: [Param] -> Code a -> Constants a -- | The constants that are made available to the functions. [constsDecl] :: Constants a -> [Param] -- | Setting the value of the constants. Note that this must not contain -- declarations of the names defined in constsDecl. [constsInit] :: Constants a -> Code a -- | A collection of imperative functions. newtype Functions a Functions :: [(Name, Function a)] -> Functions a -- | A collection of imperative functions and constants. data Definitions a Definitions :: Constants a -> Functions a -> Definitions a [defConsts] :: Definitions a -> Constants a [defFuns] :: Definitions a -> Functions a -- | An ImpCode function parameter. data Param MemParam :: VName -> Space -> Param ScalarParam :: VName -> PrimType -> Param -- | The size of an array. type DimSize = SubExp -- | The size of a memory block. type MemSize = SubExp -- | The name of a parameter. paramName :: Param -> VName -- | Find those memory blocks that are used only lexically. That is, are -- not used as the source or target of a SetMem, or are the result -- of the function, nor passed as arguments to other functions. This is -- interesting because such memory blocks do not need reference counting, -- but can be managed in a purely stack-like fashion. -- -- We do not look inside any Ops. We assume that no Op is -- going to SetMem a memory block declared outside it. lexicalMemoryUsage :: Function a -> Map VName Space -- | The set of functions that are called by this code. Assumes there are -- no function calls in Ops. calledFuncs :: Code a -> Set Name -- | This expression counts elements. elements :: a -> Count Elements a -- | This expression counts bytes. bytes :: a -> Count Bytes a -- | Convert a count of elements into a count of bytes, given the -- per-element size. withElemType :: Count Elements (TExp Int64) -> PrimType -> Count Bytes (TExp Int64) -- | Turn a VName into a ScalarVar. var :: VName -> PrimType -> Exp -- | Turn a VName into a Int32 ScalarVar. vi32 :: VName -> TExp Int32 -- | Turn a VName into a Int64 ScalarVar. vi64 :: VName -> TExp Int64 -- | Concise wrapper for using Index. index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp declaredIn :: Code a -> Names instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Sequential.Sequential instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Sequential.Sequential -- | Imperative code with an OpenCL component. -- -- Apart from ordinary imperative code, this also carries around an -- OpenCL program as a string, as well as a list of kernels defined by -- the OpenCL program. -- -- The imperative code has been augmented with a LaunchKernel -- operation that allows one to execute an OpenCL kernel. module Futhark.CodeGen.ImpCode.OpenCL -- | An program calling OpenCL kernels. data Program Program :: String -> String -> Map KernelName KernelSafety -> [PrimType] -> Map Name SizeClass -> [FailureMsg] -> Definitions OpenCL -> Program [openClProgram] :: Program -> String -- | Must be prepended to the program. [openClPrelude] :: Program -> String [openClKernelNames] :: Program -> Map KernelName KernelSafety -- | So we can detect whether the device is capable. [openClUsedTypes] :: Program -> [PrimType] -- | Runtime-configurable constants. [openClSizes] :: Program -> Map Name SizeClass -- | Assertion failure error messages. [openClFailures] :: Program -> [FailureMsg] [hostDefinitions] :: Program -> Definitions OpenCL -- | A function calling OpenCL kernels. type Function = Function OpenCL -- | A imperative function, containing the body as well as its low-level -- inputs and outputs, as well as its high-level arguments and results. -- The latter are only used if the function is an entry point. data FunctionT a Function :: Bool -> [Param] -> [Param] -> Code a -> [ExternalValue] -> [ExternalValue] -> FunctionT a -- | A piece of code calling OpenCL. type Code = Code OpenCL -- | The name of a kernel. type KernelName = Name -- | An argument to be passed to a kernel. data KernelArg -- | Pass the value of this scalar expression as argument. ValueKArg :: Exp -> PrimType -> KernelArg -- | Pass this pointer as argument. MemKArg :: VName -> KernelArg -- | Create this much local memory per workgroup. SharedMemoryKArg :: Count Bytes Exp -> KernelArg -- | Host-level OpenCL operation. data OpenCL LaunchKernel :: KernelSafety -> KernelName -> [KernelArg] -> [Exp] -> [Exp] -> OpenCL GetSize :: VName -> Name -> OpenCL CmpSizeLe :: VName -> Name -> Exp -> OpenCL GetSizeMax :: VName -> SizeClass -> OpenCL -- | Information about bounds checks and how sensitive it is to errors. -- Ordered by least demanding to most. data KernelSafety -- | Does not need to know if we are in a failing state, and also cannot -- fail. SafetyNone :: KernelSafety -- | Needs to be told if there's a global failure, and that's it, and -- cannot fail. SafetyCheap :: KernelSafety -- | Needs all parameters, may fail itself. SafetyFull :: KernelSafety -- | How many leading failure arguments we must pass when launching a -- kernel with these safety characteristics. numFailureParams :: KernelSafety -> Int -- | The target platform when compiling imperative code to a Program data KernelTarget TargetOpenCL :: KernelTarget TargetCUDA :: KernelTarget -- | Something that can go wrong in a kernel. Part of the machinery for -- reporting error messages from within kernels. data FailureMsg FailureMsg :: ErrorMsg Exp -> String -> FailureMsg [failureError] :: FailureMsg -> ErrorMsg Exp [failureBacktrace] :: FailureMsg -> String -- | 8-bit signed integer type data Int8 -- | 16-bit signed integer type data Int16 -- | 32-bit signed integer type data Int32 -- | 64-bit signed integer type data Int64 -- | 8-bit unsigned integer type data Word8 -- | 16-bit unsigned integer type data Word16 -- | 32-bit unsigned integer type data Word32 -- | 64-bit unsigned integer type data Word64 -- | The SrcLoc of a Located value. srclocOf :: Located a => a -> SrcLoc -- | Location type, consisting of a beginning position and an end position. data Loc -- | Source location type. Source location are all equal, which allows AST -- nodes to be compared modulo location information. data SrcLoc -- | Located values have a location. class Located a locOf :: Located a => a -> Loc locOfList :: Located a => [a] -> Loc -- | Prettyprint a value, wrapped to 80 characters. pretty :: Pretty a => a -> String -- | Conversion operators try to generalise the from t0 x to t1 -- instructions from LLVM. data ConvOp -- | Zero-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. ZExt :: IntType -> IntType -> ConvOp -- | Sign-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. SExt :: IntType -> IntType -> ConvOp -- | Convert value of the former floating-point type to the latter. If the -- new type is smaller, the result is a truncation. FPConv :: FloatType -> FloatType -> ConvOp -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). FPToUI :: FloatType -> IntType -> ConvOp -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). FPToSI :: FloatType -> IntType -> ConvOp -- | Convert an unsigned integer to a floating-point value. UIToFP :: IntType -> FloatType -> ConvOp -- | Convert a signed integer to a floating-point value. SIToFP :: IntType -> FloatType -> ConvOp -- | Convert an integer to a boolean value. Zero becomes false; anything -- else is true. IToB :: IntType -> ConvOp -- | Convert a boolean to an integer. True is converted to 1 and False to -- 0. BToI :: IntType -> ConvOp -- | Comparison operators are like BinOps, but they always return a -- boolean value. The somewhat ugly constructor names are straight out of -- LLVM. data CmpOp -- | All types equality. CmpEq :: PrimType -> CmpOp -- | Unsigned less than. CmpUlt :: IntType -> CmpOp -- | Unsigned less than or equal. CmpUle :: IntType -> CmpOp -- | Signed less than. CmpSlt :: IntType -> CmpOp -- | Signed less than or equal. CmpSle :: IntType -> CmpOp -- | Floating-point less than. FCmpLt :: FloatType -> CmpOp -- | Floating-point less than or equal. FCmpLe :: FloatType -> CmpOp -- | Boolean less than. CmpLlt :: CmpOp -- | Boolean less than or equal. CmpLle :: CmpOp -- | Binary operators. These correspond closely to the binary operators in -- LLVM. Most are parametrised by their expected input and output types. data BinOp -- | Integer addition. Add :: IntType -> Overflow -> BinOp -- | Floating-point addition. FAdd :: FloatType -> BinOp -- | Integer subtraction. Sub :: IntType -> Overflow -> BinOp -- | Floating-point subtraction. FSub :: FloatType -> BinOp -- | Integer multiplication. Mul :: IntType -> Overflow -> BinOp -- | Floating-point multiplication. FMul :: FloatType -> BinOp -- | Unsigned integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. UDiv :: IntType -> Safety -> BinOp -- | Unsigned integer division. Rounds towards positive infinity. UDivUp :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. SDiv :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards positive infinity. SDivUp :: IntType -> Safety -> BinOp -- | Floating-point division. FDiv :: FloatType -> BinOp -- | Floating-point modulus. FMod :: FloatType -> BinOp -- | Unsigned integer modulus; the countepart to UDiv. UMod :: IntType -> Safety -> BinOp -- | Signed integer modulus; the countepart to SDiv. SMod :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- sdiv instruction in LLVM and integer division in C. SQuot :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- srem instruction in LLVM and integer modulo in C. SRem :: IntType -> Safety -> BinOp -- | Returns the smallest of two signed integers. SMin :: IntType -> BinOp -- | Returns the smallest of two unsigned integers. UMin :: IntType -> BinOp -- | Returns the smallest of two floating-point numbers. FMin :: FloatType -> BinOp -- | Returns the greatest of two signed integers. SMax :: IntType -> BinOp -- | Returns the greatest of two unsigned integers. UMax :: IntType -> BinOp -- | Returns the greatest of two floating-point numbers. FMax :: FloatType -> BinOp -- | Left-shift. Shl :: IntType -> BinOp -- | Logical right-shift, zero-extended. LShr :: IntType -> BinOp -- | Arithmetic right-shift, sign-extended. AShr :: IntType -> BinOp -- | Bitwise and. And :: IntType -> BinOp -- | Bitwise or. Or :: IntType -> BinOp -- | Bitwise exclusive-or. Xor :: IntType -> BinOp -- | Integer exponentiation. Pow :: IntType -> BinOp -- | Floating-point exponentiation. FPow :: FloatType -> BinOp -- | Boolean and - not short-circuiting. LogAnd :: BinOp -- | Boolean or - not short-circuiting. LogOr :: BinOp -- | Whether something is safe or unsafe (mostly function calls, and in the -- context of whether operations are dynamically checked). When we inline -- an Unsafe function, we remove all safety checks in its body. -- The Ord instance picks Unsafe as being less than -- Safe. -- -- For operations like integer division, a safe division will not explode -- the computer in case of division by zero, but instead return some -- unspecified value. This always involves a run-time check, so generally -- the unsafe variant is what the compiler will insert, but guarded by an -- explicit assertion elsewhere. Safe operations are useful when the -- optimiser wants to move e.g. a division to a location where the -- divisor may be zero, but where the result will only be used when it is -- non-zero (so it doesn't matter what result is provided with a zero -- divisor, as long as the program keeps running). data Safety Unsafe :: Safety Safe :: Safety -- | What to do in case of arithmetic overflow. Futhark's semantics are -- that overflow does wraparound, but for generated code (like address -- arithmetic), it can be beneficial for overflow to be undefined -- behaviour, as it allows better optimisation of things such as GPU -- kernels. -- -- Note that all values of this type are considered equal for Eq -- and Ord. data Overflow OverflowWrap :: Overflow OverflowUndef :: Overflow -- | Various unary operators. It is a bit ad-hoc what is a unary operator -- and what is a built-in function. Perhaps these should all go away -- eventually. data UnOp -- | E.g., ! True == False. Not :: UnOp -- | E.g., ~(~1) = 1. Complement :: IntType -> UnOp -- | abs(-2) = 2. Abs :: IntType -> UnOp -- | fabs(-2.0) = 2.0. FAbs :: FloatType -> UnOp -- | Signed sign function: ssignum(-2) = -1. SSignum :: IntType -> UnOp -- | Unsigned sign function: usignum(2) = 1. USignum :: IntType -> UnOp -- | Non-array values. data PrimValue IntValue :: !IntValue -> PrimValue FloatValue :: !FloatValue -> PrimValue BoolValue :: !Bool -> PrimValue -- | The only value of type cert. Checked :: PrimValue -- | A floating-point value. data FloatValue Float32Value :: !Float -> FloatValue Float64Value :: !Double -> FloatValue -- | An integer value. data IntValue Int8Value :: !Int8 -> IntValue Int16Value :: !Int16 -> IntValue Int32Value :: !Int32 -> IntValue Int64Value :: !Int64 -> IntValue -- | Low-level primitive types. data PrimType IntType :: IntType -> PrimType FloatType :: FloatType -> PrimType Bool :: PrimType Cert :: PrimType -- | A floating point type. data FloatType Float32 :: FloatType Float64 :: FloatType -- | An integer type, ordered by size. Note that signedness is not a -- property of the type, but a property of the operations performed on -- values of these types. data IntType Int8 :: IntType Int16 :: IntType Int32 :: IntType Int64 :: IntType -- | A list of all integer types. allIntTypes :: [IntType] -- | A list of all floating-point types. allFloatTypes :: [FloatType] -- | A list of all primitive types. allPrimTypes :: [PrimType] -- | Create an IntValue from a type and an Integer. intValue :: Integral int => IntType -> int -> IntValue -- | The type of an integer value. intValueType :: IntValue -> IntType -- | Convert an IntValue to any Integral type. valueIntegral :: Integral int => IntValue -> int -- | Create a FloatValue from a type and a Rational. floatValue :: Real num => FloatType -> num -> FloatValue -- | The type of a floating-point value. floatValueType :: FloatValue -> FloatType -- | The type of a basic value. primValueType :: PrimValue -> PrimType -- | A "blank" value of the given primitive type - this is zero, or -- whatever is close to it. Don't depend on this value, but use it for -- e.g. creating arrays to be populated by do-loops. blankPrimValue :: PrimType -> PrimValue -- | A list of all unary operators for all types. allUnOps :: [UnOp] -- | A list of all binary operators for all types. allBinOps :: [BinOp] -- | A list of all comparison operators for all types. allCmpOps :: [CmpOp] -- | A list of all conversion operators for all types. allConvOps :: [ConvOp] -- | Apply an UnOp to an operand. Returns Nothing if the -- application is mistyped. doUnOp :: UnOp -> PrimValue -> Maybe PrimValue -- | E.g., ~(~1) = 1. doComplement :: IntValue -> IntValue -- | abs(-2) = 2. doAbs :: IntValue -> IntValue -- | abs(-2.0) = 2.0. doFAbs :: FloatValue -> FloatValue -- | ssignum(-2) = -1. doSSignum :: IntValue -> IntValue -- | usignum(-2) = -1. doUSignum :: IntValue -> IntValue -- | Apply a BinOp to an operand. Returns Nothing if the -- application is mistyped, or outside the domain (e.g. division by -- zero). doBinOp :: BinOp -> PrimValue -> PrimValue -> Maybe PrimValue -- | Integer addition. doAdd :: IntValue -> IntValue -> IntValue -- | Integer multiplication. doMul :: IntValue -> IntValue -> IntValue -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. doSDiv :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer modulus; the countepart to SDiv. doSMod :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer exponentatation. doPow :: IntValue -> IntValue -> Maybe IntValue -- | Apply a ConvOp to an operand. Returns Nothing if the -- application is mistyped. doConvOp :: ConvOp -> PrimValue -> Maybe PrimValue -- | Zero-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doZExt :: IntValue -> IntType -> IntValue -- | Sign-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doSExt :: IntValue -> IntType -> IntValue -- | Convert the former floating-point type to the latter. doFPConv :: FloatValue -> FloatType -> FloatValue -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). doFPToUI :: FloatValue -> IntType -> IntValue -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). doFPToSI :: FloatValue -> IntType -> IntValue -- | Convert an unsigned integer to a floating-point value. doUIToFP :: IntValue -> FloatType -> FloatValue -- | Convert a signed integer to a floating-point value. doSIToFP :: IntValue -> FloatType -> FloatValue -- | Apply a CmpOp to an operand. Returns Nothing if the -- application is mistyped. doCmpOp :: CmpOp -> PrimValue -> PrimValue -> Maybe Bool -- | Compare any two primtive values for exact equality. doCmpEq :: PrimValue -> PrimValue -> Bool -- | Unsigned less than. doCmpUlt :: IntValue -> IntValue -> Bool -- | Unsigned less than or equal. doCmpUle :: IntValue -> IntValue -> Bool -- | Signed less than. doCmpSlt :: IntValue -> IntValue -> Bool -- | Signed less than or equal. doCmpSle :: IntValue -> IntValue -> Bool -- | Floating-point less than. doFCmpLt :: FloatValue -> FloatValue -> Bool -- | Floating-point less than or equal. doFCmpLe :: FloatValue -> FloatValue -> Bool -- | Translate an IntValue to Word64. This is guaranteed to -- fit. intToWord64 :: IntValue -> Word64 -- | Translate an IntValue to Int64. This is guaranteed to -- fit. intToInt64 :: IntValue -> Int64 -- | The result type of a binary operator. binOpType :: BinOp -> PrimType -- | The operand types of a comparison operator. cmpOpType :: CmpOp -> PrimType -- | The operand and result type of a unary operator. unOpType :: UnOp -> PrimType -- | The input and output types of a conversion operator. convOpType :: ConvOp -> (PrimType, PrimType) -- | A mapping from names of primitive functions to their parameter types, -- their result type, and a function for evaluating them. primFuns :: Map String ([PrimType], PrimType, [PrimValue] -> Maybe PrimValue) -- | Is the given value kind of zero? zeroIsh :: PrimValue -> Bool -- | Is the given value kind of one? oneIsh :: PrimValue -> Bool -- | Is the given value kind of negative? negativeIsh :: PrimValue -> Bool -- | Is the given integer value kind of zero? zeroIshInt :: IntValue -> Bool -- | Is the given integer value kind of one? oneIshInt :: IntValue -> Bool -- | The size of a value of a given primitive type in bites. primBitSize :: PrimType -> Int -- | The size of a value of a given primitive type in eight-bit bytes. primByteSize :: Num a => PrimType -> a -- | The size of a value of a given integer type in eight-bit bytes. intByteSize :: Num a => IntType -> a -- | The size of a value of a given floating-point type in eight-bit bytes. floatByteSize :: Num a => FloatType -> a -- | True if the given binary operator is commutative. commutativeBinOp :: BinOp -> Bool -- | The human-readable name for a ConvOp. This is used to expose -- the ConvOp in the intrinsics module of a Futhark -- program. convOpFun :: ConvOp -> String -- | True if signed. Only makes a difference for integer types. prettySigned :: Bool -> PrimType -> String -- | A name tagged with some integer. Only the integer is used in -- comparisons, no matter the type of vn. data VName VName :: !Name -> !Int -> VName -- | The abstract (not really) type representing names in the Futhark -- compiler. Strings, being lists of characters, are very slow, -- while Texts are based on byte-arrays. data Name -- | Whether some operator is commutative or not. The Monoid -- instance returns the least commutative of its arguments. data Commutativity Noncommutative :: Commutativity Commutative :: Commutativity -- | The uniqueness attribute of a type. This essentially indicates whether -- or not in-place modifications are acceptable. With respect to -- ordering, Unique is greater than Nonunique. data Uniqueness -- | May have references outside current function. Nonunique :: Uniqueness -- | No references outside current function. Unique :: Uniqueness -- | The name of the default program entry point (main). defaultEntryPoint :: Name -- | Convert a name to the corresponding list of characters. nameToString :: Name -> String -- | Convert a list of characters to the corresponding name. nameFromString :: String -> Name -- | Convert a name to the corresponding Text. nameToText :: Name -> Text -- | Convert a Text to the corresponding name. nameFromText :: Text -> Name -- | A human-readable location string, of the form -- filename:lineno:columnno. This follows the GNU coding -- standards for error messages: -- https://www.gnu.org/prep/standards/html_node/Errors.html -- -- This function assumes that both start and end position is in the same -- file (it is not clear what the alternative would even mean). locStr :: Located a => a -> String -- | Like locStr, but locStrRel prev now prints the -- location now with the file name left out if the same as -- prev. This is useful when printing messages that are all in -- the context of some initially printed location (e.g. the first mention -- contains the file name; the rest just line and column name). locStrRel :: (Located a, Located b) => a -> b -> String -- | Given a list of strings representing entries in the stack trace and -- the index of the frame to highlight, produce a final -- newline-terminated string for showing to the user. This string should -- also be preceded by a newline. The most recent stack frame must come -- first in the list. prettyStacktrace :: Int -> [String] -> String -- | Return the tag contained in the VName. baseTag :: VName -> Int -- | Return the name contained in the VName. baseName :: VName -> Name -- | Return the base Name converted to a string. baseString :: VName -> String -- | Enclose a string in the prefered quotes used in error messages. These -- are picked to not collide with characters permitted in identifiers. quote :: String -> String -- | As quote, but works on prettyprinted representation. pquote :: Doc -> Doc -- | A part of an error message. data ErrorMsgPart a -- | A literal string. ErrorString :: String -> ErrorMsgPart a -- | A run-time integer value. ErrorInt32 :: a -> ErrorMsgPart a -- | A bigger run-time integer value. ErrorInt64 :: a -> ErrorMsgPart a -- | An error message is a list of error parts, which are concatenated to -- form the final message. newtype ErrorMsg a ErrorMsg :: [ErrorMsgPart a] -> ErrorMsg a -- | A subexpression is either a scalar constant or a variable. One -- important property is that evaluation of a subexpression is guaranteed -- to complete in constant time. data SubExp Constant :: PrimValue -> SubExp Var :: VName -> SubExp -- | A string representing a specific non-default memory space. type SpaceId = String -- | The memory space of a block. If DefaultSpace, this is the -- "default" space, whatever that is. The exact meaning of the -- SpaceId depends on the backend used. In GPU kernels, for -- example, this is used to distinguish between constant, global and -- shared memory spaces. In GPU-enabled host code, it is used to -- distinguish between host memory (DefaultSpace) and GPU space. data Space DefaultSpace :: Space Space :: SpaceId -> Space -- | A special kind of memory that is a statically sized array of some -- primitive type. Used for private memory on GPUs. ScalarSpace :: [SubExp] -> PrimType -> Space -- | How many non-constant parts does the error message have, and what is -- their type? errorMsgArgTypes :: ErrorMsg a -> [PrimType] -- | Either return precomputed free names stored in the attribute, or the -- freshly computed names. Relies on lazy evaluation to avoid the work. class FreeIn dec => FreeDec dec precomputed :: FreeDec dec => dec -> FV -> FV -- | A class indicating that we can obtain free variable information from -- values of this type. class FreeIn a freeIn' :: FreeIn a => a -> FV -- | A computation to build a free variable set. data FV -- | A set of names. Note that the Ord instance is a dummy that -- treats everything as EQ if ==, and otherwise LT. data Names -- | Retrieve the data structure underlying the names representation. namesIntMap :: Names -> IntMap VName -- | Does the set of names contain this name? nameIn :: VName -> Names -> Bool -- | Construct a name set from a list. Slow. namesFromList :: [VName] -> Names -- | Turn a name set into a list of names. Slow. namesToList :: Names -> [VName] -- | Construct a name set from a single name. oneName :: VName -> Names -- | The intersection of two name sets. namesIntersection :: Names -> Names -> Names -- | Do the two name sets intersect? namesIntersect :: Names -> Names -> Bool -- | Subtract the latter name set from the former. namesSubtract :: Names -> Names -> Names -- | Map over the names in a set. mapNames :: (VName -> VName) -> Names -> Names -- | Consider a variable to be bound in the given FV computation. fvBind :: Names -> FV -> FV -- | Take note of a variable reference. fvName :: VName -> FV -- | Take note of a set of variable references. fvNames :: Names -> FV -- | Return the set of variable names that are free in the given statements -- and result. Filters away the names that are bound by the statements. freeInStmsAndRes :: (FreeIn (Op lore), FreeIn (LetDec lore), FreeIn (LParamInfo lore), FreeIn (FParamInfo lore), FreeDec (BodyDec lore), FreeDec (ExpDec lore)) => Stms lore -> Result -> FV -- | The free variables of some syntactic construct. freeIn :: FreeIn a => a -> Names -- | The names bound by the bindings immediately in a Body. boundInBody :: Body lore -> Names -- | The names bound by a binding. boundByStm :: Stm lore -> Names -- | The names bound by the bindings. boundByStms :: Stms lore -> Names -- | The names of the lambda parameters plus the index parameter. boundByLambda :: Lambda lore -> [VName] -- | The class of floating-point types that can be used for constructing -- TPrimExps. class NumExp t => FloatExp t -- | Construct a typed expression from a rational. fromRational' :: FloatExp t => Rational -> TPrimExp t v -- | The class of integer types that can be used for constructing -- TPrimExps. class NumExp t => IntExp t -- | The class of numeric types that can be used for constructing -- TPrimExps. class NumExp t -- | Construct a typed expression from an integer. fromInteger' :: NumExp t => Integer -> TPrimExp t v -- | A PrimExp tagged with a phantom type used to provide type-safe -- construction. Does not guarantee that the underlying expression is -- actually type correct. newtype TPrimExp t v TPrimExp :: PrimExp v -> TPrimExp t v [untyped] :: TPrimExp t v -> PrimExp v -- | A primitive expression parametrised over the representation of free -- variables. Note that the Functor, Traversable, and -- Num instances perform automatic (but simple) constant folding. -- -- Note also that the Num instance assumes OverflowUndef -- semantics! data PrimExp v LeafExp :: v -> PrimType -> PrimExp v ValueExp :: PrimValue -> PrimExp v BinOpExp :: BinOp -> PrimExp v -> PrimExp v -> PrimExp v CmpOpExp :: CmpOp -> PrimExp v -> PrimExp v -> PrimExp v UnOpExp :: UnOp -> PrimExp v -> PrimExp v ConvOpExp :: ConvOp -> PrimExp v -> PrimExp v FunExp :: String -> [PrimExp v] -> PrimType -> PrimExp v -- | This expression is of type Int8. isInt8 :: PrimExp v -> TPrimExp Int8 v -- | This expression is of type Int16. isInt16 :: PrimExp v -> TPrimExp Int16 v -- | This expression is of type Int32. isInt32 :: PrimExp v -> TPrimExp Int32 v -- | This expression is of type Int64. isInt64 :: PrimExp v -> TPrimExp Int64 v -- | This is a boolean expression. isBool :: PrimExp v -> TPrimExp Bool v -- | This expression is of type Float. isF32 :: PrimExp v -> TPrimExp Float v -- | This expression is of type Double. isF64 :: PrimExp v -> TPrimExp Double v -- | True if the PrimExp has at least this many nodes. This can be -- much more efficient than comparing with length for large -- PrimExps, as this function is lazy. primExpSizeAtLeast :: Int -> PrimExp v -> Bool -- | Perform quick and dirty constant folding on the top level of a -- PrimExp. This is necessary because we want to consider e.g. equality -- modulo constant folding. constFoldPrimExp :: PrimExp v -> PrimExp v -- | Lifted logical conjunction. (.&&.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 3 .&&. -- | Lifted logical conjunction. (.||.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 2 .||. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<=. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.==.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .==. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>=. -- | Lifted bitwise operators. (.&.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.|.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.^.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Untyped smart constructor for sign extension that does a bit of -- constant folding. sExt :: IntType -> PrimExp v -> PrimExp v -- | Untyped smart constructor for zero extension that does a bit of -- constant folding. zExt :: IntType -> PrimExp v -> PrimExp v -- | Evaluate a PrimExp in the given monad. Invokes fail on -- type errors. evalPrimExp :: (Pretty v, MonadFail m) => (v -> m PrimValue) -> PrimExp v -> m PrimValue -- | The type of values returned by a PrimExp. This function -- returning does not imply that the PrimExp is type-correct. primExpType :: PrimExp v -> PrimType -- | If the given PrimExp is a constant of the wrong integer type, -- coerce it to the given integer type. This is a workaround for an issue -- in the Num instance. coerceIntPrimExp :: IntType -> PrimExp v -> PrimExp v -- | Boolean-valued PrimExps. true :: TPrimExp Bool v -- | Boolean-valued PrimExps. false :: TPrimExp Bool v -- | Boolean negation smart constructor. bNot :: TPrimExp Bool v -> TPrimExp Bool v -- | SMax on 32-bit integers. sMax32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMin on 32-bit integers. sMin32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMax on 64-bit integers. sMax64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | SMin on 64-bit integers. sMin64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | Sign-extend to 32 bit integer. sExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Sign-extend to 64 bit integer. sExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | Zero-extend to 32 bit integer. zExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Zero-extend to 64 bit integer. zExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | 64-bit float minimum. fMin64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v -- | 64-bit float maximum. fMax64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v -- | Produce a mapping from the leaves of the PrimExp to their -- designated types. leafExpTypes :: Ord a => PrimExp a -> Set (a, PrimType) -- | A wrapper supporting a phantom type for indicating what we are -- counting. newtype Count u e Count :: e -> Count u e [unCount] :: Count u e -> e -- | Phantom type for a count of bytes. data Bytes -- | Phantom type for a count of elements. data Elements -- | A function call argument. data Arg ExpArg :: Exp -> Arg MemArg :: VName -> Arg -- | Like Exp, but with a required/known type. type TExp t = TPrimExp t ExpLeaf -- | A side-effect free expression whose execution will produce a single -- primitive value. type Exp = PrimExp ExpLeaf -- | The leaves of an Exp. data ExpLeaf -- | A scalar variable. The type is stored in the LeafExp -- constructor itself. ScalarVar :: VName -> ExpLeaf -- | The size of a primitive type. SizeOf :: PrimType -> ExpLeaf -- | Reading a value from memory. The arguments have the same meaning as -- with Write. Index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> ExpLeaf -- | The volatility of a memory access or variable. Feel free to ignore -- this for backends where it makes no sense (anything but C and similar -- low-level things) data Volatility Volatile :: Volatility Nonvolatile :: Volatility -- | Print the given value to the screen, somehow annotated with the given -- string as a description. If no type/value pair, just print the string. -- This has no semantic meaning, but is used entirely for debugging. Code -- generators are free to ignore this statement. pattern DebugPrint :: () => String -> Maybe Exp -> Code a -- | Function call. The results are written to the provided VName -- variables. pattern Call :: () => [VName] -> Name -> [Arg] -> Code a -- | Must be in same space. pattern SetMem :: () => VName -> VName -> Space -> Code a -- | Set a scalar variable. pattern SetScalar :: () => VName -> Exp -> Code a -- | Create an array containing the given values. The lifetime of the array -- will be the entire application. This is mostly used for constant -- arrays, but also for some bookkeeping data, like the synchronisation -- counts used to implement reduction. pattern DeclareArray :: () => VName -> Space -> PrimType -> ArrayContents -> Code a -- | Declare a scalar variable with an initially undefined value. pattern DeclareScalar :: () => VName -> Volatility -> PrimType -> Code a -- | Declare a memory block variable that will point to memory in the given -- memory space. Note that this is distinct from allocation. The memory -- block must be the target of either an Allocate or a -- SetMem before it can be used for reading or writing. pattern DeclareMem :: () => VName -> Space -> Code a -- | Statement composition. Crucial for the Semigroup instance. pattern (:>>:) :: () => Code a -> Code a -> Code a -- | Assert that something must be true. Should it turn out not to be true, -- then report a failure along with the given error message. pattern Assert :: () => Exp -> ErrorMsg Exp -> (SrcLoc, [SrcLoc]) -> Code a -- | Destination, offset in destination, destination space, source, offset -- in source, offset space, number of bytes. pattern Copy :: () => VName -> Count Bytes (TExp Int64) -> Space -> VName -> Count Bytes (TExp Int64) -> Space -> Count Bytes (TExp Int64) -> Code a -- | Memory space must match the corresponding DeclareMem. pattern Allocate :: () => VName -> Count Bytes (TExp Int64) -> Space -> Code a -- | No-op. Crucial for the Monoid instance. pattern Skip :: () => Code a -- | A for-loop iterating the given number of times. The loop parameter -- starts counting from zero and will have the same (integer) type as the -- bound. The bound is evaluated just once, before the loop is entered. pattern For :: () => VName -> Exp -> Code a -> Code a -- | While loop. The conditional is (of course) re-evaluated before every -- iteration of the loop. pattern While :: () => TExp Bool -> Code a -> Code a -- | Indicate that some memory block will never again be referenced via the -- indicated variable. However, it may still be accessed through aliases. -- It is only safe to actually deallocate the memory block if this is the -- last reference. There is no guarantee that all memory blocks will be -- freed with this statement. Backends are free to ignore it entirely. pattern Free :: () => VName -> Space -> Code a -- | Has the same semantics as the contained code, but the comment should -- show up in generated code for ease of inspection. pattern Comment :: () => String -> Code a -> Code a -- | Write mem i t space vol v writes the value v to -- mem offset by i elements of type t. The -- Space argument is the memory space of mem (technically -- redundant, but convenient). Note that reading is done with an -- Exp (Index). pattern Write :: () => VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp -> Code a -- | Conditional execution. pattern If :: () => TExp Bool -> Code a -> Code a -> Code a -- | Perform an extensible operation. pattern Op :: () => a -> Code a -- | The contents of a statically declared constant array. Such arrays are -- always unidimensional, and reshaped if necessary in the code that uses -- them. data ArrayContents -- | Precisely these values. ArrayValues :: [PrimValue] -> ArrayContents -- | This many zeroes. ArrayZeros :: Int -> ArrayContents -- | A imperative function, containing the body as well as its low-level -- inputs and outputs, as well as its high-level arguments and results. -- The latter are only used if the function is an entry point. data FunctionT a -- | ^ An externally visible value. This can be an opaque value (covering -- several physical internal values), or a single value that can be used -- externally. data ExternalValue -- | The string is a human-readable description with no other semantics. OpaqueValue :: String -> [ValueDesc] -> ExternalValue TransparentValue :: ValueDesc -> ExternalValue -- | A description of an externally meaningful value. data ValueDesc -- | An array with memory block, memory block size, memory space, element -- type, signedness of element type (if applicable), and shape. ArrayValue :: VName -> Space -> PrimType -> Signedness -> [DimSize] -> ValueDesc -- | A scalar value with signedness if applicable. ScalarValue :: PrimType -> Signedness -> VName -> ValueDesc -- | Since the core language does not care for signedness, but the source -- language does, entry point input/output information has metadata for -- integer types (and arrays containing these) that indicate whether they -- are really unsigned integers. data Signedness TypeUnsigned :: Signedness TypeDirect :: Signedness -- | A collection of imperative constants. data Constants a Constants :: [Param] -> Code a -> Constants a -- | The constants that are made available to the functions. [constsDecl] :: Constants a -> [Param] -- | Setting the value of the constants. Note that this must not contain -- declarations of the names defined in constsDecl. [constsInit] :: Constants a -> Code a -- | A collection of imperative functions. newtype Functions a Functions :: [(Name, Function a)] -> Functions a -- | A collection of imperative functions and constants. data Definitions a Definitions :: Constants a -> Functions a -> Definitions a [defConsts] :: Definitions a -> Constants a [defFuns] :: Definitions a -> Functions a -- | An ImpCode function parameter. data Param MemParam :: VName -> Space -> Param ScalarParam :: VName -> PrimType -> Param -- | The size of an array. type DimSize = SubExp -- | The size of a memory block. type MemSize = SubExp -- | The name of a parameter. paramName :: Param -> VName -- | Find those memory blocks that are used only lexically. That is, are -- not used as the source or target of a SetMem, or are the result -- of the function, nor passed as arguments to other functions. This is -- interesting because such memory blocks do not need reference counting, -- but can be managed in a purely stack-like fashion. -- -- We do not look inside any Ops. We assume that no Op is -- going to SetMem a memory block declared outside it. lexicalMemoryUsage :: Function a -> Map VName Space -- | The set of functions that are called by this code. Assumes there are -- no function calls in Ops. calledFuncs :: Code a -> Set Name -- | This expression counts elements. elements :: a -> Count Elements a -- | This expression counts bytes. bytes :: a -> Count Bytes a -- | Convert a count of elements into a count of bytes, given the -- per-element size. withElemType :: Count Elements (TExp Int64) -> PrimType -> Count Bytes (TExp Int64) -- | Turn a VName into a ScalarVar. var :: VName -> PrimType -> Exp -- | Turn a VName into a Int32 ScalarVar. vi32 :: VName -> TExp Int32 -- | Turn a VName into a Int64 ScalarVar. vi64 :: VName -> TExp Int64 -- | Concise wrapper for using Index. index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp declaredIn :: Code a -> Names instance GHC.Show.Show Futhark.CodeGen.ImpCode.OpenCL.KernelArg instance GHC.Show.Show Futhark.CodeGen.ImpCode.OpenCL.MayFail instance GHC.Show.Show Futhark.CodeGen.ImpCode.OpenCL.KernelSafety instance GHC.Classes.Ord Futhark.CodeGen.ImpCode.OpenCL.KernelSafety instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.OpenCL.KernelSafety instance GHC.Show.Show Futhark.CodeGen.ImpCode.OpenCL.OpenCL instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.OpenCL.KernelTarget instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.OpenCL.OpenCL -- | Multicore imperative code. module Futhark.CodeGen.ImpCode.Multicore -- | An imperative program. type Program = Functions Multicore -- | An imperative function. type Function = Function Multicore -- | A imperative function, containing the body as well as its low-level -- inputs and outputs, as well as its high-level arguments and results. -- The latter are only used if the function is an entry point. data FunctionT a Function :: Bool -> [Param] -> [Param] -> Code a -> [ExternalValue] -> [ExternalValue] -> FunctionT a -- | A piece of imperative code, with multicore operations inside. type Code = Code Multicore -- | A multicore operation. data Multicore Segop :: String -> [Param] -> ParallelTask -> Maybe ParallelTask -> [Param] -> SchedulerInfo -> Multicore ParLoop :: String -> VName -> Code -> Code -> Code -> [Param] -> VName -> Multicore Atomic :: AtomicOp -> Multicore -- | Whether the Scheduler should schedule the tasks as Dynamic or it is -- restainted to Static data Scheduling Dynamic :: Scheduling Static :: Scheduling data SchedulerInfo SchedulerInfo :: VName -> Exp -> Scheduling -> SchedulerInfo [nsubtasks] :: SchedulerInfo -> VName [iterations] :: SchedulerInfo -> Exp [scheduling] :: SchedulerInfo -> Scheduling -- | Atomic operations return the value stored before the update. This old -- value is stored in the first VName. The second VName is -- the memory block to update. The Exp is the new value. data AtomicOp AtomicAdd :: IntType -> VName -> VName -> Count Elements (TExp Int32) -> Exp -> AtomicOp AtomicSub :: IntType -> VName -> VName -> Count Elements (TExp Int32) -> Exp -> AtomicOp AtomicAnd :: IntType -> VName -> VName -> Count Elements (TExp Int32) -> Exp -> AtomicOp AtomicOr :: IntType -> VName -> VName -> Count Elements (TExp Int32) -> Exp -> AtomicOp AtomicXor :: IntType -> VName -> VName -> Count Elements (TExp Int32) -> Exp -> AtomicOp AtomicXchg :: PrimType -> VName -> VName -> Count Elements (TExp Int32) -> Exp -> AtomicOp AtomicCmpXchg :: PrimType -> VName -> VName -> Count Elements (TExp Int32) -> VName -> Exp -> AtomicOp data ParallelTask ParallelTask :: Code -> VName -> ParallelTask [task_code] :: ParallelTask -> Code [flatTid] :: ParallelTask -> VName -- | 8-bit signed integer type data Int8 -- | 16-bit signed integer type data Int16 -- | 32-bit signed integer type data Int32 -- | 64-bit signed integer type data Int64 -- | 8-bit unsigned integer type data Word8 -- | 16-bit unsigned integer type data Word16 -- | 32-bit unsigned integer type data Word32 -- | 64-bit unsigned integer type data Word64 -- | The SrcLoc of a Located value. srclocOf :: Located a => a -> SrcLoc -- | Location type, consisting of a beginning position and an end position. data Loc -- | Source location type. Source location are all equal, which allows AST -- nodes to be compared modulo location information. data SrcLoc -- | Located values have a location. class Located a locOf :: Located a => a -> Loc locOfList :: Located a => [a] -> Loc -- | Prettyprint a value, wrapped to 80 characters. pretty :: Pretty a => a -> String -- | Conversion operators try to generalise the from t0 x to t1 -- instructions from LLVM. data ConvOp -- | Zero-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. ZExt :: IntType -> IntType -> ConvOp -- | Sign-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. SExt :: IntType -> IntType -> ConvOp -- | Convert value of the former floating-point type to the latter. If the -- new type is smaller, the result is a truncation. FPConv :: FloatType -> FloatType -> ConvOp -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). FPToUI :: FloatType -> IntType -> ConvOp -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). FPToSI :: FloatType -> IntType -> ConvOp -- | Convert an unsigned integer to a floating-point value. UIToFP :: IntType -> FloatType -> ConvOp -- | Convert a signed integer to a floating-point value. SIToFP :: IntType -> FloatType -> ConvOp -- | Convert an integer to a boolean value. Zero becomes false; anything -- else is true. IToB :: IntType -> ConvOp -- | Convert a boolean to an integer. True is converted to 1 and False to -- 0. BToI :: IntType -> ConvOp -- | Comparison operators are like BinOps, but they always return a -- boolean value. The somewhat ugly constructor names are straight out of -- LLVM. data CmpOp -- | All types equality. CmpEq :: PrimType -> CmpOp -- | Unsigned less than. CmpUlt :: IntType -> CmpOp -- | Unsigned less than or equal. CmpUle :: IntType -> CmpOp -- | Signed less than. CmpSlt :: IntType -> CmpOp -- | Signed less than or equal. CmpSle :: IntType -> CmpOp -- | Floating-point less than. FCmpLt :: FloatType -> CmpOp -- | Floating-point less than or equal. FCmpLe :: FloatType -> CmpOp -- | Boolean less than. CmpLlt :: CmpOp -- | Boolean less than or equal. CmpLle :: CmpOp -- | Binary operators. These correspond closely to the binary operators in -- LLVM. Most are parametrised by their expected input and output types. data BinOp -- | Integer addition. Add :: IntType -> Overflow -> BinOp -- | Floating-point addition. FAdd :: FloatType -> BinOp -- | Integer subtraction. Sub :: IntType -> Overflow -> BinOp -- | Floating-point subtraction. FSub :: FloatType -> BinOp -- | Integer multiplication. Mul :: IntType -> Overflow -> BinOp -- | Floating-point multiplication. FMul :: FloatType -> BinOp -- | Unsigned integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. UDiv :: IntType -> Safety -> BinOp -- | Unsigned integer division. Rounds towards positive infinity. UDivUp :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. SDiv :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards positive infinity. SDivUp :: IntType -> Safety -> BinOp -- | Floating-point division. FDiv :: FloatType -> BinOp -- | Floating-point modulus. FMod :: FloatType -> BinOp -- | Unsigned integer modulus; the countepart to UDiv. UMod :: IntType -> Safety -> BinOp -- | Signed integer modulus; the countepart to SDiv. SMod :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- sdiv instruction in LLVM and integer division in C. SQuot :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- srem instruction in LLVM and integer modulo in C. SRem :: IntType -> Safety -> BinOp -- | Returns the smallest of two signed integers. SMin :: IntType -> BinOp -- | Returns the smallest of two unsigned integers. UMin :: IntType -> BinOp -- | Returns the smallest of two floating-point numbers. FMin :: FloatType -> BinOp -- | Returns the greatest of two signed integers. SMax :: IntType -> BinOp -- | Returns the greatest of two unsigned integers. UMax :: IntType -> BinOp -- | Returns the greatest of two floating-point numbers. FMax :: FloatType -> BinOp -- | Left-shift. Shl :: IntType -> BinOp -- | Logical right-shift, zero-extended. LShr :: IntType -> BinOp -- | Arithmetic right-shift, sign-extended. AShr :: IntType -> BinOp -- | Bitwise and. And :: IntType -> BinOp -- | Bitwise or. Or :: IntType -> BinOp -- | Bitwise exclusive-or. Xor :: IntType -> BinOp -- | Integer exponentiation. Pow :: IntType -> BinOp -- | Floating-point exponentiation. FPow :: FloatType -> BinOp -- | Boolean and - not short-circuiting. LogAnd :: BinOp -- | Boolean or - not short-circuiting. LogOr :: BinOp -- | Whether something is safe or unsafe (mostly function calls, and in the -- context of whether operations are dynamically checked). When we inline -- an Unsafe function, we remove all safety checks in its body. -- The Ord instance picks Unsafe as being less than -- Safe. -- -- For operations like integer division, a safe division will not explode -- the computer in case of division by zero, but instead return some -- unspecified value. This always involves a run-time check, so generally -- the unsafe variant is what the compiler will insert, but guarded by an -- explicit assertion elsewhere. Safe operations are useful when the -- optimiser wants to move e.g. a division to a location where the -- divisor may be zero, but where the result will only be used when it is -- non-zero (so it doesn't matter what result is provided with a zero -- divisor, as long as the program keeps running). data Safety Unsafe :: Safety Safe :: Safety -- | What to do in case of arithmetic overflow. Futhark's semantics are -- that overflow does wraparound, but for generated code (like address -- arithmetic), it can be beneficial for overflow to be undefined -- behaviour, as it allows better optimisation of things such as GPU -- kernels. -- -- Note that all values of this type are considered equal for Eq -- and Ord. data Overflow OverflowWrap :: Overflow OverflowUndef :: Overflow -- | Various unary operators. It is a bit ad-hoc what is a unary operator -- and what is a built-in function. Perhaps these should all go away -- eventually. data UnOp -- | E.g., ! True == False. Not :: UnOp -- | E.g., ~(~1) = 1. Complement :: IntType -> UnOp -- | abs(-2) = 2. Abs :: IntType -> UnOp -- | fabs(-2.0) = 2.0. FAbs :: FloatType -> UnOp -- | Signed sign function: ssignum(-2) = -1. SSignum :: IntType -> UnOp -- | Unsigned sign function: usignum(2) = 1. USignum :: IntType -> UnOp -- | Non-array values. data PrimValue IntValue :: !IntValue -> PrimValue FloatValue :: !FloatValue -> PrimValue BoolValue :: !Bool -> PrimValue -- | The only value of type cert. Checked :: PrimValue -- | A floating-point value. data FloatValue Float32Value :: !Float -> FloatValue Float64Value :: !Double -> FloatValue -- | An integer value. data IntValue Int8Value :: !Int8 -> IntValue Int16Value :: !Int16 -> IntValue Int32Value :: !Int32 -> IntValue Int64Value :: !Int64 -> IntValue -- | Low-level primitive types. data PrimType IntType :: IntType -> PrimType FloatType :: FloatType -> PrimType Bool :: PrimType Cert :: PrimType -- | A floating point type. data FloatType Float32 :: FloatType Float64 :: FloatType -- | An integer type, ordered by size. Note that signedness is not a -- property of the type, but a property of the operations performed on -- values of these types. data IntType Int8 :: IntType Int16 :: IntType Int32 :: IntType Int64 :: IntType -- | A list of all integer types. allIntTypes :: [IntType] -- | A list of all floating-point types. allFloatTypes :: [FloatType] -- | A list of all primitive types. allPrimTypes :: [PrimType] -- | Create an IntValue from a type and an Integer. intValue :: Integral int => IntType -> int -> IntValue -- | The type of an integer value. intValueType :: IntValue -> IntType -- | Convert an IntValue to any Integral type. valueIntegral :: Integral int => IntValue -> int -- | Create a FloatValue from a type and a Rational. floatValue :: Real num => FloatType -> num -> FloatValue -- | The type of a floating-point value. floatValueType :: FloatValue -> FloatType -- | The type of a basic value. primValueType :: PrimValue -> PrimType -- | A "blank" value of the given primitive type - this is zero, or -- whatever is close to it. Don't depend on this value, but use it for -- e.g. creating arrays to be populated by do-loops. blankPrimValue :: PrimType -> PrimValue -- | A list of all unary operators for all types. allUnOps :: [UnOp] -- | A list of all binary operators for all types. allBinOps :: [BinOp] -- | A list of all comparison operators for all types. allCmpOps :: [CmpOp] -- | A list of all conversion operators for all types. allConvOps :: [ConvOp] -- | Apply an UnOp to an operand. Returns Nothing if the -- application is mistyped. doUnOp :: UnOp -> PrimValue -> Maybe PrimValue -- | E.g., ~(~1) = 1. doComplement :: IntValue -> IntValue -- | abs(-2) = 2. doAbs :: IntValue -> IntValue -- | abs(-2.0) = 2.0. doFAbs :: FloatValue -> FloatValue -- | ssignum(-2) = -1. doSSignum :: IntValue -> IntValue -- | usignum(-2) = -1. doUSignum :: IntValue -> IntValue -- | Apply a BinOp to an operand. Returns Nothing if the -- application is mistyped, or outside the domain (e.g. division by -- zero). doBinOp :: BinOp -> PrimValue -> PrimValue -> Maybe PrimValue -- | Integer addition. doAdd :: IntValue -> IntValue -> IntValue -- | Integer multiplication. doMul :: IntValue -> IntValue -> IntValue -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. doSDiv :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer modulus; the countepart to SDiv. doSMod :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer exponentatation. doPow :: IntValue -> IntValue -> Maybe IntValue -- | Apply a ConvOp to an operand. Returns Nothing if the -- application is mistyped. doConvOp :: ConvOp -> PrimValue -> Maybe PrimValue -- | Zero-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doZExt :: IntValue -> IntType -> IntValue -- | Sign-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doSExt :: IntValue -> IntType -> IntValue -- | Convert the former floating-point type to the latter. doFPConv :: FloatValue -> FloatType -> FloatValue -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). doFPToUI :: FloatValue -> IntType -> IntValue -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). doFPToSI :: FloatValue -> IntType -> IntValue -- | Convert an unsigned integer to a floating-point value. doUIToFP :: IntValue -> FloatType -> FloatValue -- | Convert a signed integer to a floating-point value. doSIToFP :: IntValue -> FloatType -> FloatValue -- | Apply a CmpOp to an operand. Returns Nothing if the -- application is mistyped. doCmpOp :: CmpOp -> PrimValue -> PrimValue -> Maybe Bool -- | Compare any two primtive values for exact equality. doCmpEq :: PrimValue -> PrimValue -> Bool -- | Unsigned less than. doCmpUlt :: IntValue -> IntValue -> Bool -- | Unsigned less than or equal. doCmpUle :: IntValue -> IntValue -> Bool -- | Signed less than. doCmpSlt :: IntValue -> IntValue -> Bool -- | Signed less than or equal. doCmpSle :: IntValue -> IntValue -> Bool -- | Floating-point less than. doFCmpLt :: FloatValue -> FloatValue -> Bool -- | Floating-point less than or equal. doFCmpLe :: FloatValue -> FloatValue -> Bool -- | Translate an IntValue to Word64. This is guaranteed to -- fit. intToWord64 :: IntValue -> Word64 -- | Translate an IntValue to Int64. This is guaranteed to -- fit. intToInt64 :: IntValue -> Int64 -- | The result type of a binary operator. binOpType :: BinOp -> PrimType -- | The operand types of a comparison operator. cmpOpType :: CmpOp -> PrimType -- | The operand and result type of a unary operator. unOpType :: UnOp -> PrimType -- | The input and output types of a conversion operator. convOpType :: ConvOp -> (PrimType, PrimType) -- | A mapping from names of primitive functions to their parameter types, -- their result type, and a function for evaluating them. primFuns :: Map String ([PrimType], PrimType, [PrimValue] -> Maybe PrimValue) -- | Is the given value kind of zero? zeroIsh :: PrimValue -> Bool -- | Is the given value kind of one? oneIsh :: PrimValue -> Bool -- | Is the given value kind of negative? negativeIsh :: PrimValue -> Bool -- | Is the given integer value kind of zero? zeroIshInt :: IntValue -> Bool -- | Is the given integer value kind of one? oneIshInt :: IntValue -> Bool -- | The size of a value of a given primitive type in bites. primBitSize :: PrimType -> Int -- | The size of a value of a given primitive type in eight-bit bytes. primByteSize :: Num a => PrimType -> a -- | The size of a value of a given integer type in eight-bit bytes. intByteSize :: Num a => IntType -> a -- | The size of a value of a given floating-point type in eight-bit bytes. floatByteSize :: Num a => FloatType -> a -- | True if the given binary operator is commutative. commutativeBinOp :: BinOp -> Bool -- | The human-readable name for a ConvOp. This is used to expose -- the ConvOp in the intrinsics module of a Futhark -- program. convOpFun :: ConvOp -> String -- | True if signed. Only makes a difference for integer types. prettySigned :: Bool -> PrimType -> String -- | A name tagged with some integer. Only the integer is used in -- comparisons, no matter the type of vn. data VName VName :: !Name -> !Int -> VName -- | The abstract (not really) type representing names in the Futhark -- compiler. Strings, being lists of characters, are very slow, -- while Texts are based on byte-arrays. data Name -- | Whether some operator is commutative or not. The Monoid -- instance returns the least commutative of its arguments. data Commutativity Noncommutative :: Commutativity Commutative :: Commutativity -- | The uniqueness attribute of a type. This essentially indicates whether -- or not in-place modifications are acceptable. With respect to -- ordering, Unique is greater than Nonunique. data Uniqueness -- | May have references outside current function. Nonunique :: Uniqueness -- | No references outside current function. Unique :: Uniqueness -- | The name of the default program entry point (main). defaultEntryPoint :: Name -- | Convert a name to the corresponding list of characters. nameToString :: Name -> String -- | Convert a list of characters to the corresponding name. nameFromString :: String -> Name -- | Convert a name to the corresponding Text. nameToText :: Name -> Text -- | Convert a Text to the corresponding name. nameFromText :: Text -> Name -- | A human-readable location string, of the form -- filename:lineno:columnno. This follows the GNU coding -- standards for error messages: -- https://www.gnu.org/prep/standards/html_node/Errors.html -- -- This function assumes that both start and end position is in the same -- file (it is not clear what the alternative would even mean). locStr :: Located a => a -> String -- | Like locStr, but locStrRel prev now prints the -- location now with the file name left out if the same as -- prev. This is useful when printing messages that are all in -- the context of some initially printed location (e.g. the first mention -- contains the file name; the rest just line and column name). locStrRel :: (Located a, Located b) => a -> b -> String -- | Given a list of strings representing entries in the stack trace and -- the index of the frame to highlight, produce a final -- newline-terminated string for showing to the user. This string should -- also be preceded by a newline. The most recent stack frame must come -- first in the list. prettyStacktrace :: Int -> [String] -> String -- | Return the tag contained in the VName. baseTag :: VName -> Int -- | Return the name contained in the VName. baseName :: VName -> Name -- | Return the base Name converted to a string. baseString :: VName -> String -- | Enclose a string in the prefered quotes used in error messages. These -- are picked to not collide with characters permitted in identifiers. quote :: String -> String -- | As quote, but works on prettyprinted representation. pquote :: Doc -> Doc -- | A part of an error message. data ErrorMsgPart a -- | A literal string. ErrorString :: String -> ErrorMsgPart a -- | A run-time integer value. ErrorInt32 :: a -> ErrorMsgPart a -- | A bigger run-time integer value. ErrorInt64 :: a -> ErrorMsgPart a -- | An error message is a list of error parts, which are concatenated to -- form the final message. newtype ErrorMsg a ErrorMsg :: [ErrorMsgPart a] -> ErrorMsg a -- | A subexpression is either a scalar constant or a variable. One -- important property is that evaluation of a subexpression is guaranteed -- to complete in constant time. data SubExp Constant :: PrimValue -> SubExp Var :: VName -> SubExp -- | A string representing a specific non-default memory space. type SpaceId = String -- | The memory space of a block. If DefaultSpace, this is the -- "default" space, whatever that is. The exact meaning of the -- SpaceId depends on the backend used. In GPU kernels, for -- example, this is used to distinguish between constant, global and -- shared memory spaces. In GPU-enabled host code, it is used to -- distinguish between host memory (DefaultSpace) and GPU space. data Space DefaultSpace :: Space Space :: SpaceId -> Space -- | A special kind of memory that is a statically sized array of some -- primitive type. Used for private memory on GPUs. ScalarSpace :: [SubExp] -> PrimType -> Space -- | How many non-constant parts does the error message have, and what is -- their type? errorMsgArgTypes :: ErrorMsg a -> [PrimType] -- | Either return precomputed free names stored in the attribute, or the -- freshly computed names. Relies on lazy evaluation to avoid the work. class FreeIn dec => FreeDec dec precomputed :: FreeDec dec => dec -> FV -> FV -- | A class indicating that we can obtain free variable information from -- values of this type. class FreeIn a freeIn' :: FreeIn a => a -> FV -- | A computation to build a free variable set. data FV -- | A set of names. Note that the Ord instance is a dummy that -- treats everything as EQ if ==, and otherwise LT. data Names -- | Retrieve the data structure underlying the names representation. namesIntMap :: Names -> IntMap VName -- | Does the set of names contain this name? nameIn :: VName -> Names -> Bool -- | Construct a name set from a list. Slow. namesFromList :: [VName] -> Names -- | Turn a name set into a list of names. Slow. namesToList :: Names -> [VName] -- | Construct a name set from a single name. oneName :: VName -> Names -- | The intersection of two name sets. namesIntersection :: Names -> Names -> Names -- | Do the two name sets intersect? namesIntersect :: Names -> Names -> Bool -- | Subtract the latter name set from the former. namesSubtract :: Names -> Names -> Names -- | Map over the names in a set. mapNames :: (VName -> VName) -> Names -> Names -- | Consider a variable to be bound in the given FV computation. fvBind :: Names -> FV -> FV -- | Take note of a variable reference. fvName :: VName -> FV -- | Take note of a set of variable references. fvNames :: Names -> FV -- | Return the set of variable names that are free in the given statements -- and result. Filters away the names that are bound by the statements. freeInStmsAndRes :: (FreeIn (Op lore), FreeIn (LetDec lore), FreeIn (LParamInfo lore), FreeIn (FParamInfo lore), FreeDec (BodyDec lore), FreeDec (ExpDec lore)) => Stms lore -> Result -> FV -- | The free variables of some syntactic construct. freeIn :: FreeIn a => a -> Names -- | The names bound by the bindings immediately in a Body. boundInBody :: Body lore -> Names -- | The names bound by a binding. boundByStm :: Stm lore -> Names -- | The names bound by the bindings. boundByStms :: Stms lore -> Names -- | The names of the lambda parameters plus the index parameter. boundByLambda :: Lambda lore -> [VName] -- | The class of floating-point types that can be used for constructing -- TPrimExps. class NumExp t => FloatExp t -- | Construct a typed expression from a rational. fromRational' :: FloatExp t => Rational -> TPrimExp t v -- | The class of integer types that can be used for constructing -- TPrimExps. class NumExp t => IntExp t -- | The class of numeric types that can be used for constructing -- TPrimExps. class NumExp t -- | Construct a typed expression from an integer. fromInteger' :: NumExp t => Integer -> TPrimExp t v -- | A PrimExp tagged with a phantom type used to provide type-safe -- construction. Does not guarantee that the underlying expression is -- actually type correct. newtype TPrimExp t v TPrimExp :: PrimExp v -> TPrimExp t v [untyped] :: TPrimExp t v -> PrimExp v -- | A primitive expression parametrised over the representation of free -- variables. Note that the Functor, Traversable, and -- Num instances perform automatic (but simple) constant folding. -- -- Note also that the Num instance assumes OverflowUndef -- semantics! data PrimExp v LeafExp :: v -> PrimType -> PrimExp v ValueExp :: PrimValue -> PrimExp v BinOpExp :: BinOp -> PrimExp v -> PrimExp v -> PrimExp v CmpOpExp :: CmpOp -> PrimExp v -> PrimExp v -> PrimExp v UnOpExp :: UnOp -> PrimExp v -> PrimExp v ConvOpExp :: ConvOp -> PrimExp v -> PrimExp v FunExp :: String -> [PrimExp v] -> PrimType -> PrimExp v -- | This expression is of type Int8. isInt8 :: PrimExp v -> TPrimExp Int8 v -- | This expression is of type Int16. isInt16 :: PrimExp v -> TPrimExp Int16 v -- | This expression is of type Int32. isInt32 :: PrimExp v -> TPrimExp Int32 v -- | This expression is of type Int64. isInt64 :: PrimExp v -> TPrimExp Int64 v -- | This is a boolean expression. isBool :: PrimExp v -> TPrimExp Bool v -- | This expression is of type Float. isF32 :: PrimExp v -> TPrimExp Float v -- | This expression is of type Double. isF64 :: PrimExp v -> TPrimExp Double v -- | True if the PrimExp has at least this many nodes. This can be -- much more efficient than comparing with length for large -- PrimExps, as this function is lazy. primExpSizeAtLeast :: Int -> PrimExp v -> Bool -- | Perform quick and dirty constant folding on the top level of a -- PrimExp. This is necessary because we want to consider e.g. equality -- modulo constant folding. constFoldPrimExp :: PrimExp v -> PrimExp v -- | Lifted logical conjunction. (.&&.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 3 .&&. -- | Lifted logical conjunction. (.||.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 2 .||. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<=. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.==.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .==. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>=. -- | Lifted bitwise operators. (.&.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.|.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.^.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Untyped smart constructor for sign extension that does a bit of -- constant folding. sExt :: IntType -> PrimExp v -> PrimExp v -- | Untyped smart constructor for zero extension that does a bit of -- constant folding. zExt :: IntType -> PrimExp v -> PrimExp v -- | Evaluate a PrimExp in the given monad. Invokes fail on -- type errors. evalPrimExp :: (Pretty v, MonadFail m) => (v -> m PrimValue) -> PrimExp v -> m PrimValue -- | The type of values returned by a PrimExp. This function -- returning does not imply that the PrimExp is type-correct. primExpType :: PrimExp v -> PrimType -- | If the given PrimExp is a constant of the wrong integer type, -- coerce it to the given integer type. This is a workaround for an issue -- in the Num instance. coerceIntPrimExp :: IntType -> PrimExp v -> PrimExp v -- | Boolean-valued PrimExps. true :: TPrimExp Bool v -- | Boolean-valued PrimExps. false :: TPrimExp Bool v -- | Boolean negation smart constructor. bNot :: TPrimExp Bool v -> TPrimExp Bool v -- | SMax on 32-bit integers. sMax32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMin on 32-bit integers. sMin32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMax on 64-bit integers. sMax64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | SMin on 64-bit integers. sMin64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | Sign-extend to 32 bit integer. sExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Sign-extend to 64 bit integer. sExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | Zero-extend to 32 bit integer. zExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Zero-extend to 64 bit integer. zExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | 64-bit float minimum. fMin64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v -- | 64-bit float maximum. fMax64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v -- | Produce a mapping from the leaves of the PrimExp to their -- designated types. leafExpTypes :: Ord a => PrimExp a -> Set (a, PrimType) -- | A wrapper supporting a phantom type for indicating what we are -- counting. newtype Count u e Count :: e -> Count u e [unCount] :: Count u e -> e -- | Phantom type for a count of bytes. data Bytes -- | Phantom type for a count of elements. data Elements -- | A function call argument. data Arg ExpArg :: Exp -> Arg MemArg :: VName -> Arg -- | Like Exp, but with a required/known type. type TExp t = TPrimExp t ExpLeaf -- | A side-effect free expression whose execution will produce a single -- primitive value. type Exp = PrimExp ExpLeaf -- | The leaves of an Exp. data ExpLeaf -- | A scalar variable. The type is stored in the LeafExp -- constructor itself. ScalarVar :: VName -> ExpLeaf -- | The size of a primitive type. SizeOf :: PrimType -> ExpLeaf -- | Reading a value from memory. The arguments have the same meaning as -- with Write. Index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> ExpLeaf -- | The volatility of a memory access or variable. Feel free to ignore -- this for backends where it makes no sense (anything but C and similar -- low-level things) data Volatility Volatile :: Volatility Nonvolatile :: Volatility -- | Print the given value to the screen, somehow annotated with the given -- string as a description. If no type/value pair, just print the string. -- This has no semantic meaning, but is used entirely for debugging. Code -- generators are free to ignore this statement. pattern DebugPrint :: () => String -> Maybe Exp -> Code a -- | Function call. The results are written to the provided VName -- variables. pattern Call :: () => [VName] -> Name -> [Arg] -> Code a -- | Must be in same space. pattern SetMem :: () => VName -> VName -> Space -> Code a -- | Set a scalar variable. pattern SetScalar :: () => VName -> Exp -> Code a -- | Create an array containing the given values. The lifetime of the array -- will be the entire application. This is mostly used for constant -- arrays, but also for some bookkeeping data, like the synchronisation -- counts used to implement reduction. pattern DeclareArray :: () => VName -> Space -> PrimType -> ArrayContents -> Code a -- | Declare a scalar variable with an initially undefined value. pattern DeclareScalar :: () => VName -> Volatility -> PrimType -> Code a -- | Declare a memory block variable that will point to memory in the given -- memory space. Note that this is distinct from allocation. The memory -- block must be the target of either an Allocate or a -- SetMem before it can be used for reading or writing. pattern DeclareMem :: () => VName -> Space -> Code a -- | Statement composition. Crucial for the Semigroup instance. pattern (:>>:) :: () => Code a -> Code a -> Code a -- | Assert that something must be true. Should it turn out not to be true, -- then report a failure along with the given error message. pattern Assert :: () => Exp -> ErrorMsg Exp -> (SrcLoc, [SrcLoc]) -> Code a -- | Destination, offset in destination, destination space, source, offset -- in source, offset space, number of bytes. pattern Copy :: () => VName -> Count Bytes (TExp Int64) -> Space -> VName -> Count Bytes (TExp Int64) -> Space -> Count Bytes (TExp Int64) -> Code a -- | Memory space must match the corresponding DeclareMem. pattern Allocate :: () => VName -> Count Bytes (TExp Int64) -> Space -> Code a -- | No-op. Crucial for the Monoid instance. pattern Skip :: () => Code a -- | A for-loop iterating the given number of times. The loop parameter -- starts counting from zero and will have the same (integer) type as the -- bound. The bound is evaluated just once, before the loop is entered. pattern For :: () => VName -> Exp -> Code a -> Code a -- | While loop. The conditional is (of course) re-evaluated before every -- iteration of the loop. pattern While :: () => TExp Bool -> Code a -> Code a -- | Indicate that some memory block will never again be referenced via the -- indicated variable. However, it may still be accessed through aliases. -- It is only safe to actually deallocate the memory block if this is the -- last reference. There is no guarantee that all memory blocks will be -- freed with this statement. Backends are free to ignore it entirely. pattern Free :: () => VName -> Space -> Code a -- | Has the same semantics as the contained code, but the comment should -- show up in generated code for ease of inspection. pattern Comment :: () => String -> Code a -> Code a -- | Write mem i t space vol v writes the value v to -- mem offset by i elements of type t. The -- Space argument is the memory space of mem (technically -- redundant, but convenient). Note that reading is done with an -- Exp (Index). pattern Write :: () => VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp -> Code a -- | Conditional execution. pattern If :: () => TExp Bool -> Code a -> Code a -> Code a -- | Perform an extensible operation. pattern Op :: () => a -> Code a -- | The contents of a statically declared constant array. Such arrays are -- always unidimensional, and reshaped if necessary in the code that uses -- them. data ArrayContents -- | Precisely these values. ArrayValues :: [PrimValue] -> ArrayContents -- | This many zeroes. ArrayZeros :: Int -> ArrayContents -- | A imperative function, containing the body as well as its low-level -- inputs and outputs, as well as its high-level arguments and results. -- The latter are only used if the function is an entry point. data FunctionT a -- | ^ An externally visible value. This can be an opaque value (covering -- several physical internal values), or a single value that can be used -- externally. data ExternalValue -- | The string is a human-readable description with no other semantics. OpaqueValue :: String -> [ValueDesc] -> ExternalValue TransparentValue :: ValueDesc -> ExternalValue -- | A description of an externally meaningful value. data ValueDesc -- | An array with memory block, memory block size, memory space, element -- type, signedness of element type (if applicable), and shape. ArrayValue :: VName -> Space -> PrimType -> Signedness -> [DimSize] -> ValueDesc -- | A scalar value with signedness if applicable. ScalarValue :: PrimType -> Signedness -> VName -> ValueDesc -- | Since the core language does not care for signedness, but the source -- language does, entry point input/output information has metadata for -- integer types (and arrays containing these) that indicate whether they -- are really unsigned integers. data Signedness TypeUnsigned :: Signedness TypeDirect :: Signedness -- | A collection of imperative constants. data Constants a Constants :: [Param] -> Code a -> Constants a -- | The constants that are made available to the functions. [constsDecl] :: Constants a -> [Param] -- | Setting the value of the constants. Note that this must not contain -- declarations of the names defined in constsDecl. [constsInit] :: Constants a -> Code a -- | A collection of imperative functions. newtype Functions a Functions :: [(Name, Function a)] -> Functions a -- | A collection of imperative functions and constants. data Definitions a Definitions :: Constants a -> Functions a -> Definitions a [defConsts] :: Definitions a -> Constants a [defFuns] :: Definitions a -> Functions a -- | An ImpCode function parameter. data Param MemParam :: VName -> Space -> Param ScalarParam :: VName -> PrimType -> Param -- | The size of an array. type DimSize = SubExp -- | The size of a memory block. type MemSize = SubExp -- | The name of a parameter. paramName :: Param -> VName -- | Find those memory blocks that are used only lexically. That is, are -- not used as the source or target of a SetMem, or are the result -- of the function, nor passed as arguments to other functions. This is -- interesting because such memory blocks do not need reference counting, -- but can be managed in a purely stack-like fashion. -- -- We do not look inside any Ops. We assume that no Op is -- going to SetMem a memory block declared outside it. lexicalMemoryUsage :: Function a -> Map VName Space -- | The set of functions that are called by this code. Assumes there are -- no function calls in Ops. calledFuncs :: Code a -> Set Name -- | This expression counts elements. elements :: a -> Count Elements a -- | This expression counts bytes. bytes :: a -> Count Bytes a -- | Convert a count of elements into a count of bytes, given the -- per-element size. withElemType :: Count Elements (TExp Int64) -> PrimType -> Count Bytes (TExp Int64) -- | Turn a VName into a ScalarVar. var :: VName -> PrimType -> Exp -- | Turn a VName into a Int32 ScalarVar. vi32 :: VName -> TExp Int32 -- | Turn a VName into a Int64 ScalarVar. vi64 :: VName -> TExp Int64 -- | Concise wrapper for using Index. index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp declaredIn :: Code a -> Names instance GHC.Show.Show Futhark.CodeGen.ImpCode.Multicore.AtomicOp instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Multicore.ParallelTask instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Multicore.Multicore instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Multicore.ParallelTask instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Multicore.Multicore instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Multicore.SchedulerInfo instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Multicore.SchedulerInfo instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Multicore.Scheduling instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Multicore.AtomicOp -- | Variation of Futhark.CodeGen.ImpCode that contains the notion -- of a kernel invocation. module Futhark.CodeGen.ImpCode.Kernels -- | A program that calls kernels. type Program = Definitions HostOp -- | A function that calls kernels. type Function = Function HostOp -- | A imperative function, containing the body as well as its low-level -- inputs and outputs, as well as its high-level arguments and results. -- The latter are only used if the function is an entry point. data FunctionT a Function :: Bool -> [Param] -> [Param] -> Code a -> [ExternalValue] -> [ExternalValue] -> FunctionT a -- | Host-level code that can call kernels. type Code = Code HostOp -- | Code inside a kernel. type KernelCode = Code KernelOp -- | A run-time constant related to kernels. newtype KernelConst SizeConst :: Name -> KernelConst -- | An expression whose variables are kernel constants. type KernelConstExp = PrimExp KernelConst -- | An operation that runs on the host (CPU). data HostOp CallKernel :: Kernel -> HostOp GetSize :: VName -> Name -> SizeClass -> HostOp CmpSizeLe :: VName -> Name -> SizeClass -> Exp -> HostOp GetSizeMax :: VName -> SizeClass -> HostOp -- | An operation that occurs within a kernel body. data KernelOp GetGroupId :: VName -> Int -> KernelOp GetLocalId :: VName -> Int -> KernelOp GetLocalSize :: VName -> Int -> KernelOp GetGlobalSize :: VName -> Int -> KernelOp GetGlobalId :: VName -> Int -> KernelOp GetLockstepWidth :: VName -> KernelOp Atomic :: Space -> AtomicOp -> KernelOp Barrier :: Fence -> KernelOp MemFence :: Fence -> KernelOp LocalAlloc :: VName -> Count Bytes (TExp Int64) -> KernelOp -- | Perform a barrier and also check whether any threads have failed an -- assertion. Make sure all threads would reach all ErrorSyncs if -- any of them do. A failing assertion will jump to the next following -- ErrorSync, so make sure it's not inside control flow or -- similar. ErrorSync :: Fence -> KernelOp -- | When we do a barrier or fence, is it at the local or global level? data Fence FenceLocal :: Fence FenceGlobal :: Fence -- | Atomic operations return the value stored before the update. This old -- value is stored in the first VName. The second VName is -- the memory block to update. The Exp is the new value. data AtomicOp AtomicAdd :: IntType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp AtomicFAdd :: FloatType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp AtomicSMax :: IntType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp AtomicSMin :: IntType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp AtomicUMax :: IntType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp AtomicUMin :: IntType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp AtomicAnd :: IntType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp AtomicOr :: IntType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp AtomicXor :: IntType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp AtomicCmpXchg :: PrimType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> Exp -> AtomicOp AtomicXchg :: PrimType -> VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp -- | A generic kernel containing arbitrary kernel code. data Kernel Kernel :: Code KernelOp -> [KernelUse] -> [Exp] -> [Exp] -> Name -> Bool -> Kernel [kernelBody] :: Kernel -> Code KernelOp -- | The host variables referenced by the kernel. [kernelUses] :: Kernel -> [KernelUse] [kernelNumGroups] :: Kernel -> [Exp] [kernelGroupSize] :: Kernel -> [Exp] -- | A short descriptive and _unique_ name - should be alphanumeric and -- without spaces. [kernelName] :: Kernel -> Name -- | If true, this kernel does not need to check whether we are in a -- failing state, as it can cope. Intuitively, it means that the kernel -- does not depend on any non-scalar parameters to make control flow -- decisions. Replication, transpose, and copy kernels are examples of -- this. [kernelFailureTolerant] :: Kernel -> Bool -- | Information about a host-level variable that is used inside this -- kernel. When generating the actual kernel code, this is used to deduce -- which parameters are needed. data KernelUse ScalarUse :: VName -> PrimType -> KernelUse MemoryUse :: VName -> KernelUse ConstUse :: VName -> KernelConstExp -> KernelUse -- | 8-bit signed integer type data Int8 -- | 16-bit signed integer type data Int16 -- | 32-bit signed integer type data Int32 -- | 64-bit signed integer type data Int64 -- | 8-bit unsigned integer type data Word8 -- | 16-bit unsigned integer type data Word16 -- | 32-bit unsigned integer type data Word32 -- | 64-bit unsigned integer type data Word64 -- | The SrcLoc of a Located value. srclocOf :: Located a => a -> SrcLoc -- | Location type, consisting of a beginning position and an end position. data Loc -- | Source location type. Source location are all equal, which allows AST -- nodes to be compared modulo location information. data SrcLoc -- | Located values have a location. class Located a locOf :: Located a => a -> Loc locOfList :: Located a => [a] -> Loc -- | Prettyprint a value, wrapped to 80 characters. pretty :: Pretty a => a -> String -- | Conversion operators try to generalise the from t0 x to t1 -- instructions from LLVM. data ConvOp -- | Zero-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. ZExt :: IntType -> IntType -> ConvOp -- | Sign-extend the former integer type to the latter. If the new type is -- smaller, the result is a truncation. SExt :: IntType -> IntType -> ConvOp -- | Convert value of the former floating-point type to the latter. If the -- new type is smaller, the result is a truncation. FPConv :: FloatType -> FloatType -> ConvOp -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). FPToUI :: FloatType -> IntType -> ConvOp -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). FPToSI :: FloatType -> IntType -> ConvOp -- | Convert an unsigned integer to a floating-point value. UIToFP :: IntType -> FloatType -> ConvOp -- | Convert a signed integer to a floating-point value. SIToFP :: IntType -> FloatType -> ConvOp -- | Convert an integer to a boolean value. Zero becomes false; anything -- else is true. IToB :: IntType -> ConvOp -- | Convert a boolean to an integer. True is converted to 1 and False to -- 0. BToI :: IntType -> ConvOp -- | Comparison operators are like BinOps, but they always return a -- boolean value. The somewhat ugly constructor names are straight out of -- LLVM. data CmpOp -- | All types equality. CmpEq :: PrimType -> CmpOp -- | Unsigned less than. CmpUlt :: IntType -> CmpOp -- | Unsigned less than or equal. CmpUle :: IntType -> CmpOp -- | Signed less than. CmpSlt :: IntType -> CmpOp -- | Signed less than or equal. CmpSle :: IntType -> CmpOp -- | Floating-point less than. FCmpLt :: FloatType -> CmpOp -- | Floating-point less than or equal. FCmpLe :: FloatType -> CmpOp -- | Boolean less than. CmpLlt :: CmpOp -- | Boolean less than or equal. CmpLle :: CmpOp -- | Binary operators. These correspond closely to the binary operators in -- LLVM. Most are parametrised by their expected input and output types. data BinOp -- | Integer addition. Add :: IntType -> Overflow -> BinOp -- | Floating-point addition. FAdd :: FloatType -> BinOp -- | Integer subtraction. Sub :: IntType -> Overflow -> BinOp -- | Floating-point subtraction. FSub :: FloatType -> BinOp -- | Integer multiplication. Mul :: IntType -> Overflow -> BinOp -- | Floating-point multiplication. FMul :: FloatType -> BinOp -- | Unsigned integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. UDiv :: IntType -> Safety -> BinOp -- | Unsigned integer division. Rounds towards positive infinity. UDivUp :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. SDiv :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards positive infinity. SDivUp :: IntType -> Safety -> BinOp -- | Floating-point division. FDiv :: FloatType -> BinOp -- | Floating-point modulus. FMod :: FloatType -> BinOp -- | Unsigned integer modulus; the countepart to UDiv. UMod :: IntType -> Safety -> BinOp -- | Signed integer modulus; the countepart to SDiv. SMod :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- sdiv instruction in LLVM and integer division in C. SQuot :: IntType -> Safety -> BinOp -- | Signed integer division. Rounds towards zero. This corresponds to the -- srem instruction in LLVM and integer modulo in C. SRem :: IntType -> Safety -> BinOp -- | Returns the smallest of two signed integers. SMin :: IntType -> BinOp -- | Returns the smallest of two unsigned integers. UMin :: IntType -> BinOp -- | Returns the smallest of two floating-point numbers. FMin :: FloatType -> BinOp -- | Returns the greatest of two signed integers. SMax :: IntType -> BinOp -- | Returns the greatest of two unsigned integers. UMax :: IntType -> BinOp -- | Returns the greatest of two floating-point numbers. FMax :: FloatType -> BinOp -- | Left-shift. Shl :: IntType -> BinOp -- | Logical right-shift, zero-extended. LShr :: IntType -> BinOp -- | Arithmetic right-shift, sign-extended. AShr :: IntType -> BinOp -- | Bitwise and. And :: IntType -> BinOp -- | Bitwise or. Or :: IntType -> BinOp -- | Bitwise exclusive-or. Xor :: IntType -> BinOp -- | Integer exponentiation. Pow :: IntType -> BinOp -- | Floating-point exponentiation. FPow :: FloatType -> BinOp -- | Boolean and - not short-circuiting. LogAnd :: BinOp -- | Boolean or - not short-circuiting. LogOr :: BinOp -- | Whether something is safe or unsafe (mostly function calls, and in the -- context of whether operations are dynamically checked). When we inline -- an Unsafe function, we remove all safety checks in its body. -- The Ord instance picks Unsafe as being less than -- Safe. -- -- For operations like integer division, a safe division will not explode -- the computer in case of division by zero, but instead return some -- unspecified value. This always involves a run-time check, so generally -- the unsafe variant is what the compiler will insert, but guarded by an -- explicit assertion elsewhere. Safe operations are useful when the -- optimiser wants to move e.g. a division to a location where the -- divisor may be zero, but where the result will only be used when it is -- non-zero (so it doesn't matter what result is provided with a zero -- divisor, as long as the program keeps running). data Safety Unsafe :: Safety Safe :: Safety -- | What to do in case of arithmetic overflow. Futhark's semantics are -- that overflow does wraparound, but for generated code (like address -- arithmetic), it can be beneficial for overflow to be undefined -- behaviour, as it allows better optimisation of things such as GPU -- kernels. -- -- Note that all values of this type are considered equal for Eq -- and Ord. data Overflow OverflowWrap :: Overflow OverflowUndef :: Overflow -- | Various unary operators. It is a bit ad-hoc what is a unary operator -- and what is a built-in function. Perhaps these should all go away -- eventually. data UnOp -- | E.g., ! True == False. Not :: UnOp -- | E.g., ~(~1) = 1. Complement :: IntType -> UnOp -- | abs(-2) = 2. Abs :: IntType -> UnOp -- | fabs(-2.0) = 2.0. FAbs :: FloatType -> UnOp -- | Signed sign function: ssignum(-2) = -1. SSignum :: IntType -> UnOp -- | Unsigned sign function: usignum(2) = 1. USignum :: IntType -> UnOp -- | Non-array values. data PrimValue IntValue :: !IntValue -> PrimValue FloatValue :: !FloatValue -> PrimValue BoolValue :: !Bool -> PrimValue -- | The only value of type cert. Checked :: PrimValue -- | A floating-point value. data FloatValue Float32Value :: !Float -> FloatValue Float64Value :: !Double -> FloatValue -- | An integer value. data IntValue Int8Value :: !Int8 -> IntValue Int16Value :: !Int16 -> IntValue Int32Value :: !Int32 -> IntValue Int64Value :: !Int64 -> IntValue -- | Low-level primitive types. data PrimType IntType :: IntType -> PrimType FloatType :: FloatType -> PrimType Bool :: PrimType Cert :: PrimType -- | A floating point type. data FloatType Float32 :: FloatType Float64 :: FloatType -- | An integer type, ordered by size. Note that signedness is not a -- property of the type, but a property of the operations performed on -- values of these types. data IntType Int8 :: IntType Int16 :: IntType Int32 :: IntType Int64 :: IntType -- | A list of all integer types. allIntTypes :: [IntType] -- | A list of all floating-point types. allFloatTypes :: [FloatType] -- | A list of all primitive types. allPrimTypes :: [PrimType] -- | Create an IntValue from a type and an Integer. intValue :: Integral int => IntType -> int -> IntValue -- | The type of an integer value. intValueType :: IntValue -> IntType -- | Convert an IntValue to any Integral type. valueIntegral :: Integral int => IntValue -> int -- | Create a FloatValue from a type and a Rational. floatValue :: Real num => FloatType -> num -> FloatValue -- | The type of a floating-point value. floatValueType :: FloatValue -> FloatType -- | The type of a basic value. primValueType :: PrimValue -> PrimType -- | A "blank" value of the given primitive type - this is zero, or -- whatever is close to it. Don't depend on this value, but use it for -- e.g. creating arrays to be populated by do-loops. blankPrimValue :: PrimType -> PrimValue -- | A list of all unary operators for all types. allUnOps :: [UnOp] -- | A list of all binary operators for all types. allBinOps :: [BinOp] -- | A list of all comparison operators for all types. allCmpOps :: [CmpOp] -- | A list of all conversion operators for all types. allConvOps :: [ConvOp] -- | Apply an UnOp to an operand. Returns Nothing if the -- application is mistyped. doUnOp :: UnOp -> PrimValue -> Maybe PrimValue -- | E.g., ~(~1) = 1. doComplement :: IntValue -> IntValue -- | abs(-2) = 2. doAbs :: IntValue -> IntValue -- | abs(-2.0) = 2.0. doFAbs :: FloatValue -> FloatValue -- | ssignum(-2) = -1. doSSignum :: IntValue -> IntValue -- | usignum(-2) = -1. doUSignum :: IntValue -> IntValue -- | Apply a BinOp to an operand. Returns Nothing if the -- application is mistyped, or outside the domain (e.g. division by -- zero). doBinOp :: BinOp -> PrimValue -> PrimValue -> Maybe PrimValue -- | Integer addition. doAdd :: IntValue -> IntValue -> IntValue -- | Integer multiplication. doMul :: IntValue -> IntValue -> IntValue -- | Signed integer division. Rounds towards negativity infinity. Note: -- this is different from LLVM. doSDiv :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer modulus; the countepart to SDiv. doSMod :: IntValue -> IntValue -> Maybe IntValue -- | Signed integer exponentatation. doPow :: IntValue -> IntValue -> Maybe IntValue -- | Apply a ConvOp to an operand. Returns Nothing if the -- application is mistyped. doConvOp :: ConvOp -> PrimValue -> Maybe PrimValue -- | Zero-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doZExt :: IntValue -> IntType -> IntValue -- | Sign-extend the given integer value to the size of the given type. If -- the type is smaller than the given value, the result is a truncation. doSExt :: IntValue -> IntType -> IntValue -- | Convert the former floating-point type to the latter. doFPConv :: FloatValue -> FloatType -> FloatValue -- | Convert a floating-point value to the nearest unsigned integer -- (rounding towards zero). doFPToUI :: FloatValue -> IntType -> IntValue -- | Convert a floating-point value to the nearest signed integer (rounding -- towards zero). doFPToSI :: FloatValue -> IntType -> IntValue -- | Convert an unsigned integer to a floating-point value. doUIToFP :: IntValue -> FloatType -> FloatValue -- | Convert a signed integer to a floating-point value. doSIToFP :: IntValue -> FloatType -> FloatValue -- | Apply a CmpOp to an operand. Returns Nothing if the -- application is mistyped. doCmpOp :: CmpOp -> PrimValue -> PrimValue -> Maybe Bool -- | Compare any two primtive values for exact equality. doCmpEq :: PrimValue -> PrimValue -> Bool -- | Unsigned less than. doCmpUlt :: IntValue -> IntValue -> Bool -- | Unsigned less than or equal. doCmpUle :: IntValue -> IntValue -> Bool -- | Signed less than. doCmpSlt :: IntValue -> IntValue -> Bool -- | Signed less than or equal. doCmpSle :: IntValue -> IntValue -> Bool -- | Floating-point less than. doFCmpLt :: FloatValue -> FloatValue -> Bool -- | Floating-point less than or equal. doFCmpLe :: FloatValue -> FloatValue -> Bool -- | Translate an IntValue to Word64. This is guaranteed to -- fit. intToWord64 :: IntValue -> Word64 -- | Translate an IntValue to Int64. This is guaranteed to -- fit. intToInt64 :: IntValue -> Int64 -- | The result type of a binary operator. binOpType :: BinOp -> PrimType -- | The operand types of a comparison operator. cmpOpType :: CmpOp -> PrimType -- | The operand and result type of a unary operator. unOpType :: UnOp -> PrimType -- | The input and output types of a conversion operator. convOpType :: ConvOp -> (PrimType, PrimType) -- | A mapping from names of primitive functions to their parameter types, -- their result type, and a function for evaluating them. primFuns :: Map String ([PrimType], PrimType, [PrimValue] -> Maybe PrimValue) -- | Is the given value kind of zero? zeroIsh :: PrimValue -> Bool -- | Is the given value kind of one? oneIsh :: PrimValue -> Bool -- | Is the given value kind of negative? negativeIsh :: PrimValue -> Bool -- | Is the given integer value kind of zero? zeroIshInt :: IntValue -> Bool -- | Is the given integer value kind of one? oneIshInt :: IntValue -> Bool -- | The size of a value of a given primitive type in bites. primBitSize :: PrimType -> Int -- | The size of a value of a given primitive type in eight-bit bytes. primByteSize :: Num a => PrimType -> a -- | The size of a value of a given integer type in eight-bit bytes. intByteSize :: Num a => IntType -> a -- | The size of a value of a given floating-point type in eight-bit bytes. floatByteSize :: Num a => FloatType -> a -- | True if the given binary operator is commutative. commutativeBinOp :: BinOp -> Bool -- | The human-readable name for a ConvOp. This is used to expose -- the ConvOp in the intrinsics module of a Futhark -- program. convOpFun :: ConvOp -> String -- | True if signed. Only makes a difference for integer types. prettySigned :: Bool -> PrimType -> String -- | A name tagged with some integer. Only the integer is used in -- comparisons, no matter the type of vn. data VName VName :: !Name -> !Int -> VName -- | The abstract (not really) type representing names in the Futhark -- compiler. Strings, being lists of characters, are very slow, -- while Texts are based on byte-arrays. data Name -- | Whether some operator is commutative or not. The Monoid -- instance returns the least commutative of its arguments. data Commutativity Noncommutative :: Commutativity Commutative :: Commutativity -- | The uniqueness attribute of a type. This essentially indicates whether -- or not in-place modifications are acceptable. With respect to -- ordering, Unique is greater than Nonunique. data Uniqueness -- | May have references outside current function. Nonunique :: Uniqueness -- | No references outside current function. Unique :: Uniqueness -- | The name of the default program entry point (main). defaultEntryPoint :: Name -- | Convert a name to the corresponding list of characters. nameToString :: Name -> String -- | Convert a list of characters to the corresponding name. nameFromString :: String -> Name -- | Convert a name to the corresponding Text. nameToText :: Name -> Text -- | Convert a Text to the corresponding name. nameFromText :: Text -> Name -- | A human-readable location string, of the form -- filename:lineno:columnno. This follows the GNU coding -- standards for error messages: -- https://www.gnu.org/prep/standards/html_node/Errors.html -- -- This function assumes that both start and end position is in the same -- file (it is not clear what the alternative would even mean). locStr :: Located a => a -> String -- | Like locStr, but locStrRel prev now prints the -- location now with the file name left out if the same as -- prev. This is useful when printing messages that are all in -- the context of some initially printed location (e.g. the first mention -- contains the file name; the rest just line and column name). locStrRel :: (Located a, Located b) => a -> b -> String -- | Given a list of strings representing entries in the stack trace and -- the index of the frame to highlight, produce a final -- newline-terminated string for showing to the user. This string should -- also be preceded by a newline. The most recent stack frame must come -- first in the list. prettyStacktrace :: Int -> [String] -> String -- | Return the tag contained in the VName. baseTag :: VName -> Int -- | Return the name contained in the VName. baseName :: VName -> Name -- | Return the base Name converted to a string. baseString :: VName -> String -- | Enclose a string in the prefered quotes used in error messages. These -- are picked to not collide with characters permitted in identifiers. quote :: String -> String -- | As quote, but works on prettyprinted representation. pquote :: Doc -> Doc -- | A part of an error message. data ErrorMsgPart a -- | A literal string. ErrorString :: String -> ErrorMsgPart a -- | A run-time integer value. ErrorInt32 :: a -> ErrorMsgPart a -- | A bigger run-time integer value. ErrorInt64 :: a -> ErrorMsgPart a -- | An error message is a list of error parts, which are concatenated to -- form the final message. newtype ErrorMsg a ErrorMsg :: [ErrorMsgPart a] -> ErrorMsg a -- | A subexpression is either a scalar constant or a variable. One -- important property is that evaluation of a subexpression is guaranteed -- to complete in constant time. data SubExp Constant :: PrimValue -> SubExp Var :: VName -> SubExp -- | A string representing a specific non-default memory space. type SpaceId = String -- | The memory space of a block. If DefaultSpace, this is the -- "default" space, whatever that is. The exact meaning of the -- SpaceId depends on the backend used. In GPU kernels, for -- example, this is used to distinguish between constant, global and -- shared memory spaces. In GPU-enabled host code, it is used to -- distinguish between host memory (DefaultSpace) and GPU space. data Space DefaultSpace :: Space Space :: SpaceId -> Space -- | A special kind of memory that is a statically sized array of some -- primitive type. Used for private memory on GPUs. ScalarSpace :: [SubExp] -> PrimType -> Space -- | How many non-constant parts does the error message have, and what is -- their type? errorMsgArgTypes :: ErrorMsg a -> [PrimType] -- | Either return precomputed free names stored in the attribute, or the -- freshly computed names. Relies on lazy evaluation to avoid the work. class FreeIn dec => FreeDec dec precomputed :: FreeDec dec => dec -> FV -> FV -- | A class indicating that we can obtain free variable information from -- values of this type. class FreeIn a freeIn' :: FreeIn a => a -> FV -- | A computation to build a free variable set. data FV -- | A set of names. Note that the Ord instance is a dummy that -- treats everything as EQ if ==, and otherwise LT. data Names -- | Retrieve the data structure underlying the names representation. namesIntMap :: Names -> IntMap VName -- | Does the set of names contain this name? nameIn :: VName -> Names -> Bool -- | Construct a name set from a list. Slow. namesFromList :: [VName] -> Names -- | Turn a name set into a list of names. Slow. namesToList :: Names -> [VName] -- | Construct a name set from a single name. oneName :: VName -> Names -- | The intersection of two name sets. namesIntersection :: Names -> Names -> Names -- | Do the two name sets intersect? namesIntersect :: Names -> Names -> Bool -- | Subtract the latter name set from the former. namesSubtract :: Names -> Names -> Names -- | Map over the names in a set. mapNames :: (VName -> VName) -> Names -> Names -- | Consider a variable to be bound in the given FV computation. fvBind :: Names -> FV -> FV -- | Take note of a variable reference. fvName :: VName -> FV -- | Take note of a set of variable references. fvNames :: Names -> FV -- | Return the set of variable names that are free in the given statements -- and result. Filters away the names that are bound by the statements. freeInStmsAndRes :: (FreeIn (Op lore), FreeIn (LetDec lore), FreeIn (LParamInfo lore), FreeIn (FParamInfo lore), FreeDec (BodyDec lore), FreeDec (ExpDec lore)) => Stms lore -> Result -> FV -- | The free variables of some syntactic construct. freeIn :: FreeIn a => a -> Names -- | The names bound by the bindings immediately in a Body. boundInBody :: Body lore -> Names -- | The names bound by a binding. boundByStm :: Stm lore -> Names -- | The names bound by the bindings. boundByStms :: Stms lore -> Names -- | The names of the lambda parameters plus the index parameter. boundByLambda :: Lambda lore -> [VName] -- | The class of floating-point types that can be used for constructing -- TPrimExps. class NumExp t => FloatExp t -- | Construct a typed expression from a rational. fromRational' :: FloatExp t => Rational -> TPrimExp t v -- | The class of integer types that can be used for constructing -- TPrimExps. class NumExp t => IntExp t -- | The class of numeric types that can be used for constructing -- TPrimExps. class NumExp t -- | Construct a typed expression from an integer. fromInteger' :: NumExp t => Integer -> TPrimExp t v -- | A PrimExp tagged with a phantom type used to provide type-safe -- construction. Does not guarantee that the underlying expression is -- actually type correct. newtype TPrimExp t v TPrimExp :: PrimExp v -> TPrimExp t v [untyped] :: TPrimExp t v -> PrimExp v -- | A primitive expression parametrised over the representation of free -- variables. Note that the Functor, Traversable, and -- Num instances perform automatic (but simple) constant folding. -- -- Note also that the Num instance assumes OverflowUndef -- semantics! data PrimExp v LeafExp :: v -> PrimType -> PrimExp v ValueExp :: PrimValue -> PrimExp v BinOpExp :: BinOp -> PrimExp v -> PrimExp v -> PrimExp v CmpOpExp :: CmpOp -> PrimExp v -> PrimExp v -> PrimExp v UnOpExp :: UnOp -> PrimExp v -> PrimExp v ConvOpExp :: ConvOp -> PrimExp v -> PrimExp v FunExp :: String -> [PrimExp v] -> PrimType -> PrimExp v -- | This expression is of type Int8. isInt8 :: PrimExp v -> TPrimExp Int8 v -- | This expression is of type Int16. isInt16 :: PrimExp v -> TPrimExp Int16 v -- | This expression is of type Int32. isInt32 :: PrimExp v -> TPrimExp Int32 v -- | This expression is of type Int64. isInt64 :: PrimExp v -> TPrimExp Int64 v -- | This is a boolean expression. isBool :: PrimExp v -> TPrimExp Bool v -- | This expression is of type Float. isF32 :: PrimExp v -> TPrimExp Float v -- | This expression is of type Double. isF64 :: PrimExp v -> TPrimExp Double v -- | True if the PrimExp has at least this many nodes. This can be -- much more efficient than comparing with length for large -- PrimExps, as this function is lazy. primExpSizeAtLeast :: Int -> PrimExp v -> Bool -- | Perform quick and dirty constant folding on the top level of a -- PrimExp. This is necessary because we want to consider e.g. equality -- modulo constant folding. constFoldPrimExp :: PrimExp v -> PrimExp v -- | Lifted logical conjunction. (.&&.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 3 .&&. -- | Lifted logical conjunction. (.||.) :: TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v infixr 2 .||. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.<=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .<=. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.==.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .==. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>. -- | Lifted relational operators; assuming signed numbers in case of -- integers. (.>=.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v infix 4 .>=. -- | Lifted bitwise operators. (.&.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.|.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Lifted bitwise operators. (.^.) :: TPrimExp t v -> TPrimExp t v -> TPrimExp t v -- | Untyped smart constructor for sign extension that does a bit of -- constant folding. sExt :: IntType -> PrimExp v -> PrimExp v -- | Untyped smart constructor for zero extension that does a bit of -- constant folding. zExt :: IntType -> PrimExp v -> PrimExp v -- | Evaluate a PrimExp in the given monad. Invokes fail on -- type errors. evalPrimExp :: (Pretty v, MonadFail m) => (v -> m PrimValue) -> PrimExp v -> m PrimValue -- | The type of values returned by a PrimExp. This function -- returning does not imply that the PrimExp is type-correct. primExpType :: PrimExp v -> PrimType -- | If the given PrimExp is a constant of the wrong integer type, -- coerce it to the given integer type. This is a workaround for an issue -- in the Num instance. coerceIntPrimExp :: IntType -> PrimExp v -> PrimExp v -- | Boolean-valued PrimExps. true :: TPrimExp Bool v -- | Boolean-valued PrimExps. false :: TPrimExp Bool v -- | Boolean negation smart constructor. bNot :: TPrimExp Bool v -> TPrimExp Bool v -- | SMax on 32-bit integers. sMax32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMin on 32-bit integers. sMin32 :: TPrimExp Int32 v -> TPrimExp Int32 v -> TPrimExp Int32 v -- | SMax on 64-bit integers. sMax64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | SMin on 64-bit integers. sMin64 :: TPrimExp Int64 v -> TPrimExp Int64 v -> TPrimExp Int64 v -- | Sign-extend to 32 bit integer. sExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Sign-extend to 64 bit integer. sExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | Zero-extend to 32 bit integer. zExt32 :: IntExp t => TPrimExp t v -> TPrimExp Int32 v -- | Zero-extend to 64 bit integer. zExt64 :: IntExp t => TPrimExp t v -> TPrimExp Int64 v -- | 64-bit float minimum. fMin64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v -- | 64-bit float maximum. fMax64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v -- | Produce a mapping from the leaves of the PrimExp to their -- designated types. leafExpTypes :: Ord a => PrimExp a -> Set (a, PrimType) -- | A wrapper supporting a phantom type for indicating what we are -- counting. newtype Count u e Count :: e -> Count u e [unCount] :: Count u e -> e -- | Phantom type for a count of bytes. data Bytes -- | Phantom type for a count of elements. data Elements -- | A function call argument. data Arg ExpArg :: Exp -> Arg MemArg :: VName -> Arg -- | Like Exp, but with a required/known type. type TExp t = TPrimExp t ExpLeaf -- | A side-effect free expression whose execution will produce a single -- primitive value. type Exp = PrimExp ExpLeaf -- | The leaves of an Exp. data ExpLeaf -- | A scalar variable. The type is stored in the LeafExp -- constructor itself. ScalarVar :: VName -> ExpLeaf -- | The size of a primitive type. SizeOf :: PrimType -> ExpLeaf -- | Reading a value from memory. The arguments have the same meaning as -- with Write. Index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> ExpLeaf -- | The volatility of a memory access or variable. Feel free to ignore -- this for backends where it makes no sense (anything but C and similar -- low-level things) data Volatility Volatile :: Volatility Nonvolatile :: Volatility -- | Print the given value to the screen, somehow annotated with the given -- string as a description. If no type/value pair, just print the string. -- This has no semantic meaning, but is used entirely for debugging. Code -- generators are free to ignore this statement. pattern DebugPrint :: () => String -> Maybe Exp -> Code a -- | Function call. The results are written to the provided VName -- variables. pattern Call :: () => [VName] -> Name -> [Arg] -> Code a -- | Must be in same space. pattern SetMem :: () => VName -> VName -> Space -> Code a -- | Set a scalar variable. pattern SetScalar :: () => VName -> Exp -> Code a -- | Create an array containing the given values. The lifetime of the array -- will be the entire application. This is mostly used for constant -- arrays, but also for some bookkeeping data, like the synchronisation -- counts used to implement reduction. pattern DeclareArray :: () => VName -> Space -> PrimType -> ArrayContents -> Code a -- | Declare a scalar variable with an initially undefined value. pattern DeclareScalar :: () => VName -> Volatility -> PrimType -> Code a -- | Declare a memory block variable that will point to memory in the given -- memory space. Note that this is distinct from allocation. The memory -- block must be the target of either an Allocate or a -- SetMem before it can be used for reading or writing. pattern DeclareMem :: () => VName -> Space -> Code a -- | Statement composition. Crucial for the Semigroup instance. pattern (:>>:) :: () => Code a -> Code a -> Code a -- | Assert that something must be true. Should it turn out not to be true, -- then report a failure along with the given error message. pattern Assert :: () => Exp -> ErrorMsg Exp -> (SrcLoc, [SrcLoc]) -> Code a -- | Destination, offset in destination, destination space, source, offset -- in source, offset space, number of bytes. pattern Copy :: () => VName -> Count Bytes (TExp Int64) -> Space -> VName -> Count Bytes (TExp Int64) -> Space -> Count Bytes (TExp Int64) -> Code a -- | Memory space must match the corresponding DeclareMem. pattern Allocate :: () => VName -> Count Bytes (TExp Int64) -> Space -> Code a -- | No-op. Crucial for the Monoid instance. pattern Skip :: () => Code a -- | A for-loop iterating the given number of times. The loop parameter -- starts counting from zero and will have the same (integer) type as the -- bound. The bound is evaluated just once, before the loop is entered. pattern For :: () => VName -> Exp -> Code a -> Code a -- | While loop. The conditional is (of course) re-evaluated before every -- iteration of the loop. pattern While :: () => TExp Bool -> Code a -> Code a -- | Indicate that some memory block will never again be referenced via the -- indicated variable. However, it may still be accessed through aliases. -- It is only safe to actually deallocate the memory block if this is the -- last reference. There is no guarantee that all memory blocks will be -- freed with this statement. Backends are free to ignore it entirely. pattern Free :: () => VName -> Space -> Code a -- | Has the same semantics as the contained code, but the comment should -- show up in generated code for ease of inspection. pattern Comment :: () => String -> Code a -> Code a -- | Write mem i t space vol v writes the value v to -- mem offset by i elements of type t. The -- Space argument is the memory space of mem (technically -- redundant, but convenient). Note that reading is done with an -- Exp (Index). pattern Write :: () => VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp -> Code a -- | Conditional execution. pattern If :: () => TExp Bool -> Code a -> Code a -> Code a -- | Perform an extensible operation. pattern Op :: () => a -> Code a -- | The contents of a statically declared constant array. Such arrays are -- always unidimensional, and reshaped if necessary in the code that uses -- them. data ArrayContents -- | Precisely these values. ArrayValues :: [PrimValue] -> ArrayContents -- | This many zeroes. ArrayZeros :: Int -> ArrayContents -- | A imperative function, containing the body as well as its low-level -- inputs and outputs, as well as its high-level arguments and results. -- The latter are only used if the function is an entry point. data FunctionT a -- | ^ An externally visible value. This can be an opaque value (covering -- several physical internal values), or a single value that can be used -- externally. data ExternalValue -- | The string is a human-readable description with no other semantics. OpaqueValue :: String -> [ValueDesc] -> ExternalValue TransparentValue :: ValueDesc -> ExternalValue -- | A description of an externally meaningful value. data ValueDesc -- | An array with memory block, memory block size, memory space, element -- type, signedness of element type (if applicable), and shape. ArrayValue :: VName -> Space -> PrimType -> Signedness -> [DimSize] -> ValueDesc -- | A scalar value with signedness if applicable. ScalarValue :: PrimType -> Signedness -> VName -> ValueDesc -- | Since the core language does not care for signedness, but the source -- language does, entry point input/output information has metadata for -- integer types (and arrays containing these) that indicate whether they -- are really unsigned integers. data Signedness TypeUnsigned :: Signedness TypeDirect :: Signedness -- | A collection of imperative constants. data Constants a Constants :: [Param] -> Code a -> Constants a -- | The constants that are made available to the functions. [constsDecl] :: Constants a -> [Param] -- | Setting the value of the constants. Note that this must not contain -- declarations of the names defined in constsDecl. [constsInit] :: Constants a -> Code a -- | A collection of imperative functions. newtype Functions a Functions :: [(Name, Function a)] -> Functions a -- | A collection of imperative functions and constants. data Definitions a Definitions :: Constants a -> Functions a -> Definitions a [defConsts] :: Definitions a -> Constants a [defFuns] :: Definitions a -> Functions a -- | An ImpCode function parameter. data Param MemParam :: VName -> Space -> Param ScalarParam :: VName -> PrimType -> Param -- | The size of an array. type DimSize = SubExp -- | The size of a memory block. type MemSize = SubExp -- | The name of a parameter. paramName :: Param -> VName -- | Find those memory blocks that are used only lexically. That is, are -- not used as the source or target of a SetMem, or are the result -- of the function, nor passed as arguments to other functions. This is -- interesting because such memory blocks do not need reference counting, -- but can be managed in a purely stack-like fashion. -- -- We do not look inside any Ops. We assume that no Op is -- going to SetMem a memory block declared outside it. lexicalMemoryUsage :: Function a -> Map VName Space -- | The set of functions that are called by this code. Assumes there are -- no function calls in Ops. calledFuncs :: Code a -> Set Name -- | This expression counts elements. elements :: a -> Count Elements a -- | This expression counts bytes. bytes :: a -> Count Bytes a -- | Convert a count of elements into a count of bytes, given the -- per-element size. withElemType :: Count Elements (TExp Int64) -> PrimType -> Count Bytes (TExp Int64) -- | Turn a VName into a ScalarVar. var :: VName -> PrimType -> Exp -- | Turn a VName into a Int32 ScalarVar. vi32 :: VName -> TExp Int32 -- | Turn a VName into a Int64 ScalarVar. vi64 :: VName -> TExp Int64 -- | Concise wrapper for using Index. index :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp declaredIn :: Code a -> Names instance GHC.Show.Show Futhark.CodeGen.ImpCode.Kernels.KernelConst instance GHC.Classes.Ord Futhark.CodeGen.ImpCode.Kernels.KernelConst instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.Kernels.KernelConst instance GHC.Show.Show Futhark.CodeGen.ImpCode.Kernels.KernelUse instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.Kernels.KernelUse instance GHC.Show.Show Futhark.CodeGen.ImpCode.Kernels.Fence instance GHC.Show.Show Futhark.CodeGen.ImpCode.Kernels.AtomicOp instance GHC.Show.Show Futhark.CodeGen.ImpCode.Kernels.KernelOp instance GHC.Show.Show Futhark.CodeGen.ImpCode.Kernels.Kernel instance GHC.Show.Show Futhark.CodeGen.ImpCode.Kernels.HostOp instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Kernels.HostOp instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Kernels.HostOp instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Kernels.Kernel instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Kernels.Kernel instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Kernels.KernelOp instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Kernels.KernelOp instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Kernels.AtomicOp instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Kernels.KernelUse instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.ImpCode.Kernels.KernelConst -- | Carefully optimised implementations of GPU transpositions. Written in -- ImpCode so we can compile it to both CUDA and OpenCL. module Futhark.CodeGen.ImpGen.Kernels.Transpose -- | Which form of transposition to generate code for. data TransposeType TransposeNormal :: TransposeType TransposeLowWidth :: TransposeType TransposeLowHeight :: TransposeType -- | For small arrays that do not benefit from coalescing. TransposeSmall :: TransposeType -- | The types of the arguments accepted by a transposition function. type TransposeArgs = (VName, TExp Int32, VName, TExp Int32, TExp Int32, TExp Int32, TExp Int32, TExp Int32, TExp Int32, VName) -- | Generate a transpose kernel. There is special support to handle input -- arrays with low width, low height, or both. -- -- Normally when transposing a [2][n] array we would use a -- FUT_BLOCK_DIM x FUT_BLOCK_DIM group to process a -- [2][FUT_BLOCK_DIM] slice of the input array. This would mean -- that many of the threads in a group would be inactive. We try to -- remedy this by using a special kernel that will process a larger part -- of the input, by using more complex indexing. In our example, we could -- use all threads in a group if we are processing -- (2/FUT_BLOCK_DIM) as large a slice of each rows per group. -- The variable mulx contains this factor for the kernel to -- handle input arrays with low height. -- -- See issue #308 on GitHub for more details. -- -- These kernels are optimized to ensure all global reads and writes are -- coalesced, and to avoid bank conflicts in shared memory. Each thread -- group transposes a 2D tile of block_dim*2 by block_dim*2 elements. The -- size of a thread group is block_dim/2 by block_dim*2, meaning that -- each thread will process 4 elements in a 2D tile. The shared memory -- array containing the 2D tile consists of block_dim*2 by block_dim*2+1 -- elements. Padding each row with an additional element prevents bank -- conflicts from occuring when the tile is accessed column-wise. mapTransposeKernel :: String -> Integer -> TransposeArgs -> PrimType -> TransposeType -> Kernel instance GHC.Show.Show Futhark.CodeGen.ImpGen.Kernels.Transpose.TransposeType instance GHC.Classes.Ord Futhark.CodeGen.ImpGen.Kernels.Transpose.TransposeType instance GHC.Classes.Eq Futhark.CodeGen.ImpGen.Kernels.Transpose.TransposeType -- | Simple C runtime representation. module Futhark.CodeGen.Backends.SimpleRep -- | tupleField i is the name of field number i in a -- tuple. tupleField :: Int -> String -- | funName f is the name of the C function corresponding to the -- Futhark function f. funName :: Name -> String -- | The type of memory blocks in the default memory space. defaultMemBlockType :: Type -- | The C type corresponding to a signed integer type. intTypeToCType :: IntType -> Type -- | The C type corresponding to a primitive type. Integers are assumed to -- be unsigned. primTypeToCType :: PrimType -> Type -- | The C type corresponding to a primitive type. Integers are assumed to -- have the specified sign. signedPrimTypeToCType :: Signedness -> PrimType -> Type cIntOps :: [Definition] cFloat32Ops :: [Definition] cFloat32Funs :: [Definition] cFloat64Ops :: [Definition] cFloat64Funs :: [Definition] cFloatConvOps :: [Definition] -- | C code generator framework. module Futhark.CodeGen.Backends.GenericC -- | Compile imperative program to a C program. Always uses the function -- named "main" as entry point, so make sure it is defined. compileProg :: MonadFreshNames m => String -> Operations op () -> CompilerM op () () -> String -> [Space] -> [Option] -> Definitions op -> m CParts -- | The result of compilation to C is four parts, which can be put -- together in various ways. The obvious way is to concatenate all of -- them, which yields a CLI program. Another is to compile the library -- part by itself, and use the header file to call into it. data CParts CParts :: String -> String -> String -> String -> CParts [cHeader] :: CParts -> String -- | Utility definitions that must be visible to both CLI and library -- parts. [cUtils] :: CParts -> String [cCLI] :: CParts -> String [cLib] :: CParts -> String -- | Produce header and implementation files. asLibrary :: CParts -> (String, String) -- | As executable with command-line interface. asExecutable :: CParts -> String data Operations op s Operations :: WriteScalar op s -> ReadScalar op s -> Allocate op s -> Deallocate op s -> Copy op s -> StaticArray op s -> MemoryType op s -> OpCompiler op s -> ErrorCompiler op s -> CallCompiler op s -> Bool -> ([BlockItem], [BlockItem]) -> Operations op s [opsWriteScalar] :: Operations op s -> WriteScalar op s [opsReadScalar] :: Operations op s -> ReadScalar op s [opsAllocate] :: Operations op s -> Allocate op s [opsDeallocate] :: Operations op s -> Deallocate op s [opsCopy] :: Operations op s -> Copy op s [opsStaticArray] :: Operations op s -> StaticArray op s [opsMemoryType] :: Operations op s -> MemoryType op s [opsCompiler] :: Operations op s -> OpCompiler op s [opsError] :: Operations op s -> ErrorCompiler op s [opsCall] :: Operations op s -> CallCompiler op s -- | If true, use reference counting. Otherwise, bare pointers. [opsFatMemory] :: Operations op s -> Bool -- | Code to bracket critical sections. [opsCritical] :: Operations op s -> ([BlockItem], [BlockItem]) -- | A set of operations that fail for every operation involving -- non-default memory spaces. Uses plain pointers and malloc for -- memory management. defaultOperations :: Operations op s -- | A substitute expression compiler, tried before the main compilation -- function. type OpCompiler op s = op -> CompilerM op s () type ErrorCompiler op s = ErrorMsg Exp -> String -> CompilerM op s () -- | Call a function. type CallCompiler op s = [VName] -> Name -> [Exp] -> CompilerM op s () -- | The address space qualifiers for a pointer of the given type with the -- given annotation. type PointerQuals op s = String -> CompilerM op s [TypeQual] -- | The type of a memory block in the given memory space. type MemoryType op s = SpaceId -> CompilerM op s Type -- | Write a scalar to the given memory block with the given element index -- and in the given memory space. type WriteScalar op s = Exp -> Exp -> Type -> SpaceId -> Volatility -> Exp -> CompilerM op s () writeScalarPointerWithQuals :: PointerQuals op s -> WriteScalar op s -- | Read a scalar from the given memory block with the given element index -- and in the given memory space. type ReadScalar op s = Exp -> Exp -> Type -> SpaceId -> Volatility -> CompilerM op s Exp readScalarPointerWithQuals :: PointerQuals op s -> ReadScalar op s -- | Allocate a memory block of the given size and with the given tag in -- the given memory space, saving a reference in the given variable name. type Allocate op s = Exp -> Exp -> Exp -> SpaceId -> CompilerM op s () -- | De-allocate the given memory block with the given tag, which is in the -- given memory space. type Deallocate op s = Exp -> Exp -> SpaceId -> CompilerM op s () -- | Copy from one memory block to another. type Copy op s = Exp -> Exp -> Space -> Exp -> Exp -> Space -> Exp -> CompilerM op s () -- | Create a static array of values - initialised at load time. type StaticArray op s = VName -> SpaceId -> PrimType -> ArrayContents -> CompilerM op s () data CompilerM op s a data CompilerState s getUserState :: CompilerM op s s modifyUserState :: (s -> s) -> CompilerM op s () contextContents :: CompilerM op s ([FieldGroup], [Stm]) contextFinalInits :: CompilerM op s [Stm] runCompilerM :: Operations op s -> VNameSource -> s -> CompilerM op s a -> (a, CompilerState s) -- | Used when we, inside an existing CompilerM action, want to -- generate code for a new function. Use this so that the compiler -- understands that previously declared memory doesn't need to be freed -- inside this action. inNewFunction :: Bool -> CompilerM op s a -> CompilerM op s a cachingMemory :: Map VName Space -> ([BlockItem] -> [Stm] -> CompilerM op s a) -> CompilerM op s a blockScope :: CompilerM op s () -> CompilerM op s [BlockItem] compileFun :: [BlockItem] -> [Param] -> (Name, Function op) -> CompilerM op s (Definition, Func) compileCode :: Code op -> CompilerM op s () compileExp :: Exp -> CompilerM op s Exp -- | Tell me how to compile a v, and I'll Compile any PrimExp -- v for you. compilePrimExp :: Monad m => (v -> m Exp) -> PrimExp v -> m Exp compilePrimValue :: PrimValue -> Exp compileExpToName :: String -> PrimType -> Exp -> CompilerM op s VName rawMem :: VName -> CompilerM op s Exp item :: BlockItem -> CompilerM op s () items :: [BlockItem] -> CompilerM op s () stm :: Stm -> CompilerM op s () stms :: [Stm] -> CompilerM op s () decl :: InitGroup -> CompilerM op s () atInit :: Stm -> CompilerM op s () headerDecl :: HeaderSection -> Definition -> CompilerM op s () -- | Construct a publicly visible definition using the specified name as -- the template. The first returned definition is put in the header file, -- and the second is the implementation. Returns the public name. publicDef :: String -> HeaderSection -> (String -> (Definition, Definition)) -> CompilerM op s String -- | As publicDef, but ignores the public name. publicDef_ :: String -> HeaderSection -> (String -> (Definition, Definition)) -> CompilerM op s () profileReport :: BlockItem -> CompilerM op s () -- | In which part of the header file we put the declaration. This is to -- ensure that the header file remains structured and readable. data HeaderSection ArrayDecl :: String -> HeaderSection OpaqueDecl :: String -> HeaderSection EntryDecl :: HeaderSection MiscDecl :: HeaderSection InitDecl :: HeaderSection libDecl :: Definition -> CompilerM op s () earlyDecl :: Definition -> CompilerM op s () -- | Public names must have a consitent prefix. publicName :: String -> CompilerM op s String -- | The generated code must define a struct with this name. contextType :: CompilerM op s Type contextField :: Id -> Type -> Maybe Exp -> CompilerM op s () memToCType :: VName -> Space -> CompilerM op s Type cacheMem :: ToExp a => a -> CompilerM op s (Maybe VName) fatMemory :: Space -> CompilerM op s Bool rawMemCType :: Space -> CompilerM op s Type -- | Return an expression multiplying together the given expressions. If an -- empty list is given, the expression 1 is returned. cproduct :: [Exp] -> Exp fatMemType :: Space -> Type -- | The C type corresponding to a primitive type. Integers are assumed to -- be unsigned. primTypeToCType :: PrimType -> Type -- | The C type corresponding to a signed integer type. intTypeToCType :: IntType -> Type copyMemoryDefaultSpace :: Exp -> Exp -> Exp -> Exp -> Exp -> CompilerM op s () instance GHC.Classes.Ord Futhark.CodeGen.Backends.GenericC.HeaderSection instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericC.HeaderSection instance Control.Monad.Writer.Class.MonadWriter (Futhark.CodeGen.Backends.GenericC.CompilerAcc op s) (Futhark.CodeGen.Backends.GenericC.CompilerM op s) instance Control.Monad.Reader.Class.MonadReader (Futhark.CodeGen.Backends.GenericC.CompilerEnv op s) (Futhark.CodeGen.Backends.GenericC.CompilerM op s) instance Control.Monad.State.Class.MonadState (Futhark.CodeGen.Backends.GenericC.CompilerState s) (Futhark.CodeGen.Backends.GenericC.CompilerM op s) instance GHC.Base.Monad (Futhark.CodeGen.Backends.GenericC.CompilerM op s) instance GHC.Base.Applicative (Futhark.CodeGen.Backends.GenericC.CompilerM op s) instance GHC.Base.Functor (Futhark.CodeGen.Backends.GenericC.CompilerM op s) instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.CodeGen.Backends.GenericC.CompilerM op s) instance GHC.Base.Semigroup (Futhark.CodeGen.Backends.GenericC.CompilerAcc op s) instance GHC.Base.Monoid (Futhark.CodeGen.Backends.GenericC.CompilerAcc op s) instance Language.C.Quote.Base.ToIdent Language.Futhark.Core.Name instance Language.C.Quote.Base.ToIdent Language.Futhark.Core.VName instance Language.C.Quote.Base.ToExp Language.Futhark.Core.VName instance Language.C.Quote.Base.ToExp Futhark.IR.Primitive.IntValue instance Language.C.Quote.Base.ToExp Futhark.IR.Primitive.FloatValue instance Language.C.Quote.Base.ToExp Futhark.IR.Primitive.PrimValue instance Language.C.Quote.Base.ToExp Futhark.IR.Syntax.Core.SubExp -- | This module defines a translation from imperative code with kernels to -- imperative code with OpenCL calls. module Futhark.CodeGen.ImpGen.Kernels.ToOpenCL kernelsToOpenCL :: Program -> Program kernelsToCUDA :: Program -> Program instance GHC.Classes.Eq Futhark.CodeGen.ImpGen.Kernels.ToOpenCL.OpsMode module Futhark.CodeGen.Backends.COpenCL.Boilerplate -- | Called after most code has been generated to generate the bulk of the -- boilerplate. generateBoilerplate :: String -> String -> [Name] -> Map KernelName KernelSafety -> [PrimType] -> Map Name SizeClass -> [FailureMsg] -> CompilerM OpenCL () () profilingEvent :: Name -> Exp copyDevToDev :: Name copyDevToHost :: Name copyHostToDev :: Name copyScalarToDev :: Name copyScalarFromDev :: Name commonOptions :: [Option] failureSwitch :: [FailureMsg] -> Stm costCentreReport :: [Name] -> [BlockItem] kernelRuntime :: KernelName -> Name kernelRuns :: KernelName -> Name -- | Various boilerplate definitions for the CUDA backend. module Futhark.CodeGen.Backends.CCUDA.Boilerplate -- | Called after most code has been generated to generate the bulk of the -- boilerplate. generateBoilerplate :: String -> String -> [Name] -> Map KernelName KernelSafety -> Map Name SizeClass -> [FailureMsg] -> CompilerM OpenCL () () -- | Block items to put before and after a thing to be profiled. profilingEnclosure :: Name -> ([BlockItem], [BlockItem]) failureSwitch :: [FailureMsg] -> Stm copyDevToDev :: Name copyDevToHost :: Name copyHostToDev :: Name copyScalarToDev :: Name copyScalarFromDev :: Name kernelRuntime :: KernelName -> Name kernelRuns :: KernelName -> Name costCentreReport :: [Name] -> [BlockItem] module Futhark.CodeGen.Backends.GenericPython.AST data PyExp Integer :: Integer -> PyExp Bool :: Bool -> PyExp Float :: Double -> PyExp String :: String -> PyExp RawStringLiteral :: String -> PyExp Var :: String -> PyExp BinOp :: String -> PyExp -> PyExp -> PyExp UnOp :: String -> PyExp -> PyExp Cond :: PyExp -> PyExp -> PyExp -> PyExp Index :: PyExp -> PyIdx -> PyExp Call :: PyExp -> [PyArg] -> PyExp Cast :: PyExp -> String -> PyExp Tuple :: [PyExp] -> PyExp List :: [PyExp] -> PyExp Field :: PyExp -> String -> PyExp Dict :: [(PyExp, PyExp)] -> PyExp Lambda :: String -> PyExp -> PyExp None :: PyExp data PyIdx IdxRange :: PyExp -> PyExp -> PyIdx IdxExp :: PyExp -> PyIdx data PyArg ArgKeyword :: String -> PyExp -> PyArg Arg :: PyExp -> PyArg data PyStmt If :: PyExp -> [PyStmt] -> [PyStmt] -> PyStmt Try :: [PyStmt] -> [PyExcept] -> PyStmt While :: PyExp -> [PyStmt] -> PyStmt For :: String -> PyExp -> [PyStmt] -> PyStmt With :: PyExp -> [PyStmt] -> PyStmt Assign :: PyExp -> PyExp -> PyStmt AssignOp :: String -> PyExp -> PyExp -> PyStmt Comment :: String -> [PyStmt] -> PyStmt Assert :: PyExp -> PyExp -> PyStmt Raise :: PyExp -> PyStmt Exp :: PyExp -> PyStmt Return :: PyExp -> PyStmt Pass :: PyStmt Import :: String -> Maybe String -> PyStmt FunDef :: PyFunDef -> PyStmt ClassDef :: PyClassDef -> PyStmt Escape :: String -> PyStmt newtype PyProg PyProg :: [PyStmt] -> PyProg data PyExcept Catch :: PyExp -> [PyStmt] -> PyExcept data PyFunDef Def :: String -> [String] -> [PyStmt] -> PyFunDef data PyClassDef Class :: String -> [PyStmt] -> PyClassDef instance GHC.Show.Show Futhark.CodeGen.Backends.GenericPython.AST.UnOp instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericPython.AST.UnOp instance GHC.Show.Show Futhark.CodeGen.Backends.GenericPython.AST.PyIdx instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericPython.AST.PyIdx instance GHC.Show.Show Futhark.CodeGen.Backends.GenericPython.AST.PyExp instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericPython.AST.PyExp instance GHC.Show.Show Futhark.CodeGen.Backends.GenericPython.AST.PyArg instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericPython.AST.PyArg instance GHC.Show.Show Futhark.CodeGen.Backends.GenericPython.AST.PyExcept instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericPython.AST.PyExcept instance GHC.Show.Show Futhark.CodeGen.Backends.GenericPython.AST.PyFunDef instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericPython.AST.PyFunDef instance GHC.Show.Show Futhark.CodeGen.Backends.GenericPython.AST.PyStmt instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericPython.AST.PyStmt instance GHC.Show.Show Futhark.CodeGen.Backends.GenericPython.AST.PyClassDef instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericPython.AST.PyClassDef instance GHC.Show.Show Futhark.CodeGen.Backends.GenericPython.AST.PyProg instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericPython.AST.PyProg instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyProg instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyStmt instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyFunDef instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyClassDef instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyExcept instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyIdx instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyArg instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyExp -- | This module defines a generator for getopt based command line -- argument parsing. Each option is associated with arbitrary Python code -- that will perform side effects, usually by setting some global -- variables. module Futhark.CodeGen.Backends.GenericPython.Options -- | Specification if a single command line option. The option must have a -- long name, and may also have a short name. -- -- When the statement is being executed, the argument (if any) will be -- stored in the variable optarg. data Option Option :: String -> Maybe Char -> OptionArgument -> [PyStmt] -> Option [optionLongName] :: Option -> String [optionShortName] :: Option -> Maybe Char [optionArgument] :: Option -> OptionArgument [optionAction] :: Option -> [PyStmt] -- | Whether an option accepts an argument. data OptionArgument NoArgument :: OptionArgument RequiredArgument :: String -> OptionArgument OptionalArgument :: OptionArgument -- | Generate option parsing code that accepts the given command line -- options. Will read from sys.argv. -- -- If option parsing fails for any reason, the entire process will -- terminate with error code 1. generateOptionParser :: [Option] -> [PyStmt] -- | A generic Python code generator which is polymorphic in the type of -- the operations. Concretely, we use this to handle both sequential and -- PyOpenCL Python code. module Futhark.CodeGen.Backends.GenericPython compileProg :: MonadFreshNames m => Maybe String -> Constructor -> [PyStmt] -> [PyStmt] -> Operations op s -> s -> [PyStmt] -> [Option] -> Definitions op -> m String -- | The class generated by the code generator must have a constructor, -- although it can be vacuous. data Constructor Constructor :: [String] -> [PyStmt] -> Constructor -- | A constructor that takes no arguments and does nothing. emptyConstructor :: Constructor compileName :: VName -> String compileVar :: VName -> CompilerM op s PyExp compileDim :: DimSize -> PyExp compileExp :: Exp -> CompilerM op s PyExp -- | Tell me how to compile a v, and I'll Compile any PrimExp -- v for you. compilePrimExp :: Monad m => (v -> m PyExp) -> PrimExp v -> m PyExp compileCode :: Code op -> CompilerM op s () compilePrimValue :: PrimValue -> PyExp -- | The ctypes type corresponding to a PrimType. compilePrimType :: PrimType -> String -- | The ctypes type corresponding to a PrimType, taking sign into -- account. compilePrimTypeExt :: PrimType -> Signedness -> String -- | The Numpy type corresponding to a PrimType. compilePrimToNp :: PrimType -> String -- | The Numpy type corresponding to a PrimType, taking sign into -- account. compilePrimToExtNp :: PrimType -> Signedness -> String data Operations op s Operations :: WriteScalar op s -> ReadScalar op s -> Allocate op s -> Copy op s -> StaticArray op s -> OpCompiler op s -> EntryOutput op s -> EntryInput op s -> Operations op s [opsWriteScalar] :: Operations op s -> WriteScalar op s [opsReadScalar] :: Operations op s -> ReadScalar op s [opsAllocate] :: Operations op s -> Allocate op s [opsCopy] :: Operations op s -> Copy op s [opsStaticArray] :: Operations op s -> StaticArray op s [opsCompiler] :: Operations op s -> OpCompiler op s [opsEntryOutput] :: Operations op s -> EntryOutput op s [opsEntryInput] :: Operations op s -> EntryInput op s -- | A set of operations that fail for every operation involving -- non-default memory spaces. Uses plain pointers and malloc for -- memory management. defaultOperations :: Operations op s unpackDim :: PyExp -> DimSize -> Int32 -> CompilerM op s () newtype CompilerM op s a CompilerM :: RWS (CompilerEnv op s) [PyStmt] (CompilerState s) a -> CompilerM op s a -- | A substitute expression compiler, tried before the main compilation -- function. type OpCompiler op s = op -> CompilerM op s () -- | Write a scalar to the given memory block with the given index and in -- the given memory space. type WriteScalar op s = PyExp -> PyExp -> PrimType -> SpaceId -> PyExp -> CompilerM op s () -- | Read a scalar from the given memory block with the given index and in -- the given memory space. type ReadScalar op s = PyExp -> PyExp -> PrimType -> SpaceId -> CompilerM op s PyExp -- | Allocate a memory block of the given size in the given memory space, -- saving a reference in the given variable name. type Allocate op s = PyExp -> PyExp -> SpaceId -> CompilerM op s () -- | Copy from one memory block to another. type Copy op s = PyExp -> PyExp -> Space -> PyExp -> PyExp -> Space -> PyExp -> PrimType -> CompilerM op s () -- | Create a static array of values - initialised at load time. type StaticArray op s = VName -> SpaceId -> PrimType -> ArrayContents -> CompilerM op s () -- | Construct the Python array being returned from an entry point. type EntryOutput op s = VName -> SpaceId -> PrimType -> Signedness -> [DimSize] -> CompilerM op s PyExp -- | Unpack the array being passed to an entry point. type EntryInput op s = PyExp -> SpaceId -> PrimType -> Signedness -> [DimSize] -> PyExp -> CompilerM op s () data CompilerEnv op s CompilerEnv :: Operations op s -> Map VName PyExp -> CompilerEnv op s [envOperations] :: CompilerEnv op s -> Operations op s [envVarExp] :: CompilerEnv op s -> Map VName PyExp data CompilerState s CompilerState :: VNameSource -> [PyStmt] -> s -> CompilerState s [compNameSrc] :: CompilerState s -> VNameSource [compInit] :: CompilerState s -> [PyStmt] [compUserState] :: CompilerState s -> s stm :: PyStmt -> CompilerM op s () atInit :: PyStmt -> CompilerM op s () collect' :: CompilerM op s a -> CompilerM op s (a, [PyStmt]) collect :: CompilerM op s () -> CompilerM op s [PyStmt] -- | A Call where the function is a variable and every argument is a -- simple Arg. simpleCall :: String -> [PyExp] -> PyExp copyMemoryDefaultSpace :: PyExp -> PyExp -> PyExp -> PyExp -> PyExp -> CompilerM op s () instance Control.Monad.Writer.Class.MonadWriter [Futhark.CodeGen.Backends.GenericPython.AST.PyStmt] (Futhark.CodeGen.Backends.GenericPython.CompilerM op s) instance Control.Monad.Reader.Class.MonadReader (Futhark.CodeGen.Backends.GenericPython.CompilerEnv op s) (Futhark.CodeGen.Backends.GenericPython.CompilerM op s) instance Control.Monad.State.Class.MonadState (Futhark.CodeGen.Backends.GenericPython.CompilerState s) (Futhark.CodeGen.Backends.GenericPython.CompilerM op s) instance GHC.Base.Monad (Futhark.CodeGen.Backends.GenericPython.CompilerM op s) instance GHC.Base.Applicative (Futhark.CodeGen.Backends.GenericPython.CompilerM op s) instance GHC.Base.Functor (Futhark.CodeGen.Backends.GenericPython.CompilerM op s) instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.CodeGen.Backends.GenericPython.CompilerM op s) -- | Various boilerplate definitions for the PyOpenCL backend. module Futhark.CodeGen.Backends.PyOpenCL.Boilerplate -- | Python code (as a string) that calls the -- initiatialize_opencl_object procedure. Should be put in the -- class constructor. openClInit :: [PrimType] -> String -> Map Name SizeClass -> [FailureMsg] -> String -- | rtspythonopencl.py embedded as a string. openClPrelude :: String -- | The Futhark Prelude Library embedded embedded as strings read during -- compilation of the Futhark compiler. The advantage is that the prelude -- can be accessed without reading it from disk, thus saving users from -- include path headaches. module Language.Futhark.Prelude -- | Prelude embedded as Text values, one for every file. prelude :: [(FilePath, Text)] -- | The Futhark source language AST definition. Many types, such as -- ExpBase, are parametrised by type and name representation. -- See the https://futhark.readthedocs.org@ for a language -- reference, or this module may be a little hard to understand. module Language.Futhark.Syntax -- | The uniqueness attribute of a type. This essentially indicates whether -- or not in-place modifications are acceptable. With respect to -- ordering, Unique is greater than Nonunique. data Uniqueness -- | May have references outside current function. Nonunique :: Uniqueness -- | No references outside current function. Unique :: Uniqueness -- | An integer type, ordered by size. Note that signedness is not a -- property of the type, but a property of the operations performed on -- values of these types. data IntType Int8 :: IntType Int16 :: IntType Int32 :: IntType Int64 :: IntType -- | A floating point type. data FloatType Float32 :: FloatType Float64 :: FloatType -- | Low-level primitive types. data PrimType Signed :: IntType -> PrimType Unsigned :: IntType -> PrimType FloatType :: FloatType -> PrimType Bool :: PrimType -- | A type class for things that can be array dimensions. class Eq dim => ArrayDim dim -- | unifyDims x y combines x and y to contain -- their maximum common information, and fails if they conflict. unifyDims :: ArrayDim dim => dim -> dim -> Maybe dim -- | Declaration of a dimension size. data DimDecl vn -- | The size of the dimension is this name, which must be in scope. In a -- return type, this will give rise to an assertion. NamedDim :: QualName vn -> DimDecl vn -- | The size is a constant. ConstDim :: Int -> DimDecl vn -- | No dimension declaration. AnyDim :: DimDecl vn -- | The size of an array type is a list of its dimension sizes. If -- Nothing, that dimension is of a (statically) unknown size. newtype ShapeDecl dim ShapeDecl :: [dim] -> ShapeDecl dim [shapeDims] :: ShapeDecl dim -> [dim] -- | The number of dimensions contained in a shape. shapeRank :: ShapeDecl dim -> Int -- | stripDims n shape strips the outer n dimensions from -- shape, returning Nothing if this would result in zero -- or fewer dimensions. stripDims :: Int -> ShapeDecl dim -> Maybe (ShapeDecl dim) -- | unifyShapes x y combines x and y to contain -- their maximum common information, and fails if they conflict. unifyShapes :: ArrayDim dim => ShapeDecl dim -> ShapeDecl dim -> Maybe (ShapeDecl dim) -- | A type name consists of qualifiers (for error messages) and a -- VName (for equality checking). data TypeName TypeName :: [VName] -> VName -> TypeName [typeQuals] :: TypeName -> [VName] [typeLeaf] :: TypeName -> VName -- | Convert a QualName to a TypeName. typeNameFromQualName :: QualName VName -> TypeName -- | Convert a TypeName to a QualName. qualNameFromTypeName :: TypeName -> QualName VName -- | An expanded Futhark type is either an array, or something that can be -- an element of an array. When comparing types for equality, function -- parameter names are ignored. This representation permits some -- malformed types (arrays of functions), but importantly rules out -- arrays-of-arrays. data TypeBase dim as Scalar :: ScalarTypeBase dim as -> TypeBase dim as Array :: as -> Uniqueness -> ScalarTypeBase dim () -> ShapeDecl dim -> TypeBase dim as -- | An argument passed to a type constructor. data TypeArg dim TypeArgDim :: dim -> SrcLoc -> TypeArg dim TypeArgType :: TypeBase dim () -> SrcLoc -> TypeArg dim -- | A dimension declaration expression for use in a TypeExp. data DimExp vn -- | The size of the dimension is this name, which must be in scope. DimExpNamed :: QualName vn -> SrcLoc -> DimExp vn -- | The size is a constant. DimExpConst :: Int -> SrcLoc -> DimExp vn -- | No dimension declaration. DimExpAny :: DimExp vn -- | An unstructured type with type variables and possibly shape -- declarations - this is what the user types in the source program. -- These are used to construct TypeBases in the type checker. data TypeExp vn TEVar :: QualName vn -> SrcLoc -> TypeExp vn TETuple :: [TypeExp vn] -> SrcLoc -> TypeExp vn TERecord :: [(Name, TypeExp vn)] -> SrcLoc -> TypeExp vn TEArray :: TypeExp vn -> DimExp vn -> SrcLoc -> TypeExp vn TEUnique :: TypeExp vn -> SrcLoc -> TypeExp vn TEApply :: TypeExp vn -> TypeArgExp vn -> SrcLoc -> TypeExp vn TEArrow :: Maybe vn -> TypeExp vn -> TypeExp vn -> SrcLoc -> TypeExp vn TESum :: [(Name, [TypeExp vn])] -> SrcLoc -> TypeExp vn -- | A type argument expression passed to a type constructor. data TypeArgExp vn TypeArgExpDim :: DimExp vn -> SrcLoc -> TypeArgExp vn TypeArgExpType :: TypeExp vn -> TypeArgExp vn -- | The name (if any) of a function parameter. The Eq and -- Ord instances always compare values of this type equal. data PName Named :: VName -> PName Unnamed :: PName -- | Types that can be elements of arrays. This representation does allow -- arrays of records of functions, which is nonsensical, but it -- convolutes the code too much if we try to statically rule it out. data ScalarTypeBase dim as Prim :: PrimType -> ScalarTypeBase dim as TypeVar :: as -> Uniqueness -> TypeName -> [TypeArg dim] -> ScalarTypeBase dim as Record :: Map Name (TypeBase dim as) -> ScalarTypeBase dim as Sum :: Map Name [TypeBase dim as] -> ScalarTypeBase dim as -- | The aliasing corresponds to the lexical closure of the function. Arrow :: as -> PName -> TypeBase dim as -> TypeBase dim as -> ScalarTypeBase dim as -- | A type with aliasing information and shape annotations, used for -- describing the type patterns and expressions. type PatternType = TypeBase (DimDecl VName) Aliasing -- | A "structural" type with shape annotations and no aliasing -- information, used for declarations. type StructType = TypeBase (DimDecl VName) () -- | A value type contains full, manifest size information. type ValueType = TypeBase Int64 () -- | Information about which parts of a value/type are consumed. data Diet -- | Consumes these fields in the record. RecordDiet :: Map Name Diet -> Diet -- | A function that consumes its argument(s) like this. The final -- Diet should always be Observe, as there is no way for a -- function to consume its return value. FuncDiet :: Diet -> Diet -> Diet -- | Consumes this value. Consume :: Diet -- | Only observes value in this position, does not consume. Observe :: Diet -- | A declaration of the type of something. data TypeDeclBase f vn TypeDecl :: TypeExp vn -> f StructType -> TypeDeclBase f vn -- | The type declared by the user. [declaredType] :: TypeDeclBase f vn -> TypeExp vn -- | The type deduced by the type checker. [expandedType] :: TypeDeclBase f vn -> f StructType -- | An integer value. data IntValue Int8Value :: !Int8 -> IntValue Int16Value :: !Int16 -> IntValue Int32Value :: !Int32 -> IntValue Int64Value :: !Int64 -> IntValue -- | A floating-point value. data FloatValue Float32Value :: !Float -> FloatValue Float64Value :: !Double -> FloatValue -- | Non-array values. data PrimValue SignedValue :: !IntValue -> PrimValue UnsignedValue :: !IntValue -> PrimValue FloatValue :: !FloatValue -> PrimValue BoolValue :: !Bool -> PrimValue -- | A class for converting ordinary Haskell values to primitive Futhark -- values. class IsPrimValue v primValue :: IsPrimValue v => v -> PrimValue -- | Simple Futhark values. Values are fully evaluated and their type is -- always unambiguous. data Value PrimValue :: !PrimValue -> Value -- | It is assumed that the array is 0-indexed. The type is the full type. ArrayValue :: !Array Int Value -> ValueType -> Value -- | The payload of an attribute. data AttrInfo AttrAtom :: Name -> AttrInfo AttrComp :: Name -> [AttrInfo] -> AttrInfo -- | Default binary operators. data BinOp -- | A pseudo-operator standing in for any normal identifier used as an -- operator (they all have the same fixity). Binary Ops for Numbers Backtick :: BinOp Plus :: BinOp Minus :: BinOp Pow :: BinOp Times :: BinOp Divide :: BinOp Mod :: BinOp Quot :: BinOp Rem :: BinOp ShiftR :: BinOp ShiftL :: BinOp Band :: BinOp Xor :: BinOp Bor :: BinOp LogAnd :: BinOp LogOr :: BinOp Equal :: BinOp NotEqual :: BinOp Less :: BinOp Leq :: BinOp Greater :: BinOp Geq :: BinOp -- |
--   |>
--   
PipeRight :: BinOp -- | <| Misc PipeLeft :: BinOp -- | An identifier consists of its name and the type of the value bound to -- the identifier. data IdentBase f vn Ident :: vn -> f PatternType -> SrcLoc -> IdentBase f vn [identName] :: IdentBase f vn -> vn [identType] :: IdentBase f vn -> f PatternType [identSrcLoc] :: IdentBase f vn -> SrcLoc -- | Whether a bound for an end-point of a DimSlice or a range -- literal is inclusive or exclusive. data Inclusiveness a DownToExclusive :: a -> Inclusiveness a -- | May be "down to" if step is negative. ToInclusive :: a -> Inclusiveness a UpToExclusive :: a -> Inclusiveness a -- | An indexing of a single dimension. data DimIndexBase f vn DimFix :: ExpBase f vn -> DimIndexBase f vn DimSlice :: Maybe (ExpBase f vn) -> Maybe (ExpBase f vn) -> Maybe (ExpBase f vn) -> DimIndexBase f vn -- | The Futhark expression language. -- -- In a value of type Exp f vn, annotations are wrapped in the -- functor f, and all names are of type vn. -- -- This allows us to encode whether or not the expression has been -- type-checked in the Haskell type of the expression. Specifically, the -- parser will produce expressions of type Exp NoInfo -- Name, and the type checker will convert these to Exp -- Info VName, in which type information is always -- present and all names are unique. data ExpBase f vn Literal :: PrimValue -> SrcLoc -> ExpBase f vn -- | A polymorphic integral literal. IntLit :: Integer -> f PatternType -> SrcLoc -> ExpBase f vn -- | A polymorphic decimal literal. FloatLit :: Double -> f PatternType -> SrcLoc -> ExpBase f vn -- | A string literal is just a fancy syntax for an array of bytes. StringLit :: [Word8] -> SrcLoc -> ExpBase f vn -- | A parenthesized expression. Parens :: ExpBase f vn -> SrcLoc -> ExpBase f vn QualParens :: (QualName vn, SrcLoc) -> ExpBase f vn -> SrcLoc -> ExpBase f vn -- | Tuple literals, e.g., {1+3, {x, y+z}}. TupLit :: [ExpBase f vn] -> SrcLoc -> ExpBase f vn -- | Record literals, e.g. {x=2,y=3,z}. RecordLit :: [FieldBase f vn] -> SrcLoc -> ExpBase f vn -- | Array literals, e.g., [ [1+x, 3], [2, 1+4] ]. Second arg is -- the row type of the rows of the array. ArrayLit :: [ExpBase f vn] -> f PatternType -> SrcLoc -> ExpBase f vn Range :: ExpBase f vn -> Maybe (ExpBase f vn) -> Inclusiveness (ExpBase f vn) -> (f PatternType, f [VName]) -> SrcLoc -> ExpBase f vn Var :: QualName vn -> f PatternType -> SrcLoc -> ExpBase f vn -- | Type ascription: e : t. Ascript :: ExpBase f vn -> TypeDeclBase f vn -> SrcLoc -> ExpBase f vn -- | Size coercion: e :> t. Coerce :: ExpBase f vn -> TypeDeclBase f vn -> (f PatternType, f [VName]) -> SrcLoc -> ExpBase f vn LetPat :: PatternBase f vn -> ExpBase f vn -> ExpBase f vn -> (f PatternType, f [VName]) -> SrcLoc -> ExpBase f vn LetFun :: vn -> ([TypeParamBase vn], [PatternBase f vn], Maybe (TypeExp vn), f StructType, ExpBase f vn) -> ExpBase f vn -> f PatternType -> SrcLoc -> ExpBase f vn If :: ExpBase f vn -> ExpBase f vn -> ExpBase f vn -> (f PatternType, f [VName]) -> SrcLoc -> ExpBase f vn -- | The Maybe VName is a possible existential size that is -- instantiated by this argument.. -- -- The [VName] are the existential sizes that come into being at -- this call site. Apply :: ExpBase f vn -> ExpBase f vn -> f (Diet, Maybe VName) -> (f PatternType, f [VName]) -> SrcLoc -> ExpBase f vn -- | Numeric negation (ugly special case; Haskell did it first). Negate :: ExpBase f vn -> SrcLoc -> ExpBase f vn Lambda :: [PatternBase f vn] -> ExpBase f vn -> Maybe (TypeExp vn) -> f (Aliasing, StructType) -> SrcLoc -> ExpBase f vn -- | +; first two types are operands, third is result. OpSection :: QualName vn -> f PatternType -> SrcLoc -> ExpBase f vn -- | 2+; first type is operand, second is result. OpSectionLeft :: QualName vn -> f PatternType -> ExpBase f vn -> (f (StructType, Maybe VName), f StructType) -> (f PatternType, f [VName]) -> SrcLoc -> ExpBase f vn -- | +2; first type is operand, second is result. OpSectionRight :: QualName vn -> f PatternType -> ExpBase f vn -> (f StructType, f (StructType, Maybe VName)) -> f PatternType -> SrcLoc -> ExpBase f vn -- | Field projection as a section: (.x.y.z). ProjectSection :: [Name] -> f PatternType -> SrcLoc -> ExpBase f vn -- | Array indexing as a section: (.[i,j]). IndexSection :: [DimIndexBase f vn] -> f PatternType -> SrcLoc -> ExpBase f vn DoLoop :: [VName] -> PatternBase f vn -> ExpBase f vn -> LoopFormBase f vn -> ExpBase f vn -> f (PatternType, [VName]) -> SrcLoc -> ExpBase f vn BinOp :: (QualName vn, SrcLoc) -> f PatternType -> (ExpBase f vn, f (StructType, Maybe VName)) -> (ExpBase f vn, f (StructType, Maybe VName)) -> f PatternType -> f [VName] -> SrcLoc -> ExpBase f vn Project :: Name -> ExpBase f vn -> f PatternType -> SrcLoc -> ExpBase f vn LetWith :: IdentBase f vn -> IdentBase f vn -> [DimIndexBase f vn] -> ExpBase f vn -> ExpBase f vn -> f PatternType -> SrcLoc -> ExpBase f vn Index :: ExpBase f vn -> [DimIndexBase f vn] -> (f PatternType, f [VName]) -> SrcLoc -> ExpBase f vn Update :: ExpBase f vn -> [DimIndexBase f vn] -> ExpBase f vn -> SrcLoc -> ExpBase f vn RecordUpdate :: ExpBase f vn -> [Name] -> ExpBase f vn -> f PatternType -> SrcLoc -> ExpBase f vn -- | Fail if the first expression does not return true, and return the -- value of the second expression if it does. Assert :: ExpBase f vn -> ExpBase f vn -> f String -> SrcLoc -> ExpBase f vn -- | An n-ary value constructor. Constr :: Name -> [ExpBase f vn] -> f PatternType -> SrcLoc -> ExpBase f vn -- | A match expression. Match :: ExpBase f vn -> NonEmpty (CaseBase f vn) -> (f PatternType, f [VName]) -> SrcLoc -> ExpBase f vn -- | An attribute applied to the following expression. Attr :: AttrInfo -> ExpBase f vn -> SrcLoc -> ExpBase f vn -- | An entry in a record literal. data FieldBase f vn RecordFieldExplicit :: Name -> ExpBase f vn -> SrcLoc -> FieldBase f vn RecordFieldImplicit :: vn -> f PatternType -> SrcLoc -> FieldBase f vn -- | A case in a match expression. data CaseBase f vn CasePat :: PatternBase f vn -> ExpBase f vn -> SrcLoc -> CaseBase f vn -- | Whether the loop is a for-loop or a while-loop. data LoopFormBase f vn For :: IdentBase f vn -> ExpBase f vn -> LoopFormBase f vn ForIn :: PatternBase f vn -> ExpBase f vn -> LoopFormBase f vn While :: ExpBase f vn -> LoopFormBase f vn -- | A literal in a pattern. data PatLit PatLitInt :: Integer -> PatLit PatLitFloat :: Double -> PatLit PatLitPrim :: PrimValue -> PatLit -- | A pattern as used most places where variables are bound (function -- parameters, let expressions, etc). data PatternBase f vn TuplePattern :: [PatternBase f vn] -> SrcLoc -> PatternBase f vn RecordPattern :: [(Name, PatternBase f vn)] -> SrcLoc -> PatternBase f vn PatternParens :: PatternBase f vn -> SrcLoc -> PatternBase f vn Id :: vn -> f PatternType -> SrcLoc -> PatternBase f vn Wildcard :: f PatternType -> SrcLoc -> PatternBase f vn PatternAscription :: PatternBase f vn -> TypeDeclBase f vn -> SrcLoc -> PatternBase f vn PatternLit :: PatLit -> f PatternType -> SrcLoc -> PatternBase f vn PatternConstr :: Name -> f PatternType -> [PatternBase f vn] -> SrcLoc -> PatternBase f vn -- | A spec is a component of a module type. data SpecBase f vn ValSpec :: vn -> [TypeParamBase vn] -> TypeDeclBase f vn -> Maybe DocComment -> SrcLoc -> SpecBase f vn [specName] :: SpecBase f vn -> vn [specTypeParams] :: SpecBase f vn -> [TypeParamBase vn] [specType] :: SpecBase f vn -> TypeDeclBase f vn [specDoc] :: SpecBase f vn -> Maybe DocComment [specLocation] :: SpecBase f vn -> SrcLoc TypeAbbrSpec :: TypeBindBase f vn -> SpecBase f vn -- | Abstract type. TypeSpec :: Liftedness -> vn -> [TypeParamBase vn] -> Maybe DocComment -> SrcLoc -> SpecBase f vn ModSpec :: vn -> SigExpBase f vn -> Maybe DocComment -> SrcLoc -> SpecBase f vn IncludeSpec :: SigExpBase f vn -> SrcLoc -> SpecBase f vn -- | A module type expression. data SigExpBase f vn SigVar :: QualName vn -> f (Map VName VName) -> SrcLoc -> SigExpBase f vn SigParens :: SigExpBase f vn -> SrcLoc -> SigExpBase f vn SigSpecs :: [SpecBase f vn] -> SrcLoc -> SigExpBase f vn SigWith :: SigExpBase f vn -> TypeRefBase f vn -> SrcLoc -> SigExpBase f vn SigArrow :: Maybe vn -> SigExpBase f vn -> SigExpBase f vn -> SrcLoc -> SigExpBase f vn -- | A type refinement. data TypeRefBase f vn TypeRef :: QualName vn -> [TypeParamBase vn] -> TypeDeclBase f vn -> SrcLoc -> TypeRefBase f vn -- | Module type binding. data SigBindBase f vn SigBind :: vn -> SigExpBase f vn -> Maybe DocComment -> SrcLoc -> SigBindBase f vn [sigName] :: SigBindBase f vn -> vn [sigExp] :: SigBindBase f vn -> SigExpBase f vn [sigDoc] :: SigBindBase f vn -> Maybe DocComment [sigLoc] :: SigBindBase f vn -> SrcLoc -- | Module expression. data ModExpBase f vn ModVar :: QualName vn -> SrcLoc -> ModExpBase f vn ModParens :: ModExpBase f vn -> SrcLoc -> ModExpBase f vn -- | The contents of another file as a module. ModImport :: FilePath -> f FilePath -> SrcLoc -> ModExpBase f vn ModDecs :: [DecBase f vn] -> SrcLoc -> ModExpBase f vn -- | Functor application. The first mapping is from parameter names to -- argument names, while the second maps names in the constructed module -- to the names inside the functor. ModApply :: ModExpBase f vn -> ModExpBase f vn -> f (Map VName VName) -> f (Map VName VName) -> SrcLoc -> ModExpBase f vn ModAscript :: ModExpBase f vn -> SigExpBase f vn -> f (Map VName VName) -> SrcLoc -> ModExpBase f vn ModLambda :: ModParamBase f vn -> Maybe (SigExpBase f vn, f (Map VName VName)) -> ModExpBase f vn -> SrcLoc -> ModExpBase f vn -- | A module binding. data ModBindBase f vn ModBind :: vn -> [ModParamBase f vn] -> Maybe (SigExpBase f vn, f (Map VName VName)) -> ModExpBase f vn -> Maybe DocComment -> SrcLoc -> ModBindBase f vn [modName] :: ModBindBase f vn -> vn [modParams] :: ModBindBase f vn -> [ModParamBase f vn] [modSignature] :: ModBindBase f vn -> Maybe (SigExpBase f vn, f (Map VName VName)) [modExp] :: ModBindBase f vn -> ModExpBase f vn [modDoc] :: ModBindBase f vn -> Maybe DocComment [modLocation] :: ModBindBase f vn -> SrcLoc -- | A module parameter. data ModParamBase f vn ModParam :: vn -> SigExpBase f vn -> f [VName] -> SrcLoc -> ModParamBase f vn [modParamName] :: ModParamBase f vn -> vn [modParamType] :: ModParamBase f vn -> SigExpBase f vn [modParamAbs] :: ModParamBase f vn -> f [VName] [modParamLocation] :: ModParamBase f vn -> SrcLoc -- | Documentation strings, including source location. data DocComment DocComment :: String -> SrcLoc -> DocComment -- | Function Declarations data ValBindBase f vn ValBind :: Maybe (f EntryPoint) -> vn -> Maybe (TypeExp vn) -> f (StructType, [VName]) -> [TypeParamBase vn] -> [PatternBase f vn] -> ExpBase f vn -> Maybe DocComment -> [AttrInfo] -> SrcLoc -> ValBindBase f vn -- | Just if this function is an entry point. If so, it also contains the -- externally visible interface. Note that this may not strictly be -- well-typed after some desugaring operations, as it may refer to -- abstract types that are no longer in scope. [valBindEntryPoint] :: ValBindBase f vn -> Maybe (f EntryPoint) [valBindName] :: ValBindBase f vn -> vn [valBindRetDecl] :: ValBindBase f vn -> Maybe (TypeExp vn) [valBindRetType] :: ValBindBase f vn -> f (StructType, [VName]) [valBindTypeParams] :: ValBindBase f vn -> [TypeParamBase vn] [valBindParams] :: ValBindBase f vn -> [PatternBase f vn] [valBindBody] :: ValBindBase f vn -> ExpBase f vn [valBindDoc] :: ValBindBase f vn -> Maybe DocComment [valBindAttrs] :: ValBindBase f vn -> [AttrInfo] [valBindLocation] :: ValBindBase f vn -> SrcLoc -- | Information about the external interface exposed by an entry point. -- The important thing is that that we remember the original -- source-language types, without desugaring them at all. The annoying -- thing is that we do not require type annotations on entry points, so -- the types can be either ascribed or inferred. data EntryPoint EntryPoint :: [EntryType] -> EntryType -> EntryPoint [entryParams] :: EntryPoint -> [EntryType] [entryReturn] :: EntryPoint -> EntryType -- | Part of the type of an entry point. Has an actual type, and maybe also -- an ascribed type expression. data EntryType EntryType :: StructType -> Maybe (TypeExp VName) -> EntryType [entryType] :: EntryType -> StructType [entryAscribed] :: EntryType -> Maybe (TypeExp VName) -- | The liftedness of a type parameter. By the Ord instance, -- Unlifted < SizeLifted < Lifted. data Liftedness -- | May only be instantiated with a zero-order type of (possibly -- symbolically) known size. Unlifted :: Liftedness -- | May only be instantiated with a zero-order type, but the size can be -- varying. SizeLifted :: Liftedness -- | May be instantiated with a functional type. Lifted :: Liftedness -- | Type Declarations data TypeBindBase f vn TypeBind :: vn -> Liftedness -> [TypeParamBase vn] -> TypeDeclBase f vn -> Maybe DocComment -> SrcLoc -> TypeBindBase f vn [typeAlias] :: TypeBindBase f vn -> vn [typeLiftedness] :: TypeBindBase f vn -> Liftedness [typeParams] :: TypeBindBase f vn -> [TypeParamBase vn] [typeExp] :: TypeBindBase f vn -> TypeDeclBase f vn [typeDoc] :: TypeBindBase f vn -> Maybe DocComment [typeBindLocation] :: TypeBindBase f vn -> SrcLoc -- | A type parameter. data TypeParamBase vn -- | A type parameter that must be a size. TypeParamDim :: vn -> SrcLoc -> TypeParamBase vn -- | A type parameter that must be a type. TypeParamType :: Liftedness -> vn -> SrcLoc -> TypeParamBase vn -- | The name of a type parameter. typeParamName :: TypeParamBase vn -> vn -- | The program described by a single Futhark file. May depend on other -- files. data ProgBase f vn Prog :: Maybe DocComment -> [DecBase f vn] -> ProgBase f vn [progDoc] :: ProgBase f vn -> Maybe DocComment [progDecs] :: ProgBase f vn -> [DecBase f vn] -- | A top-level binding. data DecBase f vn ValDec :: ValBindBase f vn -> DecBase f vn TypeDec :: TypeBindBase f vn -> DecBase f vn SigDec :: SigBindBase f vn -> DecBase f vn ModDec :: ModBindBase f vn -> DecBase f vn OpenDec :: ModExpBase f vn -> SrcLoc -> DecBase f vn LocalDec :: DecBase f vn -> SrcLoc -> DecBase f vn ImportDec :: FilePath -> f FilePath -> SrcLoc -> DecBase f vn -- | Convenience class for deriving Show instances for the AST. class (Show vn, Show (f VName), Show (f (Diet, Maybe VName)), Show (f String), Show (f [VName]), Show (f ([VName], [VName])), Show (f PatternType), Show (f (PatternType, [VName])), Show (f (StructType, [VName])), Show (f EntryPoint), Show (f Int), Show (f StructType), Show (f (StructType, Maybe VName)), Show (f (Aliasing, StructType)), Show (f (Map VName VName)), Show (f Uniqueness)) => Showable f vn -- | No information functor. Usually used for placeholder type- or aliasing -- information. data NoInfo a NoInfo :: NoInfo a -- | Some information. The dual to NoInfo newtype Info a Info :: a -> Info a [unInfo] :: Info a -> a -- | A variable that is aliased. Can be still in-scope, or have gone out of -- scope and be free. In the latter case, it behaves more like an -- equivalence class. See uniqueness-error18.fut for an example of why -- this is necessary. data Alias AliasBound :: VName -> Alias [aliasVar] :: Alias -> VName AliasFree :: VName -> Alias [aliasVar] :: Alias -> VName -- | Aliasing for a type, which is a set of the variables that are aliased. type Aliasing = Set Alias -- | A name qualified with a breadcrumb of module accesses. data QualName vn QualName :: ![vn] -> !vn -> QualName vn [qualQuals] :: QualName vn -> ![vn] [qualLeaf] :: QualName vn -> !vn instance GHC.Show.Show (Language.Futhark.Syntax.NoInfo a) instance GHC.Classes.Ord (Language.Futhark.Syntax.NoInfo a) instance GHC.Classes.Eq (Language.Futhark.Syntax.NoInfo a) instance GHC.Show.Show a => GHC.Show.Show (Language.Futhark.Syntax.Info a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Language.Futhark.Syntax.Info a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.Futhark.Syntax.Info a) instance GHC.Show.Show Language.Futhark.Syntax.PrimType instance GHC.Classes.Ord Language.Futhark.Syntax.PrimType instance GHC.Classes.Eq Language.Futhark.Syntax.PrimType instance GHC.Show.Show Language.Futhark.Syntax.PrimValue instance GHC.Classes.Ord Language.Futhark.Syntax.PrimValue instance GHC.Classes.Eq Language.Futhark.Syntax.PrimValue instance GHC.Show.Show Language.Futhark.Syntax.AttrInfo instance GHC.Classes.Ord Language.Futhark.Syntax.AttrInfo instance GHC.Classes.Eq Language.Futhark.Syntax.AttrInfo instance GHC.Show.Show dim => GHC.Show.Show (Language.Futhark.Syntax.ShapeDecl dim) instance GHC.Classes.Ord dim => GHC.Classes.Ord (Language.Futhark.Syntax.ShapeDecl dim) instance GHC.Classes.Eq dim => GHC.Classes.Eq (Language.Futhark.Syntax.ShapeDecl dim) instance GHC.Show.Show Language.Futhark.Syntax.TypeName instance GHC.Show.Show Language.Futhark.Syntax.PName instance (GHC.Show.Show as, GHC.Show.Show dim) => GHC.Show.Show (Language.Futhark.Syntax.ScalarTypeBase dim as) instance (GHC.Classes.Ord as, GHC.Classes.Ord dim) => GHC.Classes.Ord (Language.Futhark.Syntax.ScalarTypeBase dim as) instance (GHC.Classes.Eq as, GHC.Classes.Eq dim) => GHC.Classes.Eq (Language.Futhark.Syntax.ScalarTypeBase dim as) instance (GHC.Show.Show as, GHC.Show.Show dim) => GHC.Show.Show (Language.Futhark.Syntax.TypeBase dim as) instance (GHC.Classes.Ord as, GHC.Classes.Ord dim) => GHC.Classes.Ord (Language.Futhark.Syntax.TypeBase dim as) instance (GHC.Classes.Eq as, GHC.Classes.Eq dim) => GHC.Classes.Eq (Language.Futhark.Syntax.TypeBase dim as) instance GHC.Show.Show dim => GHC.Show.Show (Language.Futhark.Syntax.TypeArg dim) instance GHC.Classes.Ord dim => GHC.Classes.Ord (Language.Futhark.Syntax.TypeArg dim) instance GHC.Classes.Eq dim => GHC.Classes.Eq (Language.Futhark.Syntax.TypeArg dim) instance GHC.Show.Show Language.Futhark.Syntax.Alias instance GHC.Classes.Ord Language.Futhark.Syntax.Alias instance GHC.Classes.Eq Language.Futhark.Syntax.Alias instance GHC.Show.Show Language.Futhark.Syntax.Diet instance GHC.Classes.Eq Language.Futhark.Syntax.Diet instance GHC.Show.Show Language.Futhark.Syntax.Value instance GHC.Classes.Eq Language.Futhark.Syntax.Value instance GHC.Enum.Bounded Language.Futhark.Syntax.BinOp instance GHC.Enum.Enum Language.Futhark.Syntax.BinOp instance GHC.Show.Show Language.Futhark.Syntax.BinOp instance GHC.Classes.Ord Language.Futhark.Syntax.BinOp instance GHC.Classes.Eq Language.Futhark.Syntax.BinOp instance GHC.Show.Show a => GHC.Show.Show (Language.Futhark.Syntax.Inclusiveness a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Language.Futhark.Syntax.Inclusiveness a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.Futhark.Syntax.Inclusiveness a) instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.QualName vn) instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.DimExp vn) instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.TypeArgExp vn) instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.TypeExp vn) instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.DimDecl vn) instance GHC.Show.Show Language.Futhark.Syntax.PatLit instance GHC.Classes.Ord Language.Futhark.Syntax.PatLit instance GHC.Classes.Eq Language.Futhark.Syntax.PatLit instance GHC.Show.Show Language.Futhark.Syntax.DocComment instance GHC.Show.Show Language.Futhark.Syntax.EntryType instance GHC.Show.Show Language.Futhark.Syntax.EntryPoint instance GHC.Show.Show Language.Futhark.Syntax.Liftedness instance GHC.Classes.Ord Language.Futhark.Syntax.Liftedness instance GHC.Classes.Eq Language.Futhark.Syntax.Liftedness instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.TypeParamBase vn) instance GHC.Classes.Ord vn => GHC.Classes.Ord (Language.Futhark.Syntax.TypeParamBase vn) instance GHC.Classes.Eq vn => GHC.Classes.Eq (Language.Futhark.Syntax.TypeParamBase vn) instance GHC.Classes.Eq (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.Name) instance GHC.Classes.Eq (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.Name) instance GHC.Classes.Ord (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.VName) instance GHC.Classes.Eq (Language.Futhark.Syntax.DimExp Language.Futhark.Core.Name) instance GHC.Classes.Eq (Language.Futhark.Syntax.DimExp Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.DimExp Language.Futhark.Core.Name) instance GHC.Classes.Ord (Language.Futhark.Syntax.DimExp Language.Futhark.Core.VName) instance GHC.Classes.Eq (Language.Futhark.Syntax.TypeExp Language.Futhark.Core.Name) instance GHC.Classes.Eq (Language.Futhark.Syntax.TypeExp Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.TypeExp Language.Futhark.Core.Name) instance GHC.Classes.Ord (Language.Futhark.Syntax.TypeExp Language.Futhark.Core.VName) instance GHC.Classes.Eq (Language.Futhark.Syntax.TypeArgExp Language.Futhark.Core.Name) instance GHC.Classes.Eq (Language.Futhark.Syntax.TypeArgExp Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.TypeArgExp Language.Futhark.Core.Name) instance GHC.Classes.Ord (Language.Futhark.Syntax.TypeArgExp Language.Futhark.Core.VName) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.TypeDeclBase f vn) instance GHC.Classes.Eq (Language.Futhark.Syntax.TypeDeclBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.TypeDeclBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.IdentBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.DimIndexBase f vn) instance GHC.Classes.Eq (Language.Futhark.Syntax.DimIndexBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.DimIndexBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.ExpBase f vn) instance GHC.Classes.Eq (Language.Futhark.Syntax.ExpBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.ExpBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.FieldBase f vn) instance GHC.Classes.Eq (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.CaseBase f vn) instance GHC.Classes.Eq (Language.Futhark.Syntax.CaseBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.CaseBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.LoopFormBase f vn) instance GHC.Classes.Eq (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.PatternBase f vn) instance GHC.Classes.Eq (Language.Futhark.Syntax.PatternBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.PatternBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.ValBindBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.TypeBindBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.SpecBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.SigExpBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.TypeRefBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.SigBindBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.ModExpBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.ModBindBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.ModParamBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.DecBase f vn) instance Language.Futhark.Syntax.Showable f vn => GHC.Show.Show (Language.Futhark.Syntax.ProgBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.ModExpBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.ModBindBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.DecBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.ModParamBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.SigBindBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.SpecBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.SigExpBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.TypeRefBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.ValBindBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.ExpBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.FieldBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.CaseBase f vn) instance Data.Loc.Located (Language.Futhark.Syntax.TypeBindBase f vn) instance GHC.Base.Functor Language.Futhark.Syntax.TypeParamBase instance Data.Foldable.Foldable Language.Futhark.Syntax.TypeParamBase instance Data.Traversable.Traversable Language.Futhark.Syntax.TypeParamBase instance Data.Loc.Located (Language.Futhark.Syntax.TypeParamBase vn) instance GHC.Show.Show vn => Language.Futhark.Syntax.Showable Language.Futhark.Syntax.NoInfo vn instance GHC.Show.Show vn => Language.Futhark.Syntax.Showable Language.Futhark.Syntax.Info vn instance Data.Loc.Located Language.Futhark.Syntax.DocComment instance Data.Loc.Located (Language.Futhark.Syntax.PatternBase f vn) instance GHC.Classes.Eq vn => GHC.Classes.Eq (Language.Futhark.Syntax.IdentBase ty vn) instance GHC.Classes.Ord vn => GHC.Classes.Ord (Language.Futhark.Syntax.IdentBase ty vn) instance Data.Loc.Located (Language.Futhark.Syntax.IdentBase ty vn) instance Data.Loc.Located (Language.Futhark.Syntax.TypeDeclBase f vn) instance GHC.Base.Functor Language.Futhark.Syntax.DimDecl instance Data.Foldable.Foldable Language.Futhark.Syntax.DimDecl instance Data.Traversable.Traversable Language.Futhark.Syntax.DimDecl instance Language.Futhark.Syntax.ArrayDim (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.VName) instance Data.Loc.Located (Language.Futhark.Syntax.TypeExp vn) instance Data.Loc.Located (Language.Futhark.Syntax.TypeArgExp vn) instance GHC.Classes.Eq (Language.Futhark.Syntax.QualName Language.Futhark.Core.Name) instance GHC.Classes.Eq (Language.Futhark.Syntax.QualName Language.Futhark.Core.VName) instance GHC.Classes.Ord (Language.Futhark.Syntax.QualName Language.Futhark.Core.Name) instance GHC.Classes.Ord (Language.Futhark.Syntax.QualName Language.Futhark.Core.VName) instance GHC.Base.Functor Language.Futhark.Syntax.QualName instance Data.Foldable.Foldable Language.Futhark.Syntax.QualName instance Data.Traversable.Traversable Language.Futhark.Syntax.QualName instance Data.Loc.Located a => Data.Loc.Located (Language.Futhark.Syntax.Inclusiveness a) instance GHC.Base.Functor Language.Futhark.Syntax.Inclusiveness instance Data.Foldable.Foldable Language.Futhark.Syntax.Inclusiveness instance Data.Traversable.Traversable Language.Futhark.Syntax.Inclusiveness instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Syntax.BinOp instance Data.Bitraversable.Bitraversable Language.Futhark.Syntax.ScalarTypeBase instance Data.Bifunctor.Bifunctor Language.Futhark.Syntax.ScalarTypeBase instance Data.Bifoldable.Bifoldable Language.Futhark.Syntax.ScalarTypeBase instance Data.Bitraversable.Bitraversable Language.Futhark.Syntax.TypeBase instance Data.Bifunctor.Bifunctor Language.Futhark.Syntax.TypeBase instance Data.Bifoldable.Bifoldable Language.Futhark.Syntax.TypeBase instance Data.Traversable.Traversable Language.Futhark.Syntax.TypeArg instance GHC.Base.Functor Language.Futhark.Syntax.TypeArg instance Data.Foldable.Foldable Language.Futhark.Syntax.TypeArg instance GHC.Classes.Eq Language.Futhark.Syntax.PName instance GHC.Classes.Ord Language.Futhark.Syntax.PName instance GHC.Classes.Eq Language.Futhark.Syntax.TypeName instance GHC.Classes.Ord Language.Futhark.Syntax.TypeName instance Data.Foldable.Foldable Language.Futhark.Syntax.ShapeDecl instance Data.Traversable.Traversable Language.Futhark.Syntax.ShapeDecl instance GHC.Base.Functor Language.Futhark.Syntax.ShapeDecl instance GHC.Base.Semigroup (Language.Futhark.Syntax.ShapeDecl dim) instance GHC.Base.Monoid (Language.Futhark.Syntax.ShapeDecl dim) instance Language.Futhark.Syntax.ArrayDim () instance Language.Futhark.Syntax.IsPrimValue GHC.Types.Int instance Language.Futhark.Syntax.IsPrimValue GHC.Int.Int8 instance Language.Futhark.Syntax.IsPrimValue GHC.Int.Int16 instance Language.Futhark.Syntax.IsPrimValue GHC.Int.Int32 instance Language.Futhark.Syntax.IsPrimValue GHC.Int.Int64 instance Language.Futhark.Syntax.IsPrimValue GHC.Word.Word8 instance Language.Futhark.Syntax.IsPrimValue GHC.Word.Word16 instance Language.Futhark.Syntax.IsPrimValue GHC.Word.Word32 instance Language.Futhark.Syntax.IsPrimValue GHC.Word.Word64 instance Language.Futhark.Syntax.IsPrimValue GHC.Types.Float instance Language.Futhark.Syntax.IsPrimValue GHC.Types.Double instance Language.Futhark.Syntax.IsPrimValue GHC.Types.Bool instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Syntax.PrimType instance GHC.Base.Functor Language.Futhark.Syntax.Info instance Data.Foldable.Foldable Language.Futhark.Syntax.Info instance Data.Traversable.Traversable Language.Futhark.Syntax.Info instance GHC.Base.Functor Language.Futhark.Syntax.NoInfo instance Data.Foldable.Foldable Language.Futhark.Syntax.NoInfo instance Data.Traversable.Traversable Language.Futhark.Syntax.NoInfo -- | This module provides various simple ways to query and manipulate -- fundamental Futhark terms, such as types and values. The intent is to -- keep Futhark.Language.Syntax simple, and put whatever -- embellishments we need here. module Language.Futhark.Prop -- | The nature of something predefined. These can either be monomorphic or -- overloaded. An overloaded builtin is a list valid types it can be -- instantiated with, to the parameter and result type, with -- Nothing representing the overloaded parameter type. data Intrinsic IntrinsicMonoFun :: [PrimType] -> PrimType -> Intrinsic IntrinsicOverloadedFun :: [PrimType] -> [Maybe PrimType] -> Maybe PrimType -> Intrinsic IntrinsicPolyFun :: [TypeParamBase VName] -> [StructType] -> StructType -> Intrinsic IntrinsicType :: PrimType -> Intrinsic IntrinsicEquality :: Intrinsic -- | A map of all built-ins. intrinsics :: Map VName Intrinsic -- | The largest tag used by an intrinsic - this can be used to determine -- whether a VName refers to an intrinsic or a user-defined name. maxIntrinsicTag :: Int -- | Names of primitive types to types. This is only valid if no shadowing -- is going on, but useful for tools. namesToPrimTypes :: Map Name PrimType -- | Create a name with no qualifiers from a name. qualName :: v -> QualName v -- | Add another qualifier (at the head) to a qualified name. qualify :: v -> QualName v -> QualName v -- | Create a type name name with no qualifiers from a VName. typeName :: VName -> TypeName -- | The type of the value. valueType :: Value -> ValueType -- | The type of a basic value. primValueType :: PrimValue -> PrimType -- | Given an operator name, return the operator that determines its -- syntactical properties. leadingOperator :: Name -> BinOp -- | The modules imported by a Futhark program. progImports :: ProgBase f vn -> [(String, SrcLoc)] -- | The modules imported by a single declaration. decImports :: DecBase f vn -> [(String, SrcLoc)] -- | The set of module types used in any exported (non-local) declaration. progModuleTypes :: Ord vn => ProgBase f vn -> Set vn -- | Extract a leading ((name, namespace, file), remainder) from a -- documentation comment string. These are formatted as -- `name`@namespace[@file]. Let us hope that this pattern does not occur -- anywhere else. identifierReference :: String -> Maybe ((String, String, Maybe FilePath), String) -- | Given a list of strings representing entries in the stack trace and -- the index of the frame to highlight, produce a final -- newline-terminated string for showing to the user. This string should -- also be preceded by a newline. The most recent stack frame must come -- first in the list. prettyStacktrace :: Int -> [String] -> String -- | The type of an Futhark term. The aliasing will refer to itself, if the -- term is a non-tuple-typed variable. typeOf :: ExpBase Info VName -> PatternType -- | The set of identifiers bound in a pattern. patternIdents :: (Functor f, Ord vn) => PatternBase f vn -> Set (IdentBase f vn) -- | The set of names bound in a pattern. patternNames :: (Functor f, Ord vn) => PatternBase f vn -> Set vn -- | A mapping from names bound in a map to their identifier. patternMap :: Functor f => PatternBase f VName -> Map VName (IdentBase f VName) -- | The type of values bound by the pattern. patternType :: PatternBase Info VName -> PatternType -- | The type matched by the pattern, including shape declarations if -- present. patternStructType :: PatternBase Info VName -> StructType -- | When viewed as a function parameter, does this pattern correspond to a -- named parameter of some type? patternParam :: PatternBase Info VName -> (PName, StructType) -- | patternOrderZero pat is True if all of the types in -- the given pattern have order 0. patternOrderZero :: PatternBase Info vn -> Bool -- | Extract all the shape names that occur in a given pattern. patternDimNames :: PatternBase Info VName -> Set VName -- | Return the uniqueness of a type. uniqueness :: TypeBase shape as -> Uniqueness -- | unique t is True if the type of the argument is -- unique. unique :: TypeBase shape as -> Bool -- | Return the set of all variables mentioned in the aliasing of a type. aliases :: Monoid as => TypeBase shape as -> as -- | diet t returns a description of how a function parameter of -- type t might consume its argument. diet :: TypeBase shape as -> Diet -- | Return the dimensionality of a type. For non-arrays, this is zero. For -- a one-dimensional array it is one, for a two-dimensional it is two, -- and so forth. arrayRank :: TypeBase dim as -> Int -- | Return the shape of a type - for non-arrays, this is mempty. arrayShape :: TypeBase dim as -> ShapeDecl dim -- | Return any shape declarations in the type, with duplicates removed. nestedDims :: TypeBase (DimDecl VName) as -> [DimDecl VName] -- | orderZero t is True if the argument type has order 0, -- i.e., it is not a function type, does not contain a function type as a -- subcomponent, and may not be instantiated with a function type. orderZero :: TypeBase dim as -> Bool -- | Extract the parameter types and return type from a type. If the type -- is not an arrow type, the list of parameter types is empty. unfoldFunType :: TypeBase dim as -> ([TypeBase dim as], TypeBase dim as) -- | foldFunType ts ret creates a function type (Arrow) -- that takes ts as parameters and returns ret. foldFunType :: Monoid as => [TypeBase dim as] -> TypeBase dim as -> TypeBase dim as -- | The type names mentioned in a type. typeVars :: Monoid as => TypeBase dim as -> Set VName -- | Extract all the shape names that occur in a given type. typeDimNames :: TypeBase (DimDecl VName) als -> Set VName -- | The size of values of this type, in bytes. primByteSize :: Num a => PrimType -> a -- | Construct a ShapeDecl with the given number of AnyDim -- dimensions. rank :: Int -> ShapeDecl (DimDecl VName) -- | peelArray n t returns the type resulting from peeling the -- first n array dimensions from t. Returns -- Nothing if t has less than n dimensions. peelArray :: Int -> TypeBase dim as -> Maybe (TypeBase dim as) -- | stripArray n t removes the n outermost layers of the -- array. Essentially, it is the type of indexing an array of type -- t with n indexes. stripArray :: Int -> TypeBase dim as -> TypeBase dim as -- | arrayOf t s u constructs an array type. The convenience -- compared to using the Array constructor directly is that -- t can itself be an array. If t is an -- n-dimensional array, and s is a list of length -- n, the resulting type is of an n+m dimensions. The -- uniqueness of the new array will be u, no matter the -- uniqueness of t. arrayOf :: Monoid as => TypeBase dim as -> ShapeDecl dim -> Uniqueness -> TypeBase dim as -- | Convert any type to one that has rank information, no alias -- information, and no embedded names. toStructural :: TypeBase dim as -> TypeBase () () -- | Remove aliasing information from a type. toStruct :: TypeBase dim as -> TypeBase dim () -- | Replace no aliasing with an empty alias set. fromStruct :: TypeBase dim as -> TypeBase dim Aliasing -- | t `setAliases` als returns t, but with als -- substituted for any already present aliasing. setAliases :: TypeBase dim asf -> ast -> TypeBase dim ast -- | t `addAliases` f returns t, but with any already -- present aliasing replaced by f applied to that aliasing. addAliases :: TypeBase dim asf -> (asf -> ast) -> TypeBase dim ast -- | Set the uniqueness attribute of a type. If the type is a record or sum -- type, the uniqueness of its components will be modified. setUniqueness :: TypeBase dim as -> Uniqueness -> TypeBase dim as -- | Change the shape of a type to be just the rank. noSizes :: TypeBase (DimDecl vn) as -> TypeBase () as -- | Add size annotations that are all AnyDim. addSizes :: TypeBase () as -> TypeBase (DimDecl vn) as -- | Change all size annotations to be AnyDim. anySizes :: TypeBase (DimDecl vn) as -> TypeBase (DimDecl vn) as -- | Perform a traversal (possibly including replacement) on sizes that are -- parameters in a function type, but also including the type immediately -- passed to the function. Also passes along a set of the parameter names -- inside the type that have come in scope at the occurrence of the -- dimension. traverseDims :: forall f fdim tdim als. Applicative f => (Set VName -> DimPos -> fdim -> f tdim) -> TypeBase fdim als -> f (TypeBase tdim als) -- | Where does this dimension occur? data DimPos -- | Immediately in the argument to traverseDims. PosImmediate :: DimPos -- | In a function parameter type. PosParam :: DimPos -- | In a function return type. PosReturn :: DimPos -- | Figure out which of the sizes in a binding type must be passed -- explicitly, because their first use is as something else than just an -- array dimension. mustBeExplicit :: StructType -> Set VName -- | Figure out which of the sizes in a parameter type must be passed -- explicitly, because their first use is as something else than just an -- array dimension. mustBeExplicit is like this function, but -- first decomposes into parameter types. mustBeExplicitInType :: StructType -> Set VName -- | Create a record type corresponding to a tuple with the given element -- types. tupleRecord :: [TypeBase dim as] -> TypeBase dim as -- | Does this type corespond to a tuple? If so, return the elements of -- that tuple. isTupleRecord :: TypeBase dim as -> Maybe [TypeBase dim as] -- | Does this record map correspond to a tuple? areTupleFields :: Map Name a -> Maybe [a] -- | Construct a record map corresponding to a tuple. tupleFields :: [a] -> Map Name a -- | Increasing field names for a tuple (starts at 0). tupleFieldNames :: [Name] -- | Sort fields by their name; taking care to sort numeric fields by their -- numeric value. This ensures that tuples and tuple-like records match. sortFields :: Map Name a -> [(Name, a)] -- | Sort the constructors of a sum type in some well-defined (but not -- otherwise significant) manner. sortConstrs :: Map Name a -> [(Name, a)] -- | Is this a TypeParamType? isTypeParam :: TypeParamBase vn -> Bool -- | Is this a TypeParamDim? isSizeParam :: TypeParamBase vn -> Bool -- | Combine the shape information of types as much as possible. The first -- argument is the orignal type and the second is the type of the -- transformed expression. This is necessary since the original type may -- contain additional information (e.g., shape restrictions) from the -- user given annotation. combineTypeShapes :: (Monoid as, ArrayDim dim) => TypeBase dim as -> TypeBase dim as -> TypeBase dim as -- | Match the dimensions of otherwise assumed-equal types. matchDims :: (Monoid as, Monad m) => (d1 -> d2 -> m d1) -> TypeBase d1 as -> TypeBase d2 as -> m (TypeBase d1 as) -- | The type is leaving a scope, so clean up any aliases that reference -- the bound variables, and turn any dimensions that name them into -- AnyDim instead. unscopeType :: Set VName -> PatternType -> PatternType -- | Perform some operation on a given record field. Returns Nothing -- if that field does not exist. onRecordField :: (TypeBase dim als -> TypeBase dim als) -> [Name] -> TypeBase dim als -> Maybe (TypeBase dim als) -- | No information functor. Usually used for placeholder type- or aliasing -- information. data NoInfo a NoInfo :: NoInfo a -- | A type with no aliasing information but shape annotations. type UncheckedType = TypeBase (ShapeDecl Name) () -- | An expression with no type annotations. type UncheckedTypeExp = TypeExp Name -- | An identifier with no type annotations. type UncheckedIdent = IdentBase NoInfo Name -- | A type declaration with no expanded type. type UncheckedTypeDecl = TypeDeclBase NoInfo Name -- | An index with no type annotations. type UncheckedDimIndex = DimIndexBase NoInfo Name -- | An expression with no type annotations. type UncheckedExp = ExpBase NoInfo Name -- | A module expression with no type annotations. type UncheckedModExp = ModExpBase NoInfo Name -- | A module type expression with no type annotations. type UncheckedSigExp = SigExpBase NoInfo Name -- | A type parameter with no type annotations. type UncheckedTypeParam = TypeParamBase Name -- | A pattern with no type annotations. type UncheckedPattern = PatternBase NoInfo Name -- | A function declaration with no type annotations. type UncheckedValBind = ValBindBase NoInfo Name -- | A declaration with no type annotations. type UncheckedDec = DecBase NoInfo Name -- | A spec with no type annotations. type UncheckedSpec = SpecBase NoInfo Name -- | A Futhark program with no type annotations. type UncheckedProg = ProgBase NoInfo Name -- | A case (of a match expression) with no type annotations. type UncheckedCase = CaseBase NoInfo Name instance GHC.Show.Show Language.Futhark.Prop.DimPos instance GHC.Classes.Ord Language.Futhark.Prop.DimPos instance GHC.Classes.Eq Language.Futhark.Prop.DimPos -- | Futhark prettyprinter. This module defines Pretty instances for -- the AST defined in Language.Futhark.Syntax. module Language.Futhark.Pretty -- | Prettyprint a value, wrapped to 80 characters. pretty :: Pretty a => a -> String -- | Prettyprint a list enclosed in curly braces. prettyTuple :: Pretty a => [a] -> String -- | Given an operator name, return the operator that determines its -- syntactical properties. leadingOperator :: Name -> BinOp -- | A class for types that are variable names in the Futhark source -- language. This is used instead of a mere Pretty instance -- because in the compiler frontend we want to print VNames differently -- depending on whether the FUTHARK_COMPILER_DEBUGGING environment -- variable is set, yet in the backend we want to always print VNames -- with the tag. To avoid erroneously using the Pretty instance -- for VNames, we in fact only define it inside the modules for the core -- language (as an orphan instance). class IsName v pprName :: IsName v => v -> Doc -- | Prettyprint a name to a string. prettyName :: IsName v => v -> String -- | Class for type constructors that represent annotations. Used in the -- prettyprinter to either print the original AST, or the computed -- decoration. class Annot f -- | Extract value, if any. unAnnot :: Annot f => f a -> Maybe a instance Language.Futhark.Pretty.Annot Language.Futhark.Syntax.NoInfo instance Language.Futhark.Pretty.Annot Language.Futhark.Syntax.Info instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.TypeDeclBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.DimIndexBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ExpBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.FieldBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.CaseBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.LoopFormBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.PatternBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ProgBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.DecBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ModExpBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.TypeBindBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ValBindBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.SpecBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.SigExpBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.SigBindBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ModParamBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ModBindBase f vn) instance Language.Futhark.Pretty.IsName Language.Futhark.Core.VName instance Language.Futhark.Pretty.IsName Language.Futhark.Core.Name instance Language.Futhark.Pretty.IsName vn => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.DimDecl vn) instance Language.Futhark.Pretty.IsName vn => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.DimExp vn) instance Language.Futhark.Pretty.IsName vn => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ShapeDecl (Language.Futhark.Syntax.DimDecl vn)) instance Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ShapeDecl dim) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ScalarTypeBase dim as) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.TypeExp vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.TypeArgExp vn) instance Language.Futhark.Pretty.IsName vn => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.QualName vn) instance Language.Futhark.Pretty.IsName vn => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.IdentBase f vn) instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.TypeParamBase vn) instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Syntax.Value instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Syntax.PrimValue instance Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ShapeDecl ()) instance Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ShapeDecl GHC.Int.Int64) instance Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ShapeDecl GHC.Types.Bool) instance Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ShapeDecl dim) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.TypeBase dim as) instance Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ShapeDecl dim) => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.TypeArg dim) instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Syntax.AttrInfo instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Syntax.PatLit instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Syntax.Liftedness -- | Interface to the Futhark parser. module Language.Futhark.Parser -- | Parse an entire Futhark program from the given Text, using the -- FilePath as the source name for error messages. parseFuthark :: FilePath -> Text -> Either ParseError UncheckedProg -- | Parse an Futhark expression from the given String, using the -- FilePath as the source name for error messages. parseExp :: FilePath -> Text -> Either ParseError UncheckedExp -- | Parse a Futhark module expression from the given String, using -- the FilePath as the source name for error messages. parseModExp :: FilePath -> Text -> Either ParseError (ModExpBase NoInfo Name) -- | Parse an Futhark type from the given String, using the -- FilePath as the source name for error messages. parseType :: FilePath -> Text -> Either ParseError UncheckedTypeExp -- | Parse any Futhark value from the given String, using the -- FilePath as the source name for error messages. parseValue :: FilePath -> Text -> Either ParseError Value -- | Parse several Futhark values (separated by anything) from the given -- String, using the FilePath as the source name for error -- messages. parseValues :: FilePath -> Text -> Either ParseError [Value] -- | Parse either an expression or a declaration incrementally; favouring -- declarations in case of ambiguity. parseDecOrExpIncrM :: Monad m => m Text -> FilePath -> Text -> m (Either ParseError (Either UncheckedDec UncheckedExp)) -- | A parse error. Use show to get a human-readable description. data ParseError ParseError :: String -> ParseError -- | Given a starting position, produce tokens from the given text (or a -- lexer error). Returns the final position. scanTokensText :: Pos -> Text -> Either String ([L Token], Pos) -- | A value tagged with a source location. data L a L :: SrcLoc -> a -> L a -- | A lexical token. It does not itself contain position information, so -- in practice the parser will consume tokens tagged with a source -- position. data Token ID :: Name -> Token INDEXING :: Name -> Token QUALINDEXING :: [Name] -> Name -> Token QUALPAREN :: [Name] -> Name -> Token UNOP :: Name -> Token QUALUNOP :: [Name] -> Name -> Token SYMBOL :: BinOp -> [Name] -> Name -> Token CONSTRUCTOR :: Name -> Token PROJ_FIELD :: Name -> Token PROJ_INDEX :: Token INTLIT :: Integer -> Token STRINGLIT :: String -> Token I8LIT :: Int8 -> Token I16LIT :: Int16 -> Token I32LIT :: Int32 -> Token I64LIT :: Int64 -> Token U8LIT :: Word8 -> Token U16LIT :: Word16 -> Token U32LIT :: Word32 -> Token U64LIT :: Word64 -> Token FLOATLIT :: Double -> Token F32LIT :: Float -> Token F64LIT :: Double -> Token CHARLIT :: Char -> Token COLON :: Token COLON_GT :: Token BACKSLASH :: Token APOSTROPHE :: Token APOSTROPHE_THEN_HAT :: Token APOSTROPHE_THEN_TILDE :: Token BACKTICK :: Token HASH_LBRACKET :: Token TWO_DOTS :: Token TWO_DOTS_LT :: Token TWO_DOTS_GT :: Token THREE_DOTS :: Token LPAR :: Token RPAR :: Token RPAR_THEN_LBRACKET :: Token LBRACKET :: Token RBRACKET :: Token LCURLY :: Token RCURLY :: Token COMMA :: Token UNDERSCORE :: Token RIGHT_ARROW :: Token EQU :: Token ASTERISK :: Token NEGATE :: Token LTH :: Token HAT :: Token TILDE :: Token PIPE :: Token IF :: Token THEN :: Token ELSE :: Token LET :: Token LOOP :: Token IN :: Token FOR :: Token DO :: Token WITH :: Token ASSERT :: Token TRUE :: Token FALSE :: Token WHILE :: Token INCLUDE :: Token IMPORT :: Token ENTRY :: Token TYPE :: Token MODULE :: Token VAL :: Token OPEN :: Token LOCAL :: Token MATCH :: Token CASE :: Token DOC :: String -> Token EOF :: Token -- | Re-export the external Futhark modules for convenience. module Language.Futhark -- | An identifier with type- and aliasing information. type Ident = IdentBase Info VName -- | An index with type information. type DimIndex = DimIndexBase Info VName -- | An expression with type information. type Exp = ExpBase Info VName -- | A pattern with type information. type Pattern = PatternBase Info VName -- | A type-checked module expression. type ModExp = ModExpBase Info VName -- | A type-checked module parameter. type ModParam = ModParamBase Info VName -- | A type-checked module type expression. type SigExp = SigExpBase Info VName -- | A type-checked module binding. type ModBind = ModBindBase Info VName -- | A type-checked module type binding. type SigBind = SigBindBase Info VName -- | An constant declaration with type information. type ValBind = ValBindBase Info VName -- | A type-checked declaration. type Dec = DecBase Info VName -- | A type-checked specification. type Spec = SpecBase Info VName -- | An Futhark program with type information. type Prog = ProgBase Info VName -- | A type binding with type information. type TypeBind = TypeBindBase Info VName -- | A type declaration with type information type TypeDecl = TypeDeclBase Info VName -- | A known type arg with shape annotations. type StructTypeArg = TypeArg (DimDecl VName) -- | A known scalar type with no shape annotations. type ScalarType = ScalarTypeBase () -- | A type-checked type parameter. type TypeParam = TypeParamBase VName -- | A type-checked case (of a match expression). type Case = CaseBase Info VName -- | Definitions of various semantic objects (*not* the Futhark semantics -- themselves). module Language.Futhark.Semantic -- | Canonical reference to a Futhark code file. Does not include the -- .fut extension. This is most often a path relative to the -- current working directory of the compiler. data ImportName -- | Create an import name immediately from a file path specified by the -- user. mkInitialImport :: FilePath -> ImportName -- | We resolve '..' paths here and assume that no shenanigans are going on -- with symbolic links. If there is, too bad. Don't do that. mkImportFrom :: ImportName -> String -> SrcLoc -> ImportName -- | Create a .fut file corresponding to an ImportName. includeToFilePath :: ImportName -> FilePath -- | Produce a human-readable canonicalized string from an -- ImportName. includeToString :: ImportName -> String -- | The result of type checking some file. Can be passed to further -- invocations of the type checker. data FileModule FileModule :: TySet -> Env -> Prog -> FileModule -- | Abstract types. [fileAbs] :: FileModule -> TySet [fileEnv] :: FileModule -> Env [fileProg] :: FileModule -> Prog -- | A mapping from import names to imports. The ordering is significant. type Imports = [(String, FileModule)] -- | The space inhabited by a name. data Namespace -- | Functions and values. Term :: Namespace Type :: Namespace Signature :: Namespace -- | Modules produces environment with this representation. data Env Env :: Map VName BoundV -> Map VName TypeBinding -> Map VName MTy -> Map VName Mod -> NameMap -> Env [envVtable] :: Env -> Map VName BoundV [envTypeTable] :: Env -> Map VName TypeBinding [envSigTable] :: Env -> Map VName MTy [envModTable] :: Env -> Map VName Mod [envNameMap] :: Env -> NameMap -- | A mapping of abstract types to their liftedness. type TySet = Map (QualName VName) Liftedness -- | A parametric functor consists of a set of abstract types, the -- environment of its parameter, and the resulting module type. data FunSig FunSig :: TySet -> Mod -> MTy -> FunSig [funSigAbs] :: FunSig -> TySet [funSigMod] :: FunSig -> Mod [funSigMty] :: FunSig -> MTy -- | A mapping from names (which always exist in some namespace) to a -- unique (tagged) name. type NameMap = Map (Namespace, Name) (QualName VName) -- | Type parameters, list of parameter types (optinally named), and return -- type. The type parameters are in scope in both parameter types and the -- return type. Non-functional values have only a return type. data BoundV BoundV :: [TypeParam] -> StructType -> BoundV -- | Representation of a module, which is either a plain environment, or a -- parametric module ("functor" in SML). data Mod ModEnv :: Env -> Mod ModFun :: FunSig -> Mod -- | A binding from a name to its definition as a type. data TypeBinding TypeAbbr :: Liftedness -> [TypeParam] -> StructType -> TypeBinding -- | Representation of a module type. data MTy MTy :: TySet -> Mod -> MTy -- | Abstract types in the module type. [mtyAbs] :: MTy -> TySet [mtyMod] :: MTy -> Mod instance GHC.Show.Show Language.Futhark.Semantic.ImportName instance GHC.Classes.Ord Language.Futhark.Semantic.ImportName instance GHC.Classes.Eq Language.Futhark.Semantic.ImportName instance GHC.Enum.Enum Language.Futhark.Semantic.Namespace instance GHC.Show.Show Language.Futhark.Semantic.Namespace instance GHC.Classes.Ord Language.Futhark.Semantic.Namespace instance GHC.Classes.Eq Language.Futhark.Semantic.Namespace instance GHC.Show.Show Language.Futhark.Semantic.TypeBinding instance GHC.Classes.Eq Language.Futhark.Semantic.TypeBinding instance GHC.Show.Show Language.Futhark.Semantic.BoundV instance GHC.Show.Show Language.Futhark.Semantic.FunSig instance GHC.Show.Show Language.Futhark.Semantic.Mod instance GHC.Show.Show Language.Futhark.Semantic.MTy instance GHC.Show.Show Language.Futhark.Semantic.Env instance GHC.Base.Semigroup Language.Futhark.Semantic.Env instance GHC.Base.Monoid Language.Futhark.Semantic.Env instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Semantic.MTy instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Semantic.Mod instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Semantic.Env instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Semantic.Namespace instance Data.Loc.Located Language.Futhark.Semantic.ImportName -- | An interpreter operating on type-checked source Futhark terms. -- Relatively slow. module Language.Futhark.Interpreter -- | The interpreter context. All evaluation takes place with respect to a -- context, and it can be extended with more definitions, which is how -- the REPL works. data Ctx Ctx :: Env -> Map FilePath Env -> Ctx [ctxEnv] :: Ctx -> Env [ctxImports] :: Ctx -> Map FilePath Env -- | The actual type- and value environment. data Env -- | An error occurred during interpretation due to an error in the user -- program. Actual interpreter errors will be signaled with an IO -- exception (error). data InterpreterError -- | The initial environment contains definitions of the various intrinsic -- functions. initialCtx :: Ctx interpretExp :: Ctx -> Exp -> F ExtOp Value interpretDec :: Ctx -> Dec -> F ExtOp Ctx interpretImport :: Ctx -> (FilePath, Prog) -> F ExtOp Ctx -- | Execute the named function on the given arguments; may fail horribly -- if these are ill-typed. interpretFunction :: Ctx -> VName -> [Value] -> Either String (F ExtOp Value) data ExtOp a ExtOpTrace :: Loc -> String -> a -> ExtOp a ExtOpBreak :: BreakReason -> NonEmpty StackFrame -> a -> ExtOp a ExtOpError :: InterpreterError -> ExtOp a -- | What is the reason for this break point? data BreakReason -- | An explicit breakpoint in the program. BreakPoint :: BreakReason -- | A BreakNaN :: BreakReason data StackFrame StackFrame :: Loc -> Ctx -> StackFrame [stackFrameLoc] :: StackFrame -> Loc [stackFrameCtx] :: StackFrame -> Ctx typeCheckerEnv :: Env -> Env -- | A fully evaluated Futhark value. data Value ValuePrim :: !PrimValue -> Value ValueArray :: ValueShape -> !Array Int Value -> Value ValueRecord :: Map Name Value -> Value fromTuple :: Value -> Maybe [Value] -- | Does the value correspond to an empty array? isEmptyArray :: Value -> Bool -- | String representation of an empty array with the provided element -- type. This is pretty ad-hoc - don't expect good results unless the -- element type is a primitive. prettyEmptyArray :: TypeBase () () -> Value -> String instance Data.Traversable.Traversable Language.Futhark.Interpreter.Shape instance Data.Foldable.Foldable Language.Futhark.Interpreter.Shape instance GHC.Base.Functor Language.Futhark.Interpreter.Shape instance GHC.Show.Show d => GHC.Show.Show (Language.Futhark.Interpreter.Shape d) instance GHC.Classes.Eq d => GHC.Classes.Eq (Language.Futhark.Interpreter.Shape d) instance Control.Monad.State.Class.MonadState Language.Futhark.Interpreter.Sizes Language.Futhark.Interpreter.EvalM instance Control.Monad.Reader.Class.MonadReader (Language.Futhark.Interpreter.Stack, Data.Map.Internal.Map GHC.IO.FilePath Language.Futhark.Interpreter.Env) Language.Futhark.Interpreter.EvalM instance Control.Monad.Free.Class.MonadFree Language.Futhark.Interpreter.ExtOp Language.Futhark.Interpreter.EvalM instance GHC.Base.Functor Language.Futhark.Interpreter.EvalM instance GHC.Base.Applicative Language.Futhark.Interpreter.EvalM instance GHC.Base.Monad Language.Futhark.Interpreter.EvalM instance Data.Loc.Located Language.Futhark.Interpreter.StackFrame instance GHC.Base.Functor Language.Futhark.Interpreter.ExtOp instance GHC.Classes.Eq Language.Futhark.Interpreter.Value instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Interpreter.Value instance GHC.Base.Monoid Language.Futhark.Interpreter.Env instance GHC.Base.Semigroup Language.Futhark.Interpreter.Env instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Interpreter.Indexing instance GHC.Show.Show Language.Futhark.Interpreter.InterpreterError instance Text.PrettyPrint.Mainland.Class.Pretty d => Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Interpreter.Shape d) module Futhark.Internalise.TypesValues internaliseReturnType :: TypeBase (DimDecl VName) () -> InternaliseM [TypeBase ExtShape Uniqueness] internaliseLambdaReturnType :: TypeBase (DimDecl VName) () -> InternaliseM [TypeBase Shape NoUniqueness] -- | As internaliseReturnType, but returns components of a top-level -- tuple type piecemeal. internaliseEntryReturnType :: TypeBase (DimDecl VName) () -> InternaliseM [[TypeBase ExtShape Uniqueness]] internaliseType :: TypeBase (DimDecl VName) () -> InternaliseM [TypeBase ExtShape Uniqueness] internaliseParamTypes :: [TypeBase (DimDecl VName) ()] -> InternaliseM [[TypeBase Shape Uniqueness]] internaliseLoopParamType :: TypeBase (DimDecl VName) () -> InternaliseM [TypeBase Shape Uniqueness] -- | Convert an external primitive to an internal primitive. internalisePrimType :: PrimType -> PrimType -- | How many core language values are needed to represent one source -- language value of the given type? internalisedTypeSize :: TypeBase (DimDecl VName) () -> InternaliseM Int internaliseSumType :: Map Name [StructType] -> InternaliseM ([TypeBase ExtShape Uniqueness], Map Name (Int, [Int])) -- | Convert an external primitive value to an internal primitive value. internalisePrimValue :: PrimValue -> PrimValue instance Control.Monad.State.Class.MonadState Futhark.Internalise.TypesValues.TypeState Futhark.Internalise.TypesValues.InternaliseTypeM instance GHC.Base.Monad Futhark.Internalise.TypesValues.InternaliseTypeM instance GHC.Base.Applicative Futhark.Internalise.TypesValues.InternaliseTypeM instance GHC.Base.Functor Futhark.Internalise.TypesValues.InternaliseTypeM module Futhark.Internalise.Lambdas -- | A function for internalising lambdas. type InternaliseLambda = Exp -> [Type] -> InternaliseM ([LParam], Body, [Type]) internaliseMapLambda :: InternaliseLambda -> Exp -> [SubExp] -> InternaliseM Lambda internaliseStreamMapLambda :: InternaliseLambda -> Exp -> [SubExp] -> InternaliseM Lambda internaliseFoldLambda :: InternaliseLambda -> Exp -> [Type] -> [Type] -> InternaliseM Lambda internaliseStreamLambda :: InternaliseLambda -> Exp -> [Type] -> InternaliseM ([LParam], Body) internalisePartitionLambda :: InternaliseLambda -> Int -> Exp -> [SubExp] -> InternaliseM Lambda -- | Internalising bindings. module Futhark.Internalise.Bindings bindingParams :: [TypeParam] -> [Pattern] -> ([FParam] -> [[FParam]] -> InternaliseM a) -> InternaliseM a bindingLoopParams :: [TypeParam] -> Pattern -> ([FParam] -> [FParam] -> InternaliseM a) -> InternaliseM a bindingLambdaParams :: [Pattern] -> [Type] -> ([LParam] -> InternaliseM a) -> InternaliseM a stmPattern :: Pattern -> [Type] -> ([VName] -> InternaliseM a) -> InternaliseM a -- | This module defines an efficient value representation as well as -- parsing and comparison functions. This is because the standard Futhark -- parser is not able to cope with large values (like arrays that are -- tens of megabytes in size). The representation defined here does not -- support tuples, so don't use those as input/output for your test -- programs. module Futhark.Test.Values -- | An efficiently represented Futhark value. Use pretty to get a -- human-readable representation, and put to obtain binary a -- representation. data Value Int8Value :: Vector Int -> Vector Int8 -> Value Int16Value :: Vector Int -> Vector Int16 -> Value Int32Value :: Vector Int -> Vector Int32 -> Value Int64Value :: Vector Int -> Vector Int64 -> Value Word8Value :: Vector Int -> Vector Word8 -> Value Word16Value :: Vector Int -> Vector Word16 -> Value Word32Value :: Vector Int -> Vector Word32 -> Value Word64Value :: Vector Int -> Vector Word64 -> Value Float32Value :: Vector Int -> Vector Float -> Value Float64Value :: Vector Int -> Vector Double -> Value BoolValue :: Vector Int -> Vector Bool -> Value -- | An Unboxed vector. type Vector = Vector -- | Parse Futhark values from the given bytestring. readValues :: ByteString -> Maybe [Value] -- | A representation of the simple values we represent in this module. data ValueType ValueType :: [Int] -> PrimType -> ValueType -- | A textual description of the type of a value. Follows Futhark type -- notation, and contains the exact dimension sizes if an array. valueType :: Value -> ValueType -- | Compare two sets of Futhark values for equality. Shapes and types must -- also match. compareValues :: [Value] -> [Value] -> [Mismatch] -- | As compareValues, but only reports one mismatch. compareValues1 :: [Value] -> [Value] -> Maybe Mismatch -- | Two values differ in some way. The Show instance produces a -- human-readable explanation. data Mismatch instance GHC.Show.Show Futhark.Test.Values.Value instance GHC.Show.Show Futhark.Test.Values.ValueType instance GHC.Show.Show Futhark.Test.Values.Mismatch instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.Test.Values.ValueType instance Data.Binary.Class.Binary Futhark.Test.Values.Value instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.Test.Values.Value -- | Facilities for reading Futhark test programs. A Futhark test program -- is an ordinary Futhark program where an initial comment block -- specifies input- and output-sets. module Futhark.Test -- | Read the test specification from the given Futhark program. testSpecFromFile :: FilePath -> IO (Either String ProgramTest) -- | Like testSpecFromFile, but kills the process on error. testSpecFromFileOrDie :: FilePath -> IO ProgramTest -- | Read test specifications from the given paths, which can be a files or -- directories containing .fut files and further directories. testSpecsFromPaths :: [FilePath] -> IO (Either String [(FilePath, ProgramTest)]) -- | Like testSpecsFromPaths, but kills the process on errors. testSpecsFromPathsOrDie :: [FilePath] -> IO [(FilePath, ProgramTest)] -- | Try to parse a several values from a byte string. The String -- parameter is used for error messages. valuesFromByteString :: String -> ByteString -> Either String [Value] -- | The futhark executable we are using. This is merely a wrapper -- around the underlying file path, because we will be using a lot of -- different file paths here, and it is easy to mix them up. newtype FutharkExe FutharkExe :: FilePath -> FutharkExe -- | Get the actual core Futhark values corresponding to a Values -- specification. The first FilePath is the path of the -- futhark executable, and the second is the directory which -- file paths are read relative to. getValues :: (MonadFail m, MonadIO m) => FutharkExe -> FilePath -> Values -> m [Value] -- | Extract a pretty representation of some Values. In the IO monad -- because this might involve reading from a file. There is no guarantee -- that the resulting byte string yields a readable value. getValuesBS :: MonadIO m => FutharkExe -> FilePath -> Values -> m ByteString -- | Compare two sets of Futhark values for equality. Shapes and types must -- also match. compareValues :: [Value] -> [Value] -> [Mismatch] -- | As compareValues, but only reports one mismatch. compareValues1 :: [Value] -> [Value] -> Maybe Mismatch -- | When/if generating a reference output file for this run, what should -- it be called? Includes the "data/" folder. testRunReferenceOutput :: FilePath -> Text -> TestRun -> FilePath -- | Get the values corresponding to an expected result, if any. getExpectedResult :: (MonadFail m, MonadIO m) => FutharkExe -> FilePath -> Text -> TestRun -> m (ExpectedResult [Value]) -- | compileProgram extra_options futhark backend program compiles -- program with the command futhark backend -- extra-options..., and returns stdout and stderr of the compiler. -- Throws an IO exception containing stderr if compilation fails. compileProgram :: (MonadIO m, MonadError [Text] m) => [String] -> FutharkExe -> String -> FilePath -> m (ByteString, ByteString) -- | runProgram futhark runner extra_options prog entry input runs -- the Futhark program prog (which must have the .fut -- suffix), executing the entry entry point and providing -- input on stdin. The program must have been compiled in -- advance with compileProgram. If runner is non-null, -- then it is used as "interpreter" for the compiled program (e.g. -- python when using the Python backends). The -- extra_options are passed to the program. runProgram :: MonadIO m => FutharkExe -> FilePath -> [String] -> String -> Text -> Values -> m (ExitCode, ByteString, ByteString) -- | Ensure that any reference output files exist, or create them (by -- compiling the program with the reference compiler and running it on -- the input) if necessary. ensureReferenceOutput :: (MonadIO m, MonadError [Text] m) => Maybe Int -> FutharkExe -> String -> FilePath -> [InputOutputs] -> m () -- | Determine the --tuning options to pass to the program. The first -- argument is the extension of the tuning file, or Nothing if -- none should be used. determineTuning :: MonadIO m => Maybe FilePath -> FilePath -> m ([String], String) -- | The name we use for compiled programs. binaryName :: FilePath -> FilePath -- | Two values differ in some way. The Show instance produces a -- human-readable explanation. data Mismatch -- | Description of a test to be carried out on a Futhark program. The -- Futhark program is stored separately. data ProgramTest ProgramTest :: Text -> [Text] -> TestAction -> ProgramTest [testDescription] :: ProgramTest -> Text [testTags] :: ProgramTest -> [Text] [testAction] :: ProgramTest -> TestAction -- | A structure test specifies a compilation pipeline, as well as metrics -- for the program coming out the other end. data StructureTest StructureTest :: StructurePipeline -> AstMetrics -> StructureTest -- | How a program can be transformed. data StructurePipeline KernelsPipeline :: StructurePipeline SOACSPipeline :: StructurePipeline SequentialCpuPipeline :: StructurePipeline GpuPipeline :: StructurePipeline -- | A warning test requires that a warning matching the regular expression -- is produced. The program must also compile succesfully. data WarningTest ExpectedWarning :: Text -> Regex -> WarningTest -- | How to test a program. data TestAction CompileTimeFailure :: ExpectedError -> TestAction RunCases :: [InputOutputs] -> [StructureTest] -> [WarningTest] -> TestAction -- | The error expected for a negative test. data ExpectedError AnyError :: ExpectedError ThisError :: Text -> Regex -> ExpectedError -- | Input and output pairs for some entry point(s). data InputOutputs InputOutputs :: Text -> [TestRun] -> InputOutputs [iosEntryPoint] :: InputOutputs -> Text [iosTestRuns] :: InputOutputs -> [TestRun] -- | A condition for execution, input, and expected result. data TestRun TestRun :: [String] -> Values -> ExpectedResult Success -> Int -> String -> TestRun [runTags] :: TestRun -> [String] [runInput] :: TestRun -> Values [runExpectedResult] :: TestRun -> ExpectedResult Success [runIndex] :: TestRun -> Int [runDescription] :: TestRun -> String -- | How a test case is expected to terminate. data ExpectedResult values -- | Execution suceeds, with or without expected result values. Succeeds :: Maybe values -> ExpectedResult values -- | Execution fails with this error. RunTimeFailure :: ExpectedError -> ExpectedResult values -- | The result expected from a succesful execution. data Success -- | These values are expected. SuccessValues :: Values -> Success -- | Compute expected values from executing a known-good reference -- implementation. SuccessGenerateValues :: Success -- | Several Values - either literally, or by reference to a file, or to be -- generated on demand. data Values Values :: [Value] -> Values InFile :: FilePath -> Values GenValues :: [GenValue] -> Values -- | An efficiently represented Futhark value. Use pretty to get a -- human-readable representation, and put to obtain binary a -- representation. data Value instance GHC.Show.Show Futhark.Test.StructurePipeline instance GHC.Show.Show Futhark.Test.StructureTest instance GHC.Show.Show Futhark.Test.GenValue instance GHC.Show.Show Futhark.Test.Values instance GHC.Show.Show values => GHC.Show.Show (Futhark.Test.ExpectedResult values) instance GHC.Show.Show Futhark.Test.Success instance GHC.Show.Show Futhark.Test.TestRun instance GHC.Show.Show Futhark.Test.InputOutputs instance GHC.Show.Show Futhark.Test.TestAction instance GHC.Show.Show Futhark.Test.ProgramTest instance GHC.Show.Show Futhark.Test.FutharkExe instance GHC.Classes.Ord Futhark.Test.FutharkExe instance GHC.Classes.Eq Futhark.Test.FutharkExe instance GHC.Show.Show Futhark.Test.WarningTest instance GHC.Show.Show Futhark.Test.ExpectedError -- | Facilities for handling Futhark benchmark results. A Futhark benchmark -- program is just like a Futhark test program. module Futhark.Bench -- | The runtime of a single succesful run. newtype RunResult RunResult :: Int -> RunResult [runMicroseconds] :: RunResult -> Int -- | The results for a single named dataset is either an error message, or -- runtime measurements along the stderr that was produced. data DataResult DataResult :: String -> Either Text ([RunResult], Text) -> DataResult -- | The results for all datasets for some benchmark program. data BenchResult BenchResult :: FilePath -> [DataResult] -> BenchResult -- | Transform benchmark results to a JSON bytestring. encodeBenchResults :: [BenchResult] -> ByteString -- | Decode benchmark results from a JSON bytestring. decodeBenchResults :: ByteString -> Either String [BenchResult] -- | The name we use for compiled programs. binaryName :: FilePath -> FilePath -- | Run the benchmark program on the indicated dataset. benchmarkDataset :: RunOptions -> FutharkExe -> FilePath -> Text -> Values -> Maybe Success -> FilePath -> IO (Either Text ([RunResult], Text)) -- | How to run a benchmark. data RunOptions RunOptions :: String -> Int -> [String] -> Int -> Int -> Maybe (Int -> IO ()) -> RunOptions [runRunner] :: RunOptions -> String [runRuns] :: RunOptions -> Int [runExtraOptions] :: RunOptions -> [String] [runTimeout] :: RunOptions -> Int [runVerbose] :: RunOptions -> Int -- | Invoked for every runtime measured during the run. Can be used to -- provide a progress bar. [runResultAction] :: RunOptions -> Maybe (Int -> IO ()) -- | Compile and produce reference datasets. prepareBenchmarkProgram :: MonadIO m => Maybe Int -> CompileOptions -> FilePath -> [InputOutputs] -> m (Either (String, Maybe ByteString) ()) -- | How to compile a benchmark. data CompileOptions CompileOptions :: String -> String -> [String] -> CompileOptions [compFuthark] :: CompileOptions -> String [compBackend] :: CompileOptions -> String [compOptions] :: CompileOptions -> [String] instance GHC.Show.Show Futhark.Bench.RunResult instance GHC.Classes.Eq Futhark.Bench.RunResult instance GHC.Show.Show Futhark.Bench.DataResult instance GHC.Classes.Eq Futhark.Bench.DataResult instance GHC.Show.Show Futhark.Bench.BenchResult instance GHC.Classes.Eq Futhark.Bench.BenchResult instance Data.Aeson.Types.ToJSON.ToJSON Futhark.Bench.BenchResults instance Data.Aeson.Types.FromJSON.FromJSON Futhark.Bench.BenchResults instance Data.Aeson.Types.ToJSON.ToJSON Futhark.Bench.DataResults instance Data.Aeson.Types.FromJSON.FromJSON Futhark.Bench.DataResults instance Data.Aeson.Types.ToJSON.ToJSON Futhark.Bench.RunResult instance Data.Aeson.Types.FromJSON.FromJSON Futhark.Bench.RunResult -- | Functions for generic traversals across Futhark syntax trees. The -- motivation for this module came from dissatisfaction with rewriting -- the same trivial tree recursions for every module. A possible -- alternative would be to use normal "Scrap your -- boilerplate"-techniques, but these are rejected for two reasons: -- -- -- -- Instead, this module defines various traversals of the Futhark syntax -- tree. The implementation is rather tedious, but the interface is easy -- to use. -- -- A traversal of the Futhark syntax tree is expressed as a record of -- functions expressing the operations to be performed on the various -- types of nodes. module Language.Futhark.Traversals -- | Express a monad mapping operation on a syntax node. Each element of -- this structure expresses the operation to be performed on a given -- child. data ASTMapper m ASTMapper :: (ExpBase Info VName -> m (ExpBase Info VName)) -> (VName -> m VName) -> (QualName VName -> m (QualName VName)) -> (StructType -> m StructType) -> (PatternType -> m PatternType) -> ASTMapper m [mapOnExp] :: ASTMapper m -> ExpBase Info VName -> m (ExpBase Info VName) [mapOnName] :: ASTMapper m -> VName -> m VName [mapOnQualName] :: ASTMapper m -> QualName VName -> m (QualName VName) [mapOnStructType] :: ASTMapper m -> StructType -> m StructType [mapOnPatternType] :: ASTMapper m -> PatternType -> m PatternType -- | The class of things that we can map an ASTMapper across. class ASTMappable x -- | Map a monadic action across the immediate children of an object. -- Importantly, the astMap action is not invoked for the object -- itself, and the mapping does not descend recursively into -- subexpressions. The mapping is done left-to-right. astMap :: (ASTMappable x, Monad m) => ASTMapper m -> x -> m x -- | An ASTMapper that just leaves its input unchanged. identityMapper :: Monad m => ASTMapper m -- | Remove all annotations from an expression, but retain the name/scope -- information. bareExp :: ExpBase Info VName -> ExpBase NoInfo VName instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.ExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.TypeExp Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.TypeArgExp Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.DimExp Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.TypeParamBase Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.DimIndexBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable Language.Futhark.Syntax.Alias instance Language.Futhark.Traversals.ASTMappable Language.Futhark.Syntax.Aliasing instance Language.Futhark.Traversals.ASTMappable Language.Futhark.Syntax.StructType instance Language.Futhark.Traversals.ASTMappable Language.Futhark.Syntax.PatternType instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.TypeDeclBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.IdentBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.PatternBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.CaseBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) instance Language.Futhark.Traversals.ASTMappable a => Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.Info a) instance Language.Futhark.Traversals.ASTMappable a => Language.Futhark.Traversals.ASTMappable [a] instance Language.Futhark.Traversals.ASTMappable a => Language.Futhark.Traversals.ASTMappable (GHC.Base.NonEmpty a) instance (Language.Futhark.Traversals.ASTMappable a, Language.Futhark.Traversals.ASTMappable b) => Language.Futhark.Traversals.ASTMappable (a, b) instance (Language.Futhark.Traversals.ASTMappable a, Language.Futhark.Traversals.ASTMappable b, Language.Futhark.Traversals.ASTMappable c) => Language.Futhark.Traversals.ASTMappable (a, b, c) -- | Facilities for answering queries about a program, such as "what -- appears at this source location", or "where is this name bound". The -- intent is that this is used as a building block for IDE-like -- functionality. module Language.Futhark.Query -- | What a name is bound to. data BoundTo BoundTerm :: StructType -> Loc -> BoundTo BoundModule :: Loc -> BoundTo BoundModuleType :: Loc -> BoundTo BoundType :: Loc -> BoundTo -- | Where was a bound variable actually bound? That is, what is the -- location of its definition? boundLoc :: BoundTo -> Loc -- | Information about what is at the given source location. data AtPos AtName :: QualName VName -> Maybe BoundTo -> Loc -> AtPos -- | Information about what's at the given source position. Returns -- Nothing if there is nothing there, including if the source -- position is invalid. atPos :: Imports -> Pos -> Maybe AtPos -- | Position type. data Pos -- | Source file name, line, column, and character offset. -- -- Line numbering starts at 1, column offset starts at 1, and character -- offset starts at 0. Pos :: !FilePath -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> Pos instance GHC.Show.Show Language.Futhark.Query.BoundTo instance GHC.Classes.Eq Language.Futhark.Query.BoundTo instance GHC.Show.Show Language.Futhark.Query.Def instance GHC.Classes.Eq Language.Futhark.Query.Def instance GHC.Show.Show Language.Futhark.Query.AtPos instance GHC.Classes.Eq Language.Futhark.Query.AtPos -- | Partially evaluate all modules away from a source Futhark program. -- This is implemented as a source-to-source transformation. module Futhark.Internalise.Defunctorise -- | Perform defunctorisation. transformProg :: MonadFreshNames m => Imports -> m [Dec] instance GHC.Show.Show Futhark.Internalise.Defunctorise.Scope instance GHC.Show.Show Futhark.Internalise.Defunctorise.Mod instance Control.Monad.Writer.Class.MonadWriter (Data.DList.Internal.DList Language.Futhark.Dec) Futhark.Internalise.Defunctorise.TransformM instance Control.Monad.Reader.Class.MonadReader Futhark.Internalise.Defunctorise.Env Futhark.Internalise.Defunctorise.TransformM instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Internalise.Defunctorise.TransformM instance GHC.Base.Monad Futhark.Internalise.Defunctorise.TransformM instance GHC.Base.Functor Futhark.Internalise.Defunctorise.TransformM instance GHC.Base.Applicative Futhark.Internalise.Defunctorise.TransformM instance GHC.Base.Semigroup Futhark.Internalise.Defunctorise.Scope instance GHC.Base.Monoid Futhark.Internalise.Defunctorise.Scope -- | Defunctionalization of typed, monomorphic Futhark programs without -- modules. module Futhark.Internalise.Defunctionalise -- | Transform a list of top-level value bindings. May produce new lifted -- function definitions, which are placed in front of the resulting list -- of declarations. transformProg :: MonadFreshNames m => [ValBind] -> m [ValBind] instance GHC.Show.Show Futhark.Internalise.Defunctionalise.ExtExp instance GHC.Show.Show Futhark.Internalise.Defunctionalise.StaticVal instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Internalise.Defunctionalise.DefM instance Control.Monad.Writer.Class.MonadWriter (Data.Sequence.Internal.Seq Language.Futhark.ValBind) Futhark.Internalise.Defunctionalise.DefM instance Control.Monad.Reader.Class.MonadReader (Data.Set.Internal.Set Language.Futhark.Core.VName, Futhark.Internalise.Defunctionalise.Env) Futhark.Internalise.Defunctionalise.DefM instance GHC.Base.Monad Futhark.Internalise.Defunctionalise.DefM instance GHC.Base.Applicative Futhark.Internalise.Defunctionalise.DefM instance GHC.Base.Functor Futhark.Internalise.Defunctionalise.DefM instance GHC.Show.Show Futhark.Internalise.Defunctionalise.NameSet instance GHC.Base.Semigroup Futhark.Internalise.Defunctionalise.NameSet instance GHC.Base.Monoid Futhark.Internalise.Defunctionalise.NameSet -- | Checking for missing cases in a match expression. Based on "Warnings -- for pattern matching" by Luc Maranget. We only detect inexhaustiveness -- here - ideally, we would also like to check for redundant cases. module Language.Futhark.TypeChecker.Match unmatched :: [Pattern] -> [Match] -- | A representation of the essentials of a pattern. data Match instance GHC.Show.Show Language.Futhark.TypeChecker.Match.Constr instance GHC.Classes.Ord Language.Futhark.TypeChecker.Match.Constr instance GHC.Classes.Eq Language.Futhark.TypeChecker.Match.Constr instance GHC.Show.Show Language.Futhark.TypeChecker.Match.Match instance GHC.Classes.Ord Language.Futhark.TypeChecker.Match.Match instance GHC.Classes.Eq Language.Futhark.TypeChecker.Match.Match instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.TypeChecker.Match.Match -- | A very simple representation of collections of warnings. Warnings have -- a position (so they can be ordered), and their Show-instance -- produces a human-readable string. module Language.Futhark.Warnings -- | The warnings produced by the compiler. The Show instance -- produces a human-readable description. data Warnings -- | True if there are any warnings in the set. anyWarnings :: Warnings -> Bool -- | A single warning at the given location. singleWarning :: SrcLoc -> Doc -> Warnings -- | A single warning at the given location, but also with a stack trace -- (sort of) to the location. singleWarning' :: SrcLoc -> [SrcLoc] -> Doc -> Warnings instance GHC.Base.Semigroup Language.Futhark.Warnings.Warnings instance GHC.Base.Monoid Language.Futhark.Warnings.Warnings instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.Warnings.Warnings -- | Main monad in which the type checker runs, as well as ancillary data -- definitions. module Language.Futhark.TypeChecker.Monad -- | The type checker runs in this monad. data TypeM a -- | Run a TypeM computation. runTypeM :: Env -> ImportTable -> ImportName -> VNameSource -> TypeM a -> (Warnings, Either TypeError (a, VNameSource)) -- | Retrieve the current Env. askEnv :: TypeM Env -- | The name of the current file/import. askImportName :: TypeM ImportName -- | Map source-level names do fresh unique internal names, and evaluate a -- type checker context with the mapping active. bindSpaced :: MonadTypeChecker m => [(Namespace, Name)] -> m a -> m a -- | Try to prepend qualifiers to the type names such that they represent -- how to access the type in some scope. qualifyTypeVars :: Env -> [VName] -> [VName] -> TypeBase (DimDecl VName) as -> TypeBase (DimDecl VName) as -- | Look up a module type. lookupMTy :: SrcLoc -> QualName Name -> TypeM (QualName VName, MTy) -- | Look up an import. lookupImport :: SrcLoc -> FilePath -> TypeM (FilePath, Env) -- | Evaluate a TypeM computation within an extended (not -- replaced) environment. localEnv :: Env -> TypeM a -> TypeM a -- | Information about an error during type checking. data TypeError TypeError :: SrcLoc -> Notes -> Doc -> TypeError -- | An unexpected functor appeared! unappliedFunctor :: MonadTypeChecker m => SrcLoc -> m a -- | An unknown variable was referenced. unknownVariable :: MonadTypeChecker m => Namespace -> QualName Name -> SrcLoc -> m a -- | An unknown type was referenced. unknownType :: MonadTypeChecker m => SrcLoc -> QualName Name -> m a -- | A name prefixed with an underscore was used. underscoreUse :: MonadTypeChecker m => SrcLoc -> QualName Name -> m a -- | A collection of Notes. data Notes -- | A single note. aNote :: Pretty a => a -> Notes -- | Monads that support type checking. The reason we have this internal -- interface is because we use distinct monads for checking expressions -- and declarations. class Monad m => MonadTypeChecker m warn :: (MonadTypeChecker m, Located loc) => loc -> Doc -> m () newName :: MonadTypeChecker m => VName -> m VName newID :: MonadTypeChecker m => Name -> m VName bindNameMap :: MonadTypeChecker m => NameMap -> m a -> m a bindVal :: MonadTypeChecker m => VName -> BoundV -> m a -> m a checkQualName :: MonadTypeChecker m => Namespace -> QualName Name -> SrcLoc -> m (QualName VName) lookupType :: MonadTypeChecker m => SrcLoc -> QualName Name -> m (QualName VName, [TypeParam], StructType, Liftedness) lookupMod :: MonadTypeChecker m => SrcLoc -> QualName Name -> m (QualName VName, Mod) lookupVar :: MonadTypeChecker m => SrcLoc -> QualName Name -> m (QualName VName, PatternType) checkNamedDim :: MonadTypeChecker m => SrcLoc -> QualName Name -> m (QualName VName) typeError :: (MonadTypeChecker m, Located loc) => loc -> Notes -> Doc -> m a -- | Elaborate the given name in the given namespace at the given location, -- producing the corresponding unique VName. checkName :: MonadTypeChecker m => Namespace -> Name -> SrcLoc -> m VName -- | Turn a Left TypeError into an actual error. badOnLeft :: Either TypeError a -> TypeM a -- | Modules produces environment with this representation. data Env Env :: Map VName BoundV -> Map VName TypeBinding -> Map VName MTy -> Map VName Mod -> NameMap -> Env [envVtable] :: Env -> Map VName BoundV [envTypeTable] :: Env -> Map VName TypeBinding [envSigTable] :: Env -> Map VName MTy [envModTable] :: Env -> Map VName Mod [envNameMap] :: Env -> NameMap -- | A mapping of abstract types to their liftedness. type TySet = Map (QualName VName) Liftedness -- | A parametric functor consists of a set of abstract types, the -- environment of its parameter, and the resulting module type. data FunSig FunSig :: TySet -> Mod -> MTy -> FunSig [funSigAbs] :: FunSig -> TySet [funSigMod] :: FunSig -> Mod [funSigMty] :: FunSig -> MTy -- | A mapping from import strings to Envs. This is used to resolve -- import declarations. type ImportTable = Map String Env -- | A mapping from names (which always exist in some namespace) to a -- unique (tagged) name. type NameMap = Map (Namespace, Name) (QualName VName) -- | Type parameters, list of parameter types (optinally named), and return -- type. The type parameters are in scope in both parameter types and the -- return type. Non-functional values have only a return type. data BoundV BoundV :: [TypeParam] -> StructType -> BoundV -- | Representation of a module, which is either a plain environment, or a -- parametric module ("functor" in SML). data Mod ModEnv :: Env -> Mod ModFun :: FunSig -> Mod -- | A binding from a name to its definition as a type. data TypeBinding TypeAbbr :: Liftedness -> [TypeParam] -> StructType -> TypeBinding -- | Representation of a module type. data MTy MTy :: TySet -> Mod -> MTy -- | Abstract types in the module type. [mtyAbs] :: MTy -> TySet [mtyMod] :: MTy -> Mod -- | All signed integer types. anySignedType :: [PrimType] -- | All unsigned integer types. anyUnsignedType :: [PrimType] -- | All floating-point types. anyFloatType :: [PrimType] -- | All number types. anyNumberType :: [PrimType] -- | All primitive types. anyPrimType :: [PrimType] -- | The space inhabited by a name. data Namespace -- | Functions and values. Term :: Namespace Type :: Namespace Signature :: Namespace -- | The NameMap corresponding to the intrinsics module. intrinsicsNameMap :: NameMap -- | The names that are available in the initial environment. topLevelNameMap :: NameMap instance GHC.Base.Monoid Language.Futhark.TypeChecker.Monad.Notes instance GHC.Base.Semigroup Language.Futhark.TypeChecker.Monad.Notes instance Control.Monad.State.Class.MonadState Language.Futhark.TypeChecker.Monad.TypeState Language.Futhark.TypeChecker.Monad.TypeM instance Control.Monad.Reader.Class.MonadReader Language.Futhark.TypeChecker.Monad.Context Language.Futhark.TypeChecker.Monad.TypeM instance GHC.Base.Applicative Language.Futhark.TypeChecker.Monad.TypeM instance GHC.Base.Functor Language.Futhark.TypeChecker.Monad.TypeM instance GHC.Base.Monad Language.Futhark.TypeChecker.Monad.TypeM instance Language.Futhark.TypeChecker.Monad.MonadTypeChecker Language.Futhark.TypeChecker.Monad.TypeM instance Control.Monad.Error.Class.MonadError Language.Futhark.TypeChecker.Monad.TypeError Language.Futhark.TypeChecker.Monad.TypeM instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.TypeChecker.Monad.TypeError instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.TypeChecker.Monad.Notes instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.TypeChecker.Monad.Note -- | Type checker building blocks that do not involve unification. module Language.Futhark.TypeChecker.Types -- | Type-check a single TypeExp, returning the checked -- TypeExp, its fully expanded type (modulo yet-unelaborated type -- variables), and whether it is potentially higher-order. checkTypeExp :: MonadTypeChecker m => TypeExp Name -> m (TypeExp VName, StructType, Liftedness) -- | Use checkTypeExp to check a type declaration. checkTypeDecl :: MonadTypeChecker m => TypeDeclBase NoInfo Name -> m (TypeDeclBase Info VName, Liftedness) -- | unifyTypes uf t1 t2 attempts to unify t1 and -- t2. If unification cannot happen, Nothing is returned, -- otherwise a type that combines the aliasing of t1 and -- t2 is returned. Uniqueness is unified with uf. unifyTypesU :: (Monoid als, ArrayDim dim) => (Uniqueness -> Uniqueness -> Maybe Uniqueness) -> TypeBase dim als -> TypeBase dim als -> Maybe (TypeBase dim als) -- | x `subtypeOf` y is true if x is a subtype of -- y (or equal to y), meaning x is valid -- whenever y is. subtypeOf :: ArrayDim dim => TypeBase dim as1 -> TypeBase dim as2 -> Bool -- | x subuniqueOf y is true if x is not less -- unique than y. subuniqueOf :: Uniqueness -> Uniqueness -> Bool -- | Check for duplication of names inside a pattern group. Produces a -- description of all names used in the pattern group. checkForDuplicateNames :: MonadTypeChecker m => [UncheckedPattern] -> m () -- | checkTypeParams ps m checks the type parameters ps, -- then invokes the continuation m with the checked parameters, -- while extending the monadic name map with ps. checkTypeParams :: MonadTypeChecker m => [TypeParamBase Name] -> ([TypeParamBase VName] -> m a) -> m a -- | Construct a type argument corresponding to a type parameter. typeParamToArg :: TypeParam -> StructTypeArg -- | A substitution for when using substituteTypes. data TypeSub TypeSub :: TypeBinding -> TypeSub DimSub :: DimDecl VName -> TypeSub -- | A collection of type substitutions. type TypeSubs = Map VName TypeSub -- | Apply type substitutions to the given type. substituteTypes :: Monoid als => TypeSubs -> TypeBase (DimDecl VName) als -> TypeBase (DimDecl VName) als -- | A type substituion may be a substitution or a yet-unknown substitution -- (but which is certainly an overloaded primitive type!). The latter is -- used to remove aliases from types that are yet-unknown but that we -- know cannot carry aliases (see issue #682). data Subst t Subst :: t -> Subst t PrimSubst :: Subst t SizeSubst :: DimDecl VName -> Subst t -- | Class of types which allow for substitution of types with no -- annotations for type variable names. class Substitutable a applySubst :: Substitutable a => (VName -> Maybe (Subst StructType)) -> a -> a -- | Perform substitutions, from type names to types, on a type. Works -- regardless of what shape and uniqueness information is attached to the -- type. substTypesAny :: Monoid as => (VName -> Maybe (Subst (TypeBase (DimDecl VName) as))) -> TypeBase (DimDecl VName) as -> TypeBase (DimDecl VName) as instance GHC.Show.Show Language.Futhark.TypeChecker.Types.TypeSub instance GHC.Show.Show t => GHC.Show.Show (Language.Futhark.TypeChecker.Types.Subst t) instance Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Syntax.TypeBase (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.VName) ()) instance Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Syntax.TypeBase (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.VName) Language.Futhark.Syntax.Aliasing) instance Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Syntax.DimDecl Language.Futhark.Core.VName) instance Language.Futhark.TypeChecker.Types.Substitutable d => Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Syntax.ShapeDecl d) instance Language.Futhark.TypeChecker.Types.Substitutable Language.Futhark.Pattern instance GHC.Base.Functor Language.Futhark.TypeChecker.Types.Subst -- | Implementation of unification and other core type system building -- blocks. module Language.Futhark.TypeChecker.Unify -- | A constraint on a yet-ambiguous type variable. data Constraint NoConstraint :: Liftedness -> Usage -> Constraint ParamType :: Liftedness -> SrcLoc -> Constraint Constraint :: StructType -> Usage -> Constraint Overloaded :: [PrimType] -> Usage -> Constraint HasFields :: Map Name StructType -> Usage -> Constraint Equality :: Usage -> Constraint HasConstrs :: Map Name [StructType] -> Usage -> Constraint ParamSize :: SrcLoc -> Constraint -- | Is not actually a type, but a term-level size, possibly already set to -- something specific. Size :: Maybe (DimDecl VName) -> Usage -> Constraint -- | A size that does not unify with anything - created from the result of -- applying a function whose return size is existential, or otherwise -- hiding a size. UnknowableSize :: SrcLoc -> RigidSource -> Constraint -- | A usage that caused a type constraint. data Usage -- | Construct a Usage from a location and a description. mkUsage :: SrcLoc -> String -> Usage -- | Construct a Usage that has just a location, but no particular -- description. mkUsage' :: SrcLoc -> Usage -- | The level at which a type variable is bound. Higher means deeper. We -- can only unify a type variable at level i with a type -- t if all type names that occur in t are at most at -- level i. type Level = Int -- | Mapping from fresh type variables, instantiated from the type schemes -- of polymorphic functions, to (possibly) specific types as determined -- on application and the location of that application, or a partial -- constraint on their type. type Constraints = Map VName (Level, Constraint) -- | Monads that which to perform unification must implement this type -- class. class Monad m => MonadUnify m getConstraints :: MonadUnify m => m Constraints putConstraints :: MonadUnify m => Constraints -> m () modifyConstraints :: MonadUnify m => (Constraints -> Constraints) -> m () newTypeVar :: (MonadUnify m, Monoid als) => SrcLoc -> String -> m (TypeBase dim als) newDimVar :: MonadUnify m => SrcLoc -> Rigidity -> String -> m VName curLevel :: MonadUnify m => m Level matchError :: (MonadUnify m, Located loc) => loc -> Notes -> BreadCrumbs -> StructType -> StructType -> m a unifyError :: (MonadUnify m, Located loc) => loc -> Notes -> BreadCrumbs -> Doc -> m a -- | The ridigity of a size variable. All rigid sizes are tagged with -- information about how they were generated. data Rigidity Rigid :: RigidSource -> Rigidity Nonrigid :: Rigidity -- | The source of a rigid size. data RigidSource -- | A function argument that is not a constant or variable name. RigidArg :: Maybe (QualName VName) -> String -> RigidSource -- | An existential return size. RigidRet :: Maybe (QualName VName) -> RigidSource RigidLoop :: RigidSource -- | Produced by a complicated slice expression. RigidSlice :: Maybe (DimDecl VName) -> String -> RigidSource -- | Produced by a complicated range expression. RigidRange :: RigidSource -- | Produced by a range expression with this bound. RigidBound :: String -> RigidSource -- | Mismatch in branches. RigidCond :: StructType -> StructType -> RigidSource -- | Invented during unification. RigidUnify :: RigidSource RigidOutOfScope :: SrcLoc -> VName -> RigidSource -- | Unification failures can occur deep down inside complicated types -- (consider nested records). We leave breadcrumbs behind us so we can -- report the path we took to find the mismatch. data BreadCrumbs -- | An empty path. noBreadCrumbs :: BreadCrumbs -- | Is the path empty? hasNoBreadCrumbs :: BreadCrumbs -> Bool -- | Retrieve notes describing the purpose or origin of the given -- DimDecl. The location is used as the *current* location, for -- the purpose of reporting relative locations. dimNotes :: (Located a, MonadUnify m) => a -> DimDecl VName -> m Notes -- | Construct a the name of a new type variable given a base description -- and a tag number (note that this is distinct from actually -- constructing a VName; the tag here is intended for human consumption -- but the machine does not care). mkTypeVarName :: String -> Int -> Name -- | Assert that this type must be zero-order. zeroOrderType :: (MonadUnify m, Pretty (ShapeDecl dim), Monoid as) => Usage -> String -> TypeBase dim as -> m () -- | In mustHaveConstr usage c t fs, the type t must have -- a constructor named c that takes arguments of types -- ts. mustHaveConstr :: MonadUnify m => Usage -> Name -> StructType -> [StructType] -> m () -- | Assert that some type must have a field with this name and type. mustHaveField :: MonadUnify m => Usage -> Name -> PatternType -> m PatternType -- | Assert that this type must be one of the given primitive types. mustBeOneOf :: MonadUnify m => [PrimType] -> Usage -> StructType -> m () -- | Assert that this type must support equality. equalityType :: (MonadUnify m, Pretty (ShapeDecl dim), Monoid as) => Usage -> TypeBase dim as -> m () -- | Replace any top-level type variable with its substitution. normType :: MonadUnify m => StructType -> m StructType -- | Replace any top-level type variable with its substitution. normPatternType :: MonadUnify m => PatternType -> m PatternType -- | Replace all type variables with their substitution. normTypeFully :: (Substitutable a, MonadUnify m) => a -> m a -- | Replace AnyDim dimensions that occur as PosImmediate or -- PosParam with a fresh NamedDim. instantiateEmptyArrayDims :: MonadUnify m => SrcLoc -> String -> Rigidity -> TypeBase (DimDecl VName) als -> m (TypeBase (DimDecl VName) als, [VName]) -- | Unifies two types. unify :: MonadUnify m => Usage -> StructType -> StructType -> m () -- | expect super sub checks that sub is a subtype of -- super. expect :: MonadUnify m => Usage -> StructType -> StructType -> m () -- | Like unification, but creates new size variables where mismatches -- occur. Returns the new dimensions thus created. unifyMostCommon :: MonadUnify m => Usage -> PatternType -> PatternType -> m (PatternType, [VName]) -- | Replace dimension mismatches with AnyDim. anyDimOnMismatch :: Monoid as => TypeBase (DimDecl VName) as -> TypeBase (DimDecl VName) as -> (TypeBase (DimDecl VName) as, [(DimDecl VName, DimDecl VName)]) -- | Perform a unification of two types outside a monadic context. The type -- parameters are allowed to be instantiated; all other types are -- considered rigid. doUnification :: SrcLoc -> [TypeParam] -> StructType -> StructType -> Either TypeError StructType instance GHC.Show.Show Language.Futhark.TypeChecker.Unify.Usage instance GHC.Show.Show Language.Futhark.TypeChecker.Unify.RigidSource instance GHC.Classes.Ord Language.Futhark.TypeChecker.Unify.RigidSource instance GHC.Classes.Eq Language.Futhark.TypeChecker.Unify.RigidSource instance GHC.Show.Show Language.Futhark.TypeChecker.Unify.Constraint instance GHC.Show.Show Language.Futhark.TypeChecker.Unify.Rigidity instance GHC.Classes.Ord Language.Futhark.TypeChecker.Unify.Rigidity instance GHC.Classes.Eq Language.Futhark.TypeChecker.Unify.Rigidity instance Control.Monad.Error.Class.MonadError Language.Futhark.TypeChecker.Monad.TypeError Language.Futhark.TypeChecker.Unify.UnifyM instance Control.Monad.State.Class.MonadState Language.Futhark.TypeChecker.Unify.UnifyMState Language.Futhark.TypeChecker.Unify.UnifyM instance GHC.Base.Applicative Language.Futhark.TypeChecker.Unify.UnifyM instance GHC.Base.Functor Language.Futhark.TypeChecker.Unify.UnifyM instance GHC.Base.Monad Language.Futhark.TypeChecker.Unify.UnifyM instance Language.Futhark.TypeChecker.Unify.MonadUnify Language.Futhark.TypeChecker.Unify.UnifyM instance Data.Loc.Located Language.Futhark.TypeChecker.Unify.Constraint instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.TypeChecker.Unify.Usage instance Data.Loc.Located Language.Futhark.TypeChecker.Unify.Usage instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.TypeChecker.Unify.BreadCrumbs instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.TypeChecker.Unify.BreadCrumb -- | This monomorphization module converts a well-typed, polymorphic, -- module-free Futhark program into an equivalent monomorphic program. -- -- This pass also does a few other simplifications to make the job of -- subsequent passes easier. Specifically, it does the following: -- -- -- -- Note that these changes are unfortunately not visible in the AST -- representation. module Futhark.Internalise.Monomorphise -- | Monomorphise a list of top-level declarations. A module-free input -- program is expected, so only value declarations and type declaration -- are accepted. transformProg :: MonadFreshNames m => [Dec] -> m [ValBind] instance GHC.Show.Show Futhark.Internalise.Monomorphise.MonoSize instance GHC.Classes.Ord Futhark.Internalise.Monomorphise.MonoSize instance GHC.Classes.Eq Futhark.Internalise.Monomorphise.MonoSize instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Internalise.Monomorphise.MonoM instance Control.Monad.Writer.Class.MonadWriter (Data.Sequence.Internal.Seq (Language.Futhark.Core.VName, Language.Futhark.ValBind)) Futhark.Internalise.Monomorphise.MonoM instance Control.Monad.Reader.Class.MonadReader Futhark.Internalise.Monomorphise.Env Futhark.Internalise.Monomorphise.MonoM instance GHC.Base.Monad Futhark.Internalise.Monomorphise.MonoM instance GHC.Base.Applicative Futhark.Internalise.Monomorphise.MonoM instance GHC.Base.Functor Futhark.Internalise.Monomorphise.MonoM instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.Internalise.Monomorphise.MonoSize instance Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.Syntax.ShapeDecl Futhark.Internalise.Monomorphise.MonoSize) instance GHC.Base.Semigroup Futhark.Internalise.Monomorphise.Env instance GHC.Base.Monoid Futhark.Internalise.Monomorphise.Env -- | This module implements a transformation from source to core Futhark. module Futhark.Internalise -- | Convert a program in source Futhark to a program in the Futhark core -- language. internaliseProg :: MonadFreshNames m => Bool -> Imports -> m (Prog SOACS) -- | Facilities for type-checking Futhark terms. Checking a term requires a -- little more context to track uniqueness and such. -- -- Type inference is implemented through a variation of Hindley-Milner. -- The main complication is supporting the rich number of built-in -- language constructs, as well as uniqueness types. This is mostly done -- in an ad hoc way, and many programs will require the programmer to -- fall back on type annotations. module Language.Futhark.TypeChecker.Terms -- | Type-check a single expression in isolation. This expression may turn -- out to be polymorphic, in which case the list of type parameters will -- be non-empty. checkOneExp :: UncheckedExp -> TypeM ([TypeParam], Exp) -- | Type-check a top-level (or module-level) function definition. Despite -- the name, this is also used for checking constant definitions, by -- treating them as 0-ary functions. checkFunDef :: (Name, Maybe UncheckedTypeExp, [UncheckedTypeParam], [UncheckedPattern], UncheckedExp, SrcLoc) -> TypeM (VName, [TypeParam], [Pattern], Maybe (TypeExp VName), StructType, [VName], Exp) instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.Usage instance GHC.Classes.Ord Language.Futhark.TypeChecker.Terms.Usage instance GHC.Classes.Eq Language.Futhark.TypeChecker.Terms.Usage instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.Occurence instance GHC.Classes.Eq Language.Futhark.TypeChecker.Terms.Occurence instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.Locality instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.ValBinding instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.TermScope instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.FName instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.SizeSource instance GHC.Classes.Ord Language.Futhark.TypeChecker.Terms.SizeSource instance GHC.Classes.Eq Language.Futhark.TypeChecker.Terms.SizeSource instance Control.Monad.Error.Class.MonadError Language.Futhark.TypeChecker.Monad.TypeError Language.Futhark.TypeChecker.Terms.TermTypeM instance Control.Monad.State.Class.MonadState Language.Futhark.TypeChecker.Terms.TermTypeState Language.Futhark.TypeChecker.Terms.TermTypeM instance Control.Monad.Writer.Class.MonadWriter Language.Futhark.TypeChecker.Terms.Occurences Language.Futhark.TypeChecker.Terms.TermTypeM instance Control.Monad.Reader.Class.MonadReader Language.Futhark.TypeChecker.Terms.TermEnv Language.Futhark.TypeChecker.Terms.TermTypeM instance GHC.Base.Applicative Language.Futhark.TypeChecker.Terms.TermTypeM instance GHC.Base.Functor Language.Futhark.TypeChecker.Terms.TermTypeM instance GHC.Base.Monad Language.Futhark.TypeChecker.Terms.TermTypeM instance GHC.Show.Show p => GHC.Show.Show (Language.Futhark.TypeChecker.Terms.Unmatched p) instance GHC.Base.Functor Language.Futhark.TypeChecker.Terms.Unmatched instance Text.PrettyPrint.Mainland.Class.Pretty (Language.Futhark.TypeChecker.Terms.Unmatched (Language.Futhark.Syntax.PatternBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)) instance Language.Futhark.TypeChecker.Unify.MonadUnify Language.Futhark.TypeChecker.Terms.TermTypeM instance Language.Futhark.TypeChecker.Monad.MonadTypeChecker Language.Futhark.TypeChecker.Terms.TermTypeM instance Text.PrettyPrint.Mainland.Class.Pretty Language.Futhark.TypeChecker.Terms.Checking instance GHC.Classes.Eq Language.Futhark.TypeChecker.Terms.FName instance GHC.Classes.Ord Language.Futhark.TypeChecker.Terms.FName instance GHC.Base.Semigroup Language.Futhark.TypeChecker.Terms.TermScope instance Data.Loc.Located Language.Futhark.TypeChecker.Terms.Occurence -- | Implementation of the Futhark module system (at least most of it; some -- is scattered elsewhere in the type checker). module Language.Futhark.TypeChecker.Modules -- | Return new renamed/abstracted env, as well as a mapping from names in -- the signature to names in the new env. This is used for functor -- application. The first env is the module env, and the second the env -- it must match. matchMTys :: MTy -> MTy -> SrcLoc -> Either TypeError (Map VName VName) -- | Create unique renames for the module type. This is used for e.g. -- generative functor application. newNamesForMTy :: MTy -> TypeM (MTy, Map VName VName) -- | Refine the given type name in the given env. refineEnv :: SrcLoc -> TySet -> Env -> QualName Name -> [TypeParam] -> StructType -> TypeM (QualName VName, TySet, Env) -- | Apply a parametric module to an argument. applyFunctor :: SrcLoc -> FunSig -> MTy -> TypeM (MTy, Map VName VName, Map VName VName) -- | The type checker checks whether the program is type-consistent and -- adds type annotations and various other elaborations. The program does -- not need to have any particular properties for the type checker to -- function; in particular it does not need unique names. module Language.Futhark.TypeChecker -- | Type check a program containing no type information, yielding either a -- type error or a program with complete type information. Accepts a -- mapping from file names (excluding extension) to previously type -- checker results. The FilePath is used to resolve relative -- imports. checkProg :: Imports -> VNameSource -> ImportName -> UncheckedProg -> (Warnings, Either TypeError (FileModule, VNameSource)) -- | Type check a single expression containing no type information, -- yielding either a type error or the same expression annotated with -- type information. Also returns a list of type parameters, which will -- be nonempty if the expression is polymorphic. See also -- checkProg. checkExp :: Imports -> VNameSource -> Env -> UncheckedExp -> (Warnings, Either TypeError ([TypeParam], Exp)) -- | Type check a single declaration containing no type information, -- yielding either a type error or the same declaration annotated with -- type information along the Env produced by that declaration. See also -- checkProg. checkDec :: Imports -> VNameSource -> Env -> ImportName -> UncheckedDec -> (Warnings, Either TypeError (Env, Dec, VNameSource)) -- | Type check a single module expression containing no type information, -- yielding either a type error or the same expression annotated with -- type information along the Env produced by that declaration. See also -- checkProg. checkModExp :: Imports -> VNameSource -> Env -> ModExpBase NoInfo Name -> (Warnings, Either TypeError (MTy, ModExpBase Info VName)) -- | Information about an error during type checking. data TypeError -- | The warnings produced by the compiler. The Show instance -- produces a human-readable description. data Warnings -- | An initial environment for the type checker, containing intrinsics and -- such. initialEnv :: Env -- | Low-level compilation parts. Look at Futhark.Compiler for a -- more high-level API. module Futhark.Compiler.Program -- | Read Futhark files from some basis, and printing log messages if the -- first parameter is True. readLibraryWithBasis :: (MonadError CompilerError m, MonadIO m) => Basis -> [FilePath] -> m (Warnings, Imports, VNameSource) -- | Read and type-check Futhark imports (no .fut extension; may -- refer to baked-in prelude). This is an exotic operation that probably -- only makes sense in an interactive environment. readImports :: (MonadError CompilerError m, MonadIO m) => Basis -> [ImportName] -> m (Warnings, Imports, VNameSource) -- | A mapping from import names to imports. The ordering is significant. type Imports = [(String, FileModule)] -- | The result of type checking some file. Can be passed to further -- invocations of the type checker. data FileModule FileModule :: TySet -> Env -> Prog -> FileModule -- | Abstract types. [fileAbs] :: FileModule -> TySet [fileEnv] :: FileModule -> Env [fileProg] :: FileModule -> Prog -- | The warnings produced by the compiler. The Show instance -- produces a human-readable description. data Warnings -- | Pre-typechecked imports, including a starting point for the name -- source. data Basis Basis :: Imports -> VNameSource -> [String] -> Basis [basisImports] :: Basis -> Imports [basisNameSource] :: Basis -> VNameSource -- | Files that should be implicitly opened. [basisRoots] :: Basis -> [String] -- | A basis that contains no imports, and has a properly initialised name -- source. emptyBasis :: Basis -- | High-level API for invoking the Futhark compiler. module Futhark.Compiler -- | Read a program from the given FilePath, run the given -- Pipeline, and return it. runPipelineOnProgram :: FutharkConfig -> Pipeline SOACS tolore -> FilePath -> FutharkM (Prog tolore) -- | Read a program from the given FilePath, run the given -- Pipeline, and finish up with the given Action. runCompilerOnProgram :: FutharkConfig -> Pipeline SOACS lore -> Action lore -> FilePath -> IO () -- | The compiler configuration. This only contains options related to core -- compiler functionality, such as reading the initial program and -- running passes. Options related to code generation are handled -- elsewhere. data FutharkConfig FutharkConfig :: (Verbosity, Maybe FilePath) -> Bool -> Bool -> Bool -> FutharkConfig [futharkVerbose] :: FutharkConfig -> (Verbosity, Maybe FilePath) -- | Warn if True. [futharkWarn] :: FutharkConfig -> Bool -- | If true, error on any warnings. [futharkWerror] :: FutharkConfig -> Bool -- | If True, ignore unsafe. [futharkSafe] :: FutharkConfig -> Bool -- | The default compiler configuration. newFutharkConfig :: FutharkConfig -- | Print a compiler error to stdout. The FutharkConfig controls to -- which degree auxiliary information (e.g. the failing program) is also -- printed. dumpError :: FutharkConfig -> CompilerError -> IO () -- | Run an operation that produces warnings, and handle them -- appropriately, yielding the non-warning return value. "Proper -- handling" means e.g. to print them to the screen, as directed by the -- compiler configuration. handleWarnings :: FutharkConfig -> FutharkM (Warnings, a) -> FutharkM a -- | Read and type-check a Futhark program, including all imports. readProgram :: (MonadError CompilerError m, MonadIO m) => FilePath -> m (Warnings, Imports, VNameSource) -- | Read and type-check a collection of Futhark files, including all -- imports. readLibrary :: (MonadError CompilerError m, MonadIO m) => [FilePath] -> m (Warnings, Imports, VNameSource) -- | Not verbose, and terminates process on error. readProgramOrDie :: MonadIO m => FilePath -> m (Warnings, Imports, VNameSource) module Futhark.CodeGen.ImpGen compileProg :: (Mem lore, FreeIn op, MonadFreshNames m) => r -> Operations lore r op -> Space -> Prog lore -> m (Warnings, Definitions op) -- | How to compile an Op. type OpCompiler lore r op = Pattern lore -> Op lore -> ImpM lore r op () -- | How to compile an Exp. type ExpCompiler lore r op = Pattern lore -> Exp lore -> ImpM lore r op () type CopyCompiler lore r op = PrimType -> MemLocation -> Slice (TExp Int64) -> MemLocation -> Slice (TExp Int64) -> ImpM lore r op () -- | How to compile some Stms. type StmsCompiler lore r op = Names -> Stms lore -> ImpM lore r op () -> ImpM lore r op () -- | An alternate way of compiling an allocation. type AllocCompiler lore r op = VName -> Count Bytes (TExp Int64) -> ImpM lore r op () data Operations lore r op Operations :: ExpCompiler lore r op -> OpCompiler lore r op -> StmsCompiler lore r op -> CopyCompiler lore r op -> Map Space (AllocCompiler lore r op) -> Operations lore r op [opsExpCompiler] :: Operations lore r op -> ExpCompiler lore r op [opsOpCompiler] :: Operations lore r op -> OpCompiler lore r op [opsStmsCompiler] :: Operations lore r op -> StmsCompiler lore r op [opsCopyCompiler] :: Operations lore r op -> CopyCompiler lore r op [opsAllocCompilers] :: Operations lore r op -> Map Space (AllocCompiler lore r op) -- | An operations set for which the expression compiler always returns -- defCompileExp. defaultOperations :: (Mem lore, FreeIn op) => OpCompiler lore r op -> Operations lore r op -- | When an array is dared, this is where it is stored. data MemLocation MemLocation :: VName -> [DimSize] -> IxFun (TExp Int64) -> MemLocation [memLocationName] :: MemLocation -> VName [memLocationShape] :: MemLocation -> [DimSize] [memLocationIxFun] :: MemLocation -> IxFun (TExp Int64) newtype MemEntry MemEntry :: Space -> MemEntry [entryMemSpace] :: MemEntry -> Space newtype ScalarEntry ScalarEntry :: PrimType -> ScalarEntry [entryScalarType] :: ScalarEntry -> PrimType data ImpM lore r op a localDefaultSpace :: Space -> ImpM lore r op a -> ImpM lore r op a askFunction :: ImpM lore r op (Maybe Name) -- | Generate a VName, prefixed with askFunction if it -- exists. newVNameForFun :: String -> ImpM lore r op VName -- | Generate a Name, prefixed with askFunction if it exists. nameForFun :: String -> ImpM lore r op Name askEnv :: ImpM lore r op r localEnv :: (r -> r) -> ImpM lore r op a -> ImpM lore r op a localOps :: Operations lore r op -> ImpM lore r op a -> ImpM lore r op a -- | The symbol table used during compilation. type VTable lore = Map VName (VarEntry lore) -- | Get the current symbol table. getVTable :: ImpM lore r op (VTable lore) -- | Run an action with a modified symbol table. All changes to the symbol -- table will be reverted once the action is done! localVTable :: (VTable lore -> VTable lore) -> ImpM lore r op a -> ImpM lore r op a subImpM :: r' -> Operations lore r' op' -> ImpM lore r' op' a -> ImpM lore r op (a, Code op') subImpM_ :: r' -> Operations lore r' op' -> ImpM lore r' op' a -> ImpM lore r op (Code op') -- | Emit some generated imperative code. emit :: Code op -> ImpM lore r op () -- | Emit a function in the generated code. emitFunction :: Name -> Function op -> ImpM lore r op () -- | Check if a function of a given name exists. hasFunction :: Name -> ImpM lore r op Bool -- | Execute a code generation action, returning the code that was emitted. collect :: ImpM lore r op () -> ImpM lore r op (Code op) collect' :: ImpM lore r op a -> ImpM lore r op (a, Code op) -- | Execute a code generation action, wrapping the generated code within a -- Comment with the given description. comment :: String -> ImpM lore r op () -> ImpM lore r op () -- | Every non-scalar variable must be associated with an entry. data VarEntry lore ArrayVar :: Maybe (Exp lore) -> ArrayEntry -> VarEntry lore ScalarVar :: Maybe (Exp lore) -> ScalarEntry -> VarEntry lore MemVar :: Maybe (Exp lore) -> MemEntry -> VarEntry lore data ArrayEntry ArrayEntry :: MemLocation -> PrimType -> ArrayEntry [entryArrayLocation] :: ArrayEntry -> MemLocation [entryArrayElemType] :: ArrayEntry -> PrimType lookupVar :: VName -> ImpM lore r op (VarEntry lore) lookupArray :: VName -> ImpM lore r op ArrayEntry lookupMemory :: VName -> ImpM lore r op MemEntry -- | A typed variable, which we can turn into a typed expression, or use as -- the target for an assignment. This is used to aid in type safety when -- doing code generation, by keeping the types straight. It is still easy -- to cheat when you need to. data TV t -- | Create a typed variable from a name and a dynamic type. Note that -- there is no guarantee that the dynamic type corresponds to the -- inferred static type, but the latter will at least have to be used -- consistently. mkTV :: VName -> PrimType -> TV t -- | Convert a typed variable to a size (a SubExp). tvSize :: TV t -> DimSize -- | Convert a typed variable to a similarly typed expression. tvExp :: TV t -> TExp t -- | Extract the underlying variable name from a typed variable. tvVar :: TV t -> VName -- | Compile things to Exp. class ToExp a -- | Compile to an Exp, where the type (must must still be a -- primitive) is deduced monadically. toExp :: ToExp a => a -> ImpM lore r op Exp -- | Compile where we know the type in advance. toExp' :: ToExp a => PrimType -> a -> Exp toInt64Exp :: ToExp a => a -> TExp Int64 toBoolExp :: ToExp a => a -> TExp Bool -- | compileAlloc pat size space allocates n bytes of -- memory in space, writing the result to dest, which -- must be a single MemoryDestination, compileAlloc :: Mem lore => Pattern lore -> SubExp -> Space -> ImpM lore r op () everythingVolatile :: ImpM lore r op a -> ImpM lore r op a compileBody :: Mem lore => Pattern lore -> Body lore -> ImpM lore r op () compileBody' :: [Param dec] -> Body lore -> ImpM lore r op () compileLoopBody :: Typed dec => [Param dec] -> Body lore -> ImpM lore r op () defCompileStms :: (Mem lore, FreeIn op) => Names -> Stms lore -> ImpM lore r op () -> ImpM lore r op () compileStms :: Names -> Stms lore -> ImpM lore r op () -> ImpM lore r op () compileExp :: Pattern lore -> Exp lore -> ImpM lore r op () defCompileExp :: Mem lore => Pattern lore -> Exp lore -> ImpM lore r op () fullyIndexArray :: VName -> [TExp Int64] -> ImpM lore r op (VName, Space, Count Elements (TExp Int64)) fullyIndexArray' :: MemLocation -> [TExp Int64] -> ImpM lore r op (VName, Space, Count Elements (TExp Int64)) copy :: CopyCompiler lore r op -- | Copy from here to there; both destination and source be indexeded. If -- so, they better be arrays of enough dimensions. This function will -- generally just Do What I Mean, and Do The Right Thing. Both -- destination and source must be in scope. copyDWIM :: VName -> [DimIndex (TExp Int64)] -> SubExp -> [DimIndex (TExp Int64)] -> ImpM lore r op () -- | As copyDWIM, but implicitly DimFixes the indexes. copyDWIMFix :: VName -> [TExp Int64] -> SubExp -> [TExp Int64] -> ImpM lore r op () copyElementWise :: CopyCompiler lore r op -- | The number of bytes needed to represent the array in a straightforward -- contiguous format, as an Int64 expression. typeSize :: Type -> Count Bytes (TExp Int64) -- | Is this copy really a mapping with transpose? isMapTransposeCopy :: PrimType -> MemLocation -> Slice (TExp Int64) -> MemLocation -> Slice (TExp Int64) -> Maybe (TExp Int64, TExp Int64, TExp Int64, TExp Int64, TExp Int64) dLParams :: Mem lore => [LParam lore] -> ImpM lore r op () dFParams :: Mem lore => [FParam lore] -> ImpM lore r op () dScope :: Mem lore => Maybe (Exp lore) -> Scope lore -> ImpM lore r op () dArray :: VName -> PrimType -> ShapeBase SubExp -> MemBind -> ImpM lore r op () -- | The return type is polymorphic, so there is no guarantee it actually -- matches the PrimType, but at least we have to use it -- consistently. dPrim :: String -> PrimType -> ImpM lore r op (TV t) dPrimVol :: String -> PrimType -> TExp t -> ImpM lore r op (TV t) dPrim_ :: VName -> PrimType -> ImpM lore r op () dPrimV_ :: VName -> TExp t -> ImpM lore r op () dPrimV :: String -> TExp t -> ImpM lore r op (TV t) dPrimVE :: String -> TExp t -> ImpM lore r op (TExp t) sFor :: String -> TExp t -> (TExp t -> ImpM lore r op ()) -> ImpM lore r op () sWhile :: TExp Bool -> ImpM lore r op () -> ImpM lore r op () sComment :: String -> ImpM lore r op () -> ImpM lore r op () sIf :: TExp Bool -> ImpM lore r op () -> ImpM lore r op () -> ImpM lore r op () sWhen :: TExp Bool -> ImpM lore r op () -> ImpM lore r op () sUnless :: TExp Bool -> ImpM lore r op () -> ImpM lore r op () sOp :: op -> ImpM lore r op () sDeclareMem :: String -> Space -> ImpM lore r op VName sAlloc :: String -> Count Bytes (TExp Int64) -> Space -> ImpM lore r op VName sAlloc_ :: VName -> Count Bytes (TExp Int64) -> Space -> ImpM lore r op () sArray :: String -> PrimType -> ShapeBase SubExp -> MemBind -> ImpM lore r op VName -- | Declare an array in row-major order in the given memory block. sArrayInMem :: String -> PrimType -> ShapeBase SubExp -> VName -> ImpM lore r op VName -- | Uses linear/iota index function. sAllocArray :: String -> PrimType -> ShapeBase SubExp -> Space -> ImpM lore r op VName -- | Like sAllocArray, but permute the in-memory representation of -- the indices as specified. sAllocArrayPerm :: String -> PrimType -> ShapeBase SubExp -> Space -> [Int] -> ImpM lore r op VName -- | Uses linear/iota index function. sStaticArray :: String -> Space -> PrimType -> ArrayContents -> ImpM lore r op VName sWrite :: VName -> [TExp Int64] -> Exp -> ImpM lore r op () sUpdate :: VName -> Slice (TExp Int64) -> SubExp -> ImpM lore r op () sLoopNest :: Shape -> ([TExp Int64] -> ImpM lore r op ()) -> ImpM lore r op () -- | Typed assignment. (<--) :: TV t -> TExp t -> ImpM lore r op () infixl 3 <-- -- | Untyped assignment. (<~~) :: VName -> Exp -> ImpM lore r op () infixl 3 <~~ -- | Constructing an ad-hoc function that does not correspond to any of the -- IR functions in the input program. function :: Name -> [Param] -> [Param] -> ImpM lore r op () -> ImpM lore r op () -- | Emit a warning about something the user should be aware of. warn :: Located loc => loc -> [loc] -> String -> ImpM lore r op () instance GHC.Show.Show Futhark.CodeGen.ImpGen.MemLocation instance GHC.Classes.Eq Futhark.CodeGen.ImpGen.MemLocation instance GHC.Show.Show Futhark.CodeGen.ImpGen.ArrayEntry instance GHC.Show.Show Futhark.CodeGen.ImpGen.MemEntry instance GHC.Show.Show Futhark.CodeGen.ImpGen.ScalarEntry instance Futhark.IR.Decorations.Decorations lore => GHC.Show.Show (Futhark.CodeGen.ImpGen.VarEntry lore) instance GHC.Show.Show Futhark.CodeGen.ImpGen.ValueDestination instance GHC.Show.Show Futhark.CodeGen.ImpGen.Destination instance Control.Monad.Reader.Class.MonadReader (Futhark.CodeGen.ImpGen.Env lore r op) (Futhark.CodeGen.ImpGen.ImpM lore r op) instance Control.Monad.State.Class.MonadState (Futhark.CodeGen.ImpGen.ImpState lore r op) (Futhark.CodeGen.ImpGen.ImpM lore r op) instance GHC.Base.Monad (Futhark.CodeGen.ImpGen.ImpM lore r op) instance GHC.Base.Applicative (Futhark.CodeGen.ImpGen.ImpM lore r op) instance GHC.Base.Functor (Futhark.CodeGen.ImpGen.ImpM lore r op) instance Futhark.CodeGen.ImpGen.ToExp Futhark.IR.Syntax.Core.SubExp instance Futhark.CodeGen.ImpGen.ToExp (Futhark.Analysis.PrimExp.PrimExp Language.Futhark.Core.VName) instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.CodeGen.ImpGen.ImpM lore r op) instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.SOACS.SOACS (Futhark.CodeGen.ImpGen.ImpM lore r op) -- | Compile Futhark to sequential imperative code. module Futhark.CodeGen.ImpGen.Sequential -- | Compile a SeqMem program to sequential imperative code. compileProg :: MonadFreshNames m => Prog SeqMem -> m (Warnings, Program) -- | The warnings produced by the compiler. The Show instance -- produces a human-readable description. data Warnings module Futhark.CodeGen.Backends.SequentialPython compileProg :: MonadFreshNames m => Maybe String -> Prog SeqMem -> m (Warnings, String) -- | C code generator. This module can convert a correct ImpCode program to -- an equivalent C program. The C code is strictly sequential, but can -- handle the full Futhark language. module Futhark.CodeGen.Backends.SequentialC -- | Compile the program to sequential C. compileProg :: MonadFreshNames m => Prog SeqMem -> m (Warnings, CParts) -- | The result of compilation to C is four parts, which can be put -- together in various ways. The obvious way is to concatenate all of -- them, which yields a CLI program. Another is to compile the library -- part by itself, and use the header file to call into it. data CParts CParts :: String -> String -> String -> String -> CParts [cHeader] :: CParts -> String -- | Utility definitions that must be visible to both CLI and library -- parts. [cUtils] :: CParts -> String [cCLI] :: CParts -> String [cLib] :: CParts -> String -- | Produce header and implementation files. asLibrary :: CParts -> (String, String) -- | As executable with command-line interface. asExecutable :: CParts -> String module Futhark.CodeGen.ImpGen.Multicore.Base toParam :: VName -> TypeBase shape u -> MulticoreGen Param compileKBody :: KernelBody MCMem -> ([(SubExp, [Exp])] -> ImpM MCMem () Multicore ()) -> ImpM MCMem () Multicore () -- | Try to extract invariant allocations. If we assume that the given -- Code is the body of a SegOp, then it is always safe to -- move the immediate allocations to the prebody. extractAllocations :: Code -> (Code, Code) compileThreadResult :: SegSpace -> PatElem MCMem -> KernelResult -> MulticoreGen () newtype HostEnv HostEnv :: AtomicBinOp -> HostEnv [hostAtomics] :: HostEnv -> AtomicBinOp -- | Is there an atomic BinOp corresponding to this BinOp? type AtomicBinOp = BinOp -> Maybe (VName -> VName -> Count Elements (TExp Int32) -> Exp -> AtomicOp) type MulticoreGen = ImpM MCMem HostEnv Multicore decideScheduling :: Code -> Scheduling decideScheduling' :: SegOp () lore -> Code -> Scheduling -- | Arrays for storing group results shared between threads groupResultArrays :: String -> SubExp -> [SegBinOp MCMem] -> MulticoreGen [[VName]] renameSegBinOp :: [SegBinOp MCMem] -> MulticoreGen [SegBinOp MCMem] -- | Arrays for storing group results. resultArrays :: String -> [SegBinOp MCMem] -> MulticoreGen [[VName]] freeParams :: Code -> [VName] -> MulticoreGen [Param] renameHistOpLambda :: [HistOp MCMem] -> MulticoreGen [HistOp MCMem] atomicUpdateLocking :: AtomicBinOp -> Lambda MCMem -> AtomicUpdate MCMem () -- | The mechanism that will be used for performing the atomic update. -- Approximates how efficient it will be. Ordered from most to least -- efficient. data AtomicUpdate lore r AtomicPrim :: DoAtomicUpdate lore r -> AtomicUpdate lore r -- | Can be done by efficient swaps. AtomicCAS :: DoAtomicUpdate lore r -> AtomicUpdate lore r -- | Requires explicit locking. AtomicLocking :: (Locking -> DoAtomicUpdate lore r) -> AtomicUpdate lore r -- | Locking strategy used for an atomic update. data Locking Locking :: VName -> TExp Int32 -> TExp Int32 -> TExp Int32 -> ([TExp Int64] -> [TExp Int64]) -> Locking -- | Array containing the lock. [lockingArray] :: Locking -> VName -- | Value for us to consider the lock free. [lockingIsUnlocked] :: Locking -> TExp Int32 -- | What to write when we lock it. [lockingToLock] :: Locking -> TExp Int32 -- | What to write when we unlock it. [lockingToUnlock] :: Locking -> TExp Int32 -- | A transformation from the logical lock index to the physical position -- in the array. This can also be used to make the lock array smaller. [lockingMapping] :: Locking -> [TExp Int64] -> [TExp Int64] getSpace :: SegOp () MCMem -> SegSpace getIterationDomain :: SegOp () MCMem -> SegSpace -> MulticoreGen (TExp Int64) getReturnParams :: Pattern MCMem -> SegOp () MCMem -> MulticoreGen [Param] segOpString :: SegOp () MCMem -> MulticoreGen String module Futhark.CodeGen.ImpGen.Multicore.SegScan compileSegScan :: Pattern MCMem -> SegSpace -> [SegBinOp MCMem] -> KernelBody MCMem -> TV Int32 -> MulticoreGen Code module Futhark.CodeGen.ImpGen.Multicore.SegRed -- | Generate code for a SegRed construct compileSegRed :: Pattern MCMem -> SegSpace -> [SegBinOp MCMem] -> KernelBody MCMem -> TV Int32 -> MulticoreGen Code -- | Like compileSegRed, but where the body is a monadic action. compileSegRed' :: Pattern MCMem -> SegSpace -> [SegBinOp MCMem] -> TV Int32 -> DoSegBody -> MulticoreGen Code module Futhark.CodeGen.ImpGen.Multicore.SegMap compileSegMap :: Pattern MCMem -> SegSpace -> KernelBody MCMem -> MulticoreGen Code module Futhark.CodeGen.ImpGen.Multicore.SegHist compileSegHist :: Pattern MCMem -> SegSpace -> [HistOp MCMem] -> KernelBody MCMem -> TV Int32 -> MulticoreGen Code module Futhark.CodeGen.ImpGen.Multicore compileProg :: MonadFreshNames m => Prog MCMem -> m (Warnings, Definitions Multicore) -- | The warnings produced by the compiler. The Show instance -- produces a human-readable description. data Warnings -- | C code generator. This module can convert a correct ImpCode program to -- an equivalent C program. module Futhark.CodeGen.Backends.MulticoreC compileProg :: MonadFreshNames m => Prog MCMem -> m (Warnings, CParts) -- | The result of compilation to C is four parts, which can be put -- together in various ways. The obvious way is to concatenate all of -- them, which yields a CLI program. Another is to compile the library -- part by itself, and use the header file to call into it. data CParts CParts :: String -> String -> String -> String -> CParts [cHeader] :: CParts -> String -- | Utility definitions that must be visible to both CLI and library -- parts. [cUtils] :: CParts -> String [cCLI] :: CParts -> String [cLib] :: CParts -> String -- | Produce header and implementation files. asLibrary :: CParts -> (String, String) -- | As executable with command-line interface. asExecutable :: CParts -> String module Futhark.CodeGen.ImpGen.Kernels.Base data KernelConstants KernelConstants :: TExp Int32 -> TExp Int32 -> TExp Int32 -> VName -> VName -> VName -> TExp Int64 -> TExp Int64 -> TExp Int32 -> TExp Int32 -> TExp Bool -> Map [SubExp] [TExp Int32] -> KernelConstants [kernelGlobalThreadId] :: KernelConstants -> TExp Int32 [kernelLocalThreadId] :: KernelConstants -> TExp Int32 [kernelGroupId] :: KernelConstants -> TExp Int32 [kernelGlobalThreadIdVar] :: KernelConstants -> VName [kernelLocalThreadIdVar] :: KernelConstants -> VName [kernelGroupIdVar] :: KernelConstants -> VName [kernelNumGroups] :: KernelConstants -> TExp Int64 [kernelGroupSize] :: KernelConstants -> TExp Int64 [kernelNumThreads] :: KernelConstants -> TExp Int32 [kernelWaveSize] :: KernelConstants -> TExp Int32 [kernelThreadActive] :: KernelConstants -> TExp Bool -- | A mapping from dimensions of nested SegOps to already computed local -- thread IDs. [kernelLocalIdMap] :: KernelConstants -> Map [SubExp] [TExp Int32] keyWithEntryPoint :: Maybe Name -> Name -> Name type CallKernelGen = ImpM KernelsMem HostEnv HostOp type InKernelGen = ImpM KernelsMem KernelEnv KernelOp newtype HostEnv HostEnv :: AtomicBinOp -> HostEnv [hostAtomics] :: HostEnv -> AtomicBinOp data KernelEnv KernelEnv :: AtomicBinOp -> KernelConstants -> KernelEnv [kernelAtomics] :: KernelEnv -> AtomicBinOp [kernelConstants] :: KernelEnv -> KernelConstants computeThreadChunkSize :: SplitOrdering -> TExp Int64 -> Count Elements (TExp Int64) -> Count Elements (TExp Int64) -> TV Int64 -> ImpM lore r op () groupReduce :: TExp Int32 -> Lambda KernelsMem -> [VName] -> InKernelGen () groupScan :: Maybe (TExp Int32 -> TExp Int32 -> TExp Bool) -> TExp Int64 -> TExp Int64 -> Lambda KernelsMem -> [VName] -> InKernelGen () isActive :: [(VName, SubExp)] -> TExp Bool sKernelThread :: String -> Count NumGroups (TExp Int64) -> Count GroupSize (TExp Int64) -> VName -> InKernelGen () -> CallKernelGen () sKernelGroup :: String -> Count NumGroups (TExp Int64) -> Count GroupSize (TExp Int64) -> VName -> InKernelGen () -> CallKernelGen () -- | Perform a Replicate with a kernel. sReplicate :: VName -> SubExp -> CallKernelGen () -- | Perform an Iota with a kernel. sIota :: VName -> TExp Int64 -> Exp -> Exp -> IntType -> CallKernelGen () sCopy :: CopyCompiler KernelsMem HostEnv HostOp compileThreadResult :: SegSpace -> PatElem KernelsMem -> KernelResult -> InKernelGen () compileGroupResult :: SegSpace -> PatElem KernelsMem -> KernelResult -> InKernelGen () -- | For many kernels, we may not have enough physical groups to cover the -- logical iteration space. Some groups thus have to perform double duty; -- we put an outer loop to accomplish this. The advantage over just -- launching a bazillion threads is that the cost of memory expansion -- should be proportional to the number of *physical* threads (hardware -- parallelism), not the amount of application parallelism. virtualiseGroups :: SegVirt -> TExp Int32 -> (TExp Int32 -> InKernelGen ()) -> InKernelGen () -- | Assign iterations of a for-loop to threads in the workgroup. The -- passed-in function is invoked with the (symbolic) iteration. For -- multidimensional loops, use groupCoverSpace. groupLoop :: TExp Int64 -> (TExp Int64 -> InKernelGen ()) -> InKernelGen () -- | Assign iterations of a for-loop to all threads in the kernel. The -- passed-in function is invoked with the (symbolic) iteration. -- threadOperations will be in effect in the body. For -- multidimensional loops, use groupCoverSpace. kernelLoop :: IntExp t => TExp t -> TExp t -> TExp t -> (TExp t -> InKernelGen ()) -> InKernelGen () -- | Iterate collectively though a multidimensional space, such that all -- threads in the group participate. The passed-in function is invoked -- with a (symbolic) point in the index space. groupCoverSpace :: [TExp Int64] -> ([TExp Int64] -> InKernelGen ()) -> InKernelGen () precomputeSegOpIDs :: Stms KernelsMem -> InKernelGen a -> InKernelGen a -- | Do an atomic update corresponding to a binary operator lambda. atomicUpdateLocking :: AtomicBinOp -> Lambda KernelsMem -> AtomicUpdate KernelsMem KernelEnv -- | Is there an atomic BinOp corresponding to this BinOp? type AtomicBinOp = BinOp -> Maybe (VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp) -- | Locking strategy used for an atomic update. data Locking Locking :: VName -> TExp Int32 -> TExp Int32 -> TExp Int32 -> ([TExp Int64] -> [TExp Int64]) -> Locking -- | Array containing the lock. [lockingArray] :: Locking -> VName -- | Value for us to consider the lock free. [lockingIsUnlocked] :: Locking -> TExp Int32 -- | What to write when we lock it. [lockingToLock] :: Locking -> TExp Int32 -- | What to write when we unlock it. [lockingToUnlock] :: Locking -> TExp Int32 -- | A transformation from the logical lock index to the physical position -- in the array. This can also be used to make the lock array smaller. [lockingMapping] :: Locking -> [TExp Int64] -> [TExp Int64] -- | The mechanism that will be used for performing the atomic update. -- Approximates how efficient it will be. Ordered from most to least -- efficient. data AtomicUpdate lore r -- | Supported directly by primitive. AtomicPrim :: DoAtomicUpdate lore r -> AtomicUpdate lore r -- | Can be done by efficient swaps. AtomicCAS :: DoAtomicUpdate lore r -> AtomicUpdate lore r -- | Requires explicit locking. AtomicLocking :: (Locking -> DoAtomicUpdate lore r) -> AtomicUpdate lore r -- | A function for generating code for an atomic update. Assumes that the -- bucket is in-bounds. type DoAtomicUpdate lore r = Space -> [VName] -> [TExp Int64] -> ImpM lore r KernelOp () -- | Code generation for segmented and non-segmented scans. Uses a fairly -- inefficient two-pass algorithm. module Futhark.CodeGen.ImpGen.Kernels.SegScan -- | Compile SegScan instance to host-level code with calls to -- various kernels. compileSegScan :: Pattern KernelsMem -> SegLevel -> SegSpace -> [SegBinOp KernelsMem] -> KernelBody KernelsMem -> CallKernelGen () -- | We generate code for non-segmented/single-segment SegRed using the -- basic approach outlined in the paper "Design and GPGPU Performance of -- Futhark’s Redomap Construct" (ARRAY '16). The main deviations are: -- -- -- -- For segmented reductions we use the approach from "Strategies for -- Regular Segmented Reductions on GPU" (FHPC '17). This involves having -- two different strategies, and dynamically deciding which one to use -- based on the number of segments and segment size. We use the (static) -- group_size to decide which of the following two strategies to -- choose: -- -- -- -- Each thread can read multiple elements, which will greatly -- increase performance; however, if the reduction is non-commutative we -- will have to use a less efficient traversal (with interim group-wide -- reductions) to enable coalesced memory accesses, just as in the -- non-segmented case. -- -- module Futhark.CodeGen.ImpGen.Kernels.SegRed -- | Compile SegRed instance to host-level code with calls to -- various kernels. compileSegRed :: Pattern KernelsMem -> SegLevel -> SegSpace -> [SegBinOp KernelsMem] -> KernelBody KernelsMem -> CallKernelGen () -- | Like compileSegRed, but where the body is a monadic action. compileSegRed' :: Pattern KernelsMem -> SegLevel -> SegSpace -> [SegBinOp KernelsMem] -> DoSegBody -> CallKernelGen () -- | Code generation for the body of the SegRed, taking a continuation for -- saving the results of the body. The results should be represented as a -- pairing of a SubExp along with a list of indexes into that -- SubExp for reading the result. type DoSegBody = ([(SubExp, [TExp Int64])] -> InKernelGen ()) -> InKernelGen () -- | Code generation for SegMap is quite straightforward. The only -- trick is virtualisation in case the physical number of threads is not -- sufficient to cover the logical thread space. This is handled by -- having actual workgroups run a loop to imitate multiple workgroups. module Futhark.CodeGen.ImpGen.Kernels.SegMap -- | Compile SegMap instance code. compileSegMap :: Pattern KernelsMem -> SegLevel -> SegSpace -> KernelBody KernelsMem -> CallKernelGen () -- | Our compilation strategy for SegHist is based around avoiding -- bin conflicts. We do this by splitting the input into chunks, and for -- each chunk computing a single subhistogram. Then we combine the -- subhistograms using an ordinary segmented reduction (SegRed). -- -- There are some branches around to efficiently handle the case where we -- use only a single subhistogram (because it's large), so that we -- respect the asymptotics, and do not copy the destination array. -- -- We also use a heuristic strategy for computing subhistograms in local -- memory when possible. Given: -- -- H: total size of histograms in bytes, including any lock arrays. -- -- G: group size -- -- T: number of bytes of local memory each thread can be given without -- impacting occupancy (determined experimentally, e.g. 32). -- -- LMAX: maximum amount of local memory per workgroup (hard limit). -- -- We wish to compute: -- -- COOP: cooperation level (number of threads per subhistogram) -- -- LH: number of local memory subhistograms -- -- We do this as: -- -- COOP = ceil(H / T) LH = ceil((G*T)/H) if COOP <= G && H -- <= LMAX then use local memory else use global memory module Futhark.CodeGen.ImpGen.Kernels.SegHist -- | Generate code for a segmented histogram called from the host. compileSegHist :: Pattern KernelsMem -> Count NumGroups SubExp -> Count GroupSize SubExp -> SegSpace -> [HistOp KernelsMem] -> KernelBody KernelsMem -> CallKernelGen () instance GHC.Classes.Ord Futhark.CodeGen.ImpGen.Kernels.SegHist.Passage instance GHC.Classes.Eq Futhark.CodeGen.ImpGen.Kernels.SegHist.Passage -- | Compile a KernelsMem program to imperative code with kernels. -- This is mostly (but not entirely) the same process no matter if we are -- targeting OpenCL or CUDA. The important distinctions (the host level -- code) are introduced later. module Futhark.CodeGen.ImpGen.Kernels -- | Compile a KernelsMem program to low-level parallel code, with -- either CUDA or OpenCL characteristics. compileProgOpenCL :: MonadFreshNames m => Prog KernelsMem -> m (Warnings, Program) -- | Compile a KernelsMem program to low-level parallel code, with -- either CUDA or OpenCL characteristics. compileProgCUDA :: MonadFreshNames m => Prog KernelsMem -> m (Warnings, Program) -- | The warnings produced by the compiler. The Show instance -- produces a human-readable description. data Warnings module Futhark.CodeGen.ImpGen.OpenCL compileProg :: MonadFreshNames m => Prog KernelsMem -> m (Warnings, Program) -- | The warnings produced by the compiler. The Show instance -- produces a human-readable description. data Warnings module Futhark.CodeGen.Backends.PyOpenCL compileProg :: MonadFreshNames m => Maybe String -> Prog KernelsMem -> m (Warnings, String) -- | Code generation for C with OpenCL. module Futhark.CodeGen.Backends.COpenCL -- | Compile the program to C with calls to OpenCL. compileProg :: MonadFreshNames m => Prog KernelsMem -> m (Warnings, CParts) -- | The result of compilation to C is four parts, which can be put -- together in various ways. The obvious way is to concatenate all of -- them, which yields a CLI program. Another is to compile the library -- part by itself, and use the header file to call into it. data CParts CParts :: String -> String -> String -> String -> CParts [cHeader] :: CParts -> String -- | Utility definitions that must be visible to both CLI and library -- parts. [cUtils] :: CParts -> String [cCLI] :: CParts -> String [cLib] :: CParts -> String -- | Produce header and implementation files. asLibrary :: CParts -> (String, String) -- | As executable with command-line interface. asExecutable :: CParts -> String module Futhark.CodeGen.ImpGen.CUDA compileProg :: MonadFreshNames m => Prog KernelsMem -> m (Warnings, Program) -- | The warnings produced by the compiler. The Show instance -- produces a human-readable description. data Warnings -- | Code generation for CUDA. module Futhark.CodeGen.Backends.CCUDA -- | Compile the program to C with calls to CUDA. compileProg :: MonadFreshNames m => Prog KernelsMem -> m (Warnings, CParts) -- | The result of compilation to C is four parts, which can be put -- together in various ways. The obvious way is to concatenate all of -- them, which yields a CLI program. Another is to compile the library -- part by itself, and use the header file to call into it. data CParts CParts :: String -> String -> String -> String -> CParts [cHeader] :: CParts -> String -- | Utility definitions that must be visible to both CLI and library -- parts. [cUtils] :: CParts -> String [cCLI] :: CParts -> String [cLib] :: CParts -> String -- | Produce header and implementation files. asLibrary :: CParts -> (String, String) -- | As executable with command-line interface. asExecutable :: CParts -> String -- | This module exports version information about the Futhark compiler. module Futhark.Version -- | The version of Futhark that we are using. This is equivalent to the -- version defined in the .cabal file. version :: Version -- | The version of Futhark that we are using, as a String versionString :: String -- | Common code for parsing command line options based on getopt. module Futhark.Util.Options -- | A command line option that either purely updates a configuration, or -- performs an IO action (and stops). type FunOptDescr cfg = OptDescr (Either (IO ()) (cfg -> cfg)) -- | Generate a main action that parses the given command line options -- (while always adding commonOptions). mainWithOptions :: cfg -> [FunOptDescr cfg] -> String -> ([String] -> cfg -> Maybe (IO ())) -> String -> [String] -> IO () -- | Common definitions for -v and -h, given the list of -- all other options. commonOptions :: String -> String -> [FunOptDescr cfg] -> [FunOptDescr cfg] -- | Convenient common interface for command line Futhark compilers. Using -- this module ensures that all compilers take the same options. A small -- amount of flexibility is provided for backend-specific options. module Futhark.Compiler.CLI -- | Run a parameterised Futhark compiler, where cfg is a -- user-given configuration type. Call this from main. compilerMain :: cfg -> [CompilerOption cfg] -> String -> String -> Pipeline SOACS lore -> (FutharkConfig -> cfg -> CompilerMode -> FilePath -> Prog lore -> FutharkM ()) -> String -> [String] -> IO () -- | An option that modifies the configuration of type cfg. type CompilerOption cfg = OptDescr (Either (IO ()) (cfg -> cfg)) -- | Are we compiling a library or an executable? data CompilerMode ToLibrary :: CompilerMode ToExecutable :: CompilerMode instance GHC.Show.Show Futhark.Compiler.CLI.CompilerMode instance GHC.Classes.Ord Futhark.Compiler.CLI.CompilerMode instance GHC.Classes.Eq Futhark.Compiler.CLI.CompilerMode -- |
--   futhark py
--   
module Futhark.CLI.Python -- | Run futhark py main :: String -> [String] -> IO () -- |
--   futhark pyopencl
--   
module Futhark.CLI.PyOpenCL -- | Run futhark pyopencl. main :: String -> [String] -> IO () -- | All (almost) compiler pipelines end with an Action, which does -- something with the result of the pipeline. module Futhark.Actions -- | Print the result to stdout, with alias annotations. printAction :: (ASTLore lore, CanBeAliased (Op lore)) => Action lore -- | Convert the program to sequential ImpCode and print it to stdout. impCodeGenAction :: Action SeqMem -- | Convert the program to GPU ImpCode and print it to stdout. kernelImpCodeGenAction :: Action KernelsMem multicoreImpCodeGenAction :: Action MCMem -- | Print metrics about AST node counts to stdout. metricsAction :: OpMetrics (Op lore) => Action lore -- | The futhark c action. compileCAction :: FutharkConfig -> CompilerMode -> FilePath -> Action SeqMem -- | The futhark opencl action. compileOpenCLAction :: FutharkConfig -> CompilerMode -> FilePath -> Action KernelsMem -- | The futhark cuda action. compileCUDAAction :: FutharkConfig -> CompilerMode -> FilePath -> Action KernelsMem -- | The futhark multicore action. compileMulticoreAction :: FutharkConfig -> CompilerMode -> FilePath -> Action MCMem -- | Print metrics about AST node counts to stdout. sexpAction :: ASTLore lore => Action lore -- |
--   futhark opencl
--   
module Futhark.CLI.OpenCL -- | Run futhark opencl main :: String -> [String] -> IO () module Futhark.CLI.Multicore main :: String -> [String] -> IO () -- |
--   futhark cuda
--   
module Futhark.CLI.CUDA -- | Run futhark cuda. main :: String -> [String] -> IO () -- |
--   futhark c
--   
module Futhark.CLI.C -- | Run futhark c main :: String -> [String] -> IO () -- |
--   futhark test
--   
module Futhark.CLI.Test -- | Run futhark test. main :: String -> [String] -> IO () instance GHC.Show.Show Futhark.CLI.Test.TestResult instance GHC.Classes.Eq Futhark.CLI.Test.TestResult instance GHC.Show.Show Futhark.CLI.Test.ProgConfig instance GHC.Show.Show Futhark.CLI.Test.TestMode instance GHC.Classes.Eq Futhark.CLI.Test.TestMode instance GHC.Show.Show Futhark.CLI.Test.TestCase instance GHC.Classes.Eq Futhark.CLI.Test.TestCase instance GHC.Classes.Ord Futhark.CLI.Test.TestCase -- |
--   futhark run
--   
module Futhark.CLI.Run -- | Run futhark run. main :: String -> [String] -> IO () -- |
--   futhark query
--   
module Futhark.CLI.Query -- | Run futhark query. main :: String -> [String] -> IO () -- |
--   futhark pkg
--   
module Futhark.CLI.Pkg -- | Run futhark pkg. main :: String -> [String] -> IO () instance Control.Monad.Reader.Class.MonadReader Futhark.CLI.Pkg.PkgConfig Futhark.CLI.Pkg.PkgM instance Control.Monad.IO.Class.MonadIO Futhark.CLI.Pkg.PkgM instance GHC.Base.Applicative Futhark.CLI.Pkg.PkgM instance GHC.Base.Functor Futhark.CLI.Pkg.PkgM instance GHC.Base.Monad Futhark.CLI.Pkg.PkgM instance Control.Monad.Fail.MonadFail Futhark.CLI.Pkg.PkgM instance Futhark.Pkg.Info.MonadPkgRegistry Futhark.CLI.Pkg.PkgM instance Futhark.Util.Log.MonadLogger Futhark.CLI.Pkg.PkgM -- | Various small subcommands that are too simple to deserve their own -- file. module Futhark.CLI.Misc -- |
--   futhark imports
--   
mainImports :: String -> [String] -> IO () -- |
--   futhark dataget
--   
mainDataget :: String -> [String] -> IO () -- | Futhark Compiler Driver module Futhark.CLI.Dev -- | Entry point. Non-interactive, except when reading interpreter input -- from standard input. main :: String -> [String] -> IO () instance Futhark.CLI.Dev.Representation Futhark.CLI.Dev.UntypedAction instance Futhark.CLI.Dev.Representation Futhark.CLI.Dev.UntypedPassState instance Text.PrettyPrint.Mainland.Class.Pretty Futhark.CLI.Dev.UntypedPassState -- |
--   futhark dataset
--   
module Futhark.CLI.Dataset -- | Run futhark dataset. main :: String -> [String] -> IO () instance GHC.Show.Show Futhark.CLI.Dataset.OutputFormat instance GHC.Classes.Ord Futhark.CLI.Dataset.OutputFormat instance GHC.Classes.Eq Futhark.CLI.Dataset.OutputFormat -- |
--   futhark datacmp
--   
module Futhark.CLI.Datacmp -- | Run futhark datacmp main :: String -> [String] -> IO () -- |
--   futhark check
--   
module Futhark.CLI.Check -- | Run futhark check. main :: String -> [String] -> IO () -- |
--   futhark bench
--   
module Futhark.CLI.Bench -- | Run futhark bench. main :: String -> [String] -> IO () instance GHC.Classes.Eq Futhark.CLI.Bench.SkipReason -- |
--   futhark autotune
--   
module Futhark.CLI.Autotune -- | Run futhark autotune main :: String -> [String] -> IO () instance GHC.Show.Show Futhark.CLI.Autotune.DatasetResult -- | The core logic of futhark doc. module Futhark.Doc.Generator -- | renderFiles important_imports imports produces HTML files -- documenting the type-checked program imports, with the files -- in important_imports considered most important. The HTML -- files must be written to the specific locations indicated in the -- return value, or the relative links will be wrong. renderFiles :: [FilePath] -> Imports -> ([(FilePath, Html)], Warnings) -- |
--   futhark doc
--   
module Futhark.CLI.Doc -- | Run futhark doc. main :: String -> [String] -> IO () -- |
--   futhark repl
--   
module Futhark.CLI.REPL -- | Run futhark repl. main :: String -> [String] -> IO () instance Control.Monad.Error.Class.MonadError Futhark.CLI.REPL.StopReason Futhark.CLI.REPL.FutharkiM instance Control.Monad.IO.Class.MonadIO Futhark.CLI.REPL.FutharkiM instance Control.Monad.State.Class.MonadState Futhark.CLI.REPL.FutharkiState Futhark.CLI.REPL.FutharkiM instance GHC.Base.Monad Futhark.CLI.REPL.FutharkiM instance GHC.Base.Applicative Futhark.CLI.REPL.FutharkiM instance GHC.Base.Functor Futhark.CLI.REPL.FutharkiM