-- |
-- Module      : Data.Array.Accelerate.LLVM.Native.Target
-- Copyright   : [2014..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--

module Data.Array.Accelerate.LLVM.Native.Target (

  module Data.Array.Accelerate.LLVM.Target,
  module Data.Array.Accelerate.LLVM.Native.Target

) where

-- llvm-hs
import LLVM.Target                                                  hiding ( Target )
import LLVM.AST.DataLayout                                          ( DataLayout )
import qualified LLVM.Relocation                                    as RelocationModel
import qualified LLVM.CodeModel                                     as CodeModel
import qualified LLVM.CodeGenOpt                                    as CodeOptimisation

-- accelerate
import Data.Array.Accelerate.LLVM.Native.Link.Cache                 ( LinkCache )
import Data.Array.Accelerate.LLVM.Native.Execute.Scheduler          ( Workers )
import Data.Array.Accelerate.LLVM.Target                            ( Target(..) )

-- standard library
import Data.ByteString                                              ( ByteString )
import Data.ByteString.Short                                        ( ShortByteString )
import System.IO.Unsafe


-- | Native machine code JIT execution target
--
data Native = Native
  { Native -> LinkCache
linkCache     :: !LinkCache
  , Native -> Workers
workers       :: !Workers
  }

instance Target Native where
  targetTriple :: Maybe ShortByteString
targetTriple     = ShortByteString -> Maybe ShortByteString
forall a. a -> Maybe a
Just ShortByteString
nativeTargetTriple
  targetDataLayout :: Maybe DataLayout
targetDataLayout = DataLayout -> Maybe DataLayout
forall a. a -> Maybe a
Just DataLayout
nativeDataLayout


-- | String that describes the native target
--
{-# NOINLINE nativeTargetTriple #-}
nativeTargetTriple :: ShortByteString
nativeTargetTriple :: ShortByteString
nativeTargetTriple = IO ShortByteString -> ShortByteString
forall a. IO a -> a
unsafePerformIO (IO ShortByteString -> ShortByteString)
-> IO ShortByteString -> ShortByteString
forall a b. (a -> b) -> a -> b
$
    -- A target triple suitable for loading code into the current process
    IO ShortByteString
getProcessTargetTriple

-- | A description of the various data layout properties that may be used during
-- optimisation.
--
{-# NOINLINE nativeDataLayout #-}
nativeDataLayout :: DataLayout
nativeDataLayout :: DataLayout
nativeDataLayout
  = IO DataLayout -> DataLayout
forall a. IO a -> a
unsafePerformIO
  (IO DataLayout -> DataLayout) -> IO DataLayout -> DataLayout
forall a b. (a -> b) -> a -> b
$ (TargetMachine -> IO DataLayout) -> IO DataLayout
forall a. (TargetMachine -> IO a) -> IO a
withNativeTargetMachine TargetMachine -> IO DataLayout
getTargetMachineDataLayout

-- | String that describes the host CPU
--
{-# NOINLINE nativeCPUName #-}
nativeCPUName :: ByteString
nativeCPUName :: ByteString
nativeCPUName = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ IO ByteString
getHostCPUName


-- | Bracket the creation and destruction of a target machine for the native
-- backend running on this host.
--
withNativeTargetMachine
    :: (TargetMachine -> IO a)
    -> IO a
withNativeTargetMachine :: (TargetMachine -> IO a) -> IO a
withNativeTargetMachine TargetMachine -> IO a
k = do
  IO ()
initializeNativeTarget
  Map CPUFeature Bool
nativeCPUFeatures <- IO (Map CPUFeature Bool)
getHostCPUFeatures
  (Target
nativeTarget, ShortByteString
_) <- Maybe ShortByteString
-> ShortByteString -> IO (Target, ShortByteString)
lookupTarget Maybe ShortByteString
forall a. Maybe a
Nothing ShortByteString
nativeTargetTriple
  (TargetOptions -> IO a) -> IO a
forall a. (TargetOptions -> IO a) -> IO a
withTargetOptions ((TargetOptions -> IO a) -> IO a)
-> (TargetOptions -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \TargetOptions
targetOptions ->
    Target
-> ShortByteString
-> ByteString
-> Map CPUFeature Bool
-> TargetOptions
-> Model
-> Model
-> Level
-> (TargetMachine -> IO a)
-> IO a
forall a.
Target
-> ShortByteString
-> ByteString
-> Map CPUFeature Bool
-> TargetOptions
-> Model
-> Model
-> Level
-> (TargetMachine -> IO a)
-> IO a
withTargetMachine
        Target
nativeTarget
        ShortByteString
nativeTargetTriple
        ByteString
nativeCPUName
        Map CPUFeature Bool
nativeCPUFeatures
        TargetOptions
targetOptions
        Model
RelocationModel.PIC
        Model
CodeModel.Default
        Level
CodeOptimisation.Default
        TargetMachine -> IO a
k