accelerate-llvm-1.3.0.0: src/LLVM/AST/Type/Constant.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_HADDOCK hide #-}
-- |
-- Module : LLVM.AST.Type.Constant
-- Copyright : [2015..2020] The Accelerate Team
-- License : BSD3
--
-- Maintainer : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability : experimental
-- Portability : non-portable (GHC extensions)
--
module LLVM.AST.Type.Constant
where
import LLVM.AST.Type.Downcast
import LLVM.AST.Type.Name
import LLVM.AST.Type.Representation
import qualified LLVM.AST.Constant as LLVM
import qualified LLVM.AST.Float as LLVM
import qualified LLVM.AST.Type as LLVM
import Data.Constraint
import Data.Primitive.ByteArray
import Data.Primitive.Types
import Data.Primitive.Vec
-- | Although constant expressions and instructions have many similarities,
-- there are important differences - so they're represented using different
-- types in this AST. At the cost of making it harder to move an code back and
-- forth between being constant and not, this approach embeds more of the rules
-- of what IR is legal into the Haskell types.
--
-- <http://llvm.org/docs/LangRef.html#constants>
--
-- <http://llvm.org/docs/LangRef.html#constant-expressions>
--
data Constant a where
ScalarConstant :: ScalarType a
-> a
-> Constant a
BooleanConstant :: Bool
-> Constant Bool
UndefConstant :: Type a
-> Constant a
GlobalReference :: Type a
-> Name a
-> Constant a
-- | Convert to llvm-hs
--
instance Downcast (Constant a) LLVM.Constant where
downcast = \case
UndefConstant t -> LLVM.Undef (downcast t)
GlobalReference t n -> LLVM.GlobalReference (downcast t) (downcast n)
BooleanConstant x -> LLVM.Int 1 (toInteger (fromEnum x))
ScalarConstant t x -> scalar t x
where
scalar :: ScalarType s -> s -> LLVM.Constant
scalar (SingleScalarType s) = single s
scalar (VectorScalarType s) = vector s
single :: SingleType s -> s -> LLVM.Constant
single (NumSingleType s) = num s
vector :: VectorType s -> s -> LLVM.Constant
vector (VectorType _ s) (Vec ba#)
= LLVM.Vector
$ map (single s)
$ singlePrim s `withDict` foldrByteArray (:) [] (ByteArray ba#)
num :: NumType s -> s -> LLVM.Constant
num (IntegralNumType s) v
| IntegralDict <- integralDict s
= LLVM.Int (LLVM.typeBits (downcast s)) (fromIntegral v)
num (FloatingNumType s) v
= LLVM.Float
$ case s of
TypeFloat -> LLVM.Single v
TypeDouble -> LLVM.Double v
TypeHalf | Half (CUShort u) <- v -> LLVM.Half u
singlePrim :: SingleType s -> Dict (Prim s)
singlePrim (NumSingleType s) = numPrim s
numPrim :: NumType s -> Dict (Prim s)
numPrim (IntegralNumType s) = integralPrim s
numPrim (FloatingNumType s) = floatingPrim s
integralPrim :: IntegralType s -> Dict (Prim s)
integralPrim TypeInt = Dict
integralPrim TypeInt8 = Dict
integralPrim TypeInt16 = Dict
integralPrim TypeInt32 = Dict
integralPrim TypeInt64 = Dict
integralPrim TypeWord = Dict
integralPrim TypeWord8 = Dict
integralPrim TypeWord16 = Dict
integralPrim TypeWord32 = Dict
integralPrim TypeWord64 = Dict
floatingPrim :: FloatingType s -> Dict (Prim s)
floatingPrim TypeHalf = Dict
floatingPrim TypeFloat = Dict
floatingPrim TypeDouble = Dict
instance TypeOf Constant where
typeOf (BooleanConstant _) = type'
typeOf (ScalarConstant t _) = PrimType (ScalarPrimType t)
typeOf (UndefConstant t) = t
typeOf (GlobalReference t _) = t