{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# OPTIONS_HADDOCK hide, prune, not-home #-}

module MLIR.AST.Dialect.Generated.Func where

import Prelude (Int, Double, Maybe(..), Bool(..), (++), (<$>), ($), (<>), Show)
import qualified Prelude
import Data.Int (Int64)
import qualified Data.Maybe
import Data.Array (Ix)
import qualified Data.Array.IArray as IArray
import qualified Data.ByteString as BS
import qualified Data.Map.Strict as M
import qualified Control.Monad

import MLIR.AST ( Attribute(..), Type(..), AbstractOperation(..), ResultTypes(..)
                , Location(..), Signedness(..), DenseElements(..)
                , NamedAttributes, Name
                , pattern NoAttrs )
import qualified MLIR.AST as AST
import MLIR.AST.Builder (Value, EndOfBlock, MonadBlockBuilder, RegionBuilderT)
import qualified MLIR.AST.Builder as AST
import qualified MLIR.AST.IStorableArray as AST
import qualified MLIR.AST.PatternUtil as PatternUtil
import qualified MLIR.AST.Dialect.Affine as Affine

-- * call_indirect
-- $call_indirect
-- 
-- The @func.call_indirect@ operation represents an indirect call to a value
-- of function type. The operands and result types of the call must match the
-- specified function type.
-- 
-- Function values can be created with the
-- @func.constant@ operation.
-- 
-- Example:
-- 
-- @
-- %func = func.constant \@my_func : (tensor\<16xf32>, tensor\<16xf32>) -> tensor\<16xf32>
-- %result = func.call_indirect %func(%0, %1) : (tensor\<16xf32>, tensor\<16xf32>) -> tensor\<16xf32>
-- @
--   

-- | A builder for @func.call_indirect@.
call_indirect :: () => MonadBlockBuilder m => [Type] -> Value -> [Value] -> m Value
call_indirect :: [Type] -> Value -> [Value] -> m Value
call_indirect [Type]
ty0 Value
callee_ [Value]
callee_operands_   = do
  ([Value] -> Value) -> m [Value] -> m Value
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
Control.Monad.liftM [Value] -> Value
forall a. [a] -> a
Prelude.head (Operation -> m [Value]
forall (m :: * -> *). MonadBlockBuilder m => Operation -> m [Value]
AST.emitOp (Operation :: forall operand.
Name
-> Location
-> ResultTypes
-> [operand]
-> [Region]
-> [Name]
-> Map Name Attribute
-> AbstractOperation operand
Operation
          { opName :: Name
opName = Name
"func.call_indirect"
          , opLocation :: Location
opLocation = Location
UnknownLocation
          , opResultTypes :: ResultTypes
opResultTypes = [Type] -> ResultTypes
Explicit ([Type]
ty0)
          , opOperands :: [Name]
opOperands = ([(Value -> Name
AST.operand Value
callee_)] [Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
++ ([Value] -> [Name]
AST.operands [Value]
callee_operands_))
          , opRegions :: [Region]
opRegions = []
          , opSuccessors :: [Name]
opSuccessors = []
          , opAttributes :: Map Name Attribute
opAttributes = (Map Name Attribute
NoAttrs)
          }))

-- * call
-- $call
-- 
-- The @func.call@ operation represents a direct call to a function that is
-- within the same symbol scope as the call. The operands and result types of
-- the call must match the specified function type. The callee is encoded as a
-- symbol reference attribute named \"callee\".
-- 
-- Example:
-- 
-- @
-- %2 = func.call \@my_add(%0, %1) : (f32, f32) -> f32
-- @
--   

-- * constant
-- $constant
-- 
-- The @func.constant@ operation produces an SSA value from a symbol reference
-- to a @func.func@ operation
-- 
-- Example:
-- 
-- @
-- // Reference to function \@myfn.
-- %2 = func.constant \@myfn : (tensor\<16xf32>, f32) -> tensor\<16xf32>
-- 
-- // Equivalent generic forms
-- %2 = \"func.constant\"() { value = \@myfn } : () -> ((tensor\<16xf32>, f32) -> tensor\<16xf32>)
-- @
-- 
-- MLIR does not allow direct references to functions in SSA operands because
-- the compiler is multithreaded, and disallowing SSA values to directly
-- reference a function simplifies this
-- (rationale.
--   

-- * func
-- $func
-- 
-- Operations within the function cannot implicitly capture values defined
-- outside of the function, i.e. Functions are @IsolatedFromAbove@. All
-- external references must use function arguments or attributes that establish
-- a symbolic connection (e.g. symbols referenced by name via a string
-- attribute like SymbolRefAttr). An external function declaration (used when
-- referring to a function declared in some other module) has no body. While
-- the MLIR textual form provides a nice inline syntax for function arguments,
-- they are internally represented as “block arguments” to the first block in
-- the region.
-- 
-- Only dialect attribute names may be specified in the attribute dictionaries
-- for function arguments, results, or the function itself.
-- 
-- Example:
-- 
-- @
-- // External function definitions.
-- func.func private \@abort()
-- func.func private \@scribble(i32, i64, memref\<? x 128 x f32, \#layout_map0>) -> f64
-- 
-- // A function that returns its argument twice:
-- func.func \@count(%x: i64) -> (i64, i64)
--   attributes {fruit = \"banana\"} {
--   return %x, %x: i64, i64
-- }
-- 
-- // A function with an argument attribute
-- func.func private \@example_fn_arg(%x: i32 {swift.self = unit})
-- 
-- // A function with a result attribute
-- func.func private \@example_fn_result() -> (f64 {dialectName.attrName = 0 : i64})
-- 
-- // A function with an attribute
-- func.func private \@example_fn_attr() attributes {dialectName.attrName = false}
-- @
--   

-- * return
-- $return
-- 
-- The @func.return@ operation represents a return operation within a function.
-- The operation takes variable number of operands and produces no results.
-- The operand number and types must match the signature of the function
-- that contains the operation.
-- 
-- Example:
-- 
-- @
-- func.func \@foo() -> (i32, f8) {
--   ...
--   return %0, %1 : i32, f8
-- }
-- @
--   

-- | A pattern for @func.return@.
pattern Return :: () => () => Location -> [operand] -> AbstractOperation operand
pattern $bReturn :: Location -> [operand] -> AbstractOperation operand
$mReturn :: forall r operand.
AbstractOperation operand
-> (Location -> [operand] -> r) -> (Void# -> r) -> r
Return loc  operands_  = Operation
          { opName = "func.return"
          , opLocation = loc
          , opResultTypes = Explicit []
          , opOperands = operands_
          , opRegions = []
          , opSuccessors = []
          , opAttributes = (NoAttrs)
          }

-- | A builder for @func.return@.
return :: () => MonadBlockBuilder m => [Value] -> m EndOfBlock
return :: [Value] -> m EndOfBlock
return  [Value]
operands_   = do
  m [Value] -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
Control.Monad.void (Operation -> m [Value]
forall (m :: * -> *). MonadBlockBuilder m => Operation -> m [Value]
AST.emitOp (Operation :: forall operand.
Name
-> Location
-> ResultTypes
-> [operand]
-> [Region]
-> [Name]
-> Map Name Attribute
-> AbstractOperation operand
Operation
          { opName :: Name
opName = Name
"func.return"
          , opLocation :: Location
opLocation = Location
UnknownLocation
          , opResultTypes :: ResultTypes
opResultTypes = [Type] -> ResultTypes
Explicit []
          , opOperands :: [Name]
opOperands = ([Value] -> [Name]
AST.operands [Value]
operands_)
          , opRegions :: [Region]
opRegions = []
          , opSuccessors :: [Name]
opSuccessors = []
          , opAttributes :: Map Name Attribute
opAttributes = (Map Name Attribute
NoAttrs)
          }))
  m EndOfBlock
forall (m :: * -> *). Monad m => m EndOfBlock
AST.terminateBlock