-- 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:
--   
--   
--   
- Futhark contains a basic architectural overview of the
--   compiler.
--   
- Futhark.IR.Syntax explains the basic design of the
--   intermediate representation (IR).
--   
- Futhark.Construct explains how to write code that
--   manipulates and creates AST fragments.
--   
--   
@package futhark
@version 0.25.27

-- | This module contains no code. Its purpose is to explain the overall
--   architecture of the code base, with links to the relevant modules and
--   definitions. It is intended for people who intend to hack on the
--   compiler itself, not for those who just want to use its public API as
--   a library. Most of what's here discusses the compiler itself, but
--   we'll also provide pointers for where to find the code for the various
--   other tools and subcommands.
--   
--   Much of the documentation here is by referencing other modules that
--   contain more information. Make sure to follow the links. Also, make
--   sure to click the *source* links to study the actual code. Many of the
--   links are provided not because the exposed module API is particularly
--   interesting, but because their implementation is.
--   
--   
Compiler
--   
--   At a very high level, the Futhark compiler has a fairly conventional
--   architecture. After reading and type-checking a program, it is
--   gradually transformed, passing through a variety of different
--   intermediate representations (IRs), where the specifics depend
--   on which code generator is intended. The final result is then written
--   to one or more files. We can divide the compiler into roughly three
--   parts: frontend, middle-end [sic], and backend.
--   
--   
Frontend
--   
--   The frontend of the compiler is concerned with parsing the Futhark
--   source language, type-checking it, and transforming it to the core IR
--   used by the middle-end of the compiler. The following modules are of
--   particular interest:
--   
--   
--   
- Language.Futhark.Syntax contains the source language AST
--   definition.
--   
- Language.Futhark.Parser contains parsers for the source
--   language and various fragments.
--   
- Futhark.Compiler and Futhark.Compiler.Program
--   contains functions for conveniently reading and type-checking an
--   entire Futhark source program, chasing down imports, and so on.
--   
- Language.Futhark.TypeChecker is the type checker
--   itself.
--   
- Internalisation of the source language to the core IR is in
--   Futhark.Internalise.
--   
--   
--   
Middle-end
--   
--   The compiler middle-end is based around passes that are
--   essentially pure functions that accept a program as input and produce
--   a program as output. A composition of such passes is called a
--   pipeline. The various compiler backends (futhark
--   opencl, futhark multicore, etc) use different pipelines.
--   See Futhark.Pass and (less importantly)
--   Futhark.Pipeline. The actual pipelines we use are in
--   Futhark.Passes.
--   
--   The compiler front-end produces a core IR program that is then
--   processed by a pipeline in the middle-end. The fundamental structure
--   of this IR is defined in Futhark.IR.Syntax. As mentioned in
--   that module, the IR supports multiple representations. The
--   middle-end always starts with the program in the SOACS representation
--   (Futhark.IR.SOACS), which closely resembles the kind of
--   free-form nested parallelism that the source language permits.
--   Depending on the specific compilation pipeline, the program will
--   eventually be transformed to various other representations. The output
--   of the middle-end is always a core IR program in some representation
--   (probably not the same one that it started with).
--   
--   Many passes will involve constructing core IR AST fragments. See
--   Futhark.Construct for advice and guidance on how to do that.
--   
--   
Main representations
--   
--   
--   
- Futhark.IR.SOACS: the initial core representation of any
--   Futhark program. This is the representation on which we perform
--   optimisations such as fusion, inlining, and a host of other
--   cleanup.
--   
--   
--   
--   
- Futhark.IR.GPU: a representation where parallelism is
--   expressed with flat segmented operations, and a few other
--   GPU-specific operations are also supported. The pass
--   Futhark.Pass.ExtractKernels transforms a SOACS program
--   to a GPU program.
--   
- Futhark.IR.MC: a representation where parallelism is
--   expressed with flat segmented operations, and a few other
--   multicore-specific operations are also supported. The pass
--   Futhark.Pass.ExtractMulticore transforms a SOACS program
--   to a MC program.
--   
- Futhark.IR.GPUMem: like GPU, but with memory
--   information. See Futhark.IR.Mem for information on how we
--   represent memory in the Futhark compiler. This representation is
--   produced by Futhark.Pass.ExplicitAllocations.GPU
--   
- Futhark.IR.MCMem: the multicore counterpart to
--   GPUMem. Produced by
--   Futhark.Pass.ExplicitAllocations.MC.
--   
--   
--   
Backend
--   
--   The backend accepts a program in some core IR representation.
--   Currently this must always be a representation with memory information
--   (e.g. GPUMem). It then translates the program to the
--   imperative IR, which we call ImpCode.
--   
--   
--   
- Futhark.CodeGen.ImpCode: The main definition of ImpCode,
--   which is an extensible representation like the core IR.
--   
- Futhark.CodeGen.ImpCode.GPU: an example of ImpCode
--   extended/specialised to handle GPU operations (but at a high level,
--   before generating actual CUDA/OpenCL kernel code).
--   
- Futhark.CodeGen.ImpGen: a translator from core IR to
--   ImpCode. Heavily parameterised so that it can handle the various
--   dialects of both core IR and ImpCode that it must be expected to work
--   with. In practice, when adding a new backend (or modifying an existing
--   one), you'll be working on more specialised modules such as
--   Futhark.CodeGen.ImpGen.GPU.
--   
--   
--   Ultimately, ImpCode must then be translated to some real
--   executable language, which in our case means C or Python.
--   
--   
--   
- Futhark.CodeGen.Backends.GenericC: framework for
--   translating ImpCode to C. Rather convoluted because it is used in a
--   large number of settings. The module
--   Futhark.CodeGen.Backends.SequentialC shows perhaps the simplest
--   use of it.
--   
- Futhark.CodeGen.Backends.GenericPython: the generic Python
--   code generator (see Futhark.CodeGen.Backends.SequentialPython
--   for a usage example).
--   
--   
--   
Command line interface
--   
--   The futhark program dispatches to a Haskell-level main
--   function based on its first argument (the subcommand). Some of these
--   subcommands are implemented as their own modules under the
--   Futhark.CLI hierarchy. Others, particularly the simplest
--   ones, are bundled together in Futhark.CLI.Misc.
module Futhark

-- | The data type definition for Futhark.Analysis.Metrics, factored
--   out to simplify the module import hierarchies when working on the test
--   modules.
module Futhark.Analysis.Metrics.Type

-- | 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
instance GHC.Show.Show Futhark.Analysis.Metrics.Type.AstMetrics
instance GHC.Read.Read Futhark.Analysis.Metrics.Type.AstMetrics

-- | 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 pretty.
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

-- | Compatibility shims for mainland-pretty; the prettyprinting library
--   used by language-c-quote.
module Futhark.CodeGen.Backends.GenericC.Pretty

-- | Prettyprint a C expression.
expText :: Exp -> Text

-- | Prettyprint a list of C definitions.
definitionsText :: [Definition] -> Text

-- | Prettyprint a single C type.
typeText :: Type -> Text

-- | Prettyprint a single identifier.
idText :: Id -> Text

-- | Prettyprint a single function.
funcText :: Func -> Text

-- | Prettyprint a list of functions.
funcsText :: [Func] -> Text

-- | Code snippets used by the C backends.
module Futhark.CodeGen.RTS.C

-- | 
--   rtscatomics.h
--   
atomicsH :: Text

-- | 
--   rtsccontext.h
--   
contextH :: Text

-- | 
--   rtsccontext_prototypes.h
--   
contextPrototypesH :: Text

-- | 
--   rtsccopy.h
--   
copyH :: Text

-- | 
--   rtscfree_list.h
--   
freeListH :: Text

-- | 
--   rtscevent_list.h
--   
eventListH :: Text

-- | 
--   rtscgpu.h
--   
gpuH :: Text

-- | 
--   rtscgpu_prototypes.h
--   
gpuPrototypesH :: Text

-- | 
--   rtschalf.h
--   
halfH :: Text

-- | 
--   rtsclock.h
--   
lockH :: Text

-- | 
--   rtscscalar_f16.h
--   
scalarF16H :: Text

-- | 
--   rtscscalar.h
--   
scalarH :: Text

-- | 
--   rtscscheduler.h
--   
schedulerH :: Text

-- | 
--   rtscserver.h
--   
serverH :: Text

-- | 
--   rtsctiming.h
--   
timingH :: Text

-- | 
--   rtsctuning.h
--   
tuningH :: Text

-- | 
--   rtscutil.h
--   
utilH :: Text

-- | 
--   rtscvalues.h
--   
valuesH :: Text

-- | 
--   rtscerrors.h
--   
errorsH :: Text

-- | 
--   rtsccache.h
--   
cacheH :: Text

-- | 
--   rtscuniform.h
--   
uniformH :: Text

-- | 
--   rtscispc_util.h
--   
ispcUtilH :: Text

-- | 
--   rtscbackends/opencl.h
--   
backendsOpenclH :: Text

-- | 
--   rtscbackends/cuda.h
--   
backendsCudaH :: Text

-- | 
--   rtscbackends/hip.h
--   
backendsHipH :: Text

-- | 
--   rtscbackends/c.h
--   
backendsCH :: Text

-- | 
--   rtscbackends/multicore.h
--   
backendsMulticoreH :: Text

-- | Code snippets used by the CUDA backend.
module Futhark.CodeGen.RTS.CUDA

-- | 
--   rtscudaprelude.cu
--   
preludeCU :: Text

-- | Code snippets used by the JS backends.
module Futhark.CodeGen.RTS.JavaScript

-- | 
--   rtsjavascriptserver.js
--   
serverJs :: Text

-- | 
--   rtsjavascriptvalues.js
--   
valuesJs :: Text

-- | 
--   rtsjavascriptwrapperclasses.js
--   
wrapperclassesJs :: Text

-- | Code snippets used by the OpenCL and CUDA backends.
module Futhark.CodeGen.RTS.OpenCL

-- | 
--   rtsopencltranspose.cl
--   
transposeCL :: Text

-- | 
--   rtsopenclprelude.cl
--   
preludeCL :: Text

-- | 
--   rtsopenclcopy.cl
--   
copyCL :: Text

-- | Code snippets used by the Python backends.
module Futhark.CodeGen.RTS.Python

-- | 
--   rtspythonmemory.py
--   
memoryPy :: Text

-- | 
--   rtspythonopencl.py
--   
openclPy :: Text

-- | 
--   rtspythonpanic.py
--   
panicPy :: Text

-- | 
--   rtspythonscalar.py
--   
scalarPy :: Text

-- | 
--   rtspythonserver.py
--   
serverPy :: Text

-- | 
--   rtspythontuning.py
--   
tuningPy :: Text

-- | 
--   rtspythonvalues.py
--   
valuesPy :: Text

-- | Parsing of format strings.
module Futhark.Format

-- | The Lefts are pure text; the Rights are the contents of
--   interpolations.
parseFormatString :: Text -> Either Text [Either Text Text]

-- | This module contains the type definitions and basic operations for the
--   graph that Futhark.Optimise.ReduceDeviceSyncs.MigrationTable
--   internally uses to construct a migration table. It is however
--   completely Futhark-agnostic and implements a generic graph
--   abstraction.
--   
--   
Overview
--   
--   The Graph type is a data flow dependency graph of program
--   variables, each variable represented by a Vertex. A vertex may
--   have edges to other vertices or to a sink, which is a special vertex
--   with no graph representation. Each edge to a vertex is either from
--   another vertex or from a source, which also is a special vertex with
--   no graph representation.
--   
--   The primary graph operation provided by this module is route.
--   Given the vertex that some unspecified source has an edge to, a path
--   is attempted found to a sink. If a sink can be reached from the
--   source, all edges along the path are reversed. The path in the
--   opposite direction of reversed edges from a source to some sink is a
--   route.
--   
--   Routes can be used to find a minimum vertex cut in the graph through
--   what amounts to a specialized depth-first search implementation of the
--   Ford-Fulkerson method. When viewed in this way each graph edge has a
--   capacity of 1 and the reversing of edges to create routes amounts to
--   sending reverse flow through a residual network (the current state of
--   the graph). The max-flow min-cut theorem allows one to determine a
--   minimum edge cut that separates the sources and sinks.
--   
--   If each vertex v in the graph is viewed as two vertices,
--   v_in and v_out, with all ingoing edges to v
--   going to v_in, all outgoing edges from v going from
--   v_out, and v_in connected to v_out with a
--   single edge, then the minimum edge cut of the view amounts to a
--   minimum vertex cut in the actual graph. The view need not be
--   manifested as whether v_in or v_out is reached by an
--   edge to v can be determined from whether that edge is
--   reversed or not. The presence of an outgoing, reversed edge also gives
--   the state of the virtual edge that connects v_in to
--   v_out.
--   
--   When routing fails to find a sink in some subgraph reached via an edge
--   then that edge is marked exhausted. No sink can be reached via an
--   exhausted edge, and any subsequent routing attempt will skip
--   pathfinding along such edge.
module Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph

-- | A data flow dependency graph of program variables, each variable
--   represented by a Vertex.
data Graph m

-- | A handle that identifies a specific Vertex.
type Id = Int

-- | A set of Ids.
type IdSet = IntSet

-- | A graph representation of some program variable.
data Vertex m
Vertex :: Id -> m -> Routing -> Edges -> Vertex m

-- | The handle for this vertex in the graph.
[vertexId] :: Vertex m -> Id

-- | Custom data associated with the variable.
[vertexMeta] :: Vertex m -> m

-- | Whether a route passes through this vertex, and from where.
[vertexRouting] :: Vertex m -> Routing

-- | Handles of vertices that this vertex has an edge to.
[vertexEdges] :: Vertex m -> Edges

-- | Route tracking for some vertex. If a route passes through the vertex
--   then both an ingoing and an outgoing edge to/from that vertex will
--   have been reversed, and the vertex will in effect have lost one edge
--   and gained another. The gained edge will be to the prior vertex along
--   the route that passes through.
data Routing

-- | No route passes through the vertex, and no edges have been reversed,
--   added, nor deleted compared to what was declared.
NoRoute :: Routing

-- | A route passes through the vertex, and the prior vertex is the source
--   of that route. The edge gained by reversal is by definition exhausted.
FromSource :: Routing

-- | A route passes through the vertex, and this is the handle of the prior
--   vertex. The edge gained by reversal may be exhausted. Routing assumes
--   that at most one FromNode routing exists to each vertex in a
--   graph.
FromNode :: Id -> Exhaustion -> Routing

-- | Whether some edge is exhausted or not. No sink can be reached via an
--   exhausted edge.
data Exhaustion
Exhausted :: Exhaustion
NotExhausted :: Exhaustion

-- | All relevant edges that have been declared from some vertex, plus
--   bookkeeping to track their exhaustion and reversal.
data Edges

-- | The vertex has an edge to a sink; all other declared edges are
--   irrelevant. The edge cannot become exhausted, and it is reversed if a
--   route passes through the vertex (vertexRouting v /= NoRoute).
ToSink :: Edges

-- | All vertices that the vertex has a declared edge to, and which of
--   those edges that are not exhausted nor reversed, if not all.
ToNodes :: IdSet -> Maybe IdSet -> Edges

-- | Whether a vertex is reached via a normal or reversed edge.
data EdgeType
Normal :: EdgeType
Reversed :: EdgeType

-- | State that tracks which vertices a traversal has visited, caching
--   immediate computations.
data Visited a

-- | The result of a graph traversal that may abort early in case a sink is
--   reached.
data Result a

-- | The traversal finished without encountering a sink, producing this
--   value.
Produced :: a -> Result a

-- | The traversal was aborted because a sink was reached.
FoundSink :: Result a

-- | The empty graph.
empty :: Graph m

-- | Constructs a Vertex without any edges.
vertex :: Id -> m -> Vertex m

-- | Creates a set of edges where no edge is reversed or exhausted.
declareEdges :: [Id] -> Edges

-- | Like declareEdges but for a single vertex.
oneEdge :: Id -> Edges

-- | Initial Visited state before any vertex has been visited.
none :: Visited a

-- | Insert a new vertex into the graph. If its variable already is
--   represented in the graph, the original graph is returned.
insert :: Vertex m -> Graph m -> Graph m

-- | Adjust the vertex with this specific id. When no vertex with that id
--   is a member of the graph, the original graph is returned.
adjust :: (Vertex m -> Vertex m) -> Id -> Graph m -> Graph m

-- | Connect the vertex with this id to a sink. When no vertex with that id
--   is a member of the graph, the original graph is returned.
connectToSink :: Id -> Graph m -> Graph m

-- | Add these edges to the vertex with this id. When no vertex with that
--   id is a member of the graph, the original graph is returned.
addEdges :: Edges -> Id -> Graph m -> Graph m

-- | Does a vertex for the given id exist in the graph?
member :: Id -> Graph m -> Bool

-- | Returns the vertex with the given id.
lookup :: Id -> Graph m -> Maybe (Vertex m)

-- | Returns whether a vertex with the given id exists in the graph and is
--   connected directly to a sink.
isSinkConnected :: Id -> Graph m -> Bool

-- | route src g attempts to find a path in g from the
--   source connected vertex with id src. If a sink is found, all
--   edges along the path will be reversed to create a route, and the id of
--   the vertex that connects to the sink is returned.
route :: Id -> Graph m -> (Maybe Id, Graph m)

-- | routeMany srcs g attempts to create a route in
--   g from every vertex in srcs. Returns the ids for the
--   vertices connected to each found sink.
routeMany :: [Id] -> Graph m -> ([Id], Graph m)

-- | fold g f (a, vs) et i folds f over the vertices in
--   g that can be reached from the vertex with handle i
--   accessed via an edge of type et. Each vertex v may
--   be visited up to two times, once for each type of edge e
--   pointing to it, and each time f a e v is evaluated to produce
--   an updated a value to be used in future f
--   evaluations or to be returned. The vs set records which f
--   a e v evaluations already have taken place. The function returns
--   an updated Visited set recording the evaluations it has
--   performed.
fold :: Graph m -> (a -> EdgeType -> Vertex m -> a) -> (a, Visited ()) -> EdgeType -> Id -> (a, Visited ())

-- | reduce g r vs et i returns FoundSink if a sink can be
--   reached via the vertex v with id i in g.
--   Otherwise it returns Produced (r x et v) where
--   x is the <> aggregate of all values produced by
--   reducing the vertices that are available via the edges of v.
--   et identifies the type of edge that v is accessed by
--   and thereby which edges of v that are available. vs
--   caches reductions of vertices that previously have been visited in the
--   graph.
--   
--   The reduction of a cyclic reference resolves to mempty.
reduce :: Monoid a => Graph m -> (a -> EdgeType -> Vertex m -> a) -> Visited (Result a) -> EdgeType -> Id -> (Result a, Visited (Result a))
instance GHC.Classes.Ord Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Exhaustion
instance GHC.Classes.Eq Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Exhaustion
instance GHC.Show.Show Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Exhaustion
instance GHC.Classes.Ord Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Routing
instance GHC.Classes.Eq Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Routing
instance GHC.Show.Show Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Routing
instance GHC.Classes.Ord Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Edges
instance GHC.Classes.Eq Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Edges
instance GHC.Show.Show Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Edges
instance GHC.Classes.Ord Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.EdgeType
instance GHC.Classes.Eq Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.EdgeType
instance GHC.Classes.Eq a => GHC.Classes.Eq (Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Result a)
instance GHC.Base.Semigroup (Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.RoutingResult a)
instance GHC.Base.Monoid (Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.RoutingResult a)
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Result a)
instance GHC.Base.Semigroup Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Edges
instance GHC.Base.Monoid Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph.Edges

-- | 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

-- | A logical unit of a version number.
--   
--   Either entirely numerical (with no leading zeroes) or entirely
--   alphanumerical (with a free mixture of numbers, letters, and hyphens.)
--   
--   Groups of these (like Release) are separated by periods to form
--   a full section of a version number.
--   
--   Examples:
--   
--   
--   1
--   20150826
--   r3
--   0rc1-abc3
--   
data () => Chunk
Alphanum :: !Text -> Chunk

-- | Chunks have comparison behaviour according to SemVer's rules
--   for preleases.
newtype () => Release
Release :: NonEmpty Chunk -> Release

-- | 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:
--   
--   
--   
- Pre-release versions have lower precedence than normal
--   versions.
--   
- Build metadata does not affect version precedence.
--   
- PREREL and META strings may only contain ASCII alphanumerics and
--   hyphens.
--   
--   
--   For more information, see http://semver.org
data () => SemVer
SemVer :: !Word -> !Word -> !Word -> !Maybe Release -> !Maybe Text -> SemVer
[_svMajor] :: SemVer -> !Word
[_svMinor] :: SemVer -> !Word
[_svPatch] :: SemVer -> !Word
[_svPreRel] :: SemVer -> !Maybe Release
[_svMeta] :: SemVer -> !Maybe Text

-- | Convert a SemVer back to its textual representation.
prettySemVer :: SemVer -> Text

-- | 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 pretty 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 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

-- | Profiling information emitted by a running Futhark program.
module Futhark.Profile

-- | A thing that has occurred during execution.
data ProfilingEvent
ProfilingEvent :: Text -> Double -> Text -> ProfilingEvent

-- | Short, single line.
[eventName] :: ProfilingEvent -> Text

-- | In microseconds.
[eventDuration] :: ProfilingEvent -> Double

-- | Long, may be multiple lines.
[eventDescription] :: ProfilingEvent -> Text

-- | A profiling report contains all profiling information for a single
--   benchmark (meaning a single invocation on an entry point on a specific
--   dataset).
data ProfilingReport
ProfilingReport :: [ProfilingEvent] -> Map Text Integer -> ProfilingReport
[profilingEvents] :: ProfilingReport -> [ProfilingEvent]

-- | Mapping memory spaces to bytes.
[profilingMemory] :: ProfilingReport -> Map Text Integer

-- | Read a profiling report from a text containing JSON.
profilingReportFromText :: Text -> Maybe ProfilingReport

-- | Read a profiling report from a bytestring containing JSON.
decodeProfilingReport :: ByteString -> Maybe ProfilingReport
instance GHC.Show.Show Futhark.Profile.ProfilingEvent
instance GHC.Classes.Ord Futhark.Profile.ProfilingEvent
instance GHC.Classes.Eq Futhark.Profile.ProfilingEvent
instance GHC.Show.Show Futhark.Profile.ProfilingReport
instance GHC.Classes.Ord Futhark.Profile.ProfilingReport
instance GHC.Classes.Eq Futhark.Profile.ProfilingReport
instance Data.Aeson.Types.ToJSON.ToJSON Futhark.Profile.ProfilingReport
instance Data.Aeson.Types.FromJSON.FromJSON Futhark.Profile.ProfilingReport
instance Data.Aeson.Types.ToJSON.ToJSON Futhark.Profile.ProfilingEvent
instance Data.Aeson.Types.FromJSON.FromJSON Futhark.Profile.ProfilingEvent

-- | 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 nubBy, but without the quadratic runtime.
nubByOrd :: (a -> a -> Ordering) -> [a] -> [a]

-- | Like mapAccumL, but monadic and generalised to any
--   Traversable.
mapAccumLM :: (Monad m, Traversable t) => (acc -> x -> m (acc, y)) -> acc -> t x -> m (acc, t y)

-- | Like maximum, but returns zero for an empty list.
maxinum :: (Num a, Ord a, Foldable f) => f a -> a

-- | Like minimum, but returns zero for an empty list.
mininum :: (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]]

-- | chunkLike xss ys chunks the elements of ys to match
--   the elements of xss. The sum of the lengths of the sublists
--   of xss must match the length of ys.
chunkLike :: [[a]] -> [b] -> [[b]]

-- | 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])

-- | A combination of partition and mapMaybe
partitionMaybe :: (a -> Maybe b) -> [a] -> ([b], [a])

-- | 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

-- | Lookup a value, returning also the index at which it appears.
lookupWithIndex :: Eq a => a -> [(a, b)] -> Maybe (Int, b)

-- | 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])

-- | Return the first list element that satisifes a predicate, along with
--   the elements before and after.
focusMaybe :: (a -> Maybe b) -> [a] -> Maybe ([a], b, [a])

-- | Compute a hash of a text that is stable across OS versions. Returns
--   the hash as a text as well, ready for human consumption.
hashText :: Text -> Text

-- | Like show, but produces text.
showText :: Show a => a -> Text

-- | The Unix environment when the Futhark compiler started.
unixEnvironment :: [(String, String)]

-- | True if the environment variable, viewed as an integer, has at least
--   this numeric value. Returns False if variable is unset or not numeric.
isEnvVarAtLeast :: String -> Int -> Bool

-- | The time at which the process started - or more accurately, the first
--   time this binding was forced.
startupTime :: UTCTime

-- | Are we running in a terminal capable of fancy commands and
--   visualisation?
fancyTerminal :: Bool

-- | Is this handle connected to a terminal capable of fancy commands and
--   visualisation?
hFancyTerminal :: Handle -> IO 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]

-- | 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]

-- | Do some operation on a file, returning Nothing if the file does
--   not exist, and Left if some other error occurs.
interactWithFileSafely :: IO a -> IO (Maybe (Either String a))

-- | Convert between different floating-point types, preserving infinities
--   and NaNs.
convFloat :: (RealFloat from, RealFloat to) => from -> to

-- | As the user typed it.
type UserText = Text

-- | Encoded form.
type EncodedText = Text

-- | Z-encode a text using a slightly simplified variant of GHC Z-encoding.
--   The encoded string is a valid identifier in most programming
--   languages.
zEncodeText :: UserText -> EncodedText

-- | Truncate to at most this many characters, making the last three
--   characters "..." if truncation is necessary.
atMostChars :: Int -> Text -> Text

-- | Invert a map, handling duplicate values (now keys) by constructing a
--   set of corresponding values.
invertMap :: (Ord v, Ord k) => Map k v -> Map v (Set k)

-- | Compute the cartesian product of two foldable collections, using the
--   given combinator function.
cartesian :: (Monoid m, Foldable t) => (a -> a -> m) -> t a -> t a -> m

-- | Applicatively fold a traversable.
traverseFold :: (Monoid m, Traversable t, Applicative f) => (a -> f m) -> t a -> f m

-- | Perform fixpoint iteration.
fixPoint :: Eq a => (a -> a) -> a -> a

-- | Like concatMap, but monoidal and monadic.
concatMapM :: (Monad m, Monoid b) => (a -> m b) -> [a] -> m b

-- | Topological sorting of an array with an adjancency function, if there
--   is a cycle, it causes an error. dep a b means a ->
--   b, and the returned array guarantee that for i < j:
--   
--   not ( dep (ret !! j) (ret !! i) ).
topologicalSort :: (a -> a -> Bool) -> [a] -> [a]

-- | traceM, but only if FUTHARK_COMPILER_DEBUGGING is set
--   to to the appropriate level.
debugTraceM :: Monad m => Int -> String -> m ()

-- | 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)

-- | Bindings to the C math library.
--   
--   Follows the naming scheme of the C functions when feasible.
module Futhark.Util.CMath

-- | 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 next representable single-precision floating-point value in the
--   given direction.
nextafterf :: Float -> Float -> Float

-- | The next representable double-precision floating-point value in the
--   given direction.
nextafter :: Double -> 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

-- | The system-level erf() function.
erf :: Double -> Double

-- | The system-level erff() function.
erff :: Float -> Float

-- | The system-level erfc() function.
erfc :: Double -> Double

-- | The system-level erfcf() function.
erfcf :: Float -> Float

-- | The system-level cbrt function.
cbrt :: Double -> Double

-- | The system-level cbrtf function.
cbrtf :: Float -> Float

-- | The system-level hypot function.
hypot :: Double -> Double -> Double

-- | The system-level hypotf function.
hypotf :: Float -> Float -> Float

-- | The system-level ldexp function.
ldexp :: Double -> CInt -> Double

-- | The system-level ldexpf function.
ldexpf :: Float -> CInt -> Float

-- | The system-level copysign function.
copysign :: Double -> Double -> Double

-- | The system-level copysignf function.
copysignf :: Float -> Float -> Float

-- | 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
pow :: IntegralExp e => e -> e -> e

-- | Like div, but rounds towards positive infinity.
divUp :: IntegralExp e => e -> e -> e
nextMul :: 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.Enum.Enum a => GHC.Enum.Enum (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 pretty. 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.Monad m => Futhark.Util.Log.MonadLogger (Control.Monad.Trans.Writer.Lazy.WriterT Futhark.Util.Log.Log m)
instance GHC.Base.Monad m => Futhark.Util.Log.MonadLogger (Control.Monad.Trans.RWS.Lazy.RWST r Futhark.Util.Log.Log s m)
instance 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.MonadLogger GHC.Types.IO
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) => CacheDir -> PkgPath -> m (PkgInfo m)

-- | Information about a version of a single package. The version number is
--   stored separately.
data PkgRevInfo m
PkgRevInfo :: GetFiles m -> Text -> GetManifest m -> UTCTime -> PkgRevInfo m
[pkgGetFiles] :: PkgRevInfo m -> GetFiles m

-- | 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

-- | Get the absolute path to a package directory on disk, as well as
--   relative paths to files that should be installed from this
--   package. Composing the package directory and one of these paths refers
--   to a local file (pointing into the cache) and is valid at least until
--   the next cache operation.
data GetFiles m

-- | A temporary directory in which we store Git checkouts while running.
--   This is to avoid constantly re-cloning. Will be deleted when
--   futhark pkg terminates. In principle we could keep this
--   around for longer, but then we would have to 'git pull' now and then
--   also. Note that the cache is stateful - we are going to use git
--   checkout to move around the history. It is generally not safe to
--   have multiple operations running concurrently.
newtype CacheDir
CacheDir :: FilePath -> CacheDir

-- | 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 => CacheDir -> PkgPath -> m (PkgInfo m)

-- | Look up information about a specific version of a package.
lookupPackageRev :: MonadPkgRegistry m => CacheDir -> PkgPath -> SemVer -> m (PkgRevInfo m)

-- | Find the newest version of a package.
lookupNewestRev :: MonadPkgRegistry m => CacheDir -> 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.GetFiles m)
instance GHC.Classes.Eq (Futhark.Pkg.Info.GetFiles 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 => CacheDir -> 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

-- | Prettyprint a list enclosed in curly braces.
prettyTuple :: Pretty a => [a] -> Text

-- | Like prettyTuple, but put a linebreak after every element.
prettyTupleLines :: Pretty a => [a] -> Text

-- | Prettyprint a value to a String, appropriately wrapped.
prettyString :: Pretty a => a -> String

-- | Prettyprint a value to a String on a single line.
prettyStringOneLine :: Pretty a => a -> String

-- | Prettyprint a value to a Text, appropriately wrapped.
prettyText :: Pretty a => a -> Text

-- | Prettyprint a value to a Text on a single line.
prettyTextOneLine :: Pretty a => a -> Text

-- | Convert a Doc to text. This ignores any annotations (i.e. it
--   will be non-coloured output).
docText :: Doc a -> Text

-- | Produce text suitable for printing on the given handle. This mostly
--   means stripping any control characters if the handle is not a
--   terminal.
docTextForHandle :: Handle -> Doc AnsiStyle -> IO Text

-- | Convert a Doc to a String, through docText.
--   Intended for debugging.
docString :: Doc a -> String

-- | Like hPutDoc, but to stdout.
putDoc :: Doc AnsiStyle -> IO ()

-- | Print a doc with styling to the given file; stripping colors if the
--   file does not seem to support such things.
hPutDoc :: Handle -> Doc AnsiStyle -> IO ()

-- | Like putDoc, but with a final newline.
putDocLn :: Doc AnsiStyle -> IO ()

-- | Like hPutDoc, but with a final newline.
hPutDocLn :: Handle -> Doc AnsiStyle -> IO ()

-- | The 8 ANSI terminal colors.
data () => Color
Black :: Color
Red :: Color
Green :: Color
Yellow :: Color
Blue :: Color
Magenta :: Color
Cyan :: Color
White :: Color

-- | Render the annotated document in a certain style. Styles not set in
--   the annotation will use the style of the surrounding document, or the
--   terminal’s default if none has been set yet.
--   
--   
--   style = color Green <> bold
--   styledDoc = annotate style "hello world"
--   
data () => AnsiStyle

-- | Render in bold.
bold :: AnsiStyle

-- | Style the foreground with a vivid color.
color :: Color -> AnsiStyle

-- | Style the background with a vivid color.
bgColor :: Color -> AnsiStyle

-- | Style the foreground with a dull color.
colorDull :: Color -> AnsiStyle

-- | Style the background with a dull color.
bgColorDull :: Color -> AnsiStyle

-- | Render in italics.
italicized :: AnsiStyle

-- | Render underlined.
underlined :: AnsiStyle

-- | The document apply ds separates ds with
--   commas and encloses them with parentheses.
apply :: [Doc a] -> Doc a

-- | Make sure that the given document is printed on just a single line.
oneLine :: Doc a -> Doc a

-- | 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 a] -> Doc a -> Doc a

-- | Surround the given document with enclosers and add linebreaks and
--   indents.
nestedBlock :: Doc a -> Doc a -> Doc a -> Doc a

-- | Splits the string into words and permits line breaks between all of
--   them.
textwrap :: Text -> Doc a

-- | Prettyprint on a single line up to at most some appropriate number of
--   characters, with trailing ... if necessary. Used for error messages.
shorten :: Doc a -> Doc b

-- | Like commasep, but a newline after every comma.
commastack :: [Doc a] -> Doc a

-- | Separate with commas.
commasep :: [Doc a] -> Doc a

-- | Separate with semicolons and newlines.
semistack :: [Doc a] -> Doc a

-- | Separate with linebreaks.
stack :: [Doc a] -> Doc a

-- | The document parensIf p d encloses the document
--   d in parenthesis if p is True, and
--   otherwise yields just d.
parensIf :: Bool -> Doc a -> Doc a
ppTuple' :: [Doc a] -> Doc a
ppTupleLines' :: [Doc a] -> Doc a
(</>) :: Doc a -> Doc a -> Doc a
instance Prettyprinter.Internal.Pretty Numeric.Half.Internal.Half

-- | This module provides an efficient value representation as well as
--   parsing and comparison functions.
module Futhark.Test.Values

-- | The structure of a compound value, parameterised over the actual
--   values. For most cases you probably want CompoundValue.
data Compound v
ValueRecord :: Map Text (Compound v) -> Compound v

-- | Must not be single value.
ValueTuple :: [Compound v] -> Compound v
ValueAtom :: v -> Compound v

-- | Like a Value, but also grouped in compound ways that are not
--   supported by raw values. You cannot parse or read these in standard
--   ways, and they cannot be elements of arrays.
type CompoundValue = Compound Value

-- | Create a tuple for a non-unit list, and otherwise a ValueAtom
mkCompound :: [Compound v] -> Compound v

-- | If the value is a tuple, extract the components, otherwise return a
--   singleton list of the value.
unCompound :: Compound v -> [Compound v]
instance GHC.Show.Show v => GHC.Show.Show (Futhark.Test.Values.Compound v)
instance GHC.Classes.Ord v => GHC.Classes.Ord (Futhark.Test.Values.Compound v)
instance GHC.Classes.Eq v => GHC.Classes.Eq (Futhark.Test.Values.Compound v)
instance GHC.Base.Functor Futhark.Test.Values.Compound
instance Data.Foldable.Foldable Futhark.Test.Values.Compound
instance Data.Traversable.Traversable Futhark.Test.Values.Compound
instance Prettyprinter.Internal.Pretty v => Prettyprinter.Internal.Pretty (Futhark.Test.Values.Compound v)
instance Prettyprinter.Internal.Pretty Futhark.Data.Value
instance Prettyprinter.Internal.Pretty Futhark.Data.ValueType

-- | 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 AnsiStyle -> CompilerError

-- | An internal compiler error. The second pretty is extra data for
--   debugging, which can be written to a file.
InternalError :: Text -> Text -> ErrorClass -> CompilerError

-- | Print an error intended for human consumption.
prettyCompilerError :: CompilerError -> Doc AnsiStyle

-- | 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 AnsiStyle -> 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 AnsiStyle -> 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

-- | Facilities for generating and otherwise handling pretty-based progress
--   bars.
module Futhark.Util.ProgressBar

-- | Render the progress bar.
progressBar :: ProgressBar -> Text

-- | Information about a progress bar to render. The "progress space" spans
--   from 0 and up to the progressBarBound, but can be visualised in
--   any number of steps.
data ProgressBar
ProgressBar :: Int -> Double -> Double -> ProgressBar

-- | Number of steps in the visualisation.
[progressBarSteps] :: ProgressBar -> Int

-- | The logical upper bound.
[progressBarBound] :: ProgressBar -> Double

-- | The current position in the progress bar, relative to the upper bound.
[progressBarElapsed] :: ProgressBar -> Double

-- | Render a spinner - a kind of progress bar where there is no upper
--   bound because we don't know how long it'll take. You certainly know
--   these from THE INTERNET. The non-negative integer is how many "steps"
--   have been taken. The spinner looks best if this is incremented by one
--   for every call.
progressSpinner :: Int -> Text

-- | Basic table building for prettier futhark-test output.
module Futhark.Util.Table

-- | Produce 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.
hPutTable :: Handle -> [[Entry]] -> Int -> IO ()

-- | Makes a table entry.
mkEntry :: String -> AnsiStyle -> Entry

-- | A table entry. Consists of the content as well as how it should be
--   styled..
data Entry

-- | Render the annotated document in a certain style. Styles not set in
--   the annotation will use the style of the surrounding document, or the
--   terminal’s default if none has been set yet.
--   
--   
--   style = color Green <> bold
--   styledDoc = annotate style "hello world"
--   
data () => AnsiStyle

-- | The 8 ANSI terminal colors.
data () => Color
Black :: Color
Red :: Color
Green :: Color
Yellow :: Color
Blue :: Color
Magenta :: Color
Cyan :: Color
White :: Color

-- | Style the foreground with a vivid color.
color :: Color -> AnsiStyle
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

-- | A fancier name for () - encodes no uniqueness information.
--   Also has a different prettyprinting instance.
data NoUniqueness
NoUniqueness :: NoUniqueness

-- | 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

-- | No location.
noLoc :: IsLocation a => a

-- | A value of type L a is a value of type a with an
--   associated Loc, but this location is ignored when performing
--   comparisons.
data () => L a
L :: Loc -> a -> L a
unLoc :: L a -> a

-- | 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

-- | locStr, but for text.
locText :: Located a => a -> Text

-- | locStrRel, but for text.
locTextRel :: (Located a, Located b) => a -> b -> Text

-- | 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 -> [Text] -> Text

-- | 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

-- | Return the base Name converted to a text.
baseText :: VName -> Text

-- | Enclose a string in the prefered quotes used in error messages. These
--   are picked to not collide with characters permitted in identifiers.
quote :: Text -> Text

-- | 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
data () => Half
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.Show.Show Language.Futhark.Core.NoUniqueness
instance GHC.Classes.Ord Language.Futhark.Core.NoUniqueness
instance GHC.Classes.Eq Language.Futhark.Core.NoUniqueness
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.Show.Show Language.Futhark.Core.VName
instance GHC.Classes.Eq Language.Futhark.Core.VName
instance GHC.Classes.Ord Language.Futhark.Core.VName
instance Prettyprinter.Internal.Pretty Language.Futhark.Core.Name
instance GHC.Base.Semigroup Language.Futhark.Core.NoUniqueness
instance GHC.Base.Monoid Language.Futhark.Core.NoUniqueness
instance Prettyprinter.Internal.Pretty Language.Futhark.Core.NoUniqueness
instance GHC.Base.Semigroup Language.Futhark.Core.Uniqueness
instance GHC.Base.Monoid Language.Futhark.Core.Uniqueness
instance Prettyprinter.Internal.Pretty Language.Futhark.Core.Uniqueness

-- | 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

module Futhark.CodeGen.Backends.GenericPython.AST
data PyExp
Integer :: Integer -> PyExp
Bool :: Bool -> PyExp
Float :: Double -> PyExp
String :: Text -> PyExp
RawStringLiteral :: Text -> 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
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 :: Text -> 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 Prettyprinter.Internal.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyProg
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyStmt
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyFunDef
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyClassDef
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyExcept
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyIdx
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.Backends.GenericPython.AST.PyArg
instance Prettyprinter.Internal.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 :: Text -> Maybe Char -> OptionArgument -> [PyStmt] -> Option
[optionLongName] :: Option -> Text
[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]

-- | Utility definitions used by the lexer. None of the default Alex
--   "wrappers" are precisely what we need. The code here is highly
--   minimalistic. Lexers should not be complicated!
module Language.Futhark.Parser.Lexer.Wrapper
initialLexerState :: Pos -> ByteString -> AlexInput

-- | The input type. Contains:
--   
--   
--   
- current position
--   
- previous char
--   
- current input string
--   
- bytes consumed so far
--   
type AlexInput = (Pos, Char, ByteString, Int64)
alexInputPrevChar :: AlexInput -> Char
data LexerError
LexerError :: Loc -> Text -> LexerError
alexGetByte :: AlexInput -> Maybe (Byte, AlexInput)
alexGetPos :: AlexInput -> Pos
instance GHC.Show.Show Language.Futhark.Parser.Lexer.Wrapper.LexerError

-- | 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)]

-- | Definitions of primitive types, the values that inhabit these types,
--   and operations on these values. A primitive value can also be called a
--   scalar.
--   
--   This module diverges from the actual Futhark language in that it does
--   not distinguish signed and unsigned types. Further, we allow a "unit"
--   type that is only indirectly present in source Futhark in the form of
--   empty tuples.
module Language.Futhark.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
Float16 :: 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

-- | An informationless type - An array of this type takes up no space.
Unit :: 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

-- | 8-bit unsigned integer type
data () => Word8

-- | 64-bit unsigned integer type
data () => Word64

-- | 32-bit unsigned integer type
data () => Word32

-- | 16-bit unsigned integer type
data () => Word16
data () => Half

-- | 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
Float16Value :: !Half -> 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 Unit.
UnitValue :: 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

-- | A one value of the given primitive type - this is one whatever is
--   close to it.
onePrimValue :: 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

-- | Flip sign. Logical negation for booleans.
Neg :: PrimType -> 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

-- | Floating-point sign function.
FSignum :: FloatType -> 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

-- | Convert a float to a boolean value. Zero becomes false; | anything
--   else is true.
FToB :: FloatType -> ConvOp

-- | Convert a boolean to a float. True is converted to 1 and False to 0.
BToF :: FloatType -> 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

-- | Turn the conversion the other way around. Note that most conversions
--   are lossy, so there is no guarantee the value will round-trip.
flipConvOp :: ConvOp -> ConvOp

-- | 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 Text ([PrimType], PrimType, [PrimValue] -> Maybe PrimValue)

-- | condFun t is the name of the ternary conditional function
--   that accepts operands of type [Bool, t, t], and returns
--   either the first or second t based on the truth value of the
--   Bool.
condFun :: PrimType -> Text

-- | Is this the name of a condition function as per condFun, and
--   for which type?
isCondFun :: Text -> Maybe PrimType

-- | 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 bits.
primBitSize :: PrimType -> Int

-- | The size of a value of a given primitive type in eight-bit bytes.
--   
--   Warning: note that this is 0 for Unit, but a Unit takes
--   up a byte in the binary data format.
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

-- | True if the given binary operator is associative.
associativeBinOp :: 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 -> Text
instance GHC.Enum.Bounded Language.Futhark.Primitive.IntType
instance GHC.Enum.Enum Language.Futhark.Primitive.IntType
instance GHC.Show.Show Language.Futhark.Primitive.IntType
instance GHC.Classes.Ord Language.Futhark.Primitive.IntType
instance GHC.Classes.Eq Language.Futhark.Primitive.IntType
instance GHC.Enum.Bounded Language.Futhark.Primitive.FloatType
instance GHC.Enum.Enum Language.Futhark.Primitive.FloatType
instance GHC.Show.Show Language.Futhark.Primitive.FloatType
instance GHC.Classes.Ord Language.Futhark.Primitive.FloatType
instance GHC.Classes.Eq Language.Futhark.Primitive.FloatType
instance GHC.Show.Show Language.Futhark.Primitive.PrimType
instance GHC.Classes.Ord Language.Futhark.Primitive.PrimType
instance GHC.Classes.Eq Language.Futhark.Primitive.PrimType
instance GHC.Show.Show Language.Futhark.Primitive.IntValue
instance GHC.Classes.Ord Language.Futhark.Primitive.IntValue
instance GHC.Classes.Eq Language.Futhark.Primitive.IntValue
instance GHC.Show.Show Language.Futhark.Primitive.FloatValue
instance GHC.Show.Show Language.Futhark.Primitive.PrimValue
instance GHC.Classes.Ord Language.Futhark.Primitive.PrimValue
instance GHC.Classes.Eq Language.Futhark.Primitive.PrimValue
instance GHC.Show.Show Language.Futhark.Primitive.UnOp
instance GHC.Classes.Ord Language.Futhark.Primitive.UnOp
instance GHC.Classes.Eq Language.Futhark.Primitive.UnOp
instance GHC.Show.Show Language.Futhark.Primitive.Overflow
instance GHC.Show.Show Language.Futhark.Primitive.Safety
instance GHC.Classes.Ord Language.Futhark.Primitive.Safety
instance GHC.Classes.Eq Language.Futhark.Primitive.Safety
instance GHC.Show.Show Language.Futhark.Primitive.BinOp
instance GHC.Classes.Ord Language.Futhark.Primitive.BinOp
instance GHC.Classes.Eq Language.Futhark.Primitive.BinOp
instance GHC.Show.Show Language.Futhark.Primitive.CmpOp
instance GHC.Classes.Ord Language.Futhark.Primitive.CmpOp
instance GHC.Classes.Eq Language.Futhark.Primitive.CmpOp
instance GHC.Show.Show Language.Futhark.Primitive.ConvOp
instance GHC.Classes.Ord Language.Futhark.Primitive.ConvOp
instance GHC.Classes.Eq Language.Futhark.Primitive.ConvOp
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.ConvOp
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.CmpOp
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.BinOp
instance GHC.Classes.Eq Language.Futhark.Primitive.Overflow
instance GHC.Classes.Ord Language.Futhark.Primitive.Overflow
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.UnOp
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.PrimValue
instance GHC.Classes.Eq Language.Futhark.Primitive.FloatValue
instance GHC.Classes.Ord Language.Futhark.Primitive.FloatValue
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.FloatValue
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.IntValue
instance GHC.Enum.Enum Language.Futhark.Primitive.PrimType
instance GHC.Enum.Bounded Language.Futhark.Primitive.PrimType
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.PrimType
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.FloatType
instance Prettyprinter.Internal.Pretty Language.Futhark.Primitive.IntType

-- | The most primitive ("core") aspects of the AST. Split out of
--   Futhark.IR.Syntax in order for Futhark.IR.Rep 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

-- | 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 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

-- | stripDims n shape strips the outer n dimensions from
--   shape.
stripDims :: Int -> ShapeBase d -> ShapeBase d

-- | 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

-- | 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

-- | The type of a value. When comparing types for equality with ==,
--   shapes must match.
data TypeBase shape u
Prim :: PrimType -> TypeBase shape u

-- | Token, index space, element type, and uniqueness.
Acc :: VName -> Shape -> [Type] -> u -> 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 :: Text -> ErrorMsgPart a

-- | A run-time value.
ErrorVal :: PrimType -> a -> ErrorMsgPart a

-- | How many non-constant parts does the error message have, and what is
--   their type?
errorMsgArgTypes :: ErrorMsg a -> [PrimType]

-- | An actual non-opaque type that can be passed to and from Futhark
--   programs, or serve as the contents of opaque types. Scalars are
--   represented with zero rank.
data ValueType
ValueType :: Signedness -> Rank -> PrimType -> ValueType

-- | The representation of an opaque type.
data OpaqueType
OpaqueType :: [ValueType] -> OpaqueType

-- | Note that the field ordering here denote the actual representation -
--   make sure it is preserved.
OpaqueRecord :: [(Name, EntryPointType)] -> OpaqueType

-- | Constructor ordering also denotes representation, in that the index of
--   the constructor is the identifying number.
--   
--   The total values used to represent a sum values is the
--   ValueType list. The Ints associated with each
--   EntryPointType are the indexes of the values used to represent
--   that constructor payload. This is necessary because we deduplicate
--   payloads across constructors.
OpaqueSum :: [ValueType] -> [(Name, [(EntryPointType, [Int])])] -> OpaqueType

-- | An array with this rank and named opaque element type.
OpaqueArray :: Int -> Name -> [ValueType] -> OpaqueType

-- | An array with known rank and where the elements are this record type.
OpaqueRecordArray :: Int -> Name -> [(Name, EntryPointType)] -> OpaqueType

-- | Names of opaque types and their representation.
newtype OpaqueTypes
OpaqueTypes :: [(Name, OpaqueType)] -> OpaqueTypes

-- | 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. This doesn't matter for non-integer
--   types.
data Signedness
Unsigned :: Signedness
Signed :: Signedness

-- | Every entry point argument and return value has an annotation
--   indicating how it maps to the original source program type.
data EntryPointType

-- | An opaque type of this name.
TypeOpaque :: Name -> EntryPointType

-- | A transparent type, which is scalar if the rank is zero.
TypeTransparent :: ValueType -> EntryPointType

-- | A single attribute.
data Attr
AttrName :: Name -> Attr
AttrInt :: Integer -> 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

-- | Map a function over an attribute set.
mapAttrs :: (Attr -> a) -> Attrs -> [a]

-- | Non-array values.
data PrimValue
IntValue :: !IntValue -> PrimValue
FloatValue :: !FloatValue -> PrimValue
BoolValue :: !Bool -> PrimValue

-- | The only value of type Unit.
UnitValue :: 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 Certs
Certs :: [VName] -> Certs
[unCerts] :: Certs -> [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 :: Attrs -> VName -> dec -> Param dec

-- | Attributes of the parameter. When constructing a parameter, feel free
--   to just pass mempty.
[paramAttrs] :: Param dec -> Attrs

-- | 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 DimIndexs, 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.
newtype Slice d
Slice :: [DimIndex d] -> Slice d
[unSlice] :: 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]

-- | The shape of the array produced by this slice.
sliceShape :: Slice d -> ShapeBase 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 PatElem dec
PatElem :: VName -> dec -> PatElem dec

-- | The name being bound.
[patElemName] :: PatElem dec -> VName

-- | Pat element decoration.
[patElemDec] :: PatElem dec -> dec

-- | A flat slice is a way of viewing a one-dimensional array as a
--   multi-dimensional array, using a more compressed mechanism than
--   reshaping and using Slice. The initial d is an offset,
--   and the list then specifies the shape of the resulting array.
data FlatSlice d
FlatSlice :: d -> [FlatDimIndex d] -> FlatSlice d

-- | A dimension in a FlatSlice.
data FlatDimIndex d
FlatDimIndex :: d -> d -> FlatDimIndex d

-- | The dimensions (shape) of the view produced by a flat slice.
flatSliceDims :: FlatSlice d -> [d]

-- | The strides of each dimension produced by a flat slice.
flatSliceStrides :: FlatSlice d -> [d]
instance GHC.Show.Show Futhark.IR.Syntax.Core.Commutativity
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Commutativity
instance GHC.Classes.Eq Futhark.IR.Syntax.Core.Commutativity
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.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.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.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.Show.Show Futhark.IR.Syntax.Core.Certs
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Certs
instance GHC.Classes.Eq Futhark.IR.Syntax.Core.Certs
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.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.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.Show.Show Futhark.IR.Syntax.Core.Ident
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.Show.Show d => GHC.Show.Show (Futhark.IR.Syntax.Core.Slice d)
instance GHC.Classes.Ord d => GHC.Classes.Ord (Futhark.IR.Syntax.Core.Slice d)
instance GHC.Classes.Eq d => GHC.Classes.Eq (Futhark.IR.Syntax.Core.Slice d)
instance GHC.Show.Show d => GHC.Show.Show (Futhark.IR.Syntax.Core.FlatDimIndex d)
instance GHC.Classes.Ord d => GHC.Classes.Ord (Futhark.IR.Syntax.Core.FlatDimIndex d)
instance GHC.Classes.Eq d => GHC.Classes.Eq (Futhark.IR.Syntax.Core.FlatDimIndex d)
instance GHC.Show.Show d => GHC.Show.Show (Futhark.IR.Syntax.Core.FlatSlice d)
instance GHC.Classes.Ord d => GHC.Classes.Ord (Futhark.IR.Syntax.Core.FlatSlice d)
instance GHC.Classes.Eq d => GHC.Classes.Eq (Futhark.IR.Syntax.Core.FlatSlice d)
instance GHC.Classes.Eq dec => GHC.Classes.Eq (Futhark.IR.Syntax.Core.PatElem dec)
instance GHC.Show.Show dec => GHC.Show.Show (Futhark.IR.Syntax.Core.PatElem dec)
instance GHC.Classes.Ord dec => GHC.Classes.Ord (Futhark.IR.Syntax.Core.PatElem dec)
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.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 GHC.Classes.Eq Futhark.IR.Syntax.Core.Attr
instance GHC.Show.Show Futhark.IR.Syntax.Core.Attr
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Attr
instance GHC.Base.Semigroup Futhark.IR.Syntax.Core.Attrs
instance GHC.Base.Monoid Futhark.IR.Syntax.Core.Attrs
instance GHC.Classes.Eq Futhark.IR.Syntax.Core.Attrs
instance GHC.Show.Show Futhark.IR.Syntax.Core.Attrs
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Attrs
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.Show.Show Futhark.IR.Syntax.Core.Signedness
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Signedness
instance GHC.Classes.Eq Futhark.IR.Syntax.Core.Signedness
instance GHC.Show.Show Futhark.IR.Syntax.Core.ValueType
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.ValueType
instance GHC.Classes.Eq Futhark.IR.Syntax.Core.ValueType
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.EntryPointType
instance GHC.Show.Show Futhark.IR.Syntax.Core.EntryPointType
instance GHC.Classes.Eq Futhark.IR.Syntax.Core.EntryPointType
instance GHC.Show.Show Futhark.IR.Syntax.Core.OpaqueType
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.OpaqueType
instance GHC.Classes.Eq Futhark.IR.Syntax.Core.OpaqueType
instance GHC.Show.Show Futhark.IR.Syntax.Core.OpaqueTypes
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.OpaqueTypes
instance GHC.Classes.Eq Futhark.IR.Syntax.Core.OpaqueTypes
instance GHC.Base.Monoid Futhark.IR.Syntax.Core.OpaqueTypes
instance GHC.Base.Semigroup Futhark.IR.Syntax.Core.OpaqueTypes
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 Data.String.IsString Futhark.IR.Syntax.Core.Attr
instance Data.String.IsString (Futhark.IR.Syntax.Core.ErrorMsg a)
instance GHC.Base.Monoid (Futhark.IR.Syntax.Core.ErrorMsg a)
instance GHC.Base.Semigroup (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 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 GHC.Base.Functor Futhark.IR.Syntax.Core.PatElem
instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.PatElem
instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.PatElem
instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.FlatSlice
instance GHC.Base.Functor Futhark.IR.Syntax.Core.FlatSlice
instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.FlatSlice
instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.FlatDimIndex
instance GHC.Base.Functor Futhark.IR.Syntax.Core.FlatDimIndex
instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.FlatDimIndex
instance Data.Traversable.Traversable Futhark.IR.Syntax.Core.Slice
instance GHC.Base.Functor Futhark.IR.Syntax.Core.Slice
instance Data.Foldable.Foldable Futhark.IR.Syntax.Core.Slice
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 GHC.Classes.Eq Futhark.IR.Syntax.Core.Ident
instance GHC.Classes.Ord Futhark.IR.Syntax.Core.Ident
instance Data.Bitraversable.Bitraversable Futhark.IR.Syntax.Core.TypeBase
instance GHC.Base.Functor (Futhark.IR.Syntax.Core.TypeBase shape)
instance Data.Foldable.Foldable (Futhark.IR.Syntax.Core.TypeBase shape)
instance Data.Traversable.Traversable (Futhark.IR.Syntax.Core.TypeBase shape)
instance Data.Bifunctor.Bifunctor Futhark.IR.Syntax.Core.TypeBase
instance Data.Bifoldable.Bifoldable Futhark.IR.Syntax.Core.TypeBase
instance Futhark.IR.Syntax.Core.ArrayShape (Futhark.IR.Syntax.Core.ShapeBase Futhark.IR.Syntax.Core.ExtSize)
instance Futhark.IR.Syntax.Core.ArrayShape (Futhark.IR.Syntax.Core.ShapeBase Futhark.IR.Syntax.Core.SubExp)
instance GHC.Base.Semigroup Futhark.IR.Syntax.Core.Certs
instance GHC.Base.Monoid Futhark.IR.Syntax.Core.Certs
instance Futhark.IR.Syntax.Core.ArrayShape Futhark.IR.Syntax.Core.Rank
instance GHC.Base.Semigroup Futhark.IR.Syntax.Core.Rank
instance GHC.Base.Monoid Futhark.IR.Syntax.Core.Rank
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 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)
instance GHC.Base.Semigroup Futhark.IR.Syntax.Core.Commutativity
instance GHC.Base.Monoid Futhark.IR.Syntax.Core.Commutativity

-- | Configuration of compiler behaviour that is universal to all backends.
module Futhark.Compiler.Config

-- | 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 -> [Name] -> 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

-- | Additional functions that should be exposed as entry points.
[futharkEntryPoints] :: FutharkConfig -> [Name]

-- | If false, disable type-checking
[futharkTypeCheck] :: FutharkConfig -> Bool

-- | The default compiler configuration.
newFutharkConfig :: FutharkConfig

-- | 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

-- | Are we compiling a library or an executable?
data CompilerMode
ToLibrary :: CompilerMode
ToExecutable :: CompilerMode
ToServer :: CompilerMode
instance GHC.Show.Show Futhark.Compiler.Config.CompilerMode
instance GHC.Classes.Ord Futhark.Compiler.Config.CompilerMode
instance GHC.Classes.Eq Futhark.Compiler.Config.CompilerMode
instance GHC.Classes.Ord Futhark.Compiler.Config.Verbosity
instance GHC.Classes.Eq Futhark.Compiler.Config.Verbosity

-- | 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 Language.Futhark.Primitive.PrimValue
instance Futhark.IR.Prop.Constants.IsValue Language.Futhark.Primitive.IntValue
instance Futhark.IR.Prop.Constants.IsValue Language.Futhark.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

-- | If the array is statically an empty array (meaning any dimension is a
--   static zero), return the element type and the shape.
isEmptyArray :: Type -> Maybe (PrimType, Shape)

-- | 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 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

-- | Is this an accumulator?
isAcc :: 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 some outermost dimensions of an array shape.
setOuterDims :: ShapeBase d -> Int -> ShapeBase 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 :: 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 :: 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

-- | Returns the bottommost type of an array. For [][]i32, this
--   would be i32. If the given type is not an array, it is
--   returned.
elemType :: TypeBase shape u -> PrimType

-- | Return the immediate row-type of an array. For [[int]], this
--   would be [int].
rowType :: TypeBase Shape u -> TypeBase Shape u

-- | 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 Ext integers used for existential sizes in the given types.
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

-- | 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

-- | Map a function onto any existential.
mapExt :: FixExt t => (Int -> Int) -> t -> t
instance Futhark.IR.Prop.Types.ExtTyped Futhark.IR.Syntax.Core.ExtType
instance Futhark.IR.Prop.Types.ExtTyped Futhark.IR.Syntax.Core.DeclExtType
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.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.PatElem 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, ExtTyped 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 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 rep type
--   parameter, which is then used to invoke the type families defined
--   here.
module Futhark.IR.Rep

-- | A collection of type families giving various common types for a
--   representation, 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)) => RepTypes l where {
    
    -- | Decoration for every let-pattern element.
    type LetDec l :: Type;
    
    -- | Decoration for every expression.
    type ExpDec l :: Type;
    
    -- | Decoration for every body.
    type BodyDec l :: Type;
    
    -- | Decoration for every (non-lambda) function parameter.
    type FParamInfo l :: Type;
    
    -- | Decoration for every lambda function parameter.
    type LParamInfo l :: Type;
    
    -- | The return type decoration of function calls.
    type RetType l :: Type;
    
    -- | The return type decoration of branches.
    type BranchType l :: Type;
    
    -- | Type constructor for the extensible operation. The somewhat funky
    --   definition is to ensure that we can change the "inner" representation
    --   in a generic way (e.g. add aliasing information) In most code, you
    --   will use the <a>Op</a> alias instead.
    type OpC l :: Type -> 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 OpC l = NoOp;
}

-- | Apply the OpC constructor of a representation to that
--   representation.
type Op l = OpC l l

-- | Returns nothing and does nothing. Placeholder for when we don't really
--   want an operation.
data NoOp rep
NoOp :: NoOp rep
instance forall k (rep :: k). GHC.Show.Show (Futhark.IR.Rep.NoOp rep)
instance forall k (rep :: k). GHC.Classes.Ord (Futhark.IR.Rep.NoOp rep)
instance forall k (rep :: k). GHC.Classes.Eq (Futhark.IR.Rep.NoOp rep)

-- | 
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 and
--   Acc 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
--   Language.Futhark.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 Pat alongside an
--   expression Exp. A pattern is a sequence of name/type pairs.
--   
--   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}
--   
--   
--   
Representations
--   
--   Most AST types (Stm, Exp, Prog, etc) are
--   parameterised by a type parameter rep. The representation
--   specifies how to fill out various polymorphic parts of the AST. For
--   example, Exp has a constructor Op whose payload depends
--   on rep, via the use of a type family called Op (a kind
--   of type-level function) which is applied to the rep. The
--   SOACS representation (Futhark.IR.SOACS) thus uses a rep 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 PatElem)
--   are also type families.
--   
--   The full list of possible decorations is defined as part of the type
--   class RepTypes (although other type families are also used
--   elsewhere in the compiler on an ad hoc basis).
--   
--   Essentially, the rep 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).
--   
--   Some AST elements (such as Pat) do not take a rep type
--   parameter, but instead immediately the single type of decoration that
--   they contain. We only use the more complicated machinery when needed.
--   
--   Defining a new representation (or rep) 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

-- | Prettyprint a value to a String, appropriately wrapped.
prettyString :: Pretty a => a -> String

-- | Prettyprint a value to a Text, appropriately wrapped.
prettyText :: Pretty a => a -> Text

-- | Overloaded conversion to Doc.
--   
--   Laws:
--   
--   
--   
- output should be pretty. :-)
--   
class () => Pretty a

-- | 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.
--   Also has a different prettyprinting instance.
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

-- | 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

-- | The type of a value. When comparing types for equality with ==,
--   shapes must match.
data TypeBase shape u
Prim :: PrimType -> TypeBase shape u

-- | Token, index space, element type, and uniqueness.
Acc :: VName -> Shape -> [Type] -> u -> 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

-- | 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

-- | 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 PatElem dec
PatElem :: VName -> dec -> PatElem dec

-- | The name being bound.
[patElemName] :: PatElem dec -> VName

-- | Pat element decoration.
[patElemDec] :: PatElem dec -> dec

-- | A pattern is conceptually just a list of names and their types.
newtype Pat dec
Pat :: [PatElem dec] -> Pat dec
[patElems] :: Pat dec -> [PatElem dec]

-- | Auxilliary Information associated with a statement.
data StmAux dec
StmAux :: !Certs -> Attrs -> dec -> StmAux dec
[stmAuxCerts] :: StmAux dec -> !Certs
[stmAuxAttrs] :: StmAux dec -> Attrs
[stmAuxDec] :: StmAux dec -> dec

-- | A local variable binding.
data Stm rep
Let :: Pat (LetDec rep) -> StmAux (ExpDec rep) -> Exp rep -> Stm rep

-- | Pat.
[stmPat] :: Stm rep -> Pat (LetDec rep)

-- | Auxiliary information statement.
[stmAux] :: Stm rep -> StmAux (ExpDec rep)

-- | Expression.
[stmExp] :: Stm rep -> Exp rep

-- | A sequence of statements.
type Stms rep = Seq (Stm rep)

-- | A pairing of a subexpression and some certificates.
data SubExpRes
SubExpRes :: Certs -> SubExp -> SubExpRes
[resCerts] :: SubExpRes -> Certs
[resSubExp] :: SubExpRes -> SubExp

-- | The result of a body is a sequence of subexpressions.
type Result = [SubExpRes]

-- | A body consists of a sequence of statements, terminating in a list of
--   result values.
data Body rep
Body :: BodyDec rep -> Stms rep -> Result -> Body rep
[bodyDec] :: Body rep -> BodyDec rep
[bodyStms] :: Body rep -> Stms rep
[bodyResult] :: Body rep -> Result

-- | 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 partially a
--   hack to avoid optimisation (so, to work around compiler limitations),
--   but is also used to implement tracing and other operations that are
--   semantically invisible, but have some sort of effect (brrr).
Opaque :: OpaqueOp -> SubExp -> BasicOp

-- | Array literals, e.g., [ [1+x, 3], [2, 1+4] ]. Second arg is
--   the element type of the rows of the array.
ArrayLit :: [SubExp] -> Type -> BasicOp

-- | A one-dimensional array literal that contains only constants. This is
--   a fast-path for representing very large array literals that show up in
--   some programs. The key rule for processing this in compiler passes is
--   that you should never need to look at the individual elements. Has
--   exactly the same semantics as an ArrayLit.
ArrayVal :: [PrimValue] -> PrimType -> 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. If Safe, perform a run-time bounds check and ignore
--   the write if out of bounds (like Scatter).
Update :: Safety -> VName -> Slice SubExp -> SubExp -> BasicOp
FlatIndex :: VName -> FlatSlice SubExp -> BasicOp
FlatUpdate :: VName -> FlatSlice SubExp -> VName -> BasicOp

-- | 
--   concat(0, [1] :| [[2, 3, 4], [5, 6]], 6) = [1, 2, 3, 4, 5, 6]
--   
--   
--   Concatenates the non-empty list of VName resulting in an array
--   of length SubExp. The Int argument is used to specify
--   the dimension along which the arrays are concatenated. For instance:
--   
--   
--   concat(1, [[1,2], [3, 4]] :| [[[5,6]], [[7, 8]]], 4) = [[1, 2, 5, 6], [3, 4, 7, 8]]
--   
Concat :: Int -> NonEmpty VName -> SubExp -> 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]]. The result has
--   no aliases. Copy a value by passing an empty shape.
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 :: ReshapeKind -> Shape -> 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

-- | Update an accumulator at the given index with the given value.
--   Consumes the accumulator and produces a new one. If Safe,
--   perform a run-time bounds check and ignore the write if out of bounds
--   (like Scatter).
UpdateAcc :: Safety -> VName -> [SubExp] -> [SubExp] -> 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

-- | Flip sign. Logical negation for booleans.
Neg :: PrimType -> 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

-- | Floating-point sign function.
FSignum :: FloatType -> 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

-- | Convert a float to a boolean value. Zero becomes false; | anything
--   else is true.
FToB :: FloatType -> ConvOp

-- | Convert a boolean to a float. True is converted to 1 and False to 0.
BToF :: FloatType -> ConvOp

-- | Apart from being Opaque, what else is going on here?
data OpaqueOp

-- | No special operation.
OpaqueNil :: OpaqueOp

-- | Print the argument, prefixed by this string.
OpaqueTrace :: Text -> OpaqueOp

-- | Which kind of reshape is this?
data ReshapeKind

-- | New shape is dynamically same as original.
ReshapeCoerce :: ReshapeKind

-- | Any kind of reshaping.
ReshapeArbitrary :: ReshapeKind

-- | The input to a WithAcc construct. Comprises the index space of
--   the accumulator, the underlying arrays, and possibly a combining
--   function.
type WithAccInput rep = (Shape, [VName], Maybe (Lambda rep, [SubExp]))

-- | The root Futhark expression type. The Op constructor contains a
--   rep-specific operation. Do-loops, branches and function calls are
--   special. Everything else is a simple BasicOp.
data Exp rep

-- | A simple (non-recursive) operation.
BasicOp :: BasicOp -> Exp rep
Apply :: Name -> [(SubExp, Diet)] -> [(RetType rep, RetAls)] -> (Safety, SrcLoc, [SrcLoc]) -> Exp rep

-- | A match statement picks a branch by comparing the given subexpressions
--   (called the scrutinee) with the pattern in each of the cases.
--   If none of the cases match, the /default body/ is picked.
Match :: [SubExp] -> [Case (Body rep)] -> Body rep -> MatchDec (BranchType rep) -> Exp rep

-- | loop {a} = {v} (for i < n|while b) do b.
Loop :: [(FParam rep, SubExp)] -> LoopForm -> Body rep -> Exp rep

-- | Create accumulators backed by the given arrays (which are consumed)
--   and pass them to the lambda, which must return the updated
--   accumulators and possibly some extra values. The accumulators are
--   turned back into arrays. In the lambda, the result accumulators come
--   first, and are ordered in a manner consistent with that of the input
--   (accumulator) arguments. The Shape is the write index space.
--   The corresponding arrays must all have this shape outermost. This
--   construct is not part of BasicOp because we need the
--   rep parameter.
WithAcc :: [WithAccInput rep] -> Lambda rep -> Exp rep
Op :: Op rep -> Exp rep

-- | A non-default case in a Match statement. The number of elements
--   in the pattern must match the number of scrutinees. A Nothing
--   value indicates that we don't care about it (i.e. a wildcard).
data Case body
Case :: [Maybe PrimValue] -> body -> Case body
[casePat] :: Case body -> [Maybe PrimValue]
[caseBody] :: Case body -> body

-- | For-loop or while-loop?
data LoopForm
ForLoop :: VName -> IntType -> SubExp -> LoopForm
WhileLoop :: VName -> LoopForm

-- | Data associated with a branch.
data MatchDec rt
MatchDec :: [rt] -> MatchSort -> MatchDec rt
[matchReturns] :: MatchDec rt -> [rt]
[matchSort] :: MatchDec rt -> MatchSort

-- | What kind of branch is this? This has no semantic meaning, but
--   provides hints to simplifications.
data MatchSort

-- | An ordinary branch.
MatchNormal :: MatchSort

-- | 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.
MatchFallback :: MatchSort

-- | 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).
MatchEquiv :: MatchSort

-- | 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 Lambda rep
Lambda :: [LParam rep] -> [Type] -> Body rep -> Lambda rep
[lambdaParams] :: Lambda rep -> [LParam rep]
[lambdaReturnType] :: Lambda rep -> [Type]
[lambdaBody] :: Lambda rep -> Body rep

-- | Information about the possible aliases of a function result.
data RetAls
RetAls :: [Int] -> [Int] -> RetAls

-- | Which of the parameters may be aliased, numbered from zero. Must be
--   sorted in increasing order.
[paramAls] :: RetAls -> [Int]

-- | Which of the other results may be aliased, numbered from zero. This
--   must be a reflexive relation. Must be sorted in increasing order.
[otherAls] :: RetAls -> [Int]

-- | A function or lambda parameter.
data Param dec
Param :: Attrs -> VName -> dec -> Param dec

-- | Attributes of the parameter. When constructing a parameter, feel free
--   to just pass mempty.
[paramAttrs] :: Param dec -> Attrs

-- | Name of the parameter.
[paramName] :: Param dec -> VName

-- | Function parameter decoration.
[paramDec] :: Param dec -> dec

-- | A function and loop parameter.
type FParam rep = Param (FParamInfo rep)

-- | A lambda parameter.
type LParam rep = Param (LParamInfo rep)

-- | Function definitions.
data FunDef rep
FunDef :: Maybe EntryPoint -> Attrs -> Name -> [(RetType rep, RetAls)] -> [FParam rep] -> Body rep -> FunDef rep

-- | Contains a value if this function is an entry point.
[funDefEntryPoint] :: FunDef rep -> Maybe EntryPoint
[funDefAttrs] :: FunDef rep -> Attrs
[funDefName] :: FunDef rep -> Name
[funDefRetType] :: FunDef rep -> [(RetType rep, RetAls)]
[funDefParams] :: FunDef rep -> [FParam rep]
[funDefBody] :: FunDef rep -> Body rep

-- | An entry point parameter, comprising its name and original type.
data EntryParam
EntryParam :: Name -> Uniqueness -> EntryPointType -> EntryParam
[entryParamName] :: EntryParam -> Name
[entryParamUniqueness] :: EntryParam -> Uniqueness
[entryParamType] :: EntryParam -> EntryPointType

-- | An entry point result type.
data EntryResult
EntryResult :: Uniqueness -> EntryPointType -> EntryResult
[entryResultUniqueness] :: EntryResult -> Uniqueness
[entryResultType] :: EntryResult -> EntryPointType

-- | Information about the inputs and outputs (return value) of an entry
--   point.
type EntryPoint = (Name, [EntryParam], [EntryResult])

-- | An entire Futhark program.
data Prog rep
Prog :: OpaqueTypes -> Stms rep -> [FunDef rep] -> Prog rep

-- | The opaque types used in entry points. This information is used to
--   generate extra API functions for construction and deconstruction of
--   values of these types.
[progTypes] :: Prog rep -> OpaqueTypes

-- | Top-level constants that are computed at program startup, and which
--   are in scope inside all functions.
[progConsts] :: Prog rep -> Stms rep

-- | The functions comprising the program. All functions are also available
--   in scope in the definitions of the constants, so be careful not to
--   introduce circular dependencies (not currently checked).
[progFuns] :: Prog rep -> [FunDef rep]

-- | A single statement.
oneStm :: Stm rep -> Stms rep

-- | Convert a statement list to a statement sequence.
stmsFromList :: [Stm rep] -> Stms rep

-- | Convert a statement sequence to a statement list.
stmsToList :: Stms rep -> [Stm rep]

-- | The first statement in the sequence, if any.
stmsHead :: Stms rep -> Maybe (Stm rep, Stms rep)

-- | The last statement in the sequence, if any.
stmsLast :: Stms lore -> Maybe (Stms lore, Stm lore)

-- | Construct a SubExpRes with no certificates.
subExpRes :: SubExp -> SubExpRes

-- | Construct a Result from subexpressions.
subExpsRes :: [SubExp] -> Result

-- | Construct a SubExpRes from a variable name.
varRes :: VName -> SubExpRes

-- | Construct a Result from variable names.
varsRes :: [VName] -> Result

-- | The VName of a SubExpRes, if it exists.
subExpResVName :: SubExpRes -> Maybe VName
instance GHC.Classes.Eq dec => GHC.Classes.Eq (Futhark.IR.Syntax.Pat dec)
instance GHC.Show.Show dec => GHC.Show.Show (Futhark.IR.Syntax.Pat dec)
instance GHC.Classes.Ord dec => GHC.Classes.Ord (Futhark.IR.Syntax.Pat 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.Show.Show Futhark.IR.Syntax.SubExpRes
instance GHC.Classes.Ord Futhark.IR.Syntax.SubExpRes
instance GHC.Classes.Eq Futhark.IR.Syntax.SubExpRes
instance GHC.Show.Show Futhark.IR.Syntax.OpaqueOp
instance GHC.Classes.Ord Futhark.IR.Syntax.OpaqueOp
instance GHC.Classes.Eq Futhark.IR.Syntax.OpaqueOp
instance GHC.Show.Show Futhark.IR.Syntax.ReshapeKind
instance GHC.Classes.Ord Futhark.IR.Syntax.ReshapeKind
instance GHC.Classes.Eq Futhark.IR.Syntax.ReshapeKind
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.Show.Show body => GHC.Show.Show (Futhark.IR.Syntax.Case body)
instance GHC.Classes.Ord body => GHC.Classes.Ord (Futhark.IR.Syntax.Case body)
instance GHC.Classes.Eq body => GHC.Classes.Eq (Futhark.IR.Syntax.Case body)
instance GHC.Show.Show Futhark.IR.Syntax.RetAls
instance GHC.Classes.Ord Futhark.IR.Syntax.RetAls
instance GHC.Classes.Eq Futhark.IR.Syntax.RetAls
instance GHC.Show.Show Futhark.IR.Syntax.LoopForm
instance GHC.Classes.Ord Futhark.IR.Syntax.LoopForm
instance GHC.Classes.Eq Futhark.IR.Syntax.LoopForm
instance GHC.Classes.Ord Futhark.IR.Syntax.MatchSort
instance GHC.Show.Show Futhark.IR.Syntax.MatchSort
instance GHC.Classes.Eq Futhark.IR.Syntax.MatchSort
instance GHC.Classes.Ord rt => GHC.Classes.Ord (Futhark.IR.Syntax.MatchDec rt)
instance GHC.Show.Show rt => GHC.Show.Show (Futhark.IR.Syntax.MatchDec rt)
instance GHC.Classes.Eq rt => GHC.Classes.Eq (Futhark.IR.Syntax.MatchDec rt)
instance GHC.Classes.Ord Futhark.IR.Syntax.EntryParam
instance GHC.Show.Show Futhark.IR.Syntax.EntryParam
instance GHC.Classes.Eq Futhark.IR.Syntax.EntryParam
instance GHC.Classes.Ord Futhark.IR.Syntax.EntryResult
instance GHC.Show.Show Futhark.IR.Syntax.EntryResult
instance GHC.Classes.Eq Futhark.IR.Syntax.EntryResult
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.Syntax.Prog rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.Syntax.Prog rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.Syntax.Prog rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.Syntax.Stm rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.Syntax.Stm rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.Syntax.Stm rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.Syntax.Body rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.Syntax.Body rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.Syntax.Body rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.Syntax.Exp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.Syntax.Exp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.Syntax.Exp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.Syntax.Lambda rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.Syntax.Lambda rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.Syntax.Lambda rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.Syntax.FunDef rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.Syntax.FunDef rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.Syntax.FunDef rep)
instance GHC.Base.Monoid Futhark.IR.Syntax.RetAls
instance GHC.Base.Semigroup Futhark.IR.Syntax.RetAls
instance GHC.Base.Functor Futhark.IR.Syntax.Case
instance Data.Foldable.Foldable Futhark.IR.Syntax.Case
instance Data.Traversable.Traversable Futhark.IR.Syntax.Case
instance GHC.Base.Semigroup dec => GHC.Base.Semigroup (Futhark.IR.Syntax.StmAux dec)
instance GHC.Base.Semigroup (Futhark.IR.Syntax.Pat dec)
instance GHC.Base.Monoid (Futhark.IR.Syntax.Pat dec)
instance GHC.Base.Functor Futhark.IR.Syntax.Pat
instance Data.Foldable.Foldable Futhark.IR.Syntax.Pat
instance Data.Traversable.Traversable Futhark.IR.Syntax.Pat

-- | 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 (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.Monad im => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.State.Lazy.StateT Futhark.FreshNames.VNameSource im)
instance GHC.Base.Monad im => Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.State.Strict.StateT Futhark.FreshNames.VNameSource im)
instance (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.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)

-- | Facilities for creating, inspecting, and simplifying reshape and
--   coercion operations.
module Futhark.IR.Prop.Reshape

-- | Construct a Reshape that is a ReshapeCoerce.
shapeCoerce :: [SubExp] -> VName -> Exp rep

-- | reshapeOuter newshape n oldshape returns a Reshape
--   expression that replaces the outer n dimensions of
--   oldshape with newshape.
reshapeOuter :: Shape -> Int -> Shape -> Shape

-- | 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 :: Shape -> Int -> Shape -> Shape

-- | 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]

-- | 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] -> Text

-- | Like prettyTuple, but put a linebreak after every element.
prettyTupleLines :: Pretty a => [a] -> Text

-- | Prettyprint a value to a String, appropriately wrapped.
prettyString :: Pretty a => a -> String

-- | The class of representations whose annotations can be prettyprinted.
class (RepTypes rep, Pretty (RetType rep), Pretty (BranchType rep), Pretty (FParamInfo rep), Pretty (LParamInfo rep), Pretty (LetDec rep), Pretty (Op rep)) => PrettyRep rep
ppExpDec :: PrettyRep rep => ExpDec rep -> Exp rep -> Maybe (Doc a)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Stms rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Body rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Stm rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Case (Futhark.IR.Syntax.Body rep))
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Exp rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Lambda rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.FunDef rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Prog rep)
instance forall k (rep :: k). Prettyprinter.Internal.Pretty (Futhark.IR.Rep.NoOp rep)
instance Prettyprinter.Internal.Pretty Language.Futhark.Core.VName
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.Commutativity
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.Shape
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.Rank
instance Prettyprinter.Internal.Pretty a => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.Ext a)
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.ExtShape
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.Space
instance Prettyprinter.Internal.Pretty u => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.TypeBase Futhark.IR.Syntax.Core.Shape u)
instance Prettyprinter.Internal.Pretty u => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.TypeBase Futhark.IR.Syntax.Core.ExtShape u)
instance Prettyprinter.Internal.Pretty u => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.TypeBase Futhark.IR.Syntax.Core.Rank u)
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.Ident
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.SubExp
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.Certs
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.SubExpRes
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.Attr
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.Attrs
instance Prettyprinter.Internal.Pretty t => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Pat t)
instance Prettyprinter.Internal.Pretty t => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.PatElem t)
instance Prettyprinter.Internal.Pretty t => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.Param t)
instance Prettyprinter.Internal.Pretty a => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.Slice a)
instance Prettyprinter.Internal.Pretty d => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.FlatDimIndex d)
instance Prettyprinter.Internal.Pretty a => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.FlatSlice a)
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.BasicOp
instance Prettyprinter.Internal.Pretty a => Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.ErrorMsg a)
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.Signedness
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.ValueType
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.EntryPointType
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.EntryParam
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.EntryResult
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.OpaqueType
instance Prettyprinter.Internal.Pretty Futhark.IR.Syntax.Core.OpaqueTypes
instance Prettyprinter.Internal.Pretty d => Prettyprinter.Internal.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.
--   
--   A simple example of a monad that maintains such as environment is
--   Reader. Indeed, HasScope and LocalScope instances
--   for this monad are already defined.
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, RepTypes rep) => HasScope rep m | m -> rep

-- | Return the type of the given variable, or fail if it is not in the
--   type environment.
lookupType :: HasScope rep m => VName -> m Type

-- | Return the info of the given variable, or fail if it is not in the
--   type environment.
lookupInfo :: HasScope rep m => VName -> m (NameInfo rep)

-- | Return the type environment contained in the applicative functor.
askScope :: HasScope rep m => m (Scope rep)

-- | Return the result of applying some function to the type environment.
asksScope :: HasScope rep m => (Scope rep -> a) -> m a

-- | How some name in scope was bound.
data NameInfo rep
LetName :: LetDec rep -> NameInfo rep
FParamName :: FParamInfo rep -> NameInfo rep
LParamName :: LParamInfo rep -> NameInfo rep
IndexName :: IntType -> NameInfo rep

-- | 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 rep m, Monad m) => LocalScope rep 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 rep m => Scope rep -> m a -> m a

-- | A scope is a mapping from variable names to information about that
--   name.
type Scope rep = Map VName (NameInfo rep)

-- | 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 rep a | a -> rep
scopeOf :: Scoped rep a => a -> Scope rep

-- | Extend the monadic scope with the scopeOf the given value.
inScopeOf :: (Scoped rep a, LocalScope rep m) => a -> m b -> m b

-- | The scope of some lambda parameters.
scopeOfLParams :: LParamInfo rep ~ dec => [Param dec] -> Scope rep

-- | The scope of some function or loop parameters.
scopeOfFParams :: FParamInfo rep ~ dec => [Param dec] -> Scope rep

-- | The scope of a loop form.
scopeOfLoopForm :: LoopForm -> Scope rep

-- | The scope of a pattern.
scopeOfPat :: LetDec rep ~ dec => Pat dec -> Scope rep

-- | The scope of a pattern element.
scopeOfPatElem :: LetDec rep ~ dec => PatElem dec -> Scope rep

-- | A constraint that indicates two representations have the same
--   NameInfo representation.
type SameScope rep1 rep2 = (LetDec rep1 ~ LetDec rep2, FParamInfo rep1 ~ FParamInfo rep2, LParamInfo rep1 ~ LParamInfo rep2)

-- | If two scopes are really the same, then you can convert one to the
--   other.
castScope :: SameScope fromrep torep => Scope fromrep -> Scope torep

-- | 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 rep m a

-- | Run a computation in the extended type environment.
extendedScope :: ExtendedScope rep m a -> Scope rep -> m a
instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (Futhark.IR.Prop.Scope.Scope rep) (Futhark.IR.Prop.Scope.ExtendedScope rep m)
instance GHC.Base.Monad m => GHC.Base.Monad (Futhark.IR.Prop.Scope.ExtendedScope rep m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Futhark.IR.Prop.Scope.ExtendedScope rep m)
instance GHC.Base.Functor m => GHC.Base.Functor (Futhark.IR.Prop.Scope.ExtendedScope rep m)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.Prop.Scope.NameInfo rep)
instance (Futhark.IR.Prop.Scope.HasScope rep m, GHC.Base.Monad m) => Futhark.IR.Prop.Scope.HasScope rep (Futhark.IR.Prop.Scope.ExtendedScope rep m)
instance Futhark.IR.Prop.Scope.Scoped rep a => Futhark.IR.Prop.Scope.Scoped rep [a]
instance Futhark.IR.Prop.Scope.Scoped rep (Futhark.IR.Syntax.Stms rep)
instance Futhark.IR.Prop.Scope.Scoped rep (Futhark.IR.Syntax.Stm rep)
instance Futhark.IR.Prop.Scope.Scoped rep (Futhark.IR.Syntax.FunDef rep)
instance Futhark.IR.Prop.Scope.Scoped rep (Language.Futhark.Core.VName, Futhark.IR.Prop.Scope.NameInfo rep)
instance Futhark.IR.Prop.Scope.Scoped rep (Futhark.IR.Syntax.Lambda rep)
instance Futhark.IR.Prop.Scope.LocalScope rep m => Futhark.IR.Prop.Scope.LocalScope rep (Control.Monad.Trans.Except.ExceptT e m)
instance (GHC.Base.Monad m, Futhark.IR.Rep.RepTypes rep) => Futhark.IR.Prop.Scope.LocalScope rep (Control.Monad.Trans.Reader.ReaderT (Futhark.IR.Prop.Scope.Scope rep) m)
instance (GHC.Base.Monad m, GHC.Base.Monoid w, Futhark.IR.Rep.RepTypes rep) => Futhark.IR.Prop.Scope.LocalScope rep (Control.Monad.Trans.RWS.Strict.RWST (Futhark.IR.Prop.Scope.Scope rep) w s m)
instance (GHC.Base.Monad m, GHC.Base.Monoid w, Futhark.IR.Rep.RepTypes rep) => Futhark.IR.Prop.Scope.LocalScope rep (Control.Monad.Trans.RWS.Lazy.RWST (Futhark.IR.Prop.Scope.Scope rep) w s m)
instance (GHC.Base.Monad m, Futhark.IR.Rep.RepTypes rep) => Futhark.IR.Prop.Scope.HasScope rep (Control.Monad.Trans.Reader.ReaderT (Futhark.IR.Prop.Scope.Scope rep) m)
instance (GHC.Base.Monad m, Futhark.IR.Prop.Scope.HasScope rep m) => Futhark.IR.Prop.Scope.HasScope rep (Control.Monad.Trans.Except.ExceptT e m)
instance (GHC.Base.Monad m, GHC.Base.Monoid w, Futhark.IR.Rep.RepTypes rep) => Futhark.IR.Prop.Scope.HasScope rep (Control.Monad.Trans.RWS.Strict.RWST (Futhark.IR.Prop.Scope.Scope rep) w s m)
instance (GHC.Base.Monad m, GHC.Base.Monoid w, Futhark.IR.Rep.RepTypes rep) => Futhark.IR.Prop.Scope.HasScope rep (Control.Monad.Trans.RWS.Lazy.RWST (Futhark.IR.Prop.Scope.Scope rep) w s m)
instance Futhark.IR.Rep.RepTypes rep => Futhark.IR.Prop.Types.Typed (Futhark.IR.Prop.Scope.NameInfo rep)

-- | 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:
--   
--   
--   
- They are too slow.
--   
- More importantly, they do not tell you whether you have missed
--   some cases.
--   
--   
--   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 frep trep m
Mapper :: (SubExp -> m SubExp) -> (Scope trep -> Body frep -> m (Body trep)) -> (VName -> m VName) -> (RetType frep -> m (RetType trep)) -> (BranchType frep -> m (BranchType trep)) -> (FParam frep -> m (FParam trep)) -> (LParam frep -> m (LParam trep)) -> (Op frep -> m (Op trep)) -> Mapper frep trep m
[mapOnSubExp] :: Mapper frep trep m -> SubExp -> m SubExp

-- | Most bodies are enclosed in a scope, which is passed along for
--   convenience.
[mapOnBody] :: Mapper frep trep m -> Scope trep -> Body frep -> m (Body trep)
[mapOnVName] :: Mapper frep trep m -> VName -> m VName
[mapOnRetType] :: Mapper frep trep m -> RetType frep -> m (RetType trep)
[mapOnBranchType] :: Mapper frep trep m -> BranchType frep -> m (BranchType trep)
[mapOnFParam] :: Mapper frep trep m -> FParam frep -> m (FParam trep)
[mapOnLParam] :: Mapper frep trep m -> LParam frep -> m (LParam trep)
[mapOnOp] :: Mapper frep trep m -> Op frep -> m (Op trep)

-- | A mapper that simply returns the tree verbatim.
identityMapper :: forall rep m. Monad m => Mapper rep rep 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 :: Monad m => Mapper frep trep m -> Exp frep -> m (Exp trep)

-- | Like mapExpM, but in the Identity monad.
mapExp :: Mapper frep trep Identity -> Exp frep -> Exp trep

-- | 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 rep m
Walker :: (SubExp -> m ()) -> (Scope rep -> Body rep -> m ()) -> (VName -> m ()) -> (RetType rep -> m ()) -> (BranchType rep -> m ()) -> (FParam rep -> m ()) -> (LParam rep -> m ()) -> (Op rep -> m ()) -> Walker rep m
[walkOnSubExp] :: Walker rep m -> SubExp -> m ()
[walkOnBody] :: Walker rep m -> Scope rep -> Body rep -> m ()
[walkOnVName] :: Walker rep m -> VName -> m ()
[walkOnRetType] :: Walker rep m -> RetType rep -> m ()
[walkOnBranchType] :: Walker rep m -> BranchType rep -> m ()
[walkOnFParam] :: Walker rep m -> FParam rep -> m ()
[walkOnLParam] :: Walker rep m -> LParam rep -> m ()
[walkOnOp] :: Walker rep m -> Op rep -> m ()

-- | A no-op traversal.
identityWalker :: forall rep m. Monad m => Walker rep m

-- | As mapExpM, but do not construct a result AST.
walkExpM :: Monad m => Walker rep m -> Exp rep -> m ()

-- | This representation supports an OpStmsTraverser for its
--   Op. This is used for some simplification rules.
class TraverseOpStms rep

-- | Transform every sub-Stms of this op.
traverseOpStms :: (TraverseOpStms rep, Monad m) => OpStmsTraverser m (Op rep) rep

-- | A function for monadically traversing any sub-statements of the given
--   op for some representation.
type OpStmsTraverser m op rep = (Scope rep -> Stms rep -> m (Stms rep)) -> op -> m op

-- | A helper for defining traverseOpStms.
traverseLambdaStms :: Monad m => OpStmsTraverser m (Lambda rep) rep

-- | Facilities for changing the representation of some fragment, within a
--   monadic context. We call this "rephrasing", for no deep reason.
module Futhark.IR.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.
rephrasePat :: Monad m => (from -> m to) -> Pat from -> m (Pat to)

-- | Rephrase a pattern element.
rephrasePatElem :: Monad m => (from -> m to) -> PatElem from -> m (PatElem 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 rep 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
[rephraseExpDec] :: Rephraser m from to -> ExpDec from -> m (ExpDec to)
[rephraseLetBoundDec] :: Rephraser m from to -> LetDec from -> m (LetDec to)
[rephraseFParamDec] :: Rephraser m from to -> FParamInfo from -> m (FParamInfo to)
[rephraseLParamDec] :: Rephraser m from to -> LParamInfo from -> m (LParamInfo to)
[rephraseBodyDec] :: 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)

-- | Rephrasing any fragments inside an Op from one representation to
--   another.
class RephraseOp op
rephraseInOp :: (RephraseOp op, Monad m) => Rephraser m from to -> op from -> m (op to)
instance Futhark.IR.Rephrase.RephraseOp Futhark.IR.Rep.NoOp

-- | Inspecing and modifying Pats, function parameters and pattern
--   elements.
module Futhark.IR.Prop.Pat

-- | 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 => PatElem dec -> Ident

-- | The type of a name bound by a PatElem.
patElemType :: Typed dec => PatElem dec -> Type

-- | Set the rep of a PatElem.
setPatElemDec :: PatElem oldattr -> newattr -> PatElem newattr

-- | Return a list of the Idents bound by the Pat.
patIdents :: Typed dec => Pat dec -> [Ident]

-- | Return a list of the Names bound by the Pat.
patNames :: Pat dec -> [VName]

-- | Return a list of the typess bound by the pattern.
patTypes :: Typed dec => Pat dec -> [Type]

-- | Return the number of names bound by the pattern.
patSize :: Pat dec -> Int

-- | Create a pattern using Type as the attribute.
basicPat :: [Ident] -> Pat Type

-- | 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

-- | Retrieve the set of tags in the names set.
namesIntSet :: Names -> IntSet

-- | Does the set of names contain this name?
nameIn :: VName -> Names -> Bool

-- | Does the set of names not contain this name?
notNameIn :: 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 rep), FreeIn (LetDec rep), FreeIn (LParamInfo rep), FreeIn (FParamInfo rep), FreeDec (BodyDec rep), FreeIn (RetType rep), FreeIn (BranchType rep), FreeDec (ExpDec rep)) => Stms rep -> Result -> FV

-- | The names bound by the bindings immediately in a Body.
boundInBody :: Body rep -> Names

-- | The names bound by a binding.
boundByStm :: Stm rep -> Names

-- | The names bound by the bindings.
boundByStms :: Stms rep -> Names

-- | The names of the lambda parameters plus the index parameter.
boundByLambda :: Lambda rep -> [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.Show.Show Futhark.IR.Prop.Names.Names
instance GHC.Classes.Eq Futhark.IR.Prop.Names.Names
instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.ExpDec rep), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.BodyDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.FParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LetDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.RetType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.BranchType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.Op rep)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.FunDef rep)
instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.ExpDec rep), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.BodyDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.FParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LetDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.RetType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.BranchType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.Op rep)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Lambda rep)
instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.ExpDec rep), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.BodyDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.FParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LetDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.RetType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.BranchType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.Op rep)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Body rep)
instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.ExpDec rep), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.BodyDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.FParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LetDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.RetType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.BranchType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.Op rep)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Exp rep)
instance (Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.ExpDec rep), Futhark.IR.Prop.Names.FreeDec (Futhark.IR.Rep.BodyDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.FParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LParamInfo rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.LetDec rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.RetType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.BranchType rep), Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.Op rep)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Stm rep)
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 b, Futhark.IR.Prop.Names.FreeIn c, Futhark.IR.Prop.Names.FreeIn d) => Futhark.IR.Prop.Names.FreeIn (a, b, c, d)
instance (Futhark.IR.Prop.Names.FreeIn a, Futhark.IR.Prop.Names.FreeIn b) => Futhark.IR.Prop.Names.FreeIn (Data.Either.Either a b)
instance Futhark.IR.Prop.Names.FreeIn a => Futhark.IR.Prop.Names.FreeIn [a]
instance Futhark.IR.Prop.Names.FreeIn a => Futhark.IR.Prop.Names.FreeIn (Data.Set.Internal.Set a)
instance forall k (rep :: k). Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Rep.NoOp rep)
instance Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Stm rep) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Stms rep)
instance Futhark.IR.Prop.Names.FreeIn body => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Case body)
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 Language.Futhark.Primitive.PrimType
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.PatElem dec)
instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Syntax.LoopForm
instance Futhark.IR.Prop.Names.FreeIn d => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.DimIndex d)
instance Futhark.IR.Prop.Names.FreeIn d => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.Slice d)
instance Futhark.IR.Prop.Names.FreeIn d => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.FlatDimIndex d)
instance Futhark.IR.Prop.Names.FreeIn d => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Core.FlatSlice d)
instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Syntax.SubExpRes
instance Futhark.IR.Prop.Names.FreeIn dec => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Syntax.Pat dec)
instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Syntax.Core.Certs
instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Syntax.Core.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.MatchDec a)
instance GHC.Base.Monoid Futhark.IR.Prop.Names.FV
instance GHC.Base.Semigroup Futhark.IR.Prop.Names.FV
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 Prettyprinter.Internal.Pretty Futhark.IR.Prop.Names.Names

-- | 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 rep m, TypedOp (OpC rep)) => Exp rep -> m [ExtType]

-- | The type of a subexpression.
subExpType :: HasScope t m => SubExp -> m Type

-- | Type type of a SubExpRes - not that this might refer to names
--   bound in the body containing the result.
subExpResType :: HasScope t m => SubExpRes -> m Type

-- | The type of a primitive operation.
basicOpType :: HasScope rep 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 rep -> [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 rep m) => op rep -> m [ExtType]
instance Futhark.IR.Prop.TypeOf.TypedOp Futhark.IR.Rep.NoOp

-- | 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 :: Text -> [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 Half.
isF16 :: PrimExp v -> TPrimExp Half 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

-- | Conversion from Bool to TPrimExp
fromBool :: Bool -> 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

-- | Construct a numeric expression from a boolean expression. This can be
--   used to encode arithmetic control flow.
fromBoolExp :: NumExp t => TPrimExp Bool v -> TPrimExp t v

-- | The class of integer types that can be used for constructing
--   TPrimExps.
class (NumExp t) => IntExp t

-- | The type of an expression, known to be an integer type.
expIntType :: IntExp t => TPrimExp t v -> IntType

-- | 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 type of an expression, known to be a floating-point type.
expFloatType :: FloatExp t => TPrimExp t v -> FloatType

-- | 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.
(.&&.) :: Eq v => TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v
infixr 3 .&&.

-- | Lifted logical conjunction.
(.||.) :: Eq v => TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v
infixr 2 .||.

-- | Lifted relational operators; assuming signed numbers in case of
--   integers.
(.<.) :: Eq v => TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v
infix 4 .<.

-- | Lifted relational operators; assuming signed numbers in case of
--   integers.
(.<=.) :: Eq v => TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v
infix 4 .<=.

-- | Lifted relational operators; assuming signed numbers in case of
--   integers.
(.>.) :: Eq v => TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v
infix 4 .>.

-- | Lifted relational operators; assuming signed numbers in case of
--   integers.
(.>=.) :: Eq v => TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v
infix 4 .>=.

-- | Lifted relational operators; assuming signed numbers in case of
--   integers.
(.==.) :: Eq v => TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v
infix 4 .==.

-- | Lifted bitwise operators. The right-shift is logical, *not*
--   arithmetic.
(.&.) :: Eq v => TPrimExp t v -> TPrimExp t v -> TPrimExp t v

-- | Lifted bitwise operators. The right-shift is logical, *not*
--   arithmetic.
(.|.) :: Eq v => TPrimExp t v -> TPrimExp t v -> TPrimExp t v

-- | Lifted bitwise operators. The right-shift is logical, *not*
--   arithmetic.
(.^.) :: Eq v => TPrimExp t v -> TPrimExp t v -> TPrimExp t v

-- | Lifted bitwise operators. The right-shift is logical, *not*
--   arithmetic.
(.>>.) :: Eq v => TPrimExp t v -> TPrimExp t v -> TPrimExp t v

-- | Lifted bitwise operators. The right-shift is logical, *not*
--   arithmetic.
(.<<.) :: Eq v => 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

-- | Convert result of some integer expression to have the same type as
--   another, using sign extension.
sExtAs :: (IntExp to, IntExp from) => TPrimExp from v -> TPrimExp to v -> TPrimExp to v

-- | 16-bit float minimum.
fMin16 :: TPrimExp Half v -> TPrimExp Half v -> TPrimExp Half v

-- | 32-bit float minimum.
fMin32 :: TPrimExp Float v -> TPrimExp Float v -> TPrimExp Float v

-- | 64-bit float minimum.
fMin64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v

-- | 16-bit float maximum.
fMax16 :: TPrimExp Half v -> TPrimExp Half v -> TPrimExp Half v

-- | 32-bit float maximum.
fMax32 :: TPrimExp Float v -> TPrimExp Float v -> TPrimExp Float v

-- | 64-bit float maximum.
fMax64 :: TPrimExp Double v -> TPrimExp Double v -> TPrimExp Double v

-- | Conditional expression.
condExp :: TPrimExp Bool v -> TPrimExp t v -> TPrimExp t v -> TPrimExp t v

-- | Multiplication of untyped PrimExps, which must have the same
--   type. Uses OverflowWrap for integer operations.
(~*~) :: PrimExp v -> PrimExp v -> PrimExp v
infix 7 ~*~

-- | Division of untyped PrimExps, which must have the same type.
--   For integers, this is unsafe signed division.
(~/~) :: PrimExp v -> PrimExp v -> PrimExp v
infix 7 ~/~

-- | Addition of untyped PrimExps, which must have the same type.
--   Uses OverflowWrap for integer operations.
(~+~) :: PrimExp v -> PrimExp v -> PrimExp v
infix 6 ~+~

-- | Subtraction of untyped PrimExps, which must have the same type.
--   Uses OverflowWrap for integer operations.
(~-~) :: PrimExp v -> PrimExp v -> PrimExp v
infix 6 ~-~

-- | Equality of untyped PrimExps, which must have the same type.
(~==~) :: PrimExp v -> PrimExp v -> PrimExp v
infix 4 ~==~
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 forall k (t :: k) v. GHC.Show.Show v => GHC.Show.Show (Futhark.Analysis.PrimExp.TPrimExp t v)
instance forall k (t :: k) v. GHC.Classes.Ord v => GHC.Classes.Ord (Futhark.Analysis.PrimExp.TPrimExp t v)
instance forall k (t :: k) v. GHC.Classes.Eq v => GHC.Classes.Eq (Futhark.Analysis.PrimExp.TPrimExp t v)
instance Futhark.Analysis.PrimExp.FloatExp Numeric.Half.Internal.Half
instance Futhark.Analysis.PrimExp.FloatExp GHC.Types.Float
instance Futhark.Analysis.PrimExp.FloatExp GHC.Types.Double
instance forall k (t :: k) v. (Futhark.Analysis.PrimExp.FloatExp t, Prettyprinter.Internal.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 forall k (t :: k) v. (Futhark.Analysis.PrimExp.IntExp t, Prettyprinter.Internal.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 Numeric.Half.Internal.Half
instance Futhark.Analysis.PrimExp.NumExp GHC.Types.Float
instance Futhark.Analysis.PrimExp.NumExp GHC.Types.Double
instance forall k (t :: k) v. (Futhark.Analysis.PrimExp.NumExp t, Prettyprinter.Internal.Pretty v) => GHC.Num.Num (Futhark.Analysis.PrimExp.TPrimExp t v)
instance forall k (t :: k). GHC.Base.Functor (Futhark.Analysis.PrimExp.TPrimExp t)
instance forall k (t :: k). Data.Foldable.Foldable (Futhark.Analysis.PrimExp.TPrimExp t)
instance forall k (t :: k). Data.Traversable.Traversable (Futhark.Analysis.PrimExp.TPrimExp t)
instance forall k v (t :: k). Futhark.IR.Prop.Names.FreeIn v => Futhark.IR.Prop.Names.FreeIn (Futhark.Analysis.PrimExp.TPrimExp t v)
instance Prettyprinter.Internal.Pretty v => GHC.Float.Floating (Futhark.Analysis.PrimExp.TPrimExp Numeric.Half.Internal.Half v)
instance Prettyprinter.Internal.Pretty v => GHC.Float.Floating (Futhark.Analysis.PrimExp.TPrimExp GHC.Types.Float v)
instance Prettyprinter.Internal.Pretty v => GHC.Float.Floating (Futhark.Analysis.PrimExp.TPrimExp GHC.Types.Double v)
instance forall k v (t :: k). Prettyprinter.Internal.Pretty v => Prettyprinter.Internal.Pretty (Futhark.Analysis.PrimExp.TPrimExp t 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 Prettyprinter.Internal.Pretty v => Prettyprinter.Internal.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

-- | Representations in which all annotations support name substitution.
type Substitutable rep = (RepTypes rep, Substitute (ExpDec rep), Substitute (BodyDec rep), Substitute (LetDec rep), Substitute (FParamInfo rep), Substitute (LParamInfo rep), Substitute (RetType rep), Substitute (BranchType rep), Substitute (Op rep))
instance Futhark.Transform.Substitute.Substitutable rep => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Exp rep)
instance Futhark.Transform.Substitute.Substitutable rep => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Stm rep)
instance Futhark.Transform.Substitute.Substitutable rep => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Body rep)
instance Futhark.Transform.Substitute.Substitutable rep => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Lambda rep)
instance Futhark.Transform.Substitute.Substitutable rep => Futhark.Transform.Substitute.Substitute (Futhark.IR.Prop.Scope.NameInfo rep)
instance Futhark.Transform.Substitute.Substitute a => Futhark.Transform.Substitute.Substitute [a]
instance Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Stm rep) => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Stms rep)
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.PatElem dec)
instance Futhark.Transform.Substitute.Substitute Futhark.IR.Syntax.Core.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 Futhark.IR.Syntax.SubExpRes
instance Futhark.Transform.Substitute.Substitute dec => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Pat dec)
instance Futhark.Transform.Substitute.Substitute Futhark.IR.Syntax.Core.Certs
instance Futhark.Transform.Substitute.Substitute Futhark.IR.Syntax.Core.Rank
instance Futhark.Transform.Substitute.Substitute ()
instance forall k (rep :: k). Futhark.Transform.Substitute.Substitute (Futhark.IR.Rep.NoOp rep)
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 Language.Futhark.Primitive.PrimType
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.Core.DimIndex d)
instance Futhark.Transform.Substitute.Substitute d => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Core.Slice d)
instance Futhark.Transform.Substitute.Substitute d => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Core.FlatDimIndex d)
instance Futhark.Transform.Substitute.Substitute d => Futhark.Transform.Substitute.Substitute (Futhark.IR.Syntax.Core.FlatSlice d)
instance Futhark.Transform.Substitute.Substitute v => Futhark.Transform.Substitute.Substitute (Futhark.Analysis.PrimExp.PrimExp v)
instance forall k v (t :: k). 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

-- | 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 rep, MonadFreshNames m) => Prog rep -> m (Prog rep)

-- | 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 rep, MonadFreshNames m) => Exp rep -> m (Exp rep)

-- | 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 rep, MonadFreshNames m) => Stm rep -> m (Stm rep)

-- | 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 rep, MonadFreshNames m) => Body rep -> m (Body rep)

-- | 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 rep, MonadFreshNames m) => Lambda rep -> m (Lambda rep)

-- | Produce an equivalent pattern but with each pattern element given a
--   new name.
renamePat :: (Rename dec, MonadFreshNames m) => Pat dec -> m (Pat dec)

-- | Rename the bound variables in something (does not affect free
--   variables).
renameSomething :: (Rename a, MonadFreshNames m) => a -> m a

-- | Rename variables in binding position. The provided VNames are
--   associated with new, fresh names in the renaming environment.
renameBound :: [VName] -> RenameM a -> RenameM a

-- | Rename statements, then rename something within the scope of those
--   statements.
renameStmsWith :: (MonadFreshNames m, Renameable rep, Rename a) => Stms rep -> a -> m (Stms rep, 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 rep => Stms rep -> (Stms rep -> 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

-- | Representations in which all decorations are renameable.
type Renameable rep = (Rename (LetDec rep), Rename (ExpDec rep), Rename (BodyDec rep), Rename (FParamInfo rep), Rename (LParamInfo rep), Rename (RetType rep), Rename (BranchType rep), Rename (Op rep))
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 rep => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.FunDef rep)
instance Futhark.Transform.Rename.Renameable rep => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Body rep)
instance Futhark.Transform.Rename.Renameable rep => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Stm rep)
instance Futhark.Transform.Rename.Renameable rep => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Exp rep)
instance Futhark.Transform.Rename.Renameable rep => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Lambda rep)
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.Pat dec)
instance Futhark.Transform.Rename.Rename dec => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.Core.PatElem dec)
instance Futhark.Transform.Rename.Rename Futhark.IR.Syntax.Core.Certs
instance Futhark.Transform.Rename.Rename Futhark.IR.Syntax.Core.Attrs
instance Futhark.Transform.Rename.Rename dec => Futhark.Transform.Rename.Rename (Futhark.IR.Syntax.StmAux dec)
instance Futhark.Transform.Rename.Rename Futhark.IR.Syntax.SubExpRes
instance Futhark.Transform.Rename.Rename Language.Futhark.Primitive.PrimType
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 forall k (rep :: k). Futhark.Transform.Rename.Rename (Futhark.IR.Rep.NoOp rep)
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.IR.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 rep -> 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 :: ASTRep rep => Exp rep -> 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

-- | 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 rep -> Bool

-- | A StmAux with empty Certs.
defAux :: dec -> StmAux dec

-- | The certificates associated with a statement.
stmCerts :: Stm rep -> Certs

-- | Add certificates to a statement.
certify :: Certs -> Stm rep -> Stm rep

-- | Construct the type of an expression that would match the pattern.
expExtTypesFromPat :: Typed dec => Pat dec -> [ExtType]

-- | Keep only those attributes that are relevant for Assert
--   expressions.
attrsForAssert :: Attrs -> Attrs

-- | Horizontally fission a lambda that models a binary operator.
lamIsBinOp :: ASTRep rep => Lambda rep -> Maybe [(BinOp, PrimType, VName, VName)]

-- | A handy shorthand for properties that we usually want for things we
--   stuff into ASTs.
type ASTConstraints a = (Eq a, Ord a, Show a, Rename a, Substitute a, FreeIn a, Pretty a)

-- | A type class for operations.
class (TypedOp op) => IsOp op

-- | Like safeExp, but for arbitrary ops.
safeOp :: (IsOp op, ASTRep rep) => op rep -> Bool

-- | Should we try to hoist this out of branches?
cheapOp :: (IsOp op, ASTRep rep) => op rep -> Bool

-- | Compute the data dependencies of an operation.
opDependencies :: (IsOp op, ASTRep rep) => op rep -> [Names]

-- | Representation-specific attributes; also means the rep supports some
--   basic facilities.
class (RepTypes rep, PrettyRep rep, Renameable rep, Substitutable rep, FreeDec (ExpDec rep), FreeIn (LetDec rep), FreeDec (BodyDec rep), FreeIn (FParamInfo rep), FreeIn (LParamInfo rep), FreeIn (RetType rep), FreeIn (BranchType rep), ASTConstraints (OpC rep rep), IsOp (OpC rep), RephraseOp (OpC rep)) => ASTRep rep

-- | Given a pattern, construct the type of a body that would match it. An
--   implementation for many representations would be
--   expExtTypesFromPat.
expTypesFromPat :: (ASTRep rep, HasScope rep m, Monad m) => Pat (LetDec rep) -> m [BranchType rep]
instance Futhark.IR.Prop.IsOp Futhark.IR.Rep.NoOp

-- | 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 aliases of a subexpression.
subExpAliases :: SubExp -> Names

-- | The aliases of an expression, one for each pattern element.
--   
--   The pattern is important because some aliasing might be through
--   variables that are no longer in scope (consider the aliases for a body
--   that returns the same value multiple times).
expAliases :: Aliased rep => [PatElem dec] -> Exp rep -> [Names]

-- | The aliases of each pattern element.
patAliases :: AliasesOf dec => Pat dec -> [Names]

-- | Also includes the name itself.
lookupAliases :: AliasesOf (LetDec rep) => VName -> Scope rep -> Names

-- | The class of representations that contain aliasing information.
class (ASTRep rep, AliasedOp (OpC rep), AliasesOf (LetDec rep)) => Aliased rep

-- | The aliases of the body results. Note that this includes names bound
--   in the body!
bodyAliases :: Aliased rep => Body rep -> [Names]

-- | The variables consumed in the body.
consumedInBody :: Aliased rep => Body rep -> 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 rep => Stm rep -> Names

-- | The variables consumed in this expression.
consumedInExp :: Aliased rep => Exp rep -> Names

-- | The variables consumed by this lambda.
consumedByLambda :: Aliased rep => Lambda rep -> Names

-- | Pre-existing aliases for variables. Used to add transitive aliases.
type AliasTable = Map VName Names

-- | The class of operations that can produce aliasing and consumption
--   information.
class (IsOp op) => AliasedOp op
opAliases :: (AliasedOp op, Aliased rep) => op rep -> [Names]
consumedInOp :: (AliasedOp op, Aliased rep) => op rep -> Names
instance Futhark.IR.Prop.Aliases.AliasedOp Futhark.IR.Rep.NoOp
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.PatElem dec)

-- | A convenient re-export of basic AST modules.
module Futhark.IR

-- | Definition of a polymorphic (generic) pass that can work with programs
--   of any rep.
module Futhark.Pass

-- | The monad in which passes execute.
data PassM a

-- | Execute a PassM action, yielding logging information and either
--   an error pretty or a result.
runPassM :: MonadFreshNames m => PassM a -> m (a, Log)

-- | A compiler pass transforming a Prog of a given rep to a
--   Prog of another rep.
data Pass fromrep torep
Pass :: String -> String -> (Prog fromrep -> PassM (Prog torep)) -> Pass fromrep torep

-- | 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 fromrep torep -> String

-- | A slightly longer description, which will show up in the command-line
--   --help option.
[passDescription] :: Pass fromrep torep -> String
[passFunction] :: Pass fromrep torep -> Prog fromrep -> PassM (Prog torep)

-- | Take the name of the pass, turn spaces into dashes, and make all
--   characters lowercase.
passLongOption :: Pass fromrep torep -> 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 rep -> Stms rep -> PassM (Stms rep)) -> Prog rep -> PassM (Prog rep)

-- | Apply some operation to the top-level constants. Then applies an
--   operation to all the 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 fromrep -> PassM (Stms torep)) -> (Stms torep -> FunDef fromrep -> PassM (FunDef torep)) -> Prog fromrep -> PassM (Prog torep)
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.Builder.Class

-- | The class of representations 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
--   MonadBuilder instance, it is acceptable for them to create new
--   bindings, however.
class (ASTRep rep, FParamInfo rep ~ DeclType, LParamInfo rep ~ Type, RetType rep ~ DeclExtType, BranchType rep ~ ExtType) => Buildable rep
mkExpPat :: Buildable rep => [Ident] -> Exp rep -> Pat (LetDec rep)
mkExpDec :: Buildable rep => Pat (LetDec rep) -> Exp rep -> ExpDec rep
mkBody :: Buildable rep => Stms rep -> Result -> Body rep
mkLetNames :: (Buildable rep, MonadFreshNames m, HasScope rep m) => [VName] -> Exp rep -> m (Stm rep)

-- | Construct a Stm from identifiers for the context- and value
--   part of the pattern, as well as the expression.
mkLet :: Buildable rep => [Ident] -> Exp rep -> Stm rep

-- | Like mkLet, but also take attributes and certificates from the given
--   StmAux.
mkLet' :: Buildable rep => [Ident] -> StmAux a -> Exp rep -> Stm rep

-- | A monad that supports the creation of bindings from expressions and
--   bodies from bindings, with a specific rep. 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 (ASTRep (Rep m), MonadFreshNames m, Applicative m, Monad m, LocalScope (Rep m) m) => MonadBuilder m where {
    type Rep m :: Type;
}
mkExpDecM :: MonadBuilder m => Pat (LetDec (Rep m)) -> Exp (Rep m) -> m (ExpDec (Rep m))
mkBodyM :: MonadBuilder m => Stms (Rep m) -> Result -> m (Body (Rep m))
mkLetNamesM :: MonadBuilder m => [VName] -> Exp (Rep m) -> m (Stm (Rep m))

-- | Add a statement to the Stms under construction.
addStm :: MonadBuilder m => Stm (Rep m) -> m ()

-- | Add multiple statements to the Stms under construction.
addStms :: MonadBuilder m => Stms (Rep m) -> m ()

-- | Obtain the statements constructed during a monadic action, instead of
--   adding them to the state.
collectStms :: MonadBuilder m => m a -> m (a, Stms (Rep m))

-- | Add the provided certificates to any statements added during execution
--   of the action.
certifying :: MonadBuilder m => Certs -> m a -> m a

-- | Add several bindings at the outermost level of a Body.
insertStms :: Buildable rep => Stms rep -> Body rep -> Body rep

-- | Add a single binding at the outermost level of a Body.
insertStm :: Buildable rep => Stm rep -> Body rep -> Body rep

-- | Add a statement with the given pattern and expression.
letBind :: MonadBuilder m => Pat (LetDec (Rep m)) -> Exp (Rep m) -> m ()

-- | Add a statement with the given pattern element names and expression.
letBindNames :: MonadBuilder m => [VName] -> Exp (Rep m) -> m ()

-- | As collectStms, but throw away the ordinary result.
collectStms_ :: MonadBuilder m => m a -> m (Stms (Rep m))

-- | Add the statements of the body, then return the body result.
bodyBind :: MonadBuilder m => Body (Rep m) -> m Result

-- | Add the given attributes to any statements added by this action.
attributing :: MonadBuilder m => Attrs -> m a -> m a

-- | Add the certificates and attributes to any statements added by this
--   action.
auxing :: MonadBuilder m => StmAux anyrep -> m a -> m a

-- | This module defines a convenience monad/typeclass for building ASTs.
--   The fundamental building block is BuilderT and its execution
--   functions, but it is usually easier to use Builder.
--   
--   See Futhark.Construct for a high-level description.
module Futhark.Builder

-- | A monad transformer that tracks statements and provides a
--   MonadBuilder 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 MonadBuilder
--   from scratch, then it is likely that you are making a mistake.
data BuilderT rep m a

-- | Run a builder action given an initial scope, returning a value and the
--   statements added (addStm) during the action.
runBuilderT :: MonadFreshNames m => BuilderT rep m a -> Scope rep -> m (a, Stms rep)

-- | Like runBuilderT, but return only the statements.
runBuilderT_ :: MonadFreshNames m => BuilderT rep m () -> Scope rep -> m (Stms rep)

-- | Like runBuilderT, but get the initial scope from the current
--   monad.
runBuilderT' :: (MonadFreshNames m, HasScope somerep m, SameScope somerep rep) => BuilderT rep m a -> m (a, Stms rep)

-- | Like runBuilderT_, but get the initial scope from the current
--   monad.
runBuilderT'_ :: (MonadFreshNames m, HasScope somerep m, SameScope somerep rep) => BuilderT rep m a -> m (Stms rep)

-- | A BuilderT (and by extension, a Builder) is only an
--   instance of MonadBuilder for representations that implement
--   this type class, which contains methods for constructing statements.
class (ASTRep rep) => BuilderOps rep
mkExpDecB :: (BuilderOps rep, MonadBuilder m, Rep m ~ rep) => Pat (LetDec rep) -> Exp rep -> m (ExpDec rep)
mkBodyB :: (BuilderOps rep, MonadBuilder m, Rep m ~ rep) => Stms rep -> Result -> m (Body rep)
mkLetNamesB :: (BuilderOps rep, MonadBuilder m, Rep m ~ rep) => [VName] -> Exp rep -> m (Stm rep)
mkExpDecB :: (BuilderOps rep, MonadBuilder m, Buildable rep) => Pat (LetDec rep) -> Exp rep -> m (ExpDec rep)
mkBodyB :: (BuilderOps rep, MonadBuilder m, Buildable rep) => Stms rep -> Result -> m (Body rep)
mkLetNamesB :: (BuilderOps rep, MonadBuilder m, Rep m ~ rep, Buildable rep) => [VName] -> Exp rep -> m (Stm rep)

-- | The most commonly used builder monad.
type Builder rep = BuilderT rep (State VNameSource)

-- | Run a builder action, returning a value and the statements added
--   (addStm) during the action. Assumes that the current monad
--   provides initial scope and name source.
runBuilder :: (MonadFreshNames m, HasScope somerep m, SameScope somerep rep) => Builder rep a -> m (a, Stms rep)

-- | Like runBuilder, but throw away the result and just return the
--   added statements.
runBuilder_ :: (MonadFreshNames m, HasScope somerep m, SameScope somerep rep) => Builder rep a -> m (Stms rep)

-- | Run a builder that produces a Result and construct a body that
--   contains that result alongside the statements produced during the
--   builder.
runBodyBuilder :: (Buildable rep, MonadFreshNames m, HasScope somerep m, SameScope somerep rep) => Builder rep Result -> m (Body rep)

-- | Given lambda parameters, Run a builder action that produces the
--   statements and returns the Result of the lambda body.
runLambdaBuilder :: (Buildable rep, MonadFreshNames m, HasScope somerep m, SameScope somerep rep) => [LParam rep] -> Builder rep Result -> m (Lambda rep)
instance GHC.Base.Monad m => GHC.Base.Applicative (Futhark.Builder.BuilderT rep m)
instance GHC.Base.Monad m => GHC.Base.Monad (Futhark.Builder.BuilderT rep m)
instance GHC.Base.Functor m => GHC.Base.Functor (Futhark.Builder.BuilderT rep m)
instance Control.Monad.Trans.Class.MonadTrans (Futhark.Builder.BuilderT rep)
instance Futhark.MonadFreshNames.MonadFreshNames m => Futhark.MonadFreshNames.MonadFreshNames (Futhark.Builder.BuilderT rep m)
instance (Futhark.IR.Prop.ASTRep rep, GHC.Base.Monad m) => Futhark.IR.Prop.Scope.HasScope rep (Futhark.Builder.BuilderT rep m)
instance (Futhark.IR.Prop.ASTRep rep, GHC.Base.Monad m) => Futhark.IR.Prop.Scope.LocalScope rep (Futhark.Builder.BuilderT rep m)
instance (Futhark.MonadFreshNames.MonadFreshNames m, Futhark.Builder.BuilderOps rep) => Futhark.Builder.Class.MonadBuilder (Futhark.Builder.BuilderT rep m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Futhark.Builder.BuilderT rep m)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Futhark.Builder.BuilderT rep m)
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Futhark.Builder.BuilderT rep m)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Futhark.Builder.BuilderT rep m)

-- | 
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
--   MonadBuilder 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.
--   
--   
MonadBuilder
--   
--   A monad that implements MonadBuilder tracks the statements
--   added so far, the current names in scope, and allows you to add
--   additional statements with addStm. Any monad that implements
--   MonadBuilder also implements the Rep type family, which
--   indicates which rep it works with. Inside a MonadBuilder we can
--   use collectStms to gather up the Stms added with
--   addStm in some nested computation.
--   
--   The BuilderT monad (and its convenient Builder version)
--   provides the simplest implementation of MonadBuilder.
--   
--   
Higher-level building blocks
--   
--   On top of the raw facilities provided by MonadBuilder, 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)
--   
--   
--   
Monadic expression builders
--   
--   This module also contains "monadic expression" functions that let us
--   build nested expressions in a "direct" style, rather than using
--   letExp and friends to bind every sub-part first. See functions
--   such as eIf and eBody for example. See also
--   Futhark.Analysis.PrimExp and the ToExp type class.
--   
--   
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 desc e binds the expression e, which must
--   produce a single value. Returns a SubExp corresponding to the
--   resulting value. For expressions that produce multiple values, see
--   letTupExp.
letSubExp :: MonadBuilder m => String -> Exp (Rep m) -> m SubExp

-- | Like letSubExp, but returns a name rather than a SubExp.
letExp :: MonadBuilder m => String -> Exp (Rep m) -> m VName

-- | Like letExp, but the expression may return multiple values.
letTupExp :: MonadBuilder m => String -> Exp (Rep m) -> m [VName]

-- | Like letTupExp, but returns SubExps instead of
--   VNames.
letTupExp' :: MonadBuilder m => String -> Exp (Rep m) -> m [SubExp]

-- | Like letExp, but the VName and Slice denote an
--   array that is Updated with the result of the expression. The
--   name of the updated array is returned.
letInPlace :: MonadBuilder m => String -> VName -> Slice SubExp -> Exp (Rep m) -> m VName

-- | Turn a subexpression into a monad expression. Does not actually lead
--   to any code generation. This is supposed to be used alongside the
--   other monadic expression functions, such as eIf.
eSubExp :: MonadBuilder m => SubExp -> m (Exp (Rep m))

-- | Treat a parameter as a monadic expression.
eParam :: MonadBuilder m => Param t -> m (Exp (Rep m))

-- | As eMatch, but an MatchSort can be given.
eMatch' :: (MonadBuilder m, BranchType (Rep m) ~ ExtType) => [SubExp] -> [Case (m (Body (Rep m)))] -> m (Body (Rep m)) -> MatchSort -> m (Exp (Rep m))

-- | Construct a Match expression. The main convenience here is that
--   the existential context of the return type is automatically deduced,
--   and the necessary elements added to the branches.
eMatch :: (MonadBuilder m, BranchType (Rep m) ~ ExtType) => [SubExp] -> [Case (m (Body (Rep m)))] -> m (Body (Rep m)) -> m (Exp (Rep m))

-- | Construct a Match modelling an if-expression from a monadic
--   condition and monadic branches. eBody might be convenient for
--   constructing the branches.
eIf :: (MonadBuilder m, BranchType (Rep m) ~ ExtType) => m (Exp (Rep m)) -> m (Body (Rep m)) -> m (Body (Rep m)) -> m (Exp (Rep m))

-- | As eIf, but an MatchSort can be given.
eIf' :: (MonadBuilder m, BranchType (Rep m) ~ ExtType) => m (Exp (Rep m)) -> m (Body (Rep m)) -> m (Body (Rep m)) -> MatchSort -> m (Exp (Rep m))

-- | Construct a BinOp expression with the given operator.
eBinOp :: MonadBuilder m => BinOp -> m (Exp (Rep m)) -> m (Exp (Rep m)) -> m (Exp (Rep m))

-- | Construct a UnOp expression with the given operator.
eUnOp :: MonadBuilder m => UnOp -> m (Exp (Rep m)) -> m (Exp (Rep m))

-- | Construct a CmpOp expression with the given comparison.
eCmpOp :: MonadBuilder m => CmpOp -> m (Exp (Rep m)) -> m (Exp (Rep m)) -> m (Exp (Rep m))

-- | Construct a ConvOp expression with the given conversion.
eConvOp :: MonadBuilder m => ConvOp -> m (Exp (Rep m)) -> m (Exp (Rep m))

-- | Construct a SSignum expression. Fails if the provided
--   expression is not of integer type.
eSignum :: MonadBuilder m => m (Exp (Rep m)) -> m (Exp (Rep m))

-- | Copy a value.
eCopy :: MonadBuilder m => m (Exp (Rep m)) -> m (Exp (Rep m))

-- | Construct a body from expressions. If multiple expressions are
--   provided, their results will be concatenated in order and returned as
--   the result.
--   
--   Beware: this will not produce correct code if the type of the
--   body would be existential. That is, the type of the results being
--   returned should be invariant to the body.
eBody :: MonadBuilder m => [m (Exp (Rep m))] -> m (Body (Rep m))

-- | Bind each lambda parameter to the result of an expression, then bind
--   the body of the lambda. The expressions must produce only a single
--   value each.
eLambda :: MonadBuilder m => Lambda (Rep m) -> [m (Exp (Rep m))] -> m [SubExpRes]

-- | Construct an unspecified value of the given type.
eBlank :: MonadBuilder m => Type -> m (Exp (Rep m))

-- | True if all operands are true.
eAll :: MonadBuilder m => [SubExp] -> m (Exp (Rep m))

-- | True if any operand is true.
eAny :: MonadBuilder m => [SubExp] -> m (Exp (Rep m))

-- | eInBoundsForDim w i produces 0 <= i < w.
eDimInBounds :: MonadBuilder m => m (Exp (Rep m)) -> m (Exp (Rep m)) -> m (Exp (Rep m))

-- | Are these indexes out-of-bounds for the array?
eOutOfBounds :: MonadBuilder m => VName -> [m (Exp (Rep m))] -> m (Exp (Rep m))

-- | The array element at this index. Returns array unmodified if indexes
--   are null (does not even need to be an array in that case).
eIndex :: MonadBuilder m => VName -> [m (Exp (Rep m))] -> m (Exp (Rep m))

-- | The last element of the given array.
eLast :: MonadBuilder m => VName -> m (Exp (Rep m))

-- | Zero-extend to the given integer type.
asIntZ :: MonadBuilder m => IntType -> SubExp -> m SubExp

-- | Sign-extend to the given integer type.
asIntS :: MonadBuilder m => IntType -> SubExp -> m SubExp

-- | Conveniently construct a body that contains no bindings.
resultBody :: Buildable rep => [SubExp] -> Body rep

-- | Conveniently construct a body that contains no bindings - but this
--   time, monadically!
resultBodyM :: MonadBuilder m => [SubExp] -> m (Body (Rep m))

-- | Evaluate the action, producing a body, then wrap it in all the
--   bindings it created using addStm.
insertStmsM :: MonadBuilder m => m (Body (Rep m)) -> m (Body (Rep m))

-- | Evaluate an action that produces a Result and an auxiliary
--   value, then return the body constructed from the Result and any
--   statements added during the action, along the auxiliary value.
buildBody :: MonadBuilder m => m (Result, a) -> m (Body (Rep m), a)

-- | As buildBody, but there is no auxiliary value.
buildBody_ :: MonadBuilder m => m Result -> m (Body (Rep m))

-- | Change that result where evaluation of the body would stop. Also
--   change type annotations at branches.
mapResult :: Buildable rep => (Result -> Body rep) -> Body rep -> Body rep

-- | Apply a binary operator to several subexpressions. A left-fold.
foldBinOp :: MonadBuilder m => BinOp -> SubExp -> [SubExp] -> m (Exp (Rep 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 :: (MonadBuilder m, Buildable (Rep m)) => BinOp -> PrimType -> m (Lambda (Rep m))

-- | As binOpLambda, but for CmpOps.
cmpOpLambda :: (MonadBuilder m, Buildable (Rep m)) => CmpOp -> m (Lambda (Rep m))

-- | Easily construct a Lambda within a MonadBuilder. See
--   also runLambdaBuilder.
mkLambda :: MonadBuilder m => [LParam (Rep m)] -> m Result -> m (Lambda (Rep 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

-- | 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, State).
instantiateShapes :: Monad m => (Int -> m SubExp) -> [TypeBase ExtShape u] -> m [TypeBase Shape u]

-- | Like instantiateShapes, but obtains names from the provided
--   list. If an Ext is out of bounds of this list, the function
--   fails with error.
instantiateShapes' :: [VName] -> [TypeBase ExtShape u] -> [TypeBase Shape u]

-- | Remove existentials by imposing sizes from another type where needed.
removeExistentials :: ExtType -> Type -> Type

-- | Can be used as the definition of mkLetNames for a
--   Buildable instance for simple representations.
simpleMkLetNames :: (ExpDec rep ~ (), LetDec rep ~ Type, MonadFreshNames m, TypedOp (OpC rep), HasScope rep m) => [VName] -> Exp rep -> m (Stm rep)

-- | Instances of this class can be converted to Futhark expressions within
--   a MonadBuilder.
class ToExp a
toExp :: (ToExp a, MonadBuilder m) => a -> m (Exp (Rep m))

-- | A convenient composition of letSubExp and toExp.
toSubExp :: (MonadBuilder m, ToExp a) => String -> a -> m SubExp
instance Futhark.Construct.ToExp Futhark.IR.Syntax.Core.SubExp
instance Futhark.Construct.ToExp Language.Futhark.Core.VName

-- | 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

-- | x - y, but for Usages.
withoutU :: Usages -> Usages -> Usages

-- | A description of how a single variable has been used.
data Usages

-- | A kind of usage.
consumedU :: Usages

-- | A kind of usage.
presentU :: Usages

-- | Produce a usage table reflecting the use of the free variables in a
--   single statement.
usageInStm :: Aliased rep => Stm rep -> UsageTable

-- | Usage table reflecting use in pattern. In particular, free variables
--   in the decorations are considered used as sizes, even if they are also
--   bound in this pattern.
usageInPat :: FreeIn t => Pat t -> 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

-- | 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 rep) => Prog rep -> 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 rep) => Stm rep -> MetricsM ()

-- | Compute metrics for this lambda.
lambdaMetrics :: OpMetrics (Op rep) => Lambda rep -> MetricsM ()

-- | Compute metrics for this body.
bodyMetrics :: OpMetrics (Op rep) => Body rep -> 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 forall k (rep :: k). Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Rep.NoOp rep)
instance GHC.Base.Semigroup Futhark.Analysis.Metrics.CountMetrics
instance GHC.Base.Monoid Futhark.Analysis.Metrics.CountMetrics

-- | 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 :: ASTRep rep => Body rep -> Dependencies
depsOf :: Dependencies -> SubExp -> Names
depsOf' :: SubExp -> Names
depsOfArrays :: SubExp -> [VName] -> [Names]
depsOfShape :: Shape -> Names

-- | Determine the variables on which the results of applying anonymous
--   function lam to inputs depend.
lambdaDependencies :: ASTRep rep => Dependencies -> Lambda rep -> [Names] -> [Names]

-- | Like lambdaDependencies, but lam is a binary operation
--   with a neutral element.
reductionDependencies :: ASTRep rep => Dependencies -> Lambda rep -> [SubExp] -> [Names] -> [Names]

-- | 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

-- | In the context of this module, a "size" is any kind of tunable
--   (run-time) constant.
module Futhark.IR.GPU.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
SizeThreadBlock :: SizeClass

-- | The number of thread blocks.
SizeGrid :: SizeClass
SizeTile :: SizeClass
SizeRegTile :: SizeClass

-- | Likely not useful on its own, but querying the maximum can be handy.
SizeSharedMemory :: SizeClass

-- | A bespoke size with a default.
SizeBespoke :: Name -> Int64 -> SizeClass

-- | Amount of registers available per threadblock. Mostly meaningful for
--   querying the maximum.
SizeRegisters :: SizeClass

-- | Amount of L2 cache memory, in bytes. Mostly meaningful for querying
--   the maximum.
SizeCache :: 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 blocks of some kernel.
data NumBlocks

-- | Phantom type for the block size of some kernel.
data BlockSize

-- | Phantom type for number of threads.
data NumThreads
instance GHC.Show.Show Futhark.IR.GPU.Sizes.SizeClass
instance GHC.Classes.Ord Futhark.IR.GPU.Sizes.SizeClass
instance GHC.Classes.Eq Futhark.IR.GPU.Sizes.SizeClass
instance forall k (u :: k) e. Futhark.Transform.Substitute.Substitute e => Futhark.Transform.Substitute.Substitute (Futhark.IR.GPU.Sizes.Count u e)
instance forall k (u :: k) e. Prettyprinter.Internal.Pretty e => Prettyprinter.Internal.Pretty (Futhark.IR.GPU.Sizes.Count u e)
instance forall k (u :: k) e. Futhark.IR.Prop.Names.FreeIn e => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.GPU.Sizes.Count u e)
instance forall k (u :: k) e. Futhark.Util.IntegralExp.IntegralExp e => Futhark.Util.IntegralExp.IntegralExp (Futhark.IR.GPU.Sizes.Count u e)
instance forall k (u :: k) e. GHC.Num.Num e => GHC.Num.Num (Futhark.IR.GPU.Sizes.Count u e)
instance forall k (u :: k) e. GHC.Show.Show e => GHC.Show.Show (Futhark.IR.GPU.Sizes.Count u e)
instance forall k (u :: k) e. GHC.Classes.Ord e => GHC.Classes.Ord (Futhark.IR.GPU.Sizes.Count u e)
instance forall k (u :: k) e. GHC.Classes.Eq e => GHC.Classes.Eq (Futhark.IR.GPU.Sizes.Count u e)
instance forall k (u :: k). GHC.Base.Functor (Futhark.IR.GPU.Sizes.Count u)
instance forall k (u :: k). Data.Foldable.Foldable (Futhark.IR.GPU.Sizes.Count u)
instance forall k (u :: k). Data.Traversable.Traversable (Futhark.IR.GPU.Sizes.Count u)
instance Prettyprinter.Internal.Pretty Futhark.IR.GPU.Sizes.SizeClass

-- | A representation where all patterns are annotated with aliasing
--   information. It also records consumption of variables in bodies.
--   
--   Note that this module is mostly not concerned with actually
--   computing the aliasing information; only with shuffling it
--   around and providing some basic building blocks. See modules such as
--   Futhark.Analysis.Alias for computing the aliases in the first
--   place.
module Futhark.IR.Aliases

-- | The rep for the basic representation.
data Aliases (rep :: Type)

-- | 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)

-- | Augment a body decoration with aliasing information provided by the
--   statements and result of that body.
mkAliasedBody :: (ASTRep rep, AliasedOp (OpC rep), ASTConstraints (OpC rep (Aliases rep))) => BodyDec rep -> Stms (Aliases rep) -> Result -> Body (Aliases rep)

-- | Augment a pattern with aliasing information provided by the expression
--   the pattern is bound to.
mkAliasedPat :: (Aliased rep, Typed dec) => Pat dec -> Exp rep -> Pat (VarAliases, dec)

-- | Given statements (with aliasing information) and a body result,
--   produce aliasing information for the corresponding body as a whole.
--   The aliasing includes names bound in the body, i.e. which are not in
--   scope outside of it. Note that this does *not* include aliases of
--   results that are not bound in the statements!
mkBodyAliasing :: Aliased rep => Stms rep -> Result -> BodyAliasing

-- | 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 "rep adapters".
class CanBeAliased op

-- | Add aliases to this op.
addOpAliases :: (CanBeAliased op, AliasableRep rep) => AliasTable -> op rep -> op (Aliases rep)

-- | What we require of an aliasable representation.
type AliasableRep rep = (ASTRep rep, RephraseOp (OpC rep), CanBeAliased (OpC rep), AliasedOp (OpC rep), ASTConstraints (OpC rep (Aliases rep)))

-- | Remove alias information from a program.
removeProgAliases :: RephraseOp (OpC rep) => Prog (Aliases rep) -> Prog rep

-- | Remove alias information from a function.
removeFunDefAliases :: RephraseOp (OpC rep) => FunDef (Aliases rep) -> FunDef rep

-- | Remove alias information from an expression.
removeExpAliases :: RephraseOp (OpC rep) => Exp (Aliases rep) -> Exp rep

-- | Remove alias information from statements.
removeStmAliases :: RephraseOp (OpC rep) => Stm (Aliases rep) -> Stm rep

-- | Remove alias information from body.
removeBodyAliases :: RephraseOp (OpC rep) => Body (Aliases rep) -> Body rep

-- | Remove alias information from lambda.
removeLambdaAliases :: RephraseOp (OpC rep) => Lambda (Aliases rep) -> Lambda rep

-- | Remove alias information from pattern.
removePatAliases :: Pat (AliasDec, a) -> Pat a

-- | Remove alias information from an aliased scope.
removeScopeAliases :: Scope (Aliases rep) -> Scope rep

-- | A tuple of a mapping from variable names to their aliases, and the
--   names of consumed variables.
type AliasesAndConsumed = (Map VName Names, Names)

-- | A helper function for computing the aliases of a sequence of
--   statements. You'd use this while recursing down the statements from
--   first to last. The AliasesAndConsumed parameter is the current
--   "state" of aliasing, and the function then returns a new state. The
--   main thing this function provides is proper handling of transitivity
--   and "reverse" aliases.
trackAliases :: Aliased rep => AliasesAndConsumed -> Stm rep -> AliasesAndConsumed

-- | The aliases of the result and everything consumed in the given
--   statements.
mkStmsAliases :: Aliased rep => Stms rep -> Result -> ([Names], Names)

-- | The variables consumed in these statements.
consumedInStms :: Aliased rep => Stms rep -> Names
instance GHC.Show.Show Futhark.IR.Aliases.AliasDec
instance Futhark.IR.Aliases.CanBeAliased Futhark.IR.Rep.NoOp
instance (Futhark.IR.Rep.RepTypes rep, Futhark.IR.Prop.ASTConstraints (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep))) => Futhark.IR.Rep.RepTypes (Futhark.IR.Aliases.Aliases rep)
instance Futhark.IR.Prop.Aliases.AliasesOf (Futhark.IR.Aliases.VarAliases, dec)
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 Prettyprinter.Internal.Pretty Futhark.IR.Aliases.AliasDec
instance Futhark.IR.Prop.Names.FreeDec Futhark.IR.Aliases.AliasDec
instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Rep.OpC rep), Futhark.IR.Prop.ASTConstraints (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep))) => Futhark.IR.Prop.Aliases.Aliased (Futhark.IR.Aliases.Aliases rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Rep.OpC rep), Futhark.IR.Prop.ASTConstraints (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep))) => Futhark.IR.Pretty.PrettyRep (Futhark.IR.Aliases.Aliases rep)
instance (Futhark.Builder.Class.Buildable rep, Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Rep.OpC rep), Futhark.IR.Prop.ASTConstraints (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep))) => Futhark.Builder.Class.Buildable (Futhark.IR.Aliases.Aliases rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Rep.OpC rep), Futhark.IR.Prop.ASTConstraints (Futhark.IR.Rep.OpC rep (Futhark.IR.Aliases.Aliases rep))) => Futhark.IR.Prop.ASTRep (Futhark.IR.Aliases.Aliases rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.Rep.OpC rep), Futhark.Builder.Class.Buildable (Futhark.IR.Aliases.Aliases rep)) => Futhark.Builder.BuilderOps (Futhark.IR.Aliases.Aliases rep)

-- | Representation used by the simplification engine. It contains aliasing
--   information and a bit of caching for various information that is
--   looked up frequently. The name is an old relic; feel free to suggest a
--   better one.
module Futhark.Optimise.Simplify.Rep

-- | Representative phantom type for the simplifier representation.
data Wise rep

-- | The information associated with a let-bound variable.
newtype VarWisdom
VarWisdom :: VarAliases -> VarWisdom
[varWisdomAliases] :: VarWisdom -> VarAliases

-- | Simplifier information about an expression.
data ExpWisdom

-- | Remove simplifier information from statement.
removeStmWisdom :: RephraseOp (OpC rep) => Stm (Wise rep) -> Stm rep

-- | Remove simplifier information from lambda.
removeLambdaWisdom :: RephraseOp (OpC rep) => Lambda (Wise rep) -> Lambda rep

-- | Remove simplifier information from function.
removeFunDefWisdom :: RephraseOp (OpC rep) => FunDef (Wise rep) -> FunDef rep

-- | Remove simplifier information from expression.
removeExpWisdom :: RephraseOp (OpC rep) => Exp (Wise rep) -> Exp rep

-- | Remove simplifier information from pattern.
removePatWisdom :: Pat (VarWisdom, a) -> Pat a

-- | Remove simplifier information from body.
removeBodyWisdom :: RephraseOp (OpC rep) => Body (Wise rep) -> Body rep

-- | Remove simplifier information from scope.
removeScopeWisdom :: Scope (Wise rep) -> Scope rep

-- | Add simplifier information to scope. All the aliasing information will
--   be vacuous, however.
addScopeWisdom :: Scope rep -> Scope (Wise rep)

-- | Add simplifier information to pattern.
addWisdomToPat :: Informing rep => Pat (LetDec rep) -> Exp (Wise rep) -> Pat (LetDec (Wise rep))

-- | Produce a body with simplifier information.
mkWiseBody :: Informing rep => BodyDec rep -> Stms (Wise rep) -> Result -> Body (Wise rep)

-- | Produce a statement with simplifier information.
mkWiseStm :: Informing rep => Pat (LetDec rep) -> StmAux (ExpDec rep) -> Exp (Wise rep) -> Stm (Wise rep)

-- | Produce simplifier information for an expression.
mkWiseExpDec :: Informing rep => Pat (LetDec (Wise rep)) -> ExpDec rep -> Exp (Wise rep) -> ExpDec (Wise rep)

-- | A type class for indicating that this operation can be lifted into the
--   simplifier representation.
class CanBeWise op
addOpWisdom :: (CanBeWise op, Informing rep) => op rep -> op (Wise rep)

-- | Constraints that let us transform a representation into a Wise
--   representation.
type Informing rep = (ASTRep rep, AliasedOp (OpC rep), RephraseOp (OpC rep), CanBeWise (OpC rep), FreeIn (OpC rep (Wise rep)), ASTConstraints (OpC rep (Wise rep)))

-- | Construct a Wise lambda.
informLambda :: Informing rep => Lambda rep -> Lambda (Wise rep)

-- | Construct a Wise function definition.
informFunDef :: Informing rep => FunDef rep -> FunDef (Wise rep)

-- | Construct Wise statements.
informStms :: Informing rep => Stms rep -> Stms (Wise rep)

-- | Construct a Wise body.
informBody :: Informing rep => Body rep -> Body (Wise rep)
instance GHC.Show.Show Futhark.Optimise.Simplify.Rep.VarWisdom
instance GHC.Classes.Ord Futhark.Optimise.Simplify.Rep.VarWisdom
instance GHC.Classes.Eq Futhark.Optimise.Simplify.Rep.VarWisdom
instance GHC.Show.Show Futhark.Optimise.Simplify.Rep.ExpWisdom
instance GHC.Classes.Ord Futhark.Optimise.Simplify.Rep.ExpWisdom
instance GHC.Classes.Eq Futhark.Optimise.Simplify.Rep.ExpWisdom
instance GHC.Show.Show Futhark.Optimise.Simplify.Rep.BodyWisdom
instance GHC.Classes.Ord Futhark.Optimise.Simplify.Rep.BodyWisdom
instance GHC.Classes.Eq Futhark.Optimise.Simplify.Rep.BodyWisdom
instance (Futhark.Optimise.Simplify.Rep.Informing rep, GHC.Classes.Ord (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep)), GHC.Classes.Eq (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep)), GHC.Show.Show (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep)), Futhark.IR.Prop.IsOp (Futhark.IR.Rep.OpC rep), Prettyprinter.Internal.Pretty (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep))) => Futhark.IR.Rep.RepTypes (Futhark.Optimise.Simplify.Rep.Wise rep)
instance (Futhark.Optimise.Simplify.Rep.Informing rep, Futhark.IR.Prop.IsOp (Futhark.IR.Rep.OpC rep)) => Futhark.IR.Prop.ASTRep (Futhark.Optimise.Simplify.Rep.Wise rep)
instance (Futhark.Optimise.Simplify.Rep.Informing rep, Prettyprinter.Internal.Pretty (Futhark.IR.Rep.OpC rep (Futhark.Optimise.Simplify.Rep.Wise rep))) => Futhark.IR.Pretty.PrettyRep (Futhark.Optimise.Simplify.Rep.Wise rep)
instance Futhark.Optimise.Simplify.Rep.Informing rep => Futhark.IR.Prop.Aliases.Aliased (Futhark.Optimise.Simplify.Rep.Wise rep)
instance (Futhark.Builder.Class.Buildable rep, Futhark.Optimise.Simplify.Rep.Informing rep) => Futhark.Builder.Class.Buildable (Futhark.Optimise.Simplify.Rep.Wise rep)
instance Futhark.Optimise.Simplify.Rep.CanBeWise Futhark.IR.Rep.NoOp
instance Futhark.Transform.Rename.Rename Futhark.Optimise.Simplify.Rep.BodyWisdom
instance Futhark.Transform.Substitute.Substitute Futhark.Optimise.Simplify.Rep.BodyWisdom
instance Futhark.IR.Prop.Names.FreeIn Futhark.Optimise.Simplify.Rep.BodyWisdom
instance Futhark.IR.Prop.Names.FreeDec Futhark.Optimise.Simplify.Rep.BodyWisdom
instance Futhark.IR.Prop.Names.FreeIn Futhark.Optimise.Simplify.Rep.ExpWisdom
instance Futhark.IR.Prop.Names.FreeDec Futhark.Optimise.Simplify.Rep.ExpWisdom
instance Futhark.Transform.Substitute.Substitute Futhark.Optimise.Simplify.Rep.ExpWisdom
instance Futhark.Transform.Rename.Rename Futhark.Optimise.Simplify.Rep.ExpWisdom
instance Futhark.Transform.Rename.Rename Futhark.Optimise.Simplify.Rep.VarWisdom
instance Futhark.Transform.Substitute.Substitute Futhark.Optimise.Simplify.Rep.VarWisdom
instance Futhark.IR.Prop.Names.FreeIn Futhark.Optimise.Simplify.Rep.VarWisdom
instance Prettyprinter.Internal.Pretty Futhark.Optimise.Simplify.Rep.VarWisdom
instance Futhark.IR.Prop.Aliases.AliasesOf (Futhark.Optimise.Simplify.Rep.VarWisdom, dec)

-- | Alias analysis of a full Futhark program. Takes as input a program
--   with an arbitrary rep 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 :: AliasableRep rep => Prog rep -> Prog (Aliases rep)

-- | What we require of an aliasable representation.
type AliasableRep rep = (ASTRep rep, RephraseOp (OpC rep), CanBeAliased (OpC rep), AliasedOp (OpC rep), ASTConstraints (OpC rep (Aliases rep)))

-- | Perform alias analysis on function.
analyseFun :: AliasableRep rep => FunDef rep -> FunDef (Aliases rep)

-- | Perform alias analysis on statements.
analyseStms :: AliasableRep rep => AliasTable -> Stms rep -> (Stms (Aliases rep), AliasesAndConsumed)

-- | Perform alias analysis on statement.
analyseStm :: AliasableRep rep => AliasTable -> Stm rep -> Stm (Aliases rep)

-- | Perform alias analysis on expression.
analyseExp :: AliasableRep rep => AliasTable -> Exp rep -> Exp (Aliases rep)

-- | Perform alias analysis on Body.
analyseBody :: AliasableRep rep => AliasTable -> Body rep -> Body (Aliases rep)

-- | Perform alias analysis on lambda.
analyseLambda :: AliasableRep rep => AliasTable -> Lambda rep -> Lambda (Aliases rep)

-- | The type checker checks whether the program is type-consistent.
module Futhark.IR.TypeCheck

-- | Type check a program containing arbitrary type information, yielding
--   either a type error or a program with complete type information.
checkProg :: Checkable rep => Prog (Aliases rep) -> Either (TypeError rep) ()

-- | A type error.
data TypeError rep
Error :: [Text] -> ErrorCase rep -> TypeError rep

-- | Information about an error during type checking. The Show
--   instance for this type produces a human-readable description.
data ErrorCase rep
TypeError :: Text -> ErrorCase rep
UnexpectedType :: Exp rep -> Type -> [Type] -> ErrorCase rep
ReturnTypeError :: Name -> [ExtType] -> [ExtType] -> ErrorCase rep
DupDefinitionError :: Name -> ErrorCase rep
DupParamError :: Name -> VName -> ErrorCase rep
DupPatError :: VName -> ErrorCase rep
InvalidPatError :: Pat (LetDec (Aliases rep)) -> [ExtType] -> Maybe String -> ErrorCase rep
UnknownVariableError :: VName -> ErrorCase rep
UnknownFunctionError :: Name -> ErrorCase rep
ParameterMismatch :: Maybe Name -> [Type] -> [Type] -> ErrorCase rep
SlicingError :: Int -> Int -> ErrorCase rep
BadAnnotation :: String -> Type -> Type -> ErrorCase rep
ReturnAliased :: Name -> VName -> ErrorCase rep
UniqueReturnAliased :: Name -> ErrorCase rep
NotAnArray :: VName -> Type -> ErrorCase rep
PermutationError :: [Int] -> Int -> Maybe VName -> ErrorCase rep

-- | The type checker runs in this monad.
data TypeM rep a

-- | Signal a type error.
bad :: ErrorCase rep -> TypeM rep 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 :: Text -> TypeM rep a -> TypeM rep a

-- | The class of representations that can be type-checked.
class (AliasableRep rep, TypedOp (OpC rep)) => Checkable rep
checkExpDec :: Checkable rep => ExpDec rep -> TypeM rep ()
checkBodyDec :: Checkable rep => BodyDec rep -> TypeM rep ()
checkFParamDec :: Checkable rep => VName -> FParamInfo rep -> TypeM rep ()
checkLParamDec :: Checkable rep => VName -> LParamInfo rep -> TypeM rep ()
checkLetBoundDec :: Checkable rep => VName -> LetDec rep -> TypeM rep ()
checkRetType :: Checkable rep => [RetType rep] -> TypeM rep ()
matchPat :: Checkable rep => Pat (LetDec (Aliases rep)) -> Exp (Aliases rep) -> TypeM rep ()
primFParam :: Checkable rep => VName -> PrimType -> TypeM rep (FParam (Aliases rep))
matchReturnType :: Checkable rep => [RetType rep] -> Result -> TypeM rep ()
matchBranchType :: Checkable rep => [BranchType rep] -> Body (Aliases rep) -> TypeM rep ()
matchLoopResult :: Checkable rep => [FParam (Aliases rep)] -> Result -> TypeM rep ()

-- | Used at top level; can be locally changed with checkOpWith.
checkOp :: Checkable rep => Op (Aliases rep) -> TypeM rep ()
checkExpDec :: (Checkable rep, ExpDec rep ~ ()) => ExpDec rep -> TypeM rep ()
checkBodyDec :: (Checkable rep, BodyDec rep ~ ()) => BodyDec rep -> TypeM rep ()
checkFParamDec :: (Checkable rep, FParamInfo rep ~ DeclType) => VName -> FParamInfo rep -> TypeM rep ()
checkLParamDec :: (Checkable rep, LParamInfo rep ~ Type) => VName -> LParamInfo rep -> TypeM rep ()
checkLetBoundDec :: (Checkable rep, LetDec rep ~ Type) => VName -> LetDec rep -> TypeM rep ()
checkRetType :: (Checkable rep, RetType rep ~ DeclExtType) => [RetType rep] -> TypeM rep ()
matchPat :: Checkable rep => Pat (LetDec (Aliases rep)) -> Exp (Aliases rep) -> TypeM rep ()
primFParam :: (Checkable rep, FParamInfo rep ~ DeclType) => VName -> PrimType -> TypeM rep (FParam (Aliases rep))
matchReturnType :: (Checkable rep, RetType rep ~ DeclExtType) => [RetType rep] -> Result -> TypeM rep ()
matchBranchType :: (Checkable rep, BranchType rep ~ ExtType) => [BranchType rep] -> Body (Aliases rep) -> TypeM rep ()
matchLoopResult :: (Checkable rep, FParamInfo rep ~ DeclType) => [FParam (Aliases rep)] -> Result -> TypeM rep ()
lookupVar :: VName -> TypeM rep (NameInfo (Aliases rep))
lookupAliases :: Checkable rep => VName -> TypeM rep Names
checkOpWith :: (Op (Aliases rep) -> TypeM rep ()) -> TypeM rep a -> TypeM rep 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 rep => [Type] -> SubExp -> TypeM rep ()

-- | Variant of require working on variable names.
requireI :: Checkable rep => [Type] -> VName -> TypeM rep ()
requirePrimExp :: Checkable rep => PrimType -> PrimExp VName -> TypeM rep ()
checkSubExp :: Checkable rep => SubExp -> TypeM rep Type
checkCerts :: Checkable rep => Certs -> TypeM rep ()
checkExp :: Checkable rep => Exp (Aliases rep) -> TypeM rep ()
checkStms :: Checkable rep => Stms (Aliases rep) -> TypeM rep a -> TypeM rep a
checkStm :: Checkable rep => Stm (Aliases rep) -> TypeM rep a -> TypeM rep a

-- | Check a slicing operation of an array of the provided type.
checkSlice :: Checkable rep => Type -> Slice SubExp -> TypeM rep ()
checkType :: Checkable rep => TypeBase Shape u -> TypeM rep ()
checkExtType :: Checkable rep => TypeBase ExtShape u -> TypeM rep ()
matchExtPat :: Checkable rep => Pat (LetDec (Aliases rep)) -> [ExtType] -> TypeM rep ()
matchExtBranchType :: Checkable rep => [ExtType] -> Body (Aliases rep) -> TypeM rep ()
argType :: Arg -> Type
noArgAliases :: Arg -> Arg
checkArg :: Checkable rep => SubExp -> TypeM rep Arg
checkSOACArrayArgs :: Checkable rep => SubExp -> [VName] -> TypeM rep [Arg]
checkLambda :: Checkable rep => Lambda (Aliases rep) -> [Arg] -> TypeM rep ()
checkBody :: Checkable rep => Body (Aliases rep) -> TypeM rep [Names]

-- | Proclaim that we have written to the given variables.
consume :: Checkable rep => Names -> TypeM rep ()
binding :: Checkable rep => Scope (Aliases rep) -> TypeM rep a -> TypeM rep a

-- | Type check two mutually exclusive control flow branches. Think
--   if. This interacts with consumption checking, as it is OK for
--   an array to be consumed in both branches.
alternative :: TypeM rep a -> TypeM rep b -> TypeM rep (a, b)
instance GHC.Show.Show Futhark.IR.TypeCheck.Usage
instance GHC.Classes.Ord Futhark.IR.TypeCheck.Usage
instance GHC.Classes.Eq Futhark.IR.TypeCheck.Usage
instance GHC.Show.Show Futhark.IR.TypeCheck.Occurence
instance GHC.Classes.Eq Futhark.IR.TypeCheck.Occurence
instance GHC.Show.Show Futhark.IR.TypeCheck.Consumption
instance Control.Monad.State.Class.MonadState Futhark.IR.TypeCheck.TState (Futhark.IR.TypeCheck.TypeM rep)
instance Control.Monad.Reader.Class.MonadReader (Futhark.IR.TypeCheck.Env rep) (Futhark.IR.TypeCheck.TypeM rep)
instance GHC.Base.Applicative (Futhark.IR.TypeCheck.TypeM rep)
instance GHC.Base.Functor (Futhark.IR.TypeCheck.TypeM rep)
instance GHC.Base.Monad (Futhark.IR.TypeCheck.TypeM rep)
instance Futhark.IR.TypeCheck.Checkable rep => GHC.Show.Show (Futhark.IR.TypeCheck.ErrorCase rep)
instance Futhark.IR.TypeCheck.Checkable rep => GHC.Show.Show (Futhark.IR.TypeCheck.TypeError rep)
instance Futhark.IR.TypeCheck.Checkable rep => Futhark.IR.Prop.Scope.HasScope (Futhark.IR.Aliases.Aliases rep) (Futhark.IR.TypeCheck.TypeM rep)
instance GHC.Base.Semigroup Futhark.IR.TypeCheck.Consumption
instance GHC.Base.Monoid Futhark.IR.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 fromrep torep

-- | 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 rep
Action :: String -> String -> (Prog rep -> FutharkM ()) -> Action rep
[actionName] :: Action rep -> String
[actionDescription] :: Action rep -> String
[actionProcedure] :: Action rep -> Prog rep -> 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 torep => Pass fromrep torep -> Pipeline fromrep torep

-- | Create a pipeline from a list of passes.
passes :: Checkable rep => [Pass rep rep] -> Pipeline rep rep

-- | Conditionally run pipeline if predicate is true.
condPipeline :: (Prog rep -> Bool) -> Pipeline rep rep -> Pipeline rep rep

-- | Run the pipeline on the given program.
runPipeline :: Pipeline fromrep torep -> PipelineConfig -> Prog fromrep -> FutharkM (Prog torep)
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

-- | Some GPU platforms have a SIMDwarpwavefront-based execution
--   model that execute blocks of threads in lockstep, permitting us to
--   perform cross-thread synchronisation within each such block 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 block sizes and block
--   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
NumBlocks :: WhichSize
BlockSize :: WhichSize
TileSize :: WhichSize
RegTileSize :: 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 Prettyprinter.Internal.Pretty Futhark.CodeGen.OpenCL.Heuristics.DeviceInfo

-- | 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, RepTypes rep) => (VName -> m (PrimExp v)) -> Exp rep -> 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

-- | Shorthand for constructing a TPrimExp of type Float32.
f32pe :: SubExp -> TPrimExp Float VName

-- | Shorthand for constructing a TPrimExp of type Float32,
--   from a leaf.
f32le :: a -> TPrimExp Float a

-- | Shorthand for constructing a TPrimExp of type Float64.
f64pe :: SubExp -> TPrimExp Double VName

-- | Shorthand for constructing a TPrimExp of type Float64,
--   from a leaf.
f64le :: a -> TPrimExp Double 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 :: MonadBuilder m => Slice (TPrimExp Int64 VName) -> m (Slice SubExp)
instance Futhark.Construct.ToExp v => Futhark.Construct.ToExp (Futhark.Analysis.PrimExp.PrimExp v)
instance forall k v (t :: k). Futhark.Construct.ToExp v => Futhark.Construct.ToExp (Futhark.Analysis.PrimExp.TPrimExp t v)

-- | Particularly simple simplification rules.
module Futhark.Optimise.Simplify.Rules.Simple

-- | A function that, given a subexpression, returns its type.
type TypeLookup = SubExp -> Maybe Type

-- | A function that, given a variable name, returns its definition.
type VarLookup rep = VName -> Maybe (Exp rep, Certs)

-- | Try to simplify the given BasicOp, returning a new
--   BasicOp and certificates that it must depend on.
applySimpleRules :: VarLookup rep -> TypeLookup -> BasicOp -> Maybe (BasicOp, Certs)

-- | ImpCode is an imperative intermediate language used as a stepping
--   stone in code generation. The functional core IR
--   (Futhark.IR.Syntax) gets translated into ImpCode by
--   Futhark.CodeGen.ImpGen. Later we then translate ImpCode to, for
--   example, C.
--   
--   
Basic design
--   
--   ImpCode distinguishes between statements (Code), which
--   may have side effects, and expressions (Exp) which do
--   not. Expressions involve only scalars and have a type. The actual
--   expression definition is in Futhark.Analysis.PrimExp,
--   specifically PrimExp and its phantom-typed variant
--   TPrimExp.
--   
--   Code is a generic representation parametrised on an extensible
--   arbitrary operation, represented by the Op constructor.
--   Specific instantiations of ImpCode, such as
--   Futhark.CodeGen.ImpCode.Multicore, will pass in a specific kind
--   of operation to express backend-specific functionality (in the case of
--   multicore, this is Multicore).
--   
--   
Arrays and memory
--   
--   ImpCode does not have arrays. DeclareArray is for declaring
--   constant array literals, not arrays in general. Instead, ImpCode deals
--   only with memory. Array operations present in core IR programs are
--   turned into Write, Read, and Copy operations that
--   use flat indexes and offsets based on the index function of the
--   original array.
--   
--   
Scoping
--   
--   ImpCode is much simpler than the functional core IR; partly because we
--   hope to do less work on it. We don't have real optimisation passes on
--   ImpCode. One result of this simplicity is that ImpCode has a fairly
--   naive view of scoping. The only things that can bring new names
--   into scope are DeclareMem, DeclareScalar,
--   DeclareArray, For, and function parameters. In
--   particular, Ops cannot bind parameters. The standard
--   workaround is to define Ops that retrieve the value of an
--   implicit parameter and assign it to a variable declared with the
--   normal mechanisms. GetLoopBounds is an example of this pattern.
--   
--   
Inspiration
--   
--   ImpCode was 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 :: OpaqueTypes -> Constants a -> Functions a -> Definitions a
[defTypes] :: Definitions a -> OpaqueTypes
[defConsts] :: Definitions a -> Constants a
[defFuns] :: Definitions a -> Functions a

-- | A collection of imperative functions.
newtype Functions a
Functions :: [(Name, Function a)] -> Functions a
[unFunctions] :: Functions a -> [(Name, Function 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 present if the function is an entry point.
data FunctionT a
Function :: Maybe EntryPoint -> [Param] -> [Param] -> Code a -> FunctionT a
[functionEntry] :: FunctionT a -> Maybe EntryPoint
[functionOutput] :: FunctionT a -> [Param]
[functionInput] :: FunctionT a -> [Param]
[functionBody] :: FunctionT a -> Code a

-- | Information about how this function can be called from the outside
--   world.
data EntryPoint
EntryPoint :: Name -> [(Uniqueness, ExternalValue)] -> [((Name, Uniqueness), ExternalValue)] -> EntryPoint
[entryPointName] :: EntryPoint -> Name
[entryPointResults] :: EntryPoint -> [(Uniqueness, ExternalValue)]
[entryPointArgs] :: EntryPoint -> [((Name, Uniqueness), 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 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

-- | ^ An externally visible value. This can be an opaque value (covering
--   several physical internal values), or a single value that can be used
--   externally. We record the uniqueness because it is important to the
--   external interface as well.
data ExternalValue

-- | The string is a human-readable description with no other semantics.
OpaqueValue :: Name -> [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

-- | The size of a memory block.
type MemSize = SubExp

-- | The size of an array.
type DimSize = SubExp

-- | 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
(:>>:) :: 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 a DefaultSpace array containing the given values. The lifetime
--   of the array will be the entire application. This is mostly used for
--   constant arrays.
DeclareArray :: VName -> 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

-- | Copy pt shape dest dest_lmad src src_lmad.
Copy :: PrimType -> [Count Elements (TExp Int64)] -> (VName, Space) -> (Count Elements (TExp Int64), [Count Elements (TExp Int64)]) -> (VName, Space) -> (Count Elements (TExp Int64), [Count Elements (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).
Write :: VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> Exp -> Code a

-- | Set a scalar variable.
SetScalar :: VName -> Exp -> Code a

-- | Read a scalar from memory from memory. The first VName is the
--   target scalar variable, and the remaining arguments have the same
--   meaning as with Write.
Read :: VName -> VName -> Count Elements (TExp Int64) -> PrimType -> Space -> Volatility -> 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 :: Text -> 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

-- | Log the given message, *without* a trailing linebreak (unless part of
--   the message).
TracePrint :: ErrorMsg 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 Unit.
UnitValue :: PrimValue

-- | A side-effect free expression whose execution will produce a single
--   primitive value.
type Exp = PrimExp VName

-- | Like Exp, but with a required/known type.
type TExp t = TPrimExp t VName

-- | 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 Exp.
var :: VName -> PrimType -> Exp

-- | 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

-- | The names declared with DeclareMem, DeclareScalar, and
--   DeclareArray in the given code.
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

-- | Reorder the code such that all declarations appear first. This is
--   always possible, because DeclareScalar and DeclareMem do
--   not depend on any local bindings.
declsFirst :: Code a -> Code a

-- | The set of functions that are called by this code. Accepts a function
--   for determing function calls in Ops.
calledFuncs :: (a -> Set Name) -> Code a -> Set Name

-- | Compute call graph, as per calledFuncs, but also include
--   transitive calls.
callGraph :: (a -> Set Name) -> Functions a -> Map Name (Set Name)

-- | A mapping from names of tuning parameters to their class, as well as
--   which functions make use of them (including transitively).
type ParamMap = Map Name (SizeClass, 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)

-- | Prettyprint a value to a Text, appropriately wrapped.
prettyText :: Pretty a => a -> Text

-- | Prettyprint a value to a String, appropriately wrapped.
prettyString :: Pretty a => a -> 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

-- | An actual non-opaque type that can be passed to and from Futhark
--   programs, or serve as the contents of opaque types. Scalars are
--   represented with zero rank.
data ValueType
ValueType :: Signedness -> Rank -> PrimType -> ValueType

-- | 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

-- | Every entry point argument and return value has an annotation
--   indicating how it maps to the original source program type.
data EntryPointType

-- | An opaque type of this name.
TypeOpaque :: Name -> EntryPointType

-- | A transparent type, which is scalar if the rank is zero.
TypeTransparent :: ValueType -> EntryPointType

-- | 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 :: Text -> ErrorMsgPart a

-- | A run-time value.
ErrorVal :: PrimType -> a -> ErrorMsgPart a

-- | The representation of an opaque type.
data OpaqueType
OpaqueType :: [ValueType] -> OpaqueType

-- | Note that the field ordering here denote the actual representation -
--   make sure it is preserved.
OpaqueRecord :: [(Name, EntryPointType)] -> OpaqueType

-- | Constructor ordering also denotes representation, in that the index of
--   the constructor is the identifying number.
--   
--   The total values used to represent a sum values is the
--   ValueType list. The Ints associated with each
--   EntryPointType are the indexes of the values used to represent
--   that constructor payload. This is necessary because we deduplicate
--   payloads across constructors.
OpaqueSum :: [ValueType] -> [(Name, [(EntryPointType, [Int])])] -> OpaqueType

-- | An array with this rank and named opaque element type.
OpaqueArray :: Int -> Name -> [ValueType] -> OpaqueType

-- | An array with known rank and where the elements are this record type.
OpaqueRecordArray :: Int -> Name -> [(Name, EntryPointType)] -> OpaqueType

-- | Names of opaque types and their representation.
newtype OpaqueTypes
OpaqueTypes :: [(Name, OpaqueType)] -> OpaqueTypes

-- | The size of an array type as merely the number of dimensions, with no
--   further information.
newtype Rank
Rank :: Int -> Rank

-- | 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. This doesn't matter for non-integer
--   types.
data Signedness
Unsigned :: Signedness
Signed :: Signedness

-- | A string representing a specific non-default memory space.
type SpaceId = String

-- | How many non-constant parts does the error message have, and what is
--   their type?
errorMsgArgTypes :: ErrorMsg 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

-- | 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
SizeThreadBlock :: SizeClass

-- | The number of thread blocks.
SizeGrid :: SizeClass
SizeTile :: SizeClass
SizeRegTile :: SizeClass

-- | Likely not useful on its own, but querying the maximum can be handy.
SizeSharedMemory :: SizeClass

-- | A bespoke size with a default.
SizeBespoke :: Name -> Int64 -> SizeClass

-- | Amount of registers available per threadblock. Mostly meaningful for
--   querying the maximum.
SizeRegisters :: SizeClass

-- | Amount of L2 cache memory, in bytes. Mostly meaningful for querying
--   the maximum.
SizeCache :: SizeClass
instance GHC.Show.Show Futhark.CodeGen.ImpCode.Param
instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.Param
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.EntryPoint
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.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 GHC.Show.Show a => GHC.Show.Show (Futhark.CodeGen.ImpCode.Functions a)
instance GHC.Show.Show a => GHC.Show.Show (Futhark.CodeGen.ImpCode.Constants a)
instance GHC.Show.Show a => GHC.Show.Show (Futhark.CodeGen.ImpCode.Definitions a)
instance GHC.Base.Functor Futhark.CodeGen.ImpCode.Definitions
instance Prettyprinter.Internal.Pretty op => Prettyprinter.Internal.Pretty (Futhark.CodeGen.ImpCode.Definitions op)
instance GHC.Base.Functor Futhark.CodeGen.ImpCode.Constants
instance GHC.Base.Monoid (Futhark.CodeGen.ImpCode.Constants a)
instance GHC.Base.Semigroup (Futhark.CodeGen.ImpCode.Constants a)
instance Prettyprinter.Internal.Pretty op => Prettyprinter.Internal.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 Prettyprinter.Internal.Pretty op => Prettyprinter.Internal.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 Prettyprinter.Internal.Pretty op => Prettyprinter.Internal.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 Prettyprinter.Internal.Pretty op => Prettyprinter.Internal.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 Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.Arg
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Arg
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.ArrayContents
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.EntryPoint
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.EntryPoint
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.ExternalValue
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.ExternalValue
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.ValueDesc
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.ValueDesc
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.Param

-- | Sequential imperative code.
module Futhark.CodeGen.ImpCode.Sequential

-- | An imperative program.
type Program = Definitions Sequential

-- | Phantom type for identifying sequential imperative code.
data Sequential
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.Sequential.Sequential
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Sequential.Sequential

-- | Multicore imperative code.
module Futhark.CodeGen.ImpCode.Multicore

-- | An imperative multicore program.
type Program = Functions Multicore

-- | A multicore operation.
data Multicore
SegOp :: String -> [Param] -> ParallelTask -> Maybe ParallelTask -> [Param] -> SchedulerInfo -> Multicore
ParLoop :: String -> MCCode -> [Param] -> Multicore

-- | A kernel of ISPC code, or a scoped block in regular C.
ISPCKernel :: MCCode -> [Param] -> Multicore

-- | A foreach loop in ISPC, or a regular for loop in C.
ForEach :: VName -> Exp -> Exp -> MCCode -> Multicore

-- | A foreach_active loop in ISPC, or a single execution in C.
ForEachActive :: VName -> MCCode -> Multicore

-- | Extract a value from a given lane and assign it to a variable. This is
--   just a regular assignment in C.
ExtractLane :: VName -> Exp -> Exp -> Multicore

-- | Retrieve inclusive start and exclusive end indexes of the chunk we are
--   supposed to be executing. Only valid immediately inside a
--   ParLoop construct!
GetLoopBounds :: VName -> VName -> Multicore

-- | Retrieve the task ID that is currently executing. Only valid
--   immediately inside a ParLoop construct!
GetTaskId :: VName -> Multicore

-- | Retrieve the number of subtasks to execute. Only valid immediately
--   inside a SegOp or ParLoop construct!
GetNumTasks :: VName -> Multicore
Atomic :: AtomicOp -> Multicore

-- | Multicore code.
type MCCode = Code Multicore

-- | Whether the Scheduler should schedule the tasks as Dynamic or it is
--   restainted to Static
data Scheduling
Dynamic :: Scheduling
Static :: Scheduling

-- | Information about parallel work that is do be done. This is passed to
--   the scheduler to help it make scheduling decisions.
data SchedulerInfo
SchedulerInfo :: Exp -> Scheduling -> SchedulerInfo

-- | The number of total iterations for a task.
[iterations] :: SchedulerInfo -> Exp

-- | The type scheduling for the task.
[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

-- | A task for a SegOp.
newtype ParallelTask
ParallelTask :: MCCode -> ParallelTask

-- | Whether lexicalMemoryUsageMC should look inside nested kernels
--   or not.
data KernelHandling
TraverseKernels :: KernelHandling
OpaqueKernels :: KernelHandling

-- | Like lexicalMemoryUsage, but traverses some inner multicore
--   ops.
lexicalMemoryUsageMC :: KernelHandling -> Function Multicore -> Map VName Space
instance GHC.Show.Show Futhark.CodeGen.ImpCode.Multicore.AtomicOp
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.Multicore.ParallelTask
instance Prettyprinter.Internal.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 Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.Multicore.SchedulerInfo
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.Multicore.SchedulerInfo
instance Prettyprinter.Internal.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.GPU

-- | A program that calls kernels.
type Program = Definitions HostOp

-- | Host-level code that can call kernels.
type HostCode = Code HostOp

-- | Code inside a kernel.
type KernelCode = Code KernelOp

-- | A run-time constant related to kernels.
data KernelConst
SizeConst :: Name -> SizeClass -> KernelConst
SizeMaxConst :: SizeClass -> 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
GetBlockId :: VName -> Int -> KernelOp
GetLocalId :: VName -> Int -> KernelOp
GetLocalSize :: VName -> Int -> KernelOp
GetLockstepWidth :: VName -> KernelOp
Atomic :: Space -> AtomicOp -> KernelOp
Barrier :: Fence -> KernelOp
MemFence :: Fence -> KernelOp
SharedAlloc :: 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? By
--   the Ord instance, global is greater than local.
data Fence
FenceLocal :: Fence
FenceGlobal :: Fence

-- | Atomic operations return the value stored before the update. This old
--   value is stored in the first VName (except for
--   AtomicWrite). 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

-- | Corresponds to a write followed by a memory fence. The old value is
--   not read.
AtomicWrite :: PrimType -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp

-- | The size of one dimension of a block.
type BlockDim = Either Exp KernelConstExp

-- | A generic kernel containing arbitrary kernel code.
data Kernel
Kernel :: Code KernelOp -> [KernelUse] -> [Exp] -> [BlockDim] -> Name -> Bool -> Bool -> Kernel
[kernelBody] :: Kernel -> Code KernelOp

-- | The host variables referenced by the kernel.
[kernelUses] :: Kernel -> [KernelUse]
[kernelNumBlocks] :: Kernel -> [Exp]
[kernelBlockSize] :: Kernel -> [BlockDim]

-- | 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

-- | If true, multi-versioning branches will consider this kernel when
--   considering the shared memory requirements. Set this to false for
--   kernels that do their own checking.
[kernelCheckSharedMemory] :: 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
instance GHC.Show.Show Futhark.CodeGen.ImpCode.GPU.KernelConst
instance GHC.Classes.Ord Futhark.CodeGen.ImpCode.GPU.KernelConst
instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.GPU.KernelConst
instance GHC.Show.Show Futhark.CodeGen.ImpCode.GPU.KernelUse
instance GHC.Classes.Ord Futhark.CodeGen.ImpCode.GPU.KernelUse
instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.GPU.KernelUse
instance GHC.Classes.Ord Futhark.CodeGen.ImpCode.GPU.Fence
instance GHC.Classes.Eq Futhark.CodeGen.ImpCode.GPU.Fence
instance GHC.Show.Show Futhark.CodeGen.ImpCode.GPU.Fence
instance GHC.Show.Show Futhark.CodeGen.ImpCode.GPU.AtomicOp
instance GHC.Show.Show Futhark.CodeGen.ImpCode.GPU.KernelOp
instance GHC.Show.Show Futhark.CodeGen.ImpCode.GPU.Kernel
instance GHC.Show.Show Futhark.CodeGen.ImpCode.GPU.HostOp
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.GPU.HostOp
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.GPU.HostOp
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.GPU.Kernel
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.GPU.Kernel
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.GPU.KernelOp
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.GPU.KernelOp
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.GPU.AtomicOp
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.GPU.KernelUse
instance Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.GPU.KernelConst
instance Futhark.IR.Prop.Names.FreeIn Futhark.CodeGen.ImpCode.GPU.KernelConst

-- | 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 :: Text -> Text -> [(Name, KernelConstExp)] -> Map KernelName KernelSafety -> [PrimType] -> ParamMap -> [FailureMsg] -> Definitions OpenCL -> Program
[openClProgram] :: Program -> Text

-- | Must be prepended to the program.
[openClPrelude] :: Program -> Text

-- | Definitions to be passed as macro definitions to the kernel compiler.
[openClMacroDefs] :: Program -> [(Name, KernelConstExp)]
[openClKernelNames] :: Program -> Map KernelName KernelSafety

-- | So we can detect whether the device is capable.
[openClUsedTypes] :: Program -> [PrimType]

-- | Runtime-configurable constants.
[openClParams] :: Program -> ParamMap

-- | Assertion failure error messages.
[openClFailures] :: Program -> [FailureMsg]
[hostDefinitions] :: Program -> Definitions 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

-- | A piece of code calling OpenCL.
type CLCode = Code OpenCL

-- | Host-level OpenCL operation.
data OpenCL
LaunchKernel :: KernelSafety -> KernelName -> Count Bytes (TExp Int64) -> [KernelArg] -> [Exp] -> [BlockDim] -> 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
TargetHIP :: 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

-- | The size of one dimension of a block.
type BlockDim = Either Exp KernelConstExp

-- | A run-time constant related to kernels.
data KernelConst
SizeConst :: Name -> SizeClass -> KernelConst
SizeMaxConst :: SizeClass -> KernelConst

-- | An expression whose variables are kernel constants.
type KernelConstExp = PrimExp KernelConst
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 Prettyprinter.Internal.Pretty Futhark.CodeGen.ImpCode.OpenCL.OpenCL

-- | Simple C runtime representation.
--   
--   Most types use the same memory and scalar variable representation. For
--   those that do not (as of this writing, only Float16), we use
--   primStorageType for the array element representation, and
--   primTypeToCType for their scalar representation. Use
--   toStorage and fromStorage to convert back and forth.
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 -> Text

-- | 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 storage type for arrays of this primitive type.
primStorageType :: PrimType -> Type

-- | The C API corresponding to a primitive type. Integers are assumed to
--   have the specified sign.
primAPIType :: Signedness -> PrimType -> Type

-- | The name of exposed array type structs.
arrayName :: PrimType -> Signedness -> Int -> Text

-- | The name of exposed opaque types.
opaqueName :: Name -> Text

-- | Is this name a valid C identifier? If not, it should be escaped before
--   being emitted into C.
isValidCName :: Text -> Bool

-- | If the provided text is a valid C identifier, then return it verbatim.
--   Otherwise, escape it such that it becomes valid.
escapeName :: Text -> Text

-- | Convert from scalar to storage representation for the given type.
toStorage :: PrimType -> Exp -> Exp

-- | Convert from storage to scalar representation for the given type.
fromStorage :: PrimType -> Exp -> Exp

-- | Return an expression multiplying together the given expressions. If an
--   empty list is given, the expression 1 is returned.
cproduct :: [Exp] -> Exp

-- | Return an expression summing the given expressions. If an empty list
--   is given, the expression 0 is returned.
csum :: [Exp] -> Exp

-- | An expression that is true if these expressions are all equal by
--   ==.
allEqual :: [Exp] -> Exp

-- | An expression that is true if these are also all true.
allTrue :: [Exp] -> Exp

-- | The PrimType (and sign) corresponding to a human-readable
--   scalar type name (e.g. f64). Beware: partial!
scalarToPrim :: Text -> (Signedness, PrimType)

-- | Implementations of scalar operations.
cScalarDefs :: Text

-- | storageSize pt rank shape produces an expression giving size
--   taken when storing this value in the binary value format. It is
--   assumed that the shape is an array with rank
--   dimensions.
storageSize :: PrimType -> Int -> Exp -> Exp

-- | Produce code for storing the header (everything besides the actual
--   payload) for a value of this type.
storeValueHeader :: Signedness -> PrimType -> Int -> Exp -> Exp -> [Stm]

-- | Produce code for loading the header (everything besides the actual
--   payload) for a value of this type.
loadValueHeader :: Signedness -> PrimType -> Int -> Exp -> Exp -> [Stm]
instance Language.C.Quote.Base.ToIdent Language.Futhark.Core.Name
instance Language.C.Quote.Base.ToIdent Data.Text.Internal.Text
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 Language.Futhark.Primitive.IntValue
instance Language.C.Quote.Base.ToExp Language.Futhark.Primitive.FloatValue
instance Language.C.Quote.Base.ToExp Language.Futhark.Primitive.PrimValue
instance Language.C.Quote.Base.ToExp Futhark.IR.Syntax.Core.SubExp

-- | Code generation for server executables.
module Futhark.CodeGen.Backends.GenericC.Server

-- | Generate Futhark server executable code.
serverDefs :: [Option] -> Manifest -> Text

-- | Code generation for standalone executables.
module Futhark.CodeGen.Backends.GenericC.CLI

-- | Generate Futhark standalone executable code.
cliDefs :: [Option] -> Manifest -> Text

-- | 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 => CompilerMode -> String -> Constructor -> [PyStmt] -> [PyStmt] -> Operations op s -> s -> [PyStmt] -> [Option] -> Definitions op -> m Text

-- | Are we compiling a library or an executable?
data CompilerMode

-- | 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 -> CompilerM op s 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 Numpy type corresponding to a PrimType.
compilePrimToNp :: PrimType -> String

-- | The Numpy type corresponding to a PrimType, taking sign into
--   account.
compilePrimToExtNp :: PrimType -> Signedness -> String

-- | Convert from storage to scalar representation for the given type.
fromStorage :: PrimType -> PyExp -> PyExp

-- | Convert from scalar to storage representation for the given type.
toStorage :: PrimType -> PyExp -> PyExp
data Operations op s
Operations :: WriteScalar op s -> ReadScalar op s -> Allocate op s -> Map (Space, Space) (DoCopy 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

-- | (dst,src)-space mapping to copy functions.
[opsCopies] :: Operations op s -> Map (Space, Space) (DoCopy op s)
[opsCompiler] :: Operations op s -> OpCompiler op s
[opsEntryOutput] :: Operations op s -> EntryOutput op s
[opsEntryInput] :: Operations op s -> EntryInput op s

-- | Perform an Copy. It is expected that these functions are each
--   specialised on which spaces they operate on, so that is not part of
--   their arguments.
type DoCopy op s = PrimType -> [Count Elements PyExp] -> PyExp -> (Count Elements PyExp, [Count Elements PyExp]) -> PyExp -> (Count Elements PyExp, [Count Elements PyExp]) -> CompilerM 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 ()

-- | 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 String PyExp -> CompilerEnv op s
[envOperations] :: CompilerEnv op s -> Operations op s
[envVarExp] :: CompilerEnv op s -> Map String 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
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 :: [(Name, KernelConstExp)] -> [PrimType] -> String -> ParamMap -> [FailureMsg] -> Text

-- | C code generator framework.
module Futhark.CodeGen.Backends.GenericC.Monad
data Operations op s
Operations :: WriteScalar op s -> ReadScalar op s -> Allocate op s -> Deallocate op s -> Copy op s -> MemoryType op s -> OpCompiler op s -> ErrorCompiler op s -> CallCompiler op s -> Map (Space, Space) (DoCopy 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
[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

-- | (dst,src)-space mapping to copy functions.
[opsCopies] :: Operations op s -> Map (Space, Space) (DoCopy 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])
data Publicness
Private :: Publicness
Public :: Publicness

-- | 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 = String -> [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 -> 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 -> 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, with the given
--   size,, which is in the given memory space.
type Deallocate op s = Exp -> Exp -> Exp -> SpaceId -> CompilerM op s ()

-- | Whether a copying operation should implicitly function as a barrier
--   regarding further operations on the source. This is a rather subtle
--   detail and is mostly useful for letting some device/GPU copies be
--   asynchronous (#1664).
data CopyBarrier
CopyBarrier :: CopyBarrier

-- | Explicit context synchronisation should be done before the source or
--   target is used.
CopyNoBarrier :: CopyBarrier

-- | Copy from one memory block to another.
type Copy op s = CopyBarrier -> Exp -> Exp -> Space -> Exp -> Exp -> Space -> Exp -> CompilerM op s ()

-- | Perform an Copy. It is expected that these functions are each
--   specialised on which spaces they operate on, so that is not part of
--   their arguments.
type DoCopy op s = CopyBarrier -> PrimType -> [Count Elements Exp] -> Exp -> (Count Elements Exp, [Count Elements Exp]) -> Exp -> (Count Elements Exp, [Count Elements Exp]) -> CompilerM op s ()
data CompilerM op s a
data CompilerState s
CompilerState :: Map ArrayType Publicness -> DList Definition -> VNameSource -> s -> Map HeaderSection (DList Definition) -> DList Definition -> DList (Id, Type, Maybe Exp, Maybe (Stm, Stm)) -> DList BlockItem -> [(VName, Space)] -> DList BlockItem -> CompilerState s
[compArrayTypes] :: CompilerState s -> Map ArrayType Publicness
[compEarlyDecls] :: CompilerState s -> DList Definition
[compNameSrc] :: CompilerState s -> VNameSource
[compUserState] :: CompilerState s -> s
[compHeaderDecls] :: CompilerState s -> Map HeaderSection (DList Definition)
[compLibDecls] :: CompilerState s -> DList Definition
[compCtxFields] :: CompilerState s -> DList (Id, Type, Maybe Exp, Maybe (Stm, Stm))
[compClearItems] :: CompilerState s -> DList BlockItem
[compDeclaredMem] :: CompilerState s -> [(VName, Space)]
[compItems] :: CompilerState s -> DList BlockItem
data CompilerEnv op s
CompilerEnv :: Operations op s -> Map Exp VName -> CompilerEnv op s
[envOperations] :: CompilerEnv op s -> Operations op s

-- | Mapping memory blocks to sizes. These memory blocks are CPU memory
--   that we know are used in particularly simple ways (no reference
--   counting necessary). To cut down on allocator pressure, we keep these
--   allocations around for a long time, and record their sizes so we can
--   reuse them if possible (and realloc() when needed).
[envCachedMem] :: CompilerEnv op s -> Map Exp VName
getUserState :: CompilerM op s s
modifyUserState :: (s -> s) -> CompilerM op s ()
generateProgramStruct :: CompilerM op s ()
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 :: CompilerM op s a -> CompilerM op s a
cachingMemory :: Map VName Space -> ([BlockItem] -> [Stm] -> CompilerM op s a) -> CompilerM op s a
volQuals :: Volatility -> [TypeQual]
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 ()
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 :: Text -> HeaderSection -> (Text -> (Definition, Definition)) -> CompilerM op s Text

-- | As publicDef, but ignores the public name.
publicDef_ :: Text -> HeaderSection -> (Text -> (Definition, Definition)) -> CompilerM op s ()
onClear :: 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 :: Name -> HeaderSection
OpaqueTypeDecl :: Name -> HeaderSection
OpaqueDecl :: Name -> 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 :: Text -> CompilerM op s Text
contextField :: Id -> Type -> Maybe Exp -> CompilerM op s ()
contextFieldDyn :: Id -> Type -> Stm -> Stm -> 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
freeRawMem :: (ToExp a, ToExp b, ToExp c) => a -> b -> Space -> c -> CompilerM op s ()
allocRawMem :: (ToExp a, ToExp b, ToExp c) => a -> b -> Space -> c -> CompilerM op s ()
fatMemType :: Space -> Type
declAllocatedMem :: CompilerM op s [BlockItem]
freeAllocatedMem :: CompilerM op s [BlockItem]
collect :: CompilerM op s () -> CompilerM op s [BlockItem]
collect' :: CompilerM op s a -> CompilerM op s (a, [BlockItem])

-- | The generated code must define a context struct with this name.
contextType :: CompilerM op s Type

-- | The generated code must define a configuration struct with this name.
configType :: CompilerM op s Type
copyMemoryDefaultSpace :: Exp -> Exp -> Exp -> Exp -> Exp -> CompilerM op s ()
derefPointer :: Exp -> Exp -> Type -> Exp
setMem :: (ToExp a, ToExp b) => a -> b -> Space -> CompilerM op s ()
allocMem :: (ToExp a, ToExp b) => a -> b -> Space -> Stm -> CompilerM op s ()
unRefMem :: ToExp a => a -> Space -> CompilerM op s ()
declMem :: VName -> Space -> CompilerM op s ()
resetMem :: ToExp a => a -> Space -> CompilerM op s ()
fatMemAlloc :: Space -> String
fatMemSet :: Space -> String
fatMemUnRef :: Space -> String
criticalSection :: Operations op s -> [BlockItem] -> [BlockItem]
instance GHC.Show.Show Futhark.CodeGen.Backends.GenericC.Monad.Publicness
instance GHC.Classes.Ord Futhark.CodeGen.Backends.GenericC.Monad.Publicness
instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericC.Monad.Publicness
instance GHC.Classes.Ord Futhark.CodeGen.Backends.GenericC.Monad.HeaderSection
instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericC.Monad.HeaderSection
instance GHC.Show.Show Futhark.CodeGen.Backends.GenericC.Monad.CopyBarrier
instance GHC.Classes.Eq Futhark.CodeGen.Backends.GenericC.Monad.CopyBarrier
instance Control.Monad.Reader.Class.MonadReader (Futhark.CodeGen.Backends.GenericC.Monad.CompilerEnv op s) (Futhark.CodeGen.Backends.GenericC.Monad.CompilerM op s)
instance Control.Monad.State.Class.MonadState (Futhark.CodeGen.Backends.GenericC.Monad.CompilerState s) (Futhark.CodeGen.Backends.GenericC.Monad.CompilerM op s)
instance GHC.Base.Monad (Futhark.CodeGen.Backends.GenericC.Monad.CompilerM op s)
instance GHC.Base.Applicative (Futhark.CodeGen.Backends.GenericC.Monad.CompilerM op s)
instance GHC.Base.Functor (Futhark.CodeGen.Backends.GenericC.Monad.CompilerM op s)
instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.CodeGen.Backends.GenericC.Monad.CompilerM op s)

-- | Code generation for public API types.
module Futhark.CodeGen.Backends.GenericC.Types
generateAPITypes :: Space -> OpaqueTypes -> CompilerM op s (Map Text Type)
valueTypeToCType :: Publicness -> ValueType -> CompilerM op s Type
opaqueToCType :: Name -> CompilerM op s Type

-- | Generate the entry point packing/unpacking code.
module Futhark.CodeGen.Backends.GenericC.EntryPoints
onEntryPoint :: [BlockItem] -> [Name] -> Name -> Function op -> CompilerM op s (Maybe (Definition, (Text, EntryPoint)))

-- | Translation of ImpCode Exp and Code to C.
module Futhark.CodeGen.Backends.GenericC.Code

-- | 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

-- | Compile prim expression to C expression.
compileExp :: Exp -> CompilerM op s Exp
compileCode :: Code op -> CompilerM op s ()

-- | Prepare a destination for function application.
compileDest :: VName -> CompilerM op s (VName, [Stm])

-- | Compile an argument to a function applicaiton.
compileArg :: Arg -> CompilerM op s Exp

-- | Compile an Copy using sequential nested loops and
--   Read/Write of individual scalars. This always works,
--   but can be pretty slow if those reads and writes are costly.
compileCopy :: PrimType -> [Count Elements (TExp Int64)] -> (VName, Space) -> (Count Elements (TExp Int64), [Count Elements (TExp Int64)]) -> (VName, Space) -> (Count Elements (TExp Int64), [Count Elements (TExp Int64)]) -> CompilerM op s ()

-- | Compile an Copy using sequential nested loops, but
--   parameterised over how to do the reads and writes.
compileCopyWith :: [Count Elements (TExp Int64)] -> (Exp -> Exp -> CompilerM op s ()) -> (Count Elements (TExp Int64), [Count Elements (TExp Int64)]) -> (Exp -> CompilerM op s Exp) -> (Count Elements (TExp Int64), [Count Elements (TExp Int64)]) -> CompilerM op s ()
errorMsgString :: ErrorMsg Exp -> CompilerM op s (String, [Exp])
linearCode :: Code op -> [Code op]
instance forall k (t :: k). Language.C.Quote.Base.ToExp (Futhark.CodeGen.ImpCode.TExp t)

-- | C code generation for functions.
module Futhark.CodeGen.Backends.GenericC.Fun
compileFun :: [BlockItem] -> [Param] -> (Name, Function op) -> CompilerM op s (Definition, Func)

-- | Generate code for a function that returns void (meaning it cannot
--   fail) and has no extra parameters (meaning it cannot allocate memory
--   non-lexxical or do anything fancy).
compileVoidFun :: [BlockItem] -> (Name, Function op) -> CompilerM op s (Definition, Func)

-- | This module defines a translation from imperative code with kernels to
--   imperative code with OpenCL or CUDA calls.
module Futhark.CodeGen.ImpGen.GPU.ToOpenCL

-- | Generate OpenCL host and device code.
kernelsToOpenCL :: Program -> Program

-- | Generate CUDA host and device code.
kernelsToCUDA :: Program -> Program

-- | Generate HIP host and device code.
kernelsToHIP :: Program -> Program
instance GHC.Classes.Eq Futhark.CodeGen.ImpGen.GPU.ToOpenCL.OpsMode

-- | C code generation for whole programs, built on
--   Futhark.CodeGen.Backends.GenericC.Monad. Most of this module is
--   concerned with constructing the C API.
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 => Text -> Text -> ParamMap -> Operations op () -> CompilerM op () () -> Text -> (Space, [Space]) -> [Option] -> Definitions op -> m CParts
compileProg' :: MonadFreshNames m => Text -> Text -> ParamMap -> Operations op s -> s -> CompilerM op s () -> Text -> (Space, [Space]) -> [Option] -> Definitions op -> m (CParts, CompilerState 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

-- | A mapping from names of tuning parameters to their class, as well as
--   which functions make use of them (including transitively).
type ParamMap = Map Name (SizeClass, Set Name)

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text

-- | Boilerplate for sequential C code.
module Futhark.CodeGen.Backends.SequentialC.Boilerplate

-- | Generate the necessary boilerplate.
generateBoilerplate :: CompilerM op s ()

-- | Boilerplate for multicore C code.
module Futhark.CodeGen.Backends.MulticoreC.Boilerplate

-- | Generate the necessary boilerplate.
generateBoilerplate :: CompilerM op s ()

module Futhark.CodeGen.Backends.GenericWASM

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text
type EntryPointType = String
data JSEntryPoint
JSEntryPoint :: String -> [EntryPointType] -> [EntryPointType] -> JSEntryPoint
[name] :: JSEntryPoint -> String
[parameters] :: JSEntryPoint -> [EntryPointType]
[ret] :: JSEntryPoint -> [EntryPointType]
emccExportNames :: [JSEntryPoint] -> [String]
javascriptWrapper :: [JSEntryPoint] -> Text
extToString :: ExternalValue -> String

-- | Javascript code that can be appended to the generated module to run a
--   Futhark server instance on startup.
runServer :: Text

-- | The names exported by the generated module.
libraryExports :: Text

-- | C code generation for GPU, in general.
--   
--   This module generates codes that targets the tiny GPU API abstraction
--   layer we define in the runtime system.
module Futhark.CodeGen.Backends.GPU
gpuOperations :: Operations OpenCL ()

-- | Options that are common to multiple GPU-like backends.
gpuOptions :: [Option]

-- | Called after most code has been generated to generate the bulk of the
--   boilerplate.
generateGPUBoilerplate :: Text -> [(Name, KernelConstExp)] -> Text -> [Name] -> [PrimType] -> [FailureMsg] -> CompilerM OpenCL () ()

module Futhark.Analysis.SymbolTable
data SymbolTable rep
empty :: SymbolTable rep
fromScope :: ASTRep rep => Scope rep -> SymbolTable rep
toScope :: SymbolTable rep -> Scope rep
data Entry rep
deepen :: SymbolTable rep -> SymbolTable rep

-- | For names that are tokens of an accumulator, this is the corresponding
--   combining function and neutral element.
entryAccInput :: Entry rep -> Maybe (WithAccInput rep)
entryDepth :: Entry rep -> Int
entryLetBoundDec :: Entry rep -> Maybe (LetDec rep)

-- | True if this name has been used as an array size, implying that it is
--   non-negative.
entryIsSize :: Entry rep -> Bool
entryStm :: Entry rep -> Maybe (Stm rep)
entryFParam :: Entry rep -> Maybe (FParamInfo rep)
entryLParam :: Entry rep -> Maybe (LParamInfo rep)

-- | You almost always want available instead of this one.
elem :: VName -> SymbolTable rep -> Bool
lookup :: VName -> SymbolTable rep -> Maybe (Entry rep)
lookupStm :: VName -> SymbolTable rep -> Maybe (Stm rep)
lookupExp :: VName -> SymbolTable rep -> Maybe (Exp rep, Certs)
lookupBasicOp :: VName -> SymbolTable rep -> Maybe (BasicOp, Certs)
lookupType :: ASTRep rep => VName -> SymbolTable rep -> Maybe Type
lookupSubExp :: VName -> SymbolTable rep -> Maybe (SubExp, Certs)
lookupAliases :: VName -> SymbolTable rep -> Names

-- | If the given variable name is the name of a ForLoop parameter,
--   then return the bound of that loop.
lookupLoopVar :: VName -> SymbolTable rep -> Maybe SubExp

-- | Look up the initial value and eventual result of a loop parameter.
--   Note that the result almost certainly refers to something that is not
--   part of the symbol table.
lookupLoopParam :: VName -> SymbolTable rep -> Maybe (SubExp, SubExp)

-- | Do these two names alias each other? This is expected to be a
--   commutative relationship, so the order of arguments does not matter.
aliases :: VName -> VName -> SymbolTable rep -> Bool

-- | In symbol table and not consumed.
available :: VName -> SymbolTable rep -> Bool

-- | Constant or available
subExpAvailable :: SubExp -> SymbolTable rep -> Bool
consume :: VName -> SymbolTable rep -> SymbolTable rep
index :: ASTRep rep => VName -> [SubExp] -> SymbolTable rep -> Maybe Indexed
index' :: VName -> [TPrimExp Int64 VName] -> SymbolTable rep -> 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 :: Certs -> PrimExp VName -> Indexed

-- | The indexing corresponds to another (perhaps more advantageous) array.
IndexedArray :: Certs -> VName -> [TPrimExp Int64 VName] -> Indexed
indexedAddCerts :: Certs -> Indexed -> Indexed
class IndexOp op
indexOp :: (IndexOp op, ASTRep rep, IndexOp (Op rep)) => SymbolTable rep -> Int -> op -> [TPrimExp Int64 VName] -> Maybe Indexed
insertStm :: (IndexOp (Op rep), Aliased rep) => Stm rep -> SymbolTable rep -> SymbolTable rep
insertStms :: (IndexOp (Op rep), Aliased rep) => Stms rep -> SymbolTable rep -> SymbolTable rep
insertFParams :: ASTRep rep => [FParam rep] -> SymbolTable rep -> SymbolTable rep
insertLParam :: ASTRep rep => LParam rep -> SymbolTable rep -> SymbolTable rep
insertLoopVar :: ASTRep rep => VName -> IntType -> SubExp -> SymbolTable rep -> SymbolTable rep

-- | 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 :: ASTRep rep => [(FParam rep, SubExp, SubExpRes)] -> SymbolTable rep -> SymbolTable rep

-- | Hide these definitions, if they are protected by certificates in the
--   set of names.
hideCertified :: Names -> SymbolTable rep -> SymbolTable rep

-- | Note that these names are tokens for the corresponding accumulators.
--   The names must already be present in the symbol table.
noteAccTokens :: [(VName, WithAccInput rep)] -> SymbolTable rep -> SymbolTable rep
instance forall k (rep :: k). Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.Rep.NoOp rep)
instance GHC.Base.Semigroup (Futhark.Analysis.SymbolTable.SymbolTable rep)
instance GHC.Base.Monoid (Futhark.Analysis.SymbolTable.SymbolTable rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Types.Typed (Futhark.Analysis.SymbolTable.Entry rep)
instance Futhark.IR.Prop.Names.FreeIn Futhark.Analysis.SymbolTable.Indexed

-- | Index simplification mechanics.
module Futhark.Optimise.Simplify.Rules.Index

-- | Some index expressions can be simplified to SubExps, while
--   others produce another index expression (which may be further
--   simplifiable).
data IndexResult
IndexResult :: Certs -> VName -> Slice SubExp -> IndexResult
SubExpResult :: Certs -> SubExp -> IndexResult

-- | Try to simplify an index operation.
simplifyIndexing :: MonadBuilder m => SymbolTable (Rep m) -> TypeLookup -> VName -> Slice SubExp -> Bool -> (VName -> Bool) -> Maybe (m IndexResult)

-- | 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 rep a
cannotSimplify :: RuleM rep a
liftMaybe :: Maybe a -> RuleM rep a

-- | An efficient way of encoding whether a simplification rule should even
--   be attempted.
data Rule rep

-- | Give it a shot.
Simplify :: RuleM rep () -> Rule rep

-- | Don't bother.
Skip :: Rule rep

-- | A simplification rule takes some argument and a statement, and tries
--   to simplify the statement.
data SimplificationRule rep a
RuleGeneric :: RuleGeneric rep a -> SimplificationRule rep a
RuleBasicOp :: RuleBasicOp rep a -> SimplificationRule rep a
RuleMatch :: RuleMatch rep a -> SimplificationRule rep a
RuleLoop :: RuleLoop rep a -> SimplificationRule rep a
RuleOp :: RuleOp rep a -> SimplificationRule rep a
type RuleGeneric rep a = a -> Stm rep -> Rule rep
type RuleBasicOp rep a = (a -> Pat (LetDec rep) -> StmAux (ExpDec rep) -> BasicOp -> Rule rep)
type RuleMatch rep a = a -> Pat (LetDec rep) -> StmAux (ExpDec rep) -> ([SubExp], [Case (Body rep)], Body rep, MatchDec (BranchType rep)) -> Rule rep
type RuleLoop rep a = a -> Pat (LetDec rep) -> StmAux (ExpDec rep) -> ([(FParam rep, SubExp)], LoopForm, Body rep) -> Rule rep

-- | Context for a rule applied during top-down traversal of the program.
--   Takes a symbol table as argument.
type TopDown rep = SymbolTable rep
type TopDownRule rep = SimplificationRule rep (TopDown rep)
type TopDownRuleGeneric rep = RuleGeneric rep (TopDown rep)
type TopDownRuleBasicOp rep = RuleBasicOp rep (TopDown rep)
type TopDownRuleMatch rep = RuleMatch rep (TopDown rep)
type TopDownRuleLoop rep = RuleLoop rep (TopDown rep)
type TopDownRuleOp rep = RuleOp rep (TopDown rep)

-- | Context for a rule applied during bottom-up traversal of the program.
--   Takes a symbol table and usage table as arguments.
type BottomUp rep = (SymbolTable rep, UsageTable)
type BottomUpRule rep = SimplificationRule rep (BottomUp rep)
type BottomUpRuleGeneric rep = RuleGeneric rep (BottomUp rep)
type BottomUpRuleBasicOp rep = RuleBasicOp rep (BottomUp rep)
type BottomUpRuleMatch rep = RuleMatch rep (BottomUp rep)
type BottomUpRuleLoop rep = RuleLoop rep (BottomUp rep)
type BottomUpRuleOp rep = RuleOp rep (BottomUp rep)

-- | A collection of both top-down and bottom-up rules.
data RuleBook rep

-- | Construct a rule book from a collection of rules.
ruleBook :: [TopDownRule m] -> [BottomUpRule m] -> RuleBook m

-- | simplifyStm lookup stm performs simplification of the binding
--   stm. 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 rep m, PrettyRep rep) => RuleBook rep -> SymbolTable rep -> Stm rep -> m (Maybe (Stms rep))

-- | simplifyStm uses stm performs simplification of the binding
--   stm. 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 rep m, PrettyRep rep) => RuleBook rep -> (SymbolTable rep, UsageTable) -> Stm rep -> m (Maybe (Stms rep))
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Scope.LocalScope rep (Futhark.Optimise.Simplify.Rule.RuleM rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Scope.HasScope rep (Futhark.Optimise.Simplify.Rule.RuleM rep)
instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Optimise.Simplify.Rule.RuleM rep)
instance GHC.Base.Monad (Futhark.Optimise.Simplify.Rule.RuleM rep)
instance GHC.Base.Applicative (Futhark.Optimise.Simplify.Rule.RuleM rep)
instance GHC.Base.Functor (Futhark.Optimise.Simplify.Rule.RuleM rep)
instance GHC.Base.Semigroup (Futhark.Optimise.Simplify.Rule.RuleBook rep)
instance GHC.Base.Monoid (Futhark.Optimise.Simplify.Rule.RuleBook rep)
instance GHC.Base.Semigroup (Futhark.Optimise.Simplify.Rule.Rules rep a)
instance GHC.Base.Monoid (Futhark.Optimise.Simplify.Rule.Rules rep a)
instance Futhark.Builder.BuilderOps rep => Futhark.Builder.Class.MonadBuilder (Futhark.Optimise.Simplify.Rule.RuleM rep)

-- | Match simplification rules.
module Futhark.Optimise.Simplify.Rules.Match
matchRules :: BuilderOps rep => RuleBook rep

-- | 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.Rules.ClosedForm

-- | foldClosedForm look foldfun accargs arrargs determines
--   whether each of the results of foldfun can be expressed in a
--   closed form.
foldClosedForm :: BuilderOps rep => VarLookup rep -> Pat (LetDec rep) -> Lambda rep -> [SubExp] -> [VName] -> RuleM rep ()

-- | loopClosedForm pat respat merge bound bodys determines
--   whether the do-loop can be expressed in a closed form.
loopClosedForm :: BuilderOps rep => Pat (LetDec rep) -> [(FParam rep, SubExp)] -> Names -> IntType -> SubExp -> Body rep -> RuleM rep ()

-- | Loop simplification rules.
module Futhark.Optimise.Simplify.Rules.Loop

-- | Standard loop simplification rules.
loopRules :: BuilderOps rep => RuleBook rep

-- | Some simplification rules for BasicOp.
module Futhark.Optimise.Simplify.Rules.BasicOp

-- | A set of simplification rules for BasicOps. Includes rules from
--   Futhark.Optimise.Simplify.Rules.Simple.
basicOpRules :: BuilderOps rep => RuleBook rep

-- | 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 :: (BuilderOps rep, TraverseOpStms rep) => RuleBook rep

-- | 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 :: BuilderOps rep => BottomUpRuleBasicOp rep

-- | Perform general rule-based simplification based on data dependency
--   information. This module will:
--   
--   
--   
- Perform common-subexpression elimination (CSE).
--   
- Hoist expressions out of loops (including lambdas) and branches.
--   This is done as aggressively as possible.
--   
- Apply simplification rules (see
--   Futhark.Optimise.Simplification.Rules).
--   
--   
--   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 rep a
runSimpleM :: SimpleM rep a -> SimpleOps rep -> Env rep -> VNameSource -> ((a, Bool), VNameSource)
data SimpleOps rep
SimpleOps :: (SymbolTable (Wise rep) -> Pat (LetDec (Wise rep)) -> Exp (Wise rep) -> SimpleM rep (ExpDec (Wise rep))) -> (SymbolTable (Wise rep) -> Stms (Wise rep) -> Result -> SimpleM rep (Body (Wise rep))) -> Protect (Builder (Wise rep)) -> (Op (Wise rep) -> UsageTable) -> SimplifyOp rep (Op (Wise rep)) -> SimpleOps rep
[mkExpDecS] :: SimpleOps rep -> SymbolTable (Wise rep) -> Pat (LetDec (Wise rep)) -> Exp (Wise rep) -> SimpleM rep (ExpDec (Wise rep))
[mkBodyS] :: SimpleOps rep -> SymbolTable (Wise rep) -> Stms (Wise rep) -> Result -> SimpleM rep (Body (Wise rep))

-- | 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 rep -> Protect (Builder (Wise rep))
[opUsageS] :: SimpleOps rep -> Op (Wise rep) -> UsageTable
[simplifyOpS] :: SimpleOps rep -> SimplifyOp rep (Op (Wise rep))
type SimplifyOp rep op = op -> SimpleM rep (op, Stms (Wise rep))
bindableSimpleOps :: (SimplifiableRep rep, Buildable rep) => SimplifyOp rep (Op (Wise rep)) -> SimpleOps rep
data Env rep
emptyEnv :: RuleBook (Wise rep) -> HoistBlockers rep -> Env rep
data HoistBlockers rep
HoistBlockers :: BlockPred (Wise rep) -> BlockPred (Wise rep) -> BlockPred (Wise rep) -> (Stm (Wise rep) -> Bool) -> HoistBlockers rep

-- | Blocker for hoisting out of parallel loops.
[blockHoistPar] :: HoistBlockers rep -> BlockPred (Wise rep)

-- | Blocker for hoisting out of sequential loops.
[blockHoistSeq] :: HoistBlockers rep -> BlockPred (Wise rep)

-- | Blocker for hoisting out of branches.
[blockHoistBranch] :: HoistBlockers rep -> BlockPred (Wise rep)
[isAllocation] :: HoistBlockers rep -> Stm (Wise rep) -> Bool
neverBlocks :: BlockPred rep
noExtraHoistBlockers :: HoistBlockers rep
neverHoist :: HoistBlockers rep
type BlockPred rep = SymbolTable rep -> UsageTable -> Stm rep -> Bool
orIf :: BlockPred rep -> BlockPred rep -> BlockPred rep
hasFree :: ASTRep rep => Names -> BlockPred rep
isConsumed :: BlockPred rep
isConsuming :: Aliased rep => BlockPred rep
isFalse :: Bool -> BlockPred rep
isOp :: BlockPred rep
isNotSafe :: ASTRep rep => BlockPred rep

-- | Statement is a scalar read from a single element array of rank one.
isDeviceMigrated :: SimplifiableRep rep => BlockPred (Wise rep)
asksEngineEnv :: (Env rep -> a) -> SimpleM rep a
askVtable :: SimpleM rep (SymbolTable (Wise rep))
localVtable :: (SymbolTable (Wise rep) -> SymbolTable (Wise rep)) -> SimpleM rep a -> SimpleM rep a
type SimplifiableRep rep = (ASTRep rep, Simplifiable (LetDec rep), Simplifiable (FParamInfo rep), Simplifiable (LParamInfo rep), Simplifiable (RetType rep), Simplifiable (BranchType rep), TraverseOpStms (Wise rep), CanBeWise (OpC rep), IndexOp (Op (Wise rep)), IsOp (OpC rep), ASTConstraints (OpC rep (Wise rep)), AliasedOp (OpC (Wise rep)), RephraseOp (OpC rep), BuilderOps (Wise rep), IsOp (OpC rep))
class Simplifiable e
simplify :: (Simplifiable e, SimplifiableRep rep) => e -> SimpleM rep e
simplifyFun :: SimplifiableRep rep => FunDef (Wise rep) -> SimpleM rep (FunDef (Wise rep))
simplifyStms :: SimplifiableRep rep => Stms (Wise rep) -> SimpleM rep (Stms (Wise rep))
simplifyStmsWithUsage :: SimplifiableRep rep => UsageTable -> Stms (Wise rep) -> SimpleM rep (Stms (Wise rep))
simplifyLambda :: SimplifiableRep rep => Names -> Lambda (Wise rep) -> SimpleM rep (Lambda (Wise rep), Stms (Wise rep))
simplifyLambdaNoHoisting :: SimplifiableRep rep => Lambda (Wise rep) -> SimpleM rep (Lambda (Wise rep))
bindLParams :: SimplifiableRep rep => [LParam (Wise rep)] -> SimpleM rep a -> SimpleM rep a

-- | Simplify a single body.
simplifyBody :: SimplifiableRep rep => BlockPred (Wise rep) -> UsageTable -> [Usages] -> Body (Wise rep) -> SimpleM rep (Stms (Wise rep), Body (Wise rep))
data SymbolTable rep
hoistStms :: SimplifiableRep rep => RuleBook (Wise rep) -> BlockPred (Wise rep) -> Stms (Wise rep) -> SimpleM rep (a, UsageTable) -> SimpleM rep (a, Stms (Wise rep), Stms (Wise rep))
blockIf :: SimplifiableRep rep => BlockPred (Wise rep) -> Stms (Wise rep) -> SimpleM rep (a, UsageTable) -> SimpleM rep (a, Stms (Wise rep), Stms (Wise rep))

-- | Block hoisting of Index statements introduced by migration.
blockMigrated :: SimplifiableRep rep => SimpleM rep (Lambda (Wise rep), Stms (Wise rep)) -> SimpleM rep (Lambda (Wise rep), Stms (Wise rep))

-- | Indicate in the symbol table that we have descended into a loop.
enterLoop :: SimpleM rep a -> SimpleM rep a
constructBody :: SimplifiableRep rep => Stms (Wise rep) -> Result -> SimpleM rep (Body (Wise rep))
instance forall k (rep :: k). Control.Monad.State.Class.MonadState (Futhark.FreshNames.VNameSource, GHC.Types.Bool, Futhark.IR.Syntax.Core.Certs) (Futhark.Optimise.Simplify.Engine.SimpleM rep)
instance forall k (rep :: k). Control.Monad.Reader.Class.MonadReader (Futhark.Optimise.Simplify.Engine.SimpleOps rep, Futhark.Optimise.Simplify.Engine.Env rep) (Futhark.Optimise.Simplify.Engine.SimpleM rep)
instance forall k (rep :: k). GHC.Base.Monad (Futhark.Optimise.Simplify.Engine.SimpleM rep)
instance forall k (rep :: k). GHC.Base.Functor (Futhark.Optimise.Simplify.Engine.SimpleM rep)
instance forall k (rep :: k). GHC.Base.Applicative (Futhark.Optimise.Simplify.Engine.SimpleM rep)
instance Futhark.Optimise.Simplify.Engine.SimplifiableRep rep => Futhark.IR.Prop.Scope.HasScope (Futhark.Optimise.Simplify.Rep.Wise rep) (Futhark.Optimise.Simplify.Engine.SimpleM rep)
instance Futhark.Optimise.Simplify.Engine.SimplifiableRep rep => Futhark.IR.Prop.Scope.LocalScope (Futhark.Optimise.Simplify.Rep.Wise rep) (Futhark.Optimise.Simplify.Engine.SimpleM rep)
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 Futhark.IR.Syntax.SubExpRes
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 Language.Futhark.Primitive.PrimType
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 d => Futhark.Optimise.Simplify.Engine.Simplifiable (Futhark.IR.Syntax.Core.Slice d)
instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.Syntax.Core.Certs
instance forall k (rep :: k). Futhark.MonadFreshNames.MonadFreshNames (Futhark.Optimise.Simplify.Engine.SimpleM rep)

-- | 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 :: SimplifiableRep rep => PrimExp VName -> SimpleM rep (PrimExp VName)

-- | Like simplifyPrimExp, but where leaves may be Exts.
simplifyExtPrimExp :: SimplifiableRep rep => PrimExp (Ext VName) -> SimpleM rep (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 :: SimplifiableRep rep => SimpleOps rep -> RuleBook (Wise rep) -> HoistBlockers rep -> Prog rep -> PassM (Prog rep)

-- | Run a simplification operation to convergence.
simplifySomething :: (MonadFreshNames m, SimplifiableRep rep) => (a -> SimpleM rep b) -> (b -> a) -> SimpleOps rep -> RuleBook (Wise rep) -> HoistBlockers rep -> SymbolTable (Wise rep) -> 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, SimplifiableRep rep) => SimpleOps rep -> RuleBook (Wise rep) -> HoistBlockers rep -> SymbolTable (Wise rep) -> FunDef rep -> m (FunDef rep)

-- | Simplify just a single Lambda.
simplifyLambda :: (MonadFreshNames m, HasScope rep m, SimplifiableRep rep) => SimpleOps rep -> RuleBook (Wise rep) -> HoistBlockers rep -> Lambda rep -> m (Lambda rep)

-- | Simplify a sequence of Stms.
simplifyStms :: (MonadFreshNames m, SimplifiableRep rep) => SimpleOps rep -> RuleBook (Wise rep) -> HoistBlockers rep -> Scope rep -> Stms rep -> m (Stms rep)
data SimpleOps rep
SimpleOps :: (SymbolTable (Wise rep) -> Pat (LetDec (Wise rep)) -> Exp (Wise rep) -> SimpleM rep (ExpDec (Wise rep))) -> (SymbolTable (Wise rep) -> Stms (Wise rep) -> Result -> SimpleM rep (Body (Wise rep))) -> Protect (Builder (Wise rep)) -> (Op (Wise rep) -> UsageTable) -> SimplifyOp rep (Op (Wise rep)) -> SimpleOps rep
[mkExpDecS] :: SimpleOps rep -> SymbolTable (Wise rep) -> Pat (LetDec (Wise rep)) -> Exp (Wise rep) -> SimpleM rep (ExpDec (Wise rep))
[mkBodyS] :: SimpleOps rep -> SymbolTable (Wise rep) -> Stms (Wise rep) -> Result -> SimpleM rep (Body (Wise rep))

-- | 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 rep -> Protect (Builder (Wise rep))
[opUsageS] :: SimpleOps rep -> Op (Wise rep) -> UsageTable
[simplifyOpS] :: SimpleOps rep -> SimplifyOp rep (Op (Wise rep))
data SimpleM rep a
type SimplifyOp rep op = op -> SimpleM rep (op, Stms (Wise rep))
bindableSimpleOps :: (SimplifiableRep rep, Buildable rep) => SimplifyOp rep (Op (Wise rep)) -> SimpleOps rep
noExtraHoistBlockers :: HoistBlockers rep
neverHoist :: HoistBlockers rep
type SimplifiableRep rep = (ASTRep rep, Simplifiable (LetDec rep), Simplifiable (FParamInfo rep), Simplifiable (LParamInfo rep), Simplifiable (RetType rep), Simplifiable (BranchType rep), TraverseOpStms (Wise rep), CanBeWise (OpC rep), IndexOp (Op (Wise rep)), IsOp (OpC rep), ASTConstraints (OpC rep (Wise rep)), AliasedOp (OpC (Wise rep)), RephraseOp (OpC rep), BuilderOps (Wise rep), IsOp (OpC rep))
data HoistBlockers rep

-- | A collection of both top-down and bottom-up rules.
data RuleBook rep

-- | 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 :: SimplifiableRep rep => SimpleOps rep -> Prog rep -> PassM (Prog rep)

-- | Run copy propagation on some statements.
copyPropagateInStms :: (MonadFreshNames m, SimplifiableRep rep) => SimpleOps rep -> Scope rep -> Stms rep -> m (Stms rep)

-- | Run copy propagation on a function.
copyPropagateInFun :: (MonadFreshNames m, SimplifiableRep rep) => SimpleOps rep -> SymbolTable (Wise rep) -> FunDef rep -> m (FunDef rep)

-- | 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.Rep.RepTypes Futhark.IR.Seq.Seq
instance Futhark.IR.Prop.ASTRep Futhark.IR.Seq.Seq
instance Futhark.IR.TypeCheck.Checkable Futhark.IR.Seq.Seq
instance Futhark.Builder.Class.Buildable Futhark.IR.Seq.Seq
instance Futhark.Builder.BuilderOps Futhark.IR.Seq.Seq
instance Futhark.IR.Traversals.TraverseOpStms Futhark.IR.Seq.Seq
instance Futhark.IR.Pretty.PrettyRep Futhark.IR.Seq.Seq
instance Futhark.Builder.BuilderOps (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.Seq.Seq)
instance Futhark.IR.Traversals.TraverseOpStms (Futhark.Optimise.Simplify.Rep.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 rep
Stream :: SubExp -> [VName] -> [SubExp] -> Lambda rep -> SOAC rep

-- | 
--   Scatter length inputs lambda spec
--   
--   
--   Scatter maps values from a set of input arrays to indices and values
--   of a set of output arrays. It is able to write multiple values to
--   multiple outputs each of which may have multiple dimensions.
--   
--   inputs is a list of input arrays, all having size
--   length, elements of which are applied to the lambda
--   function. For instance, if there are two arrays, lambda will
--   get two values as input, one from each array.
--   
--   spec specifies the result of the lambda and which arrays
--   to write to.
--   
--   lambda is a function that takes inputs from inputs and
--   returns values according to spec. It returns values in the
--   following manner:
--   
--   
--   
- index_0, index_1, ..., index_n, value_0, value_1, ...,
--   value_m
--   
--   
--   For each output in spec, lambda returns i *
--   j index values and j output values, where i is
--   the number of dimensions (rank) of the given output, and j is
--   the number of output values written to the given output.
--   
--   For example, given the following scatter specification:
--   
--   
--   
- ([x1, y1, z1 , 2, arr1), ([x2, y2], 1, arr2)]
--   
--   
--   lambda will produce 6 (3 * 2) index values and 2 output values
--   for arr1, and 2 (2 * 1) index values and 1 output value for
--   arr2. Additionally, the results are grouped, so the first 6 index
--   values will correspond to the first two output values, and so on. For
--   this example, lambda should return a total of 11 values, 8
--   index values and 3 output values. See also splitScatterResults.
Scatter :: SubExp -> [VName] -> ScatterSpec VName -> Lambda rep -> SOAC rep

-- | 
--   Hist length arrays dest-arrays-and-ops fun
--   
--   
--   The final lambda produces indexes and values for the HistOps.
Hist :: SubExp -> [VName] -> [HistOp rep] -> Lambda rep -> SOAC rep
JVP :: [SubExp] -> [SubExp] -> Lambda rep -> SOAC rep
VJP :: [SubExp] -> [SubExp] -> Lambda rep -> SOAC rep

-- | A combination of scan, reduction, and map. The first SubExp is
--   the size of the input arrays.
Screma :: SubExp -> [VName] -> ScremaForm rep -> SOAC rep

-- | The essential parts of a Screma factored out (everything except
--   the input arrays).
data ScremaForm rep
ScremaForm :: Lambda rep -> [Scan rep] -> [Reduce rep] -> ScremaForm rep

-- | The "main" lambda of the Screma. For a map, this is equivalent to
--   isMapSOAC. Note that the meaning of the return value of this
--   lambda depends crucially on exactly which Screma this is. The
--   parameters will correspond exactly to elements of the input arrays,
--   however.
[scremaLambda] :: ScremaForm rep -> Lambda rep
[scremaScans] :: ScremaForm rep -> [Scan rep]
[scremaReduces] :: ScremaForm rep -> [Reduce rep]

-- | How the results of a scatter operation should be written. Each element
--   of the list consists of a v (often a VName) specifying
--   which array to scatter to, a ShapeBase describing the shape of
--   that array, and an Int describing how many elements should be
--   written to that array for each invocation of the scatter.
type ScatterSpec v = [(Shape, Int, v)]

-- | Information about computing a single histogram.
data HistOp rep
HistOp :: Shape -> SubExp -> [VName] -> [SubExp] -> Lambda rep -> HistOp rep
[histShape] :: HistOp rep -> Shape

-- | Race factor RF means that only 1/RF bins are used.
[histRaceFactor] :: HistOp rep -> SubExp
[histDest] :: HistOp rep -> [VName]
[histNeutral] :: HistOp rep -> [SubExp]
[histOp] :: HistOp rep -> Lambda rep

-- | How to compute a single scan result.
data Scan rep
Scan :: Lambda rep -> [SubExp] -> Scan rep
[scanLambda] :: Scan rep -> Lambda rep
[scanNeutral] :: Scan rep -> [SubExp]

-- | How many reduction results are produced by these Scans?
scanResults :: [Scan rep] -> Int

-- | Combine multiple scan operators to a single operator.
singleScan :: Buildable rep => [Scan rep] -> Scan rep

-- | How to compute a single reduction result.
data Reduce rep
Reduce :: Commutativity -> Lambda rep -> [SubExp] -> Reduce rep
[redComm] :: Reduce rep -> Commutativity
[redLambda] :: Reduce rep -> Lambda rep
[redNeutral] :: Reduce rep -> [SubExp]

-- | How many reduction results are produced by these Reduces?
redResults :: [Reduce rep] -> Int

-- | Combine multiple reduction operators to a single operator.
singleReduce :: Buildable rep => [Reduce rep] -> Reduce rep

-- | The types produced by a single Screma, given the size of the
--   input array.
scremaType :: SubExp -> ScremaForm rep -> [Type]

-- | The type of a SOAC.
soacType :: Typed (LParamInfo rep) => SOAC rep -> [Type]

-- | Type-check a SOAC.
typeCheckSOAC :: Checkable rep => SOAC (Aliases rep) -> TypeM rep ()

-- | Construct a lambda that takes parameters of the given types and simply
--   returns them unchanged.
mkIdentityLambda :: (Buildable rep, MonadFreshNames m) => [Type] -> m (Lambda rep)

-- | Is the given lambda an identity lambda?
isIdentityLambda :: Lambda rep -> Bool

-- | A lambda with no parameters that returns no values.
nilFn :: Buildable rep => Lambda rep

-- | Construct a Screma with possibly multiple scans, and the given map
--   function.
scanomapSOAC :: [Scan rep] -> Lambda rep -> ScremaForm rep

-- | Construct a Screma with possibly multiple reductions, and the given
--   map function.
redomapSOAC :: [Reduce rep] -> Lambda rep -> ScremaForm rep

-- | Construct a Screma with possibly multiple scans, and identity map
--   function.
scanSOAC :: (Buildable rep, MonadFreshNames m) => [Scan rep] -> m (ScremaForm rep)

-- | Construct a Screma with possibly multiple reductions, and identity map
--   function.
reduceSOAC :: (Buildable rep, MonadFreshNames m) => [Reduce rep] -> m (ScremaForm rep)

-- | Construct a Screma corresponding to a map.
mapSOAC :: Lambda rep -> ScremaForm rep

-- | Does this Screma correspond to a scan-map composition?
isScanomapSOAC :: ScremaForm rep -> Maybe ([Scan rep], Lambda rep)

-- | Does this Screma correspond to a reduce-map composition?
isRedomapSOAC :: ScremaForm rep -> Maybe ([Reduce rep], Lambda rep)

-- | Does this Screma correspond to pure scan?
isScanSOAC :: ScremaForm rep -> Maybe [Scan rep]

-- | Does this Screma correspond to a pure reduce?
isReduceSOAC :: ScremaForm rep -> Maybe [Reduce rep]

-- | Does this Screma correspond to a simple map, without any reduction or
--   scan results?
isMapSOAC :: ScremaForm rep -> Maybe (Lambda rep)

-- | Prettyprint the given Screma.
ppScrema :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> ScremaForm rep -> Doc ann

-- | Prettyprint the given histogram operation.
ppHist :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> [HistOp rep] -> Lambda rep -> Doc ann

-- | Prettyprint the given Stream.
ppStream :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> [SubExp] -> Lambda rep -> Doc ann

-- | Prettyprint the given Scatter.
ppScatter :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> [(Shape, Int, VName)] -> Lambda rep -> Doc ann

-- | 
--   groupScatterResults specification results
--   
--   
--   Blocks the index values and result values of results according
--   to the specification.
--   
--   This function is used for extracting and grouping the results of a
--   scatter. In the SOACS representation, the lambda inside a
--   Scatter returns all indices and values as one big list. This
--   function groups each value with its corresponding indices (as
--   determined by the Shape of the output array).
--   
--   The elements of the resulting list correspond to the shape and name of
--   the output parameters, in addition to a list of values written to that
--   output parameter, along with the array indices marking where to write
--   them to.
--   
--   See Scatter for more information.
groupScatterResults :: ScatterSpec array -> [a] -> [(Shape, array, [([a], a)])]

-- | 
--   groupScatterResults' specification results
--   
--   
--   Blocks the index values and result values of results according
--   to the specification. This is the simpler version of
--   groupScatterResults, which doesn't return any information
--   about shapes or output arrays.
--   
--   See groupScatterResults for more information,
groupScatterResults' :: [(Shape, Int, array)] -> [a] -> [([a], a)]

-- | 
--   splitScatterResults specification results
--   
--   
--   Splits the results array into indices and values according to the
--   specification.
--   
--   See groupScatterResults for more information.
splitScatterResults :: [(Shape, Int, array)] -> [a] -> ([a], [a])

-- | Like Mapper, but just for SOACs.
data SOACMapper frep trep m
SOACMapper :: (SubExp -> m SubExp) -> (Lambda frep -> m (Lambda trep)) -> (VName -> m VName) -> SOACMapper frep trep m
[mapOnSOACSubExp] :: SOACMapper frep trep m -> SubExp -> m SubExp
[mapOnSOACLambda] :: SOACMapper frep trep m -> Lambda frep -> m (Lambda trep)
[mapOnSOACVName] :: SOACMapper frep trep m -> VName -> m VName

-- | A mapper that simply returns the SOAC verbatim.
identitySOACMapper :: forall rep m. Monad m => SOACMapper rep rep 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 :: Monad m => SOACMapper frep trep m -> SOAC frep -> m (SOAC trep)

-- | A helper for defining TraverseOpStms.
traverseSOACStms :: Monad m => OpStmsTraverser m (SOAC rep) rep
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.SOACS.SOAC.HistOp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.HistOp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.HistOp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.SOACS.SOAC.Scan rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.Scan rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.Scan rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.SOACS.SOAC.Reduce rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.Reduce rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.Reduce rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.SOACS.SOAC.ScremaForm rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.ScremaForm rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.ScremaForm rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.SOACS.SOAC.SOAC rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.SOACS.SOAC.SOAC rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.SOACS.SOAC.SOAC rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SOACS.SOAC.SOAC rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.Transform.Substitute.Substitute (Futhark.IR.SOACS.SOAC.SOAC rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.Transform.Rename.Rename (Futhark.IR.SOACS.SOAC.SOAC rep)
instance Futhark.Optimise.Simplify.Rep.CanBeWise Futhark.IR.SOACS.SOAC.SOAC
instance Futhark.IR.Prop.TypeOf.TypedOp Futhark.IR.SOACS.SOAC.SOAC
instance Futhark.IR.Prop.Aliases.AliasedOp Futhark.IR.SOACS.SOAC.SOAC
instance Futhark.IR.Aliases.CanBeAliased Futhark.IR.SOACS.SOAC.SOAC
instance Futhark.IR.Prop.IsOp Futhark.IR.SOACS.SOAC.SOAC
instance Futhark.IR.Rep.RepTypes rep => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.SOACS.SOAC.SOAC rep)
instance Futhark.IR.Rephrase.RephraseOp Futhark.IR.SOACS.SOAC.SOAC
instance Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Rep.Op rep) => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.SOACS.SOAC.SOAC rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.SOACS.SOAC.SOAC rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SOACS.SOAC.ScremaForm rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SOACS.SOAC.Reduce rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.SOACS.SOAC.Reduce rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SOACS.SOAC.Scan rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.SOACS.SOAC.Scan rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SOACS.SOAC.HistOp rep)

-- | 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.
redomapToMapAndReduce :: (MonadFreshNames m, Buildable rep, ExpDec rep ~ (), Op rep ~ SOAC rep) => Pat (LetDec rep) -> (SubExp, [Reduce rep], Lambda rep, [VName]) -> m (Stm rep, Stm rep)
scanomapToMapAndScan :: (MonadFreshNames m, Buildable rep, ExpDec rep ~ (), Op rep ~ SOAC rep) => Pat (LetDec rep) -> (SubExp, [Scan rep], Lambda rep, [VName]) -> m (Stm rep, Stm rep)

-- | 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 :: (MonadBuilder m, Op (Rep m) ~ SOAC (Rep m), Buildable (Rep m)) => Pat (LetDec (Rep m)) -> SubExp -> ScremaForm (Rep m) -> [VName] -> m ()

-- | Turn a stream SOAC into statements that apply the stream lambda to the
--   entire input.
sequentialStreamWholeArray :: (MonadBuilder m, Buildable (Rep m)) => Pat (LetDec (Rep m)) -> SubExp -> [SubExp] -> Lambda (Rep 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 rep for the basic representation.
data SOACS
usesAD :: Prog SOACS -> Bool
instance Futhark.IR.Rep.RepTypes Futhark.IR.SOACS.SOACS
instance Futhark.IR.Prop.ASTRep Futhark.IR.SOACS.SOACS
instance Futhark.IR.TypeCheck.Checkable Futhark.IR.SOACS.SOACS
instance Futhark.Builder.Class.Buildable Futhark.IR.SOACS.SOACS
instance Futhark.Builder.BuilderOps Futhark.IR.SOACS.SOACS
instance Futhark.IR.Pretty.PrettyRep 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, FirstOrderRep torep) => Scope torep -> FunDef SOACS -> m (FunDef torep)

-- | First-order-transform these top-level constants.
transformConsts :: (MonadFreshNames m, FirstOrderRep torep) => Stms SOACS -> m (Stms torep)

-- | The constraints that must hold for a rep in order to be the target of
--   first-order transformation.
type FirstOrderRep rep = (Buildable rep, BuilderOps rep, LetDec SOACS ~ LetDec rep, LParamInfo SOACS ~ LParamInfo rep, AliasableRep rep)

-- | The constraints that a monad must uphold in order to be used for
--   first-order transformation.
type Transformer m = (MonadBuilder m, LocalScope (Rep m) m, Buildable (Rep m), BuilderOps (Rep m), LParamInfo SOACS ~ LParamInfo (Rep m), AliasableRep (Rep m))

-- | First transform any nested Body or Lambda elements, then
--   apply transformSOAC if the expression is a SOAC.
transformStmRecursively :: (Transformer m, LetDec (Rep m) ~ LetDec SOACS) => Stm SOACS -> m ()

-- | Recursively first-order-transform a lambda.
transformLambda :: (MonadFreshNames m, Buildable rep, BuilderOps rep, LocalScope somerep m, SameScope somerep rep, LetDec rep ~ LetDec SOACS, AliasableRep rep) => Lambda SOACS -> m (Lambda rep)

-- | 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 rep.
transformSOAC :: Transformer m => Pat (LetDec (Rep m)) -> SOAC (Rep 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 :: FirstOrderRep rep => Pass SOACS rep

-- | 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 :: (MonadBuilder m, Rep m ~ SOACS) => Pat Type -> SubExp -> Lambda SOACS -> [(SubExp, VName)] -> Maybe (m ())

-- | Interchange Reduce With Inner Map. Tries to turn a
--   reduce(map) into a @map(reduce)
irwim :: (MonadBuilder m, Rep m ~ SOACS) => Pat Type -> SubExp -> Commutativity -> Lambda SOACS -> [(SubExp, VName)] -> Maybe (m ())

-- | Does this reduce operator contain an inner map, and if so, what does
--   that map look like?
rwimPossible :: Lambda SOACS -> Maybe (Pat Type, Certs, SubExp, Lambda SOACS)

module Futhark.Internalise.Monad
data InternaliseM a
runInternaliseM :: MonadFreshNames m => Bool -> InternaliseM () -> m (OpaqueTypes, 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 VarSubsts = Map VName [SubExp]
data InternaliseEnv
InternaliseEnv :: VarSubsts -> Bool -> Bool -> Attrs -> InternaliseEnv
[envSubsts] :: InternaliseEnv -> VarSubsts
[envDoBoundsChecks] :: InternaliseEnv -> Bool
[envSafe] :: InternaliseEnv -> Bool
[envAttrs] :: InternaliseEnv -> Attrs
type FunInfo = ([VName], [DeclType], [FParam SOACS], [(SubExp, Type)] -> Maybe [(DeclExtType, RetAls)])
substitutingVars :: VarSubsts -> InternaliseM a -> InternaliseM a
lookupSubst :: VName -> InternaliseM (Maybe [SubExp])

-- | Add opaque types. If the types are already known, they will not be
--   added.
addOpaques :: OpaqueTypes -> InternaliseM ()

-- | Add a function definition to the program being constructed.
addFunDef :: FunDef SOACS -> InternaliseM ()
lookupFunction :: VName -> InternaliseM FunInfo
lookupConst :: VName -> InternaliseM (Maybe [SubExp])
bindFunction :: VName -> FunDef SOACS -> FunInfo -> InternaliseM ()
bindConstant :: VName -> FunDef SOACS -> InternaliseM ()

-- | 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 Certs
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.IR.Prop.Scope.LocalScope Futhark.IR.SOACS.SOACS Futhark.Internalise.Monad.InternaliseM
instance Futhark.Builder.Class.MonadBuilder Futhark.Internalise.Monad.InternaliseM
instance Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.State.Lazy.State Futhark.Internalise.Monad.InternaliseState)

module Futhark.Internalise.AccurateSizes
argShapes :: [VName] -> [FParam SOACS] -> [Type] -> InternaliseM [SubExp]
ensureResultShape :: ErrorMsg SubExp -> SrcLoc -> [Type] -> Result -> InternaliseM Result
ensureResultExtShape :: ErrorMsg SubExp -> SrcLoc -> [ExtType] -> Result -> InternaliseM Result
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 SOACS -> m (Lambda SOACS)
simplifyFun :: MonadFreshNames m => SymbolTable (Wise SOACS) -> FunDef SOACS -> m (FunDef SOACS)
simplifyStms :: (HasScope SOACS m, MonadFreshNames m) => Stms SOACS -> m (Stms SOACS)
simplifyConsts :: MonadFreshNames m => Stms SOACS -> m (Stms SOACS)
simpleSOACS :: SimpleOps SOACS
simplifySOAC :: SimplifiableRep rep => SimplifyOp rep (SOAC (Wise rep))
soacRules :: RuleBook (Wise SOACS)

-- | Does this rep contain SOACs in its Ops? A rep must be an
--   instance of this class for the simplification rules to work.
class HasSOAC rep
asSOAC :: HasSOAC rep => Op rep -> Maybe (SOAC rep)
soacOp :: HasSOAC rep => SOAC rep -> Op rep
simplifyKnownIterationSOAC :: (Buildable rep, BuilderOps rep, HasSOAC rep) => TopDownRuleOp rep

-- | Remove all arguments to the map that are simply replicates. These can
--   be turned into free variables instead.
removeReplicateMapping :: (Aliased rep, BuilderOps rep, HasSOAC rep) => TopDownRuleOp rep

-- | Remove inputs that are not used inside the SOAC.
removeUnusedSOACInput :: forall rep. (Aliased rep, Buildable rep, BuilderOps rep, HasSOAC rep) => TopDownRuleOp rep
liftIdentityMapping :: forall rep. (Buildable rep, BuilderOps rep, HasSOAC rep) => TopDownRuleOp rep
simplifyMapIota :: forall rep. (Buildable rep, BuilderOps rep, HasSOAC rep) => TopDownRuleOp rep

-- | The rep 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.Rep.Wise Futhark.IR.SOACS.SOACS)
instance Futhark.Builder.BuilderOps (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.SOACS.SOACS)
instance Futhark.IR.Traversals.TraverseOpStms (Futhark.Optimise.Simplify.Rep.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 record 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

-- | Produce a mapping of the number of occurences in the call graph of
--   each function. Only counts functions that are called at least once.
numOccurences :: CallGraph -> Map Name Int
instance GHC.Show.Show Futhark.Analysis.CallGraph.FunCalls
instance GHC.Classes.Ord Futhark.Analysis.CallGraph.FunCalls
instance GHC.Classes.Eq Futhark.Analysis.CallGraph.FunCalls
instance GHC.Show.Show Futhark.Analysis.CallGraph.CallGraph
instance GHC.Classes.Ord Futhark.Analysis.CallGraph.CallGraph
instance GHC.Classes.Eq Futhark.Analysis.CallGraph.CallGraph
instance Prettyprinter.Internal.Pretty Futhark.Analysis.CallGraph.CallGraph
instance GHC.Base.Monoid Futhark.Analysis.CallGraph.FunCalls
instance GHC.Base.Semigroup Futhark.Analysis.CallGraph.FunCalls
instance Prettyprinter.Internal.Pretty Futhark.Analysis.CallGraph.FunCalls

-- | 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 rep
Stream :: SubExp -> [Input] -> [SubExp] -> Lambda rep -> SOAC rep
Scatter :: SubExp -> [Input] -> ScatterSpec VName -> Lambda rep -> SOAC rep
Screma :: SubExp -> [Input] -> ScremaForm rep -> SOAC rep
Hist :: SubExp -> [Input] -> [HistOp rep] -> Lambda rep -> SOAC rep

-- | The essential parts of a Screma factored out (everything except
--   the input arrays).
data ScremaForm rep
ScremaForm :: Lambda rep -> [Scan rep] -> [Reduce rep] -> ScremaForm rep

-- | The "main" lambda of the Screma. For a map, this is equivalent to
--   isMapSOAC. Note that the meaning of the return value of this
--   lambda depends crucially on exactly which Screma this is. The
--   parameters will correspond exactly to elements of the input arrays,
--   however.
[scremaLambda] :: ScremaForm rep -> Lambda rep
[scremaScans] :: ScremaForm rep -> [Scan rep]
[scremaReduces] :: ScremaForm rep -> [Reduce rep]

-- | Returns the inputs used in a SOAC.
inputs :: SOAC rep -> [Input]

-- | Set the inputs to a SOAC.
setInputs :: [Input] -> SOAC rep -> SOAC rep

-- | The lambda used in a given SOAC.
lambda :: SOAC rep -> Lambda rep

-- | Set the lambda used in the SOAC.
setLambda :: Lambda rep -> SOAC rep -> SOAC rep

-- | The return type of a SOAC.
typeOf :: SOAC rep -> [Type]

-- | The "width" of a SOAC is the expected outer size of its array inputs
--   _after_ input-transforms have been carried out.
width :: SOAC rep -> 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 rep ~ SOAC rep, HasScope rep m) => Exp rep -> m (Either NotSOAC (SOAC rep))

-- | Convert a SOAC to the corresponding expression.
toExp :: (MonadBuilder m, Op (Rep m) ~ SOAC (Rep m)) => SOAC (Rep m) -> m (Exp (Rep m))

-- | Convert a SOAC to a Futhark-level SOAC.
toSOAC :: MonadBuilder m => SOAC (Rep m) -> m (SOAC (Rep 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

-- | The transformations applied to an input.
inputTransforms :: Input -> ArrayTransforms

-- | 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
applyTransforms :: MonadBuilder m => ArrayTransforms -> VName -> m VName

-- | 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 :: Certs -> [Int] -> ArrayTransform

-- | A reshaping of an otherwise valid input.
Reshape :: Certs -> ReshapeKind -> Shape -> ArrayTransform

-- | A reshaping of the outer dimension.
ReshapeOuter :: Certs -> ReshapeKind -> Shape -> ArrayTransform

-- | A reshaping of everything but the outer dimension.
ReshapeInner :: Certs -> ReshapeKind -> Shape -> ArrayTransform

-- | Replicate the rows of the array a number of times.
Replicate :: Certs -> Shape -> ArrayTransform

-- | An array indexing operation.
Index :: Certs -> Slice SubExp -> 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 :: Certs -> Exp rep -> Maybe (VName, ArrayTransform)

-- | Turn an array transform on an array back into an expression.
transformToExp :: (Monad m, HasScope rep m) => ArrayTransform -> VName -> m (Certs, Exp rep)

-- | To-Stream translation of SOACs. Returns the Stream SOAC and the
--   extra-accumulator body-result ident if any.
soacToStream :: (HasScope rep m, MonadFreshNames m, Buildable rep, BuilderOps rep, Op rep ~ SOAC rep) => SOAC rep -> m (SOAC rep, [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.Rep.RepTypes rep => GHC.Show.Show (Futhark.Analysis.HORep.SOAC.SOAC rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.Analysis.HORep.SOAC.SOAC rep)
instance GHC.Show.Show Futhark.Analysis.HORep.SOAC.NotSOAC
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.Analysis.HORep.SOAC.SOAC rep)
instance Futhark.Transform.Substitute.Substitute Futhark.Analysis.HORep.SOAC.Input
instance Prettyprinter.Internal.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
instance Prettyprinter.Internal.Pretty Futhark.Analysis.HORep.SOAC.ArrayTransform

-- | A graph representation of a sequence of Futhark statements (i.e. a
--   Body), built to handle fusion. Could perhaps be made more
--   general. An important property is that it does not handle "nested
--   bodies" (e.g. Match); these are represented as single nodes.
--   
--   This is all implemented on top of the graph representation provided by
--   the fgl package (Data.Graph.Inductive). The graph
--   provided by this package allows nodes and edges to have
--   arbitrarily-typed "labels". It is these labels (EdgeT,
--   NodeT) that we use to contain Futhark-specific information. An
--   edge goes *from* consumers to producers. There are also edges that do
--   not represent normal data dependencies, but other things. This means
--   that a node can have multiple edges for the same name, indicating
--   different kinds of dependencies.
module Futhark.Optimise.Fusion.GraphRep

-- | Information associated with an edge in the graph.
data EdgeT
Alias :: VName -> EdgeT
InfDep :: VName -> EdgeT
Dep :: VName -> EdgeT
Cons :: VName -> EdgeT
Fake :: VName -> EdgeT
Res :: VName -> EdgeT

-- | Information associated with a node in the graph.
data NodeT
StmNode :: Stm SOACS -> NodeT
SoacNode :: ArrayTransforms -> Pat Type -> SOAC SOACS -> StmAux (ExpDec SOACS) -> NodeT

-- | First VName is result; last is input.
TransNode :: VName -> ArrayTransform -> VName -> NodeT

-- | Node corresponding to a result of the entire computation (i.e. the
--   Result of a body). Any node that is not transitively reachable
--   from one of these can be considered dead.
ResNode :: VName -> NodeT

-- | Node corresponding to a free variable. These are used to safely handle
--   consumption, which also means we don't have to create a node for every
--   free single variable.
FreeNode :: VName -> NodeT
MatchNode :: Stm SOACS -> [(NodeT, [EdgeT])] -> NodeT
DoNode :: Stm SOACS -> [(NodeT, [EdgeT])] -> NodeT

-- | A tuple with four parts: inbound links to the node, the node itself,
--   the NodeT "label", and outbound links from the node. This type
--   is used to modify the graph in mapAcross.
type DepContext = Context NodeT EdgeT

-- | A "graph augmentation" is a monadic action that modifies the graph.
type DepGraphAug m = DepGraph -> m DepGraph

-- | A dependency graph. Edges go from *consumers* to *producers* (i.e.
--   from usage to definition). That means the incoming edges of a node are
--   the dependents of that node, and the outgoing edges are the
--   dependencies of that node.
data DepGraph
DepGraph :: Gr NodeT EdgeT -> ProducerMapping -> AliasTable -> DepGraph
[dgGraph] :: DepGraph -> Gr NodeT EdgeT
[dgProducerMapping] :: DepGraph -> ProducerMapping

-- | A table mapping VNames to VNames that are aliased to it.
[dgAliasTable] :: DepGraph -> AliasTable

-- | A pair of a Node and the node label.
type DepNode = LNode NodeT

-- | The name that this edge depends on.
getName :: EdgeT -> VName

-- | Get the underlying fgl node.
nodeFromLNode :: DepNode -> Node

-- | Merges two contexts.
mergedContext :: Ord b => a -> Context a b -> Context a b -> Context a b

-- | Monadically modify every node of the graph.
mapAcross :: Monad m => (DepContext -> m DepContext) -> DepGraphAug m

-- | Find all the edges connecting the two nodes.
edgesBetween :: DepGraph -> Node -> Node -> [DepEdge]

-- | reachable dg from to is true if to is reachable from
--   from.
reachable :: DepGraph -> Node -> Node -> Bool

-- | Apply several graph augmentations in sequence.
applyAugs :: Monad m => [DepGraphAug m] -> DepGraphAug m

-- | Get the variable name that this edge refers to.
depsFromEdge :: DepEdge -> VName

-- | Remove the given node, and insert the DepContext into the
--   graph, replacing any existing information about the node contained in
--   the DepContext.
contractEdge :: Monad m => Node -> DepContext -> DepGraphAug m

-- | Does the node acutally represent something in the program? A
--   "non-real" node represents things like fake nodes inserted to express
--   ordering due to consumption.
isRealNode :: NodeT -> Bool

-- | Is this a Cons edge?
isCons :: EdgeT -> Bool

-- | Is there a possibility of fusion?
isDep :: EdgeT -> Bool

-- | Is this an infusible edge?
isInf :: (Node, Node, EdgeT) -> Bool

-- | Make a dependency graph corresponding to a Body.
mkDepGraph :: (HasScope SOACS m, Monad m) => Body SOACS -> m DepGraph

-- | Make a dependency graph corresponding to a function.
mkDepGraphForFun :: FunDef SOACS -> DepGraph

-- | Prettyprint dependency graph.
pprg :: DepGraph -> String

-- | Is this a withAcc?
isWithAccNodeT :: NodeT -> Bool
isWithAccNodeId :: Node -> DepGraph -> Bool
vFusionFeasability :: DepGraph -> Node -> Node -> Bool
hFusionFeasability :: DepGraph -> Node -> Node -> Bool
instance GHC.Classes.Ord Futhark.Optimise.Fusion.GraphRep.EdgeT
instance GHC.Classes.Eq Futhark.Optimise.Fusion.GraphRep.EdgeT
instance GHC.Classes.Eq Futhark.Optimise.Fusion.GraphRep.NodeT
instance GHC.Show.Show Futhark.Optimise.Fusion.GraphRep.Classification
instance GHC.Classes.Ord Futhark.Optimise.Fusion.GraphRep.Classification
instance GHC.Classes.Eq Futhark.Optimise.Fusion.GraphRep.Classification
instance GHC.Show.Show Futhark.Optimise.Fusion.GraphRep.NodeT
instance GHC.Show.Show Futhark.Optimise.Fusion.GraphRep.EdgeT

-- | This module consists of rules for fusion that involves WithAcc
--   constructs. Currently, we support two non-trivial transformations: I.
--   map-flatten-scatter: a map nest produces multi-dimensional index and
--   values arrays that are then flattened and used in a scatter consumer.
--   Such pattern can be fused by re-writing the scatter by means of a
--   WithAcc containing a map-nest, thus eliminating the flatten
--   operations. The obtained WithAcc can then be fused with the producer
--   map nest, e.g., benefiting intra-group kernels. The eloquent target
--   for this rule is an efficient implementation of radix-sort.
--   
--   II. WithAcc-WithAcc fusion: two withaccs can be fused as long as the
--   common accumulators use the same operator, and as long as the
--   non-accumulator input of an WithAcc is not used as an accumulator in
--   the other. This fusion opens the door for fusing the SOACs appearing
--   inside the WithAccs. This is also intended to demonstrate that it is
--   not so important where exactly the WithAccs were originally introduced
--   in the code, it is more important that they can be transformed by
--   various optimizations passes.
module Futhark.Optimise.Fusion.RulesWithAccs

-- | Implements a specialized rule for fusing a pattern formed by a map o
--   flatten o scatter, i.e., let (inds, vals) = map-nest f inps (finds,
--   fvals) = (flatten inds, flatten vals) let res = scatter res0 finds
--   fvals where inds & vals have higher rank than finds & fvals.
ruleMFScat :: (HasScope SOACS m, MonadFreshNames m) => DepNode -> DepGraph -> m (Maybe DepGraph)

-- | Simple case for fusing two withAccs (can be extended): let (b1, ...,
--   bm, x1, ..., xq) = withAcc a1 ... am lam1 let (d1, ..., dn, y1, ...,
--   yp) = withAcc c1 ... cn lam2 Notation: `b1 ... bm` are the accumulator
--   results of the first withAcc and `d1, ..., dn` of the second withAcc.
--   `x1 ... xq` and `y1, ..., yp` are non-accumulator results.
--   Conservative conditions: 1. for any bi (i=1..m) either `bi IN {c1,
--   ..., cm}` OR `bi NOT-IN FV(lam2)`, i.e., perfect producer-consumer
--   relation on accums. Of course the binary-op should be the same. 2. The
--   bs that are also accumulated upon in lam2 do NOT belong to
--   the infusible set (they are destroyed) 3. x1 ... xq do not
--   overlap with c1 ... cn Fusion will create one withacc that accumulates
--   on the union of `a1 ... am` and `c1 ... cn` and returns, in addition
--   to the accumulator arrays the union of regular variables `x1 ... xq`
--   and `y1, ..., yp`
tryFuseWithAccs :: (HasScope SOACS m, MonadFreshNames m) => [VName] -> Stm SOACS -> Stm SOACS -> m (Maybe (Stm SOACS))

-- | 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 :: Buildable rep => Names -> Lambda rep -> [Input] -> [(VName, Ident)] -> Lambda rep -> [Input] -> (Lambda rep, [Input])
fuseRedomap :: Buildable rep => Names -> [VName] -> Lambda rep -> [SubExp] -> [SubExp] -> [Input] -> [(VName, Ident)] -> Lambda rep -> [SubExp] -> [SubExp] -> [Input] -> (Lambda rep, [Input])

module Futhark.Analysis.HORep.MapNest
data Nesting rep
Nesting :: [VName] -> [VName] -> [Type] -> SubExp -> Nesting rep
[nestingParamNames] :: Nesting rep -> [VName]
[nestingResult] :: Nesting rep -> [VName]
[nestingReturnType] :: Nesting rep -> [Type]
[nestingWidth] :: Nesting rep -> SubExp
data MapNest rep
MapNest :: SubExp -> Lambda rep -> [Nesting rep] -> [Input] -> MapNest rep
typeOf :: MapNest rep -> [Type]
params :: MapNest rep -> [VName]
inputs :: MapNest rep -> [Input]
setInputs :: [Input] -> MapNest rep -> MapNest rep
fromSOAC :: (Buildable rep, MonadFreshNames m, LocalScope rep m, Op rep ~ SOAC rep) => SOAC rep -> m (Maybe (MapNest rep))
toSOAC :: (MonadFreshNames m, HasScope rep m, Buildable rep, BuilderOps rep, Op rep ~ SOAC rep) => MapNest rep -> m (SOAC rep)
instance forall k (rep :: k). GHC.Show.Show (Futhark.Analysis.HORep.MapNest.Nesting rep)
instance forall k (rep :: k). GHC.Classes.Ord (Futhark.Analysis.HORep.MapNest.Nesting rep)
instance forall k (rep :: k). GHC.Classes.Eq (Futhark.Analysis.HORep.MapNest.Nesting rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.Analysis.HORep.MapNest.MapNest rep)

-- | Facilities for fusing two SOACs.
--   
--   When the fusion algorithm decides that it's worth fusing two SOAC
--   statements, this is the module that tries to see if that's possible.
--   May involve massaging either producer or consumer in various ways.
module Futhark.Optimise.Fusion.TryFusion

-- | A fused SOAC contains a bit of extra information.
data FusedSOAC
FusedSOAC :: SOAC -> ArrayTransforms -> [VName] -> FusedSOAC

-- | The actual SOAC.
[fsSOAC] :: FusedSOAC -> SOAC

-- | A transformation to be applied to *all* results of the SOAC.
[fsOutputTransform] :: FusedSOAC -> ArrayTransforms

-- | The outputs of the SOAC (i.e. the names in the pattern that the result
--   of this SOAC should be bound to).
[fsOutNames] :: FusedSOAC -> [VName]

-- | Whether we are doing horizontal or vertical fusion. Note that vertical
--   also includes "diagonal" fusion, where some producer results are also
--   produced by the final SOAC.
data Mode
Horizontal :: Mode
Vertical :: Mode

-- | Attempt fusing the producer into the consumer.
attemptFusion :: (HasScope SOACS m, MonadFreshNames m) => Mode -> Names -> [VName] -> SOAC -> FusedSOAC -> m (Maybe FusedSOAC)
instance Futhark.IR.Prop.Scope.LocalScope Futhark.IR.SOACS.SOACS Futhark.Optimise.Fusion.TryFusion.TryFusion
instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.SOACS.SOACS Futhark.Optimise.Fusion.TryFusion.TryFusion
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Optimise.Fusion.TryFusion.TryFusion
instance Control.Monad.Fail.MonadFail Futhark.Optimise.Fusion.TryFusion.TryFusion
instance GHC.Base.Monad Futhark.Optimise.Fusion.TryFusion.TryFusion
instance GHC.Base.Alternative Futhark.Optimise.Fusion.TryFusion.TryFusion
instance GHC.Base.Applicative Futhark.Optimise.Fusion.TryFusion.TryFusion
instance GHC.Base.Functor Futhark.Optimise.Fusion.TryFusion.TryFusion
instance GHC.Show.Show Futhark.Optimise.Fusion.TryFusion.FusedSOAC

-- | 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 Futhark.IR.Prop.Scope.LocalScope Futhark.IR.SOACS.SOACS Futhark.Optimise.Fusion.FusionM
instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.SOACS.SOACS Futhark.Optimise.Fusion.FusionM
instance Control.Monad.State.Class.MonadState Futhark.Optimise.Fusion.FusionEnv Futhark.Optimise.Fusion.FusionM
instance GHC.Base.Functor Futhark.Optimise.Fusion.FusionM
instance GHC.Base.Applicative Futhark.Optimise.Fusion.FusionM
instance GHC.Base.Monad Futhark.Optimise.Fusion.FusionM
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Optimise.Fusion.FusionM

module Futhark.AD.Rev.Monad
data ADM a
data RState
RState :: Map VName Adj -> Substitutions -> Substitutions -> VNameSource -> RState
[stateAdjs] :: RState -> Map VName Adj
[stateLoopTape] :: RState -> Substitutions
[stateSubsts] :: RState -> Substitutions
[stateNameSource] :: RState -> VNameSource
runADM :: MonadFreshNames m => ADM a -> m a

-- | The adjoint of a variable.
data Adj
AdjSparse :: Sparse -> Adj
AdjVal :: SubExp -> Adj
AdjZero :: Shape -> PrimType -> Adj

-- | Whether Sparse should check bounds or assume they are correct.
--   The latter results in simpler code.
data InBounds

-- | If a SubExp is provided, it references a boolean that is true when
--   in-bounds.
CheckBounds :: Maybe SubExp -> InBounds
AssumeBounds :: InBounds

-- | Dynamically these will always fail, so don't bother generating code
--   for the update. This is only needed to ensure a consistent
--   representation of sparse Jacobians.
OutOfBounds :: InBounds

-- | A symbolic representation of an array that is all zeroes, except at
--   certain indexes.
data Sparse
Sparse :: Shape -> PrimType -> [(InBounds, SubExp, SubExp)] -> Sparse

-- | The shape of the array.
[sparseShape] :: Sparse -> Shape

-- | Element type of the array.
[sparseType] :: Sparse -> PrimType

-- | Locations and values of nonzero values. Indexes may be negative, in
--   which case the value is ignored (unless AssumeBounds is used).
[sparseIdxVals] :: Sparse -> [(InBounds, SubExp, SubExp)]
adjFromParam :: Param t -> Adj
adjFromVar :: VName -> Adj
lookupAdj :: VName -> ADM Adj
lookupAdjVal :: VName -> ADM VName
adjVal :: Adj -> ADM VName
updateAdj :: VName -> VName -> ADM ()
updateSubExpAdj :: SubExp -> VName -> ADM ()
updateAdjSlice :: Slice SubExp -> VName -> VName -> ADM ()
updateAdjIndex :: VName -> (InBounds, SubExp) -> SubExp -> ADM ()

-- | Set a specific adjoint.
setAdj :: VName -> Adj -> ADM ()

-- | Set an AdjVal adjoint. Simple wrapper around setAdj.
insAdj :: VName -> VName -> ADM ()

-- | Conveniently convert a list of Adjs to their representation, as well
--   as produce a function for converting back.
adjsReps :: [Adj] -> ([SubExp], [SubExp] -> [Adj])

-- | Create copies of all arrays consumed in the given statement, and
--   return statements which include copies of the consumed arrays.
--   
--   See Note [Consumption].
copyConsumedArrsInStm :: Stm SOACS -> ADM (Substitutions, Stms SOACS)
copyConsumedArrsInBody :: [VName] -> Body SOACS -> ADM Substitutions
addSubstitution :: VName -> VName -> ADM ()
returnSweepCode :: ADM a -> ADM a
adjVName :: VName -> ADM VName

-- | Ignore any changes to adjoints made while evaluating this action.
subAD :: ADM a -> ADM a
noAdjsFor :: Names -> ADM a -> ADM a
subSubsts :: ADM a -> ADM a

-- | Is this primal variable active in the AD sense? FIXME: this is
--   (obviously) much too conservative.
isActive :: VName -> ADM Bool
tabNest :: Int -> [VName] -> ([VName] -> [VName] -> ADM [VName]) -> ADM [VName]
oneExp :: Type -> Exp rep
zeroExp :: Type -> Exp rep
unitAdjOfType :: Type -> ADM Adj

-- | Construct a lambda for adding two values of the given type.
addLambda :: Type -> ADM (Lambda SOACS)
data VjpOps
VjpOps :: ([Adj] -> [VName] -> Lambda SOACS -> ADM (Lambda SOACS)) -> (Stm SOACS -> ADM () -> ADM ()) -> VjpOps
[vjpLambda] :: VjpOps -> [Adj] -> [VName] -> Lambda SOACS -> ADM (Lambda SOACS)
[vjpStm] :: VjpOps -> Stm SOACS -> ADM () -> ADM ()

-- | setLoopTape v vs establishes vs as the name of the
--   array where values of loop parameter v from the forward pass
--   are stored.
setLoopTape :: VName -> VName -> ADM ()

-- | Look-up the name of the array where v is stored.
lookupLoopTape :: VName -> ADM (Maybe VName)

-- | substLoopTape v v' substitutes the key v for
--   v'. That is, if v |-> vs then after the
--   substitution v' |-> vs (and v points to nothing).
substLoopTape :: VName -> VName -> ADM ()

-- | Renames the keys of the loop tape. Useful for fixing the the names in
--   the loop tape after a loop rename.
renameLoopTape :: Substitutions -> ADM ()
instance GHC.Show.Show Futhark.AD.Rev.Monad.InBounds
instance GHC.Classes.Ord Futhark.AD.Rev.Monad.InBounds
instance GHC.Classes.Eq Futhark.AD.Rev.Monad.InBounds
instance GHC.Show.Show Futhark.AD.Rev.Monad.Sparse
instance GHC.Classes.Ord Futhark.AD.Rev.Monad.Sparse
instance GHC.Classes.Eq Futhark.AD.Rev.Monad.Sparse
instance GHC.Show.Show Futhark.AD.Rev.Monad.Adj
instance GHC.Classes.Ord Futhark.AD.Rev.Monad.Adj
instance GHC.Classes.Eq Futhark.AD.Rev.Monad.Adj
instance Futhark.IR.Prop.Scope.LocalScope Futhark.IR.SOACS.SOACS Futhark.AD.Rev.Monad.ADM
instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.SOACS.SOACS Futhark.AD.Rev.Monad.ADM
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.AD.Rev.Monad.ADM
instance Control.Monad.State.Class.MonadState Futhark.AD.Rev.Monad.RState Futhark.AD.Rev.Monad.ADM
instance GHC.Base.Monad Futhark.AD.Rev.Monad.ADM
instance GHC.Base.Applicative Futhark.AD.Rev.Monad.ADM
instance GHC.Base.Functor Futhark.AD.Rev.Monad.ADM
instance Futhark.Builder.Class.MonadBuilder Futhark.AD.Rev.Monad.ADM
instance Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.State.Strict.State Futhark.AD.Rev.Monad.RState)
instance Futhark.Transform.Substitute.Substitute Futhark.AD.Rev.Monad.Adj

module Futhark.AD.Rev.Scatter
vjpScatter :: VjpOps -> Pat Type -> StmAux () -> (SubExp, [VName], Lambda SOACS, [(Shape, Int, VName)]) -> ADM () -> ADM ()

module Futhark.AD.Rev.Scan
diffScan :: VjpOps -> [VName] -> SubExp -> [VName] -> Scan SOACS -> ADM ()
diffScanVec :: VjpOps -> [VName] -> StmAux () -> SubExp -> Lambda SOACS -> [SubExp] -> [VName] -> ADM () -> ADM ()
diffScanAdd :: VjpOps -> VName -> SubExp -> Lambda SOACS -> SubExp -> VName -> ADM ()
instance GHC.Show.Show Futhark.AD.Rev.Scan.SpecialCase
instance GHC.Show.Show Futhark.AD.Rev.Scan.Special
instance GHC.Show.Show Futhark.AD.Rev.Scan.ScanAlgo

module Futhark.AD.Rev.Reduce
diffReduce :: VjpOps -> [VName] -> SubExp -> [VName] -> Reduce SOACS -> ADM ()
diffMinMaxReduce :: VjpOps -> VName -> StmAux () -> SubExp -> BinOp -> SubExp -> VName -> ADM () -> ADM ()
diffVecReduce :: VjpOps -> Pat Type -> StmAux () -> SubExp -> Commutativity -> Lambda SOACS -> VName -> VName -> ADM () -> ADM ()
diffMulReduce :: VjpOps -> VName -> StmAux () -> SubExp -> BinOp -> SubExp -> VName -> ADM () -> ADM ()

-- | VJP transformation for Map SOACs. This is a pretty complicated case
--   due to the possibility of free variables.
module Futhark.AD.Rev.Map

-- | Perform VJP on a Map. The Adj list is the adjoints of the
--   result of the map.
vjpMap :: VjpOps -> [Adj] -> StmAux () -> SubExp -> Lambda SOACS -> [VName] -> ADM ()

module Futhark.AD.Rev.Loop

-- | Transforms a loop into its reverse-mode derivative.
diffLoop :: (Stms SOACS -> ADM ()) -> Pat Type -> StmAux () -> Exp SOACS -> ADM () -> ADM ()
stripmineStms :: Stms SOACS -> ADM (Stms SOACS)
instance GHC.Show.Show a => GHC.Show.Show (Futhark.AD.Rev.Loop.LoopInfo a)
instance Data.Traversable.Traversable Futhark.AD.Rev.Loop.LoopInfo
instance Data.Foldable.Foldable Futhark.AD.Rev.Loop.LoopInfo
instance GHC.Base.Functor Futhark.AD.Rev.Loop.LoopInfo

module Futhark.AD.Rev.Hist
diffMinMaxHist :: VjpOps -> VName -> StmAux () -> SubExp -> BinOp -> SubExp -> VName -> VName -> SubExp -> SubExp -> VName -> ADM () -> ADM ()
diffMulHist :: VjpOps -> VName -> StmAux () -> SubExp -> BinOp -> SubExp -> VName -> VName -> SubExp -> SubExp -> VName -> ADM () -> ADM ()
diffAddHist :: VjpOps -> VName -> StmAux () -> SubExp -> Lambda SOACS -> SubExp -> VName -> VName -> SubExp -> SubExp -> VName -> ADM () -> ADM ()
diffVecHist :: VjpOps -> VName -> StmAux () -> SubExp -> Lambda SOACS -> VName -> VName -> VName -> SubExp -> SubExp -> VName -> ADM () -> ADM ()
diffHist :: VjpOps -> [VName] -> StmAux () -> SubExp -> Lambda SOACS -> [SubExp] -> [VName] -> [SubExp] -> SubExp -> [VName] -> ADM () -> ADM ()

module Futhark.AD.Rev.SOAC
vjpSOAC :: VjpOps -> Pat Type -> StmAux () -> SOAC SOACS -> ADM () -> ADM ()

-- | Partial derivatives of scalar Futhark operations and built-in
--   functions.
module Futhark.AD.Derivatives

-- | pdBuiltin f args i computes the partial derivative of
--   f applied to args with respect to each of its
--   arguments. Returns Nothing if no such derivative is known.
pdBuiltin :: Name -> [PrimExp VName] -> Maybe [PrimExp VName]

-- | pdBinOp op x y computes the partial derivatives of
--   op with respect to x and y.
pdBinOp :: BinOp -> PrimExp VName -> PrimExp VName -> (PrimExp VName, PrimExp VName)

-- | pdUnOp op x computes the partial derivatives of op
--   with respect to x.
pdUnOp :: UnOp -> PrimExp VName -> PrimExp VName

module Language.Futhark.Interpreter.AD
data Op
OpBin :: BinOp -> Op
OpCmp :: CmpOp -> Op
OpUn :: UnOp -> Op
OpFn :: Text -> Op
OpConv :: ConvOp -> Op
data ADVariable
VJP :: VJPValue -> ADVariable
JVP :: JVPValue -> ADVariable
data ADValue
Variable :: Int -> ADVariable -> ADValue
Constant :: PrimValue -> ADValue

-- | Represents a computation tree, as well as every intermediate value in
--   its evaluation. TODO: make this a graph.
data Tape

-- | This represents a variable. Each variable is given a unique ID, and
--   has an initial value
TapeID :: Int -> ADValue -> Tape

-- | This represents a constant.
TapeConst :: ADValue -> Tape

-- | This represents the application of a mathematical operation. Each
--   parameter is given by its Tape, and the return value of the operation
--   is saved
TapeOp :: Op -> [Tape] -> ADValue -> Tape
newtype VJPValue
VJPValue :: Tape -> VJPValue

-- | In JVP, the derivative of the variable must be saved. This is
--   represented as a second value.
data JVPValue
JVPValue :: ADValue -> ADValue -> JVPValue
doOp :: Op -> [ADValue] -> Maybe ADValue
addFor :: PrimType -> BinOp

-- | Returns the primal value of a Tape.
tapePrimal :: Tape -> ADValue
primitive :: ADValue -> PrimValue
varPrimal :: ADVariable -> PrimValue

-- | This calculates every partial derivative of a Tape. The result
--   is a map of the partial derivatives, each key corresponding to the ID
--   of a free variable (see TapeID).
deriveTape :: Tape -> ADValue -> Map Int ADValue
instance GHC.Show.Show Language.Futhark.Interpreter.AD.Op
instance GHC.Show.Show Language.Futhark.Interpreter.AD.Tape
instance GHC.Show.Show Language.Futhark.Interpreter.AD.VJPValue
instance GHC.Show.Show Language.Futhark.Interpreter.AD.ADVariable
instance GHC.Show.Show Language.Futhark.Interpreter.AD.ADValue
instance GHC.Show.Show Language.Futhark.Interpreter.AD.JVPValue

module Futhark.AD.Rev
revVJP :: MonadFreshNames m => Scope SOACS -> Lambda SOACS -> m (Lambda SOACS)

module Futhark.AD.Fwd
fwdJVP :: MonadFreshNames m => Scope SOACS -> Lambda SOACS -> m (Lambda SOACS)
instance Futhark.IR.Prop.Scope.LocalScope Futhark.IR.SOACS.SOACS Futhark.AD.Fwd.ADM
instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.SOACS.SOACS Futhark.AD.Fwd.ADM
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.AD.Fwd.ADM
instance Control.Monad.State.Class.MonadState Futhark.AD.Fwd.RState Futhark.AD.Fwd.ADM
instance GHC.Base.Monad Futhark.AD.Fwd.ADM
instance GHC.Base.Applicative Futhark.AD.Fwd.ADM
instance GHC.Base.Functor Futhark.AD.Fwd.ADM
instance Futhark.AD.Fwd.Tangent a => Futhark.AD.Fwd.TanBuilder (Futhark.IR.Syntax.Core.Param (Futhark.IR.Syntax.Core.TypeBase s u), a)
instance Futhark.AD.Fwd.Tangent (Futhark.IR.Syntax.Core.TypeBase s u)
instance Futhark.AD.Fwd.Tangent Language.Futhark.Core.VName
instance Futhark.AD.Fwd.Tangent Futhark.IR.Syntax.Core.SubExp
instance Futhark.AD.Fwd.Tangent Futhark.IR.Syntax.SubExpRes
instance Futhark.AD.Fwd.TanBuilder (Futhark.IR.Syntax.Core.PatElem (Futhark.IR.Syntax.Core.TypeBase s u))
instance Futhark.AD.Fwd.TanBuilder (Futhark.IR.Syntax.Core.Param (Futhark.IR.Syntax.Core.TypeBase s u))
instance Futhark.Builder.Class.MonadBuilder Futhark.AD.Fwd.ADM
instance Futhark.MonadFreshNames.MonadFreshNames (Control.Monad.Trans.State.Strict.State Futhark.AD.Fwd.RState)

-- | Apply all AD operators in the program, leaving AD-free code.
module Futhark.Pass.AD
applyAD :: Pass SOACS SOACS
applyADInnermost :: Pass SOACS SOACS
instance GHC.Classes.Eq Futhark.Pass.AD.Mode

module Futhark.Analysis.AlgSimplify
data Prod
Prod :: Bool -> [Exp] -> Prod
[negated] :: Prod -> Bool
[atoms] :: Prod -> [Exp]
type SofP = [Prod]
simplify0 :: Exp -> SofP
simplify :: Exp -> Exp
simplify' :: TExp -> TExp
simplifySofP :: SofP -> SofP
simplifySofP' :: SofP -> SofP
sumOfProducts :: Exp -> SofP
sumToExp :: SofP -> Exp
prodToExp :: Prod -> Exp
add :: SofP -> SofP -> SofP
sub :: SofP -> SofP -> SofP
negate :: Prod -> Prod
isMultipleOf :: Prod -> [Exp] -> Bool
maybeDivide :: Prod -> Prod -> Maybe Prod
removeLessThans :: SofP -> [(SubExp, PrimExp VName)] -> SofP
lessThanish :: [(VName, PrimExp VName)] -> Names -> TPrimExp Int64 VName -> TPrimExp Int64 VName -> Bool
compareComplexity :: SofP -> SofP -> Ordering
instance GHC.Classes.Ord Futhark.Analysis.AlgSimplify.Prod
instance GHC.Classes.Eq Futhark.Analysis.AlgSimplify.Prod
instance GHC.Show.Show Futhark.Analysis.AlgSimplify.Prod

module Futhark.IR.Mem.Interval
data Interval
Interval :: TPrimExp Int64 VName -> TPrimExp Int64 VName -> TPrimExp Int64 VName -> Interval
[lowerBound] :: Interval -> TPrimExp Int64 VName
[numElements] :: Interval -> TPrimExp Int64 VName
[stride] :: Interval -> TPrimExp Int64 VName
distributeOffset :: MonadFail m => SofP -> [Interval] -> m [Interval]
expandOffset :: SofP -> [Interval] -> Maybe SofP
intervalOverlap :: [(VName, PrimExp VName)] -> Names -> Interval -> Interval -> Bool

-- | Returns true if the intervals are self-overlapping, meaning that for a
--   given dimension d, the stride of d is larger than the aggregate spans
--   of the lower dimensions.
selfOverlap :: scope -> asserts -> [(VName, PrimExp VName)] -> [PrimExp VName] -> [Interval] -> Maybe Interval
primBool :: TPrimExp Bool VName -> Maybe Bool
intervalPairs :: [Interval] -> [Interval] -> [(Interval, Interval)]
justLeafExp :: PrimExp VName -> Maybe VName
instance GHC.Classes.Eq Futhark.IR.Mem.Interval.Interval
instance GHC.Show.Show Futhark.IR.Mem.Interval.Interval
instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.Mem.Interval.Interval

-- | This module contains a representation of linear-memory accessor
--   descriptors (LMAD); see work by Zhu, Hoeflinger and David.
--   
--   This module is designed to be used as a qualified import, as the
--   exported names are quite generic.
module Futhark.IR.Mem.LMAD

-- | The shape of an index function.
type Shape num = [num]

-- | Indices passed to an LMAD. Must always match the rank of the LMAD.
type Indices num = [num]

-- | LMAD's representation consists of a general offset and for each
--   dimension a stride, number of elements (or shape), and permutation.
--   Note that the permutation is not strictly necessary in that the
--   permutation can be performed directly on LMAD dimensions, but then it
--   is difficult to extract the permutation back from an LMAD.
--   
--   LMAD algebra is closed under composition w.r.t. operators such as
--   permute, index and slice. However, other operations, such as reshape,
--   cannot always be represented inside the LMAD algebra.
--   
--   It follows that the general representation of an index function is a
--   list of LMADS, in which each following LMAD in the list implicitly
--   corresponds to an irregular reshaping operation.
--   
--   However, we expect that the common case is when the index function is
--   one LMAD -- we call this the "nice" representation.
--   
--   Finally, the list of LMADs is kept in an LMAD together with
--   the shape of the original array, and a bit to indicate whether the
--   index function is contiguous, i.e., if we instantiate all the points
--   of the current index function, do we get a contiguous memory interval?
--   
--   By definition, the LMAD <math>, where <math> and
--   <math> denote the shape and stride of each dimension, denotes
--   the set of points:
--   
--   <math>
data LMAD num
LMAD :: num -> [LMADDim num] -> LMAD num
[offset] :: LMAD num -> num
[dims] :: LMAD num -> [LMADDim num]

-- | A single dimension in an LMAD.
data LMADDim num
LMADDim :: num -> num -> LMADDim num
[ldStride] :: LMADDim num -> num
[ldShape] :: LMADDim num -> num

-- | A complete permutation.
type Permutation = [Int]
index :: (IntegralExp num, Eq num) => LMAD num -> Indices num -> num

-- | Handle the case where a slice can stay within a single LMAD.
slice :: (Eq num, IntegralExp num) => LMAD num -> Slice num -> LMAD num

-- | Flat-slice an LMAD.
flatSlice :: IntegralExp num => LMAD num -> FlatSlice num -> LMAD num

-- | Reshape an LMAD.
--   
--   There are four conditions that all must hold for the result of a
--   reshape operation to remain in the one-LMAD domain:
--   
--   
--   
- the permutation of the underlying LMAD must leave unchanged the
--   LMAD dimensions that were *not* reshape coercions.
--   
- the repetition of dimensions of the underlying LMAD must refer
--   only to the coerced-dimensions of the reshape operation.
--   
--   
--   If any of these conditions do not hold, then the reshape operation
--   will conservatively add a new LMAD to the list, leading to a
--   representation that provides less opportunities for further analysis
reshape :: (Eq num, IntegralExp num) => LMAD num -> Shape num -> Maybe (LMAD num)

-- | Coerce an index function to look like it has a new shape. Dynamically
--   the shape must be the same.
coerce :: LMAD num -> Shape num -> LMAD num

-- | Permute dimensions.
permute :: LMAD num -> Permutation -> LMAD num

-- | Shape of an LMAD.
shape :: LMAD num -> Shape num

-- | Substitute a name with a PrimExp in an LMAD.
substitute :: Ord a => Map a (TPrimExp t a) -> LMAD (TPrimExp t a) -> LMAD (TPrimExp t a)

-- | Generalised iota with user-specified offset.
iota :: IntegralExp num => num -> [num] -> LMAD num

-- | Returns true if two LMADs are equivalent.
--   
--   Equivalence in this case is matching in offsets and strides.
equivalent :: Eq num => LMAD num -> LMAD num -> Bool

-- | The largest possible linear address reachable by this LMAD, not
--   counting the offset. If you add one to this number (and multiply it
--   with the element size), you get the amount of bytes you need to
--   allocate for an array with this LMAD (assuming zero offset).
range :: Pretty num => LMAD (TPrimExp Int64 num) -> TPrimExp Int64 num

-- | Conceptually expand LMAD to be a particular slice of another by
--   adjusting the offset and strides. Used for memory expansion.
expand :: IntegralExp num => num -> num -> LMAD num -> LMAD num

-- | Is this is a row-major array with zero offset?
isDirect :: (Eq num, IntegralExp num) => LMAD num -> Bool

-- | Returns True if the two LMADs could be proven
--   disjoint.
--   
--   Uses some best-approximation heuristics to determine disjointness. For
--   two 1-dimensional arrays, we can guarantee whether or not they are
--   disjoint, but as soon as more than one dimension is involved, things
--   get more tricky. Currently, we try to conservativelyFlatten
--   any LMAD with more than one dimension.
disjoint :: [(VName, PrimExp VName)] -> Names -> LMAD (TPrimExp Int64 VName) -> LMAD (TPrimExp Int64 VName) -> Bool
disjoint2 :: scope -> asserts -> [(VName, PrimExp VName)] -> Names -> LMAD (TPrimExp Int64 VName) -> LMAD (TPrimExp Int64 VName) -> Bool
disjoint3 :: Map VName Type -> [PrimExp VName] -> [(VName, PrimExp VName)] -> [PrimExp VName] -> LMAD (TPrimExp Int64 VName) -> LMAD (TPrimExp Int64 VName) -> Bool

-- | Dynamically determine if two LMAD are equal.
--   
--   True if offset and constituent LMADDim are equal.
dynamicEqualsLMAD :: Eq num => LMAD (TPrimExp t num) -> LMAD (TPrimExp t num) -> TPrimExp Bool num

-- | Create an LMAD that is existential in everything except shape.
mkExistential :: Shape (Ext a) -> Int -> LMAD (Ext a)

-- | When comparing LMADs as part of the type check in GPUMem, 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 `lmad1 == lmad2` and hope that it's good enough.
closeEnough :: LMAD num -> LMAD num -> Bool

-- | Turn all the leaves of the LMAD into Exts, except for the
--   shape, which where the leaves are simply made Free.
existentialize :: Int -> LMAD (TPrimExp Int64 a) -> LMAD (TPrimExp Int64 (Ext a))

-- | Retrieve those elements that existentialize changes. That is,
--   everything except the shape (and in the same order as
--   existentialise existentialises them).
existentialized :: LMAD a -> [a]
instance GHC.Classes.Ord num => GHC.Classes.Ord (Futhark.IR.Mem.LMAD.LMADDim num)
instance GHC.Classes.Eq num => GHC.Classes.Eq (Futhark.IR.Mem.LMAD.LMADDim num)
instance GHC.Show.Show num => GHC.Show.Show (Futhark.IR.Mem.LMAD.LMADDim num)
instance GHC.Classes.Ord num => GHC.Classes.Ord (Futhark.IR.Mem.LMAD.LMAD num)
instance GHC.Classes.Eq num => GHC.Classes.Eq (Futhark.IR.Mem.LMAD.LMAD num)
instance GHC.Show.Show num => GHC.Show.Show (Futhark.IR.Mem.LMAD.LMAD num)
instance Prettyprinter.Internal.Pretty num => Prettyprinter.Internal.Pretty (Futhark.IR.Mem.LMAD.LMAD num)
instance Futhark.Transform.Substitute.Substitute num => Futhark.Transform.Substitute.Substitute (Futhark.IR.Mem.LMAD.LMAD num)
instance Futhark.Transform.Substitute.Substitute num => Futhark.Transform.Rename.Rename (Futhark.IR.Mem.LMAD.LMAD num)
instance Futhark.IR.Prop.Names.FreeIn num => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Mem.LMAD.LMAD num)
instance GHC.Base.Functor Futhark.IR.Mem.LMAD.LMAD
instance Data.Foldable.Foldable Futhark.IR.Mem.LMAD.LMAD
instance Data.Traversable.Traversable Futhark.IR.Mem.LMAD.LMAD
instance Futhark.IR.Prop.Names.FreeIn num => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Mem.LMAD.LMADDim num)

-- | 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:
--   
--   
--   
- 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.
--   
- 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.
--   
--   
--   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 :: Type -> Type) (rep :: Type)

-- | Allocate a memory block.
Alloc :: SubExp -> Space -> MemOp (inner :: Type -> Type) (rep :: Type)
Inner :: inner rep -> MemOp (inner :: Type -> Type) (rep :: Type)

-- | A helper for defining TraverseOpStms.
traverseMemOpStms :: Monad m => OpStmsTraverser m (inner rep) rep -> OpStmsTraverser m (MemOp inner rep) rep

-- | 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

-- | An accumulator, which is not stored anywhere.
MemAcc :: VName -> Shape -> [Type] -> u -> 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 -> LMAD -> 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 -> ExtLMAD -> MemReturn

-- | The operation returns a new (existential) memory block.
ReturnsNewBlock :: Space -> Int -> ExtLMAD -> MemReturn

-- | The LMAD representation used for memory annotations.
type LMAD = LMAD (TPrimExp Int64 VName)

-- | An index function that may contain existential variables.
type ExtLMAD = LMAD (TPrimExp Int64 (Ext VName))
isStaticLMAD :: ExtLMAD -> Maybe LMAD

-- | 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 rep inner = (FParamInfo rep ~ FParamMem, LParamInfo rep ~ LParamMem, HasLetDecMem (LetDec rep), RetType rep ~ RetTypeMem, BranchType rep ~ BranchTypeMem, ASTRep rep, OpReturns inner, RephraseOp inner, ASTConstraints (inner rep), FreeIn (inner rep), OpC rep ~ MemOp inner)

-- | The class of pattern element decorators that contain memory
--   information.
class HasLetDecMem t
letDecMem :: HasLetDecMem t => t -> LetDecMem
class (IsOp op) => OpReturns op
opReturns :: (OpReturns op, Mem rep inner, Monad m, HasScope rep m) => op rep -> m [ExpReturns]
varReturns :: (HasScope rep m, Monad m, Mem rep inner) => VName -> m ExpReturns

-- | The return information of an expression. This can be seen as the
--   "return type with memory annotations" of the expression.
--   
--   This can produce Nothing, which signifies that the result is an array
--   layout that is not expressible as an index function.
expReturns :: (LocalScope rep m, Mem rep inner) => Exp rep -> m (Maybe [ExpReturns])
extReturns :: [ExtType] -> [ExpReturns]

-- | Turn info into memory information.
nameInfoToMemInfo :: Mem rep inner => NameInfo rep -> MemBound NoUniqueness

-- | Look up information about the memory block with this name.
lookupMemInfo :: (HasScope rep m, Mem rep inner) => VName -> m (MemInfo SubExp NoUniqueness MemBind)
subExpMemInfo :: (HasScope rep m, Mem rep inner) => SubExp -> m (MemInfo SubExp NoUniqueness MemBind)
lookupArraySummary :: (Mem rep inner, HasScope rep m, Monad m) => VName -> m (VName, LMAD (TPrimExp Int64 VName))
lookupMemSpace :: (Mem rep inner, HasScope rep m, Monad m) => VName -> m Space
existentialiseLMAD :: [VName] -> LMAD -> ExtLMAD
matchBranchReturnType :: (Mem rep inner, Checkable rep) => [BodyReturns] -> Body (Aliases rep) -> TypeM rep ()
matchPatToExp :: (Mem rep inner, LetDec rep ~ LetDecMem, Checkable rep) => Pat (LetDec (Aliases rep)) -> Exp (Aliases rep) -> TypeM rep ()
matchFunctionReturnType :: (Mem rep inner, Checkable rep) => [FunReturns] -> Result -> TypeM rep ()
matchLoopResultMem :: (Mem rep inner, Checkable rep) => [FParam (Aliases rep)] -> Result -> TypeM rep ()
bodyReturnsFromPat :: Pat (MemBound NoUniqueness) -> [(VName, BodyReturns)]
checkMemInfo :: Checkable rep => VName -> MemInfo SubExp u MemBind -> TypeM rep ()
instance GHC.Show.Show (inner rep) => GHC.Show.Show (Futhark.IR.Mem.MemOp inner rep)
instance GHC.Classes.Ord (inner rep) => GHC.Classes.Ord (Futhark.IR.Mem.MemOp inner rep)
instance GHC.Classes.Eq (inner rep) => GHC.Classes.Eq (Futhark.IR.Mem.MemOp inner rep)
instance (GHC.Classes.Ord d, GHC.Classes.Ord ret, GHC.Classes.Ord u) => GHC.Classes.Ord (Futhark.IR.Mem.MemInfo d u ret)
instance (GHC.Show.Show d, GHC.Show.Show ret, GHC.Show.Show u) => GHC.Show.Show (Futhark.IR.Mem.MemInfo d u ret)
instance (GHC.Classes.Eq d, GHC.Classes.Eq ret, GHC.Classes.Eq u) => GHC.Classes.Eq (Futhark.IR.Mem.MemInfo d u ret)
instance GHC.Show.Show Futhark.IR.Mem.MemBind
instance GHC.Show.Show Futhark.IR.Mem.MemReturn
instance Futhark.IR.Mem.OpReturns inner => Futhark.IR.Mem.OpReturns (Futhark.IR.Mem.MemOp inner)
instance Futhark.IR.Mem.OpReturns Futhark.IR.Rep.NoOp
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 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 Prettyprinter.Internal.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 Futhark.IR.Mem.HasLetDecMem Futhark.IR.Mem.LetDecMem
instance Futhark.IR.Mem.HasLetDecMem b => Futhark.IR.Mem.HasLetDecMem (a, b)
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 Prettyprinter.Internal.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 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 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 Language.Futhark.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 Language.Futhark.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 (Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.ShapeBase d), Prettyprinter.Internal.Pretty (Futhark.IR.Syntax.Core.TypeBase (Futhark.IR.Syntax.Core.ShapeBase d) u), Prettyprinter.Internal.Pretty d, Prettyprinter.Internal.Pretty u, Prettyprinter.Internal.Pretty ret) => Prettyprinter.Internal.Pretty (Futhark.IR.Mem.MemInfo d u ret)
instance Futhark.IR.Rephrase.RephraseOp inner => Futhark.IR.Rephrase.RephraseOp (Futhark.IR.Mem.MemOp inner)
instance Futhark.IR.Prop.Names.FreeIn (inner rep) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.Mem.MemOp inner rep)
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.Aliases.CanBeAliased inner => Futhark.IR.Aliases.CanBeAliased (Futhark.IR.Mem.MemOp inner)
instance Futhark.Transform.Rename.Rename (inner rep) => Futhark.Transform.Rename.Rename (Futhark.IR.Mem.MemOp inner rep)
instance Futhark.Transform.Substitute.Substitute (inner rep) => Futhark.Transform.Substitute.Substitute (Futhark.IR.Mem.MemOp inner rep)
instance Prettyprinter.Internal.Pretty (inner rep) => Prettyprinter.Internal.Pretty (Futhark.IR.Mem.MemOp inner rep)
instance Futhark.Analysis.Metrics.OpMetrics (inner rep) => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Mem.MemOp inner rep)
instance Futhark.IR.Prop.IsOp inner => Futhark.IR.Prop.IsOp (Futhark.IR.Mem.MemOp inner)
instance Futhark.Optimise.Simplify.Rep.CanBeWise inner => Futhark.Optimise.Simplify.Rep.CanBeWise (Futhark.IR.Mem.MemOp inner)
instance Futhark.Analysis.SymbolTable.IndexOp (inner rep) => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.Mem.MemOp inner rep)

-- | A generic transformation for adding memory allocations to a Futhark
--   program. Specialised by specific representations in submodules.
module Futhark.Pass.ExplicitAllocations
explicitAllocationsGeneric :: Allocable fromrep torep inner => Space -> (Op fromrep -> AllocM fromrep torep (Op torep)) -> (Exp torep -> AllocM fromrep torep [ExpHint]) -> Pass fromrep torep
explicitAllocationsInStmsGeneric :: (MonadFreshNames m, HasScope torep m, Allocable fromrep torep inner) => Space -> (Op fromrep -> AllocM fromrep torep (Op torep)) -> (Exp torep -> AllocM fromrep torep [ExpHint]) -> Stms fromrep -> m (Stms torep)
data ExpHint
NoHint :: ExpHint
Hint :: LMAD -> Space -> ExpHint
defaultExpHints :: (ASTRep rep, HasScope rep m) => Exp rep -> m [ExpHint]

-- | The space in which we allocate memory if we have no other preferences
--   or constraints.
askDefaultSpace :: AllocM fromrep torep Space
type Allocable fromrep torep inner = (PrettyRep fromrep, PrettyRep torep, Mem torep inner, LetDec torep ~ LetDecMem, FParamInfo fromrep ~ DeclType, LParamInfo fromrep ~ Type, BranchType fromrep ~ ExtType, RetType fromrep ~ DeclExtType, BodyDec fromrep ~ (), BodyDec torep ~ (), ExpDec torep ~ (), SizeSubst (inner torep), BuilderOps torep)

-- | Monad for adding allocations to an entire program.
data AllocM fromrep torep a
data AllocEnv fromrep torep
AllocEnv :: Space -> Set VName -> (Op fromrep -> AllocM fromrep torep (Op torep)) -> (Exp torep -> AllocM fromrep torep [ExpHint]) -> AllocEnv fromrep torep

-- | When allocating memory, put it in this memory space. This is primarily
--   used to ensure that group-wide statements store their results in
--   shared memory.
[allocSpace] :: AllocEnv fromrep torep -> Space

-- | The set of names that are known to be constants at kernel compile
--   time.
[envConsts] :: AllocEnv fromrep torep -> Set VName
[allocInOp] :: AllocEnv fromrep torep -> Op fromrep -> AllocM fromrep torep (Op torep)
[envExpHints] :: AllocEnv fromrep torep -> Exp torep -> AllocM fromrep torep [ExpHint]
class SizeSubst op
opIsConst :: SizeSubst op => op -> Bool
allocInStms :: Allocable fromrep torep inner => Stms fromrep -> AllocM fromrep torep a -> AllocM fromrep torep a

-- | Allocate memory for a value of the given type.
allocForArray :: Allocable fromrep torep inner => Type -> Space -> AllocM fromrep torep VName
simplifiable :: (SimplifiableRep rep, LetDec rep ~ LetDecMem, ExpDec rep ~ (), BodyDec rep ~ (), Mem (Wise rep) inner, CanBeWise inner, RephraseOp inner, IsOp inner, OpReturns inner, AliasedOp inner, IndexOp (inner (Wise rep))) => (inner (Wise rep) -> UsageTable) -> (inner (Wise rep) -> SimpleM rep (inner (Wise rep), Stms (Wise rep))) -> SimpleOps rep
mkLetNamesB' :: (LetDec (Rep m) ~ LetDecMem, Mem (Rep m) inner, MonadBuilder m, ExpDec (Rep m) ~ ()) => Space -> ExpDec (Rep m) -> [VName] -> Exp (Rep m) -> m (Stm (Rep m))
mkLetNamesB'' :: (Mem rep inner, LetDec rep ~ LetDecMem, OpReturns inner, ExpDec rep ~ (), Rep m ~ Wise rep, HasScope (Wise rep) m, MonadBuilder m, AliasedOp inner, RephraseOp (MemOp inner), CanBeWise inner, ASTConstraints (inner (Wise rep))) => Space -> [VName] -> Exp (Wise rep) -> m (Stm (Wise rep))
instance GHC.Show.Show Futhark.Pass.ExplicitAllocations.MemReq
instance GHC.Classes.Eq Futhark.Pass.ExplicitAllocations.MemReq
instance Control.Monad.Reader.Class.MonadReader (Futhark.Pass.ExplicitAllocations.AllocEnv fromrep torep) (Futhark.Pass.ExplicitAllocations.AllocM fromrep torep)
instance Futhark.IR.Prop.ASTRep torep => Futhark.IR.Prop.Scope.LocalScope torep (Futhark.Pass.ExplicitAllocations.AllocM fromrep torep)
instance Futhark.IR.Prop.ASTRep torep => Futhark.IR.Prop.Scope.HasScope torep (Futhark.Pass.ExplicitAllocations.AllocM fromrep torep)
instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Pass.ExplicitAllocations.AllocM fromrep torep)
instance GHC.Base.Monad (Futhark.Pass.ExplicitAllocations.AllocM fromrep torep)
instance GHC.Base.Functor (Futhark.Pass.ExplicitAllocations.AllocM fromrep torep)
instance GHC.Base.Applicative (Futhark.Pass.ExplicitAllocations.AllocM fromrep torep)
instance Futhark.Pass.ExplicitAllocations.Allocable fromrep torep inner => Futhark.Builder.Class.MonadBuilder (Futhark.Pass.ExplicitAllocations.AllocM fromrep torep)
instance forall k (rep :: k). Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.IR.Rep.NoOp rep)
instance Futhark.Pass.ExplicitAllocations.SizeSubst (op rep) => Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.IR.Mem.MemOp op rep)

-- | 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 block-level.
--   
--   The type list is usually the type of the element returned by a single
--   thread. The result of the SegOp is then an array of that type, with
--   the shape of the SegSpace prepended. One exception is for
--   WriteReturns, where the type annotation is the full type
--   of the result.
data SegOp lvl rep
SegMap :: lvl -> SegSpace -> [Type] -> KernelBody rep -> SegOp lvl rep

-- | The KernelSpace must always have at least two dimensions, implying
--   that the result of a SegRed is always an array.
SegRed :: lvl -> SegSpace -> [SegBinOp rep] -> [Type] -> KernelBody rep -> SegOp lvl rep
SegScan :: lvl -> SegSpace -> [SegBinOp rep] -> [Type] -> KernelBody rep -> SegOp lvl rep
SegHist :: lvl -> SegSpace -> [HistOp rep] -> [Type] -> KernelBody rep -> SegOp lvl rep

-- | The level of a SegOp.
segLevel :: SegOp lvl rep -> lvl

-- | The body of a SegOp.
segBody :: SegOp lvl rep -> KernelBody rep

-- | The space of a SegOp.
segSpace :: SegOp lvl rep -> SegSpace

-- | Type check a SegOp, given a checker for its level.
typeCheckSegOp :: Checkable rep => (lvl -> TypeM rep ()) -> SegOp lvl (Aliases rep) -> TypeM rep ()

-- | 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 rep

-- | The sizes spanned by the indexes of the SegSpace.
segSpaceDims :: SegSpace -> [SubExp]

-- | An operator for SegHist.
data HistOp rep
HistOp :: Shape -> SubExp -> [VName] -> [SubExp] -> Shape -> Lambda rep -> HistOp rep
[histShape] :: HistOp rep -> Shape
[histRaceFactor] :: HistOp rep -> SubExp
[histDest] :: HistOp rep -> [VName]
[histNeutral] :: HistOp rep -> [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.
[histOpShape] :: HistOp rep -> Shape
[histOp] :: HistOp rep -> Lambda rep

-- | 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 rep -> [Type]

-- | Split reduction results returned by a KernelBody into those
--   that correspond to indexes for the HistOps, and those that
--   correspond to value.
splitHistResults :: [HistOp rep] -> [SubExp] -> [([SubExp], [SubExp])]

-- | An operator for SegScan and SegRed.
data SegBinOp rep
SegBinOp :: Commutativity -> Lambda rep -> [SubExp] -> Shape -> SegBinOp rep
[segBinOpComm] :: SegBinOp rep -> Commutativity
[segBinOpLambda] :: SegBinOp rep -> Lambda rep
[segBinOpNeutral] :: SegBinOp rep -> [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 rep -> Shape

-- | How many reduction results are produced by these SegBinOps?
segBinOpResults :: [SegBinOp rep] -> Int

-- | Split some list into chunks equal to the number of values returned by
--   each SegBinOp
segBinOpChunks :: [SegBinOp rep] -> [a] -> [[a]]

-- | The body of a SegOp.
data KernelBody rep
KernelBody :: BodyDec rep -> Stms rep -> [KernelResult] -> KernelBody rep
[kernelBodyDec] :: KernelBody rep -> BodyDec rep
[kernelBodyStms] :: KernelBody rep -> Stms rep
[kernelBodyResult] :: KernelBody rep -> [KernelResult]

-- | Perform alias analysis on a KernelBody.
aliasAnalyseKernelBody :: AliasableRep rep => AliasTable -> KernelBody rep -> KernelBody (Aliases rep)

-- | The variables consumed in the kernel body.
consumedInKernelBody :: Aliased rep => KernelBody rep -> 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-block depends on where the
--   SegOp occurs.
Returns :: ResultManifest -> Certs -> SubExp -> KernelResult
WriteReturns :: Certs -> VName -> [(Slice SubExp, SubExp)] -> KernelResult
TileReturns :: Certs -> [(SubExp, SubExp)] -> VName -> KernelResult
RegTileReturns :: Certs -> [(SubExp, SubExp, SubExp)] -> VName -> KernelResult

-- | Get the certs for this KernelResult.
kernelResultCerts :: KernelResult -> Certs

-- | Get the root SubExp corresponding values for a
--   KernelResult.
kernelResultSubExp :: KernelResult -> SubExp

-- | Like Mapper, but just for SegOps.
data SegOpMapper lvl frep trep m
SegOpMapper :: (SubExp -> m SubExp) -> (Lambda frep -> m (Lambda trep)) -> (KernelBody frep -> m (KernelBody trep)) -> (VName -> m VName) -> (lvl -> m lvl) -> SegOpMapper lvl frep trep m
[mapOnSegOpSubExp] :: SegOpMapper lvl frep trep m -> SubExp -> m SubExp
[mapOnSegOpLambda] :: SegOpMapper lvl frep trep m -> Lambda frep -> m (Lambda trep)
[mapOnSegOpBody] :: SegOpMapper lvl frep trep m -> KernelBody frep -> m (KernelBody trep)
[mapOnSegOpVName] :: SegOpMapper lvl frep trep m -> VName -> m VName
[mapOnSegOpLevel] :: SegOpMapper lvl frep trep m -> lvl -> m lvl

-- | A mapper that simply returns the SegOp verbatim.
identitySegOpMapper :: Monad m => SegOpMapper lvl rep rep m

-- | Apply a SegOpMapper to the given SegOp.
mapSegOpM :: Monad m => SegOpMapper lvl frep trep m -> SegOp lvl frep -> m (SegOp lvl trep)

-- | A helper for defining TraverseOpStms.
traverseSegOpStms :: Monad m => OpStmsTraverser m (SegOp lvl rep) rep

-- | Simplify the given SegOp.
simplifySegOp :: (SimplifiableRep rep, BodyDec rep ~ (), Simplifiable lvl) => SegOp lvl (Wise rep) -> SimpleM rep (SegOp lvl (Wise rep), Stms (Wise rep))

-- | Does this rep contain SegOps in its Ops? A rep must be
--   an instance of this class for the simplification rules to work.
class HasSegOp rep where {
    type SegOpLevel rep;
}
asSegOp :: HasSegOp rep => Op rep -> Maybe (SegOp (SegOpLevel rep) rep)
segOp :: HasSegOp rep => SegOp (SegOpLevel rep) rep -> Op rep

-- | Simplification rules for simplifying SegOps.
segOpRules :: (HasSegOp rep, BuilderOps rep, Buildable rep, Aliased rep) => RuleBook rep

-- | Like segOpType, but for memory representations.
segOpReturns :: (Mem rep inner, Monad m, HasScope rep m) => SegOp lvl rep -> m [ExpReturns]
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.SegOp.HistOp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.SegOp.HistOp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.SegOp.HistOp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.SegOp.SegBinOp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.SegOp.SegBinOp rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.SegOp.SegBinOp rep)
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.Classes.Ord Futhark.IR.SegOp.KernelResult
instance GHC.Show.Show Futhark.IR.SegOp.KernelResult
instance GHC.Classes.Eq Futhark.IR.SegOp.KernelResult
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 (Futhark.IR.Rep.RepTypes rep, GHC.Show.Show lvl) => GHC.Show.Show (Futhark.IR.SegOp.SegOp lvl rep)
instance (Futhark.IR.Rep.RepTypes rep, GHC.Classes.Ord lvl) => GHC.Classes.Ord (Futhark.IR.SegOp.SegOp lvl rep)
instance (Futhark.IR.Rep.RepTypes rep, GHC.Classes.Eq lvl) => GHC.Classes.Eq (Futhark.IR.SegOp.SegOp lvl rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Ord (Futhark.IR.SegOp.KernelBody rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Show.Show (Futhark.IR.SegOp.KernelBody rep)
instance Futhark.IR.Rep.RepTypes rep => GHC.Classes.Eq (Futhark.IR.SegOp.KernelBody rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.Transform.Substitute.Substitute lvl) => Futhark.Transform.Substitute.Substitute (Futhark.IR.SegOp.SegOp lvl rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.ASTConstraints lvl) => Futhark.Transform.Rename.Rename (Futhark.IR.SegOp.SegOp lvl rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Names.FreeIn lvl) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SegOp.SegOp lvl rep)
instance Futhark.IR.Aliases.CanBeAliased (Futhark.IR.SegOp.SegOp lvl)
instance Futhark.Optimise.Simplify.Rep.CanBeWise (Futhark.IR.SegOp.SegOp lvl)
instance Futhark.IR.Prop.TypeOf.TypedOp (Futhark.IR.SegOp.SegOp lvl)
instance Futhark.IR.Prop.ASTConstraints lvl => Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.SegOp.SegOp lvl)
instance Futhark.IR.Rephrase.RephraseOp (Futhark.IR.SegOp.SegOp lvl)
instance Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Rep.Op rep) => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.SegOp.SegOp lvl rep)
instance (Futhark.IR.Pretty.PrettyRep rep, Prettyprinter.Internal.Pretty lvl) => Prettyprinter.Internal.Pretty (Futhark.IR.SegOp.SegOp lvl rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.SegOp.SegOp lvl rep)
instance Futhark.IR.Prop.ASTConstraints lvl => Futhark.IR.Prop.IsOp (Futhark.IR.SegOp.SegOp lvl)
instance Prettyprinter.Internal.Pretty Futhark.IR.SegOp.SegSpace
instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.SegOp.SegSpace
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.SegOp.KernelBody rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.Transform.Substitute.Substitute (Futhark.IR.SegOp.KernelBody rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.Transform.Rename.Rename (Futhark.IR.SegOp.KernelBody rep)
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.SegOp.KernelBody rep)
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 Prettyprinter.Internal.Pretty Futhark.IR.SegOp.KernelResult
instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.SegOp.KernelResult
instance Futhark.IR.Pretty.PrettyRep rep => Prettyprinter.Internal.Pretty (Futhark.IR.SegOp.SegBinOp rep)

module Futhark.IR.Mem.Simplify
simplifyProgGeneric :: SimplifyMemory rep inner => RuleBook (Wise rep) -> SimpleOps rep -> Prog rep -> PassM (Prog rep)
simplifyStmsGeneric :: (HasScope rep m, MonadFreshNames m, SimplifyMemory rep inner) => RuleBook (Wise rep) -> SimpleOps rep -> Stms rep -> m (Stms rep)
simpleGeneric :: SimplifyMemory rep inner => (inner (Wise rep) -> UsageTable) -> SimplifyOp rep (inner (Wise rep)) -> SimpleOps rep

-- | Some constraints that must hold for the simplification rules to work.
type SimplifyMemory rep inner = (SimplifiableRep rep, LetDec rep ~ LetDecMem, ExpDec rep ~ (), BodyDec rep ~ (), CanBeWise (OpC rep), BuilderOps (Wise rep), OpReturns inner, IndexOp (inner (Wise rep)), AliasedOp inner, Mem rep inner, CanBeWise inner, RephraseOp inner, ASTConstraints (inner (Wise rep)))

-- | Standard collection of simplification rules for representations with
--   memory.
memRuleBook :: SimplifyMemory rep inner => RuleBook (Wise rep)

module Futhark.IR.SeqMem
data SeqMem
simplifyProg :: Prog SeqMem -> PassM (Prog SeqMem)
simpleSeqMem :: SimpleOps SeqMem
instance Futhark.IR.Rep.RepTypes Futhark.IR.SeqMem.SeqMem
instance Futhark.IR.Prop.ASTRep Futhark.IR.SeqMem.SeqMem
instance Futhark.IR.Pretty.PrettyRep Futhark.IR.SeqMem.SeqMem
instance Futhark.IR.TypeCheck.Checkable Futhark.IR.SeqMem.SeqMem
instance Futhark.Builder.BuilderOps Futhark.IR.SeqMem.SeqMem
instance Futhark.IR.Traversals.TraverseOpStms Futhark.IR.SeqMem.SeqMem
instance Futhark.Builder.BuilderOps (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.SeqMem.SeqMem)
instance Futhark.IR.Traversals.TraverseOpStms (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.SeqMem.SeqMem)

module Futhark.Pass.ExplicitAllocations.Seq
explicitAllocations :: Pass Seq SeqMem
simplifiable :: (SimplifiableRep rep, LetDec rep ~ LetDecMem, ExpDec rep ~ (), BodyDec rep ~ (), Mem (Wise rep) inner, CanBeWise inner, RephraseOp inner, IsOp inner, OpReturns inner, AliasedOp inner, IndexOp (inner (Wise rep))) => (inner (Wise rep) -> UsageTable) -> (inner (Wise rep) -> SimpleM rep (inner (Wise rep), Stms (Wise rep))) -> SimpleOps rep

-- | 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 op rep

-- | 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 () rep) -> SegOp () rep -> MCOp op rep

-- | Something else (in practice often a SOAC).
OtherOp :: op rep -> MCOp op rep
traverseMCOpStms :: Monad m => OpStmsTraverser m (op rep) rep -> OpStmsTraverser m (MCOp op rep) rep
typeCheckMCOp :: Checkable rep => (op (Aliases rep) -> TypeM rep ()) -> MCOp op (Aliases rep) -> TypeM rep ()
simplifyMCOp :: (SimplifiableRep rep, BodyDec rep ~ ()) => SimplifyOp rep (op (Wise rep)) -> MCOp op (Wise rep) -> SimpleM rep (MCOp op (Wise rep), Stms (Wise rep))
instance (Futhark.IR.Rep.RepTypes rep, GHC.Show.Show (op rep)) => GHC.Show.Show (Futhark.IR.MC.Op.MCOp op rep)
instance (Futhark.IR.Rep.RepTypes rep, GHC.Classes.Ord (op rep)) => GHC.Classes.Ord (Futhark.IR.MC.Op.MCOp op rep)
instance (Futhark.IR.Rep.RepTypes rep, GHC.Classes.Eq (op rep)) => GHC.Classes.Eq (Futhark.IR.MC.Op.MCOp op rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.Transform.Substitute.Substitute (op rep)) => Futhark.Transform.Substitute.Substitute (Futhark.IR.MC.Op.MCOp op rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.Transform.Rename.Rename (op rep)) => Futhark.Transform.Rename.Rename (Futhark.IR.MC.Op.MCOp op rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Names.FreeIn (op rep)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.MC.Op.MCOp op rep)
instance Futhark.IR.Prop.IsOp op => Futhark.IR.Prop.IsOp (Futhark.IR.MC.Op.MCOp op)
instance Futhark.IR.Prop.TypeOf.TypedOp op => Futhark.IR.Prop.TypeOf.TypedOp (Futhark.IR.MC.Op.MCOp op)
instance Futhark.IR.Prop.Aliases.AliasedOp op => Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.MC.Op.MCOp op)
instance Futhark.IR.Aliases.CanBeAliased op => Futhark.IR.Aliases.CanBeAliased (Futhark.IR.MC.Op.MCOp op)
instance Futhark.Optimise.Simplify.Rep.CanBeWise op => Futhark.Optimise.Simplify.Rep.CanBeWise (Futhark.IR.MC.Op.MCOp op)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.Analysis.SymbolTable.IndexOp (op rep)) => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.MC.Op.MCOp op rep)
instance Futhark.IR.Mem.OpReturns (Futhark.IR.MC.Op.MCOp Futhark.IR.Rep.NoOp)
instance (Futhark.IR.Pretty.PrettyRep rep, Prettyprinter.Internal.Pretty (op rep)) => Prettyprinter.Internal.Pretty (Futhark.IR.MC.Op.MCOp op rep)
instance (Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Rep.Op rep), Futhark.Analysis.Metrics.OpMetrics (op rep)) => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.MC.Op.MCOp op rep)
instance Futhark.IR.Rephrase.RephraseOp op => Futhark.IR.Rephrase.RephraseOp (Futhark.IR.MC.Op.MCOp op)

module Futhark.IR.MCMem
data MCMem
simplifyProg :: Prog MCMem -> PassM (Prog MCMem)
instance Futhark.IR.Rep.RepTypes Futhark.IR.MCMem.MCMem
instance Futhark.IR.Prop.ASTRep Futhark.IR.MCMem.MCMem
instance Futhark.IR.Pretty.PrettyRep Futhark.IR.MCMem.MCMem
instance Futhark.IR.TypeCheck.Checkable Futhark.IR.MCMem.MCMem
instance Futhark.Builder.BuilderOps Futhark.IR.MCMem.MCMem
instance Futhark.Builder.BuilderOps (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.MCMem.MCMem)
instance Futhark.IR.Traversals.TraverseOpStms (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.MCMem.MCMem)

-- | A representation for multicore CPU parallelism.
module Futhark.IR.MC
data MC
simplifyProg :: Prog MC -> PassM (Prog MC)

-- | How to compute a single scan result.
data Scan rep
Scan :: Lambda rep -> [SubExp] -> Scan rep
[scanLambda] :: Scan rep -> Lambda rep
[scanNeutral] :: Scan rep -> [SubExp]

-- | A second-order array combinator (SOAC).
data SOAC rep
Stream :: SubExp -> [VName] -> [SubExp] -> Lambda rep -> SOAC rep

-- | 
--   Scatter length inputs lambda spec
--   
--   
--   Scatter maps values from a set of input arrays to indices and values
--   of a set of output arrays. It is able to write multiple values to
--   multiple outputs each of which may have multiple dimensions.
--   
--   inputs is a list of input arrays, all having size
--   length, elements of which are applied to the lambda
--   function. For instance, if there are two arrays, lambda will
--   get two values as input, one from each array.
--   
--   spec specifies the result of the lambda and which arrays
--   to write to.
--   
--   lambda is a function that takes inputs from inputs and
--   returns values according to spec. It returns values in the
--   following manner:
--   
--   
--   
- index_0, index_1, ..., index_n, value_0, value_1, ...,
--   value_m
--   
--   
--   For each output in spec, lambda returns i *
--   j index values and j output values, where i is
--   the number of dimensions (rank) of the given output, and j is
--   the number of output values written to the given output.
--   
--   For example, given the following scatter specification:
--   
--   
--   
- ([x1, y1, z1 , 2, arr1), ([x2, y2], 1, arr2)]
--   
--   
--   lambda will produce 6 (3 * 2) index values and 2 output values
--   for arr1, and 2 (2 * 1) index values and 1 output value for
--   arr2. Additionally, the results are grouped, so the first 6 index
--   values will correspond to the first two output values, and so on. For
--   this example, lambda should return a total of 11 values, 8
--   index values and 3 output values. See also splitScatterResults.
Scatter :: SubExp -> [VName] -> ScatterSpec VName -> Lambda rep -> SOAC rep

-- | 
--   Hist length arrays dest-arrays-and-ops fun
--   
--   
--   The final lambda produces indexes and values for the HistOps.
Hist :: SubExp -> [VName] -> [HistOp rep] -> Lambda rep -> SOAC rep
JVP :: [SubExp] -> [SubExp] -> Lambda rep -> SOAC rep
VJP :: [SubExp] -> [SubExp] -> Lambda rep -> SOAC rep

-- | A combination of scan, reduction, and map. The first SubExp is
--   the size of the input arrays.
Screma :: SubExp -> [VName] -> ScremaForm rep -> SOAC rep

-- | How to compute a single reduction result.
data Reduce rep
Reduce :: Commutativity -> Lambda rep -> [SubExp] -> Reduce rep
[redComm] :: Reduce rep -> Commutativity
[redLambda] :: Reduce rep -> Lambda rep
[redNeutral] :: Reduce rep -> [SubExp]

-- | The essential parts of a Screma factored out (everything except
--   the input arrays).
data ScremaForm rep
ScremaForm :: Lambda rep -> [Scan rep] -> [Reduce rep] -> ScremaForm rep

-- | The "main" lambda of the Screma. For a map, this is equivalent to
--   isMapSOAC. Note that the meaning of the return value of this
--   lambda depends crucially on exactly which Screma this is. The
--   parameters will correspond exactly to elements of the input arrays,
--   however.
[scremaLambda] :: ScremaForm rep -> Lambda rep
[scremaScans] :: ScremaForm rep -> [Scan rep]
[scremaReduces] :: ScremaForm rep -> [Reduce rep]

-- | How the results of a scatter operation should be written. Each element
--   of the list consists of a v (often a VName) specifying
--   which array to scatter to, a ShapeBase describing the shape of
--   that array, and an Int describing how many elements should be
--   written to that array for each invocation of the scatter.
type ScatterSpec v = [(Shape, Int, v)]

-- | Like Mapper, but just for SOACs.
data SOACMapper frep trep m
SOACMapper :: (SubExp -> m SubExp) -> (Lambda frep -> m (Lambda trep)) -> (VName -> m VName) -> SOACMapper frep trep m
[mapOnSOACSubExp] :: SOACMapper frep trep m -> SubExp -> m SubExp
[mapOnSOACLambda] :: SOACMapper frep trep m -> Lambda frep -> m (Lambda trep)
[mapOnSOACVName] :: SOACMapper frep trep m -> VName -> m VName

-- | The types produced by a single Screma, given the size of the
--   input array.
scremaType :: SubExp -> ScremaForm rep -> [Type]

-- | How many reduction results are produced by these Scans?
scanResults :: [Scan rep] -> Int

-- | Combine multiple scan operators to a single operator.
singleScan :: Buildable rep => [Scan rep] -> Scan rep

-- | How many reduction results are produced by these Reduces?
redResults :: [Reduce rep] -> Int

-- | Combine multiple reduction operators to a single operator.
singleReduce :: Buildable rep => [Reduce rep] -> Reduce rep

-- | The type of a SOAC.
soacType :: Typed (LParamInfo rep) => SOAC rep -> [Type]

-- | Type-check a SOAC.
typeCheckSOAC :: Checkable rep => SOAC (Aliases rep) -> TypeM rep ()

-- | Construct a lambda that takes parameters of the given types and simply
--   returns them unchanged.
mkIdentityLambda :: (Buildable rep, MonadFreshNames m) => [Type] -> m (Lambda rep)

-- | Is the given lambda an identity lambda?
isIdentityLambda :: Lambda rep -> Bool

-- | A lambda with no parameters that returns no values.
nilFn :: Buildable rep => Lambda rep

-- | Construct a Screma with possibly multiple scans, and the given map
--   function.
scanomapSOAC :: [Scan rep] -> Lambda rep -> ScremaForm rep

-- | Construct a Screma with possibly multiple reductions, and the given
--   map function.
redomapSOAC :: [Reduce rep] -> Lambda rep -> ScremaForm rep

-- | Construct a Screma with possibly multiple scans, and identity map
--   function.
scanSOAC :: (Buildable rep, MonadFreshNames m) => [Scan rep] -> m (ScremaForm rep)

-- | Construct a Screma with possibly multiple reductions, and identity map
--   function.
reduceSOAC :: (Buildable rep, MonadFreshNames m) => [Reduce rep] -> m (ScremaForm rep)

-- | Construct a Screma corresponding to a map.
mapSOAC :: Lambda rep -> ScremaForm rep

-- | Does this Screma correspond to a scan-map composition?
isScanomapSOAC :: ScremaForm rep -> Maybe ([Scan rep], Lambda rep)

-- | Does this Screma correspond to a reduce-map composition?
isRedomapSOAC :: ScremaForm rep -> Maybe ([Reduce rep], Lambda rep)

-- | Does this Screma correspond to pure scan?
isScanSOAC :: ScremaForm rep -> Maybe [Scan rep]

-- | Does this Screma correspond to a pure reduce?
isReduceSOAC :: ScremaForm rep -> Maybe [Reduce rep]

-- | Does this Screma correspond to a simple map, without any reduction or
--   scan results?
isMapSOAC :: ScremaForm rep -> Maybe (Lambda rep)

-- | Prettyprint the given Screma.
ppScrema :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> ScremaForm rep -> Doc ann

-- | Prettyprint the given histogram operation.
ppHist :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> [HistOp rep] -> Lambda rep -> Doc ann

-- | Prettyprint the given Stream.
ppStream :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> [SubExp] -> Lambda rep -> Doc ann

-- | Prettyprint the given Scatter.
ppScatter :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> [(Shape, Int, VName)] -> Lambda rep -> Doc ann

-- | 
--   groupScatterResults specification results
--   
--   
--   Blocks the index values and result values of results according
--   to the specification.
--   
--   This function is used for extracting and grouping the results of a
--   scatter. In the SOACS representation, the lambda inside a
--   Scatter returns all indices and values as one big list. This
--   function groups each value with its corresponding indices (as
--   determined by the Shape of the output array).
--   
--   The elements of the resulting list correspond to the shape and name of
--   the output parameters, in addition to a list of values written to that
--   output parameter, along with the array indices marking where to write
--   them to.
--   
--   See Scatter for more information.
groupScatterResults :: ScatterSpec array -> [a] -> [(Shape, array, [([a], a)])]

-- | 
--   groupScatterResults' specification results
--   
--   
--   Blocks the index values and result values of results according
--   to the specification. This is the simpler version of
--   groupScatterResults, which doesn't return any information
--   about shapes or output arrays.
--   
--   See groupScatterResults for more information,
groupScatterResults' :: [(Shape, Int, array)] -> [a] -> [([a], a)]

-- | 
--   splitScatterResults specification results
--   
--   
--   Splits the results array into indices and values according to the
--   specification.
--   
--   See groupScatterResults for more information.
splitScatterResults :: [(Shape, Int, array)] -> [a] -> ([a], [a])

-- | A mapper that simply returns the SOAC verbatim.
identitySOACMapper :: forall rep m. Monad m => SOACMapper rep rep 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 :: Monad m => SOACMapper frep trep m -> SOAC frep -> m (SOAC trep)

-- | A helper for defining TraverseOpStms.
traverseSOACStms :: Monad m => OpStmsTraverser m (SOAC rep) rep
instance Futhark.IR.Rep.RepTypes Futhark.IR.MC.MC
instance Futhark.IR.Prop.ASTRep Futhark.IR.MC.MC
instance Futhark.IR.TypeCheck.Checkable Futhark.IR.MC.MC
instance Futhark.Builder.Class.Buildable Futhark.IR.MC.MC
instance Futhark.Builder.BuilderOps Futhark.IR.MC.MC
instance Futhark.Builder.BuilderOps (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.MC.MC)
instance Futhark.IR.Pretty.PrettyRep Futhark.IR.MC.MC
instance Futhark.IR.Traversals.TraverseOpStms (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.MC.MC)
instance Futhark.IR.SegOp.HasSegOp Futhark.IR.MC.MC
instance Futhark.IR.SegOp.HasSegOp (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.MC.MC)

module Futhark.IR.GPU.Op

-- | A simple size-level query or computation.
data 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

-- | CalcNumBlocks w max_num_tblocks tblock_size calculates the
--   number of GPU threadblocks 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.
CalcNumBlocks :: SubExp -> Name -> SubExp -> SizeOp

-- | A host-level operation; parameterised by what else it can do.
data HostOp op rep

-- | A segmented operation.
SegOp :: SegOp SegLevel rep -> HostOp op rep
SizeOp :: SizeOp -> HostOp op rep
OtherOp :: op rep -> HostOp op rep

-- | Code to run sequentially on the GPU, in a single thread.
GPUBody :: [Type] -> Body rep -> HostOp op rep

-- | A helper for defining TraverseOpStms.
traverseHostOpStms :: Monad m => OpStmsTraverser m (op rep) rep -> OpStmsTraverser m (HostOp op rep) rep
typeCheckHostOp :: Checkable rep => (SegLevel -> Op (Aliases rep) -> TypeM rep ()) -> Maybe SegLevel -> (op (Aliases rep) -> TypeM rep ()) -> HostOp op (Aliases rep) -> TypeM rep ()

-- | At which level the *body* of a SegOp executes.
data SegLevel
SegThread :: SegVirt -> Maybe KernelGrid -> SegLevel
SegBlock :: SegVirt -> Maybe KernelGrid -> SegLevel
SegThreadInBlock :: SegVirt -> SegLevel

-- | The SegVirt of the SegLevel.
segVirt :: SegLevel -> SegVirt

-- | Do we need block-virtualisation when generating code for the segmented
--   operation? In most cases, we do, but for some simple kernels, we
--   compute the full number of blocks 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 :: SegSeqDims -> SegVirt

-- | These dimensions (indexed from 0, outermost) of the corresponding
--   SegSpace should not be parallelised, but instead iterated
--   sequentially. For example, with a SegSeqDims of [0]
--   and a SegSpace with dimensions [n][m], there will be
--   an outer loop with n iterations, while the m
--   dimension will be parallelised.
--   
--   Semantically, this has no effect, but it may allow reductions in
--   memory usage or other low-level optimisations. Operationally, the
--   guarantee is that for a SegSeqDims of e.g. [i,j,k], threads
--   running at any given moment will always have the same indexes along
--   the dimensions specified by [i,j,k].
--   
--   At the moment, this is only supported for SegNoVirtFull
--   intra-block parallelism in GPU code, as we have not yet found it
--   useful anywhere else.
newtype SegSeqDims
SegSeqDims :: [Int] -> SegSeqDims
[segSeqDims] :: SegSeqDims -> [Int]

-- | The actual, physical grid dimensions used for the GPU kernel running
--   this HostOp.
data KernelGrid
KernelGrid :: Count NumBlocks SubExp -> Count BlockSize SubExp -> KernelGrid
[gridNumBlocks] :: KernelGrid -> Count NumBlocks SubExp
[gridBlockSize] :: KernelGrid -> Count BlockSize SubExp
instance GHC.Show.Show Futhark.IR.GPU.Op.SegSeqDims
instance GHC.Classes.Ord Futhark.IR.GPU.Op.SegSeqDims
instance GHC.Classes.Eq Futhark.IR.GPU.Op.SegSeqDims
instance GHC.Show.Show Futhark.IR.GPU.Op.SegVirt
instance GHC.Classes.Ord Futhark.IR.GPU.Op.SegVirt
instance GHC.Classes.Eq Futhark.IR.GPU.Op.SegVirt
instance GHC.Show.Show Futhark.IR.GPU.Op.KernelGrid
instance GHC.Classes.Ord Futhark.IR.GPU.Op.KernelGrid
instance GHC.Classes.Eq Futhark.IR.GPU.Op.KernelGrid
instance GHC.Show.Show Futhark.IR.GPU.Op.SegLevel
instance GHC.Classes.Ord Futhark.IR.GPU.Op.SegLevel
instance GHC.Classes.Eq Futhark.IR.GPU.Op.SegLevel
instance GHC.Show.Show Futhark.IR.GPU.Op.SizeOp
instance GHC.Classes.Ord Futhark.IR.GPU.Op.SizeOp
instance GHC.Classes.Eq Futhark.IR.GPU.Op.SizeOp
instance (Futhark.IR.Rep.RepTypes rep, GHC.Show.Show (op rep)) => GHC.Show.Show (Futhark.IR.GPU.Op.HostOp op rep)
instance (Futhark.IR.Rep.RepTypes rep, GHC.Classes.Ord (op rep)) => GHC.Classes.Ord (Futhark.IR.GPU.Op.HostOp op rep)
instance (Futhark.IR.Rep.RepTypes rep, GHC.Classes.Eq (op rep)) => GHC.Classes.Eq (Futhark.IR.GPU.Op.HostOp op rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.Transform.Substitute.Substitute (op rep)) => Futhark.Transform.Substitute.Substitute (Futhark.IR.GPU.Op.HostOp op rep)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.Transform.Rename.Rename (op rep)) => Futhark.Transform.Rename.Rename (Futhark.IR.GPU.Op.HostOp op rep)
instance Futhark.IR.Prop.IsOp op => Futhark.IR.Prop.IsOp (Futhark.IR.GPU.Op.HostOp op)
instance Futhark.IR.Prop.TypeOf.TypedOp op => Futhark.IR.Prop.TypeOf.TypedOp (Futhark.IR.GPU.Op.HostOp op)
instance Futhark.IR.Prop.Aliases.AliasedOp op => Futhark.IR.Prop.Aliases.AliasedOp (Futhark.IR.GPU.Op.HostOp op)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.IR.Prop.Names.FreeIn (op rep)) => Futhark.IR.Prop.Names.FreeIn (Futhark.IR.GPU.Op.HostOp op rep)
instance Futhark.IR.Aliases.CanBeAliased op => Futhark.IR.Aliases.CanBeAliased (Futhark.IR.GPU.Op.HostOp op)
instance Futhark.Optimise.Simplify.Rep.CanBeWise op => Futhark.Optimise.Simplify.Rep.CanBeWise (Futhark.IR.GPU.Op.HostOp op)
instance Futhark.IR.Mem.OpReturns (Futhark.IR.GPU.Op.HostOp Futhark.IR.Rep.NoOp)
instance (Futhark.IR.Prop.ASTRep rep, Futhark.Analysis.SymbolTable.IndexOp (op rep)) => Futhark.Analysis.SymbolTable.IndexOp (Futhark.IR.GPU.Op.HostOp op rep)
instance (Futhark.IR.Pretty.PrettyRep rep, Prettyprinter.Internal.Pretty (op rep)) => Prettyprinter.Internal.Pretty (Futhark.IR.GPU.Op.HostOp op rep)
instance (Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.Rep.Op rep), Futhark.Analysis.Metrics.OpMetrics (op rep)) => Futhark.Analysis.Metrics.OpMetrics (Futhark.IR.GPU.Op.HostOp op rep)
instance Futhark.IR.Rephrase.RephraseOp op => Futhark.IR.Rephrase.RephraseOp (Futhark.IR.GPU.Op.HostOp op)
instance Futhark.Transform.Substitute.Substitute Futhark.IR.GPU.Op.SizeOp
instance Futhark.Transform.Rename.Rename Futhark.IR.GPU.Op.SizeOp
instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.GPU.Op.SizeOp
instance Prettyprinter.Internal.Pretty Futhark.IR.GPU.Op.SizeOp
instance Futhark.Analysis.Metrics.OpMetrics Futhark.IR.GPU.Op.SizeOp
instance Prettyprinter.Internal.Pretty Futhark.IR.GPU.Op.SegLevel
instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.GPU.Op.SegLevel
instance Futhark.Transform.Substitute.Substitute Futhark.IR.GPU.Op.SegLevel
instance Futhark.Transform.Rename.Rename Futhark.IR.GPU.Op.SegLevel
instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.GPU.Op.SegLevel
instance Prettyprinter.Internal.Pretty Futhark.IR.GPU.Op.KernelGrid
instance Futhark.Optimise.Simplify.Engine.Simplifiable Futhark.IR.GPU.Op.KernelGrid
instance Futhark.Transform.Substitute.Substitute Futhark.IR.GPU.Op.KernelGrid
instance Futhark.IR.Prop.Names.FreeIn Futhark.IR.GPU.Op.KernelGrid
instance Prettyprinter.Internal.Pretty Futhark.IR.GPU.Op.SegVirt

module Futhark.Pass.ExtractKernels.BlockedKernel

-- | Constraints pertinent to performing distribution/flattening.
type DistRep rep = (Buildable rep, HasSegOp rep, BuilderOps rep, LetDec rep ~ Type, ExpDec rep ~ (), BodyDec rep ~ (), AliasableRep rep)
type MkSegLevel rep m = [SubExp] -> String -> ThreadRecommendation -> BuilderT rep m (SegOpLevel rep)
data ThreadRecommendation
ManyThreads :: ThreadRecommendation
NoRecommendation :: SegVirt -> ThreadRecommendation
segRed :: (MonadFreshNames m, DistRep rep, HasScope rep m) => SegOpLevel rep -> Pat (LetDec rep) -> Certs -> SubExp -> [SegBinOp rep] -> Lambda rep -> [VName] -> [(VName, SubExp)] -> [KernelInput] -> m (Stms rep)
nonSegRed :: (MonadFreshNames m, DistRep rep, HasScope rep m) => SegOpLevel rep -> Pat Type -> SubExp -> [SegBinOp rep] -> Lambda rep -> [VName] -> m (Stms rep)
segScan :: (MonadFreshNames m, DistRep rep, HasScope rep m) => SegOpLevel rep -> Pat (LetDec rep) -> Certs -> SubExp -> [SegBinOp rep] -> Lambda rep -> [VName] -> [(VName, SubExp)] -> [KernelInput] -> m (Stms rep)
segHist :: (DistRep rep, MonadFreshNames m, HasScope rep m) => SegOpLevel rep -> Pat Type -> SubExp -> [(VName, SubExp)] -> [KernelInput] -> [HistOp rep] -> Lambda rep -> [VName] -> m (Stms rep)
segMap :: (MonadFreshNames m, DistRep rep, HasScope rep m) => SegOpLevel rep -> Pat (LetDec rep) -> SubExp -> Lambda rep -> [VName] -> [(VName, SubExp)] -> [KernelInput] -> m (Stms rep)
mapKernel :: (DistRep rep, HasScope rep m, MonadFreshNames m) => MkSegLevel rep m -> [(VName, SubExp)] -> [KernelInput] -> [Type] -> KernelBody rep -> m (SegOp (SegOpLevel rep) rep, Stms rep)
data KernelInput
KernelInput :: VName -> Type -> VName -> [SubExp] -> KernelInput
[kernelInputName] :: KernelInput -> VName
[kernelInputType] :: KernelInput -> Type
[kernelInputArray] :: KernelInput -> VName
[kernelInputIndices] :: KernelInput -> [SubExp]
readKernelInput :: (DistRep (Rep m), MonadBuilder m) => KernelInput -> m ()
mkSegSpace :: MonadFreshNames m => [(VName, SubExp)] -> m SegSpace
dummyDim :: MonadBuilder m => Pat Type -> m (Pat Type, [(VName, SubExp)], m ())
instance GHC.Show.Show Futhark.Pass.ExtractKernels.BlockedKernel.KernelInput

module Futhark.Pass.ExtractKernels.Distribution
type Target = (Pat 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 :: DistRep rep => Targets -> Scope rep
data LoopNesting
MapNesting :: Pat Type -> StmAux () -> SubExp -> [(Param Type, VName)] -> LoopNesting
[loopNestingPat] :: LoopNesting -> Pat Type
[loopNestingAux] :: LoopNesting -> StmAux ()
[loopNestingWidth] :: LoopNesting -> SubExp
[loopNestingParamsAndArrs] :: LoopNesting -> [(Param Type, VName)]
ppLoopNesting :: LoopNesting -> String
scopeOfLoopNesting :: LParamInfo rep ~ Type => LoopNesting -> Scope rep
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
scopeOfKernelNest :: LParamInfo rep ~ Type => KernelNest -> Scope rep
kernelNestLoops :: KernelNest -> [LoopNesting]
kernelNestWidths :: KernelNest -> [SubExp]
boundInKernelNest :: KernelNest -> Names
boundInKernelNests :: KernelNest -> [Names]

-- | Flatten a kernel nesting to:
--   
--   
--   
- The index space.
--   
- The kernel inputs - note that some of these may be unused.
--   
flatKernel :: MonadFreshNames m => KernelNest -> m ([(VName, SubExp)], [KernelInput])
constructKernel :: (DistRep rep, MonadFreshNames m, LocalScope rep m) => MkSegLevel rep m -> KernelNest -> Body rep -> m (Stm rep, Stms rep)
tryDistribute :: (DistRep rep, MonadFreshNames m, LocalScope rep m, MonadLogger m) => MkSegLevel rep m -> Nestings -> Targets -> Stms rep -> m (Maybe (Targets, Stms rep))
tryDistributeStm :: (MonadFreshNames m, HasScope t m, ASTRep rep) => Nestings -> Targets -> Stm rep -> 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] -> Pat Type -> [(FParam SOACS, SubExp)] -> LoopForm -> Body SOACS -> 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)

-- | An encoding of a branch with alongside its result pattern.
data Branch
Branch :: [Int] -> Pat Type -> [SubExp] -> [Case (Body SOACS)] -> Body SOACS -> MatchDec (BranchType SOACS) -> Branch

-- | Given a (parallel) map nesting and an inner branch, move the maps
--   inside the branch. The result is the resulting branch expression,
--   which will then contain statements with map expressions.
interchangeBranch :: (MonadFreshNames m, HasScope SOACS m) => KernelNest -> Branch -> m (Stm SOACS)

-- | An encoding of a WithAcc with alongside its result pattern.
data WithAccStm
WithAccStm :: [Int] -> Pat Type -> [(Shape, [VName], Maybe (Lambda SOACS, [SubExp]))] -> Lambda SOACS -> WithAccStm

-- | Given a (parallel) map nesting and an inner withacc, move the maps
--   inside the branch. The result is the resulting withacc expression,
--   which will then contain statements with map expressions.
interchangeWithAcc :: (MonadFreshNames m, LocalScope SOACS m) => KernelNest -> WithAccStm -> m (Stm SOACS)

module Futhark.Pass.ExtractKernels.DistributeNests
data MapLoop
MapLoop :: Pat Type -> StmAux () -> SubExp -> Lambda SOACS -> [VName] -> MapLoop
mapLoopStm :: MapLoop -> Stm SOACS
bodyContainsParallelism :: Body SOACS -> Bool
lambdaContainsParallelism :: Lambda SOACS -> Bool
determineReduceOp :: MonadBuilder m => Lambda SOACS -> [SubExp] -> m (Lambda SOACS, [SubExp], Shape)
histKernel :: (MonadBuilder m, DistRep (Rep m)) => (Lambda SOACS -> m (Lambda (Rep m))) -> SegOpLevel (Rep m) -> Pat Type -> [(VName, SubExp)] -> [KernelInput] -> Certs -> SubExp -> [HistOp SOACS] -> Lambda (Rep m) -> [VName] -> m (Stms (Rep m))
data DistEnv rep m
DistEnv :: Nestings -> Scope rep -> (Stms SOACS -> DistNestT rep m (Stms rep)) -> (MapLoop -> DistAcc rep -> DistNestT rep m (DistAcc rep)) -> (Stm SOACS -> Builder rep (Stms rep)) -> (Lambda SOACS -> Builder rep (Lambda rep)) -> MkSegLevel rep m -> DistEnv rep m
[distNest] :: DistEnv rep m -> Nestings
[distScope] :: DistEnv rep m -> Scope rep
[distOnTopLevelStms] :: DistEnv rep m -> Stms SOACS -> DistNestT rep m (Stms rep)
[distOnInnerMap] :: DistEnv rep m -> MapLoop -> DistAcc rep -> DistNestT rep m (DistAcc rep)
[distOnSOACSStms] :: DistEnv rep m -> Stm SOACS -> Builder rep (Stms rep)
[distOnSOACSLambda] :: DistEnv rep m -> Lambda SOACS -> Builder rep (Lambda rep)
[distSegLevel] :: DistEnv rep m -> MkSegLevel rep m
data DistAcc rep
DistAcc :: Targets -> Stms rep -> DistAcc rep
[distTargets] :: DistAcc rep -> Targets
[distStms] :: DistAcc rep -> Stms rep
runDistNestT :: (MonadLogger m, DistRep rep) => DistEnv rep m -> DistNestT rep m (DistAcc rep) -> m (Stms rep)
data DistNestT rep m a
liftInner :: (LocalScope rep m, DistRep rep) => m a -> DistNestT rep m a
distributeMap :: (MonadFreshNames m, LocalScope rep m, DistRep rep) => MapLoop -> DistAcc rep -> DistNestT rep m (DistAcc rep)
distribute :: (MonadFreshNames m, LocalScope rep m, DistRep rep) => DistAcc rep -> DistNestT rep m (DistAcc rep)
distributeSingleStm :: (MonadFreshNames m, LocalScope rep m, DistRep rep) => DistAcc rep -> Stm SOACS -> DistNestT rep m (Maybe (PostStms rep, Result, KernelNest, DistAcc rep))
distributeMapBodyStms :: (MonadFreshNames m, LocalScope rep m, DistRep rep) => DistAcc rep -> Stms SOACS -> DistNestT rep m (DistAcc rep)
addStmsToAcc :: Stms rep -> DistAcc rep -> DistAcc rep
addStmToAcc :: (MonadFreshNames m, DistRep rep) => Stm SOACS -> DistAcc rep -> DistNestT rep m (DistAcc rep)
permutationAndMissing :: Pat Type -> Result -> Maybe ([Int], [PatElem Type])
addPostStms :: Monad m => PostStms rep -> DistNestT rep m ()
postStm :: Monad m => Stms rep -> DistNestT rep m ()
inNesting :: (Monad m, DistRep rep) => KernelNest -> DistNestT rep m a -> DistNestT rep m a
instance GHC.Base.Monad m => Control.Monad.Writer.Class.MonadWriter (Futhark.Pass.ExtractKernels.DistributeNests.DistRes rep) (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT rep m)
instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (Futhark.Pass.ExtractKernels.DistributeNests.DistEnv rep m) (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT rep m)
instance GHC.Base.Monad m => GHC.Base.Monad (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT rep m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT rep m)
instance GHC.Base.Functor m => GHC.Base.Functor (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT rep m)
instance Futhark.MonadFreshNames.MonadFreshNames m => Futhark.MonadFreshNames.MonadFreshNames (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT rep m)
instance (GHC.Base.Monad m, Futhark.IR.Prop.ASTRep rep) => Futhark.IR.Prop.Scope.HasScope rep (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT rep m)
instance (GHC.Base.Monad m, Futhark.IR.Prop.ASTRep rep) => Futhark.IR.Prop.Scope.LocalScope rep (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT rep m)
instance GHC.Base.Monad m => Futhark.Util.Log.MonadLogger (Futhark.Pass.ExtractKernels.DistributeNests.DistNestT rep m)
instance GHC.Base.Semigroup (Futhark.Pass.ExtractKernels.DistributeNests.DistRes rep)
instance GHC.Base.Monoid (Futhark.Pass.ExtractKernels.DistributeNests.DistRes rep)
instance GHC.Base.Semigroup (Futhark.Pass.ExtractKernels.DistributeNests.PostStms rep)
instance GHC.Base.Monoid (Futhark.Pass.ExtractKernels.DistributeNests.PostStms rep)

-- | A representation with flat parallelism via GPU-oriented kernels.
module Futhark.IR.GPU

-- | The phantom data type for the kernels representation.
data GPU

-- | How to compute a single scan result.
data Scan rep
Scan :: Lambda rep -> [SubExp] -> Scan rep
[scanLambda] :: Scan rep -> Lambda rep
[scanNeutral] :: Scan rep -> [SubExp]

-- | A second-order array combinator (SOAC).
data SOAC rep
Stream :: SubExp -> [VName] -> [SubExp] -> Lambda rep -> SOAC rep

-- | 
--   Scatter length inputs lambda spec
--   
--   
--   Scatter maps values from a set of input arrays to indices and values
--   of a set of output arrays. It is able to write multiple values to
--   multiple outputs each of which may have multiple dimensions.
--   
--   inputs is a list of input arrays, all having size
--   length, elements of which are applied to the lambda
--   function. For instance, if there are two arrays, lambda will
--   get two values as input, one from each array.
--   
--   spec specifies the result of the lambda and which arrays
--   to write to.
--   
--   lambda is a function that takes inputs from inputs and
--   returns values according to spec. It returns values in the
--   following manner:
--   
--   
--   
- index_0, index_1, ..., index_n, value_0, value_1, ...,
--   value_m
--   
--   
--   For each output in spec, lambda returns i *
--   j index values and j output values, where i is
--   the number of dimensions (rank) of the given output, and j is
--   the number of output values written to the given output.
--   
--   For example, given the following scatter specification:
--   
--   
--   
- ([x1, y1, z1 , 2, arr1), ([x2, y2], 1, arr2)]
--   
--   
--   lambda will produce 6 (3 * 2) index values and 2 output values
--   for arr1, and 2 (2 * 1) index values and 1 output value for
--   arr2. Additionally, the results are grouped, so the first 6 index
--   values will correspond to the first two output values, and so on. For
--   this example, lambda should return a total of 11 values, 8
--   index values and 3 output values. See also splitScatterResults.
Scatter :: SubExp -> [VName] -> ScatterSpec VName -> Lambda rep -> SOAC rep

-- | 
--   Hist length arrays dest-arrays-and-ops fun
--   
--   
--   The final lambda produces indexes and values for the HistOps.
Hist :: SubExp -> [VName] -> [HistOp rep] -> Lambda rep -> SOAC rep
JVP :: [SubExp] -> [SubExp] -> Lambda rep -> SOAC rep
VJP :: [SubExp] -> [SubExp] -> Lambda rep -> SOAC rep

-- | A combination of scan, reduction, and map. The first SubExp is
--   the size of the input arrays.
Screma :: SubExp -> [VName] -> ScremaForm rep -> SOAC rep

-- | How to compute a single reduction result.
data Reduce rep
Reduce :: Commutativity -> Lambda rep -> [SubExp] -> Reduce rep
[redComm] :: Reduce rep -> Commutativity
[redLambda] :: Reduce rep -> Lambda rep
[redNeutral] :: Reduce rep -> [SubExp]

-- | The essential parts of a Screma factored out (everything except
--   the input arrays).
data ScremaForm rep
ScremaForm :: Lambda rep -> [Scan rep] -> [Reduce rep] -> ScremaForm rep

-- | The "main" lambda of the Screma. For a map, this is equivalent to
--   isMapSOAC. Note that the meaning of the return value of this
--   lambda depends crucially on exactly which Screma this is. The
--   parameters will correspond exactly to elements of the input arrays,
--   however.
[scremaLambda] :: ScremaForm rep -> Lambda rep
[scremaScans] :: ScremaForm rep -> [Scan rep]
[scremaReduces] :: ScremaForm rep -> [Reduce rep]

-- | How the results of a scatter operation should be written. Each element
--   of the list consists of a v (often a VName) specifying
--   which array to scatter to, a ShapeBase describing the shape of
--   that array, and an Int describing how many elements should be
--   written to that array for each invocation of the scatter.
type ScatterSpec v = [(Shape, Int, v)]

-- | Like Mapper, but just for SOACs.
data SOACMapper frep trep m
SOACMapper :: (SubExp -> m SubExp) -> (Lambda frep -> m (Lambda trep)) -> (VName -> m VName) -> SOACMapper frep trep m
[mapOnSOACSubExp] :: SOACMapper frep trep m -> SubExp -> m SubExp
[mapOnSOACLambda] :: SOACMapper frep trep m -> Lambda frep -> m (Lambda trep)
[mapOnSOACVName] :: SOACMapper frep trep m -> VName -> m VName

-- | The types produced by a single Screma, given the size of the
--   input array.
scremaType :: SubExp -> ScremaForm rep -> [Type]

-- | How many reduction results are produced by these Scans?
scanResults :: [Scan rep] -> Int

-- | Combine multiple scan operators to a single operator.
singleScan :: Buildable rep => [Scan rep] -> Scan rep

-- | How many reduction results are produced by these Reduces?
redResults :: [Reduce rep] -> Int

-- | Combine multiple reduction operators to a single operator.
singleReduce :: Buildable rep => [Reduce rep] -> Reduce rep

-- | The type of a SOAC.
soacType :: Typed (LParamInfo rep) => SOAC rep -> [Type]

-- | Type-check a SOAC.
typeCheckSOAC :: Checkable rep => SOAC (Aliases rep) -> TypeM rep ()

-- | Construct a lambda that takes parameters of the given types and simply
--   returns them unchanged.
mkIdentityLambda :: (Buildable rep, MonadFreshNames m) => [Type] -> m (Lambda rep)

-- | Is the given lambda an identity lambda?
isIdentityLambda :: Lambda rep -> Bool

-- | A lambda with no parameters that returns no values.
nilFn :: Buildable rep => Lambda rep

-- | Construct a Screma with possibly multiple scans, and the given map
--   function.
scanomapSOAC :: [Scan rep] -> Lambda rep -> ScremaForm rep

-- | Construct a Screma with possibly multiple reductions, and the given
--   map function.
redomapSOAC :: [Reduce rep] -> Lambda rep -> ScremaForm rep

-- | Construct a Screma with possibly multiple scans, and identity map
--   function.
scanSOAC :: (Buildable rep, MonadFreshNames m) => [Scan rep] -> m (ScremaForm rep)

-- | Construct a Screma with possibly multiple reductions, and identity map
--   function.
reduceSOAC :: (Buildable rep, MonadFreshNames m) => [Reduce rep] -> m (ScremaForm rep)

-- | Construct a Screma corresponding to a map.
mapSOAC :: Lambda rep -> ScremaForm rep

-- | Does this Screma correspond to a scan-map composition?
isScanomapSOAC :: ScremaForm rep -> Maybe ([Scan rep], Lambda rep)

-- | Does this Screma correspond to a reduce-map composition?
isRedomapSOAC :: ScremaForm rep -> Maybe ([Reduce rep], Lambda rep)

-- | Does this Screma correspond to pure scan?
isScanSOAC :: ScremaForm rep -> Maybe [Scan rep]

-- | Does this Screma correspond to a pure reduce?
isReduceSOAC :: ScremaForm rep -> Maybe [Reduce rep]

-- | Does this Screma correspond to a simple map, without any reduction or
--   scan results?
isMapSOAC :: ScremaForm rep -> Maybe (Lambda rep)

-- | Prettyprint the given Screma.
ppScrema :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> ScremaForm rep -> Doc ann

-- | Prettyprint the given histogram operation.
ppHist :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> [HistOp rep] -> Lambda rep -> Doc ann

-- | Prettyprint the given Stream.
ppStream :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> [SubExp] -> Lambda rep -> Doc ann

-- | Prettyprint the given Scatter.
ppScatter :: (PrettyRep rep, Pretty inp) => SubExp -> [inp] -> [(Shape, Int, VName)] -> Lambda rep -> Doc ann

-- | 
--   groupScatterResults specification results
--   
--   
--   Blocks the index values and result values of results according
--   to the specification.
--   
--   This function is used for extracting and grouping the results of a
--   scatter. In the SOACS representation, the lambda inside a
--   Scatter returns all indices and values as one big list. This
--   function groups each value with its corresponding indices (as
--   determined by the Shape of the output array).
--   
--   The elements of the resulting list correspond to the shape and name of
--   the output parameters, in addition to a list of values written to that
--   output parameter, along with the array indices marking where to write
--   them to.
--   
--   See Scatter for more information.
groupScatterResults :: ScatterSpec array -> [a] -> [(Shape, array, [([a], a)])]

-- | 
--   groupScatterResults' specification results
--   
--   
--   Blocks the index values and result values of results according
--   to the specification. This is the simpler version of
--   groupScatterResults, which doesn't return any information
--   about shapes or output arrays.
--   
--   See groupScatterResults for more information,
groupScatterResults' :: [(Shape, Int, array)] -> [a] -> [([a], a)]

-- | 
--   splitScatterResults specification results
--   
--   
--   Splits the results array into indices and values according to the
--   specification.
--   
--   See groupScatterResults for more information.
splitScatterResults :: [(Shape, Int, array)] -> [a] -> ([a], [a])

-- | A mapper that simply returns the SOAC verbatim.
identitySOACMapper :: forall rep m. Monad m => SOACMapper rep rep 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 :: Monad m => SOACMapper frep trep m -> SOAC frep -> m (SOAC trep)

-- | A helper for defining TraverseOpStms.
traverseSOACStms :: Monad m => OpStmsTraverser m (SOAC rep) rep
instance Futhark.IR.Rep.RepTypes Futhark.IR.GPU.GPU
instance Futhark.IR.Prop.ASTRep Futhark.IR.GPU.GPU
instance Futhark.IR.TypeCheck.Checkable Futhark.IR.GPU.GPU
instance Futhark.Builder.Class.Buildable Futhark.IR.GPU.GPU
instance Futhark.Builder.BuilderOps Futhark.IR.GPU.GPU
instance Futhark.IR.Pretty.PrettyRep Futhark.IR.GPU.GPU
instance Futhark.IR.SegOp.HasSegOp Futhark.IR.GPU.GPU

module Futhark.Pass.ExtractKernels.ToGPU
getSize :: (MonadBuilder m, Op (Rep m) ~ HostOp inner (Rep m)) => String -> SizeClass -> m SubExp
segThread :: (MonadBuilder m, Op (Rep m) ~ HostOp inner (Rep m)) => String -> m SegLevel
soacsLambdaToGPU :: Lambda SOACS -> Lambda GPU
soacsStmToGPU :: Stm SOACS -> Stm GPU
scopeForGPU :: Scope SOACS -> Scope GPU
scopeForSOACs :: Scope GPU -> 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

-- | Extraction of parallelism from a SOACs program. This generates
--   parallel constructs aimed at CPU execution, which in particular may
--   involve ad-hoc irregular nested parallelism.
module Futhark.Pass.ExtractMulticore

-- | Transform a program using SOACs to a program in the MC
--   representation, using some amount of flattening.
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 GPU m
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 threadblocks.
module Futhark.Pass.ExtractKernels.Intrablock

-- | 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 shared memory.
--   
--   We distinguish between "minimum group size" and "maximum exploitable
--   parallelism".
intrablockParallelise :: (MonadFreshNames m, LocalScope GPU m) => KernelNest -> Lambda SOACS -> m (Maybe ((SubExp, SubExp), SubExp, Log, Stms GPU, Stms GPU))
instance Futhark.Util.Log.MonadLogger Futhark.Pass.ExtractKernels.Intrablock.IntrablockM
instance GHC.Base.Semigroup Futhark.Pass.ExtractKernels.Intrablock.IntraAcc
instance GHC.Base.Monoid Futhark.Pass.ExtractKernels.Intrablock.IntraAcc

-- | 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)
--     stms_a...
--     map(g)
--   
--   
--   Then we want to distribute to:
--   
--   
--   map
--     map(f)
--   map
--     stms_a
--   map
--     map(g)
--   
--   
--   But for now only if
--   
--   
--   
- 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 stms_a that is also used in
--   map(g), must be invariant to the outermost loop.
--   
- the maps are _balanced_. That is, the functions f and
--   g must do the same amount of work for every iteration.
--   
--   
--   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 stms_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 GPU
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.GPU.GPU Futhark.Pass.ExtractKernels.DistribM
instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.GPU.GPU 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

module Futhark.Optimise.TileLoops.Shared
type TileM = ReaderT (Scope GPU) (State VNameSource)
type Env = (WithEnv, IxFnEnv)
index :: MonadBuilder m => String -> VName -> [VName] -> m VName
update :: MonadBuilder m => String -> VName -> [VName] -> SubExp -> m VName
forLoop' :: SubExp -> [VName] -> (VName -> [VName] -> Builder GPU (Body GPU)) -> Builder GPU [VName]
forLoop :: SubExp -> [VName] -> (VName -> [VName] -> Builder GPU (Body GPU)) -> Builder GPU VName
segMap1D :: String -> SegLevel -> ResultManifest -> SubExp -> (VName -> Builder GPU Result) -> Builder GPU [VName]
segMap2D :: String -> SegLevel -> ResultManifest -> (SubExp, SubExp) -> ((VName, VName) -> Builder GPU Result) -> Builder GPU [VName]
segMap3D :: String -> SegLevel -> ResultManifest -> (SubExp, SubExp, SubExp) -> ((VName, VName, VName) -> Builder GPU Result) -> Builder GPU [VName]
segScatter2D :: String -> VName -> [SubExp] -> (SubExp, SubExp) -> ([VName] -> (VName, VName) -> Builder GPU (SubExp, SubExp)) -> Builder GPU VName

-- | The variance table keeps a mapping from a variable name (something
--   produced by a Stm) to the kernel thread indices that name
--   depends on. If a variable is not present in this table, that means it
--   is bound outside the kernel (and so can be considered invariant to all
--   dimensions).
type VarianceTable = Map VName Names
varianceInStms :: VarianceTable -> Stms GPU -> VarianceTable
isTileableRedomap :: Stm GPU -> Maybe (SubExp, [VName], (Commutativity, Lambda GPU, [SubExp], Lambda GPU))
changeEnv :: Env -> VName -> Exp GPU -> TileM Env

-- | Are we working with full or partial tiles?
data TileKind
TilePartial :: TileKind
TileFull :: TileKind

-- | 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 post-SOACS representations. This is not
--   because we do anything GPU-specific here, but simply because more
--   explicit indexing is going on after SOACs are gone.
module Futhark.Optimise.Sink

-- | Sinking in GPU kernels.
sinkGPU :: Pass GPU GPU

-- | Sinking for multicore.
sinkMC :: Pass MC MC

-- | This module implements program analysis to determine which program
--   statements the Futhark.Optimise.ReduceDeviceSyncs pass should
--   move into GPUBody kernels to reduce blocking memory transfers
--   between host and device. The results of the analysis is encoded into a
--   MigrationTable which can be queried.
--   
--   To reduce blocking scalar reads the module constructs a data flow
--   dependency graph of program variables (see
--   Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.Graph) in
--   which it finds a minimum vertex cut that separates array reads of
--   scalars from transitive usage that cannot or should not be migrated to
--   device.
--   
--   The variables of each partition are assigned a MigrationStatus
--   that states whether the computation of those variables should be moved
--   to device or remain on host. Due to how the graph is built and the
--   vertex cut is found all variables bound by a single statement will
--   belong to the same partition.
--   
--   The vertex cut contains all variables that will reside in device
--   memory but are required by host operations. These variables must be
--   read from device memory and cannot be reduced further in number merely
--   by migrating statements (subject to the accuracy of the graph model).
--   The model is built to reduce the worst-case number of scalar reads; an
--   optimal migration of statements depends on runtime data.
--   
--   Blocking scalar writes are reduced by either turning such writes into
--   asynchronous kernels, as is done with scalar array literals and
--   accumulator updates, or by transforming host-device writing into
--   device-device copying.
--   
--   For details on how the graph is constructed and how the vertex cut is
--   found, see the master thesis "Reducing Synchronous GPU Memory
--   Transfers" by Philip Børgesen (2022).
module Futhark.Optimise.ReduceDeviceSyncs.MigrationTable

-- | Analyses a top-level function definition.
analyseFunDef :: HostOnlyFuns -> FunDef GPU -> MigrationTable

-- | Analyses top-level constants.
analyseConsts :: HostOnlyFuns -> [FunDef GPU] -> Stms GPU -> MigrationTable

-- | Returns the names of all top-level functions that cannot be called
--   from the device. The evaluation of such a function is host-only.
hostOnlyFunDefs :: [FunDef GPU] -> HostOnlyFuns

-- | Identifies
--   
--   
--   
- which statements should be moved from host to device to reduce the
--   worst case number of blocking memory transfers.
--   
- which migrated variables that still will be used on the host after
--   all such statements have been moved.
--   
data MigrationTable

-- | Where the value bound by a name should be computed.
data MigrationStatus

-- | The statement that computes the value should be moved to device. No
--   host usage of the value will be left after the migration.
MoveToDevice :: MigrationStatus

-- | As MoveToDevice but host usage of the value will remain after
--   migration.
UsedOnHost :: MigrationStatus

-- | The statement that computes the value should remain on host.
StayOnHost :: MigrationStatus

-- | Should this whole statement be moved from host to device?
shouldMoveStm :: Stm GPU -> MigrationTable -> Bool

-- | Should the value bound by this name be computed on device?
shouldMove :: VName -> MigrationTable -> Bool

-- | Will the value bound by this name be used on host?
usedOnHost :: VName -> MigrationTable -> Bool

-- | Where should the value bound by this name be computed?
statusOf :: VName -> MigrationTable -> MigrationStatus
instance GHC.Show.Show Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.MigrationStatus
instance GHC.Classes.Ord Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.MigrationStatus
instance GHC.Classes.Eq Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.MigrationStatus
instance GHC.Base.Semigroup Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.BodyStats
instance GHC.Base.Monoid Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.BodyStats
instance GHC.Base.Semigroup Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.MigrationTable

-- | This module implements an optimization that migrates host statements
--   into GPUBody kernels to reduce the number of host-device
--   synchronizations that occur when a scalar variable is written to or
--   read from device memory. Which statements that should be migrated are
--   determined by a MigrationTable produced by the
--   Futhark.Optimise.ReduceDeviceSyncs.MigrationTable module; this
--   module merely performs the migration and rewriting dictated by that
--   table.
module Futhark.Optimise.ReduceDeviceSyncs

-- | An optimization pass that migrates host statements into GPUBody
--   kernels to reduce the number of host-device synchronizations.
reduceDeviceSyncs :: Pass GPU GPU
instance Control.Monad.Reader.Class.MonadReader Futhark.Optimise.ReduceDeviceSyncs.MigrationTable.MigrationTable Futhark.Optimise.ReduceDeviceSyncs.ReduceM
instance Control.Monad.State.Class.MonadState Futhark.Optimise.ReduceDeviceSyncs.State Futhark.Optimise.ReduceDeviceSyncs.ReduceM
instance GHC.Base.Monad Futhark.Optimise.ReduceDeviceSyncs.ReduceM
instance GHC.Base.Applicative Futhark.Optimise.ReduceDeviceSyncs.ReduceM
instance GHC.Base.Functor Futhark.Optimise.ReduceDeviceSyncs.ReduceM
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Optimise.ReduceDeviceSyncs.ReduceM

-- | This module implements an optimization pass that merges GPUBody
--   kernels to eliminate memory transactions and reduce the number of
--   kernel launches. This is useful because the
--   Futhark.Optimise.ReduceDeviceSyncs pass introduces
--   GPUBody kernels that only execute single statements.
--   
--   To merge as many GPUBody kernels as possible, this pass
--   reorders statements with the goal of bringing as many GPUBody
--   statements next to each other in a sequence. Such sequence can then
--   trivially be merged.
module Futhark.Optimise.MergeGPUBodies

-- | An optimization pass that reorders and merges GPUBody
--   statements to eliminate memory transactions and reduce the number of
--   kernel launches.
mergeGPUBodies :: Pass GPU GPU
instance GHC.Base.Semigroup Futhark.Optimise.MergeGPUBodies.Group
instance GHC.Base.Monoid Futhark.Optimise.MergeGPUBodies.Group
instance GHC.Base.Semigroup Futhark.Optimise.MergeGPUBodies.Usage
instance GHC.Base.Monoid Futhark.Optimise.MergeGPUBodies.Usage

-- | Turn certain uses of accumulators into SegHists.
module Futhark.Optimise.HistAccs

-- | The pass for GPU kernels.
histAccsGPU :: Pass GPU GPU

-- | Tries to turn a generalized reduction kernel into a more specialized
--   construct, for example: (a) a map nest with a sequential redomap ripe
--   for tiling (b) a SegRed kernel followed by a smallish accumulation
--   kernel. (c) a histogram (for this we need to track the withAccs) The
--   idea is to identify the first accumulation and to separate the initial
--   kernels into two: 1. the code up to and including the accumulation,
--   which is optimized to turn the accumulation either into a map-reduce
--   composition or a histogram, and 2. the remaining code, which is
--   recursively optimized. Since this is mostly prototyping, when the
--   accumulation can be rewritten as a map-reduce, we sequentialize the
--   map-reduce, as to potentially enable tiling oportunities.
module Futhark.Optimise.GenRedOpt

-- | The pass definition.
optimiseGenRed :: Pass GPU GPU
instance GHC.Classes.Eq Futhark.Optimise.GenRedOpt.Cost

-- | 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 rep has
--   memory information, since at that point arrays have identity beyond
--   their value.
performCSE :: (AliasableRep rep, CSEInOp (Op (Aliases rep))) => Bool -> Pass rep rep

-- | 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 rep has
--   memory information, since at that point arrays have identity beyond
--   their value.
performCSEOnFunDef :: (AliasableRep rep, CSEInOp (Op (Aliases rep))) => Bool -> FunDef rep -> FunDef rep

-- | Perform CSE on some statements.
performCSEOnStms :: (AliasableRep rep, CSEInOp (Op (Aliases rep))) => Stms rep -> Stms rep

-- | The operations that permit CSE.
class CSEInOp op
instance forall k (rep :: k). Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Rep.NoOp rep)
instance (Futhark.IR.Prop.Aliases.Aliased rep, Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Rep.Op rep), Futhark.Optimise.CSE.CSEInOp (op rep)) => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.GPU.Op.HostOp op rep)
instance (Futhark.IR.Prop.Aliases.Aliased rep, Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Rep.Op rep), Futhark.Optimise.CSE.CSEInOp (op rep)) => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.MC.Op.MCOp op rep)
instance (Futhark.IR.Prop.Aliases.Aliased rep, Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Rep.Op rep)) => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.SegOp.SegOp lvl rep)
instance Futhark.Optimise.CSE.CSEInOp (op rep) => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Mem.MemOp op rep)
instance (Futhark.IR.Aliases.AliasableRep rep, Futhark.Optimise.CSE.CSEInOp (Futhark.IR.Rep.Op (Futhark.IR.Aliases.Aliases rep))) => Futhark.Optimise.CSE.CSEInOp (Futhark.IR.SOACS.SOAC.SOAC (Futhark.IR.Aliases.Aliases rep))

-- | 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.
inlineAggressively :: Pass SOACS SOACS

-- | Inline some functions and remove the resulting dead functions.
inlineConservatively :: Pass SOACS SOACS

-- | removeDeadFunctions prog removes the functions that are
--   unreachable from the main function from the program.
removeDeadFunctions :: Pass SOACS SOACS
instance GHC.Show.Show Futhark.Optimise.InliningDeadFun.Used
instance GHC.Classes.Ord Futhark.Optimise.InliningDeadFun.Used
instance GHC.Classes.Eq Futhark.Optimise.InliningDeadFun.Used

-- | Perform a restricted form of block+register tiling corresponding to
--   the following pattern: * a redomap is quasi-perfectly nested inside a
--   kernel with at least two parallel dimension (the perfectly nested
--   restriction is relaxed a bit to allow for SGEMM); * all streamed
--   arrays of redomap are one dimensional; * all streamed arrays are
--   variant to exacly one of the two innermost parallel dimensions, and
--   conversely for each of the two innermost parallel dimensions, there is
--   at least one streamed array variant to it; * the stream's result is a
--   tuple of scalar values, which are also the "thread-in-space" return of
--   the kernel. * We have further restrictions that in principle can be
--   relaxed: the redomap has exactly two array input the redomap produces
--   one scalar result the kernel produces one scalar result
module Futhark.Optimise.BlkRegTiling
mmBlkRegTiling :: Env -> Stm GPU -> TileM (Maybe (Stms GPU, Stm GPU))

-- | Expects a kernel statement as argument. CONDITIONS for 3D tiling
--   optimization to fire are: 1. a) The kernel body can be broken into
--   scalar-code-1 ++ [Redomap stmt] ++ scalar-code-2. b) The kernels has a
--   per-thread result, and obviously the result is variant to the 3rd
--   dimension (counted from innermost to outermost) 2. For the Redomap: a)
--   the streamed arrays are one dimensional b) each of the array arguments
--   of Redomap are variant to exactly one of the three innermost-parallel
--   dimension of the kernel. This condition can be relaxed by
--   interchanging kernel dimensions whenever possible. 3. For
--   scalar-code-1: a) each of the statements is a slice that produces one
--   of the streamed arrays
--   
--   mmBlkRegTiling :: Stm GPU -> TileM (Maybe (Stms GPU, Stm GPU))
--   mmBlkRegTiling (Let pat aux (Op (SegOp (SegMap SegThread{} seg_space
--   ts old_kbody))))
doRegTiling3D :: Stm GPU -> TileM (Maybe (Stms GPU, Stm GPU))

-- | Perform a restricted form of loop tiling within SegMaps. We only tile
--   primitive types, to avoid excessive shared memory use.
module Futhark.Optimise.TileLoops

-- | The pass definition.
tileLoops :: Pass GPU GPU
instance GHC.Base.Semigroup Futhark.Optimise.TileLoops.PrivStms
instance GHC.Base.Monoid Futhark.Optimise.TileLoops.PrivStms

module Futhark.IR.GPU.Simplify
simplifyGPU :: Prog GPU -> PassM (Prog GPU)
simplifyLambda :: (HasScope GPU m, MonadFreshNames m) => Lambda GPU -> m (Lambda GPU)

-- | The phantom data type for the kernels representation.
data GPU
simplifyKernelOp :: (SimplifiableRep rep, BodyDec rep ~ ()) => SimplifyOp rep (op (Wise rep)) -> HostOp op (Wise rep) -> SimpleM rep (HostOp op (Wise rep), Stms (Wise rep))
instance Futhark.IR.Traversals.TraverseOpStms (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.GPU.GPU)
instance Futhark.Builder.BuilderOps (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.GPU.GPU)
instance Futhark.IR.SegOp.HasSegOp (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.GPU.GPU)
instance Futhark.IR.SOACS.Simplify.HasSOAC (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.GPU.GPU)

-- | 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:
--   
--   
--   
- Sequentialise Stream operations, leaving other SOACs
--   intact.
--   
- Apply whole-program simplification.
--   
- Sequentialise remaining SOACs.
--   
--   
--   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.
unstreamGPU :: Pass GPU GPU

-- | The pass for multicore.
unstreamMC :: Pass MC MC

module Futhark.IR.GPUMem
data GPUMem
simplifyProg :: Prog GPUMem -> PassM (Prog GPUMem)
simplifyStms :: (HasScope GPUMem m, MonadFreshNames m) => Stms GPUMem -> m (Stms GPUMem)
simpleGPUMem :: SimpleOps GPUMem
instance Futhark.IR.Rep.RepTypes Futhark.IR.GPUMem.GPUMem
instance Futhark.IR.Prop.ASTRep Futhark.IR.GPUMem.GPUMem
instance Futhark.IR.Pretty.PrettyRep Futhark.IR.GPUMem.GPUMem
instance Futhark.IR.TypeCheck.Checkable Futhark.IR.GPUMem.GPUMem
instance Futhark.Builder.BuilderOps Futhark.IR.GPUMem.GPUMem
instance Futhark.Builder.BuilderOps (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.GPUMem.GPUMem)
instance Futhark.IR.Traversals.TraverseOpStms (Futhark.Optimise.Simplify.Rep.Wise Futhark.IR.GPUMem.GPUMem)

module Futhark.Pass.Simplify
simplify :: (Prog rep -> PassM (Prog rep)) -> Pass rep rep
simplifySOACS :: Pass SOACS SOACS
simplifySeq :: Pass Seq Seq
simplifyMC :: Pass MC MC
simplifyGPU :: Pass GPU GPU
simplifyGPUMem :: Pass GPUMem GPUMem
simplifySeqMem :: Pass SeqMem SeqMem
simplifyMCMem :: Pass MCMem MCMem

-- | This pass attempts to lower allocations as far towards the bottom of
--   their body as possible.
module Futhark.Pass.LowerAllocations
lowerAllocationsSeqMem :: Pass SeqMem SeqMem
lowerAllocationsGPUMem :: Pass GPUMem GPUMem
lowerAllocationsMCMem :: Pass MCMem MCMem

-- | This pass attempts to lift allocations and asserts as far towards the
--   top in their body as possible. This helps memory short circuiting do a
--   better job, as it is sensitive to statement ordering. It does not try
--   to hoist allocations outside across body boundaries.
module Futhark.Pass.LiftAllocations
liftAllocationsSeqMem :: Pass SeqMem SeqMem
liftAllocationsGPUMem :: Pass GPUMem GPUMem
liftAllocationsMCMem :: Pass MCMem MCMem

module Futhark.Pass.ExplicitAllocations.SegOp
allocInKernelBody :: Allocable fromrep torep inner => KernelBody fromrep -> AllocM fromrep torep (KernelBody torep)
allocInBinOpLambda :: Allocable fromrep torep inner => SubExp -> SegSpace -> Lambda fromrep -> AllocM fromrep torep (Lambda torep)
instance Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.IR.SegOp.SegOp lvl rep)

-- | Converting MC programs to MCMem.
module Futhark.Pass.ExplicitAllocations.MC

-- | The pass from MC to MCMem.
explicitAllocations :: Pass MC MCMem
instance Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.IR.MC.Op.MCOp rep op)

-- | Facilities for converting a GPU program to GPUMem.
module Futhark.Pass.ExplicitAllocations.GPU

-- | The pass from GPU to GPUMem.
explicitAllocations :: Pass GPU GPUMem

-- | Convert some GPU stms to GPUMem.
explicitAllocationsInStms :: (MonadFreshNames m, HasScope GPUMem m) => Stms GPU -> m (Stms GPUMem)
instance Futhark.Pass.ExplicitAllocations.SizeSubst (Futhark.IR.GPU.Op.HostOp rep op)

-- | Expand allocations inside of maps when possible.
module Futhark.Pass.ExpandAllocations

-- | The memory expansion pass definition.
expandAllocations :: Pass GPUMem GPUMem
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Pass.ExpandAllocations.OffsetM
instance Control.Monad.Error.Class.MonadError GHC.Base.String Futhark.Pass.ExpandAllocations.OffsetM
instance Futhark.IR.Prop.Scope.LocalScope Futhark.IR.GPUMem.GPUMem Futhark.Pass.ExpandAllocations.OffsetM
instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.GPUMem.GPUMem 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
instance Futhark.Builder.Class.MonadBuilder Futhark.Pass.ExpandAllocations.OffsetM

-- | We require that entry points return arrays with zero offset in
--   row-major order. Futhark.Pass.ExplicitAllocations is
--   conservative and inserts copies to ensure this is the case. After
--   simplification, it may turn out that those copies are redundant. This
--   pass removes them. It's a pretty simple pass, as it only has to look
--   at the top level of entry points.
module Futhark.Optimise.EntryPointMem

-- | The pass for GPU representation.
entryPointMemGPU :: Pass GPUMem GPUMem

-- | The pass for MC representation.
entryPointMemMC :: Pass MCMem MCMem

-- | The pass for Seq representation.
entryPointMemSeq :: Pass SeqMem SeqMem

-- | 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 pass tries to rewrite loops with memory parameters. Specifically,
--   it takes loops of this form:
--   
--   
--   loop {..., A_mem, ..., A, ...} ... do {
--     ...
--     let A_out_mem = alloc(...) -- stores A_out
--     in {..., A_out_mem, ..., A_out, ...}
--   }
--   
--   
--   and turns them into
--   
--   
--   let A_in_mem = alloc(...)
--   let A_out_mem = alloc(...)
--   let A_in = copy A -- in A_in_mem
--   loop {..., A_in_mem, A_out_mem, ..., A=A_in, ...} ... do {
--     ...
--     in {..., A_out_mem, A_mem, ..., A_out, ...}
--   }
--   
--   
--   The result is essentially "pointer swapping" between the two memory
--   initial blocks A_mem and A_out_mem. The invariant is
--   that the array is always stored in the "first" memory block at the
--   beginning of the loop (and also in the final result). We do need to
--   add an extra element to the pattern, however. The initial copy of
--   A could be elided if A is unique (thus
--   A_in_mem=A_mem). This is because only then is it safe to use
--   A_mem to store loop results. We don't currently do this.
--   
--   Unfortunately, not all loops fit the pattern above. In particular, a
--   nested loop that has been transformed as such does not! Therefore we
--   also have another double buffering strategy, that turns
--   
--   
--   loop {..., A_mem, ..., A, ...} ... do {
--     ...
--     let A_out_mem = alloc(...)
--     -- A in A_out_mem
--     in {..., A_out_mem, ..., A, ...}
--   }
--   
--   
--   into
--   
--   
--   let A_res_mem = alloc(...)
--   loop {..., A_mem, ..., A, ...} ... do {
--     ...
--     let A_out_mem = alloc(...)
--     -- A in A_out_mem
--     let A' = copy A
--     -- A' in A_res_mem
--     in {..., A_res_mem, ..., A, ...}
--   }
--   
--   
--   The allocation of A_out_mem can then be hoisted out because it is dead
--   at the end of the loop. This always works as long as A_out_mem has a
--   loop-invariant allocation size, but requires a copy per iteration (and
--   an initial one, elided above).
module Futhark.Optimise.DoubleBuffer

-- | The pass for GPU kernels.
doubleBufferGPU :: Pass GPUMem GPUMem

-- | The pass for multicore
doubleBufferMC :: Pass MCMem MCMem
instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Optimise.DoubleBuffer.DoubleBufferM rep)
instance Control.Monad.Reader.Class.MonadReader (Futhark.Optimise.DoubleBuffer.Env rep) (Futhark.Optimise.DoubleBuffer.DoubleBufferM rep)
instance GHC.Base.Monad (Futhark.Optimise.DoubleBuffer.DoubleBufferM rep)
instance GHC.Base.Applicative (Futhark.Optimise.DoubleBuffer.DoubleBufferM rep)
instance GHC.Base.Functor (Futhark.Optimise.DoubleBuffer.DoubleBufferM rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Scope.HasScope rep (Futhark.Optimise.DoubleBuffer.DoubleBufferM rep)
instance Futhark.IR.Prop.ASTRep rep => Futhark.IR.Prop.Scope.LocalScope rep (Futhark.Optimise.DoubleBuffer.DoubleBufferM rep)

module Futhark.Optimise.ArrayShortCircuiting.DataStructs

-- | Coalesced Access Entry
data Coalesced
Coalesced :: CoalescedKind -> ArrayMemBound -> FreeVarSubsts -> Coalesced
data CoalescedKind

-- | let x = copy b^{lu}
CopyCoal :: CoalescedKind

-- | let x[i] = b^{lu}
InPlaceCoal :: CoalescedKind

-- | let x = concat(a, b^{lu})
ConcatCoal :: CoalescedKind

-- | transitive, i.e., other variables aliased with b.
TransitiveCoal :: CoalescedKind
MapCoal :: CoalescedKind

-- | Information about a memory block: type, shape, name and ixfun.
data ArrayMemBound
MemBlock :: PrimType -> Shape -> VName -> LMAD -> ArrayMemBound
[primType] :: ArrayMemBound -> PrimType
[shape] :: ArrayMemBound -> Shape
[memName] :: ArrayMemBound -> VName
[ixfun] :: ArrayMemBound -> LMAD

-- | the allocatted memory blocks
type AllocTab = Map VName Space
class HasMemBlock rep

-- | maps a variable name to its PrimExp scalar expression
type ScalarTab = Map VName (PrimExp VName)

-- | maps a memory-block name to a CoalsEntry. Among other things,
--   it contains vartab, a map in which each variable associated
--   to that memory block is bound to its Coalesced info.
type CoalsTab = Map VName CoalsEntry

-- | maps array-variable names to various info, including types, memory
--   block and index function, etc.
type ScopeTab rep = Scope (Aliases rep)
data CoalsEntry
CoalsEntry :: VName -> LMAD -> Names -> Map VName Coalesced -> Map VName VName -> MemRefs -> Certs -> CoalsEntry

-- | destination memory block
[dstmem] :: CoalsEntry -> VName

-- | index function of the destination (used for rebasing)
[dstind] :: CoalsEntry -> LMAD

-- | aliased destination memory blocks can appear due to repeated
--   (optimistic) coalescing.
[alsmem] :: CoalsEntry -> Names

-- | per variable-name coalesced entries
[vartab] :: CoalsEntry -> Map VName Coalesced

-- | keys are variable names, values are memblock names; it records
--   optimistically added coalesced nodes, e.g., in the case of
--   if-then-else expressions. For example: x = map f a .. use
--   of y .. b = map g a x[i] = b  y[k] = x
--    the coalescing of b in x[i] succeeds, but is
--   dependent of the success of the coalescing of x in
--   y[k], which fails in this case because y is used
--   before the new array creation of x = map f. Hence
--   optdeps of the m_b CoalsEntry records x ->
--   m_x and at the end of analysis it is removed from the
--   successfully coalesced table if m_x is unsuccessful. Storing
--   m_x would probably be sufficient if memory would not be
--   reused--e.g., by register allocation on arrays--the x
--   discriminates between memory being reused across semantically
--   different arrays (searched in vartab field).
[optdeps] :: CoalsEntry -> Map VName VName

-- | Access summaries of uses and writes of destination and source
--   respectively.
[memrefs] :: CoalsEntry -> MemRefs

-- | Certificates of the destination, which must be propagated to the
--   source. When short-circuiting reaches the array creation point, we
--   must check whether the certs are in scope for short-circuiting to
--   succeed.
[certs] :: CoalsEntry -> Certs

-- | Free variable substitutions
type FreeVarSubsts = Map VName (TPrimExp Int64 VName)

-- | An LMAD specialized to TPrimExps (a typed primexp)
type LmadRef = LMAD (TPrimExp Int64 VName)
data MemRefs
MemRefs :: AccessSummary -> AccessSummary -> MemRefs

-- | The access summary of all references (reads and writes) to the
--   destination of a coalescing entry
[dstrefs] :: MemRefs -> AccessSummary

-- | The access summary of all writes to the source of a coalescing entry
[srcwrts] :: MemRefs -> AccessSummary

-- | Summary of all memory accesses at a given point in the code
data AccessSummary

-- | The access summary was statically undeterminable, for instance by
--   having multiple lmads. In this case, we should conservatively avoid
--   all coalescing.
Undeterminable :: AccessSummary

-- | A conservative estimate of the set of accesses up until this point.
Set :: Set LmadRef -> AccessSummary
data BotUpEnv
BotUpEnv :: ScalarTab -> CoalsTab -> CoalsTab -> InhibitTab -> BotUpEnv

-- | maps scalar variables to theirs PrimExp expansion
[scals] :: BotUpEnv -> ScalarTab

-- | Optimistic coalescing info. We are currently trying to coalesce these
--   memory blocks.
[activeCoals] :: BotUpEnv -> CoalsTab

-- | Committed (successfull) coalescing info. These memory blocks have been
--   successfully coalesced.
[successCoals] :: BotUpEnv -> CoalsTab

-- | The coalescing failures from this pass. We will no longer try to merge
--   these memory blocks.
[inhibit] :: BotUpEnv -> InhibitTab

-- | inhibited memory-block mergings from the key (memory block) to the
--   value (set of memory blocks).
type InhibitTab = Map VName Names

-- | Compute the union of two CoalsEntry. If two CoalsEntry
--   do not refer to the same destination memory and use the same index
--   function, the first CoalsEntry is returned.
unionCoalsEntry :: CoalsEntry -> CoalsEntry -> CoalsEntry

-- | Attempt to convert a VName to a PrimExp.
--   
--   First look in ScalarTab to see if we have recorded the scalar
--   value of the argument. Otherwise look up the type of the argument and
--   return a LeafExp if it is a PrimType.
vnameToPrimExp :: AliasableRep rep => ScopeTab rep -> ScalarTab -> VName -> Maybe (PrimExp VName)

-- | Get the names of arrays in a list of FParam and the
--   corresponding ArrayMemBound information for each array.
getArrMemAssocFParam :: [Param FParamMem] -> [(VName, Uniqueness, ArrayMemBound)]

-- | Looks up VName in the given scope. If it is a MemArray,
--   return the ArrayMemBound information for the array.
getScopeMemInfo :: HasMemBlock rep => VName -> Scope rep -> Maybe ArrayMemBound

-- | True if the expression returns a "fresh" array.
createsNewArrOK :: Exp rep -> Bool

-- | Get the names of array PatElems in a Pat and the
--   corresponding ArrayMemBound information for each array.
getArrMemAssoc :: Pat (aliases, LetDecMem) -> [(VName, ArrayMemBound)]

-- | Get memory blocks in a list of FParam that are used for unique
--   arrays in the same list of FParam.
getUniqueMemFParam :: [Param FParamMem] -> Map VName Space

-- | Memory-block removal from active-coalescing table should only be
--   handled via this function, it is easy to run into infinite execution
--   problem; i.e., the fix-pointed iteration of coalescing transformation
--   assumes that whenever a coalescing fails it is recorded in the
--   inhibit table.
markFailedCoal :: (CoalsTab, InhibitTab) -> VName -> (CoalsTab, InhibitTab)
accessSubtract :: AccessSummary -> AccessSummary -> AccessSummary

-- | promotion from active-to-successful coalescing tables should be
--   handled with this function (for clarity).
markSuccessCoal :: (CoalsTab, CoalsTab) -> VName -> CoalsEntry -> (CoalsTab, CoalsTab)
instance Futhark.Optimise.ArrayShortCircuiting.DataStructs.HasMemBlock (Futhark.IR.Aliases.Aliases Futhark.IR.SeqMem.SeqMem)
instance Futhark.Optimise.ArrayShortCircuiting.DataStructs.HasMemBlock (Futhark.IR.Aliases.Aliases Futhark.IR.GPUMem.GPUMem)
instance Futhark.Optimise.ArrayShortCircuiting.DataStructs.HasMemBlock (Futhark.IR.Aliases.Aliases Futhark.IR.MCMem.MCMem)
instance Prettyprinter.Internal.Pretty Futhark.Optimise.ArrayShortCircuiting.DataStructs.CoalsTab
instance Prettyprinter.Internal.Pretty Futhark.Optimise.ArrayShortCircuiting.DataStructs.CoalsEntry
instance Prettyprinter.Internal.Pretty Futhark.Optimise.ArrayShortCircuiting.DataStructs.Coalesced
instance Prettyprinter.Internal.Pretty Futhark.Optimise.ArrayShortCircuiting.DataStructs.ArrayMemBound
instance Prettyprinter.Internal.Pretty Futhark.Optimise.ArrayShortCircuiting.DataStructs.CoalescedKind
instance GHC.Base.Semigroup Futhark.Optimise.ArrayShortCircuiting.DataStructs.MemRefs
instance GHC.Base.Monoid Futhark.Optimise.ArrayShortCircuiting.DataStructs.MemRefs
instance Prettyprinter.Internal.Pretty Futhark.Optimise.ArrayShortCircuiting.DataStructs.MemRefs
instance GHC.Base.Semigroup Futhark.Optimise.ArrayShortCircuiting.DataStructs.AccessSummary
instance GHC.Base.Monoid Futhark.Optimise.ArrayShortCircuiting.DataStructs.AccessSummary
instance Futhark.IR.Prop.Names.FreeIn Futhark.Optimise.ArrayShortCircuiting.DataStructs.AccessSummary
instance Prettyprinter.Internal.Pretty Futhark.Optimise.ArrayShortCircuiting.DataStructs.AccessSummary

module Futhark.Optimise.ArrayShortCircuiting.TopdownAnalysis
data TopdownEnv rep
TopdownEnv :: AllocTab -> ScopeTab rep -> InhibitTab -> VarAliasTab -> MemAliasTab -> Names -> Map VName (PrimExp VName) -> [(VName, PrimExp VName)] -> [SubExp] -> TopdownEnv rep

-- | contains the already allocated memory blocks
[alloc] :: TopdownEnv rep -> AllocTab

-- | variable info, including var-to-memblock assocs
[scope] :: TopdownEnv rep -> ScopeTab rep

-- | the inherited inhibitions from the previous try
[inhibited] :: TopdownEnv rep -> InhibitTab

-- | for statements such as transpose, reshape, index, etc., that alias an
--   array variable: maps var-names to pair of aliased var name and index
--   function transformation. For example, for let b = a[slc] it
--   should add the binding  b |-> (a, slice slc )
[v_alias] :: TopdownEnv rep -> VarAliasTab

-- | keeps track of memory block aliasing. this needs to be implemented
[m_alias] :: TopdownEnv rep -> MemAliasTab

-- | Contains symbol information about the variables in the program. Used
--   to determine if a variable is non-negative.
[nonNegatives] :: TopdownEnv rep -> Names
[scalarTable] :: TopdownEnv rep -> Map VName (PrimExp VName)

-- | A list of known relations of the form VName <
--   BasicOp, typically gotten from LoopForm and
--   SegSpace.
[knownLessThan] :: TopdownEnv rep -> [(VName, PrimExp VName)]

-- | A list of the asserts encountered so far
[td_asserts] :: TopdownEnv rep -> [SubExp]

-- | maps array-variable names to various info, including types, memory
--   block and index function, etc.
type ScopeTab rep = Scope (Aliases rep)
class TopDownHelper inner

-- | inhibited memory-block mergings from the key (memory block) to the
--   value (set of memory blocks).
type InhibitTab = Map VName Names

-- | fills in the TopdownEnv table
updateTopdownEnv :: (ASTRep rep, Op rep ~ MemOp inner rep, TopDownHelper (inner (Aliases rep))) => TopdownEnv rep -> Stm (Aliases rep) -> TopdownEnv rep

-- | The topdown handler for loops.
updateTopdownEnvLoop :: TopdownEnv rep -> [(FParam rep, SubExp)] -> LoopForm -> TopdownEnv rep

-- | Get direct aliased index function. Returns a triple of current memory
--   block to be coalesced, the destination memory block and the index
--   function of the access in the space of the destination block.
getDirAliasedIxfn :: HasMemBlock (Aliases rep) => TopdownEnv rep -> CoalsTab -> VName -> Maybe (VName, VName, LMAD)

-- | Like getDirAliasedIxfn, but this version returns Nothing
--   if the value is not currently subject to coalescing.
getDirAliasedIxfn' :: HasMemBlock (Aliases rep) => TopdownEnv rep -> CoalsTab -> VName -> Maybe (VName, VName, LMAD)

-- | We assume x is in vartab and we add the variables
--   that x aliases for as long as possible following a chain of
--   direct-aliasing operators, i.e., without considering aliasing of
--   if-then-else, loops, etc. For example:  x0 = if c then ... else
--   ...  x1 = rearrange r1 x0   x2 = reverse x1
--    y[slc] = x2  We assume vartab constains a binding
--   for x2, and calling this function with x2 as
--   argument should also insert entries for x1 and x0 to
--   vartab, of course if their aliasing operations are
--   invertible. We assume inverting aliases has been performed by the
--   top-down pass.
addInvAliasesVarTab :: HasMemBlock (Aliases rep) => TopdownEnv rep -> Map VName Coalesced -> VName -> Maybe (Map VName Coalesced)
areAnyAliased :: TopdownEnv rep -> VName -> [VName] -> Bool
isInScope :: TopdownEnv rep -> VName -> Bool
nonNegativesInPat :: Typed rep => Pat rep -> Names
instance Futhark.Optimise.ArrayShortCircuiting.TopdownAnalysis.TopDownHelper (Futhark.IR.SegOp.SegOp lvl rep)
instance Futhark.Optimise.ArrayShortCircuiting.TopdownAnalysis.TopDownHelper (Futhark.IR.GPU.Op.HostOp Futhark.IR.Rep.NoOp (Futhark.IR.Aliases.Aliases Futhark.IR.GPUMem.GPUMem))
instance Futhark.Optimise.ArrayShortCircuiting.TopdownAnalysis.TopDownHelper (inner (Futhark.IR.Aliases.Aliases Futhark.IR.MCMem.MCMem)) => Futhark.Optimise.ArrayShortCircuiting.TopdownAnalysis.TopDownHelper (Futhark.IR.MC.Op.MCOp inner (Futhark.IR.Aliases.Aliases Futhark.IR.MCMem.MCMem))
instance forall k (rep :: k). Futhark.Optimise.ArrayShortCircuiting.TopdownAnalysis.TopDownHelper (Futhark.IR.Rep.NoOp rep)

module Futhark.Optimise.ArrayShortCircuiting.MemRefAggreg

-- | This function: 1. computes the written and read memory references for
--   the current statement (by calling getUseSumFromStm) 2. fails
--   the entries in active coalesced table for which the write set overlaps
--   the uses of the destination (to that point)
recordMemRefUses :: (AliasableRep rep, Op rep ~ MemOp inner rep, HasMemBlock (Aliases rep)) => TopdownEnv rep -> BotUpEnv -> Stm (Aliases rep) -> (CoalsTab, InhibitTab)

-- | Checks whether the index function can be translated at the current
--   program point and also returns the substitutions. It comes down to
--   answering the question: "can one perform enough substitutions (from
--   the bottom-up scalar table) until all vars appearing in the index
--   function are defined in the current scope?"
freeVarSubstitutions :: FreeIn a => ScopeTab rep -> ScalarTab -> a -> Maybe FreeVarSubsts

-- | Translates free variables in an access summary
translateAccessSummary :: ScopeTab rep -> ScalarTab -> AccessSummary -> AccessSummary

-- | Computes the total aggregated access summary for a loop by expanding
--   the access summary given according to the iterator variable and bounds
--   of the loop.
--   
--   Corresponds to:
--   
--   <math>
aggSummaryLoopTotal :: MonadFreshNames m => ScopeTab rep -> ScopeTab rep -> ScalarTab -> Maybe (VName, (TPrimExp Int64 VName, TPrimExp Int64 VName)) -> AccessSummary -> m AccessSummary

-- | For a given iteration of the loop $i$, computes the aggregated loop
--   access summary of all later iterations.
--   
--   Corresponds to:
--   
--   <math>
aggSummaryLoopPartial :: MonadFreshNames m => ScalarTab -> Maybe (VName, (TPrimExp Int64 VName, TPrimExp Int64 VName)) -> AccessSummary -> m AccessSummary

-- | For a given map with $k$ dimensions and an index $i$ for each
--   dimension, compute the aggregated access summary of all other threads.
--   
--   For the innermost dimension, this corresponds to
--   
--   <math>
--   
--   where $Access_j$ describes the point accesses in the map. As we move
--   up in dimensionality, the previous access summaries are kept, in
--   addition to the total aggregation of the inner dimensions. For outer
--   dimensions, the equation is the same, the point accesses in $Access_j$
--   are replaced with the total aggregation of the inner dimensions.
aggSummaryMapPartial :: MonadFreshNames m => ScalarTab -> [(VName, SubExp)] -> LmadRef -> m AccessSummary

-- | Computes to total access summary over a multi-dimensional map.
aggSummaryMapTotal :: MonadFreshNames m => ScalarTab -> [(VName, SubExp)] -> AccessSummary -> m AccessSummary

-- | Check for memory overlap of two access summaries.
--   
--   This check is conservative, so unless we can guarantee that there is
--   no overlap, we return False.
noMemOverlap :: AliasableRep rep => TopdownEnv rep -> AccessSummary -> AccessSummary -> Bool

module Futhark.Analysis.MemAlias

-- | Produce aliases for constants and for each function.
analyzeSeqMem :: Prog SeqMem -> (MemAliases, Map Name MemAliases)

-- | Produce aliases for constants and for each function.
analyzeGPUMem :: Prog GPUMem -> (MemAliases, Map Name MemAliases)
aliasesOf :: MemAliases -> VName -> Names
data MemAliases
instance GHC.Classes.Eq Futhark.Analysis.MemAlias.MemAliases
instance GHC.Show.Show Futhark.Analysis.MemAlias.MemAliases
instance GHC.Base.Semigroup Futhark.Analysis.MemAlias.MemAliases
instance GHC.Base.Monoid Futhark.Analysis.MemAlias.MemAliases
instance Prettyprinter.Internal.Pretty Futhark.Analysis.MemAlias.MemAliases

-- | Last use analysis for array short circuiting
--   
--   Last-Use analysis of a Futhark program in aliased explicit-memory lore
--   form. Takes as input such a program or a function and produces a
--   'M.Map VName Names', in which the key identified the let stmt, and the
--   list argument identifies the variables that were lastly used in that
--   stmt. Note that the results of a body do not have a last use, and
--   neither do a function parameters if it happens to not be used inside
--   function's body. Such cases are supposed to be treated separately.
module Futhark.Analysis.LastUse

-- | Perform last-use analysis on a Prog in SeqMem
lastUseSeqMem :: Prog (Aliases SeqMem) -> LUTabProg

-- | Perform last-use analysis on a Prog in GPUMem
lastUseGPUMem :: Prog (Aliases GPUMem) -> LUTabProg

-- | Perform last-use analysis on a Prog in MCMem
lastUseMCMem :: Prog (Aliases MCMem) -> LUTabProg

-- | Maps a name indentifying a Stm to the last uses in that Stm.
type LUTabFun = Map VName Names

-- | LU-table for the constants, and for each function.
type LUTabProg = (LUTabFun, Map Name LUTabFun)
instance Control.Monad.State.Class.MonadState Futhark.Analysis.LastUse.AliasTab (Futhark.Analysis.LastUse.LastUseM rep)
instance Control.Monad.Reader.Class.MonadReader (Futhark.Analysis.LastUse.LastUseReader rep) (Futhark.Analysis.LastUse.LastUseM rep)
instance GHC.Base.Applicative (Futhark.Analysis.LastUse.LastUseM rep)
instance GHC.Base.Functor (Futhark.Analysis.LastUse.LastUseM rep)
instance GHC.Base.Monad (Futhark.Analysis.LastUse.LastUseM rep)
instance Futhark.IR.Rep.RepTypes (Futhark.IR.Aliases.Aliases rep) => Futhark.IR.Prop.Scope.HasScope (Futhark.IR.Aliases.Aliases rep) (Futhark.Analysis.LastUse.LastUseM rep)
instance Futhark.IR.Rep.RepTypes (Futhark.IR.Aliases.Aliases rep) => Futhark.IR.Prop.Scope.LocalScope (Futhark.IR.Aliases.Aliases rep) (Futhark.Analysis.LastUse.LastUseM rep)

-- | The bulk of the short-circuiting implementation.
module Futhark.Optimise.ArrayShortCircuiting.ArrayCoalescing

-- | Given a Prog in SegMem representation, compute the
--   coalescing table by folding over each function.
mkCoalsTab :: MonadFreshNames m => Prog (Aliases SeqMem) -> m (Map Name CoalsTab)

-- | maps a memory-block name to a CoalsEntry. Among other things,
--   it contains vartab, a map in which each variable associated
--   to that memory block is bound to its Coalesced info.
type CoalsTab = Map VName CoalsEntry

-- | Given a Prog in GPUMem representation, compute the
--   coalescing table by folding over each function.
mkCoalsTabGPU :: MonadFreshNames m => Prog (Aliases GPUMem) -> m (Map Name CoalsTab)

-- | Given a Prog in MCMem representation, compute the
--   coalescing table by folding over each function.
mkCoalsTabMC :: MonadFreshNames m => Prog (Aliases MCMem) -> m (Map Name CoalsTab)
instance Control.Monad.State.Class.MonadState Futhark.FreshNames.VNameSource (Futhark.Optimise.ArrayShortCircuiting.ArrayCoalescing.ShortCircuitM rep)
instance Control.Monad.Reader.Class.MonadReader (Futhark.Optimise.ArrayShortCircuiting.ArrayCoalescing.ShortCircuitReader rep) (Futhark.Optimise.ArrayShortCircuiting.ArrayCoalescing.ShortCircuitM rep)
instance GHC.Base.Monad (Futhark.Optimise.ArrayShortCircuiting.ArrayCoalescing.ShortCircuitM rep)
instance GHC.Base.Applicative (Futhark.Optimise.ArrayShortCircuiting.ArrayCoalescing.ShortCircuitM rep)
instance GHC.Base.Functor (Futhark.Optimise.ArrayShortCircuiting.ArrayCoalescing.ShortCircuitM rep)
instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.Optimise.ArrayShortCircuiting.ArrayCoalescing.ShortCircuitM rep)

-- | Perform array short circuiting
module Futhark.Optimise.ArrayShortCircuiting
optimiseSeqMem :: Pass SeqMem SeqMem
optimiseGPUMem :: Pass GPUMem GPUMem
optimiseMCMem :: Pass MCMem MCMem

-- | Interference analysis for Futhark programs.
module Futhark.Analysis.Interference

-- | An interference graph. An element (x, y) in the set means
--   that there is an undirected edge between x and y,
--   and therefore the lifetimes of x and y overlap and
--   they "interfere" with each other. We assume that pairs are always
--   normalized, such that x < y, before inserting.
--   This should prevent any duplicates. We also don't allow any pairs
--   where x == y.
type Graph a = Set (a, a)
analyseProgGPU :: Prog GPUMem -> Graph VName

-- | Provides a greedy graph-coloring algorithm.
module Futhark.Optimise.MemoryBlockMerging.GreedyColoring

-- | Graph coloring that takes into account the space of values.
--   Two values can only share the same color if they live in the same
--   space. The result is map from each color to a space and a map from
--   each value in the input graph to it's new color.
colorGraph :: (Ord a, Ord space) => Map a space -> Graph a -> (Map Int space, Coloring a)

-- | A map of values to their color, identified by an integer.
type Coloring a = Map a Int

-- | This module implements an optimization that tries to statically reuse
--   kernel-level allocations. The goal is to lower the static memory
--   usage, which might allow more programs to run using intra-group
--   parallelism.
module Futhark.Optimise.MemoryBlockMerging

-- | Perform the reuse-allocations optimization.
optimise :: Pass GPUMem GPUMem

-- | Compute a mapping from variables to their corresponding (fully
--   expanded) PrimExps.
module Futhark.Analysis.PrimExp.Table
primExpTable :: (PrimExpAnalysis rep, RepTypes rep) => Prog rep -> PrimExpTable

-- | Maps variables to maybe PrimExps. Will map to nothing if it cannot be
--   resolved to a PrimExp. For all uses of this analysis atm. a variable
--   can be considered inscrutable if it cannot be resolved to a primexp.
type PrimExpTable = Map VName (Maybe (PrimExp VName))

-- | A class for extracting PrimExps from what is inside an op.
class PrimExpAnalysis rep
opPrimExp :: PrimExpAnalysis rep => Scope rep -> Op rep -> State PrimExpTable ()

-- | Adds a statement to the PrimExpTable. If it can't be resolved as a
--   PrimExp, it will be added as Nothing.
stmToPrimExps :: forall rep. (PrimExpAnalysis rep, RepTypes rep) => Scope rep -> Stm rep -> State PrimExpTable ()
instance Futhark.Analysis.PrimExp.Table.PrimExpAnalysis Futhark.IR.GPU.GPU
instance Futhark.Analysis.PrimExp.Table.PrimExpAnalysis Futhark.IR.MC.MC

module Futhark.Analysis.AccessPattern

-- | Analyse each entry and accumulate the results.
analyseDimAccesses :: Analyse rep => Prog rep -> IndexTable rep

-- | Analyse each statement in a function body.
analyseFunction :: Analyse rep => FunDef rep -> IndexTable rep
vnameFromSegOp :: SegOpName -> VName

-- | Make segops on arrays transitive, ie. if > let A = segmap (..) xs
--   -- A indexes into xs > let B = segmap (..) A -- B indexes into A
--   Then B also derives all A's array-accesses, like xs. Runs in n²
analysisPropagateByTransitivity :: IndexTable rep -> IndexTable rep
isInvariant :: DimAccess rep -> Bool

-- | A representation where we can analyse access patterns.
class Analyse rep

-- | For each array access in a program, this data structure stores the
--   dependencies of each dimension in the access, the array name, and the
--   name of the SegOp that the access is contained in. Each DimAccess
--   element corresponds to an access to a given dimension in the given
--   array, in the same order of the dimensions.
type IndexTable rep = Map SegOpName (Map ArrayName (Map IndexExprName [DimAccess rep]))

-- | Stores the name of an array, the nest of loops, kernels, conditionals
--   in which it is constructed, and the existing layout of the array. The
--   latter is currently largely unused and not trustworthy, but might be
--   useful in the future.
type ArrayName = (VName, [BodyType], [Int])

-- | Collect all features of access to a specific dimension of an array.
data DimAccess rep
DimAccess :: Map VName Dependency -> Maybe VName -> DimAccess rep

-- | Set of VNames of iteration variables (gtids, loop counters, etc.) that
--   some access is variant to. An empty set indicates that the access is
--   invariant.
[dependencies] :: DimAccess rep -> Map VName Dependency

-- | Used to store the name of the original expression from which
--   dependencies was computed. Nothing if it is a constant.
[originalVar] :: DimAccess rep -> Maybe VName

-- | Name of an array indexing expression. Taken from the pattern of the
--   expression.
type IndexExprName = VName
data BodyType
SegOpName :: SegOpName -> BodyType
LoopBodyName :: VName -> BodyType
CondBodyName :: VName -> BodyType

-- | Name of a SegOp, used to identify the SegOp that an array access is
--   contained in.
data SegOpName
SegmentedMap :: VName -> SegOpName
SegmentedRed :: VName -> SegOpName
SegmentedScan :: VName -> SegOpName
SegmentedHist :: VName -> SegOpName

-- | Used during the analysis to keep track of the dependencies of patterns
--   encountered so far.
data Context rep
Context :: Map VName (VariableInfo rep) -> Map IndexExprName (ArrayName, [VName], [DimAccess rep]) -> [BodyType] -> Int -> Context rep

-- | A mapping from patterns occuring in Let expressions to their
--   dependencies and iteration types.
[assignments] :: Context rep -> Map VName (VariableInfo rep)

-- | Maps from sliced arrays to their respective access patterns.
[slices] :: Context rep -> Map IndexExprName (ArrayName, [VName], [DimAccess rep])

-- | A list of the segMaps encountered during the analysis in the order
--   they were encountered.
[parents] :: Context rep -> [BodyType]

-- | Current level of recursion, also just `length parents`
[currentLevel] :: Context rep -> Int

-- | Gets the dependencies of each dimension and either returns a result,
--   or adds a slice to the context.
analyseIndex :: Context rep -> [VName] -> VName -> [DimIndex SubExp] -> (Context rep, IndexTable rep)

-- | Context Value (VariableInfo) is the type used in the context to
--   categorize assignments. For example, a pattern might depend on a
--   function parameter, a gtid, or some other pattern.
data VariableInfo rep
VariableInfo :: Names -> Int -> [BodyType] -> VarType -> VariableInfo rep
[deps] :: VariableInfo rep -> Names
[level] :: VariableInfo rep -> Int
[parents_nest] :: VariableInfo rep -> [BodyType]
[variableType] :: VariableInfo rep -> VarType
data VarType
ConstType :: VarType
Variable :: VarType
ThreadID :: VarType
LoopVar :: VarType
isCounter :: VarType -> Bool

-- | Tuple of patternName and nested level it index occurred at, as
--   well as what the actual iteration type is.
data Dependency
Dependency :: Int -> VarType -> Dependency
[lvl] :: Dependency -> Int
[varType] :: Dependency -> VarType
instance GHC.Show.Show Futhark.Analysis.AccessPattern.SegOpName
instance GHC.Classes.Ord Futhark.Analysis.AccessPattern.SegOpName
instance GHC.Classes.Eq Futhark.Analysis.AccessPattern.SegOpName
instance GHC.Classes.Eq Futhark.Analysis.AccessPattern.BodyType
instance GHC.Classes.Ord Futhark.Analysis.AccessPattern.BodyType
instance GHC.Show.Show Futhark.Analysis.AccessPattern.BodyType
instance GHC.Classes.Eq Futhark.Analysis.AccessPattern.VarType
instance GHC.Show.Show Futhark.Analysis.AccessPattern.VarType
instance forall k (rep :: k). GHC.Classes.Eq (Futhark.Analysis.AccessPattern.VariableInfo rep)
instance forall k (rep :: k). GHC.Show.Show (Futhark.Analysis.AccessPattern.VariableInfo rep)
instance GHC.Show.Show Futhark.Analysis.AccessPattern.Dependency
instance GHC.Classes.Eq Futhark.Analysis.AccessPattern.Dependency
instance forall k (rep :: k). GHC.Show.Show (Futhark.Analysis.AccessPattern.DimAccess rep)
instance forall k (rep :: k). GHC.Classes.Eq (Futhark.Analysis.AccessPattern.DimAccess rep)
instance forall k (rep :: k). GHC.Classes.Eq (Futhark.Analysis.AccessPattern.Context rep)
instance forall k (rep :: k). GHC.Show.Show (Futhark.Analysis.AccessPattern.Context rep)
instance Futhark.Analysis.AccessPattern.Analyse Futhark.IR.GPU.GPU
instance Futhark.Analysis.AccessPattern.Analyse Futhark.IR.MC.MC
instance Futhark.Analysis.AccessPattern.Analyse Futhark.IR.GPUMem.GPUMem
instance Futhark.Analysis.AccessPattern.Analyse Futhark.IR.MCMem.MCMem
instance Futhark.Analysis.AccessPattern.Analyse Futhark.IR.Seq.Seq
instance Futhark.Analysis.AccessPattern.Analyse Futhark.IR.SeqMem.SeqMem
instance Futhark.Analysis.AccessPattern.Analyse Futhark.IR.SOACS.SOACS
instance forall k (rep :: k). Prettyprinter.Internal.Pretty (Futhark.Analysis.AccessPattern.IndexTable rep)
instance forall k (rep :: k). GHC.Base.Monoid (Futhark.Analysis.AccessPattern.Context rep)
instance forall k (rep :: k). GHC.Base.Semigroup (Futhark.Analysis.AccessPattern.Context rep)
instance forall k (rep :: k). GHC.Base.Semigroup (Futhark.Analysis.AccessPattern.DimAccess rep)
instance forall k (rep :: k). GHC.Base.Monoid (Futhark.Analysis.AccessPattern.DimAccess rep)
instance forall k (rep :: k). Prettyprinter.Internal.Pretty (Futhark.Analysis.AccessPattern.DimAccess rep)
instance Prettyprinter.Internal.Pretty Futhark.Analysis.AccessPattern.VarType
instance Prettyprinter.Internal.Pretty Futhark.Analysis.AccessPattern.BodyType
instance Prettyprinter.Internal.Pretty Futhark.Analysis.AccessPattern.SegOpName

module Futhark.Optimise.ArrayLayout.Layout

-- | Given an ordering function for DimAccess, and an IndexTable,
--   return a LayoutTable. We remove entries with no results after
--   permutationFromDimAccess
layoutTableFromIndexTable :: Layout rep => PrimExpTable -> IndexTable rep -> LayoutTable
class Layout rep
type Permutation = [Int]
type LayoutTable = Map SegOpName (Map ArrayName (Map IndexExprName Permutation))

-- | Reasons common to all backends to not manifest an array.
commonPermutationEliminators :: [Int] -> [BodyType] -> Bool
instance Futhark.Optimise.ArrayLayout.Layout.Layout Futhark.IR.MC.MC
instance Futhark.Optimise.ArrayLayout.Layout.Layout Futhark.IR.GPU.GPU

-- | Do various kernel optimisations - mostly related to coalescing.
module Futhark.Optimise.ArrayLayout.Transform
class (Layout rep, PrimExpAnalysis rep) => Transform rep
transformStms :: (Transform rep, BuilderOps rep) => LayoutTable -> ExpMap rep -> Stms rep -> TransformM rep (Stms rep)
instance Futhark.Optimise.ArrayLayout.Transform.Transform Futhark.IR.GPU.GPU
instance Futhark.Optimise.ArrayLayout.Transform.Transform Futhark.IR.MC.MC

module Futhark.Optimise.ArrayLayout

-- | The optimisation performed on the GPU representation.
optimiseArrayLayoutGPU :: Pass GPU GPU

-- | The optimisation performed on the MC representation.
optimiseArrayLayoutMC :: Pass MC MC

-- | Optimisation pipelines.
module Futhark.Passes

-- | A pipeline used by all current compilers. Performs inlining, fusion,
--   and various forms of cleanup. This pipeline will be followed by
--   another one that deals with parallelism and memory.
standardPipeline :: Pipeline SOACS SOACS

-- | The pipeline used by the sequential backends. Turns all parallelism
--   into sequential loops. Includes standardPipeline.
seqPipeline :: Pipeline SOACS Seq

-- | The pipeline used by the CUDA, HIP, and OpenCL backends, but before
--   adding memory information. Includes standardPipeline.
gpuPipeline :: Pipeline SOACS GPU

-- | Run seqPipeline, then add memory information (and optimise it
--   slightly).
seqmemPipeline :: Pipeline SOACS SeqMem

-- | Run gpuPipeline, then add memory information (and optimise it a
--   lot).
gpumemPipeline :: Pipeline SOACS GPUMem

-- | Run standardPipeline and then convert to multicore
--   representation (and do a bunch of optimisation).
mcPipeline :: Pipeline SOACS MC

-- | Run mcPipeline and then add memory information.
mcmemPipeline :: Pipeline SOACS MCMem

-- | Parsers for primitive values and types.
module Language.Futhark.Primitive.Parse

-- | Defined in this module for convenience.
pPrimValue :: Parsec Void Text PrimValue

-- | Parse a primitive type.
pPrimType :: Parsec Void Text PrimType

-- | Parse a floating-point type.
pFloatType :: Parsec Void Text FloatType

-- | Parse an integer type.
pIntType :: Parsec Void Text IntType

-- | Is this character a valid member of an identifier?
constituent :: Char -> Bool

-- | Consume whitespace after the provided parser, if it succeeds.
lexeme :: Parsec Void Text a -> Parsec Void Text a

-- | keyword k parses k, which must not be immediately
--   followed by a constituent character. This ensures that
--   iff is not seen as the if keyword followed by
--   f. Sometimes called the "maximum munch" rule.
keyword :: Text -> Parsec Void Text ()

-- | Consume whitespace (including skipping line comments).
whitespace :: Parsec Void Text ()

-- | Building blocks for parsing prim primexpressions. *Not* an infix
--   representation.
module Futhark.Analysis.PrimExp.Parse

-- | Parse a PrimExp given a leaf parser.
pPrimExp :: PrimType -> Parsec Void Text v -> Parsec Void Text (PrimExp v)

-- | Defined in this module for convenience.
pPrimValue :: Parsec Void Text PrimValue

-- | Parser for the Futhark core language.
module Futhark.IR.Parse
parseSOACS :: FilePath -> Text -> Either Text (Prog SOACS)
parseGPU :: FilePath -> Text -> Either Text (Prog GPU)
parseGPUMem :: FilePath -> Text -> Either Text (Prog GPUMem)
parseMC :: FilePath -> Text -> Either Text (Prog MC)
parseMCMem :: FilePath -> Text -> Either Text (Prog MCMem)
parseSeq :: FilePath -> Text -> Either Text (Prog Seq)
parseSeqMem :: FilePath -> Text -> Either Text (Prog SeqMem)
parseType :: FilePath -> Text -> Either Text Type
parseDeclExtType :: FilePath -> Text -> Either Text DeclExtType
parseDeclType :: FilePath -> Text -> Either Text DeclType
parseVName :: FilePath -> Text -> Either Text VName
parseSubExp :: FilePath -> Text -> Either Text SubExp
parseSubExpRes :: FilePath -> Text -> Either Text SubExpRes
parseBodyGPU :: FilePath -> Text -> Either Text (Body GPU)
parseBodyMC :: FilePath -> Text -> Either Text (Body MC)
parseStmGPU :: FilePath -> Text -> Either Text (Stm GPU)
parseStmMC :: FilePath -> Text -> Either Text (Stm MC)

-- | The Futhark source language AST definition. Many types, such as
--   ExpBase, are parametrised by type and name representation. E.g.
--   in a value of type ExpBase f vn, annotations are wrapped in
--   the functor f, and all names are of type vn. See
--   https://futhark.readthedocs.org for a language reference, or
--   this module may be a little hard to understand.
--   
--   The system of primitive types is interesting in itself. See
--   Language.Futhark.Primitive.
module Language.Futhark.Syntax

-- | Prettyprint a value to a String, appropriately wrapped.
prettyString :: Pretty a => a -> String

-- | Prettyprint a value to a Text, appropriately wrapped.
prettyText :: Pretty a => a -> Text

-- | 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
Float16 :: FloatType
Float32 :: FloatType
Float64 :: FloatType

-- | Low-level primitive types.
data PrimType
Signed :: IntType -> PrimType
Unsigned :: IntType -> PrimType
FloatType :: FloatType -> PrimType
Bool :: PrimType

-- | The elaborated size of a dimension is just an expression.
type Size = ExpBase Info VName

-- | The size of an array type is a list of its dimension sizes. If
--   Nothing, that dimension is of a (statically) unknown size.
newtype Shape dim
Shape :: [dim] -> Shape dim
[shapeDims] :: Shape dim -> [dim]

-- | The number of dimensions contained in a shape.
shapeRank :: Shape 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 -> Shape dim -> Maybe (Shape dim)

-- | 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 u
Scalar :: ScalarTypeBase dim u -> TypeBase dim u
Array :: u -> Shape dim -> ScalarTypeBase dim NoUniqueness -> TypeBase dim u

-- | An argument passed to a type constructor.
data TypeArg dim
TypeArgDim :: dim -> TypeArg dim
TypeArgType :: TypeBase dim NoUniqueness -> TypeArg dim

-- | A dimension declaration expression for use in a TypeExp.
--   Syntactically includes the brackets.
data SizeExp d

-- | The size of the dimension is this expression (or whatever), all of
--   which free variables must be in scope.
SizeExp :: d -> SrcLoc -> SizeExp d

-- | No dimension declaration.
SizeExpAny :: SrcLoc -> SizeExp d

-- | An unstructured syntactic 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 d vn
TEVar :: QualName vn -> SrcLoc -> TypeExp d vn
TEParens :: TypeExp d vn -> SrcLoc -> TypeExp d vn
TETuple :: [TypeExp d vn] -> SrcLoc -> TypeExp d vn
TERecord :: [(L Name, TypeExp d vn)] -> SrcLoc -> TypeExp d vn
TEArray :: SizeExp d -> TypeExp d vn -> SrcLoc -> TypeExp d vn
TEUnique :: TypeExp d vn -> SrcLoc -> TypeExp d vn
TEApply :: TypeExp d vn -> TypeArgExp d vn -> SrcLoc -> TypeExp d vn
TEArrow :: Maybe vn -> TypeExp d vn -> TypeExp d vn -> SrcLoc -> TypeExp d vn
TESum :: [(Name, [TypeExp d vn])] -> SrcLoc -> TypeExp d vn
TEDim :: [vn] -> TypeExp d vn -> SrcLoc -> TypeExp d vn

-- | A type argument expression passed to a type constructor.
data TypeArgExp d vn
TypeArgExpSize :: SizeExp d -> TypeArgExp d vn
TypeArgExpType :: TypeExp d vn -> TypeArgExp d 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 u
Prim :: PrimType -> ScalarTypeBase dim u
TypeVar :: u -> QualName VName -> [TypeArg dim] -> ScalarTypeBase dim u
Record :: Map Name (TypeBase dim u) -> ScalarTypeBase dim u
Sum :: Map Name [TypeBase dim u] -> ScalarTypeBase dim u

-- | The aliasing corresponds to the lexical closure of the function.
Arrow :: u -> PName -> Diet -> TypeBase dim NoUniqueness -> RetTypeBase dim Uniqueness -> ScalarTypeBase dim u

-- | Types that can appear to the right of a function arrow. This just
--   means they can be existentially quantified.
data RetTypeBase dim as
RetType :: [VName] -> TypeBase dim as -> RetTypeBase dim as
[retDims] :: RetTypeBase dim as -> [VName]
[retType] :: RetTypeBase dim as -> TypeBase dim as

-- | A "structural" type with shape annotations and no aliasing
--   information, used for declarations.
type StructType = TypeBase Size NoUniqueness

-- | A type with consumption information, used for function parameters (but
--   not in function types).
type ParamType = TypeBase Size Diet

-- | A type with uniqueness information, used for function return types
type ResType = TypeBase Size Uniqueness

-- | The return type version of a ResType.
type StructRetType = RetTypeBase Size NoUniqueness

-- | The return type version of a StructType.
type ResRetType = RetTypeBase Size Uniqueness

-- | A value type contains full, manifest size information.
type ValueType = TypeBase Int64 NoUniqueness

-- | Information about which parts of a parameter are consumed. This can be
--   considered kind of an effect on the function.
data Diet

-- | Does not consume the parameter.
Observe :: Diet

-- | Consumes the parameter.
Consume :: Diet

-- | An integer value.
data IntValue
Int8Value :: !Int8 -> IntValue
Int16Value :: !Int16 -> IntValue
Int32Value :: !Int32 -> IntValue
Int64Value :: !Int64 -> IntValue

-- | A floating-point value.
data FloatValue
Float16Value :: !Half -> 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

-- | The payload of an attribute.
data AttrInfo vn
AttrAtom :: AttrAtom vn -> SrcLoc -> AttrInfo vn
AttrComp :: Name -> [AttrInfo vn] -> SrcLoc -> AttrInfo vn

-- | The value of an AttrAtom.
data AttrAtom vn
AtomName :: Name -> AttrAtom vn
AtomInt :: Integer -> AttrAtom vn

-- | Default binary operators.
data BinOp

-- | A pseudo-operator standing in for any normal identifier used as an
--   operator (they all have the same fixity).
Backtick :: BinOp

-- | Not a real operator, but operator with this as a prefix may be defined
--   by the user.
Bang :: BinOp

-- | Not a real operator, but operator with this as a prefix may be defined
--   by the user.
Equ :: 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 t
Ident :: vn -> f t -> SrcLoc -> IdentBase f vn t
[identName] :: IdentBase f vn t -> vn
[identType] :: IdentBase f vn t -> f t
[identSrcLoc] :: IdentBase f vn t -> 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

-- | A slicing of an array (potentially multiple dimensions).
type SliceBase f vn = [DimIndexBase f vn]

-- | A binding of a size in a pattern (essentially a size parameter in a
--   let expression).
data SizeBinder vn
SizeBinder :: !vn -> !SrcLoc -> SizeBinder vn
[sizeName] :: SizeBinder vn -> !vn
[sizeLoc] :: SizeBinder vn -> !SrcLoc

-- | An "application expression" is a semantic (not syntactic) grouping of
--   expressions that have "funcall-like" semantics, mostly meaning that
--   they can return existential sizes. In our type theory, these are all
--   thought to be bound to names (*Administrative Normal Form*), but as
--   this is not practical in a real language, we instead use an annotation
--   (AppRes) that stores the information we need, so we can pretend
--   that an application expression was really bound to a name.
data AppExpBase f vn

-- | Function application. Parts of the compiler expects that the function
--   expression is never itself an Apply. Use the mkApply
--   function to maintain this invariant, rather than constructing
--   Apply directly.
--   
--   The Maybe VNames are existential sizes generated by this
--   argument. May have duplicates across the program, but they will all
--   produce the same value (the expressions will be identical).
Apply :: ExpBase f vn -> NonEmpty (f (Maybe VName), ExpBase f vn) -> SrcLoc -> AppExpBase f vn
Range :: ExpBase f vn -> Maybe (ExpBase f vn) -> Inclusiveness (ExpBase f vn) -> SrcLoc -> AppExpBase f vn
LetPat :: [SizeBinder vn] -> PatBase f vn StructType -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> AppExpBase f vn
LetFun :: vn -> ([TypeParamBase vn], [PatBase f vn ParamType], Maybe (TypeExp (ExpBase f vn) vn), f ResRetType, ExpBase f vn) -> ExpBase f vn -> SrcLoc -> AppExpBase f vn
If :: ExpBase f vn -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> AppExpBase f vn
Loop :: [VName] -> PatBase f vn ParamType -> LoopInitBase f vn -> LoopFormBase f vn -> ExpBase f vn -> SrcLoc -> AppExpBase f vn
BinOp :: (QualName vn, SrcLoc) -> f StructType -> (ExpBase f vn, f (Maybe VName)) -> (ExpBase f vn, f (Maybe VName)) -> SrcLoc -> AppExpBase f vn
LetWith :: IdentBase f vn StructType -> IdentBase f vn StructType -> SliceBase f vn -> ExpBase f vn -> ExpBase f vn -> SrcLoc -> AppExpBase f vn
Index :: ExpBase f vn -> SliceBase f vn -> SrcLoc -> AppExpBase f vn

-- | A match expression.
Match :: ExpBase f vn -> NonEmpty (CaseBase f vn) -> SrcLoc -> AppExpBase f vn

-- | An annotation inserted by the type checker on constructs that are
--   "function calls" (either literally or conceptually). This annotation
--   encodes the result type, as well as any existential sizes that are
--   generated here.
data AppRes
AppRes :: StructType -> [VName] -> AppRes
[appResType] :: AppRes -> StructType
[appResExt] :: AppRes -> [VName]

-- | The Futhark expression language.
--   
--   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 StructType -> SrcLoc -> ExpBase f vn

-- | A polymorphic decimal literal.
FloatLit :: Double -> f StructType -> SrcLoc -> ExpBase f vn

-- | A string literal is just a fancy syntax for an array of bytes.
StringLit :: [Word8] -> SrcLoc -> ExpBase f vn
Hole :: f StructType -> SrcLoc -> ExpBase f vn
Var :: QualName vn -> f StructType -> 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 StructType -> SrcLoc -> ExpBase f vn

-- | Array value constants, where the elements are known to be constant
--   primitives. This is a fast-path variant of ArrayLit that will
--   in some cases be constructed by the parser, and also result from
--   normalisation later on. Has exactly the same semantics as an
--   ArrayLit.
ArrayVal :: [PrimValue] -> PrimType -> SrcLoc -> ExpBase f vn

-- | An attribute applied to the following expression.
Attr :: AttrInfo vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
Project :: Name -> ExpBase f vn -> f StructType -> SrcLoc -> ExpBase f vn

-- | Numeric negation (ugly special case; Haskell did it first).
Negate :: ExpBase f vn -> SrcLoc -> ExpBase f vn

-- | Logical and bitwise negation.
Not :: ExpBase f vn -> 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 Text -> SrcLoc -> ExpBase f vn

-- | An n-ary value constructor.
Constr :: Name -> [ExpBase f vn] -> f StructType -> SrcLoc -> ExpBase f vn
Update :: ExpBase f vn -> SliceBase f vn -> ExpBase f vn -> SrcLoc -> ExpBase f vn
RecordUpdate :: ExpBase f vn -> [Name] -> ExpBase f vn -> f StructType -> SrcLoc -> ExpBase f vn
Lambda :: [PatBase f vn ParamType] -> ExpBase f vn -> Maybe (TypeExp (ExpBase f vn) vn) -> f ResRetType -> SrcLoc -> ExpBase f vn

-- | +; first two types are operands, third is result.
OpSection :: QualName vn -> f StructType -> SrcLoc -> ExpBase f vn

-- | 2+; first type is operand, second is result.
OpSectionLeft :: QualName vn -> f StructType -> ExpBase f vn -> (f (PName, ParamType, Maybe VName), f (PName, ParamType)) -> (f ResRetType, f [VName]) -> SrcLoc -> ExpBase f vn

-- | +2; first type is operand, second is result.
OpSectionRight :: QualName vn -> f StructType -> ExpBase f vn -> (f (PName, ParamType), f (PName, ParamType, Maybe VName)) -> f ResRetType -> SrcLoc -> ExpBase f vn

-- | Field projection as a section: (.x.y.z).
ProjectSection :: [Name] -> f StructType -> SrcLoc -> ExpBase f vn

-- | Array indexing as a section: (.[i,j]).
IndexSection :: SliceBase f vn -> f StructType -> SrcLoc -> ExpBase f vn

-- | Type ascription: e : t.
Ascript :: ExpBase f vn -> TypeExp (ExpBase f vn) vn -> SrcLoc -> ExpBase f vn

-- | Size coercion: e :> t.
Coerce :: ExpBase f vn -> TypeExp (ExpBase f vn) vn -> f StructType -> SrcLoc -> ExpBase f vn
AppExp :: AppExpBase f vn -> f AppRes -> ExpBase f vn

-- | An entry in a record literal.
data FieldBase f vn
RecordFieldExplicit :: L Name -> ExpBase f vn -> SrcLoc -> FieldBase f vn
RecordFieldImplicit :: L vn -> f StructType -> SrcLoc -> FieldBase f vn

-- | A case in a match expression.
data CaseBase f vn
CasePat :: PatBase f vn StructType -> ExpBase f vn -> SrcLoc -> CaseBase f vn

-- | Initial value for the loop. If none is provided, then an expression
--   will be synthesised based on the parameter.
data LoopInitBase f vn
LoopInitExplicit :: ExpBase f vn -> LoopInitBase f vn
LoopInitImplicit :: f (ExpBase f vn) -> LoopInitBase f vn

-- | Whether the loop is a for-loop or a while-loop.
data LoopFormBase f vn
For :: IdentBase f vn StructType -> ExpBase f vn -> LoopFormBase f vn
ForIn :: PatBase f vn StructType -> 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 PatBase f vn t
TuplePat :: [PatBase f vn t] -> SrcLoc -> PatBase f vn t
RecordPat :: [(L Name, PatBase f vn t)] -> SrcLoc -> PatBase f vn t
PatParens :: PatBase f vn t -> SrcLoc -> PatBase f vn t
Id :: vn -> f t -> SrcLoc -> PatBase f vn t
Wildcard :: f t -> SrcLoc -> PatBase f vn t
PatAscription :: PatBase f vn t -> TypeExp (ExpBase f vn) vn -> SrcLoc -> PatBase f vn t
PatLit :: PatLit -> f t -> SrcLoc -> PatBase f vn t
PatConstr :: Name -> f t -> [PatBase f vn t] -> SrcLoc -> PatBase f vn t
PatAttr :: AttrInfo vn -> PatBase f vn t -> SrcLoc -> PatBase f vn t

-- | Canonical reference to a Futhark code file. Does not include the
--   .fut extension. This is most often a path relative to the
--   working directory of the compiler. In a multi-file program, a file is
--   known by exactly one import name, even if it is referenced relatively
--   by different names by files in different subdirectories.
newtype ImportName
ImportName :: FilePath -> ImportName

-- | A spec is a component of a module type.
data SpecBase f vn
ValSpec :: vn -> [TypeParamBase vn] -> TypeExp (ExpBase f vn) vn -> f StructType -> Maybe DocComment -> SrcLoc -> SpecBase f vn
[specName] :: SpecBase f vn -> vn
[specTypeParams] :: SpecBase f vn -> [TypeParamBase vn]
[specTypeExp] :: SpecBase f vn -> TypeExp (ExpBase f vn) vn
[specType] :: SpecBase f vn -> f StructType
[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 -> ModTypeExpBase f vn -> Maybe DocComment -> SrcLoc -> SpecBase f vn
IncludeSpec :: ModTypeExpBase f vn -> SrcLoc -> SpecBase f vn

-- | A module type expression.
data ModTypeExpBase f vn
ModTypeVar :: QualName vn -> f (Map VName VName) -> SrcLoc -> ModTypeExpBase f vn
ModTypeParens :: ModTypeExpBase f vn -> SrcLoc -> ModTypeExpBase f vn
ModTypeSpecs :: [SpecBase f vn] -> SrcLoc -> ModTypeExpBase f vn
ModTypeWith :: ModTypeExpBase f vn -> TypeRefBase f vn -> SrcLoc -> ModTypeExpBase f vn
ModTypeArrow :: Maybe vn -> ModTypeExpBase f vn -> ModTypeExpBase f vn -> SrcLoc -> ModTypeExpBase f vn

-- | A type refinement.
data TypeRefBase f vn
TypeRef :: QualName vn -> [TypeParamBase vn] -> TypeExp (ExpBase f vn) vn -> SrcLoc -> TypeRefBase f vn

-- | Module type binding.
data ModTypeBindBase f vn
ModTypeBind :: vn -> ModTypeExpBase f vn -> Maybe DocComment -> SrcLoc -> ModTypeBindBase f vn
[modTypeName] :: ModTypeBindBase f vn -> vn
[modTypeExp] :: ModTypeBindBase f vn -> ModTypeExpBase f vn
[modTypeDoc] :: ModTypeBindBase f vn -> Maybe DocComment
[modTypeLoc] :: ModTypeBindBase 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 ImportName -> 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 -> ModTypeExpBase f vn -> f (Map VName VName) -> SrcLoc -> ModExpBase f vn
ModLambda :: ModParamBase f vn -> Maybe (ModTypeExpBase 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 (ModTypeExpBase 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]
[modType] :: ModBindBase f vn -> Maybe (ModTypeExpBase 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 -> ModTypeExpBase f vn -> f [VName] -> SrcLoc -> ModParamBase f vn
[modParamName] :: ModParamBase f vn -> vn
[modParamType] :: ModParamBase f vn -> ModTypeExpBase f vn
[modParamAbs] :: ModParamBase f vn -> f [VName]
[modParamLocation] :: ModParamBase f vn -> SrcLoc

-- | Documentation strings, including source location. The string may
--   contain newline characters, but it does not contain comment prefix
--   markers.
data DocComment
DocComment :: Text -> SrcLoc -> DocComment

-- | Function Declarations
data ValBindBase f vn
ValBind :: Maybe (f EntryPoint) -> vn -> Maybe (TypeExp (ExpBase f vn) vn) -> f ResRetType -> [TypeParamBase vn] -> [PatBase f vn ParamType] -> ExpBase f vn -> Maybe DocComment -> [AttrInfo vn] -> 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 (ExpBase f vn) vn)

-- | If valBindParams is null, then the retDims are brought
--   into scope at this point.
[valBindRetType] :: ValBindBase f vn -> f ResRetType
[valBindTypeParams] :: ValBindBase f vn -> [TypeParamBase vn]
[valBindParams] :: ValBindBase f vn -> [PatBase f vn ParamType]
[valBindBody] :: ValBindBase f vn -> ExpBase f vn
[valBindDoc] :: ValBindBase f vn -> Maybe DocComment
[valBindAttrs] :: ValBindBase f vn -> [AttrInfo vn]
[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 :: [EntryParam] -> EntryType -> EntryPoint
[entryParams] :: EntryPoint -> [EntryParam]
[entryReturn] :: EntryPoint -> EntryType

-- | Part of the type of an entry point. Has an actual type, and maybe also
--   an ascribed type expression. Note that although size expressions in
--   the elaborated type can contain variables, they are no longer in
--   scope, and are considered more like equivalence classes.
data EntryType
EntryType :: StructType -> Maybe (TypeExp (ExpBase Info VName) VName) -> EntryType
[entryType] :: EntryType -> StructType
[entryAscribed] :: EntryType -> Maybe (TypeExp (ExpBase Info VName) VName)

-- | A parameter of an entry point.
data EntryParam
EntryParam :: Name -> EntryType -> EntryParam
[entryParamName] :: EntryParam -> Name
[entryParamType] :: EntryParam -> EntryType

-- | 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] -> TypeExp (ExpBase f vn) vn -> f StructRetType -> 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 -> TypeExp (ExpBase f vn) vn
[typeElab] :: TypeBindBase f vn -> f StructRetType
[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
ModTypeDec :: ModTypeBindBase 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 ImportName -> SrcLoc -> DecBase f vn

-- | A value of type L a is a value of type a with an
--   associated Loc, but this location is ignored when performing
--   comparisons.
data () => L a
L :: Loc -> a -> L a

-- | 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 name qualified with a breadcrumb of module accesses.
data QualName vn
QualName :: ![vn] -> !vn -> QualName vn
[qualQuals] :: QualName vn -> ![vn]
[qualLeaf] :: QualName vn -> !vn

-- | Construct an Apply node, with type information.
mkApply :: ExpBase Info vn -> [(Maybe VName, ExpBase Info vn)] -> AppRes -> ExpBase Info vn

-- | Construct an Apply node, without type information.
mkApplyUT :: ExpBase NoInfo vn -> ExpBase NoInfo vn -> ExpBase NoInfo vn

-- | Create a Size from a name.
sizeFromName :: QualName VName -> SrcLoc -> Size

-- | Create a Size from a constant integer.
sizeFromInteger :: Integer -> SrcLoc -> Size
loopInitExp :: LoopInitBase Info VName -> ExpBase Info VName
instance forall k (a :: k). GHC.Show.Show (Language.Futhark.Syntax.NoInfo a)
instance forall k (a :: k). GHC.Classes.Ord (Language.Futhark.Syntax.NoInfo a)
instance forall k (a :: k). 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 forall k (vn :: k). GHC.Show.Show (Language.Futhark.Syntax.AttrAtom vn)
instance forall k (vn :: k). GHC.Classes.Ord (Language.Futhark.Syntax.AttrAtom vn)
instance forall k (vn :: k). GHC.Classes.Eq (Language.Futhark.Syntax.AttrAtom vn)
instance forall k (vn :: k). GHC.Show.Show (Language.Futhark.Syntax.AttrInfo vn)
instance forall k (vn :: k). GHC.Classes.Ord (Language.Futhark.Syntax.AttrInfo vn)
instance forall k (vn :: k). GHC.Classes.Eq (Language.Futhark.Syntax.AttrInfo vn)
instance GHC.Show.Show dim => GHC.Show.Show (Language.Futhark.Syntax.Shape dim)
instance GHC.Classes.Ord dim => GHC.Classes.Ord (Language.Futhark.Syntax.Shape dim)
instance GHC.Classes.Eq dim => GHC.Classes.Eq (Language.Futhark.Syntax.Shape dim)
instance GHC.Show.Show Language.Futhark.Syntax.PName
instance GHC.Show.Show d => GHC.Show.Show (Language.Futhark.Syntax.SizeExp d)
instance GHC.Classes.Ord d => GHC.Classes.Ord (Language.Futhark.Syntax.SizeExp d)
instance GHC.Classes.Eq d => GHC.Classes.Eq (Language.Futhark.Syntax.SizeExp d)
instance GHC.Show.Show Language.Futhark.Syntax.Diet
instance GHC.Classes.Ord Language.Futhark.Syntax.Diet
instance GHC.Classes.Eq Language.Futhark.Syntax.Diet
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 d, GHC.Show.Show vn) => GHC.Show.Show (Language.Futhark.Syntax.TypeArgExp d vn)
instance (GHC.Classes.Ord d, GHC.Classes.Ord vn) => GHC.Classes.Ord (Language.Futhark.Syntax.TypeArgExp d vn)
instance (GHC.Classes.Eq d, GHC.Classes.Eq vn) => GHC.Classes.Eq (Language.Futhark.Syntax.TypeArgExp d vn)
instance (GHC.Show.Show vn, GHC.Show.Show d) => GHC.Show.Show (Language.Futhark.Syntax.TypeExp d vn)
instance (GHC.Classes.Ord vn, GHC.Classes.Ord d) => GHC.Classes.Ord (Language.Futhark.Syntax.TypeExp d vn)
instance (GHC.Classes.Eq vn, GHC.Classes.Eq d) => GHC.Classes.Eq (Language.Futhark.Syntax.TypeExp d vn)
instance (GHC.Show.Show as, GHC.Show.Show dim) => GHC.Show.Show (Language.Futhark.Syntax.RetTypeBase dim as)
instance (GHC.Classes.Ord as, GHC.Classes.Ord dim) => GHC.Classes.Ord (Language.Futhark.Syntax.RetTypeBase dim as)
instance (GHC.Classes.Eq as, GHC.Classes.Eq dim) => GHC.Classes.Eq (Language.Futhark.Syntax.RetTypeBase dim as)
instance (GHC.Show.Show dim, GHC.Show.Show u) => GHC.Show.Show (Language.Futhark.Syntax.TypeBase dim u)
instance (GHC.Classes.Ord dim, GHC.Classes.Ord u) => GHC.Classes.Ord (Language.Futhark.Syntax.TypeBase dim u)
instance (GHC.Classes.Eq dim, GHC.Classes.Eq u) => GHC.Classes.Eq (Language.Futhark.Syntax.TypeBase dim u)
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 dim, GHC.Show.Show u) => GHC.Show.Show (Language.Futhark.Syntax.ScalarTypeBase dim u)
instance (GHC.Classes.Ord dim, GHC.Classes.Ord u) => GHC.Classes.Ord (Language.Futhark.Syntax.ScalarTypeBase dim u)
instance (GHC.Classes.Eq dim, GHC.Classes.Eq u) => GHC.Classes.Eq (Language.Futhark.Syntax.ScalarTypeBase dim u)
instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.SizeBinder vn)
instance GHC.Classes.Ord vn => GHC.Classes.Ord (Language.Futhark.Syntax.SizeBinder vn)
instance GHC.Classes.Eq vn => GHC.Classes.Eq (Language.Futhark.Syntax.SizeBinder 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.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.Show.Show Language.Futhark.Syntax.AppRes
instance GHC.Classes.Ord Language.Futhark.Syntax.AppRes
instance GHC.Classes.Eq Language.Futhark.Syntax.AppRes
instance GHC.Show.Show Language.Futhark.Syntax.EntryType
instance GHC.Show.Show Language.Futhark.Syntax.EntryParam
instance GHC.Show.Show Language.Futhark.Syntax.EntryPoint
instance GHC.Show.Show Language.Futhark.Syntax.ImportName
instance GHC.Classes.Ord Language.Futhark.Syntax.ImportName
instance GHC.Classes.Eq Language.Futhark.Syntax.ImportName
instance GHC.Show.Show (Language.Futhark.Syntax.Info t) => GHC.Show.Show (Language.Futhark.Syntax.IdentBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName t)
instance (GHC.Show.Show (Language.Futhark.Syntax.Info t), GHC.Show.Show vn) => GHC.Show.Show (Language.Futhark.Syntax.IdentBase Language.Futhark.Syntax.NoInfo vn t)
instance GHC.Show.Show (Language.Futhark.Syntax.DimIndexBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.DimIndexBase Language.Futhark.Syntax.NoInfo vn)
instance GHC.Classes.Eq (Language.Futhark.Syntax.DimIndexBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Eq (Language.Futhark.Syntax.DimIndexBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.DimIndexBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.DimIndexBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.AppExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.AppExpBase Language.Futhark.Syntax.NoInfo vn)
instance GHC.Classes.Eq (Language.Futhark.Syntax.AppExpBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Eq (Language.Futhark.Syntax.AppExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.AppExpBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.AppExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.ExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.ExpBase Language.Futhark.Syntax.NoInfo 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 GHC.Classes.Eq (Language.Futhark.Syntax.ExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.ExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.NoInfo vn)
instance GHC.Classes.Eq (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Eq (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.CaseBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.CaseBase Language.Futhark.Syntax.NoInfo vn)
instance GHC.Classes.Eq (Language.Futhark.Syntax.CaseBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Eq (Language.Futhark.Syntax.CaseBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.CaseBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.CaseBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.LoopInitBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.LoopInitBase Language.Futhark.Syntax.NoInfo vn)
instance GHC.Classes.Eq (Language.Futhark.Syntax.LoopInitBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Eq (Language.Futhark.Syntax.LoopInitBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.LoopInitBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.LoopInitBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show vn => GHC.Show.Show (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.NoInfo vn)
instance GHC.Classes.Eq (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Eq (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName)
instance GHC.Classes.Ord (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.Info t) => GHC.Show.Show (Language.Futhark.Syntax.PatBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName t)
instance (GHC.Show.Show (Language.Futhark.Syntax.NoInfo t), GHC.Show.Show vn) => GHC.Show.Show (Language.Futhark.Syntax.PatBase Language.Futhark.Syntax.NoInfo vn t)
instance GHC.Classes.Eq (Language.Futhark.Syntax.NoInfo t) => GHC.Classes.Eq (Language.Futhark.Syntax.PatBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName t)
instance GHC.Classes.Eq (Language.Futhark.Syntax.Info t) => GHC.Classes.Eq (Language.Futhark.Syntax.PatBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName t)
instance GHC.Classes.Ord (Language.Futhark.Syntax.NoInfo t) => GHC.Classes.Ord (Language.Futhark.Syntax.PatBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.VName t)
instance GHC.Classes.Ord (Language.Futhark.Syntax.Info t) => GHC.Classes.Ord (Language.Futhark.Syntax.PatBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName t)
instance GHC.Show.Show (Language.Futhark.Syntax.ValBindBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.ValBindBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.TypeBindBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.TypeBindBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.SpecBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.SpecBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.ModTypeExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.ModTypeExpBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.TypeRefBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.TypeRefBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.ModTypeBindBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.ModTypeBindBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.ModExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.ModExpBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.ModBindBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.ModBindBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.ModParamBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.ModParamBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.DecBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.DecBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance GHC.Show.Show (Language.Futhark.Syntax.ProgBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName)
instance GHC.Show.Show (Language.Futhark.Syntax.ProgBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
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.ModTypeBindBase f vn)
instance Data.Loc.Located (Language.Futhark.Syntax.SpecBase f vn)
instance Data.Loc.Located (Language.Futhark.Syntax.ModTypeExpBase 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.TypeBindBase f vn)
instance Data.Loc.Located (Language.Futhark.Syntax.AppExpBase 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.LoopInitBase Language.Futhark.Syntax.Info vn)
instance Data.Loc.Located (Language.Futhark.Syntax.PatBase f vn t)
instance Data.Traversable.Traversable f => GHC.Base.Functor (Language.Futhark.Syntax.PatBase f vn)
instance Data.Traversable.Traversable f => Data.Foldable.Foldable (Language.Futhark.Syntax.PatBase f vn)
instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Language.Futhark.Syntax.PatBase 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 Data.Loc.Located Language.Futhark.Syntax.DocComment
instance Data.Loc.Located (Language.Futhark.Syntax.SizeBinder vn)
instance Data.Bitraversable.Bitraversable Language.Futhark.Syntax.RetTypeBase
instance GHC.Base.Functor (Language.Futhark.Syntax.RetTypeBase dim)
instance Data.Foldable.Foldable (Language.Futhark.Syntax.RetTypeBase dim)
instance Data.Traversable.Traversable (Language.Futhark.Syntax.RetTypeBase dim)
instance Data.Bifunctor.Bifunctor Language.Futhark.Syntax.RetTypeBase
instance Data.Bifoldable.Bifoldable Language.Futhark.Syntax.RetTypeBase
instance Data.Bitraversable.Bitraversable Language.Futhark.Syntax.ScalarTypeBase
instance GHC.Base.Functor (Language.Futhark.Syntax.ScalarTypeBase dim)
instance Data.Foldable.Foldable (Language.Futhark.Syntax.ScalarTypeBase dim)
instance Data.Traversable.Traversable (Language.Futhark.Syntax.ScalarTypeBase dim)
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 GHC.Base.Functor (Language.Futhark.Syntax.TypeBase dim)
instance Data.Foldable.Foldable (Language.Futhark.Syntax.TypeBase dim)
instance Data.Traversable.Traversable (Language.Futhark.Syntax.TypeBase dim)
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.Base.Functor (Language.Futhark.Syntax.TypeArgExp d)
instance Data.Foldable.Foldable (Language.Futhark.Syntax.TypeArgExp d)
instance Data.Traversable.Traversable (Language.Futhark.Syntax.TypeArgExp d)
instance Data.Bifunctor.Bifunctor Language.Futhark.Syntax.TypeArgExp
instance Data.Bifoldable.Bifoldable Language.Futhark.Syntax.TypeArgExp
instance Data.Bitraversable.Bitraversable Language.Futhark.Syntax.TypeArgExp
instance Data.Loc.Located (Language.Futhark.Syntax.TypeArgExp f vn)
instance Data.Bitraversable.Bitraversable Language.Futhark.Syntax.TypeExp
instance GHC.Base.Functor (Language.Futhark.Syntax.TypeExp d)
instance Data.Foldable.Foldable (Language.Futhark.Syntax.TypeExp dim)
instance Data.Traversable.Traversable (Language.Futhark.Syntax.TypeExp dim)
instance Data.Bifunctor.Bifunctor Language.Futhark.Syntax.TypeExp
instance Data.Bifoldable.Bifoldable Language.Futhark.Syntax.TypeExp
instance Data.Loc.Located (Language.Futhark.Syntax.TypeExp f vn)
instance GHC.Classes.Eq v => GHC.Classes.Eq (Language.Futhark.Syntax.QualName v)
instance GHC.Classes.Ord v => GHC.Classes.Ord (Language.Futhark.Syntax.QualName v)
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 Prettyprinter.Internal.Pretty Language.Futhark.Syntax.BinOp
instance forall k vn (ty :: k -> *) (t :: k). GHC.Classes.Eq vn => GHC.Classes.Eq (Language.Futhark.Syntax.IdentBase ty vn t)
instance forall k vn (ty :: k -> *) (t :: k). GHC.Classes.Ord vn => GHC.Classes.Ord (Language.Futhark.Syntax.IdentBase ty vn t)
instance forall k (ty :: k -> *) vn (t :: k). Data.Loc.Located (Language.Futhark.Syntax.IdentBase ty vn t)
instance GHC.Base.Semigroup Language.Futhark.Syntax.Diet
instance GHC.Base.Monoid Language.Futhark.Syntax.Diet
instance GHC.Base.Functor Language.Futhark.Syntax.SizeExp
instance Data.Foldable.Foldable Language.Futhark.Syntax.SizeExp
instance Data.Traversable.Traversable Language.Futhark.Syntax.SizeExp
instance Data.Loc.Located (Language.Futhark.Syntax.SizeExp d)
instance GHC.Classes.Eq Language.Futhark.Syntax.PName
instance GHC.Classes.Ord Language.Futhark.Syntax.PName
instance Data.Foldable.Foldable Language.Futhark.Syntax.Shape
instance Data.Traversable.Traversable Language.Futhark.Syntax.Shape
instance GHC.Base.Functor Language.Futhark.Syntax.Shape
instance GHC.Base.Semigroup (Language.Futhark.Syntax.Shape dim)
instance GHC.Base.Monoid (Language.Futhark.Syntax.Shape dim)
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 Prettyprinter.Internal.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

-- | 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:
--   
--   
--   
- They are too slow.
--   
- More importantly, they do not tell you whether you have missed
--   some cases.
--   
--   
--   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)) -> (QualName VName -> m (QualName VName)) -> (StructType -> m StructType) -> (ParamType -> m ParamType) -> (ResRetType -> m ResRetType) -> ASTMapper m
[mapOnExp] :: ASTMapper m -> ExpBase Info VName -> m (ExpBase Info VName)
[mapOnName] :: ASTMapper m -> QualName VName -> m (QualName VName)
[mapOnStructType] :: ASTMapper m -> StructType -> m StructType
[mapOnParamType] :: ASTMapper m -> ParamType -> m ParamType
[mapOnResRetType] :: ASTMapper m -> ResRetType -> m ResRetType

-- | 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.AppExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.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.LoopInitBase 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.Syntax.ExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) Language.Futhark.Core.VName)
instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.TypeArgExp (Language.Futhark.Syntax.ExpBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName) Language.Futhark.Core.VName)
instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.SizeExp (Language.Futhark.Syntax.ExpBase Language.Futhark.Syntax.Info 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.AppRes
instance Language.Futhark.Traversals.ASTMappable Language.Futhark.Syntax.StructType
instance Language.Futhark.Traversals.ASTMappable Language.Futhark.Syntax.ParamType
instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.TypeBase Language.Futhark.Syntax.Size Language.Futhark.Core.Uniqueness)
instance Language.Futhark.Traversals.ASTMappable Language.Futhark.Syntax.ResRetType
instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.IdentBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName Language.Futhark.Syntax.StructType)
instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.PatBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName Language.Futhark.Syntax.StructType)
instance Language.Futhark.Traversals.ASTMappable (Language.Futhark.Syntax.PatBase Language.Futhark.Syntax.Info Language.Futhark.Core.VName Language.Futhark.Syntax.ParamType)
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)

module Language.Futhark.Tuple

-- | 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)]

-- | 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. For functions, 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] -> [ParamType] -> RetTypeBase Size Uniqueness -> Intrinsic
IntrinsicType :: Liftedness -> [TypeParamBase VName] -> StructType -> Intrinsic
IntrinsicEquality :: Intrinsic

-- | A map of all built-ins.
intrinsics :: Map VName Intrinsic

-- | Find the VName corresponding to a builtin. Crashes if that name
--   cannot be found.
intrinsicVar :: Name -> VName

-- | Is this include part of the built-in prelude?
isBuiltin :: FilePath -> Bool

-- | Is the position of this thing builtin as per isBuiltin? Things
--   without location are considered not built-in.
isBuiltinLoc :: Located a => a -> Bool

-- | 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

-- | 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, Loc)]

-- | The modules imported by a single declaration.
decImports :: DecBase f vn -> [(String, Loc)]

-- | The set of module types used in any exported (non-local) declaration.
progModuleTypes :: ProgBase Info VName -> Set VName

-- | 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 -> [Text] -> Text

-- | Find instances of typed holes in the program.
progHoles :: ProgBase Info VName -> [(Loc, StructType)]

-- | The name of the default program entry point (main).
defaultEntryPoint :: Name

-- | The name, if any.
paramName :: PName -> Maybe VName

-- | A special expression representing no known size. When present in a
--   type, each instance represents a distinct size. The type checker
--   should _never_ produce these - they are a (hopefully temporary) thing
--   introduced by defunctorisation and monomorphisation. They represent a
--   flaw in our implementation. When they occur in a return type, they can
--   be replaced with freshly created existential sizes. When they occur in
--   parameter types, they can be replaced with size parameters.
anySize :: Size

-- | 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 -> StructType

-- | The type scheme of a value binding, comprising the type parameters and
--   the actual type.
valBindTypeScheme :: ValBindBase Info VName -> ([TypeParamBase VName], StructType)

-- | The names that are brought into scope by this value binding (not
--   including its own parameter names, but including any existential
--   sizes).
valBindBound :: ValBindBase Info VName -> [VName]

-- | The type of a function with the given parameters and return type.
funType :: [Pat ParamType] -> ResRetType -> StructType

-- | Strip semantically irrelevant stuff from the top level of expression.
--   This is used to provide a slightly fuzzy notion of expression
--   equality.
--   
--   Ideally we'd implement unification on a simpler representation that
--   simply didn't allow us.
stripExp :: Exp -> Maybe Exp

-- | All non-trivial subexpressions (as by stripExp) of some expression,
--   not including the expression itself.
subExps :: Exp -> [Exp]

-- | If these two expressions are structurally similar at top level as
--   sizes, produce their subexpressions (which are not necessarily
--   similar, but you can check for that!). This is the machinery
--   underlying expresssion unification. We assume that the expressions
--   have the same type.
similarExps :: Exp -> Exp -> Maybe [(Exp, Exp)]

-- | Are these the same expression as per recursively invoking
--   similarExps?
sameExp :: Exp -> Exp -> Bool

-- | The set of identifiers bound in a pattern.
patIdents :: PatBase f vn t -> [IdentBase f vn t]

-- | The set of names bound in a pattern.
patNames :: Pat t -> [VName]

-- | Each name bound in a pattern alongside its type.
patternMap :: Pat t -> [(VName, t)]

-- | The type of values bound by the pattern.
patternType :: Pat (TypeBase d u) -> TypeBase d u

-- | The type matched by the pattern, including shape declarations if
--   present.
patternStructType :: Pat (TypeBase Size u) -> StructType

-- | When viewed as a function parameter, does this pattern correspond to a
--   named parameter of some type?
patternParam :: Pat ParamType -> (PName, Diet, StructType)

-- | patternOrderZero pat is True if all of the types in
--   the given pattern have order 0.
patternOrderZero :: Pat (TypeBase d u) -> 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

-- | diet t returns a description of how a function parameter of
--   type t consumes its argument.
diet :: TypeBase shape Diet -> 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 d u -> Int

-- | Return the shape of a type - for non-arrays, this is mempty.
arrayShape :: TypeBase dim as -> Shape dim

-- | 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 Diet], TypeBase dim NoUniqueness)

-- | foldFunType ts ret creates a function type (Arrow)
--   that takes ts as parameters and returns ret.
foldFunType :: [ParamType] -> ResRetType -> StructType

-- | The type names mentioned in a type.
typeVars :: TypeBase dim as -> Set VName

-- | If this type corresponds to the builtin "acc" type, return the type of
--   the underlying array.
isAccType :: TypeBase d u -> Maybe (TypeBase d NoUniqueness)

-- | 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 u -> Maybe (TypeBase dim 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 :: Int -> TypeBase dim as -> TypeBase dim as

-- | arrayOf u s t 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.
arrayOf :: Shape dim -> TypeBase dim NoUniqueness -> TypeBase dim NoUniqueness

-- | Like arrayOf, but you can pass in uniqueness info of the
--   resulting array.
arrayOfWithAliases :: u -> Shape dim -> TypeBase dim u' -> TypeBase dim u

-- | Convert any type to one that has rank information, no alias
--   information, and no embedded names.
toStructural :: TypeBase dim as -> TypeBase () ()

-- | Remove uniquenss information from a type.
toStruct :: TypeBase dim u -> TypeBase dim NoUniqueness

-- | Convert to ResType
toRes :: Uniqueness -> TypeBase Size u -> ResType

-- | Uses Observe.
toParam :: Diet -> TypeBase Size u -> ParamType

-- | Preserves relation between Diet and Uniqueness.
resToParam :: ResType -> ParamType

-- | Preserves relation between Diet and Uniqueness.
paramToRes :: ParamType -> ResType

-- | Convert to ResRetType
toResRet :: Uniqueness -> RetTypeBase Size u -> ResRetType

-- | 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 u1 -> u2 -> TypeBase dim u2

-- | Change the shape of a type to be just the rank.
noSizes :: TypeBase Size as -> TypeBase () 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

-- | Create a record type corresponding to a tuple with the given element
--   types.
tupleRecord :: [TypeBase dim as] -> ScalarTypeBase 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

-- | Match the dimensions of otherwise assumed-equal types. The combining
--   function is also passed the names bound within the type (from named
--   parameters or return types).
matchDims :: forall as m d1 d2. (Monoid as, Monad m) => ([VName] -> d1 -> d2 -> m d1) -> TypeBase d1 as -> TypeBase d2 as -> m (TypeBase d1 as)

-- | A type with no aliasing information but shape annotations.
type UncheckedType = TypeBase (Shape Name) ()

-- | An unchecked type expression.
type UncheckedTypeExp = TypeExp UncheckedExp Name

-- | An identifier with no type annotations.
type UncheckedIdent = IdentBase NoInfo Name

-- | An index with no type annotations.
type UncheckedDimIndex = DimIndexBase NoInfo Name

-- | A slice with no type annotations.
type UncheckedSlice = SliceBase 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 UncheckedModTypeExp = ModTypeExpBase NoInfo Name

-- | A type parameter with no type annotations.
type UncheckedTypeParam = TypeParamBase Name

-- | A pattern with no type annotations.
type UncheckedPat = PatBase NoInfo Name

-- | A function declaration with no type annotations.
type UncheckedValBind = ValBindBase NoInfo Name

-- | A type binding with no type annotations.
type UncheckedTypeBind = TypeBindBase NoInfo Name

-- | A module type binding with no type annotations.
type UncheckedModTypeBind = ModTypeBindBase NoInfo Name

-- | A module binding with no type annotations.
type UncheckedModBind = ModBindBase 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

-- | An identifier with type- and aliasing information.
type Ident = IdentBase Info VName

-- | An index with type information.
type DimIndex = DimIndexBase Info VName

-- | A slice with type information.
type Slice = SliceBase Info VName

-- | An application expression with type information.
type AppExp = AppExpBase Info VName

-- | An expression with type information.
type Exp = ExpBase Info VName

-- | A pattern with type information.
type Pat = PatBase 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 ModTypeExp = ModTypeExpBase Info VName

-- | A type-checked module binding.
type ModBind = ModBindBase Info VName

-- | A type-checked module type binding.
type ModTypeBind = ModTypeBindBase 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 known type arg with shape annotations.
type StructTypeArg = TypeArg Size

-- | 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
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 to a String, appropriately wrapped.
prettyString :: Pretty a => a -> String

-- | Prettyprint a list enclosed in curly braces.
prettyTuple :: Pretty a => [a] -> Text

-- | 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
prettyName :: IsName v => v -> Doc a
toName :: IsName v => v -> Name

-- | Prettyprint name as string. Only use this for debugging.
prettyNameString :: 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) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.DimIndexBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.AppExpBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.ExpBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.FieldBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.CaseBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.LoopInitBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.LoopFormBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f, Prettyprinter.Internal.Pretty t) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.PatBase f vn t)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.ProgBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.DecBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.ModExpBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.TypeBindBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.ValBindBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.SpecBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.ModTypeExpBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.ModTypeBindBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.ModParamBase f vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn, Language.Futhark.Pretty.Annot f) => Prettyprinter.Internal.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, Prettyprinter.Internal.Pretty d) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.TypeExp d vn)
instance (Prettyprinter.Internal.Pretty d, Language.Futhark.Pretty.IsName vn) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.TypeArgExp d vn)
instance Language.Futhark.Pretty.IsName vn => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.QualName vn)
instance forall k vn (f :: k -> *) (t :: k). Language.Futhark.Pretty.IsName vn => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.IdentBase f vn t)
instance Language.Futhark.Pretty.IsName vn => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.SizeBinder vn)
instance Language.Futhark.Pretty.IsName vn => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.AttrAtom vn)
instance Language.Futhark.Pretty.IsName vn => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.AttrInfo vn)
instance (GHC.Classes.Eq vn, Language.Futhark.Pretty.IsName vn) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.TypeParamBase vn)
instance Prettyprinter.Internal.Pretty Language.Futhark.Syntax.PrimValue
instance Prettyprinter.Internal.Pretty d => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.SizeExp d)
instance Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.Shape Language.Futhark.Syntax.Size)
instance Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.Shape ())
instance Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.Shape GHC.Int.Int64)
instance Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.Shape GHC.Types.Bool)
instance (Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.Shape dim), Prettyprinter.Internal.Pretty u) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.RetTypeBase dim u)
instance Prettyprinter.Internal.Pretty Language.Futhark.Syntax.Diet
instance (Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.Shape dim), Prettyprinter.Internal.Pretty u) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.ScalarTypeBase dim u)
instance (Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.Shape dim), Prettyprinter.Internal.Pretty u) => Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.TypeBase dim u)
instance Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.TypeArg Language.Futhark.Syntax.Size)
instance Prettyprinter.Internal.Pretty Language.Futhark.Syntax.PatLit
instance Prettyprinter.Internal.Pretty Language.Futhark.Syntax.Liftedness

-- | Definition of the tokens used in the lexer.
--   
--   Also defines other useful building blocks for constructing tokens.
module Language.Futhark.Parser.Lexer.Tokens

-- | 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
COMMENT :: Text -> Token
INDEXING :: Token
SYMBOL :: BinOp -> [Name] -> Name -> Token
CONSTRUCTOR :: Name -> Token
NATLIT :: Name -> Integer -> Token
INTLIT :: Integer -> Token
STRINGLIT :: Text -> 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
F16LIT :: Half -> 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
DOT :: Token
TWO_DOTS :: Token
TWO_DOTS_LT :: Token
TWO_DOTS_GT :: Token
THREE_DOTS :: Token
LPAR :: Token
RPAR :: Token
LBRACKET :: Token
RBRACKET :: Token
LCURLY :: Token
RCURLY :: Token
COMMA :: Token
UNDERSCORE :: Token
RIGHT_ARROW :: Token
QUESTION_MARK :: Token
EQU :: Token
ASTERISK :: Token
NEGATE :: Token
BANG :: Token
DOLLAR :: Token
LTH :: Token
HAT :: Token
TILDE :: Token
PIPE :: Token
IF :: Token
THEN :: Token
ELSE :: Token
DEF :: 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 :: Text -> Token
EOF :: Token
HOLE :: Token
ERROR :: Text -> Token
fromRoman :: Integral a => Text -> a
symbol :: [Name] -> Name -> Token
mkQualId :: Text -> ([Name], Name)
tokenC :: a -> ByteString -> a
tokenS :: (Text -> a) -> ByteString -> a

-- | Suffix a zero if the last character is dot.
suffZero :: Text -> Text
tryRead :: Read a => String -> Text -> a
decToken :: Integral a => (a -> Token) -> ByteString -> Token
binToken :: Integral a => (a -> Token) -> ByteString -> Token
hexToken :: Integral a => (a -> Token) -> ByteString -> Token
romToken :: Integral a => (a -> Token) -> ByteString -> Token
readHexRealLit :: RealFloat a => Text -> a
instance GHC.Classes.Ord Language.Futhark.Parser.Lexer.Tokens.Token
instance GHC.Classes.Eq Language.Futhark.Parser.Lexer.Tokens.Token
instance GHC.Show.Show Language.Futhark.Parser.Lexer.Tokens.Token

-- | Utility functions and definitions used in the Happy-generated parser.
--   They are defined here because the .y file is opaque to
--   linters and other tools. In particular, we cannot enable warnings for
--   that file, because Happy-generated code is very dirty by GHC's
--   standards.
module Language.Futhark.Parser.Monad
type ParserMonad = ExceptT SyntaxError (State ParserState)
data ParserState

-- | A comment consists of its starting and end position, as well as its
--   text. The contents include the comment start marker.
data Comment
Comment :: Loc -> Text -> Comment
[commentLoc] :: Comment -> Loc
[commentText] :: Comment -> Text
parse :: ParserMonad a -> FilePath -> Text -> Either SyntaxError a
parseWithComments :: ParserMonad a -> FilePath -> Text -> Either SyntaxError (a, [Comment])
lexer :: (L Token -> ParserMonad a) -> ParserMonad a
mustBeEmpty :: Located loc => loc -> ValueType -> ParserMonad ()
arrayFromList :: [a] -> Array Int a
binOp :: UncheckedExp -> L Token -> UncheckedExp -> UncheckedExp
binOpName :: L Token -> (QualName Name, Loc)
mustBe :: L Token -> Text -> ParserMonad ()
primNegate :: PrimValue -> PrimValue
applyExp :: NonEmpty UncheckedExp -> ParserMonad UncheckedExp
arrayLitExp :: [UncheckedExp] -> SrcLoc -> UncheckedExp
addDocSpec :: DocComment -> SpecBase NoInfo Name -> SpecBase NoInfo Name
addAttrSpec :: AttrInfo Name -> UncheckedSpec -> UncheckedSpec
addDoc :: DocComment -> UncheckedDec -> UncheckedDec
addAttr :: AttrInfo Name -> UncheckedDec -> UncheckedDec
twoDotsRange :: Loc -> ParserMonad a

-- | A syntax error.
data SyntaxError
SyntaxError :: Loc -> Text -> SyntaxError
[syntaxErrorLoc] :: SyntaxError -> Loc
[syntaxErrorMsg] :: SyntaxError -> Text
emptyArrayError :: Loc -> ParserMonad a
parseError :: (L Token, [String]) -> ParserMonad a
parseErrorAt :: Located loc => loc -> Maybe Text -> ParserMonad a

-- | Move the end position back one column.
backOneCol :: Loc -> Loc

-- | A value of type L a is a value of type a with an
--   associated Loc, but this location is ignored when performing
--   comparisons.
data () => 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
instance GHC.Show.Show Language.Futhark.Parser.Monad.Comment
instance GHC.Classes.Ord Language.Futhark.Parser.Monad.Comment
instance GHC.Classes.Eq Language.Futhark.Parser.Monad.Comment
instance Data.Loc.Located Language.Futhark.Parser.Monad.Comment

module Futhark.Fmt.Monad
type Fmt = FmtM (Doc AnsiStyle)

-- | An empty input.
nil :: Fmt

-- | Indents everything after a line occurs if in multiline and if in
--   singleline then indent.
nest :: Int -> Fmt -> Fmt

-- | Nest but with the standard value of two spaces.
stdNest :: Fmt -> Fmt

-- | Creates a piece of text, it should not contain any new lines.
text :: AnsiStyle -> Text -> Fmt

-- | A space.
space :: Fmt

-- | Forces a line to be used regardless of layout, this should ideally not
--   be used.
hardline :: Fmt

-- | A line or a space depending on layout.
line :: Fmt
sep :: Fmt -> [Fmt] -> Fmt

-- | Adds brackets.
brackets :: Fmt -> Fmt

-- | Adds braces.
braces :: Fmt -> Fmt

-- | Add parenthesis.
parens :: Fmt -> Fmt

-- | If in a singleline layout then choose a, if in a multiline
--   layout choose b.
(<|>) :: Fmt -> Fmt -> Fmt
infixr 4 <|>

-- | Concatenate with a space between.
(<+>) :: Fmt -> Fmt -> Fmt
infixr 6 <+>

-- | Concatenate with a space if in singleline layout and concatenate by a
--   line in multiline.
(</>) :: Fmt -> Fmt -> Fmt
infixr 6 </>

-- | If in a singleline layout then concatenate with nil and in
--   multiline concatenate by a line.
(<:/>) :: Fmt -> Fmt -> Fmt
infixr 6 <:/>

-- | Indents everything by i, should never be used.
hardIndent :: Int -> Fmt -> Fmt

-- | Indents if in multiline by i if in singleline it does not
--   indent.
indent :: Int -> Fmt -> Fmt

-- | Hard indents with the standard size of two.
hardStdIndent :: Fmt -> Fmt

-- | Idents with the standard size of two.
stdIndent :: Fmt -> Fmt

-- | The format monad used to keep track of comments and layout. It is a a
--   combincation of a reader and state monad. The comments and reading
--   from the input file are the state monads job to deal with. While the
--   reader monad deals with the propagating the current layout.
type FmtM a = ReaderT Layout (State FmtState) a

-- | Retrieves the last comments from the monad and concatenates them
--   together.
popComments :: Fmt

-- | Given a formatter FmtM a, a sequence of comments ordered in
--   increasing order by location, and the original text files content. Run
--   the formatter and create a.
runFormat :: FmtM a -> [Comment] -> Text -> a

-- | Aligns line by line.
align :: Fmt -> Fmt

-- | Using the location of a get the segment of text in the
--   original file to create a Fmt.
fmtCopyLoc :: Located a => AnsiStyle -> a -> Fmt

-- | A comment.
comment :: Text -> Fmt

-- | This is used for function arguments. It seperates multiline arguments
--   by lines and singleline arguments by spaces. We specially handle the
--   case where all the arguments are on a single line except for the last
--   one, which may continue to the next line.
sepArgs :: Located a => (a -> Fmt) -> NonEmpty a -> Fmt

-- | This function determines the Layout of a and updates the
--   monads environment to format in the appropriate style. It determines
--   this by checking if the location of a spans over two or more
--   lines.
localLayout :: Located a => a -> FmtM b -> FmtM b

-- | This function determines the Layout of [a] and if it is
--   singleline then it updates the monads enviroment to format singleline
--   style otherwise format using multiline style. It determines this by
--   checking if the locations of [a] start and end at any
--   different line number.
localLayoutList :: Located a => [a] -> FmtM b -> FmtM b

-- | If in singleline layout seperate by spaces. In a multiline layout
--   seperate by a single line if two neighbouring elements are singleline.
--   Otherwise sepereate by two lines.
sepDecs :: Located a => (a -> Fmt) -> [a] -> Fmt

-- | This function allows to inspect the layout of an expression a
--   and if it is singleline line then use format s and if it is
--   multiline format m.
fmtByLayout :: Located a => a -> Fmt -> Fmt -> Fmt

-- | This function uses the location of a and prepends comments if
--   the comments location is less than the location of a. It
--   format b in accordance with if a is singleline or
--   multiline using localLayout. It currently does not handle
--   trailing comment perfectly. See testsfmttraillingComments*.fut.
addComments :: Located a => a -> Fmt -> Fmt
sepComments :: (a -> Loc) -> (a -> Fmt) -> Fmt -> [a] -> Fmt
sepLineComments :: (a -> Loc) -> (a -> Fmt) -> Fmt -> [a] -> Fmt

-- | Seperates element by a s followed by a space in singleline
--   layout and seperates by a line followed by a s in multine
--   layout.
sepLine :: Fmt -> [Fmt] -> Fmt
commentStyle :: AnsiStyle
constantStyle :: AnsiStyle
keywordStyle :: AnsiStyle
bindingStyle :: AnsiStyle
infixStyle :: AnsiStyle
instance GHC.Classes.Ord Futhark.Fmt.Monad.LastOutput
instance GHC.Classes.Eq Futhark.Fmt.Monad.LastOutput
instance GHC.Show.Show Futhark.Fmt.Monad.LastOutput
instance GHC.Classes.Ord Futhark.Fmt.Monad.FmtState
instance GHC.Classes.Eq Futhark.Fmt.Monad.FmtState
instance GHC.Show.Show Futhark.Fmt.Monad.FmtState
instance GHC.Classes.Eq Futhark.Fmt.Monad.Layout
instance GHC.Show.Show Futhark.Fmt.Monad.Layout
instance GHC.Base.Semigroup Futhark.Fmt.Monad.Fmt
instance GHC.Base.Monoid Futhark.Fmt.Monad.Fmt
instance Data.String.IsString Futhark.Fmt.Monad.Fmt

-- | 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 SyntaxError UncheckedProg

-- | Parse an entire Futhark program from the given Text, using the
--   FilePath as the source name for error messages. Also returns
--   the comments encountered.
parseFutharkWithComments :: FilePath -> Text -> Either SyntaxError (UncheckedProg, [Comment])

-- | Parse an Futhark expression from the given String, using the
--   FilePath as the source name for error messages.
parseExp :: FilePath -> Text -> Either SyntaxError UncheckedExp

-- | Parse a Futhark module expression from the given String, using
--   the FilePath as the source name for error messages.
parseModExp :: FilePath -> Text -> Either SyntaxError (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 SyntaxError UncheckedTypeExp

-- | Parse either an expression or a declaration; favouring declarations in
--   case of ambiguity.
parseDecOrExp :: FilePath -> Text -> Either SyntaxError (Either UncheckedDec UncheckedExp)

-- | A syntax error.
data SyntaxError
SyntaxError :: Loc -> Text -> SyntaxError
[syntaxErrorLoc] :: SyntaxError -> Loc
[syntaxErrorMsg] :: SyntaxError -> Text

-- | A comment consists of its starting and end position, as well as its
--   text. The contents include the comment start marker.
data Comment
Comment :: Loc -> Text -> Comment
[commentLoc] :: Comment -> Loc
[commentText] :: Comment -> Text

-- | Facilities for computing free term variables in various syntactic
--   constructs.
module Language.Futhark.FreeVars

-- | Compute the set of free variables of an expression.
freeInExp :: ExpBase Info VName -> FV

-- | Free variables in pattern (including types of the bound identifiers).
freeInPat :: Pat (TypeBase Size u) -> FV

-- | Free variables in the type (meaning those that are used in size
--   expression).
freeInType :: TypeBase Size u -> FV

-- | Set subtraction. Do not consider those variables as free.
freeWithout :: FV -> Set VName -> FV

-- | A set of names.
data FV

-- | The set of names in an FV.
fvVars :: FV -> Set VName
instance GHC.Show.Show Language.Futhark.FreeVars.FV
instance GHC.Base.Semigroup Language.Futhark.FreeVars.FV
instance GHC.Base.Monoid Language.Futhark.FreeVars.FV

-- | Re-export the external Futhark modules for convenience.
module Language.Futhark

-- | 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
--   working directory of the compiler. In a multi-file program, a file is
--   known by exactly one import name, even if it is referenced relatively
--   by different names by files in different subdirectories.
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 -> ImportName

-- | Create a .fut file corresponding to an ImportName.
includeToFilePath :: ImportName -> FilePath

-- | Produce a human-readable canonicalized string from an
--   ImportName.
includeToString :: ImportName -> String

-- | Produce a human-readable canonicalized text from an ImportName.
includeToText :: ImportName -> Text

-- | The result of type checking some file. Can be passed to further
--   invocations of the type checker.
data FileModule
FileModule :: TySet -> Env -> Prog -> Env -> FileModule

-- | Abstract types.
[fileAbs] :: FileModule -> TySet

-- | The environment made available when importing this module.
[fileEnv] :: FileModule -> Env
[fileProg] :: FileModule -> Prog

-- | The environment at the bottom of the file. Includes local parts.
[fileScope] :: FileModule -> Env

-- | A mapping from import names to imports. The ordering is significant.
type Imports = [(ImportName, 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
[envModTypeTable] :: 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 FunModType
FunModType :: TySet -> Mod -> MTy -> FunModType
[funModTypeAbs] :: FunModType -> TySet
[funModTypeMod] :: FunModType -> Mod
[funModTypeMty] :: FunModType -> 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
[boundValTParams] :: BoundV -> [TypeParam]
[boundValType] :: BoundV -> StructType

-- | Representation of a module, which is either a plain environment, or a
--   parametric module ("functor" in SML).
data Mod
ModEnv :: Env -> Mod
ModFun :: FunModType -> Mod

-- | A binding from a name to its definition as a type. We allow a return
--   type here to support type abbreviations that hide some inner sizes
--   (these must necessarily be Lifted or SizeLifted).
data TypeBinding
TypeAbbr :: Liftedness -> [TypeParam] -> StructRetType -> 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.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.FunModType
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 Prettyprinter.Internal.Pretty Language.Futhark.Semantic.MTy
instance Prettyprinter.Internal.Pretty Language.Futhark.Semantic.Mod
instance Prettyprinter.Internal.Pretty Language.Futhark.Semantic.Env
instance Prettyprinter.Internal.Pretty Language.Futhark.Semantic.Namespace

-- | 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

-- | The value representation used in the interpreter.
--   
--   Kept simple and free of unnecessary operational details (in
--   particular, no references to the interpreter monad).
module Language.Futhark.Interpreter.Values

-- | A shape is a tree to accomodate the case of records. It is
--   parameterised over the representation of dimensions.
data Shape d
ShapeDim :: d -> Shape d -> Shape d
ShapeLeaf :: Shape d
ShapeRecord :: Map Name (Shape d) -> Shape d
ShapeSum :: Map Name [Shape d] -> Shape d

-- | The shape of an array.
type ValueShape = Shape Int64
typeShape :: TypeBase d u -> Shape d
structTypeShape :: StructType -> Shape (Maybe Int64)

-- | A fully evaluated Futhark value.
data Value m
ValuePrim :: !PrimValue -> Value m
ValueArray :: ValueShape -> !Array Int (Value m) -> Value m
ValueRecord :: Map Name (Value m) -> Value m
ValueFun :: (Value m -> m (Value m)) -> Value m
ValueSum :: ValueShape -> Name -> [Value m] -> Value m
ValueAcc :: ValueShape -> (Value m -> Value m -> m (Value m)) -> !Array Int (Value m) -> Value m
ValueAD :: Int -> ADVariable -> Value m
valueShape :: Value m -> ValueShape

-- | Prettyprint value.
prettyValue :: Value m -> Doc a

-- | The value in the textual format.
valueText :: Value m -> Text
valueAccum :: (a -> Value m -> (a, Value m)) -> a -> Value m -> (a, Value m)
valueAccumLM :: Monad f => (a -> Value m -> f (a, Value m)) -> a -> Value m -> f (a, Value m)
fromTuple :: Value m -> Maybe [Value m]
arrayLength :: Integral int => Array Int (Value m) -> int

-- | Does the value correspond to an empty array?
isEmptyArray :: Value m -> 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 m -> Text
toArray :: ValueShape -> [Value m] -> Value m
toArray' :: ValueShape -> [Value m] -> Value m
toTuple :: [Value m] -> Value m

-- | Convert a Futhark value in the externally observable data format to an
--   interpreter value.
fromDataValue :: Value -> Value m
instance Data.Traversable.Traversable Language.Futhark.Interpreter.Values.Shape
instance Data.Foldable.Foldable Language.Futhark.Interpreter.Values.Shape
instance GHC.Base.Functor Language.Futhark.Interpreter.Values.Shape
instance GHC.Show.Show d => GHC.Show.Show (Language.Futhark.Interpreter.Values.Shape d)
instance GHC.Classes.Eq d => GHC.Classes.Eq (Language.Futhark.Interpreter.Values.Shape d)
instance GHC.Show.Show (Language.Futhark.Interpreter.Values.Value m)
instance GHC.Classes.Eq (Language.Futhark.Interpreter.Values.Value m)
instance Prettyprinter.Internal.Pretty d => Prettyprinter.Internal.Pretty (Language.Futhark.Interpreter.Values.Shape d)

-- | 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 ImportName Env -> Ctx
[ctxEnv] :: Ctx -> Env
[ctxImports] :: Ctx -> Map ImportName 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

-- | Prettyprint the error for human consumption.
prettyInterpreterError :: InterpreterError -> Doc AnsiStyle

-- | 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 -> (ImportName, 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 Text (F ExtOp Value)

-- | Produce a context, based on the one passed in, where all of the
--   provided imports have been openened in order.
ctxWithImports :: [Env] -> Ctx -> Ctx
data ExtOp a
ExtOpTrace :: Text -> Doc () -> a -> ExtOp a
ExtOpBreak :: Loc -> 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
type Value = Value EvalM
fromTuple :: Value m -> Maybe [Value m]

-- | Does the value correspond to an empty array?
isEmptyArray :: Value m -> 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 m -> Text

-- | Prettyprint value.
prettyValue :: Value m -> Doc a

-- | The value in the textual format.
valueText :: Value m -> Text
instance GHC.Show.Show Language.Futhark.Interpreter.SizeClosure
instance Control.Monad.State.Class.MonadState Language.Futhark.Interpreter.Exts Language.Futhark.Interpreter.EvalM
instance Control.Monad.Reader.Class.MonadReader (Language.Futhark.Interpreter.Stack, Data.Map.Internal.Map Language.Futhark.Syntax.ImportName 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 GHC.Show.Show Language.Futhark.Interpreter.Env
instance Data.Loc.Located Language.Futhark.Interpreter.StackFrame
instance GHC.Base.Functor Language.Futhark.Interpreter.ExtOp
instance Prettyprinter.Internal.Pretty Language.Futhark.Interpreter.SizeClosure
instance Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.Shape Language.Futhark.Interpreter.SizeClosure)
instance GHC.Show.Show Language.Futhark.Interpreter.TermBinding
instance GHC.Show.Show Language.Futhark.Interpreter.Module
instance GHC.Base.Monoid Language.Futhark.Interpreter.Env
instance GHC.Base.Semigroup Language.Futhark.Interpreter.Env
instance Prettyprinter.Internal.Pretty Language.Futhark.Interpreter.Indexing
instance GHC.Show.Show Language.Futhark.Interpreter.InterpreterError

module Futhark.Internalise.TypesValues
internaliseReturnType :: [Tree (TypeBase Shape Uniqueness)] -> ResRetType -> [TypeBase shape u] -> [(TypeBase ExtShape Uniqueness, RetAls)]
internaliseCoerceType :: StructType -> [TypeBase shape u] -> [TypeBase ExtShape Uniqueness]
internaliseLambdaReturnType :: ResType -> [TypeBase shape u] -> InternaliseM [TypeBase Shape NoUniqueness]

-- | As internaliseReturnType, but returns components of a top-level
--   tuple type piecemeal.
internaliseEntryReturnType :: [Tree (TypeBase Shape Uniqueness)] -> ResRetType -> [[(TypeBase ExtShape Uniqueness, RetAls)]]
internaliseType :: TypeBase Size NoUniqueness -> [Tree (TypeBase ExtShape Uniqueness)]
internaliseParamTypes :: [ParamType] -> InternaliseM [[Tree (TypeBase Shape Uniqueness)]]
internaliseLoopParamType :: ParamType -> [TypeBase shape u] -> 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 Size als -> Int
internaliseSumTypeRep :: Map Name [StructType] -> ([TypeBase ExtShape Uniqueness], [(Name, [Int])])
internaliseSumType :: Map Name [StructType] -> InternaliseM ([TypeBase ExtShape Uniqueness], [(Name, [Int])])

-- | A tree is just an instantiation of the free monad with a list monad.
--   
--   The important thing is that we use it to represent the original
--   structure of arrayss, as this matters for aliasing. Each Free
--   constructor corresponds to an array dimension. Only non-arrays have a
--   Pure at the top level. See Note [Alias Inference].
type Tree = Free []

-- | Convert an external primitive value to an internal primitive value.
internalisePrimValue :: PrimValue -> PrimValue
inferAliases :: [Tree (TypeBase Shape Uniqueness)] -> [Tree (TypeBase ExtShape Uniqueness)] -> [[(TypeBase ExtShape Uniqueness, RetAls)]]

-- | Only exposed for testing purposes.
internaliseConstructors :: Map Name [Tree (TypeBase ExtShape Uniqueness)] -> ([Tree (TypeBase ExtShape Uniqueness)], [(Name, [Int])])
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

-- | Converts identifiers of record type into record patterns (and
--   similarly for tuples). This is to ensure that the closures produced in
--   lambda lifting and defunctionalisation do not carry around huge
--   records of which only a tiny part is needed.
module Futhark.Internalise.ReplaceRecords

-- | 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 => [ValBind] -> m [ValBind]
instance Control.Monad.State.Class.MonadState Futhark.Internalise.ReplaceRecords.S Futhark.Internalise.ReplaceRecords.RecordM
instance Control.Monad.Reader.Class.MonadReader Futhark.Internalise.ReplaceRecords.Env Futhark.Internalise.ReplaceRecords.RecordM
instance GHC.Base.Monad Futhark.Internalise.ReplaceRecords.RecordM
instance GHC.Base.Applicative Futhark.Internalise.ReplaceRecords.RecordM
instance GHC.Base.Functor Futhark.Internalise.ReplaceRecords.RecordM
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Internalise.ReplaceRecords.RecordM

-- | Lambda-lifting of typed, monomorphic Futhark programs without modules.
--   After this pass, the program will no longer contain any LetFuns
--   or Lambdas.
module Futhark.Internalise.LiftLambdas

-- | Perform the transformation.
transformProg :: MonadFreshNames m => [ValBind] -> m [ValBind]
instance Control.Monad.State.Class.MonadState Futhark.Internalise.LiftLambdas.LiftState Futhark.Internalise.LiftLambdas.LiftM
instance Control.Monad.Reader.Class.MonadReader Futhark.Internalise.LiftLambdas.Env Futhark.Internalise.LiftLambdas.LiftM
instance GHC.Base.Monad Futhark.Internalise.LiftLambdas.LiftM
instance GHC.Base.Applicative Futhark.Internalise.LiftLambdas.LiftM
instance GHC.Base.Functor Futhark.Internalise.LiftLambdas.LiftM
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Internalise.LiftLambdas.LiftM

module Futhark.Internalise.Lambdas

-- | A function for internalising lambdas.
type InternaliseLambda = Exp -> [Type] -> InternaliseM ([LParam SOACS], Body SOACS, [Type])
internaliseFoldLambda :: InternaliseLambda -> Exp -> [Type] -> [Type] -> InternaliseM (Lambda SOACS)
internalisePartitionLambda :: InternaliseLambda -> Int -> Exp -> [SubExp] -> InternaliseM (Lambda SOACS)

-- | Generating metadata so that programs can run at all.
module Futhark.Internalise.Entry
entryPoint :: VisibleTypes -> Name -> [(EntryParam, [Param DeclType])] -> (EntryType, [[TypeBase Rank Uniqueness]]) -> (EntryPoint, OpaqueTypes)

-- | The types that are visible to the outside world.
data VisibleTypes

-- | Retrieve those type bindings that should be visible to the outside
--   world. Currently that is everything at top level that does not have
--   type parameters.
visibleTypes :: Imports -> VisibleTypes

-- | 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.Prop.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

-- | Internalising bindings.
module Futhark.Internalise.Bindings
internaliseAttrs :: [AttrInfo VName] -> InternaliseM Attrs
internaliseAttr :: AttrInfo VName -> InternaliseM Attr
bindingFParams :: [TypeParam] -> [Pat ParamType] -> ([FParam SOACS] -> [[Tree (FParam SOACS)]] -> InternaliseM a) -> InternaliseM a
bindingLoopParams :: [TypeParam] -> Pat ParamType -> [Type] -> ([FParam SOACS] -> [FParam SOACS] -> InternaliseM a) -> InternaliseM a
bindingLambdaParams :: [Pat ParamType] -> [Type] -> ([LParam SOACS] -> InternaliseM a) -> InternaliseM a
stmPat :: Pat ParamType -> [Type] -> ([VName] -> InternaliseM a) -> InternaliseM a

module Futhark.Fmt.Printer

-- | Given a filename and a futhark program, formats the program as text.
fmtToText :: String -> Text -> Either SyntaxError Text

-- | Given a filename and a futhark program, formats the program.
fmtToDoc :: String -> Text -> Either SyntaxError (Doc AnsiStyle)
instance Futhark.Fmt.Printer.Format Language.Futhark.Syntax.DocComment
instance Futhark.Fmt.Printer.Format (GHC.Maybe.Maybe Language.Futhark.Syntax.DocComment)
instance Futhark.Fmt.Printer.Format Language.Futhark.Core.Name
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedTypeExp
instance Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.TypeArgExp Language.Futhark.Prop.UncheckedExp Language.Futhark.Core.Name)
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedTypeBind
instance forall k (a :: k). Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.AttrAtom a)
instance forall k (a :: k). Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.AttrInfo a)
instance Futhark.Fmt.Printer.Format Language.Futhark.Syntax.Liftedness
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedTypeParam
instance Futhark.Fmt.Printer.Format (Language.Futhark.Prop.UncheckedPat t)
instance Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.FieldBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedDimIndex
instance Futhark.Fmt.Printer.Format Language.Futhark.Syntax.PrimValue
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedExp
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedCase
instance Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.AppExpBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.SizeBinder Language.Futhark.Core.Name)
instance forall k (t :: k). Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.IdentBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name t)
instance Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.LoopFormBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedValBind
instance Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.SizeExp Language.Futhark.Prop.UncheckedExp)
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedSpec
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedModTypeExp
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedModTypeBind
instance Futhark.Fmt.Printer.Format (Language.Futhark.Syntax.ModParamBase Language.Futhark.Syntax.NoInfo Language.Futhark.Core.Name)
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedModBind
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedModExp
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedDec
instance Futhark.Fmt.Printer.Format Language.Futhark.Prop.UncheckedProg

-- | FutharkScript is a (tiny) subset of Futhark used to write small
--   expressions that are evaluated by server executables. The futhark
--   literate command is the main user.
module Futhark.Script

-- | Like a Server, but keeps a bit more state to make FutharkScript
--   more convenient.
data ScriptServer

-- | Start a server, execute an action, then shut down the server. Similar
--   to withServer.
withScriptServer :: ServerCfg -> (ScriptServer -> IO a) -> IO a

-- | Run an action with a ScriptServer produced by an existing
--   Server, without shutting it down at the end.
withScriptServer' :: MonadIO m => Server -> (ScriptServer -> m a) -> m a

-- | A function called in a Call expression can be either a Futhark
--   function or a builtin function.
data Func
FuncFut :: EntryName -> Func
FuncBuiltin :: Text -> Func

-- | A FutharkScript expression. This is a simple AST that might not
--   correspond exactly to what the user wrote (e.g. no parentheses or
--   source locations). This is fine for small expressions, which is all
--   this is meant for.
data Exp
Call :: Func -> [Exp] -> Exp
Const :: Value -> Exp
Tuple :: [Exp] -> Exp
Record :: [(Text, Exp)] -> Exp
StringLit :: Text -> Exp
Let :: [VarName] -> Exp -> Exp -> Exp

-- | Server-side variable, *not* Futhark variable (these are handled in
--   Call).
ServerVar :: TypeName -> VarName -> Exp

-- | Parse a FutharkScript expression, given a whitespace parser.
parseExp :: Parsec Void Text () -> Parsec Void Text Exp

-- | Parse a FutharkScript expression with normal whitespace handling.
parseExpFromText :: FilePath -> Text -> Either Text Exp

-- | The set of Futhark variables that are referenced by the expression -
--   these will have to be entry points in the Futhark program.
varsInExp :: Exp -> Set EntryName

-- | The type of a ScriptValue - either a value type or a function
--   type.
data ScriptValueType
STValue :: TypeName -> ScriptValueType

-- | Ins, then outs.
STFun :: [TypeName] -> [TypeName] -> ScriptValueType

-- | A ScriptValue is either a base value or a partially applied function.
--   We don't have real first-class functions in FutharkScript, but we sort
--   of have closures.
data ScriptValue v
SValue :: TypeName -> v -> ScriptValue v

-- | Ins, then outs. Yes, this is the opposite of more or less everywhere
--   else.
SFun :: EntryName -> [TypeName] -> [TypeName] -> [ScriptValue v] -> ScriptValue v

-- | The type of a ScriptValue.
scriptValueType :: ScriptValue v -> ScriptValueType

-- | The set of server-side variables in the value.
serverVarsInValue :: ExpValue -> Set VarName

-- | A Haskell-level value or a variable on the server.
data ValOrVar
VVal :: Value -> ValOrVar
VVar :: VarName -> ValOrVar

-- | The intermediate values produced by an expression - in particular,
--   these may not be on the server.
type ExpValue = Compound (ScriptValue ValOrVar)

-- | How to evaluate a builtin function.
type EvalBuiltin m = Text -> [CompoundValue] -> m CompoundValue

-- | Handles the following builtin functions: loaddata,
--   loadbytes. Fails for everything else. The FilePath
--   indicates the directory that files should be read relative to.
scriptBuiltin :: (MonadIO m, MonadError Text m) => FilePath -> EvalBuiltin m

-- | Evaluate a FutharkScript expression relative to some running server.
evalExp :: forall m. (MonadError Text m, MonadIO m) => EvalBuiltin m -> ScriptServer -> Exp -> m ExpValue

-- | Read actual values from the server. Fails for values that have no
--   well-defined external representation.
getExpValue :: (MonadError Text m, MonadIO m) => ScriptServer -> ExpValue -> m CompoundValue

-- | Like evalExp, but requires all values to be non-functional. If
--   the value has a bad type, return that type instead. Other evaluation
--   problems (e.g. type failures) raise errors.
evalExpToGround :: (MonadError Text m, MonadIO m) => EvalBuiltin m -> ScriptServer -> Exp -> m (Either (Compound ScriptValueType) CompoundValue)

-- | Convert a value into a corresponding expression.
valueToExp :: ExpValue -> Exp

-- | Release all the server-side variables in the value. Yes, FutharkScript
--   has manual memory management...
freeValue :: (MonadError Text m, MonadIO m) => ScriptServer -> ExpValue -> m ()
instance GHC.Show.Show Futhark.Script.Func
instance GHC.Show.Show Futhark.Script.Exp
instance GHC.Show.Show v => GHC.Show.Show (Futhark.Script.ScriptValue v)
instance GHC.Show.Show Futhark.Script.ScriptValueType
instance GHC.Classes.Eq Futhark.Script.ScriptValueType
instance GHC.Show.Show Futhark.Script.ValOrVar
instance Prettyprinter.Internal.Pretty Futhark.Script.ScriptValueType
instance GHC.Base.Functor Futhark.Script.ScriptValue
instance Data.Foldable.Foldable Futhark.Script.ScriptValue
instance Data.Traversable.Traversable Futhark.Script.ScriptValue
instance Prettyprinter.Internal.Pretty Futhark.Script.Exp
instance Prettyprinter.Internal.Pretty Futhark.Script.Func

-- | Definition and parsing of a test specification.
module Futhark.Test.Spec

-- | Read the test specification from the given Futhark program.
testSpecFromProgram :: FilePath -> IO (Either String ProgramTest)

-- | Like testSpecFromProgram, but exits the process on error.
testSpecFromProgramOrDie :: 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)]

-- | Read a test specification from a file. Expects only a single block,
--   and no comment prefixes.
testSpecFromFile :: FilePath -> IO (Either String ProgramTest)

-- | Like testSpecFromFile, but kills the process on errors.
testSpecFromFileOrDie :: FilePath -> IO ProgramTest

-- | 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
GpuPipeline :: StructurePipeline
MCPipeline :: StructurePipeline
SOACSPipeline :: StructurePipeline
SeqMemPipeline :: StructurePipeline
GpuMemPipeline :: StructurePipeline
MCMemPipeline :: StructurePipeline
NoPipeline :: 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 :: [Text] -> Values -> ExpectedResult Success -> Int -> Text -> TestRun
[runTags] :: TestRun -> [Text]
[runInput] :: TestRun -> Values
[runExpectedResult] :: TestRun -> ExpectedResult Success
[runIndex] :: TestRun -> Int
[runDescription] :: TestRun -> Text

-- | 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. All paths are relative to test program.
data Values
Values :: [Value] -> Values
InFile :: FilePath -> Values
GenValues :: [GenValue] -> Values
ScriptValues :: Exp -> Values
ScriptFile :: FilePath -> Values

-- | How to generate a single random value.
data GenValue

-- | Generate a value of the given rank and primitive type. Scalars are
--   considered 0-ary arrays.
GenValue :: ValueType -> GenValue

-- | A fixed non-randomised primitive value.
GenPrim :: Value -> GenValue

-- | A prettyprinted representation of type of value produced by a
--   GenValue.
genValueType :: GenValue -> Text
instance GHC.Show.Show Futhark.Test.Spec.StructurePipeline
instance GHC.Show.Show Futhark.Test.Spec.StructureTest
instance GHC.Show.Show Futhark.Test.Spec.GenValue
instance GHC.Show.Show Futhark.Test.Spec.Values
instance GHC.Show.Show values => GHC.Show.Show (Futhark.Test.Spec.ExpectedResult values)
instance GHC.Show.Show Futhark.Test.Spec.Success
instance GHC.Show.Show Futhark.Test.Spec.TestRun
instance GHC.Show.Show Futhark.Test.Spec.InputOutputs
instance GHC.Show.Show Futhark.Test.Spec.TestAction
instance GHC.Show.Show Futhark.Test.Spec.ProgramTest
instance GHC.Show.Show Futhark.Test.Spec.WarningTest
instance GHC.Show.Show Futhark.Test.Spec.ExpectedError

-- | 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

-- | 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 text 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 :: (MonadFail m, MonadIO m) => FutharkExe -> FilePath -> Values -> m ByteString

-- | Make the provided Values available as server-side variables.
--   This may involve arbitrary server-side computation. Error detection...
--   dubious.
valuesAsVars :: (MonadError Text m, MonadIO m) => Server -> [(VarName, TypeName)] -> FutharkExe -> FilePath -> Values -> m ()

-- | Compare two Futhark values for equality.
compareValues :: Tolerance -> Value -> Value -> [Mismatch]

-- | Check that the result is as expected, and write files and throw an
--   error if not.
checkResult :: (MonadError Text m, MonadIO m) => FilePath -> [Value] -> [Value] -> m ()

-- | 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)

-- | Read the given variables from a running server.
readResults :: (MonadIO m, MonadError Text m) => Server -> [VarName] -> m [Value]

-- | 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)

-- | Determine the --cache-file options to pass to the program.
--   The first argument is the extension of the cache file, or
--   Nothing if none should be used.
determineCache :: Maybe FilePath -> FilePath -> [String]

-- | The name we use for compiled programs.
binaryName :: FilePath -> FilePath

-- | Create a Futhark server configuration suitable for use when
--   testing/benchmarking Futhark programs.
futharkServerCfg :: FilePath -> [String] -> ServerCfg

-- | Two values differ in some way. The Show instance produces a
--   human-readable explanation.
data () => Mismatch

-- | An efficiently represented Futhark value, represented as a shape
--   vector and a value vector, which contains elements in row-major order.
--   The size of the value vector must be equal to the product of the shape
--   vector. This is not enforced by the representation, but consuming
--   functions may give unexpected results if this invariant is broken.
--   Scalars are represented with an empty shape vector.
--   
--   Use valueText to get a human-readable representation, and
--   put to obtain binary a representation.
--   
--   The Eq instance is the naive one, meaning that no values
--   containing NaNs will be considered equal. Use the functions from
--   Futhark.Data.Compare if this is not what you want.
data () => Value

-- | Construct a textual representation of the value as a strict text.
valueText :: Value -> Text
instance GHC.Show.Show Futhark.Test.FutharkExe
instance GHC.Classes.Ord Futhark.Test.FutharkExe
instance GHC.Classes.Eq Futhark.Test.FutharkExe

-- | 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
--   a result.
data DataResult
DataResult :: Text -> Either Text Result -> DataResult

-- | The results for all datasets for some benchmark program.
data BenchResult
BenchResult :: FilePath -> [DataResult] -> BenchResult
[benchResultProg] :: BenchResult -> FilePath
[benchResultResults] :: BenchResult -> [DataResult]

-- | The measurements resulting from various successful runs of a benchmark
--   (same dataset).
data Result
Result :: [RunResult] -> Map Text Int -> Maybe Text -> Maybe ProfilingReport -> Result

-- | Runtime of every run.
[runResults] :: Result -> [RunResult]

-- | Memory usage.
[memoryMap] :: Result -> Map Text Int

-- | The error output produced during execution. Often Nothing for
--   space reasons, and otherwise only the output from the last run.
[stdErr] :: Result -> Maybe Text

-- | Profiling report. This will have been measured based on the last run.
[report] :: Result -> Maybe ProfilingReport

-- | 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 :: Server -> RunOptions -> FutharkExe -> FilePath -> Text -> Values -> Maybe Success -> FilePath -> IO (Either Text ([RunResult], Text, ProfilingReport))

-- | How to run a benchmark.
data RunOptions
RunOptions :: Int -> NominalDiffTime -> Int -> Int -> Bool -> NominalDiffTime -> ((Int, Maybe Double) -> IO ()) -> Bool -> RunOptions

-- | Applies both to initial and convergence phase.
[runMinRuns] :: RunOptions -> Int
[runMinTime] :: RunOptions -> NominalDiffTime
[runTimeout] :: RunOptions -> Int
[runVerbose] :: RunOptions -> Int

-- | If true, run the convergence phase.
[runConvergencePhase] :: RunOptions -> Bool

-- | Stop convergence once this much time has passed.
[runConvergenceMaxTime] :: RunOptions -> NominalDiffTime

-- | Invoked for every runtime measured during the run. Can be used to
--   provide a progress bar.
[runResultAction] :: RunOptions -> (Int, Maybe Double) -> IO ()

-- | Perform a final run at the end with profiling information enabled.
[runProfile] :: RunOptions -> Bool

-- | 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.Result
instance GHC.Classes.Eq Futhark.Bench.Result
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.Result
instance Data.Aeson.Types.FromJSON.FromJSON Futhark.Bench.Result
instance Data.Aeson.Types.ToJSON.ToJSON Futhark.Bench.RunResult
instance Data.Aeson.Types.FromJSON.FromJSON Futhark.Bench.RunResult

-- | 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

-- | Find the unmatched cases.
unmatched :: [Pat StructType] -> [Match ()]

-- | A representation of the essentials of a pattern.
data Match t
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 t => GHC.Show.Show (Language.Futhark.TypeChecker.Match.Match t)
instance GHC.Classes.Ord t => GHC.Classes.Ord (Language.Futhark.TypeChecker.Match.Match t)
instance GHC.Classes.Eq t => GHC.Classes.Eq (Language.Futhark.TypeChecker.Match.Match t)
instance Prettyprinter.Internal.Pretty (Language.Futhark.TypeChecker.Match.Match t)

-- | A very simple representation of collections of warnings. Warnings have
--   a position (so they can be ordered), and their Pretty-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 :: Loc -> Doc () -> Warnings

-- | A single warning at the given location, but also with a stack trace
--   (sort of) to the location.
singleWarning' :: Loc -> [Loc] -> Doc () -> Warnings

-- | Exports Warnings into a list of (location, problem).
listWarnings :: Warnings -> [(Loc, Doc ())]

-- | Prettyprint warnings, making use of colours and such.
prettyWarnings :: Warnings -> Doc AnsiStyle
instance GHC.Base.Semigroup Language.Futhark.Warnings.Warnings
instance GHC.Base.Monoid Language.Futhark.Warnings.Warnings

module Futhark.CodeGen.ImpGen
compileProg :: (Mem rep inner, FreeIn op, MonadFreshNames m) => r -> Operations rep r op -> Space -> Prog rep -> m (Warnings, Definitions op)

-- | How to compile an Op.
type OpCompiler rep r op = Pat (LetDec rep) -> Op rep -> ImpM rep r op ()

-- | How to compile an Exp.
type ExpCompiler rep r op = Pat (LetDec rep) -> Exp rep -> ImpM rep r op ()
type CopyCompiler rep r op = PrimType -> MemLoc -> MemLoc -> ImpM rep r op ()

-- | How to compile some Stms.
type StmsCompiler rep r op = Names -> Stms rep -> ImpM rep r op () -> ImpM rep r op ()

-- | An alternate way of compiling an allocation.
type AllocCompiler rep r op = VName -> Count Bytes (TExp Int64) -> ImpM rep r op ()
data Operations rep r op
Operations :: ExpCompiler rep r op -> OpCompiler rep r op -> StmsCompiler rep r op -> CopyCompiler rep r op -> Map Space (AllocCompiler rep r op) -> Operations rep r op
[opsExpCompiler] :: Operations rep r op -> ExpCompiler rep r op
[opsOpCompiler] :: Operations rep r op -> OpCompiler rep r op
[opsStmsCompiler] :: Operations rep r op -> StmsCompiler rep r op
[opsCopyCompiler] :: Operations rep r op -> CopyCompiler rep r op
[opsAllocCompilers] :: Operations rep r op -> Map Space (AllocCompiler rep r op)

-- | An operations set for which the expression compiler always returns
--   defCompileExp.
defaultOperations :: (Mem rep inner, FreeIn op) => OpCompiler rep r op -> Operations rep r op

-- | When an array is declared, this is where it is stored.
data MemLoc
MemLoc :: VName -> [DimSize] -> LMAD (TExp Int64) -> MemLoc
[memLocName] :: MemLoc -> VName
[memLocShape] :: MemLoc -> [DimSize]
[memLocLMAD] :: MemLoc -> LMAD (TExp Int64)
sliceMemLoc :: MemLoc -> Slice (TExp Int64) -> MemLoc
newtype MemEntry
MemEntry :: Space -> MemEntry
[entryMemSpace] :: MemEntry -> Space
newtype ScalarEntry
ScalarEntry :: PrimType -> ScalarEntry
[entryScalarType] :: ScalarEntry -> PrimType
data ImpM rep r op a
localDefaultSpace :: Space -> ImpM rep r op a -> ImpM rep r op a
askFunction :: ImpM rep r op (Maybe Name)

-- | Generate a VName, prefixed with askFunction if it
--   exists.
newVNameForFun :: String -> ImpM rep r op VName

-- | Generate a Name, prefixed with askFunction if it exists.
nameForFun :: String -> ImpM rep r op Name
askEnv :: ImpM rep r op r
localEnv :: (r -> r) -> ImpM rep r op a -> ImpM rep r op a
localOps :: Operations rep r op -> ImpM rep r op a -> ImpM rep r op a

-- | The symbol table used during compilation.
type VTable rep = Map VName (VarEntry rep)

-- | Get the current symbol table.
getVTable :: ImpM rep r op (VTable rep)

-- | Run an action with a modified symbol table. All changes to the symbol
--   table will be reverted once the action is done!
localVTable :: (VTable rep -> VTable rep) -> ImpM rep r op a -> ImpM rep r op a
subImpM :: r' -> Operations rep r' op' -> ImpM rep r' op' a -> ImpM rep r op (a, Code op')
subImpM_ :: r' -> Operations rep r' op' -> ImpM rep r' op' a -> ImpM rep r op (Code op')

-- | Emit some generated imperative code.
emit :: Code op -> ImpM rep r op ()

-- | Emit a function in the generated code.
emitFunction :: Name -> Function op -> ImpM rep r op ()

-- | Check if a function of a given name exists.
hasFunction :: Name -> ImpM rep r op Bool

-- | Execute a code generation action, returning the code that was emitted.
collect :: ImpM rep r op () -> ImpM rep r op (Code op)
collect' :: ImpM rep r op a -> ImpM rep r op (a, Code op)

-- | Every non-scalar variable must be associated with an entry.
data VarEntry rep
ArrayVar :: Maybe (Exp rep) -> ArrayEntry -> VarEntry rep
ScalarVar :: Maybe (Exp rep) -> ScalarEntry -> VarEntry rep
MemVar :: Maybe (Exp rep) -> MemEntry -> VarEntry rep
AccVar :: Maybe (Exp rep) -> (VName, Shape, [Type]) -> VarEntry rep
data ArrayEntry
ArrayEntry :: MemLoc -> PrimType -> ArrayEntry
[entryArrayLoc] :: ArrayEntry -> MemLoc
[entryArrayElemType] :: ArrayEntry -> PrimType
lookupVar :: VName -> ImpM rep r op (VarEntry rep)
lookupArray :: VName -> ImpM rep r op ArrayEntry

-- | In which memory space is this array allocated?
lookupArraySpace :: VName -> ImpM rep r op Space
lookupMemory :: VName -> ImpM rep r op MemEntry

-- | In the case of a histogram-like accumulator, also sets the index
--   parameters.
lookupAcc :: VName -> [TExp Int64] -> ImpM rep r op (VName, Space, [VName], [TExp Int64], Maybe (Lambda rep))

-- | The active attributes, including those for the statement currently
--   being compiled.
askAttrs :: ImpM rep r op Attrs

-- | 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

-- | A type class that helps ensuring that the type annotation in a
--   TV is correct.
class MkTV t

-- | Create a typed variable from a name and a dynamic type.
mkTV :: MkTV t => VName -> TV t

-- | Extract type from a TV.
tvType :: MkTV t => TV t -> PrimType

-- | 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 (which must still be a
--   primitive) is deduced monadically.
toExp :: ToExp a => a -> ImpM rep r op Exp

-- | Compile where we know the type in advance.
toExp' :: ToExp a => PrimType -> a -> Exp

-- | compileAlloc pat size space allocates n bytes of
--   memory in space, writing the result to pat, which
--   must contain a single memory-typed element.
compileAlloc :: Mem rep inner => Pat (LetDec rep) -> SubExp -> Space -> ImpM rep r op ()
everythingVolatile :: ImpM rep r op a -> ImpM rep r op a
compileBody :: Pat (LetDec rep) -> Body rep -> ImpM rep r op ()
compileBody' :: [Param dec] -> Body rep -> ImpM rep r op ()
compileLoopBody :: Typed dec => [Param dec] -> Body rep -> ImpM rep r op ()
defCompileStms :: (Mem rep inner, FreeIn op) => Names -> Stms rep -> ImpM rep r op () -> ImpM rep r op ()
compileStms :: Names -> Stms rep -> ImpM rep r op () -> ImpM rep r op ()
compileExp :: Pat (LetDec rep) -> Exp rep -> ImpM rep r op ()
defCompileExp :: Mem rep inner => Pat (LetDec rep) -> Exp rep -> ImpM rep r op ()
fullyIndexArray :: VName -> [TExp Int64] -> ImpM rep r op (VName, Space, Count Elements (TExp Int64))
fullyIndexArray' :: MemLoc -> [TExp Int64] -> ImpM rep r op (VName, Space, Count Elements (TExp Int64))
copy :: CopyCompiler rep 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 rep r op ()

-- | As copyDWIM, but implicitly DimFixes the indexes.
copyDWIMFix :: VName -> [TExp Int64] -> SubExp -> [TExp Int64] -> ImpM rep r op ()
lmadCopy :: CopyCompiler rep 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 indexing in-bounds for an array of the given shape? This is
--   useful for things like scatter, which ignores out-of-bounds writes.
inBounds :: Slice (TExp Int64) -> [TExp Int64] -> TExp Bool

-- | Generate an expression that is true if the subexpressions match the
--   case pasttern.
caseMatch :: [SubExp] -> [Maybe PrimValue] -> TExp Bool

-- | Produce a fresh VName, using the given base name as a template.
newVName :: MonadFreshNames m => String -> m VName
dLParams :: Mem rep inner => [LParam rep] -> ImpM rep r op ()
dFParams :: Mem rep inner => [FParam rep] -> ImpM rep r op ()

-- | Another hack.
addLoopVar :: VName -> IntType -> ImpM rep r op ()
dScope :: Mem rep inner => Maybe (Exp rep) -> Scope rep -> ImpM rep r op ()
dArray :: VName -> PrimType -> ShapeBase SubExp -> VName -> LMAD -> ImpM rep r op ()

-- | Create TV of some fixed type.
dPrim :: MkTV t => String -> ImpM rep r op (TV t)

-- | Create variable of some provided dynamic type. You'll need this when
--   you are compiling program code of Haskell-level unknown type. For
--   other things, use other functions.
dPrimS :: String -> PrimType -> ImpM rep r op VName

-- | Create TV of some provided dynamic type. No guarantee that the
--   dynamic type matches the inferred type.
dPrimSV :: String -> PrimType -> ImpM rep r op (TV t)
dPrimVol :: String -> PrimType -> TExp t -> ImpM rep r op (TV t)
dPrim_ :: VName -> PrimType -> ImpM rep r op ()
dPrimV_ :: VName -> TExp t -> ImpM rep r op ()
dPrimV :: String -> TExp t -> ImpM rep r op (TV t)
dPrimVE :: String -> TExp t -> ImpM rep r op (TExp t)

-- | dIndexSpace f 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. Intermediate
--   results are passed to f.
dIndexSpace :: [(VName, TExp Int64)] -> TExp Int64 -> ImpM rep r op ()

-- | Like dIndexSpace, but invent some new names for the indexes
--   based on the given template.
dIndexSpace' :: String -> [TExp Int64] -> TExp Int64 -> ImpM rep r op [TExp Int64]
sFor :: String -> TExp t -> (TExp t -> ImpM rep r op ()) -> ImpM rep r op ()
sWhile :: TExp Bool -> ImpM rep r op () -> ImpM rep r op ()

-- | Execute a code generation action, wrapping the generated code within a
--   Comment with the given description.
sComment :: Text -> ImpM rep r op () -> ImpM rep r op ()
sIf :: TExp Bool -> ImpM rep r op () -> ImpM rep r op () -> ImpM rep r op ()
sWhen :: TExp Bool -> ImpM rep r op () -> ImpM rep r op ()
sUnless :: TExp Bool -> ImpM rep r op () -> ImpM rep r op ()
sOp :: op -> ImpM rep r op ()
sDeclareMem :: String -> Space -> ImpM rep r op VName
sAlloc :: String -> Count Bytes (TExp Int64) -> Space -> ImpM rep r op VName
sAlloc_ :: VName -> Count Bytes (TExp Int64) -> Space -> ImpM rep r op ()
sArray :: String -> PrimType -> ShapeBase SubExp -> VName -> LMAD -> ImpM rep r op VName

-- | Declare an array in row-major order in the given memory block.
sArrayInMem :: String -> PrimType -> ShapeBase SubExp -> VName -> ImpM rep r op VName

-- | Uses linear/iota index function.
sAllocArray :: String -> PrimType -> ShapeBase SubExp -> Space -> ImpM rep r op VName

-- | Like sAllocArray, but permute the in-memory representation of
--   the indices as specified.
sAllocArrayPerm :: String -> PrimType -> ShapeBase SubExp -> Space -> [Int] -> ImpM rep r op VName

-- | Uses linear/iota index function.
sStaticArray :: String -> PrimType -> ArrayContents -> ImpM rep r op VName
sWrite :: VName -> [TExp Int64] -> Exp -> ImpM rep r op ()
sUpdate :: VName -> Slice (TExp Int64) -> SubExp -> ImpM rep r op ()
sLoopNest :: Shape -> ([TExp Int64] -> ImpM rep r op ()) -> ImpM rep r op ()

-- | Create a sequential For loop covering a space of the given
--   shape. The function is calling with the indexes for a given iteration.
sLoopSpace :: [TExp t] -> ([TExp t] -> ImpM rep r op ()) -> ImpM rep r op ()

-- | Typed assignment.
(<--) :: TV t -> TExp t -> ImpM rep r op ()
infixl 3 <--

-- | Untyped assignment.
(<~~) :: VName -> Exp -> ImpM rep 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 rep r op () -> ImpM rep r op ()

-- | Generate constants that get put outside of all functions. Will be
--   executed at program startup. Action must return the names that should
--   should be made available. This one has real sharp edges. Do not use
--   inside subImpM. Do not use any variable from the context.
genConstants :: ImpM rep r op (Names, a) -> ImpM rep r op a

-- | Emit a warning about something the user should be aware of.
warn :: Located loc => loc -> [loc] -> Text -> ImpM rep r op ()
instance GHC.Show.Show Futhark.CodeGen.ImpGen.MemLoc
instance GHC.Classes.Eq Futhark.CodeGen.ImpGen.MemLoc
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.Rep.RepTypes rep => GHC.Show.Show (Futhark.CodeGen.ImpGen.VarEntry rep)
instance GHC.Show.Show Futhark.CodeGen.ImpGen.ValueDestination
instance Control.Monad.Reader.Class.MonadReader (Futhark.CodeGen.ImpGen.Env rep r op) (Futhark.CodeGen.ImpGen.ImpM rep r op)
instance Control.Monad.State.Class.MonadState (Futhark.CodeGen.ImpGen.ImpState rep r op) (Futhark.CodeGen.ImpGen.ImpM rep r op)
instance GHC.Base.Monad (Futhark.CodeGen.ImpGen.ImpM rep r op)
instance GHC.Base.Applicative (Futhark.CodeGen.ImpGen.ImpM rep r op)
instance GHC.Base.Functor (Futhark.CodeGen.ImpGen.ImpM rep r op)
instance Futhark.CodeGen.ImpGen.ToExp Futhark.IR.Syntax.Core.SubExp
instance Futhark.CodeGen.ImpGen.ToExp Language.Futhark.Core.VName
instance Futhark.CodeGen.ImpGen.ToExp (Futhark.Analysis.PrimExp.PrimExp Language.Futhark.Core.VName)
instance Futhark.CodeGen.ImpGen.MkTV GHC.Types.Bool
instance Futhark.CodeGen.ImpGen.MkTV GHC.Int.Int8
instance Futhark.CodeGen.ImpGen.MkTV GHC.Int.Int16
instance Futhark.CodeGen.ImpGen.MkTV GHC.Int.Int32
instance Futhark.CodeGen.ImpGen.MkTV GHC.Int.Int64
instance Futhark.CodeGen.ImpGen.MkTV Numeric.Half.Internal.Half
instance Futhark.CodeGen.ImpGen.MkTV GHC.Types.Float
instance Futhark.CodeGen.ImpGen.MkTV GHC.Types.Double
instance Futhark.MonadFreshNames.MonadFreshNames (Futhark.CodeGen.ImpGen.ImpM rep r op)
instance Futhark.IR.Prop.Scope.HasScope Futhark.IR.SOACS.SOACS (Futhark.CodeGen.ImpGen.ImpM rep 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

-- | C code generator. This module can convert a correct ImpCode program to
--   an equivalent C program. This C program is expected to be converted to
--   WebAssembly, so we also produce the intended JavaScript wrapper.
module Futhark.CodeGen.Backends.SequentialWASM

-- | Compile Futhark program to wasm program (some assembly required).
--   
--   The triple that is returned consists of
--   
--   
--   
- Generated C code (to be passed to Emscripten).
--   
- JavaScript wrapper code that presents a nicer interface to the
--   Emscripten-produced code (this should be put in a .class.js
--   file by itself).
--   
- Options that should be passed to emcc.
--   
compileProg :: MonadFreshNames m => Text -> Prog SeqMem -> m (Warnings, (CParts, Text, [String]))

-- | Javascript code that can be appended to the generated module to run a
--   Futhark server instance on startup.
runServer :: Text

-- | The names exported by the generated module.
libraryExports :: Text

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text

-- | Code generation for sequential Python.
module Futhark.CodeGen.Backends.SequentialPython

-- | Compile the program to Python.
compileProg :: MonadFreshNames m => CompilerMode -> String -> Prog SeqMem -> m (Warnings, Text)

-- | 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 => Text -> Prog SeqMem -> m (Warnings, CParts)

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text

module Futhark.CodeGen.ImpGen.Multicore.Base

-- | Try to extract invariant allocations. If we assume that the given
--   MCCode is the body of a SegOp, then it is always safe to
--   move the immediate allocations to the prebody.
extractAllocations :: MCCode -> (MCCode, MCCode)
compileThreadResult :: SegSpace -> PatElem LetDecMem -> KernelResult -> MulticoreGen ()

-- | Information about the locks available for accumulators.
data Locks
Locks :: VName -> Int -> Locks
[locksArray] :: Locks -> VName
[locksCount] :: Locks -> Int
data HostEnv
HostEnv :: AtomicBinOp -> Map VName Locks -> HostEnv
[hostAtomics] :: HostEnv -> AtomicBinOp
[hostLocks] :: HostEnv -> Map VName Locks

-- | 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 :: MCCode -> Scheduling
decideScheduling' :: SegOp () rep -> MCCode -> Scheduling
renameSegBinOp :: [SegBinOp MCMem] -> MulticoreGen [SegBinOp MCMem]
freeParams :: FreeIn a => a -> 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 rep r
AtomicPrim :: DoAtomicUpdate rep r -> AtomicUpdate rep r

-- | Can be done by efficient swaps.
AtomicCAS :: DoAtomicUpdate rep r -> AtomicUpdate rep r

-- | Requires explicit locking.
AtomicLocking :: (Locking -> DoAtomicUpdate rep r) -> AtomicUpdate rep r

-- | A function for generating code for an atomic update. Assumes that the
--   bucket is in-bounds.
type DoAtomicUpdate rep r = [VName] -> [TExp Int64] -> MulticoreGen ()

-- | 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
getLoopBounds :: MulticoreGen (TExp Int64, TExp Int64)
getIterationDomain :: SegOp () MCMem -> SegSpace -> MulticoreGen (TExp Int64)
getReturnParams :: Pat LetDecMem -> SegOp () MCMem -> MulticoreGen [Param]
segOpString :: SegOp () MCMem -> MulticoreGen String

-- | Indicates whether to vectorize a chunk loop or keep it sequential. We
--   use this to allow falling back to sequential chunk loops in cases we
--   don't care about trying to vectorize.
data ChunkLoopVectorization
Vectorized :: ChunkLoopVectorization
Scalar :: ChunkLoopVectorization

-- | Emit code for the chunk loop, given an action that generates code for
--   a single iteration.
--   
--   The action is called with the (symbolic) index of the current
--   iteration.
generateChunkLoop :: String -> ChunkLoopVectorization -> (TExp Int64 -> MulticoreGen ()) -> MulticoreGen ()

-- | Emit code for a sequential loop over each vector lane, given and
--   action that generates code for a single iteration. The action is
--   called with the symbolic index of the current iteration.
generateUniformizeLoop :: (TExp Int64 -> MulticoreGen ()) -> MulticoreGen ()

-- | Given a piece of code, if that code performs an assignment, turn that
--   assignment into an extraction of element from a vector on the right
--   hand side, using a passed index for the extraction. Other code is left
--   as is.
extractVectorLane :: TExp Int64 -> MulticoreGen MCCode -> MulticoreGen ()

-- | Given an action that may generate some code, put that code into an
--   ISPC kernel.
inISPC :: MulticoreGen () -> MulticoreGen ()
toParam :: VName -> TypeBase shape u -> MulticoreGen [Param]

-- | Like sLoopNest, but puts a vectorized loop at the innermost layer.
sLoopNestVectorized :: Shape -> ([TExp Int64] -> MulticoreGen ()) -> MulticoreGen ()

module Futhark.CodeGen.ImpGen.Multicore.SegScan
compileSegScan :: Pat LetDecMem -> SegSpace -> [SegBinOp MCMem] -> KernelBody MCMem -> TV Int32 -> MulticoreGen MCCode

module Futhark.CodeGen.ImpGen.Multicore.SegRed

-- | Generate code for a SegRed construct
compileSegRed :: Pat LetDecMem -> SegSpace -> [SegBinOp MCMem] -> KernelBody MCMem -> TV Int32 -> MulticoreGen MCCode

-- | Like compileSegRed, but where the body is a monadic action.
compileSegRed' :: Pat LetDecMem -> SegSpace -> [SegBinOp MCMem] -> TV Int32 -> DoSegBody -> MulticoreGen MCCode
type DoSegBody = (([[(SubExp, [TExp Int64])]] -> MulticoreGen ()) -> MulticoreGen ())

-- | Multicore code generation for SegMap.
module Futhark.CodeGen.ImpGen.Multicore.SegMap
compileSegMap :: Pat LetDecMem -> SegSpace -> KernelBody MCMem -> MulticoreGen MCCode

module Futhark.CodeGen.ImpGen.Multicore.SegHist
compileSegHist :: Pat LetDecMem -> SegSpace -> [HistOp MCMem] -> KernelBody MCMem -> TV Int32 -> MulticoreGen MCCode

-- | Code generation for ImpCode with multicore operations.
module Futhark.CodeGen.ImpGen.Multicore

-- | Compile the program.
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

-- | Compile the program to ImpCode with multicore operations.
compileProg :: MonadFreshNames m => Text -> Prog MCMem -> m (Warnings, CParts)

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text

-- | Operations for generating multicore code.
operations :: Operations Multicore s

-- | Multicore-related command line options.
cliOptions :: [Option]
compileOp :: OpCompiler Multicore s
data ValueType
Prim :: PrimType -> ValueType
MemBlock :: ValueType
RawMem :: ValueType
paramToCType :: Param -> CompilerM op s (Type, ValueType)
prepareTaskStruct :: DefSpecifier s -> String -> [VName] -> [(Type, ValueType)] -> [VName] -> [(Type, ValueType)] -> CompilerM Multicore s Name
closureFreeStructField :: VName -> Name
generateParLoopFn :: ToIdent a => Map VName Space -> String -> MCCode -> a -> [(VName, (Type, ValueType))] -> [(VName, (Type, ValueType))] -> CompilerM Multicore s Name
addTimingFields :: Name -> CompilerM op s ()
functionTiming :: Name -> Id
functionIterations :: Name -> Id
multicoreDef :: DefSpecifier s
multicoreName :: String -> CompilerM op s Name
type DefSpecifier s = String -> (Name -> CompilerM Multicore s Definition) -> CompilerM Multicore s Name
atomicOps :: AtomicOp -> (Type -> VName -> CompilerM op s Type) -> CompilerM op s ()

-- | C code generator. This module can convert a correct ImpCode program to
--   an equivalent C program. This C program is expected to be converted to
--   WebAssembly, so we also produce the intended JavaScript wrapper.
module Futhark.CodeGen.Backends.MulticoreWASM

-- | Compile Futhark program to wasm-multicore program (some assembly
--   required).
--   
--   The triple that is returned consists of
--   
--   
--   
- Generated C code (to be passed to Emscripten).
--   
- JavaScript wrapper code that presents a nicer interface to the
--   Emscripten-produced code (this should be put in a .class.js
--   file by itself).
--   
- Options that should be passed to emcc.
--   
compileProg :: MonadFreshNames m => Text -> Prog MCMem -> m (Warnings, (CParts, Text, [String]))

-- | Javascript code that can be appended to the generated module to run a
--   Futhark server instance on startup.
runServer :: Text

-- | The names exported by the generated module.
libraryExports :: Text

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text

-- | C code generator. This module can convert a correct ImpCode program to
--   an equivalent ISPC program.
module Futhark.CodeGen.Backends.MulticoreISPC

-- | Compile the program to C and ISPC code using multicore operations.
compileProg :: MonadFreshNames m => Text -> Prog MCMem -> m (Warnings, (CParts, Text))

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text

-- | Compiler operations specific to the ISPC multicore backend.
operations :: Operations Multicore ISPCState

-- | Transient state tracked by the ISPC backend.
data ISPCState
instance GHC.Show.Show Futhark.CodeGen.Backends.MulticoreISPC.Variability
instance GHC.Classes.Ord Futhark.CodeGen.Backends.MulticoreISPC.Variability
instance GHC.Classes.Eq Futhark.CodeGen.Backends.MulticoreISPC.Variability
instance Control.Monad.Reader.Class.MonadReader Futhark.IR.Prop.Names.Names Futhark.CodeGen.Backends.MulticoreISPC.VariabilityM
instance Control.Monad.State.Class.MonadState Futhark.CodeGen.Backends.MulticoreISPC.Dependencies Futhark.CodeGen.Backends.MulticoreISPC.VariabilityM
instance GHC.Base.Monad Futhark.CodeGen.Backends.MulticoreISPC.VariabilityM
instance GHC.Base.Applicative Futhark.CodeGen.Backends.MulticoreISPC.VariabilityM
instance GHC.Base.Functor Futhark.CodeGen.Backends.MulticoreISPC.VariabilityM

module Futhark.CodeGen.ImpGen.GPU.Base
data KernelConstants
KernelConstants :: TV Int32 -> TV Int32 -> TV Int32 -> Count NumBlocks SubExp -> Count BlockSize SubExp -> TExp Int64 -> TExp Int64 -> TExp Int32 -> TExp Int32 -> Map [SubExp] [TExp Int32] -> Map [SubExp] (TExp Int32) -> KernelConstants
[kernelGlobalThreadIdVar] :: KernelConstants -> TV Int32
[kernelLocalThreadIdVar] :: KernelConstants -> TV Int32
[kernelBlockIdVar] :: KernelConstants -> TV Int32
[kernelNumBlocksCount] :: KernelConstants -> Count NumBlocks SubExp
[kernelBlockSizeCount] :: KernelConstants -> Count BlockSize SubExp
[kernelNumBlocks] :: KernelConstants -> TExp Int64
[kernelBlockSize] :: KernelConstants -> TExp Int64
[kernelNumThreads] :: KernelConstants -> TExp Int32
[kernelWaveSize] :: KernelConstants -> TExp Int32

-- | A mapping from dimensions of nested SegOps to already computed local
--   thread IDs. Only valid in non-virtualised case.
[kernelLocalIdMap] :: KernelConstants -> Map [SubExp] [TExp Int32]

-- | Mapping from dimensions of nested SegOps to how many iterations the
--   virtualisation loop needs.
[kernelChunkItersMap] :: KernelConstants -> Map [SubExp] (TExp Int32)
kernelGlobalThreadId :: KernelConstants -> TExp Int32
kernelLocalThreadId :: KernelConstants -> TExp Int32
kernelBlockId :: KernelConstants -> TExp Int32
threadOperations :: Operations GPUMem KernelEnv KernelOp
keyWithEntryPoint :: Maybe Name -> Name -> Name
type CallKernelGen = ImpM GPUMem HostEnv HostOp
type InKernelGen = ImpM GPUMem KernelEnv KernelOp

-- | Information about the locks available for accumulators.
data Locks
Locks :: VName -> Int -> Locks
[locksArray] :: Locks -> VName
[locksCount] :: Locks -> Int
data HostEnv
HostEnv :: AtomicBinOp -> Target -> Map VName Locks -> HostEnv
[hostAtomics] :: HostEnv -> AtomicBinOp
[hostTarget] :: HostEnv -> Target
[hostLocks] :: HostEnv -> Map VName Locks

-- | Which target are we ultimately generating code for? While most of the
--   kernels code is the same, there are some cases where we generate
--   special code based on the ultimate low-level API we are targeting.
data Target
CUDA :: Target
OpenCL :: Target
HIP :: Target
data KernelEnv
KernelEnv :: AtomicBinOp -> KernelConstants -> Map VName Locks -> KernelEnv
[kernelAtomics] :: KernelEnv -> AtomicBinOp
[kernelConstants] :: KernelEnv -> KernelConstants
[kernelLocks] :: KernelEnv -> Map VName Locks
blockReduce :: TExp Int32 -> Lambda GPUMem -> [VName] -> InKernelGen ()
blockScan :: Maybe (TExp Int32 -> TExp Int32 -> TExp Bool) -> TExp Int64 -> TExp Int64 -> Lambda GPUMem -> [VName] -> InKernelGen ()

-- | Assign iterations of a for-loop to threads in the threadblock. The
--   passed-in function is invoked with the (symbolic) iteration. For
--   multidimensional loops, use blockCoverSpace.
blockLoop :: IntExp t => TExp t -> (TExp t -> InKernelGen ()) -> InKernelGen ()
isActive :: [(VName, SubExp)] -> TExp Bool
sKernel :: Operations GPUMem KernelEnv KernelOp -> (KernelConstants -> TExp Int64) -> String -> VName -> KernelAttrs -> InKernelGen () -> CallKernelGen ()
sKernelThread :: String -> VName -> KernelAttrs -> InKernelGen () -> CallKernelGen ()

-- | Various extra configuration of the kernel being generated.
data KernelAttrs
KernelAttrs :: Bool -> Bool -> Count NumBlocks SubExp -> Count BlockSize SubExp -> Map VName KernelConstExp -> KernelAttrs

-- | Can this kernel execute correctly even if previous kernels failed?
[kAttrFailureTolerant] :: KernelAttrs -> Bool

-- | Does whatever launch this kernel check for shared memory capacity
--   itself?
[kAttrCheckSharedMemory] :: KernelAttrs -> Bool

-- | Number of blocks.
[kAttrNumBlocks] :: KernelAttrs -> Count NumBlocks SubExp

-- | Block size.
[kAttrBlockSize] :: KernelAttrs -> Count BlockSize SubExp

-- | Variables that are specially in scope inside the kernel.
--   Operationally, these will be available at kernel compile time (which
--   happens at run-time, with access to machine-specific information).
[kAttrConstExps] :: KernelAttrs -> Map VName KernelConstExp

-- | The default kernel attributes.
defKernelAttrs :: Count NumBlocks SubExp -> Count BlockSize SubExp -> KernelAttrs

-- | Compute kernel attributes from SegLevel; including synthesising
--   block-size and thread count if no grid is provided.
lvlKernelAttrs :: SegLevel -> CallKernelGen KernelAttrs
allocLocal :: AllocCompiler GPUMem r KernelOp
compileThreadResult :: SegSpace -> PatElem LetDecMem -> KernelResult -> InKernelGen ()

-- | For many kernels, we may not have enough physical blocks to cover the
--   logical iteration space. Some blocks 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.
virtualiseBlocks :: SegVirt -> TExp Int32 -> (TExp Int32 -> InKernelGen ()) -> InKernelGen ()

-- | Assign iterations of a for-loop to all threads in the kernel. The
--   passed-in function is invoked with the (symbolic) iteration. The body
--   must contain thread-level code. For multidimensional loops, use
--   blockCoverSpace.
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 block participate. The passed-in function is invoked
--   with a (symbolic) point in the index space.
blockCoverSpace :: IntExp t => [TExp t] -> ([TExp t] -> InKernelGen ()) -> InKernelGen ()

-- | If we are touching these arrays, which kind of fence do we need?
fenceForArrays :: [VName] -> InKernelGen Fence
updateAcc :: Safety -> VName -> [SubExp] -> [SubExp] -> InKernelGen ()

-- | Generate a constant device array of 32-bit integer zeroes with the
--   given number of elements. Initialised with a replicate.
genZeroes :: String -> Int -> CallKernelGen VName
isPrimParam :: Typed p => Param p -> Bool
kernelConstToExp :: KernelConstExp -> CallKernelGen Exp

-- | Given available register and a list of parameter types, compute the
--   largest available chunk size given the parameters for which we want
--   chunking and the available resources. Used in compileSegScan,
--   and compileSegRed (with primitive non-commutative operators
--   only).
getChunkSize :: [Type] -> KernelConstExp

-- | Retrieve a size of the given size class and put it in a variable with
--   the given name.
getSize :: String -> SizeClass -> CallKernelGen (TV Int64)

-- | Perform a Replicate with a kernel.
sReplicate :: VName -> SubExp -> CallKernelGen ()

-- | Perform an Iota with a kernel.
sIota :: VName -> TExp Int64 -> Exp -> Exp -> IntType -> CallKernelGen ()

-- | Is there an atomic BinOp corresponding to this BinOp?
type AtomicBinOp = BinOp -> Maybe (VName -> VName -> Count Elements (TExp Int64) -> Exp -> AtomicOp)

-- | Do an atomic update corresponding to a binary operator lambda.
atomicUpdateLocking :: AtomicBinOp -> Lambda GPUMem -> AtomicUpdate GPUMem KernelEnv

-- | 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 rep r

-- | Supported directly by primitive.
AtomicPrim :: DoAtomicUpdate rep r -> AtomicUpdate rep r

-- | Can be done by efficient swaps.
AtomicCAS :: DoAtomicUpdate rep r -> AtomicUpdate rep r

-- | Requires explicit locking.
AtomicLocking :: (Locking -> DoAtomicUpdate rep r) -> AtomicUpdate rep r

-- | A function for generating code for an atomic update. Assumes that the
--   bucket is in-bounds.
type DoAtomicUpdate rep r = Space -> [VName] -> [TExp Int64] -> ImpM rep r KernelOp ()

-- | Perform a scalar write followed by a fence.
writeAtomic :: VName -> [TExp Int64] -> SubExp -> [TExp Int64] -> InKernelGen ()

-- | Code generation for segmented and non-segmented scans. Uses a fairly
--   inefficient two-pass algorithm, but can handle anything.
module Futhark.CodeGen.ImpGen.GPU.SegScan.TwoPass

-- | Compile SegScan instance to host-level code with calls to
--   various kernels.
compileSegScan :: Pat LetDecMem -> SegLevel -> SegSpace -> [SegBinOp GPUMem] -> KernelBody GPUMem -> CallKernelGen ()

-- | Code generation for segmented and non-segmented scans. Uses a fast
--   single-pass algorithm, but which only works on NVIDIA GPUs and with
--   some constraints on the operator. We use this when we can.
module Futhark.CodeGen.ImpGen.GPU.SegScan.SinglePass

-- | Compile SegScan instance to host-level code with calls to a
--   single-pass kernel.
compileSegScan :: Pat LetDecMem -> SegLevel -> SegSpace -> SegBinOp GPUMem -> KernelBody GPUMem -> CallKernelGen ()

-- | Code generation for SegScan. Dispatches to either a single-pass
--   or two-pass implementation, depending on the nature of the scan and
--   the chosen abckend.
module Futhark.CodeGen.ImpGen.GPU.SegScan

-- | Compile SegScan instance to host-level code with calls to
--   various kernels.
compileSegScan :: Pat LetDecMem -> SegLevel -> SegSpace -> [SegBinOp GPUMem] -> KernelBody GPUMem -> 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:
--   
--   
--   
- While we still use two-phase reduction, we use only a single
--   kernel, with the final threadblock to write a result (tracked via an
--   atomic counter) performing the final reduction as well.
--   
- Instead of depending on storage layout transformations to handle
--   non-commutative reductions efficiently, we slide a
--   tblocksize-sized window over the input, and perform a
--   parallel reduction for each window. This sacrifices the notion of
--   efficient sequentialisation, but is sometimes faster and definitely
--   simpler and more predictable (and uses less auxiliary storage).
--   
--   
--   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)
--   tblock_size to decide which of the following two strategies
--   to choose:
--   
--   
--   
- Large: uses one or more blocks to process a single segment. If
--   multiple blocks are used per segment, the intermediate reduction
--   results must be recursively reduced, until there is only a single
--   value per segment.
--   
--   
--   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 block-wide
--   reductions) to enable coalesced memory accesses, just as in the
--   non-segmented case.
--   
--   
--   
- Small: is used to let each block process *multiple* segments
--   within a block. We will only use this approach when we can process at
--   least two segments within a single block. In those cases, we would
--   allocate a whole block per segment with the large strategy, but
--   at most 50% of the threads in the block would have any element to
--   read, which becomes highly inefficient.
--   
--   
--   An optimization specfically targeted at non-segmented and
--   large-segments segmented reductions with non-commutative is made: The
--   stage one main loop is essentially stripmined by a factor *chunk*,
--   inserting collective copies via shared memory of each reduction
--   parameter going into the intra-block (partial) reductions. This saves
--   a factor *chunk* number of intra-block reductions at the cost of some
--   overhead in collective copies.
module Futhark.CodeGen.ImpGen.GPU.SegRed

-- | Compile SegRed instance to host-level code with calls to
--   various kernels.
compileSegRed :: Pat LetDecMem -> SegLevel -> SegSpace -> [SegBinOp GPUMem] -> KernelBody GPUMem -> CallKernelGen ()

-- | Like compileSegRed, but where the body is a monadic action.
compileSegRed' :: Pat LetDecMem -> KernelGrid -> SegSpace -> [SegBinOp GPUMem] -> 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 ()

-- | 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 shared
--   memory when possible. Given:
--   
--   H: total size of histograms in bytes, including any lock arrays.
--   
--   G: block size
--   
--   T: number of bytes of shared memory each thread can be given without
--   impacting occupancy (determined experimentally, e.g. 32).
--   
--   LMAX: maximum amount of shared memory per threadblock (hard limit).
--   
--   We wish to compute:
--   
--   COOP: cooperation level (number of threads per subhistogram)
--   
--   LH: number of shared memory subhistograms
--   
--   We do this as:
--   
--   COOP = ceil(H / T) LH = ceil((G*T)/H) if COOP <= G && H
--   <= LMAX then use shared memory else use global memory
module Futhark.CodeGen.ImpGen.GPU.SegHist

-- | Generate code for a segmented histogram called from the host.
compileSegHist :: Pat LetDecMem -> SegLevel -> SegSpace -> [HistOp GPUMem] -> KernelBody GPUMem -> CallKernelGen ()
instance GHC.Classes.Ord Futhark.CodeGen.ImpGen.GPU.SegHist.Passage
instance GHC.Classes.Eq Futhark.CodeGen.ImpGen.GPU.SegHist.Passage

-- | Generation of kernels with block-level bodies.
module Futhark.CodeGen.ImpGen.GPU.Block
sKernelBlock :: String -> VName -> KernelAttrs -> InKernelGen () -> CallKernelGen ()
compileBlockResult :: SegSpace -> PatElem LetDecMem -> KernelResult -> InKernelGen ()
blockOperations :: Operations GPUMem KernelEnv KernelOp

-- | Various useful precomputed information for block-level SegOps.
data Precomputed

-- | Precompute various constants and useful information.
precomputeConstants :: Count BlockSize (TExp Int64) -> Stms GPUMem -> CallKernelGen Precomputed

-- | Make use of various precomputed constants.
precomputedConstants :: Precomputed -> InKernelGen a -> InKernelGen a

-- | Do an atomic update corresponding to a binary operator lambda.
atomicUpdateLocking :: AtomicBinOp -> Lambda GPUMem -> AtomicUpdate GPUMem KernelEnv

-- | 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 threadblocks run a loop to imitate multiple
--   threadblocks.
module Futhark.CodeGen.ImpGen.GPU.SegMap

-- | Compile SegMap instance code.
compileSegMap :: Pat LetDecMem -> SegLevel -> SegSpace -> KernelBody GPUMem -> CallKernelGen ()

-- | Compile a GPUMem 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.GPU

-- | Compile a GPUMem program to low-level parallel code, with
--   either CUDA or OpenCL characteristics.
compileProgOpenCL :: MonadFreshNames m => Prog GPUMem -> m (Warnings, Program)

-- | Compile a GPUMem program to low-level parallel code, with
--   either CUDA or OpenCL characteristics.
compileProgCUDA :: MonadFreshNames m => Prog GPUMem -> m (Warnings, Program)

-- | Compile a GPUMem program to low-level parallel code, with
--   either CUDA or OpenCL characteristics.
compileProgHIP :: MonadFreshNames m => Prog GPUMem -> m (Warnings, Program)

-- | The warnings produced by the compiler. The Show instance
--   produces a human-readable description.
data Warnings

-- | Code generation for ImpCode with OpenCL kernels.
module Futhark.CodeGen.ImpGen.OpenCL

-- | Compile the program to ImpCode with OpenCL kernels.
compileProg :: MonadFreshNames m => Prog GPUMem -> m (Warnings, Program)

-- | The warnings produced by the compiler. The Show instance
--   produces a human-readable description.
data Warnings

-- | Code generation for Python with OpenCL.
module Futhark.CodeGen.Backends.PyOpenCL

-- | Compile the program to Python with calls to OpenCL.
compileProg :: MonadFreshNames m => CompilerMode -> String -> Prog GPUMem -> m (Warnings, Text)

-- | Code generation for C with OpenCL.
module Futhark.CodeGen.Backends.COpenCL

-- | Compile the program to C with calls to OpenCL.
compileProg :: MonadFreshNames m => Text -> Prog GPUMem -> m (Warnings, CParts)

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text

-- | Code generation for ImpCode with HIP kernels.
module Futhark.CodeGen.ImpGen.HIP

-- | Compile the program to ImpCode with HIP kernels.
compileProg :: MonadFreshNames m => Prog GPUMem -> m (Warnings, Program)

-- | The warnings produced by the compiler. The Show instance
--   produces a human-readable description.
data Warnings

-- | Code generation for HIP.
module Futhark.CodeGen.Backends.HIP

-- | Compile the program to C with calls to HIP.
compileProg :: MonadFreshNames m => Text -> Prog GPUMem -> m (Warnings, CParts)

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text

-- | Code generation for ImpCode with CUDA kernels.
module Futhark.CodeGen.ImpGen.CUDA

-- | Compile the program to ImpCode with CUDA kernels.
compileProg :: MonadFreshNames m => Prog GPUMem -> 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 => Text -> Prog GPUMem -> m (Warnings, CParts)

-- | The result of compilation to C is multiple 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 :: Text -> Text -> Text -> Text -> Text -> Text -> CParts
[cHeader] :: CParts -> Text

-- | Utility definitions that must be visible to both CLI and library
--   parts.
[cUtils] :: CParts -> Text
[cCLI] :: CParts -> Text
[cServer] :: CParts -> Text
[cLib] :: CParts -> Text

-- | The manifest, in JSON format.
[cJsonManifest] :: CParts -> Text

-- | Produce header, implementation, and manifest files.
asLibrary :: CParts -> (Text, Text, Text)

-- | As executable with command-line interface.
asExecutable :: CParts -> Text

-- | As server executable.
asServer :: CParts -> Text

-- | 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

-- | Are we type-checking at the top level, or are we inside a nested
--   module?
atTopLevel :: TypeM Bool

-- | We are now going to type-check the body of a module.
enteringModule :: TypeM a -> TypeM a

-- | Map source-level names to fresh unique internal names, and evaluate a
--   type checker context with the mapping active.
bindSpaced :: [(Namespace, Name, SrcLoc)] -> ([VName] -> TypeM a) -> TypeM a

-- | Map single source-level name to fresh unique internal names, and
--   evaluate a type checker context with the mapping active.
bindSpaced1 :: Namespace -> Name -> SrcLoc -> (VName -> TypeM a) -> TypeM a

-- | Bind these identifiers in the name map and also check whether they
--   have been used.
bindIdents :: [IdentBase NoInfo VName t] -> TypeM a -> TypeM 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 Size as -> TypeBase Size as

-- | Look up a module type.
lookupMTy :: SrcLoc -> QualName Name -> TypeM (QualName VName, MTy)

-- | Look up an import.
lookupImport :: SrcLoc -> FilePath -> TypeM (ImportName, Env)
lookupMod :: SrcLoc -> QualName Name -> TypeM (QualName VName, Mod)

-- | 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 :: Loc -> Notes -> Doc () -> TypeError

-- | Prettyprint type error.
prettyTypeError :: TypeError -> Doc AnsiStyle

-- | Prettyprint type error, without location information. This can be used
--   for cases where the location is printed in some other way.
prettyTypeErrorNoLoc :: TypeError -> Doc AnsiStyle

-- | Attach a reference to documentation explaining the error in more
--   detail.
withIndexLink :: Doc a -> Doc a -> Doc a

-- | An unexpected functor appeared!
unappliedFunctor :: MonadTypeChecker m => SrcLoc -> m a

-- | An unknown variable was referenced.
unknownVariable :: MonadTypeChecker m => Namespace -> QualName Name -> SrcLoc -> m a

-- | A name prefixed with an underscore was used.
underscoreUse :: MonadTypeChecker m => SrcLoc -> QualName Name -> m a

-- | A collection of extra information regarding a type error.
data Notes

-- | A single note.
aNote :: Doc () -> 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 ()
warnings :: MonadTypeChecker m => Warnings -> m ()
newName :: MonadTypeChecker m => VName -> m VName
newID :: MonadTypeChecker m => Name -> m VName
newTypeName :: MonadTypeChecker m => Name -> m VName
bindVal :: MonadTypeChecker m => VName -> BoundV -> m a -> m a
lookupType :: MonadTypeChecker m => QualName VName -> m ([TypeParam], StructRetType, Liftedness)
typeError :: (MonadTypeChecker m, Located loc) => loc -> Notes -> Doc () -> m a
data TypeState

-- | Indicate that this name has been used. This is usually done implicitly
--   by other operations, but sometimes we want to make a "fake" use to
--   avoid things like top level functions being considered unused.
usedName :: VName -> TypeM ()

-- | Elaborate the given name in the given namespace at the given location,
--   producing the corresponding unique VName.
checkName :: Namespace -> Name -> SrcLoc -> TypeM VName

-- | Type-check an attribute.
checkAttr :: MonadTypeChecker m => AttrInfo VName -> m (AttrInfo VName)

-- | Elaborate the given qualified name in the given namespace at the given
--   location, producing the corresponding unique QualName.
checkQualName :: Namespace -> QualName Name -> SrcLoc -> TypeM (QualName VName)

-- | Elaborate the given qualified name in the given namespace at the given
--   location, producing the corresponding unique QualName. Fails if
--   the name is a module.
checkValName :: QualName Name -> SrcLoc -> TypeM (QualName VName)

-- | Turn a Left TypeError into an actual error.
badOnLeft :: Either TypeError a -> TypeM a

-- | Does a type with this name already exist? This is used for warnings,
--   so it is OK it's a little unprincipled.
isKnownType :: QualName VName -> TypeM Bool

-- | 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
[envModTypeTable] :: 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 FunModType
FunModType :: TySet -> Mod -> MTy -> FunModType
[funModTypeAbs] :: FunModType -> TySet
[funModTypeMod] :: FunModType -> Mod
[funModTypeMty] :: FunModType -> MTy

-- | A mapping from import import names to Envs. This is used to
--   resolve import declarations.
type ImportTable = Map ImportName 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
[boundValTParams] :: BoundV -> [TypeParam]
[boundValType] :: BoundV -> StructType

-- | Representation of a module, which is either a plain environment, or a
--   parametric module ("functor" in SML).
data Mod
ModEnv :: Env -> Mod
ModFun :: FunModType -> Mod

-- | A binding from a name to its definition as a type. We allow a return
--   type here to support type abbreviations that hide some inner sizes
--   (these must necessarily be Lifted or SizeLifted).
data TypeBinding
TypeAbbr :: Liftedness -> [TypeParam] -> StructRetType -> 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 integer types.
anyIntType :: [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

-- | Construct 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 :: Name -> Int -> Name
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 Prettyprinter.Internal.Pretty Language.Futhark.TypeChecker.Monad.Notes
instance Prettyprinter.Internal.Pretty Language.Futhark.TypeChecker.Monad.Note

-- | Type checker building blocks that do not involve unification.
module Language.Futhark.TypeChecker.Types

-- | Check a type expression, producing:
--   
--   
--   
- The checked expression.
--   
- Size variables for any anonymous sizes in the expression.
--   
- The elaborated type.
--   
- The liftedness of the type.
--   
checkTypeExp :: (MonadTypeChecker m, Pretty df) => (df -> m Exp) -> TypeExp df VName -> m (TypeExp Exp VName, [VName], ResRetType, Liftedness)

-- | Ensure that the dimensions of the RetType are unique by generating new
--   names for them. This is to avoid name capture.
renameRetType :: MonadTypeChecker m => ResRetType -> m ResRetType

-- | Construct a type argument corresponding to a type parameter.
typeParamToArg :: TypeParam -> StructTypeArg

-- | A type substitution may be a substitution or a yet-unknown
--   substitution (but which is certainly an overloaded primitive type!).
data Subst t
Subst :: [TypeParam] -> t -> Subst t
ExpSubst :: Exp -> Subst t

-- | Create a type substitution corresponding to a type binding.
substFromAbbr :: TypeBinding -> Subst StructRetType

-- | Substitutions to apply in a type.
type TypeSubs = VName -> Maybe (Subst StructRetType)

-- | Class of types which allow for substitution of types with no
--   annotations for type variable names.
class Substitutable a
applySubst :: Substitutable a => TypeSubs -> 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 u => (VName -> Maybe (Subst (RetTypeBase Size u))) -> TypeBase Size u -> TypeBase Size u

-- | 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.
mustBeExplicitInType :: StructType -> Set VName

-- | 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.
mustBeExplicitInBinding :: StructType -> Set VName

-- | Determine which of the sizes in a type are used as sizes outside of
--   functions in the type, and which are not. The former are said to be
--   "witnessed" by this type, while the latter are not. In practice, the
--   latter means that the actual sizes must come from somewhere else.
determineSizeWitnesses :: StructType -> (Set VName, Set VName)
instance GHC.Show.Show t => GHC.Show.Show (Language.Futhark.TypeChecker.Types.Subst t)
instance Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Syntax.RetTypeBase Language.Futhark.Syntax.Size Language.Futhark.Core.Uniqueness)
instance Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Syntax.RetTypeBase Language.Futhark.Syntax.Size Language.Futhark.Core.NoUniqueness)
instance Language.Futhark.TypeChecker.Types.Substitutable Language.Futhark.Syntax.StructType
instance Language.Futhark.TypeChecker.Types.Substitutable Language.Futhark.Syntax.ParamType
instance Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Syntax.TypeBase Language.Futhark.Syntax.Size Language.Futhark.Core.Uniqueness)
instance Language.Futhark.TypeChecker.Types.Substitutable Language.Futhark.Prop.Exp
instance Language.Futhark.TypeChecker.Types.Substitutable d => Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Syntax.Shape d)
instance Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Prop.Pat Language.Futhark.Syntax.StructType)
instance Language.Futhark.TypeChecker.Types.Substitutable (Language.Futhark.Prop.Pat Language.Futhark.Syntax.ParamType)
instance Prettyprinter.Internal.Pretty t => Prettyprinter.Internal.Pretty (Language.Futhark.TypeChecker.Types.Subst t)
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 -> Loc -> Constraint
Constraint :: StructRetType -> Usage -> Constraint
Overloaded :: [PrimType] -> Usage -> Constraint
HasFields :: Liftedness -> Map Name StructType -> Usage -> Constraint
Equality :: Usage -> Constraint
HasConstrs :: Liftedness -> Map Name [StructType] -> Usage -> Constraint
ParamSize :: Loc -> Constraint

-- | Is not actually a type, but a term-level size, possibly already set to
--   something specific.
Size :: Maybe Exp -> 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.
UnknownSize :: Loc -> RigidSource -> Constraint

-- | A usage that caused a type constraint.
data Usage
Usage :: Maybe Text -> Loc -> Usage

-- | Construct a Usage from a location and a description.
mkUsage :: Located a => a -> Text -> Usage

-- | Construct a Usage that has just a location, but no particular
--   description.
mkUsage' :: Located a => a -> 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, Located a) => a -> Name -> m (TypeBase dim als)
newDimVar :: MonadUnify m => Usage -> Rigidity -> Name -> m VName
newRigidDim :: (MonadUnify m, Located a) => a -> RigidSource -> Name -> m VName
newFlexibleDim :: MonadUnify m => Usage -> Name -> 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) -> Text -> RigidSource

-- | An existential return size.
RigidRet :: Maybe (QualName VName) -> RigidSource

-- | Similarly to RigidRet, but produce by a loop.
RigidLoop :: RigidSource

-- | Produced by a complicated slice expression.
RigidSlice :: Maybe Size -> Text -> RigidSource

-- | Produced by a complicated range expression.
RigidRange :: RigidSource

-- | Mismatch in branches.
RigidCond :: StructType -> StructType -> RigidSource

-- | Invented during unification.
RigidUnify :: RigidSource

-- | A name used in a size went out of scope.
RigidOutOfScope :: Loc -> 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
sizeFree :: MonadUnify m => SrcLoc -> (Exp -> Maybe VName) -> TypeBase Size u -> m (TypeBase Size u, [VName])

-- | An empty path.
noBreadCrumbs :: BreadCrumbs

-- | Is the path empty?
hasNoBreadCrumbs :: BreadCrumbs -> Bool

-- | Retrieve notes describing the purpose or origin of the given
--   Size. The location is used as the *current* location, for the
--   purpose of reporting relative locations.
dimNotes :: (Located a, MonadUnify m) => a -> Exp -> m Notes

-- | Assert that this type must be zero-order.
zeroOrderType :: MonadUnify m => Usage -> Text -> StructType -> m ()

-- | Assert that this type must be valid as an array element.
arrayElemType :: (MonadUnify m, Pretty (Shape dim), Pretty u) => Usage -> Text -> TypeBase dim u -> 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 -> StructType -> m StructType

-- | 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 (Shape dim), Pretty u) => Usage -> TypeBase dim u -> m ()

-- | Replace any top-level type variable with its substitution.
normType :: MonadUnify m => StructType -> m StructType

-- | Replace all type variables with their substitution.
normTypeFully :: (Substitutable a, MonadUnify m) => a -> m a

-- | Unifies two types.
unify :: 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 -> StructType -> StructType -> m (StructType, [VName])

-- | Perform a unification of two types outside a monadic context. The
--   first list of type parameters are rigid but may have liftedness
--   constraints; the second list of type parameters are allowed to be
--   instantiated. All other types are considered rigid with no
--   constraints.
doUnification :: Loc -> [TypeParam] -> [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 Prettyprinter.Internal.Pretty Language.Futhark.TypeChecker.Unify.Usage
instance Data.Loc.Located Language.Futhark.TypeChecker.Unify.Usage
instance Prettyprinter.Internal.Pretty Language.Futhark.TypeChecker.Unify.BreadCrumbs
instance Prettyprinter.Internal.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:
--   
--   
--   
- Turn operator sections into explicit lambdas.
--   
- Converts applications of intrinsic SOACs into SOAC AST nodes (Map,
--   Reduce, etc).
--   
- Elide functions that are not reachable from an entry point (this
--   is a side effect of the monomorphisation algorithm, which uses the
--   entry points as roots).
--   
- Rewrite BinOp nodes to Apply nodes.
--   
- Replace all size expressions by constants or variables, complex
--   expressions replaced by variables are calculated in let binding or
--   replaced by size parameters if in argument.
--   
--   
--   Note that these changes are unfortunately not visible in the AST
--   representation.
module Futhark.Internalise.Monomorphise

-- | Monomorphise a list of top-level value bindings.
transformProg :: MonadFreshNames m => [ValBind] -> m [ValBind]
instance GHC.Show.Show Futhark.Internalise.Monomorphise.ReplacedExp
instance GHC.Show.Show Futhark.Internalise.Monomorphise.MonoSize
instance GHC.Classes.Eq Futhark.Internalise.Monomorphise.MonoSize
instance Control.Monad.Writer.Class.MonadWriter (Data.Sequence.Internal.Seq (Language.Futhark.Core.VName, Language.Futhark.Prop.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 Futhark.MonadFreshNames.MonadFreshNames Futhark.Internalise.Monomorphise.MonoM
instance Control.Monad.State.Class.MonadState Futhark.Internalise.Monomorphise.ExpReplacements Futhark.Internalise.Monomorphise.MonoM
instance Prettyprinter.Internal.Pretty Futhark.Internalise.Monomorphise.MonoSize
instance Prettyprinter.Internal.Pretty (Language.Futhark.Syntax.Shape Futhark.Internalise.Monomorphise.MonoSize)
instance GHC.Base.Semigroup Futhark.Internalise.Monomorphise.Env
instance GHC.Base.Monoid Futhark.Internalise.Monomorphise.Env
instance Prettyprinter.Internal.Pretty Futhark.Internalise.Monomorphise.ReplacedExp
instance GHC.Classes.Eq Futhark.Internalise.Monomorphise.ReplacedExp

-- | This full normalisation module converts a well-typed, polymorphic,
--   module-free Futhark program into an equivalent with only simple
--   expresssions. Notably, all non-trivial expression are converted into a
--   list of let-bindings to make them simpler, with no nested apply,
--   nested lets... This module only performs syntactic operations.
--   
--   Also, it performs various kinds of desugaring:
--   
--   
--   
- Turns operator sections into explicit lambdas.
--   
- Rewrites BinOp nodes to Apply nodes (&& and || are
--   converted to conditionals).
--   
- Turns `let x [i] = e1` into `let x = x with [i] = e1`.
--   
- Binds all implicit sizes.
--   
- Turns implicit record fields into explicit record fields.
--   
--   
--   This is currently not done for expressions inside sizes, this
--   processing still needed in monomorphisation for now.
module Futhark.Internalise.FullNormalise

-- | Fully normalise top level bindings.
transformProg :: MonadFreshNames m => [ValBind] -> m [ValBind]
instance Control.Monad.State.Class.MonadState Futhark.Internalise.FullNormalise.NormState Futhark.Internalise.FullNormalise.OrderingM
instance Control.Monad.Reader.Class.MonadReader GHC.Base.String Futhark.Internalise.FullNormalise.OrderingM
instance GHC.Base.Monad Futhark.Internalise.FullNormalise.OrderingM
instance GHC.Base.Applicative Futhark.Internalise.FullNormalise.OrderingM
instance GHC.Base.Functor Futhark.Internalise.FullNormalise.OrderingM
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Internalise.FullNormalise.OrderingM

-- | Conversion of a monomorphic, first-order, defunctorised source program
--   to a core Futhark program.
module Futhark.Internalise.Exps

-- | Convert a program in source Futhark to a program in the Futhark core
--   language.
transformProg :: MonadFreshNames m => Bool -> VisibleTypes -> [ValBind] -> m (Prog SOACS)
instance GHC.Show.Show Futhark.Internalise.Exps.Function

-- | 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.StaticVal
instance GHC.Show.Show Futhark.Internalise.Defunctionalise.Binding
instance Control.Monad.State.Class.MonadState ([Language.Futhark.Prop.ValBind], Futhark.FreshNames.VNameSource) 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.SizeSubst
instance GHC.Classes.Ord Futhark.Internalise.Defunctionalise.SizeSubst
instance GHC.Classes.Eq Futhark.Internalise.Defunctionalise.SizeSubst
instance Futhark.MonadFreshNames.MonadFreshNames Futhark.Internalise.Defunctionalise.DefM

-- | A minor cleanup pass that runs after defunctorisation and applies any
--   type abbreviations. After this, the program consists entirely value
--   bindings.
module Futhark.Internalise.ApplyTypeAbbrs

-- | Apply type abbreviations from a list of top-level declarations. A
--   module-free input program is expected, so only value declarations and
--   type declaration are accepted.
transformProg :: Monad m => [Dec] -> m [ValBind]

-- | This module implements a transformation from source to core Futhark.
--   
--   The source and core language is similar in spirit, but the core
--   language is much more regular (and mostly much simpler) in order to
--   make it easier to write program transformations.
--   
--   
--   
- Language.Futhark.Syntax contains the source language
--   definition.
--   
- Futhark.IR.Syntax contains the core IR definition.
--   
--   
--   Specifically, internalisation generates the SOACS dialect of the core
--   IR (Futhark.IR.SOACS). This is then initially used by the
--   compiler middle-end. The main differences between the source and core
--   IR are as follows:
--   
--   
--   
- The core IR has no modules. These are removed in
--   Futhark.Internalise.Defunctorise.
--   
- The core IR has no type abbreviations. These are removed in
--   Futhark.Internalise.ApplyTypeAbbrs.
--   
- The core IR has little syntactic niceties. A lot of syntactic
--   sugar is removed in Futhark.Internalise.FullNormalise.
--   
- Lambda lifting is performed by
--   Futhark.Internalise.LiftLambdas,
--   
- mostly to make the job of later passes simpler.
--   
- The core IR is monomorphic. Polymorphic functions are
--   monomorphised in Futhark.Internalise.Monomorphise
--   
- The core IR is first-order.
--   Futhark.Internalise.Defunctionalise removes higher-order
--   functions.
--   
- The core IR is in ANF.
--   
- The core IR does not have arrays of tuples (or tuples or records
--   at all, really). Arrays of tuples are turned into multiple arrays. For
--   example, a source language transposition of an array of pairs becomes
--   a core IR that contains two transpositions of two distinct arrays. The
--   guts of this transformation is in
--   Futhark.Internalise.Exps.
--   
- For the above reason, SOACs also accept multiple input arrays. The
--   available primitive operations are also somewhat different than in the
--   source language. See SOAC.
--   
module Futhark.Internalise

-- | Convert a program in source Futhark to a program in the Futhark core
--   language.
internaliseProg :: (MonadFreshNames m, MonadLogger m) => FutharkConfig -> Imports -> m (Prog SOACS)

-- | Facilities for type-checking terms. Factored out of
--   Language.Futhark.TypeChecker.Terms to prevent the module from
--   being gigantic.
--   
--   Incidentally also a nice place to put Haddock comments to make the
--   internal API of the type checker easier to browse.
module Language.Futhark.TypeChecker.Terms.Monad
data TermTypeM a
runTermTypeM :: (ExpBase NoInfo VName -> TermTypeM Exp) -> TermTypeM a -> TypeM a
data ValBinding
BoundV :: [TypeParam] -> StructType -> ValBinding
OverloadedF :: [PrimType] -> [Maybe PrimType] -> Maybe PrimType -> ValBinding
EqualityF :: ValBinding

-- | What was the source of some existential size? This is used for using
--   the same existential variable if the same source is encountered in
--   multiple locations.
data SizeSource
SourceSlice :: Maybe Size -> Maybe (ExpBase NoInfo VName) -> Maybe (ExpBase NoInfo VName) -> Maybe (ExpBase NoInfo VName) -> SizeSource
data Inferred t
NoneInferred :: Inferred t
Ascribed :: t -> Inferred t
data Checking
CheckingApply :: Maybe (QualName VName) -> Exp -> StructType -> StructType -> Checking
CheckingReturn :: ResType -> StructType -> Checking
CheckingAscription :: StructType -> StructType -> Checking
CheckingLetGeneralise :: Name -> Checking
CheckingParams :: Maybe Name -> Checking
CheckingPat :: PatBase NoInfo VName StructType -> Inferred StructType -> Checking
CheckingLoopBody :: StructType -> StructType -> Checking
CheckingLoopInitial :: StructType -> StructType -> Checking
CheckingRecordUpdate :: [Name] -> StructType -> StructType -> Checking
CheckingRequired :: [StructType] -> StructType -> Checking
CheckingBranches :: StructType -> StructType -> Checking
withEnv :: TermEnv -> Env -> TermEnv
localScope :: (TermScope -> TermScope) -> TermTypeM a -> TermTypeM a

-- | Type checking happens with access to this environment. The
--   TermScope will be extended during type-checking as bindings
--   come into scope.
data TermEnv
TermEnv :: TermScope -> Maybe Checking -> Level -> (ExpBase NoInfo VName -> TermTypeM Exp) -> Env -> ImportName -> TermEnv
[termScope] :: TermEnv -> TermScope
[termChecking] :: TermEnv -> Maybe Checking
[termLevel] :: TermEnv -> Level
[termChecker] :: TermEnv -> ExpBase NoInfo VName -> TermTypeM Exp
[termOuterEnv] :: TermEnv -> Env
[termImportName] :: TermEnv -> ImportName
data TermScope
TermScope :: Map VName ValBinding -> Map VName TypeBinding -> Map VName Mod -> TermScope
[scopeVtable] :: TermScope -> Map VName ValBinding
[scopeTypeTable] :: TermScope -> Map VName TypeBinding
[scopeModTable] :: TermScope -> Map VName Mod

-- | The state is a set of constraints and a counter for generating type
--   names. This is distinct from the usual counter we use for generating
--   unique names, as these will be user-visible.
data TermTypeState
TermTypeState :: Constraints -> !Int -> Warnings -> VNameSource -> TermTypeState
[stateConstraints] :: TermTypeState -> Constraints
[stateCounter] :: TermTypeState -> !Int
[stateWarnings] :: TermTypeState -> Warnings
[stateNameSource] :: TermTypeState -> VNameSource
onFailure :: Checking -> TermTypeM a -> TermTypeM a
extSize :: SrcLoc -> SizeSource -> TermTypeM (Size, Maybe VName)

-- | Get the type of an expression, with top level type variables
--   substituted. Never call typeOf directly (except in a few
--   carefully inspected locations)!
expType :: Exp -> TermTypeM StructType

-- | Get the type of an expression, with all type variables substituted.
--   Slower than expType, but sometimes necessary. Never call
--   typeOf directly (except in a few carefully inspected
--   locations)!
expTypeFully :: Exp -> TermTypeM StructType
constrain :: VName -> Constraint -> TermTypeM ()
newArrayType :: Usage -> Name -> Int -> TermTypeM (StructType, StructType)

-- | Replace *all* dimensions with distinct fresh size variables.
allDimsFreshInType :: Usage -> Rigidity -> Name -> TypeBase Size als -> TermTypeM (TypeBase Size als, Map VName Size)

-- | Replace all type variables with their concrete types.
updateTypes :: ASTMappable e => e -> TermTypeM e
type Names = Set VName
unifies :: Text -> StructType -> Exp -> TermTypeM Exp

-- | require ts e causes a TypeError if expType e
--   is not one of the types in ts. Otherwise, simply returns
--   e.
require :: Text -> [PrimType] -> Exp -> TermTypeM Exp
checkTypeExpNonrigid :: TypeExp (ExpBase NoInfo VName) VName -> TermTypeM (TypeExp Exp VName, ResType, [VName])
lookupVar :: SrcLoc -> QualName VName -> TermTypeM StructType
lookupMod :: QualName VName -> TermTypeM Mod
isInt64 :: Exp -> Maybe Int64
incLevel :: TermTypeM a -> TermTypeM a
unusedSize :: MonadTypeChecker m => SizeBinder VName -> m a
instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.Monad.ValBinding
instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.Monad.TermScope
instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.Monad.FName
instance GHC.Show.Show Language.Futhark.TypeChecker.Terms.Monad.SizeSource
instance GHC.Classes.Ord Language.Futhark.TypeChecker.Terms.Monad.SizeSource
instance GHC.Classes.Eq Language.Futhark.TypeChecker.Terms.Monad.SizeSource
instance Control.Monad.State.Class.MonadState Language.Futhark.TypeChecker.Terms.Monad.TermTypeState Language.Futhark.TypeChecker.Terms.Monad.TermTypeM
instance Control.Monad.Reader.Class.MonadReader Language.Futhark.TypeChecker.Terms.Monad.TermEnv Language.Futhark.TypeChecker.Terms.Monad.TermTypeM
instance GHC.Base.Applicative Language.Futhark.TypeChecker.Terms.Monad.TermTypeM
instance GHC.Base.Functor Language.Futhark.TypeChecker.Terms.Monad.TermTypeM
instance GHC.Base.Monad Language.Futhark.TypeChecker.Terms.Monad.TermTypeM
instance Control.Monad.Error.Class.MonadError Language.Futhark.TypeChecker.Monad.TypeError Language.Futhark.TypeChecker.Terms.Monad.TermTypeM
instance Language.Futhark.TypeChecker.Unify.MonadUnify Language.Futhark.TypeChecker.Terms.Monad.TermTypeM
instance Language.Futhark.TypeChecker.Monad.MonadTypeChecker Language.Futhark.TypeChecker.Terms.Monad.TermTypeM
instance GHC.Classes.Eq Language.Futhark.TypeChecker.Terms.Monad.FName
instance GHC.Classes.Ord Language.Futhark.TypeChecker.Terms.Monad.FName
instance GHC.Base.Semigroup Language.Futhark.TypeChecker.Terms.Monad.TermScope
instance Prettyprinter.Internal.Pretty Language.Futhark.TypeChecker.Terms.Monad.Checking
instance GHC.Base.Functor Language.Futhark.TypeChecker.Terms.Monad.Inferred

-- | Type checking of patterns.
module Language.Futhark.TypeChecker.Terms.Pat

-- | Bind these identifiers locally while running the provided action.
binding :: [Ident StructType] -> TermTypeM a -> TermTypeM a

-- | Check and bind type and value parameters.
bindingParams :: [TypeParam] -> [PatBase NoInfo VName ParamType] -> ([Pat ParamType] -> TermTypeM a) -> TermTypeM a

-- | Check and bind a let-pattern.
bindingPat :: [SizeBinder VName] -> PatBase NoInfo VName (TypeBase Size u) -> StructType -> (Pat ParamType -> TermTypeM a) -> TermTypeM a

-- | Bind a single term-level identifier.
bindingIdent :: IdentBase NoInfo VName StructType -> StructType -> (Ident StructType -> TermTypeM a) -> TermTypeM a

-- | Bind let-bound sizes. This is usually followed by
--   bindingPat immediately afterwards.
bindingSizes :: [SizeBinder VName] -> TermTypeM a -> TermTypeM a

-- | Type inference of loop. This is complicated because of the
--   uniqueness and size inference, so the implementation is separate from
--   the main type checker.
module Language.Futhark.TypeChecker.Terms.Loop

-- | An un-checked loop.
type UncheckedLoop = (PatBase NoInfo VName ParamType, LoopInitBase NoInfo VName, LoopFormBase NoInfo VName, ExpBase NoInfo VName)

-- | A loop that has been type-checked.
type CheckedLoop = ([VName], Pat ParamType, LoopInitBase Info VName, LoopFormBase Info VName, Exp)

-- | Type-check a loop expression, passing in a function for
--   type-checking subexpressions.
checkLoop :: (ExpBase NoInfo VName -> TermTypeM Exp) -> UncheckedLoop -> SrcLoc -> TermTypeM (CheckedLoop, AppRes)

-- | Resolve names.
--   
--   This also performs a small amount of rewriting; specifically turning
--   Vars with qualified names into Projects, based on
--   whether they are referencing a module or not.
--   
--   Also checks for other name-related problems, such as duplicate names.
module Language.Futhark.TypeChecker.Names

-- | Resolve names in a value binding. If this succeeds, then it is
--   guaranteed that all names references things that are in scope.
resolveValBind :: ValBindBase NoInfo Name -> TypeM (ValBindBase NoInfo VName)

-- | resolveTypeParams ps m resolves the type parameters
--   ps, then invokes the continuation m with the
--   resolveed parameters, while extending the monadic name map with
--   ps.
resolveTypeParams :: [TypeParamBase Name] -> ([TypeParamBase VName] -> TypeM a) -> TypeM a

-- | Resolve names in a single type expression.
resolveTypeExp :: TypeExp (ExpBase NoInfo Name) Name -> TypeM (TypeExp (ExpBase NoInfo VName) VName)

-- | Resolve names in a single expression.
resolveExp :: ExpBase NoInfo Name -> TypeM (ExpBase NoInfo VName)

-- | 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 -> Loc -> 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 :: Loc -> FunModType -> MTy -> TypeM (MTy, Map VName VName, Map VName VName)

-- | Check that a value definition does not violate any consumption
--   constraints.
module Language.Futhark.TypeChecker.Consumption

-- | Type-check a value definition. This also infers a new return type that
--   may be more unique than previously.
checkValDef :: (VName, [Pat ParamType], Exp, ResRetType, Maybe (TypeExp Exp VName), SrcLoc) -> ((Exp, ResRetType), [TypeError])
instance GHC.Show.Show Language.Futhark.TypeChecker.Consumption.Alias
instance GHC.Classes.Ord Language.Futhark.TypeChecker.Consumption.Alias
instance GHC.Classes.Eq Language.Futhark.TypeChecker.Consumption.Alias
instance GHC.Show.Show a => GHC.Show.Show (Language.Futhark.TypeChecker.Consumption.Entry a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Language.Futhark.TypeChecker.Consumption.Entry a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.Futhark.TypeChecker.Consumption.Entry a)
instance Control.Monad.State.Class.MonadState Language.Futhark.TypeChecker.Consumption.CheckState Language.Futhark.TypeChecker.Consumption.CheckM
instance Control.Monad.Reader.Class.MonadReader Language.Futhark.TypeChecker.Consumption.CheckEnv Language.Futhark.TypeChecker.Consumption.CheckM
instance GHC.Base.Monad Language.Futhark.TypeChecker.Consumption.CheckM
instance GHC.Base.Applicative Language.Futhark.TypeChecker.Consumption.CheckM
instance GHC.Base.Functor Language.Futhark.TypeChecker.Consumption.CheckM
instance GHC.Base.Functor Language.Futhark.TypeChecker.Consumption.Entry
instance Prettyprinter.Internal.Pretty Language.Futhark.TypeChecker.Consumption.Alias
instance Prettyprinter.Internal.Pretty (Data.Set.Internal.Set Language.Futhark.TypeChecker.Consumption.Alias)

-- | 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 :: ExpBase NoInfo VName -> TypeM ([TypeParam], Exp)

-- | Type-check a single size expression in isolation. This expression may
--   turn out to be polymorphic, in which case it is unified with i64.
checkSizeExp :: ExpBase NoInfo VName -> TypeM 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 :: (VName, Maybe (TypeExp (ExpBase NoInfo VName) VName), [TypeParam], [PatBase NoInfo VName ParamType], ExpBase NoInfo VName, SrcLoc) -> TypeM ([TypeParam], [Pat ParamType], Maybe (TypeExp Exp VName), ResRetType, Exp)
instance GHC.Show.Show p => GHC.Show.Show (Language.Futhark.TypeChecker.Terms.Unmatched p)
instance GHC.Base.Functor Language.Futhark.TypeChecker.Terms.Unmatched
instance Prettyprinter.Internal.Pretty (Language.Futhark.TypeChecker.Terms.Unmatched (Language.Futhark.Prop.Pat Language.Futhark.Syntax.StructType))

-- | 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
--   checked results. The ImportName 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))

-- | A collection of extra information regarding a type error.
data Notes

-- | Information about an error during type checking.
data TypeError
TypeError :: Loc -> Notes -> Doc () -> TypeError

-- | Prettyprint type error.
prettyTypeError :: TypeError -> Doc AnsiStyle

-- | Prettyprint type error, without location information. This can be used
--   for cases where the location is printed in some other way.
prettyTypeErrorNoLoc :: TypeError -> Doc AnsiStyle

-- | 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

-- | Produce an environment, based on the one passed in, where all of the
--   provided imports have been openened in order. This could in
--   principle also be done with checkDec, but this is more precise.
envWithImports :: Imports -> Env -> Env

-- | Low-level compilation parts. Look at Futhark.Compiler for a
--   more high-level API.
module Futhark.Compiler.Program

-- | Read and type-check some Futhark files.
readLibrary :: [Name] -> [FilePath] -> IO (Either (NonEmpty ProgError) (Warnings, Imports, VNameSource))

-- | Read (and parse) all source files (including the builtin prelude)
--   corresponding to a set of root files.
readUntypedLibrary :: [FilePath] -> IO (Either (NonEmpty ProgError) [(ImportName, UncheckedProg)])

-- | A mapping from import names to imports. The ordering is significant.
type Imports = [(ImportName, FileModule)]

-- | The result of type checking some file. Can be passed to further
--   invocations of the type checker.
data FileModule
FileModule :: TySet -> Env -> Prog -> Env -> FileModule

-- | Abstract types.
[fileAbs] :: FileModule -> TySet

-- | The environment made available when importing this module.
[fileEnv] :: FileModule -> Env
[fileProg] :: FileModule -> Prog

-- | The environment at the bottom of the file. Includes local parts.
[fileScope] :: FileModule -> Env

-- | The warnings produced by the compiler. The Show instance
--   produces a human-readable description.
data Warnings

-- | Prettyprint warnings, making use of colours and such.
prettyWarnings :: Warnings -> Doc AnsiStyle

-- | Note that the location may be NoLoc. This essentially only
--   happens when the problem is that a root file cannot be found.
data ProgError
ProgError :: Loc -> Doc () -> ProgError

-- | Not actually an error, but we want them reported with errors.
ProgWarning :: Loc -> Doc () -> ProgError

-- | A loaded, type-checked program. This can be used to extract
--   information about the program, but also to speed up subsequent
--   reloads.
data LoadedProg

-- | A "loaded program" containing no actual files. Use this as a starting
--   point for reloadProg
noLoadedProg :: LoadedProg

-- | The Imports of a LoadedProg, as expected by e.g. type
--   checking functions.
lpImports :: LoadedProg -> Imports

-- | All warnings of a LoadedProg.
lpWarnings :: LoadedProg -> Warnings

-- | The absolute paths of the files that are part of this program.
lpFilePaths :: LoadedProg -> [FilePath]

-- | Load some new files, reusing as much of the previously loaded program
--   as possible. This does not *extend* the currently loaded program the
--   way extendProg does it, so it is always correct (if less
--   efficient) to pass noLoadedProg.
reloadProg :: LoadedProg -> [FilePath] -> VFS -> IO (Either (NonEmpty ProgError) LoadedProg)

-- | Extend a loaded program with (possibly new) files.
extendProg :: LoadedProg -> [FilePath] -> VFS -> IO (Either (NonEmpty ProgError) LoadedProg)

-- | A mapping from absolute pathnames to pretty representing a virtual
--   file system. Before loading a file from the file system, this mapping
--   is consulted. If the desired pathname has an entry here, the
--   corresponding pretty is used instead of loading the file from disk.
type VFS = Map FilePath Text
instance GHC.Show.Show fm => GHC.Show.Show (Futhark.Compiler.Program.LoadedFile fm)
instance GHC.Classes.Ord fm => GHC.Classes.Ord (Futhark.Compiler.Program.LoadedFile fm)
instance GHC.Classes.Eq fm => GHC.Classes.Eq (Futhark.Compiler.Program.LoadedFile fm)
instance Data.Loc.Located Futhark.Compiler.Program.ProgError

-- | 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 torep -> FilePath -> FutharkM (Prog torep)

-- | Read a program from the given FilePath, run the given
--   Pipeline, and finish up with the given Action.
runCompilerOnProgram :: FutharkConfig -> Pipeline SOACS rep -> Action rep -> FilePath -> IO ()

-- | 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

-- | Prettyprint program errors as suitable for showing on a text console.
prettyProgErrors :: NonEmpty ProgError -> Doc AnsiStyle

-- | Read and type-check a Futhark program, comprising a single file,
--   including all imports.
readProgramFile :: (MonadError CompilerError m, MonadIO m) => [Name] -> FilePath -> m (Warnings, Imports, VNameSource)

-- | Read and type-check a Futhark library, comprising multiple files,
--   including all imports.
readProgramFiles :: (MonadError CompilerError m, MonadIO m) => [Name] -> [FilePath] -> m (Warnings, Imports, VNameSource)

-- | Not verbose, and terminates process on error.
readProgramOrDie :: MonadIO m => FilePath -> m (Warnings, Imports, VNameSource)

-- | Read and parse (but do not type-check) a Futhark program, including
--   all imports.
readUntypedProgram :: (MonadError CompilerError m, MonadIO m) => FilePath -> m [(String, UncheckedProg)]

-- | Not verbose, and terminates process on error.
readUntypedProgramOrDie :: MonadIO m => FilePath -> m [(String, UncheckedProg)]

-- | 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, in human-readable form.
versionString :: Text

-- | 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]

-- | Terminate the program with this error message (but don't report it as
--   an ICE, as happens with error).
optionsError :: String -> IO ()

-- | 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 rep -> (FutharkConfig -> cfg -> CompilerMode -> FilePath -> Prog rep -> 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
ToServer :: CompilerMode

-- | 
--   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.TestMode
instance GHC.Classes.Eq Futhark.CLI.Test.TestMode
instance GHC.Show.Show Futhark.CLI.Test.ProgConfig
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 profile
--   
module Futhark.CLI.Profile

-- | Run futhark profile.
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 hash
--   
mainHash :: String -> [String] -> IO ()

-- | 
--   futhark dataget
--   
mainDataget :: String -> [String] -> IO ()

-- | 
--   futhark check-syntax
--   
mainCheckSyntax :: String -> [String] -> IO ()

-- | 
--   futhark thanks
--   
mainThanks :: String -> [String] -> IO ()

-- | 
--   futhark tokens
--   
mainTokens :: String -> [String] -> IO ()

-- | 
--   futhark literate
--   
--   
--   Also contains various utility definitions used by
--   Futhark.CLI.Script.
module Futhark.CLI.Literate

-- | Run futhark literate.
main :: String -> [String] -> IO ()

-- | Some of these only make sense for futhark literate, but
--   enough are also sensible for futhark script that we can share
--   them.
data Options
Options :: String -> Maybe FilePath -> [String] -> [String] -> Bool -> Maybe FilePath -> Int -> Bool -> Bool -> [Either FilePath Text] -> Options
[scriptBackend] :: Options -> String
[scriptFuthark] :: Options -> Maybe FilePath
[scriptExtraOptions] :: Options -> [String]
[scriptCompilerOptions] :: Options -> [String]
[scriptSkipCompilation] :: Options -> Bool
[scriptOutput] :: Options -> Maybe FilePath
[scriptVerbose] :: Options -> Int
[scriptStopOnError] :: Options -> Bool
[scriptBinary] :: Options -> Bool
[scriptExps] :: Options -> [Either FilePath Text]

-- | The configuration before any user-provided options are processed.
initialOptions :: Options

-- | Common command line options that transform Options.
scriptCommandLineOptions :: [FunOptDescr Options]

-- | Start up (and eventually shut down) a Futhark server corresponding to
--   the provided program. If the program has a .fut extension, it
--   will be compiled automatically.
prepareServer :: FilePath -> Options -> (ScriptServer -> IO a) -> IO a
instance GHC.Show.Show Futhark.CLI.Literate.ImgParams
instance GHC.Show.Show Futhark.CLI.Literate.VideoParams
instance GHC.Show.Show Futhark.CLI.Literate.AudioParams
instance GHC.Show.Show Futhark.CLI.Literate.Directive
instance GHC.Show.Show Futhark.CLI.Literate.Block
instance Control.Monad.State.Class.MonadState Futhark.CLI.Literate.State Futhark.CLI.Literate.ScriptM
instance Control.Monad.IO.Class.MonadIO Futhark.CLI.Literate.ScriptM
instance Control.Monad.Fail.MonadFail Futhark.CLI.Literate.ScriptM
instance Control.Monad.Error.Class.MonadError Data.Text.Internal.Text Futhark.CLI.Literate.ScriptM
instance GHC.Base.Monad Futhark.CLI.Literate.ScriptM
instance GHC.Base.Applicative Futhark.CLI.Literate.ScriptM
instance GHC.Base.Functor Futhark.CLI.Literate.ScriptM
instance GHC.Show.Show Futhark.CLI.Literate.Failure
instance GHC.Classes.Ord Futhark.CLI.Literate.Failure
instance GHC.Classes.Eq Futhark.CLI.Literate.Failure
instance Prettyprinter.Internal.Pretty Futhark.CLI.Literate.Directive

-- | 
--   futhark script
--   
module Futhark.CLI.Script

-- | Run futhark script.
main :: String -> [String] -> IO ()

-- | 
--   futhark fmt
--   
module Futhark.CLI.Fmt

-- | Run futhark fmt.
main :: String -> [String] -> IO ()

-- | 
--   futhark eval
--   
module Futhark.CLI.Eval

-- | Run futhark eval.
main :: String -> [String] -> IO ()

-- | 
--   futhark defs
--   
module Futhark.CLI.Defs

-- | Run futhark defs.
main :: String -> [String] -> IO ()

-- | 
--   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
instance System.Random.Internal.UniformRange Numeric.Half.Internal.Half

-- | 
--   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 benchcmp
--   
module Futhark.CLI.Benchcmp

-- | Run futhark benchcmp
main :: String -> [String] -> IO ()
instance GHC.Show.Show Futhark.CLI.Benchcmp.SpeedUp

-- | 
--   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 :: [ImportName] -> 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

-- | 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.
printAction :: ASTRep rep => Action rep

-- | Print the result to stdout, alias annotations.
printAliasesAction :: AliasableRep rep => Action rep

-- | Print last use information to stdout.
printLastUseGPU :: Action GPUMem

-- | Print fusion graph to stdout.
printFusionGraph :: Action SOACS

-- | Print interference information to stdout.
printInterferenceGPU :: Action GPUMem

-- | Print memory alias information to stdout
printMemAliasGPU :: Action GPUMem

-- | Print result of array access analysis on the IR
printMemoryAccessAnalysis :: Analyse rep => Action rep

-- | Print call graph to stdout.
callGraphAction :: Action SOACS

-- | 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 GPUMem

-- | Convert the program to CPU multicore ImpCode and print it to stdout.
multicoreImpCodeGenAction :: Action MCMem

-- | Print metrics about AST node counts to stdout.
metricsAction :: OpMetrics (Op rep) => Action rep

-- | The futhark c action.
compileCAction :: FutharkConfig -> CompilerMode -> FilePath -> Action SeqMem

-- | The futhark wasm action.
compileCtoWASMAction :: FutharkConfig -> CompilerMode -> FilePath -> Action SeqMem

-- | The futhark opencl action.
compileOpenCLAction :: FutharkConfig -> CompilerMode -> FilePath -> Action GPUMem

-- | The futhark cuda action.
compileCUDAAction :: FutharkConfig -> CompilerMode -> FilePath -> Action GPUMem

-- | The futhark hip action.
compileHIPAction :: FutharkConfig -> CompilerMode -> FilePath -> Action GPUMem

-- | The futhark multicore action.
compileMulticoreAction :: FutharkConfig -> CompilerMode -> FilePath -> Action MCMem

-- | The futhark ispc action.
compileMulticoreToISPCAction :: FutharkConfig -> CompilerMode -> FilePath -> Action MCMem

-- | The futhark wasm-multicore action.
compileMulticoreToWASMAction :: FutharkConfig -> CompilerMode -> FilePath -> Action MCMem

-- | The futhark python action.
compilePythonAction :: FutharkConfig -> CompilerMode -> FilePath -> Action SeqMem

-- | The futhark pyopencl action.
compilePyOpenCLAction :: FutharkConfig -> CompilerMode -> FilePath -> Action GPUMem

-- | 
--   futhark wasm
--   
module Futhark.CLI.WASM

-- | Run futhark c
main :: String -> [String] -> IO ()

-- | 
--   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 ()

-- | 
--   futhark opencl
--   
module Futhark.CLI.OpenCL

-- | Run futhark opencl
main :: String -> [String] -> IO ()

-- | 
--   futhark wasm-multicore
--   
module Futhark.CLI.MulticoreWASM

-- | Run futhark c
main :: String -> [String] -> IO ()

-- | 
--   futhark multicore
--   
module Futhark.CLI.MulticoreISPC

-- | Run futhark multicore.
main :: String -> [String] -> IO ()

-- | 
--   futhark multicore
--   
module Futhark.CLI.Multicore

-- | Run futhark multicore.
main :: String -> [String] -> IO ()

-- | 
--   futhark hip
--   
module Futhark.CLI.HIP

-- | Run futhark hip.
main :: 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 Prettyprinter.Internal.Pretty Futhark.CLI.Dev.UntypedPassState

-- | 
--   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 ()

-- | The main function for the futhark command line program.
module Futhark.CLI.Main

-- | The futhark executable.
main :: IO ()
