packages feed

llvm-hs-pure 5.1.0 → 5.1.1

raw patch · 10 files changed

+1095/−2 lines, 10 filesdep +faildep +hspecdep +textdep ~basedep ~bytestringdep ~containersPVP ok

version bump matches the API change (PVP)

Dependencies added: fail, hspec, text, unordered-containers

Dependency ranges changed: base, bytestring, containers, mtl, transformers

API changes (from Hackage documentation)

+ LLVM.AST.Typed: class Typed a
+ LLVM.AST.Typed: extractValueType :: [Word32] -> Type -> Type
+ LLVM.AST.Typed: getElementPtrType :: Type -> [Constant] -> Type
+ LLVM.AST.Typed: getElementType :: Type -> Type
+ LLVM.AST.Typed: instance LLVM.AST.Typed.Typed LLVM.AST.Constant.Constant
+ LLVM.AST.Typed: instance LLVM.AST.Typed.Typed LLVM.AST.Float.SomeFloat
+ LLVM.AST.Typed: instance LLVM.AST.Typed.Typed LLVM.AST.Global.Global
+ LLVM.AST.Typed: instance LLVM.AST.Typed.Typed LLVM.AST.Global.Parameter
+ LLVM.AST.Typed: instance LLVM.AST.Typed.Typed LLVM.AST.Operand.CallableOperand
+ LLVM.AST.Typed: instance LLVM.AST.Typed.Typed LLVM.AST.Operand.Operand
+ LLVM.AST.Typed: typeOf :: Typed a => a -> Type
+ LLVM.IRBuilder.Constant: array :: Applicative f => [Constant] -> f Operand
+ LLVM.IRBuilder.Constant: bit :: Applicative f => Integer -> f Operand
+ LLVM.IRBuilder.Constant: double :: Applicative f => Double -> f Operand
+ LLVM.IRBuilder.Constant: half :: Applicative f => Word16 -> f Operand
+ LLVM.IRBuilder.Constant: int32 :: Applicative f => Integer -> f Operand
+ LLVM.IRBuilder.Constant: int64 :: Applicative f => Integer -> f Operand
+ LLVM.IRBuilder.Constant: single :: Applicative f => Float -> f Operand
+ LLVM.IRBuilder.Constant: struct :: Applicative f => Maybe Name -> Bool -> [Constant] -> f Operand
+ LLVM.IRBuilder.Instruction: add :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: alloca :: MonadIRBuilder m => Type -> Maybe Operand -> Word32 -> m Operand
+ LLVM.IRBuilder.Instruction: and :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: ashr :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: bitcast :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Instruction: br :: MonadIRBuilder m => Name -> m ()
+ LLVM.IRBuilder.Instruction: call :: MonadIRBuilder m => Operand -> [(Operand, [ParameterAttribute])] -> m Operand
+ LLVM.IRBuilder.Instruction: condBr :: MonadIRBuilder m => Operand -> Name -> Name -> m ()
+ LLVM.IRBuilder.Instruction: fadd :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: fcmp :: MonadIRBuilder m => FloatingPointPredicate -> Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: fdiv :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: fmul :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: fptosi :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Instruction: fptoui :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Instruction: frem :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: fsub :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: gep :: MonadIRBuilder m => Operand -> [Operand] -> m Operand
+ LLVM.IRBuilder.Instruction: icmp :: MonadIRBuilder m => IntegerPredicate -> Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: inttoptr :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Instruction: load :: MonadIRBuilder m => Operand -> Word32 -> m Operand
+ LLVM.IRBuilder.Instruction: lshr :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: mul :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: or :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: phi :: MonadIRBuilder m => [(Operand, Name)] -> m Operand
+ LLVM.IRBuilder.Instruction: ptrtoint :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Instruction: ret :: MonadIRBuilder m => Operand -> m ()
+ LLVM.IRBuilder.Instruction: retVoid :: MonadIRBuilder m => m ()
+ LLVM.IRBuilder.Instruction: sdiv :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: select :: MonadIRBuilder m => Operand -> Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: sext :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Instruction: shl :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: sitofp :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Instruction: store :: MonadIRBuilder m => Operand -> Word32 -> Operand -> m ()
+ LLVM.IRBuilder.Instruction: sub :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: switch :: MonadIRBuilder m => Operand -> Name -> [(Constant, Name)] -> m ()
+ LLVM.IRBuilder.Instruction: trunc :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Instruction: udiv :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: uitofp :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Instruction: unreachable :: MonadIRBuilder m => m ()
+ LLVM.IRBuilder.Instruction: urem :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: xor :: MonadIRBuilder m => Operand -> Operand -> m Operand
+ LLVM.IRBuilder.Instruction: zext :: MonadIRBuilder m => Operand -> Type -> m Operand
+ LLVM.IRBuilder.Internal.SnocList: SnocList :: [a] -> SnocList a
+ LLVM.IRBuilder.Internal.SnocList: [unSnocList] :: SnocList a -> [a]
+ LLVM.IRBuilder.Internal.SnocList: getSnocList :: SnocList a -> [a]
+ LLVM.IRBuilder.Internal.SnocList: instance GHC.Base.Monoid (LLVM.IRBuilder.Internal.SnocList.SnocList a)
+ LLVM.IRBuilder.Internal.SnocList: instance GHC.Classes.Eq a => GHC.Classes.Eq (LLVM.IRBuilder.Internal.SnocList.SnocList a)
+ LLVM.IRBuilder.Internal.SnocList: instance GHC.Show.Show a => GHC.Show.Show (LLVM.IRBuilder.Internal.SnocList.SnocList a)
+ LLVM.IRBuilder.Internal.SnocList: newtype SnocList a
+ LLVM.IRBuilder.Internal.SnocList: snoc :: SnocList a -> a -> SnocList a
+ LLVM.IRBuilder.Module: ModuleBuilderState :: SnocList Definition -> ModuleBuilderState
+ LLVM.IRBuilder.Module: ModuleBuilderT :: StateT ModuleBuilderState m a -> ModuleBuilderT m a
+ LLVM.IRBuilder.Module: NoParameterName :: ParameterName
+ LLVM.IRBuilder.Module: ParameterName :: ShortByteString -> ParameterName
+ LLVM.IRBuilder.Module: [builderDefs] :: ModuleBuilderState -> SnocList Definition
+ LLVM.IRBuilder.Module: [unModuleBuilderT] :: ModuleBuilderT m a -> StateT ModuleBuilderState m a
+ LLVM.IRBuilder.Module: buildModule :: ShortByteString -> ModuleBuilder a -> Module
+ LLVM.IRBuilder.Module: buildModuleT :: Monad m => ShortByteString -> ModuleBuilderT m a -> m Module
+ LLVM.IRBuilder.Module: class Monad m => MonadModuleBuilder m
+ LLVM.IRBuilder.Module: data ParameterName
+ LLVM.IRBuilder.Module: emitDefn :: MonadModuleBuilder m => Definition -> m ()
+ LLVM.IRBuilder.Module: emptyModuleBuilder :: ModuleBuilderState
+ LLVM.IRBuilder.Module: execModuleBuilder :: ModuleBuilderState -> ModuleBuilder a -> [Definition]
+ LLVM.IRBuilder.Module: execModuleBuilderT :: Monad m => ModuleBuilderState -> ModuleBuilderT m a -> m [Definition]
+ LLVM.IRBuilder.Module: extern :: MonadModuleBuilder m => Name -> [Type] -> Type -> m Operand
+ LLVM.IRBuilder.Module: function :: MonadModuleBuilder m => Name -> [(Type, ParameterName)] -> Type -> ([Operand] -> IRBuilderT m ()) -> m Operand
+ LLVM.IRBuilder.Module: instance (GHC.Base.Monoid w, LLVM.IRBuilder.Module.MonadModuleBuilder m) => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.Writer.Lazy.WriterT w m)
+ LLVM.IRBuilder.Module: instance (GHC.Base.Monoid w, LLVM.IRBuilder.Module.MonadModuleBuilder m) => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.Writer.Strict.WriterT w m)
+ LLVM.IRBuilder.Module: instance (LLVM.IRBuilder.Module.MonadModuleBuilder m, GHC.Base.Monoid w) => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
+ LLVM.IRBuilder.Module: instance (LLVM.IRBuilder.Module.MonadModuleBuilder m, GHC.Base.Monoid w) => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.RWS.Strict.RWST r w s m)
+ LLVM.IRBuilder.Module: instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance Control.Monad.Trans.Class.MonadTrans LLVM.IRBuilder.Module.ModuleBuilderT
+ LLVM.IRBuilder.Module: instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance Data.Data.Data LLVM.IRBuilder.Module.ParameterName
+ LLVM.IRBuilder.Module: instance Data.String.IsString LLVM.IRBuilder.Module.ParameterName
+ LLVM.IRBuilder.Module: instance GHC.Base.Functor m => GHC.Base.Functor (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance GHC.Base.Monad m => GHC.Base.Applicative (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance GHC.Base.Monad m => GHC.Base.Monad (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance GHC.Base.Monad m => LLVM.IRBuilder.Module.MonadModuleBuilder (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance GHC.Base.MonadPlus m => GHC.Base.Alternative (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (LLVM.IRBuilder.Module.ModuleBuilderT m)
+ LLVM.IRBuilder.Module: instance GHC.Classes.Eq LLVM.IRBuilder.Module.ParameterName
+ LLVM.IRBuilder.Module: instance GHC.Classes.Ord LLVM.IRBuilder.Module.ParameterName
+ LLVM.IRBuilder.Module: instance GHC.Generics.Generic LLVM.IRBuilder.Module.ParameterName
+ LLVM.IRBuilder.Module: instance GHC.Read.Read LLVM.IRBuilder.Module.ParameterName
+ LLVM.IRBuilder.Module: instance GHC.Show.Show LLVM.IRBuilder.Module.ParameterName
+ LLVM.IRBuilder.Module: instance LLVM.IRBuilder.Module.MonadModuleBuilder m => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.Cont.ContT r m)
+ LLVM.IRBuilder.Module: instance LLVM.IRBuilder.Module.MonadModuleBuilder m => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.Except.ExceptT e m)
+ LLVM.IRBuilder.Module: instance LLVM.IRBuilder.Module.MonadModuleBuilder m => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.Identity.IdentityT m)
+ LLVM.IRBuilder.Module: instance LLVM.IRBuilder.Module.MonadModuleBuilder m => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.List.ListT m)
+ LLVM.IRBuilder.Module: instance LLVM.IRBuilder.Module.MonadModuleBuilder m => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.Maybe.MaybeT m)
+ LLVM.IRBuilder.Module: instance LLVM.IRBuilder.Module.MonadModuleBuilder m => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.Reader.ReaderT r m)
+ LLVM.IRBuilder.Module: instance LLVM.IRBuilder.Module.MonadModuleBuilder m => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.State.Lazy.StateT s m)
+ LLVM.IRBuilder.Module: instance LLVM.IRBuilder.Module.MonadModuleBuilder m => LLVM.IRBuilder.Module.MonadModuleBuilder (Control.Monad.Trans.State.Strict.StateT s m)
+ LLVM.IRBuilder.Module: liftModuleState :: (MonadModuleBuilder m, MonadTrans t, MonadModuleBuilder m1, m ~ t m1) => State ModuleBuilderState a -> m a
+ LLVM.IRBuilder.Module: newtype ModuleBuilderState
+ LLVM.IRBuilder.Module: newtype ModuleBuilderT m a
+ LLVM.IRBuilder.Module: runModuleBuilder :: ModuleBuilderState -> ModuleBuilder a -> (a, [Definition])
+ LLVM.IRBuilder.Module: runModuleBuilderT :: Monad m => ModuleBuilderState -> ModuleBuilderT m a -> m (a, [Definition])
+ LLVM.IRBuilder.Module: type ModuleBuilder = ModuleBuilderT Identity
+ LLVM.IRBuilder.Module: typedef :: MonadModuleBuilder m => Name -> Maybe Type -> m ()
+ LLVM.IRBuilder.Monad: IRBuilderState :: !Word -> !(HashSet ShortByteString) -> !(Maybe ShortByteString) -> SnocList BasicBlock -> !(Maybe PartialBlock) -> IRBuilderState
+ LLVM.IRBuilder.Monad: IRBuilderT :: StateT IRBuilderState m a -> IRBuilderT m a
+ LLVM.IRBuilder.Monad: PartialBlock :: !Name -> SnocList (Named Instruction) -> Maybe (Named Terminator) -> PartialBlock
+ LLVM.IRBuilder.Monad: [builderBlock] :: IRBuilderState -> !(Maybe PartialBlock)
+ LLVM.IRBuilder.Monad: [builderBlocks] :: IRBuilderState -> SnocList BasicBlock
+ LLVM.IRBuilder.Monad: [builderNameSuggestion] :: IRBuilderState -> !(Maybe ShortByteString)
+ LLVM.IRBuilder.Monad: [builderSupply] :: IRBuilderState -> !Word
+ LLVM.IRBuilder.Monad: [builderUsedNames] :: IRBuilderState -> !(HashSet ShortByteString)
+ LLVM.IRBuilder.Monad: [partialBlockInstrs] :: PartialBlock -> SnocList (Named Instruction)
+ LLVM.IRBuilder.Monad: [partialBlockName] :: PartialBlock -> !Name
+ LLVM.IRBuilder.Monad: [partialBlockTerm] :: PartialBlock -> Maybe (Named Terminator)
+ LLVM.IRBuilder.Monad: [unIRBuilderT] :: IRBuilderT m a -> StateT IRBuilderState m a
+ LLVM.IRBuilder.Monad: block :: MonadIRBuilder m => m Name
+ LLVM.IRBuilder.Monad: class Monad m => MonadIRBuilder m
+ LLVM.IRBuilder.Monad: data IRBuilderState
+ LLVM.IRBuilder.Monad: data PartialBlock
+ LLVM.IRBuilder.Monad: emitBlockStart :: MonadIRBuilder m => Name -> m ()
+ LLVM.IRBuilder.Monad: emitInstr :: MonadIRBuilder m => Type -> Instruction -> m Operand
+ LLVM.IRBuilder.Monad: emitInstrVoid :: MonadIRBuilder m => Instruction -> m ()
+ LLVM.IRBuilder.Monad: emitTerm :: MonadIRBuilder m => Terminator -> m ()
+ LLVM.IRBuilder.Monad: emptyIRBuilder :: IRBuilderState
+ LLVM.IRBuilder.Monad: emptyPartialBlock :: Name -> PartialBlock
+ LLVM.IRBuilder.Monad: execIRBuilder :: IRBuilderState -> IRBuilder a -> [BasicBlock]
+ LLVM.IRBuilder.Monad: execIRBuilderT :: Monad m => IRBuilderState -> IRBuilderT m a -> m [BasicBlock]
+ LLVM.IRBuilder.Monad: fresh :: MonadIRBuilder m => m Name
+ LLVM.IRBuilder.Monad: freshName :: MonadIRBuilder m => ShortByteString -> m Name
+ LLVM.IRBuilder.Monad: freshUnName :: MonadIRBuilder m => m Name
+ LLVM.IRBuilder.Monad: instance (GHC.Base.Monoid w, LLVM.IRBuilder.Monad.MonadIRBuilder m) => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.Writer.Lazy.WriterT w m)
+ LLVM.IRBuilder.Monad: instance (GHC.Base.Monoid w, LLVM.IRBuilder.Monad.MonadIRBuilder m) => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.Writer.Strict.WriterT w m)
+ LLVM.IRBuilder.Monad: instance (LLVM.IRBuilder.Monad.MonadIRBuilder m, GHC.Base.Monoid w) => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
+ LLVM.IRBuilder.Monad: instance (LLVM.IRBuilder.Monad.MonadIRBuilder m, GHC.Base.Monoid w) => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.RWS.Strict.RWST r w s m)
+ LLVM.IRBuilder.Monad: instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance Control.Monad.Trans.Class.MonadTrans LLVM.IRBuilder.Monad.IRBuilderT
+ LLVM.IRBuilder.Monad: instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance GHC.Base.Functor m => GHC.Base.Functor (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance GHC.Base.Monad m => GHC.Base.Applicative (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance GHC.Base.Monad m => GHC.Base.Monad (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance GHC.Base.Monad m => LLVM.IRBuilder.Monad.MonadIRBuilder (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance GHC.Base.MonadPlus m => GHC.Base.Alternative (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (LLVM.IRBuilder.Monad.IRBuilderT m)
+ LLVM.IRBuilder.Monad: instance LLVM.IRBuilder.Monad.MonadIRBuilder m => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.Cont.ContT r m)
+ LLVM.IRBuilder.Monad: instance LLVM.IRBuilder.Monad.MonadIRBuilder m => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.Except.ExceptT e m)
+ LLVM.IRBuilder.Monad: instance LLVM.IRBuilder.Monad.MonadIRBuilder m => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.Identity.IdentityT m)
+ LLVM.IRBuilder.Monad: instance LLVM.IRBuilder.Monad.MonadIRBuilder m => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.List.ListT m)
+ LLVM.IRBuilder.Monad: instance LLVM.IRBuilder.Monad.MonadIRBuilder m => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.Maybe.MaybeT m)
+ LLVM.IRBuilder.Monad: instance LLVM.IRBuilder.Monad.MonadIRBuilder m => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.Reader.ReaderT r m)
+ LLVM.IRBuilder.Monad: instance LLVM.IRBuilder.Monad.MonadIRBuilder m => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.State.Lazy.StateT s m)
+ LLVM.IRBuilder.Monad: instance LLVM.IRBuilder.Monad.MonadIRBuilder m => LLVM.IRBuilder.Monad.MonadIRBuilder (Control.Monad.Trans.State.Strict.StateT s m)
+ LLVM.IRBuilder.Monad: liftIRState :: (MonadIRBuilder m, MonadTrans t, MonadIRBuilder m1, m ~ t m1) => State IRBuilderState a -> m a
+ LLVM.IRBuilder.Monad: modifyBlock :: MonadIRBuilder m => (PartialBlock -> PartialBlock) -> m ()
+ LLVM.IRBuilder.Monad: named :: MonadIRBuilder m => m r -> ShortByteString -> m r
+ LLVM.IRBuilder.Monad: newtype IRBuilderT m a
+ LLVM.IRBuilder.Monad: runIRBuilder :: IRBuilderState -> IRBuilder a -> (a, [BasicBlock])
+ LLVM.IRBuilder.Monad: runIRBuilderT :: Monad m => IRBuilderState -> IRBuilderT m a -> m (a, [BasicBlock])
+ LLVM.IRBuilder.Monad: type IRBuilder = IRBuilderT Identity

