hLLVM-0.5.0.0: src/Llvm/Data/Ir.hs
{-# LANGUAGE GADTs #-}
module Llvm.Data.Ir
(module Llvm.Data.Ir
, module Llvm.Data.CoreIr
, module Data.Word
)
where
import Llvm.Data.CoreIr
import qualified Llvm.Data.CoreIr as Ci
import qualified Compiler.Hoopl as H
import qualified Data.Set as S
import Data.Word (Word32)
{- An intermediate representation that is suitable for Hoopl -}
data Toplevel a = ToplevelTriple TlTriple
| ToplevelDataLayout TlDataLayout
| ToplevelAlias TlAlias
| ToplevelDbgInit TlDbgInit
| ToplevelStandaloneMd TlStandaloneMd
| ToplevelNamedMd TlNamedMd
| ToplevelDeclare TlDeclare
| ToplevelDefine (TlDefine a)
| ToplevelGlobal TlGlobal
| ToplevelTypeDef TlTypeDef
| ToplevelDepLibs TlDepLibs
| ToplevelUnamedType TlUnamedType
| ToplevelModuleAsm TlModuleAsm
| ToplevelAttribute TlAttribute
| ToplevelComdat TlComdat
data TlTriple = TlTriple Ci.TargetTriple deriving (Eq)
data TlDataLayout = TlDataLayout Ci.DataLayout deriving (Eq)
data TlAlias = TlAlias { tla_lhs :: Ci.GlobalId
, tla_visibility :: Maybe Ci.Visibility
, tla_dllstorage :: Maybe Ci.DllStorageClass
, tla_tls :: Maybe Ci.ThreadLocalStorage
, tla_addrnaming :: AddrNaming
, tla_linkage :: Maybe Ci.Linkage
, tla_aliasee :: Ci.Aliasee
} deriving (Eq, Ord, Show)
data TlDbgInit = TlDbgInit String Word32 deriving (Eq, Ord, Show)
data TlStandaloneMd = TlStandaloneMd String MetaKindedConst deriving (Eq, Ord, Show)
data TlNamedMd = TlNamedMd Ci.MdVar [Ci.MdNode] deriving (Eq, Ord, Show)
data TlDeclare = TlDeclare Ci.FunctionPrototype deriving (Eq)
type NOOP = ()
data TlDefine a = TlDefine Ci.FunctionPrototype H.Label (H.Graph (Node a) H.C H.C)
data TlGlobal = TlGlobalDtype { tlg_lhs :: (Maybe Ci.GlobalId)
, tlg_linkage :: (Maybe Ci.Linkage)
, tlg_visibility :: (Maybe Ci.Visibility)
, tlg_dllstorage :: (Maybe Ci.DllStorageClass)
, tlg_tls :: (Maybe Ci.ThreadLocalStorage)
, tlg_addrnaming :: AddrNaming
, tlg_addrspace :: (Maybe Ci.AddrSpace)
, tlg_externallyInitialized :: (IsOrIsNot Ci.ExternallyInitialized)
, tlg_globalType :: Ci.GlobalType
, tlg_dtype :: Ci.Dtype
, tlg_const :: (Maybe Ci.Const)
, tlg_section :: (Maybe Ci.Section)
, tlg_comdat :: (Maybe Ci.Comdat)
, tlg_alignment :: (Maybe Ci.Alignment)
}
| TlGlobalOpaque { tlg_lhs :: (Maybe Ci.GlobalId)
, tlg_linkage :: (Maybe Ci.Linkage)
, tlg_visiblity :: (Maybe Ci.Visibility)
, tlg_dllstorage :: (Maybe Ci.DllStorageClass)
, tlg_tls :: (Maybe Ci.ThreadLocalStorage)
, tlg_addrnaming :: AddrNaming
, tlg_addrspace :: (Maybe Ci.AddrSpace)
, tlg_externallyInitialized :: (IsOrIsNot Ci.ExternallyInitialized)
, tlg_globalType :: Ci.GlobalType
, tlg_otype :: (Ci.Type Ci.OpaqueB D)
, tlg_const :: (Maybe Ci.Const)
, tlg_section :: (Maybe Ci.Section)
, tlg_comdat :: (Maybe Ci.Comdat)
, tlg_alignment :: (Maybe Ci.Alignment)
} deriving (Eq, Ord, Show)
data TlTypeDef = TlDatTypeDef Ci.LocalId Ci.Dtype
| TlOpqTypeDef Ci.LocalId (Ci.Type OpaqueB D)
| TlFunTypeDef Ci.LocalId (Ci.Type CodeFunB X) deriving (Eq, Ord, Show)
data TlDepLibs = TlDepLibs [Ci.DqString] deriving (Eq, Ord, Show)
data TlUnamedType = TlUnamedType Word32 Ci.Dtype deriving (Eq, Ord, Show)
data TlModuleAsm = TlModuleAsm Ci.DqString deriving (Eq, Ord, Show)
data TlAttribute = TlAttribute Word32 [FunAttr] deriving (Eq, Ord, Show)
data TlComdat = TlComdat Ci.DollarId Ci.SelectionKind deriving (Eq, Ord, Show)
data Module a = Module [Toplevel a]
-- each instruction represents a node
data Node a e x where
Nlabel :: H.Label -> Node a H.C H.O
Pinst :: Ci.PhiInstWithDbg -> Node a H.O H.O
Cinst :: Ci.CInstWithDbg -> Node a H.O H.O
Comment :: String -> Node a H.O H.O
Tinst :: Ci.TerminatorInstWithDbg -> Node a H.O H.C
Additional :: a -> Node a H.O H.O
instance Show a => Show (Node a e x) where
show x = case x of
Nlabel v -> "Nlabel: Node C O:" ++ show v
Pinst v -> "Pinst : Node O O:" ++ show v
Cinst v -> "Cinst : Node O O:" ++ show v
Tinst v -> "Tinst : Node O C:" ++ show v
Comment s -> "Comment : Node O O:" ++ s
Additional a -> "Additional : Node O O:" ++ show a
instance Eq a => Eq (Node a e x) where
(==) x1 x2 = case (x1, x2) of
(Nlabel l1, Nlabel l2) -> l1 == l2
(Pinst v1, Pinst v2) -> v1 == v2
(Cinst v1, Cinst v2) -> v1 == v2
(Tinst v1, Tinst v2) -> v1 == v2
(Comment v1, Comment v2) -> v1 == v2
(Additional a1, Additional a2) -> a1 == a2
(_, _) -> False
instance (Show a, Ord a) => Ord (Node a e x) where
compare x1 x2 = case (x1, x2) of
(Nlabel l1, Nlabel l2) -> compare l1 l2
(Pinst v1, Pinst v2) -> compare v1 v2
(Cinst v1, Cinst v2) -> compare v1 v2
(Tinst v1, Tinst v2) -> compare v1 v2
(Comment v1, Comment v2) -> compare v1 v2
(Additional v1, Additional v2) -> compare v1 v2
(_, _) -> compare (show x1) (show x2)
instance H.NonLocal (Node a) where
entryLabel (Nlabel l) = l
successors (Tinst (Ci.TerminatorInstWithDbg inst _)) = suc inst
where
suc (Ci.Unreachable) = []
suc (Ci.Return _) = []
suc (Ci.RetVoid) = []
suc (Ci.Br l) = [l]
suc (Ci.Cbr _ l1 l2) = [l1, l2]
suc (Ci.IndirectBr _ ls) = ls
suc (Ci.Switch _ d ls) = (d):(map snd ls)
suc (Ci.Invoke _ l1 l2 _) = [l1, l2]
suc (Ci.InvokeCmd _ l1 l2) = [l1, l2]
suc (Ci.Resume _) = error "what is resume"
suc (Ci.Unwind) = error "what is unwind"
globalIdOfModule :: (Module a) -> S.Set (Ci.Dtype, Ci.GlobalId) -- this should be a map, globalid might have an opaque type
globalIdOfModule (Module tl) = foldl (\a b -> S.union a (globalIdOf b)) S.empty tl
where globalIdOf (ToplevelGlobal (TlGlobalDtype lhs _ _ _ _ _ _ _ _ t _ _ _ _)) =
maybe S.empty (\x -> S.singleton (t, x)) lhs
globalIdOf _ = S.empty