Files

CHANGELOG.md view
@@ -1,3 +1,10 @@+## 5.1.1 (2017-12-26)++* Add a completely new API for building modules in a monadic style similar to the IRBuilder provided by LLVM’s C++ API. The modules can be found in `LLVM.IRBuilder`. An example can be found in the readme and in the test suite.+* Add an API for getting the type of LLVM values in+  `LLVM.AST.Typed`. This is primarily intended to be used in other+  libraries that build upon `llvm-hs-pure` such as `llvm-hs-pretty`.+ ## 5.1.0 (2017-10-12)  ### Enhancements
llvm-hs-pure.cabal view
@@ -1,5 +1,5 @@ name: llvm-hs-pure-version: 5.1.0+version: 5.1.1 license: BSD3 license-file: LICENSE author: Anthony Cowley, Stephen Diehl, Moritz Kiefer <moritz.kiefer@purelyfunctional.org>, Benjamin S. Scarlet@@ -40,10 +40,12 @@   build-depends:     attoparsec >= 0.13,     bytestring >= 0.10 && < 0.11,+    fail,     transformers >= 0.3 && < 0.6,     mtl >= 2.1,     template-haskell >= 2.5.0.0,-    containers >= 0.4.2.1+    containers >= 0.4.2.1,+    unordered-containers >= 0.2   hs-source-dirs: src   extensions:     NoImplicitPrelude@@ -76,10 +78,17 @@     LLVM.AST.RMWOperation     LLVM.AST.ThreadLocalStorage     LLVM.AST.Type+    LLVM.AST.Typed     LLVM.AST.Visibility     LLVM.AST.DLL     LLVM.AST.COMDAT     LLVM.DataLayout+    LLVM.IRBuilder+    LLVM.IRBuilder.Constant+    LLVM.IRBuilder.Instruction+    LLVM.IRBuilder.Internal.SnocList+    LLVM.IRBuilder.Module+    LLVM.IRBuilder.Monad     LLVM.Prelude  test-suite test@@ -108,3 +117,19 @@   other-modules:     LLVM.Test.DataLayout     LLVM.Test.Tests++test-suite test-irbuilder+  type: exitcode-stdio-1.0+  main-is: IRBuilder.hs+  hs-source-dirs:+      test+  build-depends:+      base >=4.8 && <4.11+    , bytestring+    , containers+    , hspec+    , llvm-hs-pure+    , mtl+    , text+    , transformers+    , unordered-containers
+ src/LLVM/AST/Typed.hs view
@@ -0,0 +1,132 @@+{-# LANGUAGE RecordWildCards #-}++-- | Querying the type of LLVM expressions+module LLVM.AST.Typed (+  Typed(..),+  getElementType,+  getElementPtrType,+  extractValueType,+) where++import LLVM.Prelude++import LLVM.AST+import LLVM.AST.Global+import LLVM.AST.Type++import qualified LLVM.AST.Constant as C+import qualified LLVM.AST.Float as F++class Typed a where+    typeOf :: a -> Type++instance Typed Operand where+  typeOf (LocalReference t _) = t+  typeOf (ConstantOperand c)  = typeOf c+  typeOf _                    = MetadataType++instance Typed CallableOperand where+  typeOf (Right op) = typeOf op+  typeOf (Left _) = error "typeOf inline assembler is not defined. (Malformed AST)"++instance Typed C.Constant where+  typeOf (C.Int bits _)  = IntegerType bits+  typeOf (C.Float t) = typeOf t+  typeOf (C.Null t)      = t+  typeOf (C.Struct {..}) = StructureType isPacked (map typeOf memberValues)+  typeOf (C.Array {..})  = ArrayType (fromIntegral $ length memberValues) memberType+  typeOf (C.Vector {..}) = VectorType (fromIntegral $ length memberValues) $+                              case memberValues of+                                  []    -> error "Vectors of size zero are not allowed. (Malformed AST)"+                                  (x:_) -> typeOf x+  typeOf (C.Undef t)     = t+  typeOf (C.BlockAddress {..})   = ptr i8+  typeOf (C.GlobalReference t _) = t+  typeOf (C.Add {..})     = typeOf operand0+  typeOf (C.FAdd {..})    = typeOf operand0+  typeOf (C.FDiv {..})    = typeOf operand0+  typeOf (C.FRem {..})    = typeOf operand0+  typeOf (C.Sub {..})     = typeOf operand0+  typeOf (C.FSub {..})    = typeOf operand0+  typeOf (C.Mul {..})     = typeOf operand0+  typeOf (C.FMul {..})    = typeOf operand0+  typeOf (C.UDiv {..})    = typeOf operand0+  typeOf (C.SDiv {..})    = typeOf operand0+  typeOf (C.URem {..})    = typeOf operand0+  typeOf (C.SRem {..})    = typeOf operand0+  typeOf (C.Shl {..})     = typeOf operand0+  typeOf (C.LShr {..})    = typeOf operand0+  typeOf (C.AShr {..})    = typeOf operand0+  typeOf (C.And {..})     = typeOf operand0+  typeOf (C.Or  {..})     = typeOf operand0+  typeOf (C.Xor {..})     = typeOf operand0+  typeOf (C.GetElementPtr {..}) = getElementPtrType (typeOf address) indices+  typeOf (C.Trunc {..})   = type'+  typeOf (C.ZExt {..})    = type'+  typeOf (C.SExt {..})    = type'+  typeOf (C.FPToUI {..})  = type'+  typeOf (C.FPToSI {..})  = type'+  typeOf (C.UIToFP {..})  = type'+  typeOf (C.SIToFP {..})  = type'+  typeOf (C.FPTrunc {..}) = type'+  typeOf (C.FPExt {..})   = type'+  typeOf (C.PtrToInt {..}) = type'+  typeOf (C.IntToPtr {..}) = type'+  typeOf (C.BitCast {..})  = type'+  typeOf (C.ICmp {..})    = case (typeOf operand0) of+                              (VectorType n _) -> VectorType n i1+                              _ -> i1+  typeOf (C.FCmp {..})    = case (typeOf operand0) of+                              (VectorType n _) -> VectorType n i1+                              _ -> i1+  typeOf (C.Select {..})  = typeOf trueValue+  typeOf (C.ExtractElement {..})  = case typeOf vector of+                                      (VectorType _ t) -> t+                                      _ -> error "The first operand of an extractelement instruction is a value of vector type. (Malformed AST)"+  typeOf (C.InsertElement {..})   = typeOf vector+  typeOf (C.ShuffleVector {..})   = case (typeOf operand0, typeOf mask) of+                                      (VectorType _ t, VectorType m _) -> VectorType m t+                                      _ -> error "The first operand of an shufflevector instruction is a value of vector type. (Malformed AST)"+  typeOf (C.ExtractValue {..})    = extractValueType indices' (typeOf aggregate)+  typeOf (C.InsertValue {..})     = typeOf aggregate+  typeOf (C.TokenNone)          = TokenType+  typeOf (C.AddrSpaceCast {..}) = type'++getElementPtrType :: Type -> [C.Constant] -> Type+getElementPtrType ty [] = ptr ty+getElementPtrType (PointerType ty _) (_:is) = getElementPtrType ty is+getElementPtrType (StructureType _ elTys) (C.Int 32 val:is) =+  getElementPtrType (elTys !! fromIntegral val) is+getElementPtrType (VectorType _ elTy) (_:is) = getElementPtrType elTy is+getElementPtrType (ArrayType _ elTy) (_:is) = getElementPtrType elTy is+getElementPtrType _ _ = error "Expecting aggregate type. (Malformed AST)"++getElementType :: Type -> Type+getElementType (PointerType t _) = t+getElementType _ = error $ "Expecting pointer type. (Malformed AST)"++extractValueType :: [Word32] -> Type -> Type+extractValueType [] ty = ty+extractValueType (i : is) (ArrayType numEls elTy)+  | fromIntegral i < numEls = extractValueType is elTy+  | fromIntegral i >= numEls = error "Expecting valid index into array type. (Malformed AST)"+extractValueType (i : is) (StructureType _ elTys)+  | fromIntegral i < length elTys = extractValueType is (elTys !! fromIntegral i)+  | otherwise = error "Expecting valid index into structure type. (Malformed AST)"+extractValueType _ _ = error "Expecting vector type. (Malformed AST)"++instance Typed F.SomeFloat where+  typeOf (F.Half _)          = FloatingPointType HalfFP+  typeOf (F.Single _)        = FloatingPointType FloatFP+  typeOf (F.Double _)        = FloatingPointType DoubleFP+  typeOf (F.Quadruple _ _)   = FloatingPointType FP128FP+  typeOf (F.X86_FP80 _ _)    = FloatingPointType X86_FP80FP+  typeOf (F.PPC_FP128 _ _)   = FloatingPointType PPC_FP128FP++instance Typed Global where+  typeOf (GlobalVariable {..}) = type'+  typeOf (GlobalAlias {..})    = type'+  typeOf (Function {..})       = let (params, isVarArg) = parameters+                                   in FunctionType returnType (map typeOf params) isVarArg+instance Typed Parameter where+  typeOf (Parameter t _ _) = t
+ src/LLVM/IRBuilder.hs view
@@ -0,0 +1,8 @@+module LLVM.IRBuilder+  (module X)+  where++import LLVM.IRBuilder.Monad as X+import LLVM.IRBuilder.Instruction as X+import LLVM.IRBuilder.Module as X+import LLVM.IRBuilder.Constant as X
+ src/LLVM/IRBuilder/Constant.hs view
@@ -0,0 +1,35 @@+module LLVM.IRBuilder.Constant where+import           Data.Word+import           LLVM.Prelude+import           LLVM.AST             hiding (args, dests)+import qualified LLVM.AST.Constant    as C+import           LLVM.AST.Type        as AST+import           LLVM.AST.Typed+import           LLVM.IRBuilder.Monad++import           LLVM.AST.Constant+import           LLVM.AST.Float++int64 :: Applicative f => Integer -> f Operand+int64 = pure . ConstantOperand . Int 64++int32 :: Applicative f => Integer -> f Operand+int32 = pure . ConstantOperand . Int 32++bit :: Applicative f => Integer -> f Operand+bit = pure . ConstantOperand . Int 1++double :: Applicative f => Double -> f Operand+double = pure . ConstantOperand . Float . Double++single :: Applicative f => Float -> f Operand+single = pure . ConstantOperand . Float . Single++half :: Applicative f => Word16 -> f Operand+half = pure . ConstantOperand . Float . Half++struct :: Applicative f => Maybe Name -> Bool -> [Constant] -> f Operand+struct nm packing members = pure . ConstantOperand $ Struct nm packing members++array :: Applicative f => [Constant] -> f Operand+array members = pure . ConstantOperand $ Array (typeOf $ head members) members
+ src/LLVM/IRBuilder/Instruction.hs view
@@ -0,0 +1,181 @@+{-# LANGUAGE FlexibleContexts #-}++module LLVM.IRBuilder.Instruction where++import Prelude hiding (and, or, pred)++import Data.Word++import LLVM.AST hiding (args, dests)+import LLVM.AST.Type as AST+import LLVM.AST.Typed+import LLVM.AST.ParameterAttribute+import qualified LLVM.AST as AST+import qualified LLVM.AST.CallingConvention as CC+import qualified LLVM.AST.Constant as C+import qualified LLVM.AST.IntegerPredicate as IP+import qualified LLVM.AST.FloatingPointPredicate as FP++import LLVM.IRBuilder.Monad++fadd :: MonadIRBuilder m => Operand -> Operand -> m Operand+fadd a b = emitInstr (typeOf a) $ FAdd NoFastMathFlags a b []++fmul :: MonadIRBuilder m => Operand -> Operand -> m Operand+fmul a b = emitInstr (typeOf a) $ FMul NoFastMathFlags a b []++fsub :: MonadIRBuilder m => Operand -> Operand -> m Operand+fsub a b = emitInstr (typeOf a) $ FSub NoFastMathFlags a b []++fdiv :: MonadIRBuilder m => Operand -> Operand -> m Operand+fdiv a b = emitInstr (typeOf a) $ FDiv NoFastMathFlags a b []++frem :: MonadIRBuilder m => Operand -> Operand -> m Operand+frem a b = emitInstr (typeOf a) $ FRem NoFastMathFlags a b []++add :: MonadIRBuilder m => Operand -> Operand -> m Operand+add a b = emitInstr (typeOf a) $ Add False False a b []++mul :: MonadIRBuilder m => Operand -> Operand -> m Operand+mul a b = emitInstr (typeOf a) $ Mul False False a b []++sub :: MonadIRBuilder m => Operand -> Operand -> m Operand+sub a b = emitInstr (typeOf a) $ Sub False False a b []++udiv :: MonadIRBuilder m => Operand -> Operand -> m Operand+udiv a b = emitInstr (typeOf a) $ UDiv True a b []++sdiv :: MonadIRBuilder m => Operand -> Operand -> m Operand+sdiv a b = emitInstr (typeOf a) $ SDiv True a b []++urem :: MonadIRBuilder m => Operand -> Operand -> m Operand+urem a b = emitInstr (typeOf a) $ URem a b []++shl :: MonadIRBuilder m => Operand -> Operand -> m Operand+shl a b = emitInstr (typeOf a) $ Shl False False a b []++lshr :: MonadIRBuilder m => Operand -> Operand -> m Operand+lshr a b = emitInstr (typeOf a) $ LShr True a b []++ashr :: MonadIRBuilder m => Operand -> Operand -> m Operand+ashr a b = emitInstr (typeOf a) $ AShr True a b []++and :: MonadIRBuilder m => Operand -> Operand -> m Operand+and a b = emitInstr (typeOf a) $ And a b []++or :: MonadIRBuilder m => Operand -> Operand -> m Operand+or a b = emitInstr (typeOf a) $ Or a b []++xor :: MonadIRBuilder m => Operand -> Operand -> m Operand+xor a b = emitInstr (typeOf a) $ Xor a b []++alloca :: MonadIRBuilder m => Type -> Maybe Operand -> Word32 -> m Operand+alloca ty count align = emitInstr (ptr ty) $ Alloca ty count align []++load :: MonadIRBuilder m => Operand -> Word32 -> m Operand+load a align = emitInstr retty $ Load False a Nothing align []+  where+    retty = case typeOf a of+      PointerType ty _ -> ty+      _ -> error "Cannot load non-pointer (Malformed AST)."++store :: MonadIRBuilder m => Operand -> Word32 -> Operand -> m ()+store addr align val = emitInstrVoid $ Store False addr val Nothing align []++gep :: MonadIRBuilder m => Operand -> [Operand] -> m Operand+gep addr is = emitInstr (gepType (typeOf addr) is) (GetElementPtr False addr is [])+  where+    -- TODO: Perhaps use the function from llvm-hs-pretty (https://github.com/llvm-hs/llvm-hs-pretty/blob/master/src/LLVM/Typed.hs)+    gepType :: Type -> [Operand] -> Type+    gepType ty [] = ptr ty+    gepType (PointerType ty _) (_:is') = gepType ty is'+    gepType (StructureType _ elTys) (ConstantOperand (C.Int 32 val):is') =+      gepType (elTys !! fromIntegral val) is'+    gepType (StructureType _ _) (i:_) = error $ "gep: Indices into structures should be 32-bit constants. " ++ show i+    gepType (VectorType _ elTy) (_:is') = gepType elTy is'+    gepType (ArrayType _ elTy) (_:is') = gepType elTy is'+    gepType t (_:_) = error $ "gep: Can't index into a " ++ show t++trunc :: MonadIRBuilder m => Operand -> Type -> m Operand+trunc a to = emitInstr to $ Trunc a to []++zext :: MonadIRBuilder m => Operand -> Type -> m Operand+zext a to = emitInstr to $ ZExt a to []++sext :: MonadIRBuilder m => Operand -> Type -> m Operand+sext a to = emitInstr to $ SExt a to []++fptoui :: MonadIRBuilder m => Operand -> Type -> m Operand+fptoui a to = emitInstr to $ FPToUI a to []++fptosi :: MonadIRBuilder m => Operand -> Type -> m Operand+fptosi a to = emitInstr to $ FPToSI a to []++uitofp :: MonadIRBuilder m => Operand -> Type -> m Operand+uitofp a to = emitInstr to $ UIToFP a to []++sitofp :: MonadIRBuilder m => Operand -> Type -> m Operand+sitofp a to = emitInstr to $ SIToFP a to []++ptrtoint :: MonadIRBuilder m => Operand -> Type -> m Operand+ptrtoint a to = emitInstr to $ PtrToInt a to []++inttoptr :: MonadIRBuilder m => Operand -> Type -> m Operand+inttoptr a to = emitInstr to $ IntToPtr a to []++bitcast :: MonadIRBuilder m => Operand -> Type -> m Operand+bitcast a to = emitInstr to $ BitCast a to []++icmp :: MonadIRBuilder m => IP.IntegerPredicate -> Operand -> Operand -> m Operand+icmp pred a b = emitInstr i1 $ ICmp pred a b []++fcmp :: MonadIRBuilder m => FP.FloatingPointPredicate -> Operand -> Operand -> m Operand+fcmp pred a b = emitInstr i1 $ FCmp pred a b []++-- | Unconditional branch+br :: MonadIRBuilder m => Name -> m ()+br val = emitTerm (Br val [])++phi :: MonadIRBuilder m => [(Operand, Name)] -> m Operand+phi [] = emitInstr AST.void $ Phi AST.void [] []+phi incoming@(i:_) = emitInstr ty $ Phi ty incoming []+  where+    ty = typeOf (fst i) -- result type++retVoid :: MonadIRBuilder m => m ()+retVoid = emitTerm (Ret Nothing [])++call :: MonadIRBuilder m => Operand -> [(Operand, [ParameterAttribute])] -> m Operand+call fun args = do+  let instr = Call {+    AST.tailCallKind = Nothing+  , AST.callingConvention = CC.C+  , AST.returnAttributes = []+  , AST.function = Right fun+  , AST.arguments = args+  , AST.functionAttributes = []+  , AST.metadata = []+  }+  case typeOf fun of+      FunctionType r _ _ -> case r of+        VoidType -> emitInstrVoid instr >> (pure (ConstantOperand (C.Undef void)))+        _        -> emitInstr r instr+      PointerType (FunctionType r _ _) _ -> case r of+        VoidType -> emitInstrVoid instr >> (pure (ConstantOperand (C.Undef void)))+        _        -> emitInstr r instr+      _ -> error "Cannot call non-function (Malformed AST)."++ret :: MonadIRBuilder m => Operand -> m ()+ret val = emitTerm (Ret (Just val) [])++switch :: MonadIRBuilder m => Operand -> Name -> [(C.Constant, Name)] -> m ()+switch val def dests = emitTerm $ Switch val def dests []++select :: MonadIRBuilder m => Operand -> Operand -> Operand -> m Operand+select cond t f = emitInstr (typeOf t) $ Select cond t f []++condBr :: MonadIRBuilder m => Operand -> Name -> Name -> m ()+condBr cond tdest fdest = emitTerm $ CondBr cond tdest fdest []++unreachable :: MonadIRBuilder m => m ()+unreachable = emitTerm $ Unreachable []
+ src/LLVM/IRBuilder/Internal/SnocList.hs view
@@ -0,0 +1,16 @@+module LLVM.IRBuilder.Internal.SnocList where++import LLVM.Prelude++newtype SnocList a = SnocList { unSnocList :: [a] }+  deriving (Eq, Show)++instance Monoid (SnocList a) where+  mappend (SnocList xs) (SnocList ys) = SnocList $ ys ++ xs+  mempty = SnocList []++snoc :: SnocList a -> a -> SnocList a+snoc (SnocList xs) x = SnocList $ x : xs++getSnocList :: SnocList a -> [a]+getSnocList = reverse . unSnocList
+ src/LLVM/IRBuilder/Module.hs view
@@ -0,0 +1,199 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-} -- For MonadState s (IRBuilderT m) instance++module LLVM.IRBuilder.Module where++import Prelude hiding (and, or)++import Control.Applicative+import Control.Monad.Cont+import Control.Monad.Except+import Control.Monad.Fail+import qualified Control.Monad.Fail as Fail+import Control.Monad.Identity+import Control.Monad.Writer.Lazy as Lazy+import Control.Monad.Writer.Strict as Strict+import Control.Monad.Reader+import Control.Monad.RWS.Lazy as Lazy+import Control.Monad.RWS.Strict as Strict+import qualified Control.Monad.State.Lazy as Lazy+import Control.Monad.State.Strict+import Control.Monad.List+import Control.Monad.Trans.Maybe+import Control.Monad.Trans.Identity++import Data.Bifunctor+import Data.ByteString.Short as BS+import Data.Char+import Data.Data+import Data.String++import GHC.Generics(Generic)++import LLVM.AST hiding (function)+import LLVM.AST.Global+import LLVM.AST.Linkage+import qualified LLVM.AST.Constant as C++import LLVM.IRBuilder.Internal.SnocList+import LLVM.IRBuilder.Monad++newtype ModuleBuilderT m a = ModuleBuilderT { unModuleBuilderT :: StateT ModuleBuilderState m a }+  deriving+    ( Functor, Alternative, Applicative, Monad, MonadCont, MonadError e+    , MonadFix, MonadIO, MonadPlus, MonadReader r, MonadTrans, MonadWriter w+    )++instance MonadFail m => MonadFail (ModuleBuilderT m) where+  fail str = ModuleBuilderT (StateT $ \_ -> Fail.fail str)++newtype ModuleBuilderState = ModuleBuilderState+  { builderDefs :: SnocList Definition+  }++emptyModuleBuilder :: ModuleBuilderState+emptyModuleBuilder = ModuleBuilderState+  { builderDefs = mempty+  }++type ModuleBuilder = ModuleBuilderT Identity++class Monad m => MonadModuleBuilder m where+  liftModuleState :: State ModuleBuilderState a -> m a++  default liftModuleState+    :: (MonadTrans t, MonadModuleBuilder m1, m ~ t m1)+    => State ModuleBuilderState a+    -> m a+  liftModuleState = lift . liftModuleState++instance Monad m => MonadModuleBuilder (ModuleBuilderT m) where+  liftModuleState (StateT s) = ModuleBuilderT $ StateT $ pure . runIdentity . s++-- | Evaluate 'ModuleBuilder' to a result and a list of definitions+runModuleBuilder :: ModuleBuilderState -> ModuleBuilder a -> (a, [Definition])+runModuleBuilder s m = runIdentity $ runModuleBuilderT s m++-- | Evaluate 'ModuleBuilderT' to a result and a list of definitions+runModuleBuilderT :: Monad m => ModuleBuilderState -> ModuleBuilderT m a -> m (a, [Definition])+runModuleBuilderT s (ModuleBuilderT m)+  = second (getSnocList . builderDefs)+  <$> runStateT m s++-- | Evaluate 'ModuleBuilder' to a list of definitions+execModuleBuilder :: ModuleBuilderState -> ModuleBuilder a -> [Definition]+execModuleBuilder s m = snd $ runModuleBuilder s m++-- | Evaluate 'ModuleBuilderT' to a list of definitions+execModuleBuilderT :: Monad m => ModuleBuilderState -> ModuleBuilderT m a -> m [Definition]+execModuleBuilderT s m = snd <$> runModuleBuilderT s m++emitDefn :: MonadModuleBuilder m => Definition -> m ()+emitDefn def = liftModuleState $ modify $ \s -> s { builderDefs = builderDefs s `snoc` def }++-- | A parameter name suggestion+data ParameterName+  = NoParameterName+  | ParameterName ShortByteString+  deriving (Eq, Ord, Read, Show, Typeable, Data, Generic)++-- | Using 'fromString` on non-ASCII strings will throw an error.+instance IsString ParameterName where+  fromString s+    | all isAscii s = ParameterName (fromString s)+    | otherwise =+      error ("Only ASCII strings are automatically converted to LLVM parameter names. "+      <> "Other strings need to be encoded to a `ShortByteString` using an arbitrary encoding.")++-- | Define and emit a (non-variadic) function definition+function+  :: MonadModuleBuilder m+  => Name  -- ^ Function name+  -> [(Type, ParameterName)]  -- ^ Parameter types and name suggestions+  -> Type  -- ^ Return type+  -> ([Operand] -> IRBuilderT m ())  -- ^ Function body builder+  -> m Operand+function label argtys retty body = do+  let tys = fst <$> argtys+  (paramNames, blocks) <- runIRBuilderT emptyIRBuilder $ do+    paramNames <- forM argtys $ \(_, paramName) -> case paramName of+      NoParameterName -> fresh+      ParameterName p -> fresh `named` p+    body $ zipWith LocalReference tys paramNames+    return paramNames+  let+    def = GlobalDefinition functionDefaults+      { name        = label+      , parameters  = (zipWith (\ty nm -> Parameter ty nm []) tys paramNames, False)+      , returnType  = retty+      , basicBlocks = blocks+      }+    funty = FunctionType retty (fst <$> argtys) False+  emitDefn def+  pure $ ConstantOperand $ C.GlobalReference funty label++-- | An external function definition+extern+  :: MonadModuleBuilder m+  => Name   -- ^ Definition name+  -> [Type] -- ^ Parametere types+  -> Type   -- ^ Type+  -> m Operand+extern nm argtys retty = do+  emitDefn $ GlobalDefinition functionDefaults+    { name        = nm+    , linkage     = External+    , parameters  = ([Parameter ty (mkName "") [] | ty <- argtys], False)+    , returnType  = retty+    }+  let funty = FunctionType retty argtys False+  pure $ ConstantOperand $ C.GlobalReference funty nm++-- | A named type definition+typedef+  :: MonadModuleBuilder m+  => Name+  -> Maybe Type+  -> m ()+typedef nm ty = do+  emitDefn $ TypeDefinition nm ty+  pure ()++-- | Convenience function for module construction+buildModule :: ShortByteString -> ModuleBuilder a -> Module+buildModule nm = mkModule . execModuleBuilder emptyModuleBuilder+  where+    mkModule ds = defaultModule { moduleName = nm, moduleDefinitions = ds }++-- | Convenience function for module construction (transformer version)+buildModuleT :: Monad m => ShortByteString -> ModuleBuilderT m a -> m Module+buildModuleT nm = fmap mkModule . execModuleBuilderT emptyModuleBuilder+  where+    mkModule ds = defaultModule { moduleName = nm, moduleDefinitions = ds }++-------------------------------------------------------------------------------+-- mtl instances+-------------------------------------------------------------------------------++instance MonadState s m => MonadState s (ModuleBuilderT m) where+  state = lift . state++instance MonadModuleBuilder m => MonadModuleBuilder (ContT r m)+instance MonadModuleBuilder m => MonadModuleBuilder (ExceptT e m)+instance MonadModuleBuilder m => MonadModuleBuilder (IdentityT m)+instance MonadModuleBuilder m => MonadModuleBuilder (ListT m)+instance MonadModuleBuilder m => MonadModuleBuilder (MaybeT m)+instance MonadModuleBuilder m => MonadModuleBuilder (ReaderT r m)+instance (MonadModuleBuilder m, Monoid w) => MonadModuleBuilder (Strict.RWST r w s m)+instance (MonadModuleBuilder m, Monoid w) => MonadModuleBuilder (Lazy.RWST r w s m)+instance MonadModuleBuilder m => MonadModuleBuilder (StateT s m)+instance MonadModuleBuilder m => MonadModuleBuilder (Lazy.StateT s m)+instance (Monoid w, MonadModuleBuilder m) => MonadModuleBuilder (Strict.WriterT w m)+instance (Monoid w, MonadModuleBuilder m) => MonadModuleBuilder (Lazy.WriterT w m)
+ src/LLVM/IRBuilder/Monad.hs view
@@ -0,0 +1,251 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-} -- For MonadState s (ModuleBuilderT m) instance++module LLVM.IRBuilder.Monad where++import LLVM.Prelude++import Control.Monad.Cont+import Control.Monad.Except+import Control.Monad.Fail+import qualified Control.Monad.Fail as Fail+import Control.Monad.Identity+import Control.Monad.Writer.Lazy as Lazy+import Control.Monad.Writer.Strict as Strict+import Control.Monad.Reader+import Control.Monad.RWS.Lazy as Lazy+import Control.Monad.RWS.Strict as Strict+import qualified Control.Monad.State.Lazy as Lazy+import Control.Monad.State.Strict+import Control.Monad.List+import Control.Monad.Trans.Maybe+import Control.Monad.Trans.Identity++import Data.Bifunctor+import Data.String+import Data.HashSet(HashSet)+import qualified Data.HashSet as HS++import LLVM.AST++import LLVM.IRBuilder.Internal.SnocList++-- | This provides a uniform API for creating instructions and inserting them+-- into a basic block: either at the end of a BasicBlock, or at a specific+-- location in a block.+newtype IRBuilderT m a = IRBuilderT { unIRBuilderT :: StateT IRBuilderState m a }+  deriving+    ( Functor, Alternative, Applicative, Monad, MonadCont, MonadError e+    , MonadFix, MonadIO, MonadPlus, MonadReader r, MonadTrans, MonadWriter w+    )++instance MonadFail m => MonadFail (IRBuilderT m) where+    fail str = IRBuilderT (StateT $ \ _ -> Fail.fail str)++type IRBuilder = IRBuilderT Identity++class Monad m => MonadIRBuilder m where+  liftIRState :: State IRBuilderState a -> m a++  default liftIRState+    :: (MonadTrans t, MonadIRBuilder m1, m ~ t m1)+    => State IRBuilderState a+    -> m a+  liftIRState = lift . liftIRState++instance Monad m => MonadIRBuilder (IRBuilderT m) where+  liftIRState (StateT s) = IRBuilderT $ StateT $ pure . runIdentity . s++-- | A partially constructed block as a sequence of instructions+data PartialBlock = PartialBlock+  { partialBlockName :: !Name+  , partialBlockInstrs :: SnocList (Named Instruction)+  , partialBlockTerm :: Maybe (Named Terminator)+  }++emptyPartialBlock :: Name -> PartialBlock+emptyPartialBlock nm = PartialBlock nm mempty Nothing++-- | Builder monad state+data IRBuilderState = IRBuilderState+  { builderSupply :: !Word+  , builderUsedNames :: !(HashSet ShortByteString)+  , builderNameSuggestion :: !(Maybe ShortByteString)+  , builderBlocks :: SnocList BasicBlock+  , builderBlock :: !(Maybe PartialBlock)+  }++emptyIRBuilder :: IRBuilderState+emptyIRBuilder = IRBuilderState+  { builderSupply = 0+  , builderUsedNames = mempty+  , builderNameSuggestion = Nothing+  , builderBlocks = mempty+  , builderBlock = Nothing+  }++-- | Evaluate IRBuilder to a result and a list of basic blocks+runIRBuilder :: IRBuilderState -> IRBuilder a -> (a, [BasicBlock])+runIRBuilder s m = runIdentity $ runIRBuilderT s m++-- | Evaluate IRBuilderT to a result and a list of basic blocks+runIRBuilderT :: Monad m => IRBuilderState -> IRBuilderT m a -> m (a, [BasicBlock])+runIRBuilderT s m+  = second (getSnocList . builderBlocks)+  <$> runStateT (unIRBuilderT $ m <* block) s++-- | Evaluate IRBuilder to a list of basic blocks+execIRBuilder :: IRBuilderState -> IRBuilder a -> [BasicBlock]+execIRBuilder s m = snd $ runIRBuilder s m++-- | Evaluate IRBuilderT to a list of basic blocks+execIRBuilderT :: Monad m => IRBuilderState -> IRBuilderT m a -> m [BasicBlock]+execIRBuilderT s m = snd <$> runIRBuilderT s m++-------------------------------------------------------------------------------+-- * Low-level functionality+-------------------------------------------------------------------------------++modifyBlock+  :: MonadIRBuilder m+  => (PartialBlock -> PartialBlock)+  -> m ()+modifyBlock f = do+  mbb <- liftIRState $ gets builderBlock+  case mbb of+    Nothing -> do+      nm <- freshUnName+      liftIRState $ modify $ \s -> s { builderBlock = Just $! f $ emptyPartialBlock nm }+    Just bb ->+      liftIRState $ modify $ \s -> s { builderBlock = Just $! f bb }++-- | Generate a fresh name. The resulting name is numbered or+-- based on the name suggested with 'named' if that's used.+fresh :: MonadIRBuilder m => m Name+fresh = do+  msuggestion <- liftIRState $ gets builderNameSuggestion+  maybe freshUnName freshName msuggestion++-- | Generate a fresh name from a name suggestion+freshName :: MonadIRBuilder m => ShortByteString -> m Name+freshName suggestion = do+  usedNames <- liftIRState $ gets builderUsedNames+  let+    candidates = suggestion : [suggestion <> fromString (show n) | n <- [(1 :: Int)..]]+    (unusedName:_) = filter (not . (`HS.member` usedNames)) candidates+  liftIRState $ modify $ \s -> s { builderUsedNames = HS.insert unusedName $ builderUsedNames s }+  return $ Name unusedName++-- | Generate a fresh numbered name+freshUnName :: MonadIRBuilder m => m Name+freshUnName = liftIRState $ do+  n <- gets builderSupply+  modify $ \s -> s { builderSupply = 1 + n }+  pure $ UnName n++-- | Emit instruction+emitInstr+  :: MonadIRBuilder m+  => Type -- ^ Return type+  -> Instruction+  -> m Operand+emitInstr retty instr = do+  nm <- fresh+  modifyBlock $ \bb -> bb+    { partialBlockInstrs = partialBlockInstrs bb `snoc` (nm := instr)+    }+  pure (LocalReference retty nm)++-- | Emit instruction that returns void+emitInstrVoid+  :: MonadIRBuilder m+  => Instruction+  -> m ()+emitInstrVoid instr = do+  modifyBlock $ \bb -> bb+    { partialBlockInstrs = partialBlockInstrs bb `snoc` (Do instr)+    }+  pure ()++-- | Emit terminator+emitTerm+  :: MonadIRBuilder m+  => Terminator+  -> m ()+emitTerm term = modifyBlock $ \bb -> bb+  { partialBlockTerm = Just (Do term)+  }++-- | Starts a new block labelled using the given name and ends the previous+-- one. The name is assumed to be fresh.+emitBlockStart+  :: MonadIRBuilder m+  => Name+  -> m ()+emitBlockStart nm = do+  mbb <- liftIRState $ gets builderBlock+  case mbb of+    Nothing -> return ()+    Just bb -> do+      let+        instrs = getSnocList $ partialBlockInstrs bb+        newBb = case partialBlockTerm bb of+          Nothing   -> BasicBlock (partialBlockName bb) instrs (Do (Ret Nothing []))+          Just term -> BasicBlock (partialBlockName bb) instrs term+      liftIRState $ modify $ \s -> s+        { builderBlocks = builderBlocks s `snoc` newBb+        }+  liftIRState $ modify $ \s -> s { builderBlock = Just $ emptyPartialBlock nm }++-------------------------------------------------------------------------------+-- * High-level functionality+-------------------------------------------------------------------------------++-- | Starts a new block and ends the previous one+block+  :: MonadIRBuilder m+  => m Name+block = do+  nm <- fresh+  emitBlockStart nm+  return nm++-- | @ir `named` name@ executes the 'IRBuilder' @ir@ using @name@ as the base+-- name whenever a fresh local name is generated. Collisions are avoided by+-- appending numbers (first @"name"@, then @"name1"@, @"name2"@, and so on).+named+  :: MonadIRBuilder m+  => m r+  -> ShortByteString+  -> m r+named ir name = do+  before <- liftIRState $ gets builderNameSuggestion+  liftIRState $ modify $ \s -> s { builderNameSuggestion = Just name }+  result <- ir+  liftIRState $ modify $ \s -> s { builderNameSuggestion = before }+  return result++-------------------------------------------------------------------------------+-- mtl instances+-------------------------------------------------------------------------------++instance MonadState s m => MonadState s (IRBuilderT m) where+  state = lift . state++instance MonadIRBuilder m => MonadIRBuilder (ContT r m)+instance MonadIRBuilder m => MonadIRBuilder (ExceptT e m)+instance MonadIRBuilder m => MonadIRBuilder (IdentityT m)+instance MonadIRBuilder m => MonadIRBuilder (ListT m)+instance MonadIRBuilder m => MonadIRBuilder (MaybeT m)+instance MonadIRBuilder m => MonadIRBuilder (ReaderT r m)+instance (MonadIRBuilder m, Monoid w) => MonadIRBuilder (Strict.RWST r w s m)+instance (MonadIRBuilder m, Monoid w) => MonadIRBuilder (Lazy.RWST r w s m)+instance MonadIRBuilder m => MonadIRBuilder (StateT s m)+instance MonadIRBuilder m => MonadIRBuilder (Lazy.StateT s m)+instance (Monoid w, MonadIRBuilder m) => MonadIRBuilder (Strict.WriterT w m)+instance (Monoid w, MonadIRBuilder m) => MonadIRBuilder (Lazy.WriterT w m)
+ test/IRBuilder.hs view
@@ -0,0 +1,239 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecursiveDo #-}+module Main+  ( main+  ) where++import           Data.Monoid+import qualified Data.Text.Lazy as T+import qualified Data.Text.Lazy.IO as T+import           LLVM.AST hiding (function)+import qualified LLVM.AST.Constant as C+import qualified LLVM.AST.Float as F+import           LLVM.AST.Global (basicBlocks, name, parameters, returnType)+import qualified LLVM.AST.Type as AST+import           Test.Hspec hiding (example)++import           LLVM.IRBuilder++main :: IO ()+main =+  hspec $ do+    describe "module builder" $ do+      it "builds the simple module" $+        simple `shouldBe`+        defaultModule {+          moduleName = "exampleModule",+          moduleDefinitions =+            [ GlobalDefinition functionDefaults {+                name = "add",+                parameters =+                  ( [ Parameter AST.i32 "a" []+                    , Parameter AST.i32 "b" []+                    ]+                  , False+                  ),+                returnType = AST.i32,+                basicBlocks =+                  [ BasicBlock+                      "entry"+                      [ UnName 0 := Add {+                          operand0 = LocalReference AST.i32 "a",+                          operand1 = LocalReference AST.i32 "b",+                          nsw = False,+                          nuw = False,+                          metadata = []+                        }+                      ]+                      (Do (Ret (Just (LocalReference AST.i32 (UnName 0))) []))+                  ]+              }+            ]+        }+      it "builds the example" $ do+        let f10 = ConstantOperand (C.Float (F.Double 10))+            fadd a b = FAdd { operand0 = a, operand1 = b, fastMathFlags = NoFastMathFlags, metadata = [] }+            add a b = Add { operand0 = a, operand1 = b, nsw = False, nuw = False, metadata = [] }+        example `shouldBe`+          defaultModule {+            moduleName = "exampleModule",+            moduleDefinitions =+              [ GlobalDefinition functionDefaults {+                  name = "foo",+                  returnType = AST.double,+                  basicBlocks =+                    [ BasicBlock (UnName 0) [ "xxx" := fadd f10 f10]+                        (Do (Ret Nothing []))+                    , BasicBlock+                        "blk"+                        [ UnName 1 := fadd f10 f10+                        , UnName 2 := fadd (LocalReference AST.double (UnName 1)) (LocalReference AST.double (UnName 1))+                        , UnName 3 := add (ConstantOperand (C.Int 32 10)) (ConstantOperand (C.Int 32 10))+                        ]+                        (Do (Br "blk1" []))+                    , BasicBlock+                        "blk1"+                        [ "c" := fadd f10 f10+                        , UnName 4 := fadd (LocalReference AST.double "c") (LocalReference AST.double "c")+                        ]+                        (Do (Br "blk2" []))+                    , BasicBlock+                        "blk2"+                        [ "phi" :=+                            Phi+                              AST.double+                              [ ( f10, "blk" )+                              , ( f10, "blk1" )+                              , ( f10, "blk2" )+                              ]+                              []+                        , UnName 5 := fadd f10 f10+                        , UnName 6 := fadd (LocalReference AST.double (UnName 5)) (LocalReference AST.double (UnName 5))+                        ]+                        (Do (Ret Nothing []))+                    ]+                }+              , GlobalDefinition functionDefaults {+                  name = "bar",+                  returnType = AST.double,+                  basicBlocks =+                    [ BasicBlock+                       (UnName 0)+                       [ UnName 1 := fadd f10 f10+                       , UnName 2 := fadd (LocalReference AST.double (UnName 1)) (LocalReference AST.double (UnName 1))+                       ]+                       (Do (Ret Nothing []))+                    ]+                }+              , GlobalDefinition functionDefaults {+                  name = "baz",+                  parameters =+                    ( [ Parameter AST.i32 (UnName 0) []+                      , Parameter AST.double "arg" []+                      , Parameter AST.i32 (UnName 1) []+                      , Parameter AST.double "arg1" []]+                    , False),+                  returnType = AST.double,+                  basicBlocks =+                    [ BasicBlock+                        (UnName 2)+                        []+                        (Do+                           (Switch+                             (LocalReference AST.i32 (UnName 1))+                             (UnName 3)+                             [ ( C.Int 32 0, UnName 4), ( C.Int 32 1, UnName 7) ] []))+                    , BasicBlock+                        (UnName 3)+                        []+                        (Do (Br (UnName 4) []))+                    , BasicBlock+                        (UnName 4)+                        [ "arg2" := fadd (LocalReference AST.double "arg") f10+                        , UnName 5 := fadd (LocalReference AST.double "arg2") (LocalReference AST.double "arg2")+                        , UnName 6 := Select {+                            condition' = ConstantOperand (C.Int 1 0),+                            trueValue = LocalReference AST.double "arg2",+                            falseValue = LocalReference AST.double (UnName 5),+                            metadata = []+                          }+                        ]+                        (Do (Ret Nothing []))+                    , BasicBlock+                        (UnName 7)+                        [ UnName 8 := GetElementPtr {+                            inBounds = False,+                            address = ConstantOperand (C.Null (AST.ptr (AST.ptr (AST.ptr AST.i32)))),+                            indices =+                              [ ConstantOperand (C.Int 32 10)+                              , ConstantOperand (C.Int 32 20)+                              , ConstantOperand (C.Int 32 30)+                              ],+                            metadata = []+                          }+                        , UnName 9 := GetElementPtr {+                            inBounds = False,+                            address = LocalReference (AST.ptr AST.i32) (UnName 8),+                            indices = [ ConstantOperand (C.Int 32 40) ],+                            metadata = []+                          }+                        ]+                        (Do (Ret Nothing []))+                    ]+                }+              ]+          }++simple :: Module+simple = buildModule "exampleModule" $ mdo++  function "add" [(AST.i32, "a"), (AST.i32, "b")] AST.i32 $ \[a, b] -> mdo++    entry <- block `named` "entry"; do+      c <- add a b+      ret c++example :: Module+example = mkModule $ execModuleBuilder emptyModuleBuilder $ mdo++  foo <- function "foo" [] AST.double $ \_ -> mdo+    xxx <- fadd c1 c1 `named` "xxx"++    blk1 <- block `named` "blk"; do+      a <- fadd c1 c1+      b <- fadd a a+      c <- add c2 c2+      br blk2++    blk2 <- block `named` "blk"; do+      a <- fadd c1 c1 `named` "c"+      b <- fadd a a+      br blk3++    blk3 <- block `named` "blk"; do+      l <- phi [(c1, blk1), (c1, blk2), (c1, blk3)] `named` "phi"+      a <- fadd c1 c1+      b <- fadd a a+      retVoid++    pure ()+++  function "bar" [] AST.double $ \_ -> mdo++    blk3 <- block; do+      a <- fadd c1 c1+      b <- fadd a a+      retVoid++    pure ()++  function "baz" [(AST.i32, NoParameterName), (AST.double, "arg"), (AST.i32, NoParameterName), (AST.double, "arg")] AST.double $ \[rrr, arg, arg2, arg3] -> mdo++    switch arg2 blk1 [(C.Int 32 0, blk2), (C.Int 32 1, blk3)]++    blk1 <- block; do+      br blk2++    blk2 <- block; do+      a <- fadd arg c1 `named` "arg"+      b <- fadd a a+      select (cons $ C.Int 1 0) a b+      retVoid++    blk3 <- block; do+      let nul = cons $ C.Null $ AST.ptr $ AST.ptr $ AST.ptr $ IntegerType 32+      addr <- gep nul [cons $ C.Int 32 10, cons $ C.Int 32 20, cons $ C.Int 32 30]+      addr' <- gep addr [cons $ C.Int 32 40]+      retVoid++    pure ()+  where+    mkModule ds = defaultModule { moduleName = "exampleModule", moduleDefinitions = ds }+    cons = ConstantOperand++c1 :: Operand+c1 = ConstantOperand $ C.Float (F.Double 10)++c2 :: Operand+c2 = ConstantOperand $ C.Int 32 10