llvm-general (empty) → 0.1
raw patch · 130 files changed
+10452/−0 lines, 130 filesdep +HUnitdep +QuickCheckdep +arraybuild-type:Customsetup-changed
Dependencies added: HUnit, QuickCheck, array, base, bytestring, containers, llvm-general, mtl, parsec, setenv, template-haskell, test-framework, test-framework-hunit, test-framework-quickcheck2, text, transformers
Files
- LICENSE +30/−0
- Setup.hs +82/−0
- llvm-general.cabal +186/−0
- src/Control/Monad/AnyCont.hs +29/−0
- src/Control/Monad/AnyCont/Class.hs +39/−0
- src/Control/Monad/Phased.hs +36/−0
- src/Control/Monad/Phased/Class.hs +46/−0
- src/Control/Monad/Trans/AnyCont.hs +39/−0
- src/Control/Monad/Trans/Phased.hs +33/−0
- src/LLVM/General.hs +7/−0
- src/LLVM/General/AST.hs +53/−0
- src/LLVM/General/AST/AddrSpace.hs +8/−0
- src/LLVM/General/AST/Attribute.hs +38/−0
- src/LLVM/General/AST/CallingConvention.hs +13/−0
- src/LLVM/General/AST/Constant.hs +218/−0
- src/LLVM/General/AST/DataLayout.hs +51/−0
- src/LLVM/General/AST/Float.hs +19/−0
- src/LLVM/General/AST/FloatingPointPredicate.hs +30/−0
- src/LLVM/General/AST/Global.hs +109/−0
- src/LLVM/General/AST/InlineAssembly.hs +30/−0
- src/LLVM/General/AST/Instruction.hs +389/−0
- src/LLVM/General/AST/IntegerPredicate.hs +24/−0
- src/LLVM/General/AST/Linkage.hs +27/−0
- src/LLVM/General/AST/Name.hs +31/−0
- src/LLVM/General/AST/Operand.hs +33/−0
- src/LLVM/General/AST/RMWOperation.hs +25/−0
- src/LLVM/General/AST/Type.hs +40/−0
- src/LLVM/General/AST/Visibility.hs +11/−0
- src/LLVM/General/CodeGenOpt.hs +15/−0
- src/LLVM/General/CodeModel.hs +17/−0
- src/LLVM/General/Context.hs +7/−0
- src/LLVM/General/Diagnostic.hs +36/−0
- src/LLVM/General/ExecutionEngine.hs +9/−0
- src/LLVM/General/Internal/Atomicity.hs +41/−0
- src/LLVM/General/Internal/Attribute.hs +152/−0
- src/LLVM/General/Internal/BasicBlock.hs +27/−0
- src/LLVM/General/Internal/CallingConvention.hs +30/−0
- src/LLVM/General/Internal/Coding.hs +125/−0
- src/LLVM/General/Internal/Constant.hs +220/−0
- src/LLVM/General/Internal/Context.hs +16/−0
- src/LLVM/General/Internal/DataLayout.hs +88/−0
- src/LLVM/General/Internal/DecodeAST.hs +171/−0
- src/LLVM/General/Internal/Diagnostic.hs +40/−0
- src/LLVM/General/Internal/EncodeAST.hs +146/−0
- src/LLVM/General/Internal/ExecutionEngine.hs +66/−0
- src/LLVM/General/Internal/FFI/Assembly.hs +24/−0
- src/LLVM/General/Internal/FFI/AssemblyC.cpp +33/−0
- src/LLVM/General/Internal/FFI/BasicBlock.hs +33/−0
- src/LLVM/General/Internal/FFI/BinaryOperator.hs +35/−0
- src/LLVM/General/Internal/FFI/Builder.hs +152/−0
- src/LLVM/General/Internal/FFI/BuilderC.cpp +181/−0
- src/LLVM/General/Internal/FFI/Cleanup.hs +73/−0
- src/LLVM/General/Internal/FFI/Constant.hs +136/−0
- src/LLVM/General/Internal/FFI/ConstantC.cpp +78/−0
- src/LLVM/General/Internal/FFI/Context.hs +27/−0
- src/LLVM/General/Internal/FFI/ExecutionEngine.hs +32/−0
- src/LLVM/General/Internal/FFI/Function.h +39/−0
- src/LLVM/General/Internal/FFI/Function.hs +60/−0
- src/LLVM/General/Internal/FFI/FunctionC.cpp +25/−0
- src/LLVM/General/Internal/FFI/GlobalAlias.hs +28/−0
- src/LLVM/General/Internal/FFI/GlobalAliasC.cpp +21/−0
- src/LLVM/General/Internal/FFI/GlobalValue.h +29/−0
- src/LLVM/General/Internal/FFI/GlobalValue.hs +53/−0
- src/LLVM/General/Internal/FFI/GlobalValueC.cpp +17/−0
- src/LLVM/General/Internal/FFI/GlobalVariable.hs +39/−0
- src/LLVM/General/Internal/FFI/InlineAssembly.h +14/−0
- src/LLVM/General/Internal/FFI/InlineAssembly.hs +34/−0
- src/LLVM/General/Internal/FFI/InlineAssemblyC.cpp +72/−0
- src/LLVM/General/Internal/FFI/Instruction.h +48/−0
- src/LLVM/General/Internal/FFI/Instruction.hs +147/−0
- src/LLVM/General/Internal/FFI/InstructionC.cpp +241/−0
- src/LLVM/General/Internal/FFI/InstructionDefs.hsc +56/−0
- src/LLVM/General/Internal/FFI/Iterate.hs +13/−0
- src/LLVM/General/Internal/FFI/LLVMCTypes.hsc +180/−0
- src/LLVM/General/Internal/FFI/Metadata.hs +69/−0
- src/LLVM/General/Internal/FFI/MetadataC.cpp +71/−0
- src/LLVM/General/Internal/FFI/Module.hs +86/−0
- src/LLVM/General/Internal/FFI/ModuleC.cpp +58/−0
- src/LLVM/General/Internal/FFI/PassManager.hs +100/−0
- src/LLVM/General/Internal/FFI/PassManagerC.cpp +130/−0
- src/LLVM/General/Internal/FFI/PtrHierarchy.hs +95/−0
- src/LLVM/General/Internal/FFI/SMDiagnostic.h +15/−0
- src/LLVM/General/Internal/FFI/SMDiagnostic.hs +40/−0
- src/LLVM/General/Internal/FFI/SMDiagnosticC.cpp +31/−0
- src/LLVM/General/Internal/FFI/Target.h +74/−0
- src/LLVM/General/Internal/FFI/Target.hs +85/−0
- src/LLVM/General/Internal/FFI/TargetC.cpp +201/−0
- src/LLVM/General/Internal/FFI/Transforms.hs +62/−0
- src/LLVM/General/Internal/FFI/Type.h +22/−0
- src/LLVM/General/Internal/FFI/Type.hs +143/−0
- src/LLVM/General/Internal/FFI/TypeC.cpp +34/−0
- src/LLVM/General/Internal/FFI/User.hs +40/−0
- src/LLVM/General/Internal/FFI/Value.h +35/−0
- src/LLVM/General/Internal/FFI/Value.hs +39/−0
- src/LLVM/General/Internal/FFI/ValueC.cpp +20/−0
- src/LLVM/General/Internal/FloatingPointPredicate.hs +31/−0
- src/LLVM/General/Internal/Function.hs +40/−0
- src/LLVM/General/Internal/Global.hs +77/−0
- src/LLVM/General/Internal/InlineAssembly.hs +68/−0
- src/LLVM/General/Internal/Instruction.hs +614/−0
- src/LLVM/General/Internal/InstructionDefs.hs +59/−0
- src/LLVM/General/Internal/IntegerPredicate.hs +25/−0
- src/LLVM/General/Internal/Metadata.hs +55/−0
- src/LLVM/General/Internal/Module.hs +281/−0
- src/LLVM/General/Internal/Operand.hs +96/−0
- src/LLVM/General/Internal/PassManager.hs +110/−0
- src/LLVM/General/Internal/RMWOperation.hs +27/−0
- src/LLVM/General/Internal/String.hs +31/−0
- src/LLVM/General/Internal/Target.hs +229/−0
- src/LLVM/General/Internal/Type.hs +158/−0
- src/LLVM/General/Internal/Value.hs +24/−0
- src/LLVM/General/Module.hs +11/−0
- src/LLVM/General/PassManager.hs +19/−0
- src/LLVM/General/Relocation.hs +15/−0
- src/LLVM/General/Target.hs +13/−0
- src/LLVM/General/Target/Options.hs +54/−0
- src/LLVM/General/Transforms.hs +143/−0
- test/LLVM/General/Test/Constants.hs +170/−0
- test/LLVM/General/Test/DataLayout.hs +29/−0
- test/LLVM/General/Test/ExecutionEngine.hs +52/−0
- test/LLVM/General/Test/Global.hs +40/−0
- test/LLVM/General/Test/InlineAssembly.hs +76/−0
- test/LLVM/General/Test/Instructions.hs +777/−0
- test/LLVM/General/Test/Metadata.hs +138/−0
- test/LLVM/General/Test/Module.hs +281/−0
- test/LLVM/General/Test/Optimization.hs +327/−0
- test/LLVM/General/Test/Support.hs +27/−0
- test/LLVM/General/Test/Target.hs +69/−0
- test/LLVM/General/Test/Tests.hs +28/−0
- test/Test.hs +6/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Benjamin S. Scarlet+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Benjamin S. Scarlet nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,82 @@+import Control.Monad+import Data.List (isPrefixOf, (\\))+import Data.Map (Map)+import qualified Data.Map as Map+import Distribution.Simple+import Distribution.Simple.Program+import Distribution.Simple.Setup+import Distribution.Simple.LocalBuildInfo+import Distribution.PackageDescription+import System.Environment+import System.SetEnv+import Distribution.System++++-- define these selectively in C files (where _not_ using HsFFI.h),+-- rather than universally in the ccOptions, because HsFFI.h currently defines them+-- without checking they're already defined and so causes warnings.+uncheckedHsFFIDefines = ["__STDC_LIMIT_MACROS"]++llvmProgram = simpleProgram "llvm-config"++main = do+ let (ldLibraryPathVar, ldLibraryPathSep) = + case buildOS of+ OSX -> ("DYLD_LIBRARY_PATH",":")+ _ -> ("LD_LIBRARY_PATH",":")+ addToLdLibraryPath s = do+ v <- lookupEnv ldLibraryPathVar+ setEnv ldLibraryPathVar (s ++ maybe "" (ldLibraryPathSep ++) v)+ getLLVMConfig configFlags = do+ let verbosity = fromFlag $ configVerbosity configFlags+ -- preconfigure the configuration-generating program "llvm-config"+ programDb <- configureProgram verbosity llvmProgram+ . userSpecifyPaths (configProgramPaths configFlags)+ . userSpecifyArgss (configProgramArgs configFlags)+ $ configPrograms configFlags+ let llvmConfig :: [String] -> IO String+ llvmConfig = getDbProgramOutput verbosity llvmProgram programDb+ return llvmConfig+ addLLVMToLdLibraryPath configFlags = do+ llvmConfig <- getLLVMConfig configFlags+ [libDir] <- liftM lines $ llvmConfig ["--libdir"]+ addToLdLibraryPath libDir+ + defaultMainWithHooks simpleUserHooks {+ hookedPrograms = [ llvmProgram ],+ confHook = \(genericPackageDescription, hookedBuildInfo) configFlags -> do+ llvmConfig <- getLLVMConfig configFlags++ cppflags <- llvmConfig ["--cppflags"]+ let useCppFlags = (filter ("-D" `isPrefixOf`) $ words cppflags) \\ (map ("-D"++) uncheckedHsFFIDefines)+ includeDirs <- liftM lines $ llvmConfig ["--includedir"]+ libDirs@[libDir] <- liftM lines $ llvmConfig ["--libdir"]++ let genericPackageDescription' = genericPackageDescription {+ condLibrary = do+ libraryCondTree <- condLibrary genericPackageDescription+ return libraryCondTree {+ condTreeData = + let library = condTreeData libraryCondTree+ in library { + libBuildInfo = + let buildInfo = libBuildInfo library + in buildInfo { ccOptions = ccOptions buildInfo ++ useCppFlags }+ }+ }+ }+ configFlags' = configFlags {+ configExtraLibDirs = libDirs ++ configExtraLibDirs configFlags,+ configExtraIncludeDirs = includeDirs ++ configExtraIncludeDirs configFlags+ }+ addLLVMToLdLibraryPath configFlags'+ confHook simpleUserHooks (genericPackageDescription', hookedBuildInfo) configFlags',+ buildHook = \packageDescription localBuildInfo userHooks buildFlags -> do+ addLLVMToLdLibraryPath (configFlags localBuildInfo)+ buildHook simpleUserHooks packageDescription localBuildInfo userHooks buildFlags,+ testHook = \packageDescription localBuildInfo userHooks testFlags -> do+ addLLVMToLdLibraryPath (configFlags localBuildInfo)+ testHook simpleUserHooks packageDescription localBuildInfo userHooks testFlags+ }+
+ llvm-general.cabal view
@@ -0,0 +1,186 @@+name: llvm-general+version: 0.1+license: BSD3+license-file: LICENSE+author: Benjamin S.Scarlet <fgthb0@greynode.net>+maintainer: Benjamin S. Scarlet <fgthb0@greynode.net>+copyright: Benjamin S. Scarlet 2013+build-type: Custom+cabal-version: >= 1.8+category: Compilers/Interpreters, Code Generation+synopsis: General purpose LLVM bindings+description:+ llvm-general is a set of Haskell bindings for LLVM <http://llvm.org/>. Unlike other current Haskell bindings,+ it uses an ADT to represent LLVM IR (<http://llvm.org/docs/LangRef.html>), and so offers two advantages: it+ handles almost all of the stateful complexities of using the LLVM API to build IR; and it supports moving IR not+ only from Haskell into LLVM C++ objects, but the other direction - from LLVM C++ into Haskell.+extra-source-files:+ src/LLVM/General/Internal/FFI/Instruction.h+ src/LLVM/General/Internal/FFI/Value.h+ src/LLVM/General/Internal/FFI/SMDiagnostic.h+ src/LLVM/General/Internal/FFI/InlineAssembly.h+ src/LLVM/General/Internal/FFI/Target.h+ src/LLVM/General/Internal/FFI/Function.h+ src/LLVM/General/Internal/FFI/GlobalValue.h+ src/LLVM/General/Internal/FFI/Type.h+ +source-repository head+ type: git+ location: git://github.com/bscarlet/llvm-general.git++library+ build-tools: llvm-config+ ghc-options: -fwarn-unused-imports+ build-depends: + base >= 3 && < 5,+ text >= 0.11.2.1,+ bytestring >= 0.9.1.10,+ transformers >= 0.3.0.0,+ mtl >= 2.0.1.0,+ template-haskell >= 2.5.0.0,+ containers >= 0.5.0.0,+ parsec >= 3.1.3,+ array >= 0.4.0.1,+ setenv >= 0.1.0+ extra-libraries: LLVM-3.2svn stdc+++ hs-source-dirs: src+ exposed-modules:+ LLVM.General+ LLVM.General.AST+ LLVM.General.AST.AddrSpace+ LLVM.General.AST.InlineAssembly+ LLVM.General.AST.Attribute+ LLVM.General.AST.CallingConvention+ LLVM.General.AST.Constant+ LLVM.General.AST.DataLayout+ LLVM.General.AST.Float+ LLVM.General.AST.FloatingPointPredicate+ LLVM.General.AST.Global+ LLVM.General.AST.Instruction+ LLVM.General.AST.IntegerPredicate+ LLVM.General.AST.Linkage+ LLVM.General.AST.Name+ LLVM.General.AST.Operand+ LLVM.General.AST.RMWOperation+ LLVM.General.AST.Type+ LLVM.General.AST.Visibility+ LLVM.General.CodeGenOpt+ LLVM.General.CodeModel+ LLVM.General.Context+ LLVM.General.Diagnostic+ LLVM.General.ExecutionEngine+ LLVM.General.Module+ LLVM.General.PassManager+ LLVM.General.Relocation+ LLVM.General.Target+ LLVM.General.Target.Options+ LLVM.General.Transforms++ other-modules:+ Control.Monad.Phased+ Control.Monad.Phased.Class+ Control.Monad.Trans.Phased+ Control.Monad.AnyCont+ Control.Monad.AnyCont.Class+ Control.Monad.Trans.AnyCont+ LLVM.General.Internal.Atomicity+ LLVM.General.Internal.Attribute+ LLVM.General.Internal.BasicBlock+ LLVM.General.Internal.CallingConvention+ LLVM.General.Internal.Coding+ LLVM.General.Internal.Constant+ LLVM.General.Internal.Context+ LLVM.General.Internal.DataLayout+ LLVM.General.Internal.DecodeAST+ LLVM.General.Internal.Diagnostic+ LLVM.General.Internal.EncodeAST+ LLVM.General.Internal.ExecutionEngine+ LLVM.General.Internal.FloatingPointPredicate+ LLVM.General.Internal.Function+ LLVM.General.Internal.Global+ LLVM.General.Internal.InlineAssembly+ LLVM.General.Internal.Instruction+ LLVM.General.Internal.InstructionDefs+ LLVM.General.Internal.IntegerPredicate+ LLVM.General.Internal.Metadata+ LLVM.General.Internal.Module+ LLVM.General.Internal.Operand+ LLVM.General.Internal.PassManager+ LLVM.General.Internal.RMWOperation+ LLVM.General.Internal.String+ LLVM.General.Internal.Target+ LLVM.General.Internal.Type+ LLVM.General.Internal.Value+ LLVM.General.Internal.FFI.Assembly+ LLVM.General.Internal.FFI.BasicBlock+ LLVM.General.Internal.FFI.BinaryOperator+ LLVM.General.Internal.FFI.Builder+ LLVM.General.Internal.FFI.Cleanup+ LLVM.General.Internal.FFI.Constant+ LLVM.General.Internal.FFI.Context+ LLVM.General.Internal.FFI.ExecutionEngine+ LLVM.General.Internal.FFI.Function+ LLVM.General.Internal.FFI.GlobalAlias+ LLVM.General.Internal.FFI.GlobalValue+ LLVM.General.Internal.FFI.GlobalVariable+ LLVM.General.Internal.FFI.InlineAssembly+ LLVM.General.Internal.FFI.Instruction+ LLVM.General.Internal.FFI.InstructionDefs+ LLVM.General.Internal.FFI.Iterate+ LLVM.General.Internal.FFI.LLVMCTypes+ LLVM.General.Internal.FFI.Metadata+ LLVM.General.Internal.FFI.Module+ LLVM.General.Internal.FFI.PassManager+ LLVM.General.Internal.FFI.PtrHierarchy+ LLVM.General.Internal.FFI.SMDiagnostic+ LLVM.General.Internal.FFI.Target+ LLVM.General.Internal.FFI.Transforms+ LLVM.General.Internal.FFI.Type+ LLVM.General.Internal.FFI.User+ LLVM.General.Internal.FFI.Value++ include-dirs: src+ c-sources: + src/LLVM/General/Internal/FFI/AssemblyC.cpp+ src/LLVM/General/Internal/FFI/BuilderC.cpp+ src/LLVM/General/Internal/FFI/ConstantC.cpp+ src/LLVM/General/Internal/FFI/FunctionC.cpp+ src/LLVM/General/Internal/FFI/GlobalAliasC.cpp+ src/LLVM/General/Internal/FFI/GlobalValueC.cpp+ src/LLVM/General/Internal/FFI/InlineAssemblyC.cpp+ src/LLVM/General/Internal/FFI/InstructionC.cpp+ src/LLVM/General/Internal/FFI/MetadataC.cpp+ src/LLVM/General/Internal/FFI/ModuleC.cpp+ src/LLVM/General/Internal/FFI/PassManagerC.cpp+ src/LLVM/General/Internal/FFI/SMDiagnosticC.cpp+ src/LLVM/General/Internal/FFI/TargetC.cpp+ src/LLVM/General/Internal/FFI/TypeC.cpp+ src/LLVM/General/Internal/FFI/ValueC.cpp++test-suite test+ type: exitcode-stdio-1.0+ build-depends: + base >= 3 && < 5,+ test-framework >= 0.5,+ test-framework-hunit >= 0.2.7,+ HUnit >= 1.2.4.2,+ test-framework-quickcheck2 >= 0.3.0.1,+ QuickCheck >= 2.5.1.1,+ llvm-general >= 0.1,+ containers >= 0.5.0.0+ hs-source-dirs: test+ main-is: Test.hs+ other-modules:+ LLVM.General.Test.Constants+ LLVM.General.Test.DataLayout+ LLVM.General.Test.ExecutionEngine+ LLVM.General.Test.Global+ LLVM.General.Test.InlineAssembly+ LLVM.General.Test.Instructions+ LLVM.General.Test.Metadata+ LLVM.General.Test.Module+ LLVM.General.Test.Optimization+ LLVM.General.Test.Support+ LLVM.General.Test.Target+ LLVM.General.Test.Tests+
+ src/Control/Monad/AnyCont.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE+ FlexibleInstances,+ MultiParamTypeClasses,+ UndecidableInstances+ #-}+module Control.Monad.AnyCont (+ MonadAnyCont(..),+ AnyContT(..),+ runAnyContT,+ withAnyContT,+ mapAnyContT,+ anyContIOToM,+ anyContT+ ) where++import Control.Monad.Trans.AnyCont+import Control.Monad.AnyCont.Class+import Control.Monad.Trans.Class+import Control.Monad.State.Class+import Control.Monad.Error.Class++instance MonadState s m => MonadState s (AnyContT m) where+ get = lift get+ put = lift . put+ state = lift . state++instance MonadError e m => MonadError e (AnyContT m) where+ throwError = lift . throwError+ x `catchError` h = anyContT $ \f -> (runAnyContT x f) `catchError` (\e -> runAnyContT (h e) f)
+ src/Control/Monad/AnyCont/Class.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE+ RankNTypes,+ MultiParamTypeClasses,+ FunctionalDependencies,+ FlexibleInstances,+ UndecidableInstances+ #-}+module Control.Monad.AnyCont.Class where++import Control.Monad.Trans.Class+import Control.Monad.Trans.AnyCont (AnyContT)+import qualified Control.Monad.Trans.AnyCont as AnyCont+import Control.Monad.Trans.Error as Error+import Control.Monad.Trans.State as State+import Control.Monad.Trans.Phased as Phased+import Control.Monad.IO.Class++class MonadAnyCont b m | m -> b where+ anyContToM :: (forall r . (a -> b r) -> b r) -> m a+ scopeAnyCont :: m a -> m a++instance Monad m => MonadAnyCont m (AnyContT m) where+ anyContToM = AnyCont.anyContT+ scopeAnyCont = lift . flip AnyCont.runAnyContT return+ +instance (Error e, Monad m, MonadAnyCont b m) => MonadAnyCont b (ErrorT e m) where+ anyContToM = lift . anyContToM+ scopeAnyCont = mapErrorT scopeAnyCont++instance (Monad m, MonadAnyCont b m) => MonadAnyCont b (PhasedT m) where+ anyContToM = lift . anyContToM+ scopeAnyCont = mapPhasedT scopeAnyCont++instance (Monad m, MonadAnyCont b m) => MonadAnyCont b (StateT s m) where+ anyContToM = lift . anyContToM+ scopeAnyCont = StateT . (scopeAnyCont .) . runStateT++anyContIOToM :: MonadIO m => (forall r . (a -> IO r) -> IO r) -> AnyContT m a+anyContIOToM ioac = AnyCont.anyContT (\c -> liftIO (ioac return) >>= c)
+ src/Control/Monad/Phased.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE+ FlexibleInstances,+ MultiParamTypeClasses,+ UndecidableInstances+ #-}+module Control.Monad.Phased (+ MonadPhased(..),+ PhasedT(..),+ runPhasedT,+ forInterleavedM,+ iap,+ defer,+ runInterleaved,+ mapPhasedT+ ) where++import Control.Monad+import Control.Monad.Trans.Phased++import Control.Monad.Trans.Class+import Control.Monad.State.Class+import Control.Monad.Reader.Class+import Control.Monad.Error.Class+import Control.Monad.Phased.Class++instance MonadState s m => MonadState s (PhasedT m) where+ state = lift . state++instance MonadReader r m => MonadReader r (PhasedT m) where+ ask = lift ask+ local f = PhasedT . local f . liftM (either (Left . local f) Right) . unPhasedT++instance (MonadError e m) => MonadError e (PhasedT m) where+ throwError = lift . throwError+ catchError pa ph = mapPhasedT (`catchError` (unPhasedT . ph)) pa+
+ src/Control/Monad/Phased/Class.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE+ MultiParamTypeClasses,+ UndecidableInstances,+ FlexibleInstances,+ TupleSections+ #-}+module Control.Monad.Phased.Class where++import Control.Monad.Trans.Class+import Control.Monad.Trans.Phased+import Control.Monad.Trans.AnyCont++class Monad m => MonadPhased m where+ later :: m a -> m a+ interleavePhasesWith :: (a -> b -> c) -> m a -> m b -> m c+ mergePhases :: m a -> m a++iap :: MonadPhased m => m (a -> b) -> m a -> m b+iap = interleavePhasesWith ($)++runInterleaved :: (MonadPhased m) => [m a] -> m [a]+runInterleaved = foldr (interleavePhasesWith (:)) (return [])++forInterleavedM x = runInterleaved . flip map x++defer :: MonadPhased m => m ()+defer = later (return ())++instance Monad m => MonadPhased (PhasedT m) where+ later = PhasedT . return . Left+ interleavePhasesWith p (PhasedT mx) (PhasedT my) = PhasedT $ do+ x <- mx+ y <- my+ return $ case (x,y) of+ (Right a, Right b) -> Right (p a b)+ _ -> Left $ interleavePhasesWith p (stall x) (stall y)+ where stall = either id return+ mergePhases = lift . runPhasedT++instance MonadPhased m => MonadPhased (AnyContT m) where+ later = lift . later . flip runAnyContT return+ interleavePhasesWith p mx my = + anyContT $ (>>=) $ interleavePhasesWith p (runAnyContT mx return) (runAnyContT my return)+ mergePhases ma = anyContT (mergePhases (runAnyContT ma return) >>= )++
+ src/Control/Monad/Trans/AnyCont.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE+ RankNTypes+ #-}+module Control.Monad.Trans.AnyCont where++import Control.Applicative+import Control.Monad.Cont++newtype AnyContT m a = AnyContT { unAnyContT :: forall r . ContT r m a }++instance Functor (AnyContT m) where+ fmap f p = AnyContT $ fmap f . unAnyContT $ p++instance Applicative (AnyContT m) where+ pure a = AnyContT $ pure a+ f <*> v = AnyContT $ unAnyContT f <*> unAnyContT v++instance Monad m => Monad (AnyContT m) where+ AnyContT f >>= k = AnyContT $ f >>= unAnyContT . k+ return a = AnyContT $ return a+ fail s = AnyContT (ContT (\_ -> fail s))+ +instance MonadIO m => MonadIO (AnyContT m) where+ liftIO = lift . liftIO++instance MonadTrans AnyContT where+ lift ma = AnyContT (lift ma)++runAnyContT :: AnyContT m a -> (forall r . (a -> m r) -> m r)+runAnyContT = runContT . unAnyContT+anyContT :: (forall r . (a -> m r) -> m r) -> AnyContT m a+anyContT f = AnyContT (ContT f)++withAnyContT :: (forall r . (b -> m r) -> (a -> m r)) -> AnyContT m a -> AnyContT m b+withAnyContT f m = anyContT $ runAnyContT m . f++mapAnyContT :: (forall r . m r -> m r) -> AnyContT m a -> AnyContT m a+mapAnyContT f m = anyContT $ f . runAnyContT m+
+ src/Control/Monad/Trans/Phased.hs view
@@ -0,0 +1,33 @@+module Control.Monad.Trans.Phased where++import Control.Monad+import Control.Applicative+import Control.Monad.Trans.Class+import Control.Monad.IO.Class++newtype PhasedT m a = PhasedT { unPhasedT :: m (Either (PhasedT m a) a) }++instance Functor m => Functor (PhasedT m) where+ fmap f = PhasedT . fmap (either (Left . fmap f) (Right . f)) . unPhasedT++instance (Functor m, Monad m) => Applicative (PhasedT m) where+ pure = return+ (<*>) = ap++instance Monad m => Monad (PhasedT m) where+ k >>= f = PhasedT $ unPhasedT k >>= either (return . Left . (>>= f)) (unPhasedT . f)+ return = PhasedT . return . Right+ fail = PhasedT . fail++instance MonadTrans PhasedT where+ lift = PhasedT . liftM Right++runPhasedT :: Monad m => PhasedT m a -> m a+runPhasedT = either runPhasedT return <=< unPhasedT++instance MonadIO m => MonadIO (PhasedT m) where+ liftIO = PhasedT . liftM Right . liftIO++mapPhasedT :: Monad n => (m (Either (PhasedT m a) a) -> n (Either (PhasedT m a) b)) -> PhasedT m a -> PhasedT n b+mapPhasedT f (PhasedT x) = PhasedT $ return (either (Left . (mapPhasedT f)) Right) `ap` f x+
+ src/LLVM/General.hs view
@@ -0,0 +1,7 @@+-- | An interface to use LLVM in all capacities+module LLVM.General (+ module LLVM.General.Module+ ) where++import LLVM.General.Module+
+ src/LLVM/General/AST.hs view
@@ -0,0 +1,53 @@+-- | This module and descendants define AST data types to represent LLVM code.+-- Note that these types are designed for fidelity rather than convenience - if the truth+-- of what LLVM supports is less than pretty, so be it.+module LLVM.General.AST (+ Module(..), defaultModule,+ Definition(..),+ Global(GlobalVariable, GlobalAlias, Function), + globalVariableDefaults,+ globalAliasDefaults,+ functionDefaults,+ Parameter(..),+ BasicBlock(..),+ module LLVM.General.AST.Instruction,+ module LLVM.General.AST.Name,+ module LLVM.General.AST.Operand,+ module LLVM.General.AST.Type+ ) where++import LLVM.General.AST.Name+import LLVM.General.AST.Type+import LLVM.General.AST.Global+import LLVM.General.AST.Operand+import LLVM.General.AST.Instruction+import LLVM.General.AST.DataLayout++-- | Any thing which can be at the top level of a 'Module'+data Definition + = GlobalDefinition Global+ | TypeDefinition Name (Maybe Type)+ | MetadataNodeDefinition MetadataNodeID [Operand]+ | NamedMetadataDefinition String [MetadataNodeID]+ | ModuleInlineAssembly String+ deriving (Eq, Read, Show)++-- | <http://llvm.org/docs/LangRef.html#modulestructure>+data Module = + Module {+ moduleName :: String,+ -- | a 'DataLayout', if specified, must match that of the eventual code generator+ moduleDataLayout :: Maybe DataLayout, + moduleTargetTriple :: Maybe String,+ moduleDefinitions :: [Definition]+ } + deriving (Eq, Read, Show)++-- | helper for making 'Module's+defaultModule = + Module {+ moduleName = "<string>",+ moduleDataLayout = Nothing,+ moduleTargetTriple = Nothing,+ moduleDefinitions = []+ }
+ src/LLVM/General/AST/AddrSpace.hs view
@@ -0,0 +1,8 @@+-- | Pointers exist in Address Spaces +module LLVM.General.AST.AddrSpace where++import Data.Word++-- | See <http://llvm.org/docs/LangRef.html#pointer-type>+data AddrSpace = AddrSpace Word32+ deriving (Eq, Ord, Read, Show)
+ src/LLVM/General/AST/Attribute.hs view
@@ -0,0 +1,38 @@+-- | Module to allow importing 'Attribute' distinctly qualified.+module LLVM.General.AST.Attribute where++import Data.Word++-- | <http://llvm.org/docs/LangRef.html#parameter-attributes>+data ParameterAttribute+ = ZeroExt+ | SignExt+ | InReg+ | SRet+ | NoAlias+ | ByVal+ | NoCapture+ | Nest+ deriving (Eq, Read, Show)++-- | <http://llvm.org/docs/LangRef.html#function-attributes>+data FunctionAttribute+ = NoReturn+ | NoUnwind+ | ReadNone+ | ReadOnly+ | NoInline+ | AlwaysInline+ | OptimizeForSize+ | StackProtect+ | StackProtectReq+ | Alignment Word32+ | NoRedZone+ | NoImplicitFloat+ | Naked+ | InlineHint+ | StackAlignment Word32+ | ReturnsTwice+ | UWTable+ | NonLazyBind+ deriving (Eq, Read, Show)
+ src/LLVM/General/AST/CallingConvention.hs view
@@ -0,0 +1,13 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+-- | Module to allow importing 'CallingConvention' distinctly qualified.+module LLVM.General.AST.CallingConvention where++import Data.Data+import Data.Word++-- | <http://llvm.org/docs/LangRef.html#callingconv>+data CallingConvention = C | Fast | Cold | GHC | Numbered Word32+ deriving (Eq, Read, Show, Typeable, Data)+
+ src/LLVM/General/AST/Constant.hs view
@@ -0,0 +1,218 @@+-- | A representation of LLVM constants+module LLVM.General.AST.Constant where++import Data.Word (Word32)+import Data.Bits ((.|.), (.&.), complement, testBit, shiftL)++import LLVM.General.AST.Type+import LLVM.General.AST.Name+import LLVM.General.AST.FloatingPointPredicate (FloatingPointPredicate)+import LLVM.General.AST.IntegerPredicate (IntegerPredicate)+import qualified LLVM.General.AST.Float as F++{- |+<http://llvm.org/docs/LangRef.html#constants>++N.B. - <http://llvm.org/docs/LangRef.html#constant-expressions>++Although constant expressions and instructions have many similarites, 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.+-} +data Constant+ = Int { integerBits :: Word32, integerValue :: Integer }+ | Float { floatValue :: F.SomeFloat }+ | Null { constantType :: Type }+ | Struct { isPacked :: Bool, memberValues :: [ Constant ] }+ | Array { memberType :: Type, memberValues :: [ Constant ] }+ | Vector { memberValues :: [ Constant ] }+ | Undef { constantType :: Type }+ | BlockAddress { blockAddressFunction :: Name, blockAddressBlock :: Name }+ | GlobalReference Name + | Add { + operand0 :: Constant,+ operand1 :: Constant+ }+ | FAdd {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | Sub {+ operand0 :: Constant,+ operand1 :: Constant+ }+ | FSub { + operand0 :: Constant, + operand1 :: Constant+ }+ | Mul { + operand0 :: Constant, + operand1 :: Constant+ }+ | FMul { + operand0 :: Constant, + operand1 :: Constant+ }+ | UDiv { + operand0 :: Constant, + operand1 :: Constant+ }+ | SDiv { + operand0 :: Constant, + operand1 :: Constant+ }+ | FDiv { + operand0 :: Constant, + operand1 :: Constant+ }+ | URem { + operand0 :: Constant, + operand1 :: Constant+ }+ | SRem { + operand0 :: Constant, + operand1 :: Constant+ }+ | FRem { + operand0 :: Constant, + operand1 :: Constant+ }+ | Shl { + operand0 :: Constant, + operand1 :: Constant+ }+ | LShr { + operand0 :: Constant, + operand1 :: Constant+ }+ | AShr { + operand0 :: Constant, + operand1 :: Constant+ }+ | And { + operand0 :: Constant, + operand1 :: Constant+ }+ | Or { + operand0 :: Constant, + operand1 :: Constant+ }+ | Xor { + operand0 :: Constant, + operand1 :: Constant+ }+ | GetElementPtr { + inBounds :: Bool,+ address :: Constant,+ indices :: [Constant]+ }+ | Trunc { + operand0 :: Constant,+ type' :: Type+ }+ | ZExt {+ operand0 :: Constant,+ type' :: Type+ }+ | SExt {+ operand0 :: Constant,+ type' :: Type+ }+ | FPToUI {+ operand0 :: Constant,+ type' :: Type+ }+ | FPToSI {+ operand0 :: Constant,+ type' :: Type+ }+ | UIToFP {+ operand0 :: Constant,+ type' :: Type+ }+ | SIToFP {+ operand0 :: Constant,+ type' :: Type+ }+ | FPTrunc {+ operand0 :: Constant,+ type' :: Type+ }+ | FPExt {+ operand0 :: Constant,+ type' :: Type+ }+ | PtrToInt {+ operand0 :: Constant,+ type' :: Type+ }+ | IntToPtr {+ operand0 :: Constant,+ type' :: Type+ }+ | BitCast {+ operand0 :: Constant,+ type' :: Type+ }+ | ICmp {+ iPredicate :: IntegerPredicate,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | FCmp {+ fpPredicate :: FloatingPointPredicate,+ operand0 :: Constant,+ operand1 :: Constant+ }+ | Select { + condition' :: Constant,+ trueValue :: Constant,+ falseValue :: Constant+ }+ | ExtractElement { + vector :: Constant,+ index :: Constant+ }+ | InsertElement { + vector :: Constant,+ element :: Constant,+ index :: Constant+ }+ | ShuffleVector { + operand0 :: Constant,+ operand1 :: Constant,+ mask :: Constant+ }+ | ExtractValue { + aggregate :: Constant,+ indices' :: [Word32]+ }+ | InsertValue { + aggregate :: Constant,+ element :: Constant,+ indices' :: [Word32]+ }+ deriving (Eq, Ord, Read, Show)+++-- | Since LLVM types don't include signedness, there's ambiguity in interpreting+-- an constant as an Integer. The LLVM assembly printer prints integers as signed, but+-- cheats for 1-bit integers and prints them as 'true' or 'false'. That way it circuments the+-- otherwise awkward fact that a twos complement 1-bit number only has the values -1 and 0.+signedIntegerValue :: Constant -> Integer+signedIntegerValue (Int nBits' bits) =+ let nBits = fromIntegral nBits'+ in+ if bits `testBit` (nBits - 1) then bits .|. (-1 `shiftL` nBits) else bits++-- | This library's conversion from LLVM C++ objects will always produce integer constants+-- as unsigned, so this function in many cases is not necessary. However, nothing's to keep+-- stop direct construction of an 'Int' with a negative 'integerValue'. There's nothing in principle+-- wrong with such a value - it has perfectly good low order bits like any integer, and will be used+-- as such, likely producing the intended result if lowered to C++. If, however one wishes to interpret+-- an 'Int' of unknown provenance as unsigned, then this function will serve.+unsignedIntegerValue :: Constant -> Integer+unsignedIntegerValue (Int nBits bits) =+ bits .&. (complement (-1 `shiftL` (fromIntegral nBits)))+
+ src/LLVM/General/AST/DataLayout.hs view
@@ -0,0 +1,51 @@+-- | <http://llvm.org/docs/LangRef.html#data-layout>+module LLVM.General.AST.DataLayout where++import Data.Word++import Data.Map (Map)+import qualified Data.Map as Map+import Data.Set (Set)++import LLVM.General.AST.AddrSpace++-- | Little Endian is the one true way :-). Sadly, we must support the infidels.+data Endianness = LittleEndian | BigEndian+ deriving (Eq, Ord, Read, Show)++-- | An AlignmentInfo describes how a given type must and would best be aligned+data AlignmentInfo = AlignmentInfo {+ abiAlignment :: Word32,+ preferredAlignment :: Word32+ }+ deriving (Eq, Ord, Read, Show)++-- | A type of type for which 'AlignmentInfo' may be specified+data AlignType+ = IntegerAlign+ | VectorAlign+ | FloatAlign+ | AggregateAlign+ | StackAlign+ deriving (Eq, Ord, Read, Show)++-- | a description of the various data layout properties which may be used during+-- optimization+data DataLayout = DataLayout {+ endianness :: Maybe Endianness,+ stackAlignment :: Maybe Word32,+ pointerLayouts :: Map AddrSpace (Word32, AlignmentInfo),+ typeLayouts :: Map (AlignType, Word32) AlignmentInfo,+ nativeSizes :: Maybe (Set Word32)+ }+ deriving (Eq, Ord, Read, Show)++-- | a 'DataLayout' which specifies nothing+defaultDataLayout = DataLayout {+ endianness = Nothing,+ stackAlignment = Nothing,+ pointerLayouts = Map.empty,+ typeLayouts = Map.empty,+ nativeSizes = Nothing+ }+
+ src/LLVM/General/AST/Float.hs view
@@ -0,0 +1,19 @@+-- | This module provides a sub-namespace for a type to support the various sizes of floating point+-- numbers LLVM supports. It is most definitely intended to be imported qualified.+module LLVM.General.AST.Float where++import Prelude as P+import Data.Word (Word16, Word64)++-- | A type summing up the various float types.+-- N.B. Note that in the constructors with multiple fields, the lower significance bits are on the right+-- - e.g. Quadruple highbits lowbits+data SomeFloat+ = Half Word16 + | Single Float+ | Double P.Double+ | Quadruple Word64 Word64+ | X86_FP80 Word16 Word64+ | PPC_FP128 Word64 Word64+ deriving (Eq, Ord, Read, Show)+
+ src/LLVM/General/AST/FloatingPointPredicate.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE+ DeriveDataTypeable + #-} +-- | Predicates for the 'LLVM.General.AST.Instruction.FCmp' instruction+module LLVM.General.AST.FloatingPointPredicate where++import Data.Data++-- | <http://llvm.org/docs/LangRef.html#fcmp-instruction>+data FloatingPointPredicate+ = False+ | OEQ+ | OGT+ | OGE+ | OLT+ | OLE+ | ONE+ | ORD+ | UNO+ | UEQ+ | UGT+ | UGE+ | ULT+ | ULE+ | UNE+ | True+ deriving (Eq, Ord, Read, Show, Data, Typeable)+++
+ src/LLVM/General/AST/Global.hs view
@@ -0,0 +1,109 @@+-- | 'Global's - top-level values in 'Module's - and supporting structures.+module LLVM.General.AST.Global where++import Data.Word++import LLVM.General.AST.Name+import LLVM.General.AST.Type+import LLVM.General.AST.Constant (Constant)+import LLVM.General.AST.AddrSpace+import LLVM.General.AST.Instruction (Named, Instruction, Terminator)+import qualified LLVM.General.AST.Linkage as L+import qualified LLVM.General.AST.Visibility as V+import qualified LLVM.General.AST.CallingConvention as CC+import qualified LLVM.General.AST.Attribute as A++-- | <http://llvm.org/doxygen/classllvm_1_1GlobalValue.html>+data Global+ -- | <http://llvm.org/docs/LangRef.html#global-variables>+ = GlobalVariable {+ name :: Name,+ linkage :: L.Linkage,+ visibility :: V.Visibility,+ isThreadLocal :: Bool,+ addrSpace :: AddrSpace,+ hasUnnamedAddr :: Bool,+ isConstant :: Bool,+ type' :: Type,+ initializer :: Maybe Constant,+ section :: Maybe String,+ alignment :: Word32+ }+ -- | <http://llvm.org/docs/LangRef.html#aliases>+ | GlobalAlias {+ name :: Name,+ linkage :: L.Linkage,+ visibility :: V.Visibility,+ type' :: Type,+ aliasee :: Constant+ }+ -- | <http://llvm.org/docs/LangRef.html#functions>+ | Function {+ linkage :: L.Linkage,+ visibility :: V.Visibility,+ callingConvention :: CC.CallingConvention,+ returnAttributes :: [A.ParameterAttribute],+ returnType :: Type,+ name :: Name,+ parameters :: ([Parameter],Bool),+ functionAttributes :: [A.FunctionAttribute],+ section :: Maybe String,+ alignment :: Word32,+ basicBlocks :: [BasicBlock]+ }+ deriving (Eq, Read, Show)++-- | 'Parameter's for 'Function's+data Parameter = Parameter Type Name [A.ParameterAttribute]+ deriving (Eq, Read, Show)++-- | <http://llvm.org/doxygen/classllvm_1_1BasicBlock.html>+-- LLVM code in a function is a sequence of 'BasicBlock's each with a label,+-- some instructions, and a terminator.+data BasicBlock = BasicBlock Name [Named Instruction] (Named Terminator)+ deriving (Eq, Read, Show)++-- | helper for making 'GlobalVariable's+globalVariableDefaults :: Global+globalVariableDefaults = + GlobalVariable {+ name = undefined,+ linkage = L.External,+ visibility = V.Default,+ isThreadLocal = False,+ addrSpace = AddrSpace 0,+ hasUnnamedAddr = False,+ isConstant = False,+ type' = undefined,+ initializer = Nothing,+ section = Nothing,+ alignment = 0+ }++-- | helper for making 'GlobalAlias's+globalAliasDefaults :: Global+globalAliasDefaults =+ GlobalAlias {+ name = undefined,+ linkage = L.External,+ visibility = V.Default,+ type' = undefined,+ aliasee = undefined+ }++-- | helper for making 'Function's+functionDefaults :: Global+functionDefaults = + Function {+ linkage = L.External,+ visibility = V.Default,+ callingConvention = CC.C,+ returnAttributes = [],+ returnType = undefined,+ name = undefined,+ parameters = undefined,+ functionAttributes = [],+ section = Nothing,+ alignment = 0,+ basicBlocks = []+ }
+ src/LLVM/General/AST/InlineAssembly.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+-- | A representation of an LLVM inline assembly+module LLVM.General.AST.InlineAssembly where++import Data.Data++import LLVM.General.AST.Type++-- | the dialect of assembly used in an inline assembly string+-- <http://en.wikipedia.org/wiki/X86_assembly_language#Syntax>+data Dialect+ = ATTDialect+ | IntelDialect+ deriving (Eq, Read, Show, Typeable, Data)++-- | <http://llvm.org/docs/LangRef.html#inline-assembler-expressions>+-- to be used through 'LLVM.General.AST.Operand.CallableOperand' with a+-- 'LLVM.General.AST.Instruction.Call' instruction+data InlineAssembly+ = InlineAssembly {+ type' :: Type,+ assembly :: String,+ constraints :: String,+ hasSideEffects :: Bool,+ alignStack :: Bool,+ dialect :: Dialect+ }+ deriving (Eq, Read, Show)
+ src/LLVM/General/AST/Instruction.hs view
@@ -0,0 +1,389 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+-- | LLVM instructions +-- <http://llvm.org/docs/LangRef.html#instruction-reference>+module LLVM.General.AST.Instruction where++import Data.Data+import Data.Word++import LLVM.General.AST.Type+import LLVM.General.AST.Name+import LLVM.General.AST.Constant+import LLVM.General.AST.Operand+import LLVM.General.AST.IntegerPredicate (IntegerPredicate)+import LLVM.General.AST.FloatingPointPredicate (FloatingPointPredicate)+import LLVM.General.AST.RMWOperation (RMWOperation)+import LLVM.General.AST.CallingConvention (CallingConvention)+import LLVM.General.AST.Attribute (ParameterAttribute, FunctionAttribute)++-- | <http://llvm.org/docs/LangRef.html#metadata-nodes-and-metadata-strings>+-- Metadata can be attached to an instruction+type InstructionMetadata = [(String, MetadataNode)]++-- | <http://llvm.org/docs/LangRef.html#terminators>+data Terminator + = Ret { + returnOperand :: Maybe Operand,+ metadata' :: InstructionMetadata+ }+ | CondBr { + condition :: Operand, + trueDest :: Name, + falseDest :: Name,+ metadata' :: InstructionMetadata+ }+ | Br { + dest :: Name,+ metadata' :: InstructionMetadata+ }+ | Switch {+ operand0' :: Operand,+ defaultDest :: Name,+ dests :: [(Constant, Name)],+ metadata' :: InstructionMetadata+ }+ | IndirectBr {+ operand0' :: Operand,+ possibleDests :: [Name],+ metadata' :: InstructionMetadata+ }+ | Invoke {+ callingConvention' :: CallingConvention,+ returnAttributes' :: [ParameterAttribute],+ function' :: CallableOperand,+ arguments' :: [(Operand, [ParameterAttribute])],+ functionAttributes' :: [FunctionAttribute],+ returnDest :: Name,+ exceptionDest :: Name,+ metadata' :: InstructionMetadata+ }+ | Resume {+ operand0' :: Operand,+ metadata' :: InstructionMetadata+ }+ | Unreachable {+ metadata' :: InstructionMetadata+ }+ deriving (Eq, Read, Show)++-- | <http://llvm.org/docs/LangRef.html#atomic-memory-ordering-constraints>+-- <http://llvm.org/docs/Atomics.html>+data MemoryOrdering+ = Unordered+ | Monotonic+ | Acquire+ | Release+ | AcquireRelease+ | SequentiallyConsistent+ deriving (Eq, Ord, Read, Show, Data, Typeable)++-- | An 'Atomicity' describes constraints on the visibility of effects of an atomic instruction+data Atomicity = Atomicity { + crossThread :: Bool, -- ^ <http://llvm.org/docs/LangRef.html#singlethread>+ memoryOrdering :: MemoryOrdering+ }+ deriving (Eq, Ord, Read, Show)++-- | For the redoubtably complex 'LandingPad' instruction+data LandingPadClause+ = Catch Constant+ | Filter Constant+ deriving (Eq, Ord, Read, Show)++-- | non-terminator instructions:+-- <http://llvm.org/docs/LangRef.html#binaryops>+-- <http://llvm.org/docs/LangRef.html#bitwiseops>+-- <http://llvm.org/docs/LangRef.html#memoryops>+-- <http://llvm.org/docs/LangRef.html#otherops>+data Instruction+ = Add { + nsw :: Bool,+ nuw :: Bool,+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | FAdd {+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | Sub {+ nsw :: Bool,+ nuw :: Bool,+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | FSub { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Mul { + nsw :: Bool, + nuw :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata + }+ | FMul { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | UDiv { + exact :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | SDiv { + exact :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | FDiv { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | URem { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | SRem { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | FRem { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Shl { + nsw :: Bool, + nuw :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | LShr { + exact :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | AShr { + exact :: Bool, + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | And { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Or { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Xor { + operand0 :: Operand, + operand1 :: Operand, + metadata :: InstructionMetadata+ }+ | Alloca { + allocatedType :: Type,+ numElements :: Maybe Operand,+ alignment :: Word32,+ metadata :: InstructionMetadata+ }+ | Load {+ volatile :: Bool, + address :: Operand,+ maybeAtomicity :: Maybe Atomicity,+ alignment :: Word32,+ metadata :: InstructionMetadata+ }+ | Store {+ volatile :: Bool, + address :: Operand,+ value :: Operand,+ maybeAtomicity :: Maybe Atomicity,+ alignment :: Word32,+ metadata :: InstructionMetadata+ }+ | GetElementPtr { + inBounds :: Bool,+ address :: Operand,+ indices :: [Operand],+ metadata :: InstructionMetadata+ }+ | Fence { + atomicity :: Atomicity,+ metadata :: InstructionMetadata + }+ | CmpXchg { + volatile :: Bool,+ address :: Operand,+ expected :: Operand,+ replacement :: Operand,+ atomicity :: Atomicity,+ metadata :: InstructionMetadata + }+ | AtomicRMW { + volatile :: Bool,+ rmwOperation :: RMWOperation,+ address :: Operand,+ value :: Operand,+ atomicity :: Atomicity,+ metadata :: InstructionMetadata + }+ | Trunc { + operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata + }+ | ZExt {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata + }+ | SExt {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | FPToUI {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | FPToSI {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | UIToFP {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | SIToFP {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | FPTrunc {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | FPExt {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | PtrToInt {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | IntToPtr {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | BitCast {+ operand0 :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata+ }+ | ICmp {+ iPredicate :: IntegerPredicate,+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | FCmp {+ fpPredicate :: FloatingPointPredicate,+ operand0 :: Operand,+ operand1 :: Operand,+ metadata :: InstructionMetadata+ }+ | Phi {+ type' :: Type,+ incomingValues :: [ (Operand, Name) ],+ metadata :: InstructionMetadata+ } + | Call {+ isTailCall :: Bool,+ callingConvention :: CallingConvention,+ returnAttributes :: [ParameterAttribute],+ function :: CallableOperand,+ arguments :: [(Operand, [ParameterAttribute])],+ functionAttributes :: [FunctionAttribute],+ metadata :: InstructionMetadata+ }+ | Select { + condition' :: Operand,+ trueValue :: Operand,+ falseValue :: Operand,+ metadata :: InstructionMetadata+ }+ | VAArg { + argList :: Operand,+ type' :: Type,+ metadata :: InstructionMetadata + }+ | ExtractElement { + vector :: Operand,+ index :: Operand,+ metadata :: InstructionMetadata + }+ | InsertElement { + vector :: Operand,+ element :: Operand,+ index :: Operand,+ metadata :: InstructionMetadata+ }+ | ShuffleVector { + operand0 :: Operand,+ operand1 :: Operand,+ mask :: Constant,+ metadata :: InstructionMetadata+ }+ | ExtractValue { + aggregate :: Operand,+ indices' :: [Word32],+ metadata :: InstructionMetadata+ }+ | InsertValue { + aggregate :: Operand,+ element :: Operand,+ indices' :: [Word32],+ metadata :: InstructionMetadata+ }+ | LandingPad { + type' :: Type,+ personalityFunction :: Operand,+ cleanup :: Bool,+ clauses :: [LandingPadClause],+ metadata :: InstructionMetadata + }+ deriving (Eq, Read, Show)++-- | Instances of instructions may be given a name, allowing their results to be referenced as 'Operand's.+-- Sometimes instructions - e.g. a call to a function returning void - don't need names.+data Named a + = Name := a+ | Do a+ deriving (Eq, Read, Show)
+ src/LLVM/General/AST/IntegerPredicate.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE+ DeriveDataTypeable + #-} +-- | Predicates for the 'LLVM.General.AST.Instruction.ICmp' instruction+module LLVM.General.AST.IntegerPredicate where++import Data.Data++-- | <http://llvm.org/docs/LangRef.html#icmp-instruction>+data IntegerPredicate+ = EQ+ | NE+ | UGT+ | UGE+ | ULT+ | ULE+ | SGT+ | SGE+ | SLT+ | SLE+ deriving (Eq, Ord, Read, Show, Data, Typeable)+++
+ src/LLVM/General/AST/Linkage.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+ +-- | Module to allow importing 'Linkage' distinctly qualified.+module LLVM.General.AST.Linkage where++import Data.Data++-- | <http://llvm.org/docs/LangRef.html#linkage>+data Linkage+ = Private+ | LinkerPrivate+ | LinkerPrivateWeak+ | Internal+ | AvailableExternally+ | LinkOnce+ | Weak+ | Common+ | Appending+ | ExternWeak+ | LinkOnceODR+ | WeakODR+ | External+ | DLLImport+ | DLLExport+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/General/AST/Name.hs view
@@ -0,0 +1,31 @@+-- | Names as used in LLVM IR+module LLVM.General.AST.Name where++import Data.Word++{- |+Objects of various sorts in LLVM IR are identified by address in the LLVM C++ API, and+may be given a string name. When printed to (resp. read from) human-readable LLVM assembly, objects without+string names are numbered sequentially (resp. must be numbered sequentially). String names may be quoted, and+are quoted when printed if they would otherwise be misread - e.g. when containing special characters. ++> 7++means the seventh unnamed object, while++> "7"++means the object named with the string "7".++This libraries handling of 'UnName's during translation of the AST down into C++ IR is somewhat more+forgiving than the LLVM assembly parser: it does not require that unnamed values be numbered sequentially;+however, the numbers of 'UnName's passed into C++ cannot be preserved in the C++ objects. If the C++ IR is+printed as assembly or translated into a Haskell AST, unnamed nodes will be renumbered sequentially. Thus+unnamed node numbers should be thought of as having any scope limited to the 'LLVM.General.AST.Module' in+which they are used.+-}+data Name + = Name String -- ^ a string name + | UnName Word -- ^ a number for a nameless thing+ deriving (Eq, Ord, Read, Show)+
+ src/LLVM/General/AST/Operand.hs view
@@ -0,0 +1,33 @@+-- | A type to represent operands to LLVM 'LLVM.General.AST.Instruction.Instruction's+module LLVM.General.AST.Operand where+ +import Data.Word++import LLVM.General.AST.Name+import LLVM.General.AST.Constant+import LLVM.General.AST.InlineAssembly++-- | A 'MetadataNodeID' is a number for identifying a metadata node.+-- Note this is different from "named metadata", which are represented with+-- 'LLVM.General.AST.NamedMetadataDefinition'.+newtype MetadataNodeID = MetadataNodeID Word+ deriving (Eq, Ord, Read, Show)++-- | <http://llvm.org/docs/LangRef.html#metadata>+data MetadataNode + = MetadataNode [Operand]+ | MetadataNodeReference MetadataNodeID+ deriving (Eq, Ord, Read, Show)++-- | An 'Operand' is roughly that which is an argument to an 'LLVM.General.AST.Instruction.Instruction'+data Operand + -- | %foo+ = LocalReference Name+ -- | 'Constant's include 'LLVM.General.AST.Constant.GlobalReference', for \@foo+ | ConstantOperand Constant+ | MetadataStringOperand String+ | MetadataNodeOperand MetadataNode+ deriving (Eq, Ord, Read, Show)++-- | The 'LLVM.General.AST.Instruction.Call' instruction is special: the callee can be inline assembly+type CallableOperand = Either InlineAssembly Operand
+ src/LLVM/General/AST/RMWOperation.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE+ DeriveDataTypeable + #-} +-- | Operations for the 'LLVM.General.AST.Instruction.AtomicRMW' instruction+module LLVM.General.AST.RMWOperation where++import Data.Data++-- | <http://llvm.org/docs/LangRef.html#atomicrmw-instruction>+data RMWOperation+ = Xchg+ | Add+ | Sub+ | And+ | Nand+ | Or+ | Xor+ | Max+ | Min+ | UMax+ | UMin+ deriving (Eq, Ord, Read, Show, Data, Typeable)+++
+ src/LLVM/General/AST/Type.hs view
@@ -0,0 +1,40 @@+-- | A representation of an LLVM type+module LLVM.General.AST.Type where++import LLVM.General.AST.AddrSpace+import LLVM.General.AST.Name++import Data.Word (Word32, Word64)++-- | LLVM supports some special formats floating point format. This type is to distinguish those format.+-- I believe it's treated as a format for "a" float, as opposed to a vector of two floats, because+-- its intended usage is to represent a single number with a combined significand.+data FloatingPointFormat+ = IEEE+ | DoubleExtended+ | PairOfFloats+ deriving (Eq, Ord, Read, Show)++-- | <http://llvm.org/docs/LangRef.html#type-system>+data Type+ -- | <http://llvm.org/docs/LangRef.html#void-type>+ = VoidType+ -- | <http://llvm.org/docs/LangRef.html#integer-type>+ | IntegerType { typeBits :: Word32 }+ -- | <http://llvm.org/docs/LangRef.html#pointer-type>+ | PointerType { pointerReferent :: Type, pointerAddrSpace :: AddrSpace }+ -- | <http://llvm.org/docs/LangRef.html#floating-point-types>+ | FloatingPointType { typeBits :: Word32, floatingPointFormat :: FloatingPointFormat }+ -- | <http://llvm.org/docs/LangRef.html#function-type>+ | FunctionType { resultType :: Type, argumentTypes :: [Type], isVarArg :: Bool }+ -- | <http://llvm.org/docs/LangRef.html#vector-type>+ | VectorType { nVectorElements :: Word32, elementType :: Type }+ -- | <http://llvm.org/docs/LangRef.html#structure-type>+ | StructureType { isPacked :: Bool, elementTypes :: [Type] }+ -- | <http://llvm.org/docs/LangRef.html#array-type>+ | ArrayType { nArrayElements :: Word64, elementType :: Type }+ -- | <http://llvm.org/docs/LangRef.html#opaque-structure-types>+ | NamedTypeReference Name+ -- | <http://llvm.org/docs/LangRef.html#metadata-type>+ | MetadataType -- only to be used as a parameter type for a few intrinsics+ deriving (Eq, Ord, Read, Show)
+ src/LLVM/General/AST/Visibility.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+-- | Module to allow importing 'Visibility' distinctly qualified.+module LLVM.General.AST.Visibility where++import Data.Data++-- | <http://llvm.org/docs/LangRef.html#visibility>+data Visibility = Default | Hidden | Protected+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/General/CodeGenOpt.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+-- | Code generation options, used in specifying TargetMachine+module LLVM.General.CodeGenOpt where++import Data.Data++-- | <http://llvm.org/doxygen/namespacellvm_1_1CodeGenOpt.html>+data Level+ = None+ | Less+ | Default+ | Aggressive+ deriving (Eq, Ord, Read, Show, Typeable, Data)
+ src/LLVM/General/CodeModel.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+-- | Relocations, used in specifying TargetMachine+module LLVM.General.CodeModel where++import Data.Data++-- | <http://llvm.org/doxygen/namespacellvm_1_1CodeModel.html>+data Model+ = Default+ | JITDefault+ | Small+ | Kernel+ | Medium+ | Large+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/General/Context.hs view
@@ -0,0 +1,7 @@+-- | functions for the LLVM Context object which holds thread-scope state+module LLVM.General.Context (+ Context,+ withContext+ ) where++import LLVM.General.Internal.Context
+ src/LLVM/General/Diagnostic.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+-- | Diagnostics describe parse errors+module LLVM.General.Diagnostic (+ DiagnosticKind(..),+ Diagnostic(..),+ diagnosticDisplay+ ) where++import Data.Data++-- | What kind of problem does a diagnostic describe?+data DiagnosticKind + = ErrorKind+ | WarningKind+ | NoteKind+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | A 'Diagnostic' described a problem during parsing of LLVM IR+data Diagnostic = Diagnostic {+ lineNumber :: Int,+ columnNumber :: Int,+ diagnosticKind :: DiagnosticKind,+ filename :: String,+ message :: String,+ lineContents :: String+ }+ deriving (Eq, Ord, Read, Show)++-- | Convert a 'Diagnostic' to a printable form.+diagnosticDisplay :: Diagnostic -> String+diagnosticDisplay d = + (filename d) ++ ":" ++ show (lineNumber d) ++ ":" ++ show (columnNumber d)+ ++ ":\n" ++ show (diagnosticKind d) ++ ": " ++ (message d) ++ "\n"+ ++ (lineContents d) ++ "\n"
+ src/LLVM/General/ExecutionEngine.hs view
@@ -0,0 +1,9 @@+-- | Tools for JIT execution+module LLVM.General.ExecutionEngine (+ ExecutionEngine,+ withExecutionEngine,+ withModuleInEngine,+ findFunction+ ) where++import LLVM.General.Internal.ExecutionEngine
+ src/LLVM/General/Internal/Atomicity.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE+ TemplateHaskell,+ MultiParamTypeClasses,+ FlexibleInstances+ #-}++module LLVM.General.Internal.Atomicity where++import Control.Monad++import Data.Maybe++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI++import LLVM.General.Internal.Coding++import qualified LLVM.General.AST as A++genCodingInstance' [t| Maybe A.MemoryOrdering |] ''FFI.MemoryOrdering [+ (FFI.memoryOrderingNotAtomic, Nothing),+ (FFI.memoryOrderingUnordered, Just A.Unordered),+ (FFI.memoryOrderingMonotonic, Just A.Monotonic),+ (FFI.memoryOrderingAcquire, Just A.Acquire),+ (FFI.memoryOrderingRelease, Just A.Release),+ (FFI.memoryOrderingAcquireRelease, Just A.AcquireRelease),+ (FFI.memoryOrderingSequentiallyConsistent, Just A.SequentiallyConsistent)+ ]++instance Monad m => EncodeM m (Maybe A.Atomicity) (FFI.LLVMBool, FFI.MemoryOrdering) where+ encodeM a =+ return (,) `ap` encodeM (maybe False A.crossThread a) `ap` encodeM (liftM A.memoryOrdering a)++instance Monad m => DecodeM m (Maybe A.Atomicity) (FFI.LLVMBool, FFI.MemoryOrdering) where+ decodeM (ss, ao) = return (liftM . A.Atomicity) `ap` decodeM ss `ap` decodeM ao++instance Monad m => EncodeM m A.Atomicity (FFI.LLVMBool, FFI.MemoryOrdering) where+ encodeM = encodeM . Just++instance Monad m => DecodeM m A.Atomicity (FFI.LLVMBool, FFI.MemoryOrdering) where+ decodeM = liftM fromJust . decodeM+
+ src/LLVM/General/Internal/Attribute.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE+ TemplateHaskell,+ MultiParamTypeClasses,+ FlexibleInstances+ #-}++module LLVM.General.Internal.Attribute where++import Language.Haskell.TH+import Language.Haskell.TH.Quote++import Data.Data+import Data.List (genericSplitAt)++import Data.Bits++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI++import qualified LLVM.General.AST.Attribute as A.A++import LLVM.General.Internal.Coding++$(do+ let+ -- build an instance of the Coding class for lists of some kind of attribute+ genAttributeListCoding :: (Data a, Bits a) => TypeQ -> Name -> [(a, String)] -> DecsQ+ genAttributeListCoding type' ctn attributeData = do+ let+ lowZeroes :: Bits b => b -> Int+ lowZeroes b | testBit b 0 = 0+ lowZeroes b = 1 + lowZeroes (shiftR b 1)+ field :: Bits b => b -> (Int, Int)+ field b = + let s = lowZeroes b+ w = lowZeroes (complement (shiftR b s))+ in + (s,w)+ attributeData' = [(mkName n, b, s,w) | (b,n) <- attributeData, let (s,w) = field b ]+ let m = varT . mkName $ "m"+ TyConI (NewtypeD _ _ _ (NormalC ctcn _) _) <- reify ctn+ let zero = [| $(conE ctcn) 0 |]+ sequence [+ instanceD (sequence [classP ''Monad [m]]) [t| EncodeM $(m) [$(type')] $(conT ctn) |] [+ funD (mkName "encodeM") [+ clause [] (normalB [| return . (+ let + encodeAttribute a = $(+ caseE [| a |] $ flip map attributeData' $ \(n, b, s, w) ->+ let bQ = (dataToExpQ (const Nothing) b)+ in+ case w of+ 1 -> match (conP n []) (normalB bQ) []+ _ -> do + a <- newName "a"+ match + (conP n [varP a])+ (normalB [| ($(conE ctcn) (fromIntegral $(varE a) `shiftL` s)) .&. $(bQ) |])+ []+ )+ in+ foldl (.|.) $(zero) . map encodeAttribute+ ) |]) []+ ]+ ],+ + -- build a decoder which uses bit masking for multiple fields at once+ -- to eliminate multiple absent attributes in fewer tests+ instanceD (sequence [classP ''Monad [m]]) [t| DecodeM $(m) [$(type')] $(conT ctn) |] [+ funD (mkName "decodeM") [+ do+ bits <- newName "bits"+ clause [varP bits] (normalB + (let+ code :: (Data a, Bits a) => [ (Name, a, Int, Int) ] -- attrs to handle+ -> Int -- length (attrs), passed in to avoid recomputation+ -> (a, ExpQ) -- (<bitmask for all the given attrs>, <code to decode the given attrs>)+ code [(n, b, s, w)] _ = (+ b, + case w of+ 1 -> [| [ $(conE n) | testBit $(varE bits) s ] |]+ _-> [| + [ + $(do+ i' <- newName "i'"+ letE + [valD (conP ctcn [varP i']) (normalB [| i |]) []]+ [| $(conE n) (fromIntegral $(varE i')) |])+ | let i = ($(varE bits) .&. $(dataToExpQ (const Nothing) b)) `shiftR` s, + i /= $(zero)+ ]+ |]+ )+ code attrs nAttrs =+ let (nEarlyAttrs, nLateAttrs) = (nAttrs `div` 2, nAttrs - nEarlyAttrs)+ (earlyAttrs, lateAttrs) = genericSplitAt nEarlyAttrs attrs+ (earlyAttrBits, earlyAttrCode) = code earlyAttrs nEarlyAttrs+ (lateAttrBits, lateAttrCode) = code lateAttrs nLateAttrs+ attrBits = earlyAttrBits .|. lateAttrBits+ in+ (+ attrBits, + [| + if ($(varE bits) .&. $(dataToExpQ (const Nothing) attrBits) /= $(zero)) then+ ($earlyAttrCode ++ $lateAttrCode) + else+ []+ |]+ )+ in+ [| return $(snd $ code attributeData' (length attributeData')) |]+ )+ ) []+ ]+ ]+ ]++ pi <- genAttributeListCoding [t| A.A.ParameterAttribute |] ''FFI.ParamAttr [+ (FFI.paramAttrZExt, "A.A.ZeroExt"),+ (FFI.paramAttrSExt, "A.A.SignExt"),+ (FFI.paramAttrInReg, "A.A.InReg"),+ (FFI.paramAttrStructRet, "A.A.SRet"),+ (FFI.paramAttrNoAlias, "A.A.NoAlias"),+ (FFI.paramAttrByVal, "A.A.ByVal"),+ (FFI.paramAttrNoCapture, "A.A.NoCapture"),+ (FFI.paramAttrNest, "A.A.Nest")+ ]++ fi <- genAttributeListCoding [t| A.A.FunctionAttribute |] ''FFI.FunctionAttr [+ (FFI.functionAttrNoReturn, "A.A.NoReturn"),+ (FFI.functionAttrNoUnwind, "A.A.NoUnwind"),+ (FFI.functionAttrReadNone, "A.A.ReadNone"),+ (FFI.functionAttrReadOnly, "A.A.ReadOnly"),+ (FFI.functionAttrNoInline, "A.A.NoInline"),+ (FFI.functionAttrAlwaysInline, "A.A.AlwaysInline"),+ (FFI.functionAttrOptimizeForSize, "A.A.OptimizeForSize"),+ (FFI.functionAttrStackProtect, "A.A.StackProtect"),+ (FFI.functionAttrStackProtectReq, "A.A.StackProtectReq"),+ (FFI.functionAttrAlignment, "A.A.Alignment"),+ (FFI.functionAttrNoRedZone, "A.A.NoRedZone"),+ (FFI.functionAttrNoImplicitFloat, "A.A.NoImplicitFloat"),+ (FFI.functionAttrNaked, "A.A.Naked"),+ (FFI.functionAttrInlineHint, "A.A.InlineHint"),+ (FFI.functionAttrStackAlignment, "A.A.StackAlignment"),+ (FFI.functionAttrReturnsTwice, "A.A.ReturnsTwice"),+ (FFI.functionAttrUWTable, "A.A.UWTable"),+ (FFI.functionAttrNonLazyBind, "A.A.NonLazyBind")+ ]+ return (pi ++ fi)+ )+++
+ src/LLVM/General/Internal/BasicBlock.hs view
@@ -0,0 +1,27 @@+module LLVM.General.Internal.BasicBlock where++import Control.Monad+import Control.Monad.Trans+import Control.Monad.Phased+import Foreign.Ptr++import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.General.Internal.FFI.BasicBlock as FFI+import qualified LLVM.General.Internal.FFI.Iterate as FFI++import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.Coding+import LLVM.General.Internal.Instruction ()++import qualified LLVM.General.AST.Instruction as A++getBasicBlockTerminator :: Ptr FFI.BasicBlock -> DecodeAST (A.Named A.Terminator)+getBasicBlockTerminator = decodeM <=< (liftIO . FFI.getBasicBlockTerminator)++getNamedInstructions :: Ptr FFI.BasicBlock -> DecodeAST [A.Named A.Instruction]+getNamedInstructions b = do+ ffiInstructions <- liftIO $ FFI.getXs (FFI.getFirstInstruction b) FFI.getNextInstruction+ let n = length ffiInstructions+ forInterleavedM (take (n-1) ffiInstructions) $ decodeM++
+ src/LLVM/General/Internal/CallingConvention.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE+ MultiParamTypeClasses,+ TemplateHaskell,+ QuasiQuotes,+ FlexibleInstances+ #-}+module LLVM.General.Internal.CallingConvention where++import LLVM.General.Internal.Coding++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI++import qualified LLVM.General.AST.CallingConvention as A.CC++instance Monad m => EncodeM m A.CC.CallingConvention FFI.CallConv where+ encodeM cc = return $ + case cc of+ A.CC.C -> FFI.callConvC+ A.CC.Fast -> FFI.callConvFast+ A.CC.Cold -> FFI.callConvCold+ A.CC.GHC -> FFI.CallConv 10+ A.CC.Numbered cc' -> FFI.CallConv (fromIntegral cc')++instance Monad m => DecodeM m A.CC.CallingConvention FFI.CallConv where+ decodeM cc = return $ case cc of+ [FFI.callConvP|C|] -> A.CC.C+ [FFI.callConvP|Fast|] -> A.CC.Fast+ [FFI.callConvP|Cold|] -> A.CC.Cold+ FFI.CallConv 10 -> A.CC.GHC+ FFI.CallConv ci | ci >= 64 -> A.CC.Numbered (fromIntegral ci)
+ src/LLVM/General/Internal/Coding.hs view
@@ -0,0 +1,125 @@+{-# LANGUAGE+ TemplateHaskell,+ FlexibleInstances,+ FlexibleContexts,+ MultiParamTypeClasses,+ FunctionalDependencies,+ UndecidableInstances+ #-}+module LLVM.General.Internal.Coding where++import Language.Haskell.TH+import Language.Haskell.TH.Quote++import Control.Monad.AnyCont+import Control.Monad.IO.Class++import Data.Data (Data)+import Data.Word (Word32, Word64)+import Data.Int (Int32)++import Foreign.C+import Foreign.Ptr+import Foreign.Storable+import Foreign.Marshal.Alloc+import Foreign.Marshal.Array++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI++class EncodeM e h c where+ encodeM :: h -> e c++class DecodeM d h c where+ decodeM :: c -> d h++genCodingInstance :: Data h => TypeQ -> Name -> [(Integer, h)] -> Q [Dec]+genCodingInstance ht ctn ihs = do+ let n = const Nothing+ TyConI (NewtypeD _ _ _ (NormalC ctcn _) _) <- reify ctn+ [d| + instance Monad m => EncodeM m $(ht) $(conT ctn) where+ encodeM h = return $ $(+ caseE [| h |] [ match (dataToPatQ n h) (normalB (appE (conE ctcn) (litE (integerL i)))) [] | (i,h) <- ihs ] + )++ instance Monad m => DecodeM m $(ht) $(conT ctn) where+ decodeM i = return $ $(+ caseE [| i |] [ match (conP ctcn [litP (integerL i)]) (normalB (dataToExpQ n h)) [] | (i,h) <- ihs ]+ )+ |]++genCodingInstance' :: (Data c, Data h) => TypeQ -> Name -> [(c, h)] -> Q [Dec]+genCodingInstance' ht ctn chs = do+ let n = const Nothing+ [d| + instance Monad m => EncodeM m $(ht) $(conT ctn) where+ encodeM h = return $ $(+ caseE [| h |] [ match (dataToPatQ n h) (normalB (dataToExpQ n c)) [] | (c,h) <- chs ] + )++ instance Monad m => DecodeM m $(ht) $(conT ctn) where+ decodeM c = return $ $(+ caseE [| c |] [ match (dataToPatQ n c) (normalB (dataToExpQ n h)) [] | (c,h) <- chs ]+ )+ |]++allocaArray :: (Integral i, Storable a, MonadAnyCont IO m) => i -> m (Ptr a)+allocaArray p = anyContToM $ Foreign.Marshal.Array.allocaArray (fromIntegral p)++alloca :: (Storable a, MonadAnyCont IO m) => m (Ptr a)+alloca = anyContToM Foreign.Marshal.Alloc.alloca++peek :: (Storable a, MonadIO m) => Ptr a -> m a+peek p = liftIO $ Foreign.Storable.peek p++peekByteOff :: (Storable a, MonadIO m) => Ptr a -> Int -> m a+peekByteOff p i = liftIO $ Foreign.Storable.peekByteOff p i++poke :: (Storable a, MonadIO m) => Ptr a -> a -> m ()+poke p a = liftIO $ Foreign.Storable.poke p a++pokeByteOff :: (Storable a, MonadIO m) => Ptr a -> Int -> a -> m ()+pokeByteOff p i a = liftIO $ Foreign.Storable.pokeByteOff p i a++peekArray :: (Integral i, Storable a, MonadIO m) => i -> Ptr a -> m [a]+peekArray n p = liftIO $ Foreign.Marshal.Array.peekArray (fromIntegral n) p++instance (Monad m, EncodeM m h c, Storable c, MonadAnyCont IO m) => EncodeM m [h] (CUInt, Ptr c) where+ encodeM hs = do+ hs <- mapM encodeM hs+ (anyContToM $ \x -> Foreign.Marshal.Array.withArrayLen hs $ \n hs -> x (fromIntegral n, hs))++instance (Monad m, DecodeM m h c, Storable c, MonadIO m) => DecodeM m [h] (CUInt, Ptr c) where+ decodeM (n, ca) = do+ cs <- liftIO $ Foreign.Marshal.Array.peekArray (fromIntegral n) ca+ mapM decodeM cs++instance Monad m => EncodeM m Bool FFI.LLVMBool where+ encodeM False = return $ FFI.LLVMBool 0+ encodeM True = return $ FFI.LLVMBool 1++instance Monad m => DecodeM m Bool FFI.LLVMBool where+ decodeM (FFI.LLVMBool 0) = return $ False+ decodeM (FFI.LLVMBool 1) = return $ True++instance Monad m => EncodeM m Word32 CUInt where+ encodeM = return . fromIntegral++instance Monad m => EncodeM m Word64 CULong where+ encodeM = return . fromIntegral++instance Monad m => DecodeM m Word32 CUInt where+ decodeM = return . fromIntegral++instance Monad m => DecodeM m Word64 CULong where+ decodeM = return . fromIntegral++instance Monad m => EncodeM m Int32 CInt where+ encodeM = return . fromIntegral++instance Monad m => DecodeM m Int32 CInt where+ decodeM = return . fromIntegral++instance Monad m => DecodeM m Int CInt where+ decodeM = return . fromIntegral+
+ src/LLVM/General/Internal/Constant.hs view
@@ -0,0 +1,220 @@+{-# LANGUAGE+ TemplateHaskell,+ QuasiQuotes,+ TupleSections,+ MultiParamTypeClasses,+ FlexibleInstances,+ FlexibleContexts,+ ScopedTypeVariables+ #-}+module LLVM.General.Internal.Constant where++import qualified Language.Haskell.TH as TH+import qualified Language.Haskell.TH.Quote as TH+import qualified LLVM.General.Internal.InstructionDefs as ID++import Control.Applicative+import Data.Word (Word32, Word64)+import Data.Bits+import Control.Monad.State+import Control.Monad.AnyCont++import qualified Data.Map as Map+import Foreign.Ptr+import Foreign.Storable (Storable, sizeOf)++import qualified LLVM.General.Internal.FFI.Constant as FFI+import qualified LLVM.General.Internal.FFI.GlobalValue as FFI+import qualified LLVM.General.Internal.FFI.Instruction as FFI+import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.General.Internal.FFI.User as FFI+import qualified LLVM.General.Internal.FFI.Value as FFI++import qualified LLVM.General.AST.Constant as A (Constant)+import qualified LLVM.General.AST.Constant as A.C hiding (Constant)+import qualified LLVM.General.AST.Type as A+import qualified LLVM.General.AST.IntegerPredicate as A (IntegerPredicate)+import qualified LLVM.General.AST.FloatingPointPredicate as A (FloatingPointPredicate)+import qualified LLVM.General.AST.Float as A.F++import LLVM.General.Internal.Coding+import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.EncodeAST+import LLVM.General.Internal.Context+import LLVM.General.Internal.Type ()+import LLVM.General.Internal.IntegerPredicate ()+import LLVM.General.Internal.FloatingPointPredicate ()++allocaWords :: forall a m . (Storable a, MonadAnyCont IO m, Monad m, MonadIO m) => Word32 -> m (Ptr a)+allocaWords nBits = do+ allocaArray (((nBits-1) `div` (8*(fromIntegral (sizeOf (undefined :: a))))) + 1)++instance EncodeM EncodeAST A.Constant (Ptr FFI.Constant) where+ encodeM c = scopeAnyCont $ case c of+ A.C.Int { A.C.integerBits = bits, A.C.integerValue = v } -> do+ t <- encodeM (A.IntegerType bits)+ words <- encodeM [+ fromIntegral ((v `shiftR` (w*64)) .&. 0xffffffffffffffff) :: Word64+ | w <- [0 .. ((fromIntegral bits-1) `div` 64)] + ]+ liftIO $ FFI.constantIntOfArbitraryPrecision t words+ A.C.Float { A.C.floatValue = v } -> do+ Context context <- gets encodeStateContext+ let poke1 f = do+ let nBits = fromIntegral $ 8*(sizeOf f)+ words <- allocaWords nBits+ poke (castPtr words) f+ return (nBits, words)+ poke2 fh fl = do+ let nBits = fromIntegral $ 8*(sizeOf fh) + 8*(sizeOf fl)+ words <- allocaWords nBits+ pokeByteOff (castPtr words) 0 fl+ pokeByteOff (castPtr words) (sizeOf fl) fh+ return (nBits, words)+ (nBits, words) <- case v of+ A.F.Half f -> poke1 f+ A.F.Single f -> poke1 f+ A.F.Double f -> poke1 f+ A.F.X86_FP80 high low -> poke2 high low+ A.F.Quadruple high low -> poke2 high low+ A.F.PPC_FP128 high low -> poke2 high low+ notPairOfFloats <- encodeM $ case v of A.F.PPC_FP128 _ _ -> False; _ -> True+ nBits <- encodeM nBits+ liftIO $ FFI.constantFloatOfArbitraryPrecision context nBits words notPairOfFloats+ A.C.GlobalReference n -> FFI.upCast <$> referGlobal n+ A.C.BlockAddress f b -> do+ f' <- referGlobal f+ b' <- getBlockForAddress f b+ liftIO $ FFI.blockAddress (FFI.upCast f') b'+ A.C.Struct p ms -> do+ Context context <- gets encodeStateContext+ p <- encodeM p+ ms <- encodeM ms+ liftIO $ FFI.constStructInContext context ms p+ o -> $(do+ let constExprInfo = ID.outerJoin ID.astConstantRecs (ID.innerJoin ID.astInstructionRecs ID.instructionDefs)+ TH.caseE [| o |] $ do+ (name, (Just (TH.RecC n fs'), instrInfo)) <- Map.toList constExprInfo+ let fns = [ TH.mkName . TH.nameBase $ fn | (fn, _, _) <- fs' ]+ coreCall n = TH.dyn $ "FFI.constant" ++ n+ buildBody c = [ TH.bindS (TH.varP fn) [| encodeM $(TH.varE fn) |] | fn <- fns ]+ ++ [ TH.noBindS [| liftIO $(foldl TH.appE c (map TH.varE fns)) |] ]+ core <- case instrInfo of+ Just (_, iDef) -> do+ let opcode = TH.dataToExpQ (const Nothing) (ID.cppOpcode iDef)+ case ID.instructionKind iDef of+ ID.Binary -> return [| $(coreCall "BinaryOperator") $(opcode) |]+ ID.Cast -> return [| $(coreCall "Cast") $(opcode) |]+ _ -> return $ coreCall name+ Nothing -> if (name `elem` ["Vector", "Null", "Array"]) + then return $ coreCall name+ else []+ return $ TH.match+ (TH.recP n [(fn,) <$> (TH.varP . TH.mkName . TH.nameBase $ fn) | (fn, _, _) <- fs'])+ (TH.normalB (TH.doE (buildBody core)))+ []+ )++instance DecodeM DecodeAST A.Constant (Ptr FFI.Constant) where+ decodeM c = scopeAnyCont $ do+ let v = FFI.upCast c :: Ptr FFI.Value+ u = FFI.upCast c :: Ptr FFI.User+ t <- decodeM =<< liftIO (FFI.typeOf v)+ valueSubclassId <- liftIO $ FFI.getValueSubclassId v+ nOps <- liftIO $ FFI.getNumOperands u+ let globalRef = return A.C.GlobalReference `ap` (getGlobalName =<< liftIO (FFI.isAGlobalValue v))+ op = decodeM <=< liftIO . FFI.getConstantOperand c+ getConstantOperands = mapM op [0..nOps-1] + getConstantData = do+ let nElements = case t of+ A.VectorType n _ -> n+ A.ArrayType n _ | n <= (fromIntegral (maxBound :: Word32)) -> fromIntegral n+ forM [0..nElements-1] $ do+ decodeM <=< liftIO . FFI.getConstantDataSequentialElementAsConstant c . fromIntegral++ case valueSubclassId of+ [FFI.valueSubclassIdP|Function|] -> globalRef+ [FFI.valueSubclassIdP|GlobalAlias|] -> globalRef+ [FFI.valueSubclassIdP|GlobalVariable|] -> globalRef+ [FFI.valueSubclassIdP|ConstantInt|] -> do+ np <- alloca+ wsp <- liftIO $ FFI.getConstantIntWords c np+ n <- peek np+ words <- decodeM (n, wsp)+ return $ A.C.Int (A.typeBits t) (foldr (\b a -> (a `shiftL` 64) .|. fromIntegral (b :: Word64)) 0 words)+ [FFI.valueSubclassIdP|ConstantFP|] -> do+ let A.FloatingPointType nBits fmt = t+ ws <- allocaWords nBits+ liftIO $ FFI.getConstantFloatWords c ws+ A.C.Float <$> (+ case (nBits, fmt) of+ (16, A.IEEE) -> A.F.Half <$> peek (castPtr ws)+ (32, A.IEEE) -> A.F.Single <$> peek (castPtr ws)+ (64, A.IEEE) -> A.F.Double <$> peek (castPtr ws)+ (128, A.IEEE) -> A.F.Quadruple <$> peekByteOff (castPtr ws) 8 <*> peekByteOff (castPtr ws) 0+ (80, A.DoubleExtended) -> A.F.X86_FP80 <$> peekByteOff (castPtr ws) 8 <*> peekByteOff (castPtr ws) 0+ (128, A.PairOfFloats) -> A.F.PPC_FP128 <$> peekByteOff (castPtr ws) 8 <*> peekByteOff (castPtr ws) 0+ _ -> error $ "don't know how to decode floating point constant of type: " ++ show t+ )+ [FFI.valueSubclassIdP|ConstantPointerNull|] -> return $ A.C.Null t+ [FFI.valueSubclassIdP|ConstantAggregateZero|] -> return $ A.C.Null t+ [FFI.valueSubclassIdP|UndefValue|] -> return $ A.C.Undef t+ [FFI.valueSubclassIdP|BlockAddress|] -> + return A.C.BlockAddress + `ap` (getGlobalName =<< do liftIO $ FFI.isAGlobalValue =<< FFI.getBlockAddressFunction c)+ `ap` (getLocalName =<< do liftIO $ FFI.getBlockAddressBlock c)+ [FFI.valueSubclassIdP|ConstantStruct|] -> + return A.C.Struct `ap` (return $ A.isPacked t) `ap` getConstantOperands+ [FFI.valueSubclassIdP|ConstantDataArray|] -> + return A.C.Array `ap` (return $ A.elementType t) `ap` getConstantData+ [FFI.valueSubclassIdP|ConstantArray|] -> + return A.C.Array `ap` (return $ A.elementType t) `ap` getConstantOperands+ [FFI.valueSubclassIdP|ConstantDataVector|] -> + return A.C.Vector `ap` getConstantData+ [FFI.valueSubclassIdP|ConstantExpr|] -> do+ cppOpcode <- liftIO $ FFI.getConstantCPPOpcode c+ $(+ TH.caseE [| cppOpcode |] $ do+ (name, ((TH.RecC n fs, _), iDef)) <- Map.toList $+ ID.innerJoin (ID.innerJoin ID.astConstantRecs ID.astInstructionRecs) ID.instructionDefs+ let apWrapper o (fn, _, ct) = do+ a <- case ct of+ TH.ConT h+ | h == ''A.Constant -> do+ operandNumber <- get+ modify (+1)+ return [| op $(TH.litE . TH.integerL $ operandNumber) |]+ | h == ''A.Type -> return [| pure t |]+ | h == ''A.IntegerPredicate -> + return [| liftIO $ decodeM =<< FFI.getConstantICmpPredicate c |]+ | h == ''A.FloatingPointPredicate -> + return [| liftIO $ decodeM =<< FFI.getConstantFCmpPredicate c |]+ | h == ''Bool -> case TH.nameBase fn of+ "inBounds" -> return [| liftIO $ decodeM =<< FFI.getInBounds v |]+ TH.AppT TH.ListT (TH.ConT h) + | h == ''Word32 -> + return [|+ do+ np <- alloca+ isp <- liftIO $ FFI.getConstantIndices c np+ n <- peek np+ decodeM (n, isp)+ |]+ | h == ''A.Constant -> + case TH.nameBase fn of+ "indices" -> do+ operandNumber <- get+ return [| mapM op [$(TH.litE . TH.integerL $ operandNumber)..nOps-1] |]+ _ -> error $ "unhandled constant expr field type: " ++ show fn ++ " - " ++ show ct+ return [| $(o) `ap` $(a) |]+ return $ TH.match + (TH.dataToPatQ (const Nothing) (ID.cppOpcode iDef))+ (TH.normalB (evalState (foldM apWrapper [| return $(TH.conE n) |] fs) 0))+ []+ )+ _ -> error $ "unhandled constant valueSubclassId: " ++ show valueSubclassId+++ +
+ src/LLVM/General/Internal/Context.hs view
@@ -0,0 +1,16 @@+module LLVM.General.Internal.Context where++import Control.Exception++import Foreign.Ptr++import qualified LLVM.General.Internal.FFI.Context as FFI++-- | a Context object holds the state the of LLVM system needs for one thread of+-- | LLVM compilation. Once upon a time, in early versions of LLVM, this state was global.+-- | Then it got packed up in this object to allow multiple threads to compile at once.+data Context = Context (Ptr FFI.Context)++-- | Create a Context, run an action (to which it is provided), then destroy the Context.+withContext :: (Context -> IO a) -> IO a+withContext = bracket FFI.contextCreate FFI.contextDispose . (. Context)
+ src/LLVM/General/Internal/DataLayout.hs view
@@ -0,0 +1,88 @@+module LLVM.General.Internal.DataLayout where++import Text.ParserCombinators.Parsec++import Data.Word+import Data.Functor++import qualified Data.List as List+import qualified Data.Map as Map+import qualified Data.Set as Set++import LLVM.General.AST.DataLayout+import LLVM.General.AST.AddrSpace++dataLayoutToString :: DataLayout -> String+dataLayoutToString dl = + let sTriple :: (Word32, AlignmentInfo) -> String+ sTriple (s, ai) = show s ++ ":" ++ show (abiAlignment ai) ++ ":" ++ show (preferredAlignment ai)+ atChar at = case at of+ IntegerAlign -> "i"+ VectorAlign -> "v"+ FloatAlign -> "f"+ AggregateAlign -> "a"+ StackAlign -> "s"+ in+ List.intercalate "-" (+ (case endianness dl of Just BigEndian -> ["E"]; Just LittleEndian -> ["e"]; _ -> [])+ +++ (maybe [] (\s -> ["S" ++ show s]) (stackAlignment dl))+ +++ [ "p" ++ show a ++ ":" ++ sTriple t | (AddrSpace a, t) <- Map.toList . pointerLayouts $ dl]+ +++ [ atChar at ++ sTriple (s, ai) | ((at, s), ai) <- Map.toList . typeLayouts $ dl ]+ ++ + (maybe [] (\ns -> ["n" ++ (List.intercalate ":" (map show . Set.toList $ ns))]) (nativeSizes dl))+ )++parseDataLayout :: String -> Maybe DataLayout+parseDataLayout "" = Nothing+parseDataLayout s = + let+ num :: Parser Word32+ num = read <$> many digit+ triple :: Parser (Word32, AlignmentInfo)+ triple = do+ s <- num+ char ':'+ abi <- num+ char ':'+ pref <- num+ return (s, (AlignmentInfo abi pref))+ parseSpec :: Parser (DataLayout -> DataLayout)+ parseSpec = choice [+ do+ char 'e'+ return $ \dl -> dl { endianness = Just LittleEndian },+ do+ char 'E' + return $ \dl -> dl { endianness = Just BigEndian },+ do+ char 'S'+ n <- num+ return $ \dl -> dl { stackAlignment = Just n },+ do+ char 'p'+ a <- AddrSpace . read <$> many digit+ char ':'+ t <- triple+ return $ \dl -> dl { pointerLayouts = Map.insert a t (pointerLayouts dl) },+ do+ at <- choice [+ char 'i' >> return IntegerAlign,+ char 'v' >> return VectorAlign,+ char 'f' >> return FloatAlign,+ char 'a' >> return AggregateAlign,+ char 's' >> return StackAlign+ ]+ (sz,ai) <- triple+ return $ \dl -> dl { typeLayouts = Map.insert (at,sz) ai (typeLayouts dl) },+ do + char 'n'+ ns <- num `sepBy` (char ':')+ return $ \dl -> dl { nativeSizes = Just (Set.fromList ns) }+ ]+ in + case parse (parseSpec `sepBy` (char '-')) "" s of+ Left _ -> error $ "ill formed data layout: " ++ show s+ Right fs -> Just $ foldr ($) defaultDataLayout fs
+ src/LLVM/General/Internal/DecodeAST.hs view
@@ -0,0 +1,171 @@+{-# LANGUAGE+ GeneralizedNewtypeDeriving,+ FlexibleContexts,+ FlexibleInstances,+ TypeFamilies,+ MultiParamTypeClasses,+ UndecidableInstances+ #-}+module LLVM.General.Internal.DecodeAST where++import Control.Applicative+import Control.Monad.State+import Control.Monad.Phased+import Control.Monad.AnyCont++import Foreign.Ptr+import Foreign.C+import Data.Word++import Data.Sequence (Seq)+import qualified Data.Sequence as Seq+import Data.Map (Map)+import qualified Data.Map as Map+import Data.Array (Array)+import qualified Data.Array as Array++import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.General.Internal.FFI.Value as FFI+import qualified LLVM.General.Internal.FFI.Type as FFI++import qualified LLVM.General.AST.Name as A+import qualified LLVM.General.AST.Operand as A (MetadataNodeID(..))++import LLVM.General.Internal.Coding+import LLVM.General.Internal.String ()++type NameMap a = Map (Ptr a) Word++data DecodeState = DecodeState {+ globalVarNum :: NameMap FFI.GlobalValue,+ localVarNum :: NameMap FFI.Value,+ localNameCounter :: Maybe Word,+ namedTypeNum :: NameMap FFI.Type,+ typesToDefine :: Seq (Ptr FFI.Type),+ metadataNodesToDefine :: Seq (A.MetadataNodeID, Ptr FFI.MDNode),+ metadataNodes :: Map (Ptr FFI.MDNode) A.MetadataNodeID,+ metadataKinds :: Array Word String+ }+initialDecode = DecodeState {+ globalVarNum = Map.empty,+ localVarNum = Map.empty,+ localNameCounter = Nothing,+ namedTypeNum = Map.empty,+ typesToDefine = Seq.empty,+ metadataNodesToDefine = Seq.empty,+ metadataNodes = Map.empty,+ metadataKinds = Array.listArray (1,0) []+ }+newtype DecodeAST a = DecodeAST { unDecodeAST :: AnyContT (PhasedT (StateT DecodeState IO)) a }+ deriving (+ Applicative,+ Functor,+ Monad,+ MonadIO,+ MonadState DecodeState,+ MonadPhased+ )++instance MonadAnyCont IO DecodeAST where+ anyContToM = DecodeAST . anyContIOToM+ scopeAnyCont = DecodeAST . scopeAnyCont . unDecodeAST++runDecodeAST :: DecodeAST a -> IO a+runDecodeAST d = flip evalStateT initialDecode . runPhasedT . flip runAnyContT return . unDecodeAST $ d++localScope :: DecodeAST a -> DecodeAST a+localScope (DecodeAST x) = DecodeAST (mapAnyContT pScope (tweak x))+ where tweak x = do+ modify (\s@DecodeState { localNameCounter = Nothing } -> s { localNameCounter = Just 0 })+ r <- x+ modify (\s@DecodeState { localNameCounter = Just _ } -> s { localNameCounter = Nothing })+ return r+ pScope (PhasedT x) = PhasedT $ do+ let s0 `withLocalsFrom` s1 = s0 { + localNameCounter = localNameCounter s1+ }+ state <- get -- save the state+ a <- x+ state' <- get -- get the modified state+ put $ state' `withLocalsFrom` state -- revert the local part+ -- Finally here's the fun bit - in the Left case where we're coming back to a deferment point,+ -- prepend an action which reinstates the local state, but re-wrap with pScope to continue+ -- containment.+ return $ either (Left . pScope . (modify (`withLocalsFrom` state') >>)) Right a++getName :: (Ptr a -> IO CString)+ -> Ptr a+ -> (DecodeState -> NameMap a)+ -> DecodeAST Word+ -> DecodeAST A.Name+getName getCString v getNameMap generate = do+ name <- liftIO $ do+ n <- getCString v+ if n == nullPtr then return "" else decodeM n+ if name /= "" + then+ return $ A.Name name+ else+ A.UnName <$> do+ nm <- gets getNameMap+ maybe generate return $ Map.lookup v nm++getValueName :: FFI.DescendentOf FFI.Value v => Ptr v -> (DecodeState -> NameMap v) -> DecodeAST Word -> DecodeAST A.Name+getValueName = getName (FFI.getValueName . FFI.upCast)++getLocalName :: FFI.DescendentOf FFI.Value v => Ptr v -> DecodeAST A.Name+getLocalName v' = do+ let v = FFI.upCast v'+ getValueName v localVarNum $ do+ nm <- gets localVarNum+ Just n <- gets localNameCounter+ modify $ \s -> s { localNameCounter = Just (1 + n), localVarNum = Map.insert v n nm }+ return n++getGlobalName :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST A.Name+getGlobalName v' = do+ let v = FFI.upCast v'+ getValueName v globalVarNum $ do+ nm <- gets globalVarNum+ let n = fromIntegral $ Map.size nm+ modify $ \s -> s { globalVarNum = Map.insert v n nm }+ return n+++getTypeName :: Ptr FFI.Type -> DecodeAST A.Name+getTypeName t = do+ getName FFI.getStructName t namedTypeNum $ do+ nm <- gets namedTypeNum+ let n = fromIntegral $ Map.size nm+ modify $ \s -> s { namedTypeNum = Map.insert t n nm }+ return n++saveNamedType :: Ptr FFI.Type -> DecodeAST ()+saveNamedType t = do+ modify $ \s -> s { typesToDefine = t Seq.<| typesToDefine s }++getMetadataNodeID :: Ptr FFI.MDNode -> DecodeAST A.MetadataNodeID+getMetadataNodeID p = do+ mdns <- gets metadataNodes+ case Map.lookup p mdns of+ Just r -> return r+ Nothing -> do+ let r = A.MetadataNodeID (fromIntegral (Map.size mdns))+ modify $ \s -> s { + metadataNodesToDefine = (r, p) Seq.<| metadataNodesToDefine s,+ metadataNodes = Map.insert p r (metadataNodes s)+ }+ return r++takeTypeToDefine :: DecodeAST (Maybe (Ptr FFI.Type))+takeTypeToDefine = state $ \s -> case Seq.viewr (typesToDefine s) of+ remaining Seq.:> t -> (Just t, s { typesToDefine = remaining })+ _ -> (Nothing, s)++takeMetadataNodeToDefine :: DecodeAST (Maybe (A.MetadataNodeID, Ptr FFI.MDNode))+takeMetadataNodeToDefine = state $ \s -> case Seq.viewr (metadataNodesToDefine s) of+ remaining Seq.:> md -> (Just md, s { metadataNodesToDefine = remaining })+ _ -> (Nothing, s) ++instance DecodeM DecodeAST A.Name (Ptr FFI.BasicBlock) where+ decodeM = getLocalName
+ src/LLVM/General/Internal/Diagnostic.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE+ TemplateHaskell,+ DeriveDataTypeable,+ MultiParamTypeClasses,+ FlexibleInstances+ #-} +module LLVM.General.Internal.Diagnostic where++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.General.Internal.FFI.SMDiagnostic as FFI++import Control.Exception++import Foreign.Ptr++import LLVM.General.Diagnostic+import LLVM.General.Internal.Coding+import LLVM.General.Internal.String ()++genCodingInstance' [t| DiagnosticKind |] ''FFI.DiagnosticKind [+ (FFI.diagnosticKindError, ErrorKind),+ (FFI.diagnosticKindWarning, WarningKind),+ (FFI.diagnosticKindNote, NoteKind)+ ]++withSMDiagnostic :: (Ptr FFI.SMDiagnostic -> IO a) -> IO a+withSMDiagnostic = bracket FFI.createSMDiagnostic FFI.disposeSMDiagnostic++getDiagnostic :: Ptr FFI.SMDiagnostic -> IO Diagnostic+getDiagnostic p = do+ l <- decodeM =<< FFI.getSMDiagnosticLineNo p+ c <- decodeM =<< FFI.getSMDiagnosticColumnNo p+ k <- decodeM =<< FFI.getSMDiagnosticKind p+ f <- decodeM =<< FFI.getSMDiagnosticFilename p+ m <- decodeM =<< FFI.getSMDiagnosticMessage p+ lc <- decodeM =<< FFI.getSMDiagnosticLineContents p+ return $ Diagnostic { + lineNumber = l, columnNumber = c, diagnosticKind = k, filename = f, message = m, lineContents = lc+ }+
+ src/LLVM/General/Internal/EncodeAST.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE+ GeneralizedNewtypeDeriving,+ FlexibleContexts,+ FlexibleInstances,+ MultiParamTypeClasses,+ UndecidableInstances+ #-}++module LLVM.General.Internal.EncodeAST where++import Control.Exception+import Control.Monad.State+import Control.Monad.Phased+import Control.Monad.Error+import Control.Monad.AnyCont++import Foreign.Ptr+import Foreign.C++import Data.Map (Map)+import qualified Data.Map as Map++import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.General.Internal.FFI.Builder as FFI+import qualified LLVM.General.Internal.FFI.Type as FFI++import qualified LLVM.General.AST as A++import LLVM.General.Internal.Context+import LLVM.General.Internal.Coding+import LLVM.General.Internal.String ()++data EncodeState = EncodeState { + encodeStateBuilder :: Ptr FFI.Builder,+ encodeStateContext :: Context,+ encodeStateLocals :: Map A.Name (Ptr FFI.Value),+ encodeStateGlobals :: Map A.Name (Ptr FFI.GlobalValue),+ encodeStateAllBlocks :: Map (A.Name, A.Name) (Ptr FFI.BasicBlock),+ encodeStateBlocks :: Map A.Name (Ptr FFI.BasicBlock),+ encodeStateMDNodes :: Map A.MetadataNodeID (Ptr FFI.MDNode),+ encodeStateNamedTypes :: Map A.Name (Ptr FFI.Type)+ }++newtype EncodeAST a = EncodeAST { unEncodeAST :: AnyContT (PhasedT (ErrorT String (StateT EncodeState IO))) a }+ deriving (+ Functor,+ Monad,+ MonadIO,+ MonadState EncodeState,+ MonadPhased,+ MonadError String+ )++instance MonadAnyCont IO EncodeAST where+ anyContToM = EncodeAST . anyContIOToM+ scopeAnyCont = EncodeAST . scopeAnyCont . unEncodeAST++lookupNamedType :: A.Name -> EncodeAST (Ptr FFI.Type)+lookupNamedType n = do+ t <- gets $ Map.lookup n . encodeStateNamedTypes+ maybe (fail $ "reference to undefined type: " ++ show n) return t++defineType :: A.Name -> Ptr FFI.Type -> EncodeAST ()+defineType n t = modify $ \s -> s { encodeStateNamedTypes = Map.insert n t (encodeStateNamedTypes s) }++runEncodeAST :: Context -> EncodeAST a -> IO (Either String a)+runEncodeAST context@(Context ctx) (EncodeAST a) = + bracket (FFI.createBuilderInContext ctx) FFI.disposeBuilder $ \builder -> do+ let initEncodeState = EncodeState { + encodeStateBuilder = builder,+ encodeStateContext = context,+ encodeStateLocals = Map.empty,+ encodeStateGlobals = Map.empty,+ encodeStateAllBlocks = Map.empty,+ encodeStateBlocks = Map.empty,+ encodeStateMDNodes = Map.empty,+ encodeStateNamedTypes = Map.empty+ }+ flip evalStateT initEncodeState . runErrorT . runPhasedT . flip runAnyContT return $ a++withName :: A.Name -> (CString -> IO a) -> IO a+withName (A.Name n) = withCString n+withName (A.UnName _) = withCString ""++instance MonadAnyCont IO m => EncodeM m A.Name CString where+ encodeM (A.Name n) = encodeM n+ encodeM _ = encodeM ""++-- contain modifications to the local part of the encode state - in this case all those except+-- those to encodeStateAllBlocks+encodeScope :: EncodeAST a -> EncodeAST a+encodeScope (EncodeAST x) = + EncodeAST . mapAnyContT pScope $ x -- get inside the boring wrappers down to the phasing+ where pScope (PhasedT x) = PhasedT $ do+ let s0 `withLocalsFrom` s1 = s0 { + encodeStateLocals = encodeStateLocals s1,+ encodeStateBlocks = encodeStateBlocks s1+ }+ state <- get -- save the state+ a <- x+ state' <- get -- get the modified state+ put $ state' `withLocalsFrom` state -- revert the local part+ -- Finally here's the fun bit - in the Left case where we're coming back to a deferment point,+ -- prepend an action which reinstates the local state, but re-wrap with pScope to continue+ -- containment.+ return $ either (Left . pScope . (modify (`withLocalsFrom` state') >>)) Right a+++define :: (Ord n, FFI.DescendentOf p v) => + (EncodeState -> Map n (Ptr p))+ -> (Map n (Ptr p) -> EncodeState -> EncodeState)+ -> n+ -> Ptr v+ -> EncodeAST ()+define r w n v = modify $ \b -> w (Map.insert n (FFI.upCast v) (r b)) b++defineLocal :: FFI.DescendentOf FFI.Value v => A.Name -> Ptr v -> EncodeAST ()+defineLocal = define encodeStateLocals (\m b -> b { encodeStateLocals = m })++defineGlobal :: FFI.DescendentOf FFI.GlobalValue v => A.Name -> Ptr v -> EncodeAST ()+defineGlobal = define encodeStateGlobals (\m b -> b { encodeStateGlobals = m })++defineMDNode :: A.MetadataNodeID -> Ptr FFI.MDNode -> EncodeAST ()+defineMDNode = define encodeStateMDNodes (\m b -> b { encodeStateMDNodes = m })++refer :: (Show n, Ord n) => (EncodeState -> Map n (Ptr p)) -> String -> n -> EncodeAST (Ptr p)+refer r m n = do+ mop <- gets $ Map.lookup n . r+ maybe (fail $ "reference to undefined " ++ m ++ ": " ++ show n) return mop++referLocal = refer encodeStateLocals "local"+referGlobal = refer encodeStateGlobals "global"+referMDNode = refer encodeStateMDNodes "metadata node"++defineBasicBlock :: A.Name -> A.Name -> Ptr FFI.BasicBlock -> EncodeAST ()+defineBasicBlock fn n b = modify $ \s -> s {+ encodeStateBlocks = Map.insert n b (encodeStateBlocks s),+ encodeStateAllBlocks = Map.insert (fn, n) b (encodeStateAllBlocks s)+}++instance EncodeM EncodeAST A.Name (Ptr FFI.BasicBlock) where+ encodeM = refer encodeStateBlocks "block"++getBlockForAddress :: A.Name -> A.Name -> EncodeAST (Ptr FFI.BasicBlock)+getBlockForAddress fn n = refer encodeStateAllBlocks "blockaddress" (fn, n)+
+ src/LLVM/General/Internal/ExecutionEngine.hs view
@@ -0,0 +1,66 @@+module LLVM.General.Internal.ExecutionEngine where++import Control.Exception+import Control.Monad+import Control.Monad.IO.Class+import Control.Monad.AnyCont+import Data.Functor++import Foreign.Ptr+import Foreign.Marshal.Alloc (free)++import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.General.Internal.FFI.ExecutionEngine as FFI+import qualified LLVM.General.Internal.FFI.Target as FFI+import qualified LLVM.General.Internal.FFI.Module as FFI++import LLVM.General.Internal.Module+import LLVM.General.Internal.Context+import LLVM.General.Internal.Coding++import qualified LLVM.General.AST as A++-- | <http://llvm.org/doxygen/classllvm_1_1ExecutionEngine.html>+newtype ExecutionEngine = ExecutionEngine (Ptr FFI.ExecutionEngine)++removeModule :: Ptr FFI.ExecutionEngine -> Ptr FFI.Module -> IO ()+removeModule e m = flip runAnyContT return $ do+ d0 <- alloca+ d1 <- alloca+ r <- liftIO $ FFI.removeModule e m d0 d1+ when (r /= 0) $ fail "FFI.removeModule failure"+++-- | bracket the creation and destruction of an 'ExecutionEngine'+withExecutionEngine :: Context -> (ExecutionEngine -> IO a) -> IO a+withExecutionEngine c f = flip runAnyContT return $ do+ liftIO $ FFI.initializeNativeTarget+ outExecutionEngine <- alloca+ outErrorCStringPtr <- alloca+ Module dummyModule <- anyContT $ liftM (either undefined id) . withModuleFromAST c (A.Module "" Nothing Nothing [])+ r <- liftIO $ FFI.createExecutionEngineForModule outExecutionEngine dummyModule outErrorCStringPtr+ when (r /= 0) $ do+ s <- anyContT $ bracket (peek outErrorCStringPtr) free+ fail =<< decodeM s+ executionEngine <- anyContT $ bracket (peek outExecutionEngine) FFI.disposeExecutionEngine+ liftIO $ removeModule executionEngine dummyModule+ liftIO $ f (ExecutionEngine executionEngine)+ + +-- | bracket the availability of machine code for a given 'Module' in an 'ExecutionEngine'.+-- See 'findFunction'.+withModuleInEngine :: ExecutionEngine -> Module -> IO a -> IO a+withModuleInEngine (ExecutionEngine e) (Module m) = bracket_ (FFI.addModule e m) (removeModule e m)++-- | While a 'Module' is in an 'ExecutionEngine', use 'findFunction' to lookup functions in the module.+-- To run them from Haskell, treat them as any other function pointer: cast them to an appropriate and+-- foreign type, then wrap them with a dynamic FFI stub.+findFunction :: ExecutionEngine -> A.Name -> IO (Maybe (Ptr ()))+findFunction (ExecutionEngine e) (A.Name fName) = flip runAnyContT return $ do+ out <- alloca+ fName <- encodeM fName+ r <- liftIO $ FFI.findFunction e fName out+ if (r /= 0) then + return Nothing+ else + Just <$> (liftIO $ FFI.getPointerToGlobal e . FFI.upCast =<< peek out)
+ src/LLVM/General/Internal/FFI/Assembly.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE+ ForeignFunctionInterface+ #-}++-- | Functions to read and write textual LLVM assembly+module LLVM.General.Internal.FFI.Assembly where++import LLVM.General.Internal.FFI.Context +import LLVM.General.Internal.FFI.Module+import LLVM.General.Internal.FFI.SMDiagnostic++import Foreign.C+import Foreign.Ptr++-- | Use LLVM's parser to parse a string of llvm assembly to get a module+foreign import ccall unsafe "LLVM_General_GetModuleFromAssemblyInContext" getModuleFromAssemblyInContext ::+ Ptr Context -> CString -> Ptr SMDiagnostic -> IO (Ptr Module)++-- | LLVM's serializer to generate a string of llvm assembly from a module+foreign import ccall unsafe "LLVM_General_GetModuleAssembly" getModuleAssembly ::+ Ptr Module -> IO CString+++
+ src/LLVM/General/Internal/FFI/AssemblyC.cpp view
@@ -0,0 +1,33 @@+#define __STDC_LIMIT_MACROS+#include "llvm/LLVMContext.h"+#include "llvm/Assembly/Parser.h"+#include "llvm/Assembly/PrintModulePass.h"+#include "llvm/Pass.h"+#include "llvm/Support/SourceMgr.h"+#include "llvm/Support/raw_ostream.h"++#include "llvm-c/Core.h"++using namespace llvm;++extern "C" {++LLVMModuleRef LLVM_General_GetModuleFromAssemblyInContext(+ LLVMContextRef context,+ const char *assembly,+ SMDiagnostic *error+) {+ wrap(ParseAssemblyString(assembly, NULL, *error, *unwrap(context))); +}++char *LLVM_General_GetModuleAssembly(LLVMModuleRef module) {+ std::string s;+ raw_string_ostream buf(s);+ ModulePass *printPass = createPrintModulePass(&buf);+ printPass->runOnModule(*unwrap(module));+ delete printPass;+ return strdup(buf.str().c_str());+}++}+
+ src/LLVM/General/Internal/FFI/BasicBlock.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses+ #-}++-- | <http://llvm.org/doxygen/classllvm_1_1BasicBlock.html>+module LLVM.General.Internal.FFI.BasicBlock where++import Foreign.Ptr++import LLVM.General.Internal.FFI.PtrHierarchy++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueBasicBlock.html#gab57c996ff697ef40966432055ae47a4e>+foreign import ccall unsafe "LLVMIsABasicBlock" isABasicBlock ::+ Ptr Value -> IO (Ptr BasicBlock)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueBasicBlock.html#ga754e45f69f4b784b658d9e379943f354>+foreign import ccall unsafe "LLVMGetBasicBlockTerminator" getBasicBlockTerminator ::+ Ptr BasicBlock -> IO (Ptr Instruction)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueBasicBlock.html#ga9baf824cd325ad211027b23fce8a7494>+foreign import ccall unsafe "LLVMGetFirstInstruction" getFirstInstruction ::+ Ptr BasicBlock -> IO (Ptr Instruction)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueBasicBlock.html#gaa0bb2c95802d06bf94f4c55e61fc3477>+foreign import ccall unsafe "LLVMGetLastInstruction" getLastInstruction ::+ Ptr BasicBlock -> IO (Ptr Instruction)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueInstruction.html#ga1b4c3bd197e86e8bffdda247ddf8ec5e>+foreign import ccall unsafe "LLVMGetNextInstruction" getNextInstruction ::+ Ptr Instruction -> IO (Ptr Instruction)+
+ src/LLVM/General/Internal/FFI/BinaryOperator.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses,+ FlexibleInstances,+ UndecidableInstances,+ OverlappingInstances+ #-}++-- | FFI functions for handling the LLVM BinaryOperator class+module LLVM.General.Internal.FFI.BinaryOperator where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.LLVMCTypes++-- | a blind type to correspond to llvm::BinaryOperator+data BinaryOperator++instance ChildOf Instruction BinaryOperator++foreign import ccall unsafe "LLVMIsABinaryOperator" isABinaryOperator ::+ Ptr Value -> IO (Ptr BinaryOperator)++foreign import ccall unsafe "LLVM_General_HasNoSignedWrap" hasNoSignedWrap ::+ Ptr BinaryOperator -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_HasNoUnsignedWrap" hasNoUnsignedWrap ::+ Ptr BinaryOperator -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_IsExact" isExact ::+ Ptr BinaryOperator -> IO LLVMBool+
+ src/LLVM/General/Internal/FFI/Builder.hs view
@@ -0,0 +1,152 @@+{-#+ LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ TemplateHaskell+ #-}++-- | FFI glue for llvm::IRBuilder - llvm's IR construction state object+module LLVM.General.Internal.FFI.Builder where++import qualified Language.Haskell.TH as TH++import qualified LLVM.General.AST.Instruction as A+import qualified LLVM.General.AST.Operand as A+import qualified LLVM.General.AST.Type as A++import LLVM.General.Internal.InstructionDefs as ID++import Foreign.Ptr+import Foreign.C++import qualified Data.Map as Map++import LLVM.General.Internal.FFI.LLVMCTypes+import LLVM.General.Internal.FFI.Context+import LLVM.General.Internal.FFI.BinaryOperator+import LLVM.General.Internal.FFI.Type+import LLVM.General.Internal.FFI.PtrHierarchy++data Builder++foreign import ccall unsafe "LLVMCreateBuilderInContext" createBuilderInContext ::+ Ptr Context -> IO (Ptr Builder)++foreign import ccall unsafe "LLVMDisposeBuilder" disposeBuilder ::+ Ptr Builder -> IO ()++foreign import ccall unsafe "LLVMPositionBuilderAtEnd" positionBuilderAtEnd ::+ Ptr Builder -> Ptr BasicBlock -> IO ()+++foreign import ccall unsafe "LLVMBuildRet" buildRet ::+ Ptr Builder -> Ptr Value -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildBr" buildBr ::+ Ptr Builder -> Ptr BasicBlock -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildCondBr" buildCondBr ::+ Ptr Builder -> Ptr Value -> Ptr BasicBlock -> Ptr BasicBlock -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildSwitch" buildSwitch ::+ Ptr Builder -> Ptr Value -> Ptr BasicBlock -> CUInt -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildIndirectBr" buildIndirectBr ::+ Ptr Builder -> Ptr Value -> CUInt -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildInvoke" buildInvoke ::+ Ptr Builder -> Ptr Value -> Ptr (Ptr Value) -> CUInt+ -> Ptr BasicBlock -> Ptr BasicBlock -> CString -> IO (Ptr Instruction)+ +foreign import ccall unsafe "LLVMBuildResume" buildResume ::+ Ptr Builder -> Ptr Value -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildUnreachable" buildUnreachable ::+ Ptr Builder -> IO (Ptr Instruction)+++$(do+ sequence [+ TH.forImpD TH.cCall TH.unsafe cName (TH.mkName ("build" ++ a)) [t| + Ptr Builder -> $(foldr (\at rt -> [t| $(at) -> $(rt) |]) [t| CString -> IO (Ptr $(rt)) |] ats)+ |]+ | (lrn, ID.InstructionDef { ID.cAPIName = a, ID.instructionKind = k }) <- Map.toList ID.instructionDefs,+ let fieldTypes = + (\(TH.RecC _ fs) -> [ t | (_,_,t) <- fs]) $+ Map.findWithDefault + (error $ "LLVM instruction not found in AST: " ++ show lrn)+ lrn ID.astInstructionRecs+ ats = flip concatMap fieldTypes $ \ft ->+ case ft of+ TH.ConT h | h == ''Bool -> [[t| LLVMBool |]]+ | h == ''A.Operand -> [[t| Ptr Value |]]+ | h == ''A.Type -> [[t| Ptr Type |]]+ | h == ''A.InstructionMetadata -> []+ _ -> error $ "show ft = " ++ show ft+ cName = (if TH.ConT ''Bool `elem` fieldTypes then "LLVM_General_" else "LLVM") ++ "Build" ++ a,+ rt <- case k of+ ID.Binary -> [[t| BinaryOperator |]]+ ID.Cast -> [[t| Instruction |]]+ _ -> []+ ]+ )++foreign import ccall unsafe "LLVMBuildArrayAlloca" buildAlloca ::+ Ptr Builder -> Ptr Type -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_General_BuildLoad" buildLoad ::+ Ptr Builder -> Ptr Value -> CUInt -> LLVMBool -> MemoryOrdering -> LLVMBool -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_General_BuildStore" buildStore ::+ Ptr Builder -> Ptr Value -> Ptr Value -> CUInt -> LLVMBool -> MemoryOrdering -> LLVMBool -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildGEP" buildGetElementPtr ::+ Ptr Builder -> Ptr Value -> Ptr (Ptr Value) -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildFence" buildFence ::+ Ptr Builder -> MemoryOrdering -> LLVMBool -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_General_BuildAtomicCmpXchg" buildCmpXchg ::+ Ptr Builder -> Ptr Value -> Ptr Value -> Ptr Value -> LLVMBool -> MemoryOrdering -> LLVMBool -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_General_BuildAtomicRMW" buildAtomicRMW ::+ Ptr Builder -> RMWOperation -> Ptr Value -> Ptr Value -> LLVMBool -> MemoryOrdering -> LLVMBool -> CString -> IO (Ptr Instruction)+++foreign import ccall unsafe "LLVMBuildICmp" buildICmp ::+ Ptr Builder -> ICmpPredicate -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildFCmp" buildFCmp ::+ Ptr Builder -> FCmpPredicate -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildPhi" buildPhi ::+ Ptr Builder -> Ptr Type -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildCall" buildCall ::+ Ptr Builder -> Ptr Value -> Ptr (Ptr Value) -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildSelect" buildSelect ::+ Ptr Builder -> Ptr Value -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildVAArg" buildVAArg ::+ Ptr Builder -> Ptr Value -> Ptr Type -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildExtractElement" buildExtractElement ::+ Ptr Builder -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildInsertElement" buildInsertElement ::+ Ptr Builder -> Ptr Value -> Ptr Value -> Ptr Value -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildShuffleVector" buildShuffleVector ::+ Ptr Builder -> Ptr Value -> Ptr Value -> Ptr Constant -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_General_BuildExtractValue" buildExtractValue ::+ Ptr Builder -> Ptr Value -> Ptr CUInt -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVM_General_BuildInsertValue" buildInsertValue ::+ Ptr Builder -> Ptr Value -> Ptr Value -> Ptr CUInt -> CUInt -> CString -> IO (Ptr Instruction)++foreign import ccall unsafe "LLVMBuildLandingPad" buildLandingPad ::+ Ptr Builder -> Ptr Type -> Ptr Value -> CUInt -> CString -> IO (Ptr Instruction)++
+ src/LLVM/General/Internal/FFI/BuilderC.cpp view
@@ -0,0 +1,181 @@+#define __STDC_LIMIT_MACROS+#include "llvm/LLVMContext.h"+#include "llvm/IRBuilder.h"++#include "llvm-c/Core.h"++#include "LLVM/General/Internal/FFI/Instruction.h"++using namespace llvm;++namespace llvm {+static AtomicOrdering unwrap(LLVMAtomicOrdering l) {+ switch(l) {+#define ENUM_CASE(x) case LLVM ## x ## AtomicOrdering: return x;+LLVM_GENERAL_FOR_EACH_ATOMIC_ORDERING(ENUM_CASE)+#undef ENUM_CASE+ default: return AtomicOrdering(0);+ }+}++static SynchronizationScope unwrap(LLVMSynchronizationScope l) {+ switch(l) {+#define ENUM_CASE(x) case LLVM ## x ## SynchronizationScope: return x;+LLVM_GENERAL_FOR_EACH_SYNCRONIZATION_SCOPE(ENUM_CASE)+#undef ENUM_CASE+ default: return SynchronizationScope(0);+ }+}+++static AtomicRMWInst::BinOp unwrap(LLVMAtomicRMWOperation l) {+ switch(l) {+#define ENUM_CASE(x) case LLVM ## x ## RMWOperation: return AtomicRMWInst::x;+LLVM_GENERAL_FOR_EACH_RMW_OPERATION(ENUM_CASE)+#undef ENUM_CASE+ default: return AtomicRMWInst::BinOp(0);+ }+}++}++extern "C" {++#define LLVM_GENERAL_FOR_ALL_OVERFLOWING_BINARY_OPERATORS(macro) \+ macro(Add) \+ macro(Mul) \+ macro(Shl) \+ macro(Sub) \++#define ENUM_CASE(Op) \+LLVMValueRef LLVM_General_Build ## Op( \+ LLVMBuilderRef b, \+ LLVMBool nsw, \+ LLVMBool nuw, \+ LLVMValueRef o0, \+ LLVMValueRef o1, \+ const char *s \+) { \+ return wrap(unwrap(b)->Create ## Op(unwrap(o0), unwrap(o1), s, nuw, nsw)); \+}+LLVM_GENERAL_FOR_ALL_OVERFLOWING_BINARY_OPERATORS(ENUM_CASE)+#undef ENUM_CASE++#define LLVM_GENERAL_FOR_ALL_POSSIBLY_EXACT_OPERATORS(macro) \+ macro(AShr) \+ macro(LShr) \+ macro(SDiv) \+ macro(UDiv) \++#define ENUM_CASE(Op) \+LLVMValueRef LLVM_General_Build ## Op( \+ LLVMBuilderRef b, \+ LLVMBool exact, \+ LLVMValueRef o0, \+ LLVMValueRef o1, \+ const char *s \+) { \+ return wrap(unwrap(b)->Create ## Op(unwrap(o0), unwrap(o1), s, exact)); \+}+LLVM_GENERAL_FOR_ALL_POSSIBLY_EXACT_OPERATORS(ENUM_CASE)+#undef ENUM_CASE+++LLVMValueRef LLVM_General_BuildLoad(+ LLVMBuilderRef b,+ LLVMValueRef p,+ unsigned align,+ LLVMBool isVolatile,+ LLVMAtomicOrdering atomicOrdering,+ LLVMSynchronizationScope synchScope,+ const char *name+) {+ LoadInst *i = unwrap(b)->CreateAlignedLoad(unwrap(p), align, isVolatile, name);+ i->setOrdering(unwrap(atomicOrdering));+ i->setSynchScope(unwrap(synchScope));+ return wrap(i);+}++LLVMValueRef LLVM_General_BuildStore(+ LLVMBuilderRef b,+ LLVMValueRef v,+ LLVMValueRef p,+ unsigned align,+ LLVMBool isVolatile,+ LLVMAtomicOrdering atomicOrdering,+ LLVMSynchronizationScope synchScope,+ const char *name+) {+ StoreInst *i = unwrap(b)->CreateAlignedStore(unwrap(v), unwrap(p), align, isVolatile);+ i->setName(name);+ i->setOrdering(unwrap(atomicOrdering));+ i->setSynchScope(unwrap(synchScope));+ return wrap(i);+}++LLVMValueRef LLVMBuildFence(+ LLVMBuilderRef b, LLVMAtomicOrdering lao, LLVMSynchronizationScope lss, const char *name+) {+ FenceInst *i = unwrap(b)->CreateFence(unwrap(lao), unwrap(lss));+ i->setName(name);+ return wrap(i);+}++LLVMValueRef LLVM_General_BuildAtomicCmpXchg(+ LLVMBuilderRef b,+ LLVMValueRef ptr, + LLVMValueRef cmp, + LLVMValueRef n, + LLVMBool v,+ LLVMAtomicOrdering lao,+ LLVMSynchronizationScope lss,+ const char *name+) {+ AtomicCmpXchgInst *a = unwrap(b)->CreateAtomicCmpXchg(+ unwrap(ptr), unwrap(cmp), unwrap(n), unwrap(lao), unwrap(lss)+ );+ a->setVolatile(v);+ a->setName(name);+ return wrap(a);+}++LLVMValueRef LLVM_General_BuildAtomicRMW(+ LLVMBuilderRef b,+ LLVMAtomicRMWOperation rmwOp,+ LLVMValueRef ptr, + LLVMValueRef val, + LLVMBool v,+ LLVMAtomicOrdering lao,+ LLVMSynchronizationScope lss,+ const char *name+) {+ AtomicRMWInst *a = unwrap(b)->CreateAtomicRMW(+ unwrap(rmwOp), unwrap(ptr), unwrap(val), unwrap(lao), unwrap(lss)+ );+ a->setVolatile(v);+ a->setName(name);+ return wrap(a);+}++LLVMValueRef LLVM_General_BuildExtractValue(+ LLVMBuilderRef b,+ LLVMValueRef a,+ unsigned *idxs,+ unsigned n,+ const char *name+) {+ return wrap(unwrap(b)->CreateExtractValue(unwrap(a), ArrayRef<unsigned>(idxs, n), name));+}++LLVMValueRef LLVM_General_BuildInsertValue(+ LLVMBuilderRef b,+ LLVMValueRef a,+ LLVMValueRef v,+ unsigned *idxs,+ unsigned n,+ const char *name+) {+ return wrap(unwrap(b)->CreateInsertValue(unwrap(a), unwrap(v), ArrayRef<unsigned>(idxs, n), name));+}++}
+ src/LLVM/General/Internal/FFI/Cleanup.hs view
@@ -0,0 +1,73 @@+{-# LANGUAGE+ TemplateHaskell+ #-}+module LLVM.General.Internal.FFI.Cleanup where++import Language.Haskell.TH+import Control.Monad+import Data.Sequence as Seq+import Data.Foldable (toList)++import Data.Function++import LLVM.General.Internal.FFI.LLVMCTypes+import Data.Word+import Data.Int+import Foreign.C+import Foreign.Ptr++import qualified LLVM.General.AST.IntegerPredicate as A (IntegerPredicate) +import qualified LLVM.General.AST.FloatingPointPredicate as A (FloatingPointPredicate) ++foreignDecl :: String -> String -> [TypeQ] -> TypeQ -> DecsQ+foreignDecl cName hName argTypeQs returnTypeQ = do+ let foreignDecl' hName argTypeQs = + forImpD cCall unsafe cName (mkName hName) + (foldr (\a b -> appT (appT arrowT a) b) (appT (conT ''IO) returnTypeQ) argTypeQs)+ splitTuples :: [Type] -> Q ([Type], [Pat], [Exp])+ splitTuples ts = do+ let f :: Type -> Q (Seq Type, Pat, Seq Exp)+ f x@(AppT _ _) = maybe (d x) (\q -> q >>= \(ts, ps, es) -> return (ts, TupP (toList ps), es)) (g 0 x)+ f x = d x+ g :: Int -> Type -> Maybe (Q (Seq Type, Seq Pat, Seq Exp))+ g n (TupleT m) | m == n = return (return (Seq.empty, Seq.empty, Seq.empty))+ g n (AppT a b) = do+ k <- g (n+1) a+ return $ do+ (ts, ps, es) <- k+ (ts', p', es') <- f b+ return (ts >< ts', ps |> p', es >< es')+ g _ _ = Nothing+ d :: Type -> Q (Seq Type, Pat, Seq Exp)+ d x = do+ n <- newName "v"+ return (Seq.singleton x, VarP n, Seq.singleton (VarE n))+ seqsToList :: [Seq a] -> [a]+ seqsToList = toList . foldr (><) Seq.empty+ + (tss, ps, ess) <- liftM unzip3 . mapM f $ ts+ return (seqsToList tss, ps, seqsToList ess)++ + argTypes <- sequence argTypeQs+ (ts, ps, es) <- splitTuples argTypes+ let phName = hName ++ "'"+ sequence [+ foreignDecl' phName (map return ts),+ funD (mkName hName) [+ clause (map return ps) (normalB (foldl appE (varE (mkName phName)) (map return es))) []+ ]+ ]++typeMappingU :: (Type -> TypeQ) -> Type -> TypeQ+typeMappingU typeMapping t = case t of+ ConT h | h == ''Bool -> [t| LLVMBool |]+ | h == ''Int32 -> [t| CInt |]+ | h == ''Word32 -> [t| CUInt |]+ | h == ''String -> [t| CString |]+ | h == ''A.FloatingPointPredicate -> [t| FCmpPredicate |]+ | h == ''A.IntegerPredicate -> [t| ICmpPredicate |]+ AppT ListT x -> foldl1 appT [tupleT 2, [t| CUInt |], appT [t| Ptr |] (typeMapping x)]++typeMapping :: Type -> TypeQ+typeMapping = fix typeMappingU
+ src/LLVM/General/Internal/FFI/Constant.hs view
@@ -0,0 +1,136 @@+{-# LANGUAGE+ TemplateHaskell,+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses,+ FlexibleInstances,+ UndecidableInstances,+ OverlappingInstances+ #-}++-- | FFI functions for handling the LLVM Constant class+module LLVM.General.Internal.FFI.Constant where++import qualified Language.Haskell.TH as TH+import qualified LLVM.General.Internal.InstructionDefs as ID+import qualified LLVM.General.AST.Constant as A.C++import Control.Monad+import Data.Function+import qualified Data.Map as Map++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.Context+import LLVM.General.Internal.FFI.Cleanup+import LLVM.General.Internal.FFI.Type+import LLVM.General.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsConstant" isConstant ::+ Ptr Value -> IO (CUInt)++foreign import ccall unsafe "LLVMIsAConstant" isAConstant ::+ Ptr Value -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMIsAConstantInt" isAConstantInt ::+ Ptr Value -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMGetOperand" getConstantOperand ::+ Ptr Constant -> CUInt -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMIsAConstantPointerNull" isAConstantPointerNull ::+ Ptr Value -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_General_GetConstantIntWords" getConstantIntWords ::+ Ptr Constant -> Ptr CUInt -> IO (Ptr CULong)++foreign import ccall unsafe "LLVM_General_ConstFloatDoubleValue" constFloatDoubleValue ::+ Ptr Constant -> IO CDouble++foreign import ccall unsafe "LLVM_General_ConstFloatFloatValue" constFloatFloatValue ::+ Ptr Constant -> IO CFloat++foreign import ccall unsafe "LLVMConstStructInContext" constStructInContext' ::+ Ptr Context -> Ptr (Ptr Constant) -> CUInt -> LLVMBool -> IO (Ptr Constant)++constStructInContext ctx (n, cs) p = constStructInContext' ctx cs n p++foreign import ccall unsafe "LLVM_General_GetConstantDataSequentialElementAsConstant" getConstantDataSequentialElementAsConstant ::+ Ptr Constant -> CUInt -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMConstIntOfArbitraryPrecision" constantIntOfArbitraryPrecision' ::+ Ptr Type -> CUInt -> Ptr CULong -> IO (Ptr Constant)++constantIntOfArbitraryPrecision t = uncurry (constantIntOfArbitraryPrecision' t)++foreign import ccall unsafe "LLVM_General_ConstFloatOfArbitraryPrecision" constantFloatOfArbitraryPrecision ::+ Ptr Context -> CUInt -> Ptr CULong -> LLVMBool -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_General_GetConstantFloatWords" getConstantFloatWords ::+ Ptr Constant -> Ptr CULong -> IO ()++foreign import ccall unsafe "LLVMConstVector" constantVector' ::+ Ptr (Ptr Constant) -> CUInt -> IO (Ptr Constant)++constantVector (n, cs) = constantVector' cs n++foreign import ccall unsafe "LLVMConstNull" constantNull ::+ Ptr Type -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMConstArray" constantArray' ::+ Ptr Type -> Ptr (Ptr Constant) -> CUInt -> IO (Ptr Constant)++constantArray t (n, cs) = constantArray' t cs n++foreign import ccall unsafe "LLVM_General_ConstCast" constantCast ::+ CPPOpcode -> Ptr Constant -> Ptr Type -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_General_ConstBinaryOperator" constantBinaryOperator ::+ CPPOpcode -> Ptr Constant -> Ptr Constant -> IO (Ptr Constant)++$(do+ let constExprInfo = ID.innerJoin (ID.innerJoin ID.astConstantRecs ID.astInstructionRecs) ID.instructionDefs+ let tm = fix tm' + where tm' _ (TH.ConT h) | h == ''A.C.Constant = [t| Ptr Constant |]+ tm' x t = typeMappingU x t+ + liftM concat $ sequence [ + foreignDecl ("LLVMConst" ++ name) ("constant" ++ name) [tm t | (_, _, t) <- fs ] [t| Ptr Constant |]+ | (name, ((TH.RecC _ fs,_), ID.InstructionDef { ID.instructionKind = ID.Other })) <- Map.toList constExprInfo+ ]+ )++foreign import ccall unsafe "LLVMConstGEP" constantGetElementPtr' ::+ Ptr Constant -> Ptr (Ptr Constant) -> CUInt -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMConstInBoundsGEP" constantInBoundsGetElementPtr' ::+ Ptr Constant -> Ptr (Ptr Constant) -> CUInt -> IO (Ptr Constant)++constantGetElementPtr (LLVMBool ib) a (n, is) = + (case ib of { 0 -> constantGetElementPtr'; 1 -> constantInBoundsGetElementPtr' }) a is n++foreign import ccall unsafe "LLVM_General_GetConstCPPOpcode" getConstantCPPOpcode ::+ Ptr Constant -> IO CPPOpcode++foreign import ccall unsafe "LLVM_General_GetConstPredicate" getConstantICmpPredicate ::+ Ptr Constant -> IO ICmpPredicate++foreign import ccall unsafe "LLVM_General_GetConstPredicate" getConstantFCmpPredicate ::+ Ptr Constant -> IO FCmpPredicate++foreign import ccall unsafe "LLVM_General_GetConstIndices" getConstantIndices ::+ Ptr Constant -> Ptr CUInt -> IO (Ptr CUInt)++foreign import ccall unsafe "LLVMGetUndef" getUndef ::+ Ptr Type -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMBlockAddress" blockAddress ::+ Ptr Value -> Ptr BasicBlock -> IO (Ptr Constant)++foreign import ccall unsafe "LLVM_General_GetBlockAddressFunction" getBlockAddressFunction ::+ Ptr Constant -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_General_GetBlockAddressBlock" getBlockAddressBlock ::+ Ptr Constant -> IO (Ptr BasicBlock)
+ src/LLVM/General/Internal/FFI/ConstantC.cpp view
@@ -0,0 +1,78 @@+#define __STDC_LIMIT_MACROS+#include "llvm-c/Core.h"+#include "llvm/LLVMContext.h"+#include "llvm/Constants.h"+#include "LLVM/General/Internal/FFI/Value.h"++using namespace llvm;++extern "C" {++LLVMValueRef LLVM_General_GetConstantDataSequentialElementAsConstant(LLVMValueRef v, unsigned i) {+ wrap(unwrap<ConstantDataSequential>(v)->getElementAsConstant(i));+}++LLVMValueRef LLVM_General_GetBlockAddressFunction(LLVMValueRef v) {+ return wrap(unwrap<BlockAddress>(v)->getFunction());+}++LLVMBasicBlockRef LLVM_General_GetBlockAddressBlock(LLVMValueRef v) {+ return wrap(unwrap<BlockAddress>(v)->getBasicBlock());+}++double LLVM_General_ConstFloatDoubleValue(LLVMValueRef v) {+ return unwrap<ConstantFP>(v)->getValueAPF().convertToDouble();+}++float LLVM_General_ConstFloatFloatValue(LLVMValueRef v) {+ return unwrap<ConstantFP>(v)->getValueAPF().convertToFloat();+}++LLVMValueRef LLVM_General_ConstCast(unsigned opcode, LLVMValueRef v, LLVMTypeRef t) {+ return wrap(ConstantExpr::getCast(opcode, unwrap<Constant>(v), unwrap(t)));+}++LLVMValueRef LLVM_General_ConstBinaryOperator(unsigned opcode, LLVMValueRef o0, LLVMValueRef o1) {+ return wrap(ConstantExpr::get(opcode, unwrap<Constant>(o0), unwrap<Constant>(o1)));+}++unsigned LLVM_General_GetConstCPPOpcode(LLVMValueRef v) {+ return unwrap<ConstantExpr>(v)->getOpcode();+}++unsigned LLVM_General_GetConstPredicate(LLVMValueRef v) {+ return unwrap<ConstantExpr>(v)->getPredicate();+}++const unsigned *LLVM_General_GetConstIndices(LLVMValueRef v, unsigned *n) {+ ArrayRef<unsigned> r = unwrap<ConstantExpr>(v)->getIndices();+ *n = r.size();+ return r.data();+}++const uint64_t *LLVM_General_GetConstantIntWords(LLVMValueRef v, unsigned *n) {+ const APInt &i = unwrap<ConstantInt>(v)->getValue();+ *n = i.getNumWords();+ return i.getRawData();+}++LLVMValueRef LLVM_General_ConstFloatOfArbitraryPrecision(+ LLVMContextRef c,+ unsigned bits,+ const uint64_t *words,+ unsigned notPairOfFloats+) {+ return wrap(+ ConstantFP::get(+ *unwrap(c),+ APFloat(APInt(bits, ArrayRef<uint64_t>(words, (bits-1)/64 + 1)), notPairOfFloats)+ )+ );+}++void LLVM_General_GetConstantFloatWords(LLVMValueRef v, uint64_t *bits) {+ APInt a = unwrap<ConstantFP>(v)->getValueAPF().bitcastToAPInt();+ for(unsigned i=0; i != a.getNumWords(); ++i) bits[i] = a.getRawData()[i];+}++}
+ src/LLVM/General/Internal/FFI/Context.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls+ #-}++-- | Functions for handling the LLVMContext class. In all other LLVM interfaces,+-- | prefer the newer explicitly thread-aware variants which use contexts+-- | over corresponding older variants which implicitly reference a global context.+-- | This choice allows multiple threads to do independent work with LLVM safely.+module LLVM.General.Internal.FFI.Context where++import Foreign.Ptr++-- | a blind type to correspond to LLVMContext+data Context++-- | <http://llvm.org/doxygen/group__LLVMCCoreContext.html#gaac4f39a2d0b9735e64ac7681ab543b4c>+foreign import ccall unsafe "LLVMContextCreate" contextCreate ::+ IO (Ptr Context)++-- | <http://llvm.org/doxygen/group__LLVMCCoreContext.html#ga0055cde9a9b2497b332d639d8844a810>+foreign import ccall unsafe "LLVMGetGlobalContext" getGlobalContext ::+ IO (Ptr Context)++-- | <http://llvm.org/doxygen/group__LLVMCCoreContext.html#ga9cf8b0fb4a546d4cdb6f64b8055f5f57>+foreign import ccall unsafe "LLVMContextDispose" contextDispose ::+ Ptr Context -> IO ()
+ src/LLVM/General/Internal/FFI/ExecutionEngine.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls+ #-}++module LLVM.General.Internal.FFI.ExecutionEngine where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.Module++data ExecutionEngine++foreign import ccall unsafe "LLVMCreateExecutionEngineForModule" createExecutionEngineForModule ::+ Ptr (Ptr ExecutionEngine) -> Ptr Module -> Ptr CString -> IO CUInt++foreign import ccall unsafe "LLVMDisposeExecutionEngine" disposeExecutionEngine ::+ Ptr ExecutionEngine -> IO ()++foreign import ccall unsafe "LLVMAddModule" addModule ::+ Ptr ExecutionEngine -> Ptr Module -> IO ()++foreign import ccall unsafe "LLVMRemoveModule" removeModule ::+ Ptr ExecutionEngine -> Ptr Module -> Ptr (Ptr Module) -> Ptr CString -> IO CUInt++foreign import ccall unsafe "LLVMFindFunction" findFunction ::+ Ptr ExecutionEngine -> CString -> Ptr (Ptr Function) -> IO CUInt++foreign import ccall unsafe "LLVMGetPointerToGlobal" getPointerToGlobal ::+ Ptr ExecutionEngine -> Ptr GlobalValue -> IO (Ptr ())
+ src/LLVM/General/Internal/FFI/Function.h view
@@ -0,0 +1,39 @@+#ifndef __LLVM_GENERAL_INTERNAL_FFI__FUNCTION__H__+#define __LLVM_GENERAL_INTERNAL_FFI__FUNCTION__H__++#define LLVM_GENERAL_FOR_EACH_CALLCONV(macro) \+ macro(C) \+ macro(Fast) \+ macro(Cold) \++#define LLVM_GENERAL_FOR_EACH_PARAM_ATTR(macro) \+ macro(ZExt) \+ macro(SExt) \+ macro(InReg) \+ macro(StructRet) \+ macro(NoAlias) \+ macro(ByVal) \+ macro(NoCapture) \+ macro(Nest) \++#define LLVM_GENERAL_FOR_EACH_FUNCTION_ATTR(macro) \+ macro(NoReturn,Attribute) \+ macro(NoUnwind,Attribute) \+ macro(ReadNone,Attribute) \+ macro(ReadOnly,Attribute) \+ macro(NoInline,Attribute) \+ macro(AlwaysInline,Attribute) \+ macro(OptimizeForSize,Attribute) \+ macro(StackProtect,Attribute) \+ macro(StackProtectReq,Attribute) \+ macro(Alignment,) \+ macro(NoRedZone,Attribute) \+ macro(NoImplicitFloat,Attribute) \+ macro(Naked,Attribute) \+ macro(InlineHint,Attribute) \+ macro(StackAlignment,) \+ macro(ReturnsTwice,) \+ macro(UWTable,) \+ macro(NonLazyBind,) \++#endif
+ src/LLVM/General/Internal/FFI/Function.hs view
@@ -0,0 +1,60 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses+ #-}++module LLVM.General.Internal.FFI.Function where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.Context+import LLVM.General.Internal.FFI.LLVMCTypes+import LLVM.General.Internal.FFI.PtrHierarchy++foreign import ccall unsafe "LLVMGetFunctionCallConv" getFunctionCallConv ::+ Ptr Function -> IO CallConv++foreign import ccall unsafe "LLVMSetFunctionCallConv" setFunctionCallConv ::+ Ptr Function -> CallConv -> IO ()++foreign import ccall unsafe "LLVMAddFunctionAttr" addFunctionAttr ::+ Ptr Function -> FunctionAttr -> IO ()++foreign import ccall unsafe "LLVMGetFunctionAttr" getFunctionAttr ::+ Ptr Function -> IO FunctionAttr++foreign import ccall unsafe "LLVMGetFirstBasicBlock" getFirstBasicBlock ::+ Ptr Function -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVMGetLastBasicBlock" getLastBasicBlock ::+ Ptr Function -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVMGetNextBasicBlock" getNextBasicBlock ::+ Ptr BasicBlock -> IO (Ptr BasicBlock)++foreign import ccall unsafe "LLVMAppendBasicBlockInContext" appendBasicBlockInContext ::+ Ptr Context -> Ptr Function -> CString -> IO (Ptr BasicBlock)+++foreign import ccall unsafe "LLVMCountParams" countParams ::+ Ptr Function -> IO CUInt++foreign import ccall unsafe "LLVMGetParams" getParams ::+ Ptr Function -> Ptr (Ptr Parameter) -> IO ()++foreign import ccall unsafe "LLVMGetAttribute" getAttribute ::+ Ptr Parameter -> IO ParamAttr++foreign import ccall unsafe "LLVMAddAttribute" addAttribute ::+ Ptr Parameter -> ParamAttr -> IO ()++foreign import ccall unsafe "LLVM_General_GetFunctionRetAttr" getFunctionRetAttr ::+ Ptr Function -> IO ParamAttr++foreign import ccall unsafe "LLVM_General_AddFunctionRetAttr" addFunctionRetAttr ::+ Ptr Function -> ParamAttr -> IO ()+++
+ src/LLVM/General/Internal/FFI/FunctionC.cpp view
@@ -0,0 +1,25 @@+#define __STDC_LIMIT_MACROS+#include "llvm/LLVMContext.h"+#include "llvm/Attributes.h"++#include "llvm-c/Core.h"++using namespace llvm;++extern "C" {++LLVMAttribute LLVM_General_GetFunctionRetAttr(LLVMValueRef f) {+ return (LLVMAttribute)unwrap<Function>(f)->getRetAttributes().Raw();+}++void LLVM_General_AddFunctionRetAttr(LLVMValueRef v, LLVMAttribute attr) {+ Function &f = *unwrap<Function>(v);+ LLVMContext &context = f.getContext();+ AttrBuilder attrBuilder(attr);+ f.setAttributes(+ f.getAttributes().addAttr(context, AttrListPtr::ReturnIndex, Attributes::get(context, attrBuilder))+ );+}+++}
+ src/LLVM/General/Internal/FFI/GlobalAlias.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses,+ FlexibleInstances,+ UndecidableInstances,+ OverlappingInstances+ #-}++-- | FFI functions for handling the LLVM GlobalAlias class+module LLVM.General.Internal.FFI.GlobalAlias where++import Foreign.Ptr++import LLVM.General.Internal.FFI.PtrHierarchy++-- | test if a 'Value' is a 'GlobalAlias'+foreign import ccall unsafe "LLVMIsAGlobalAlias" isAGlobalAlias ::+ Ptr Value -> IO (Ptr GlobalAlias)++-- | get the constant aliased by this alias+foreign import ccall unsafe "LLVM_General_GetAliasee" getAliasee ::+ Ptr GlobalAlias -> IO (Ptr Constant)++-- | set the constant aliased by this alias+foreign import ccall unsafe "LLVM_General_SetAliasee" setAliasee ::+ Ptr GlobalAlias -> Ptr Constant -> IO ()+
+ src/LLVM/General/Internal/FFI/GlobalAliasC.cpp view
@@ -0,0 +1,21 @@+#define __STDC_LIMIT_MACROS+#include "llvm/LLVMContext.h"+#include "llvm/GlobalAlias.h"++#include "llvm-c/Core.h"++#include <iostream>++using namespace llvm;++extern "C" {++LLVMValueRef LLVM_General_GetAliasee(LLVMValueRef g) {+ return wrap(unwrap<GlobalAlias>(g)->getAliasee());+}++void LLVM_General_SetAliasee(LLVMValueRef g, LLVMValueRef c) {+ unwrap<GlobalAlias>(g)->setAliasee(unwrap<Constant>(c));+}++}
+ src/LLVM/General/Internal/FFI/GlobalValue.h view
@@ -0,0 +1,29 @@+#ifndef __LLVM_GENERAL_INTERNAL_FFI__GLOBAL_VALUE__H__+#define __LLVM_GENERAL_INTERNAL_FFI__GLOBAL_VALUE__H__++#define LLVM_GENERAL_FOR_EACH_LINKAGE(macro) \+ macro(External) \+ macro(AvailableExternally) \+ macro(LinkOnceAny) \+ macro(LinkOnceODR) \+ macro(LinkOnceODRAutoHide) \+ macro(WeakAny) \+ macro(WeakODR) \+ macro(Appending) \+ macro(Internal) \+ macro(Private) \+ macro(DLLImport) \+ macro(DLLExport) \+ macro(ExternalWeak) \+ macro(Ghost) \+ macro(Common) \+ macro(LinkerPrivate) \+ macro(LinkerPrivateWeak) \+++#define LLVM_GENERAL_FOR_EACH_VISIBILITY(macro) \+ macro(Default) \+ macro(Hidden) \+ macro(Protected) \++#endif
+ src/LLVM/General/Internal/FFI/GlobalValue.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses,+ FlexibleInstances,+ UndecidableInstances,+ OverlappingInstances+ #-}++-- | FFI functions for handling the LLVM GlobalValue class+module LLVM.General.Internal.FFI.GlobalValue where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsAGlobalValue" isAGlobalValue ::+ Ptr Value -> IO (Ptr GlobalValue)++foreign import ccall unsafe "LLVMGetLinkage" getLinkage ::+ Ptr GlobalValue -> IO Linkage++foreign import ccall unsafe "LLVMSetLinkage" setLinkage ::+ Ptr GlobalValue -> Linkage -> IO ()++foreign import ccall unsafe "LLVMGetSection" getSection ::+ Ptr GlobalValue -> IO CString++foreign import ccall unsafe "LLVMSetSection" setSection ::+ Ptr GlobalValue -> CString -> IO ()++foreign import ccall unsafe "LLVMGetVisibility" getVisibility ::+ Ptr GlobalValue -> IO Visibility++foreign import ccall unsafe "LLVMSetVisibility" setVisibility ::+ Ptr GlobalValue -> Visibility -> IO ()++foreign import ccall unsafe "LLVMGetAlignment" getAlignment ::+ Ptr GlobalValue -> IO CUInt++foreign import ccall unsafe "LLVMSetAlignment" setAlignment ::+ Ptr GlobalValue -> CUInt -> IO ()++foreign import ccall unsafe "LLVM_General_HasUnnamedAddr" hasUnnamedAddr ::+ Ptr GlobalValue -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_SetUnnamedAddr" setUnnamedAddr ::+ Ptr GlobalValue -> LLVMBool -> IO ()+++
+ src/LLVM/General/Internal/FFI/GlobalValueC.cpp view
@@ -0,0 +1,17 @@+#define __STDC_LIMIT_MACROS++#include "llvm-c/Core.h"++using namespace llvm;++extern "C" {++LLVMBool LLVM_General_HasUnnamedAddr(LLVMValueRef globalVal) {+ return unwrap<GlobalValue>(globalVal)->hasUnnamedAddr();+}++void LLVM_General_SetUnnamedAddr(LLVMValueRef globalVal, LLVMBool isUnnamedAddr) {+ unwrap<GlobalValue>(globalVal)->setUnnamedAddr(isUnnamedAddr);+}++}
+ src/LLVM/General/Internal/FFI/GlobalVariable.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses,+ FlexibleInstances,+ UndecidableInstances,+ OverlappingInstances+ #-}++-- | FFI functions for handling the LLVM GlobalVariable class+module LLVM.General.Internal.FFI.GlobalVariable where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsAGlobalVariable" isAGlobalVariable ::+ Ptr Value -> IO (Ptr GlobalVariable)++foreign import ccall unsafe "LLVMIsGlobalConstant" isGlobalConstant ::+ Ptr GlobalVariable -> IO LLVMBool++foreign import ccall unsafe "LLVMSetGlobalConstant" setGlobalConstant ::+ Ptr GlobalVariable -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVMGetInitializer" getInitializer ::+ Ptr GlobalVariable -> IO (Ptr Constant)++foreign import ccall unsafe "LLVMSetInitializer" setInitializer ::+ Ptr GlobalVariable -> Ptr Constant -> IO ()++foreign import ccall unsafe "LLVMIsThreadLocal" isThreadLocal ::+ Ptr GlobalVariable -> IO LLVMBool++foreign import ccall unsafe "LLVMSetThreadLocal" setThreadLocal ::+ Ptr GlobalVariable -> LLVMBool -> IO ()+
+ src/LLVM/General/Internal/FFI/InlineAssembly.h view
@@ -0,0 +1,14 @@+#ifndef __LLVM_GENERAL_INTERNAL_FFI__INLINE_ASSEMBLY__H__+#define __LLVM_GENERAL_INTERNAL_FFI__INLINE_ASSEMBLY__H__++#define LLVM_GENERAL_FOR_EACH_ASM_DIALECT(macro) \+ macro(ATT) \+ macro(Intel) \++typedef enum {+#define ENUM_CASE(d) LLVMAsmDialect_ ## d,+ LLVM_GENERAL_FOR_EACH_ASM_DIALECT(ENUM_CASE)+#undef ENUM_CASE+} LLVMAsmDialect;++#endif
+ src/LLVM/General/Internal/FFI/InlineAssembly.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE+ ForeignFunctionInterface+ #-}++module LLVM.General.Internal.FFI.InlineAssembly where++import Foreign.C+import Foreign.Ptr++import LLVM.General.Internal.FFI.LLVMCTypes+import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.Type++foreign import ccall unsafe "LLVMIsAInlineAsm" isAInlineAsm ::+ Ptr Value -> IO (Ptr InlineAsm)++foreign import ccall unsafe "LLVM_General_CreateInlineAsm" createInlineAsm ::+ Ptr Type -> CString -> CString -> LLVMBool -> LLVMBool -> AsmDialect -> IO (Ptr InlineAsm)++foreign import ccall unsafe "LLVM_General_GetInlineAsmAsmString" getInlineAsmAssemblyString ::+ Ptr InlineAsm -> IO CString++foreign import ccall unsafe "LLVM_General_GetInlineAsmConstraintString" getInlineAsmConstraintString ::+ Ptr InlineAsm -> IO CString++foreign import ccall unsafe "LLVM_General_InlineAsmHasSideEffects" inlineAsmHasSideEffects ::+ Ptr InlineAsm -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_InlineAsmIsAlignStack" inlineAsmIsAlignStack ::+ Ptr InlineAsm -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_GetInlineAsmDialect" getInlineAsmDialect ::+ Ptr InlineAsm -> IO AsmDialect+
+ src/LLVM/General/Internal/FFI/InlineAssemblyC.cpp view
@@ -0,0 +1,72 @@+#define __STDC_LIMIT_MACROS+#include "llvm/InlineAsm.h"+#include "llvm-c/Core.h"++#include "LLVM/General/Internal/FFI/InlineAssembly.h"++using namespace llvm;++namespace llvm {+static LLVMAsmDialect wrap(InlineAsm::AsmDialect d) {+ switch(d) {+#define ENUM_CASE(x) case InlineAsm::AD_ ## x: return LLVMAsmDialect_ ## x;+LLVM_GENERAL_FOR_EACH_ASM_DIALECT(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVMAsmDialect(0);+ }+}++static InlineAsm::AsmDialect unwrap(LLVMAsmDialect d) {+ switch(d) {+#define ENUM_CASE(x) case LLVMAsmDialect_ ## x: return InlineAsm::AD_ ## x;+LLVM_GENERAL_FOR_EACH_ASM_DIALECT(ENUM_CASE)+#undef ENUM_CASE+ default: return InlineAsm::AsmDialect(0);+ }+}+}++extern "C" {++LLVMValueRef LLVM_General_CreateInlineAsm(+ LLVMTypeRef t,+ const char *asmStr,+ const char *constraintsStr,+ LLVMBool hasSideEffects,+ LLVMBool isAlignStack,+ LLVMAsmDialect dialect+) {+ return wrap(+ InlineAsm::get(+ unwrap<FunctionType>(t), + asmStr,+ constraintsStr,+ hasSideEffects,+ isAlignStack,+ unwrap(dialect)+ )+ );+}++const char *LLVM_General_GetInlineAsmAsmString(LLVMValueRef v) {+ return unwrap<InlineAsm>(v)->getAsmString().c_str();+}++const char *LLVM_General_GetInlineAsmConstraintString(LLVMValueRef v) {+ return unwrap<InlineAsm>(v)->getConstraintString().c_str();+}++LLVMBool LLVM_General_InlineAsmHasSideEffects(LLVMValueRef v) {+ return unwrap<InlineAsm>(v)->hasSideEffects();+}++LLVMBool LLVM_General_InlineAsmIsAlignStack(LLVMValueRef v) {+ return unwrap<InlineAsm>(v)->isAlignStack();+}++LLVMAsmDialect LLVM_General_GetInlineAsmDialect(LLVMValueRef v) {+ return wrap(unwrap<InlineAsm>(v)->getDialect());+}++}+
+ src/LLVM/General/Internal/FFI/Instruction.h view
@@ -0,0 +1,48 @@+#ifndef __LLVM_GENERAL_INTERNAL_FFI__INSTRUCTION__H__+#define __LLVM_GENERAL_INTERNAL_FFI__INSTRUCTION__H__++#define LLVM_GENERAL_FOR_EACH_ATOMIC_ORDERING(macro) \+ macro(NotAtomic) \+ macro(Unordered) \+ macro(Monotonic) \+ macro(Acquire) \+ macro(Release) \+ macro(AcquireRelease) \+ macro(SequentiallyConsistent)++typedef enum {+#define ENUM_CASE(x) LLVM ## x ## AtomicOrdering,+LLVM_GENERAL_FOR_EACH_ATOMIC_ORDERING(ENUM_CASE)+#undef ENUM_CASE+} LLVMAtomicOrdering;++#define LLVM_GENERAL_FOR_EACH_SYNCRONIZATION_SCOPE(macro) \+ macro(SingleThread) \+ macro(CrossThread)++typedef enum {+#define ENUM_CASE(x) LLVM ## x ## SynchronizationScope,+LLVM_GENERAL_FOR_EACH_SYNCRONIZATION_SCOPE(ENUM_CASE)+#undef ENUM_CASE+} LLVMSynchronizationScope;++#define LLVM_GENERAL_FOR_EACH_RMW_OPERATION(macro) \+ macro(Xchg) \+ macro(Add) \+ macro(Sub) \+ macro(And) \+ macro(Nand) \+ macro(Or) \+ macro(Xor) \+ macro(Max) \+ macro(Min) \+ macro(UMax) \+ macro(UMin)++typedef enum {+#define ENUM_CASE(x) LLVM ## x ## RMWOperation,+LLVM_GENERAL_FOR_EACH_RMW_OPERATION(ENUM_CASE)+#undef ENUM_CASE+} LLVMAtomicRMWOperation;++#endif
+ src/LLVM/General/Internal/FFI/Instruction.hs view
@@ -0,0 +1,147 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses,+ FlexibleInstances,+ UndecidableInstances,+ OverlappingInstances,+ TemplateHaskell+ #-}++module LLVM.General.Internal.FFI.Instruction where++import Control.Monad+import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.Type+import LLVM.General.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsAInstruction" isAInstruction ::+ Ptr Value -> IO (Ptr Instruction)++newtype COpcode = COpcode CUInt++-- get the C API opcode+foreign import ccall unsafe "LLVMGetInstructionOpcode" getInstructionOpcode :: + Ptr Instruction -> IO COpcode++-- get the C++ API opcode (one less level of mapping than for that from the C API)+foreign import ccall unsafe "LLVM_General_GetInstructionDefOpcode" getInstructionDefOpcode :: + Ptr Instruction -> IO CPPOpcode++foreign import ccall unsafe "LLVMGetICmpPredicate" getICmpPredicate ::+ Ptr Instruction -> IO ICmpPredicate++foreign import ccall unsafe "LLVM_General_GetFCmpPredicate" getFCmpPredicate ::+ Ptr Instruction -> IO FCmpPredicate++foreign import ccall unsafe "LLVMGetInstructionCallConv" getInstructionCallConv ::+ Ptr Instruction -> IO CallConv++foreign import ccall unsafe "LLVMSetInstructionCallConv" setInstructionCallConv ::+ Ptr Instruction -> CallConv -> IO ()++foreign import ccall unsafe "LLVMIsTailCall" isTailCall ::+ Ptr Instruction -> IO LLVMBool++foreign import ccall unsafe "LLVMSetTailCall" setTailCall ::+ Ptr Instruction -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVM_General_GetCallInstCalledValue" getCallInstCalledValue ::+ Ptr Instruction -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_General_GetCallInstFunctionAttr" getCallInstFunctionAttr ::+ Ptr Instruction -> IO FunctionAttr++foreign import ccall unsafe "LLVM_General_AddCallInstFunctionAttr" addCallInstFunctionAttr ::+ Ptr Instruction -> FunctionAttr -> IO ()++foreign import ccall unsafe "LLVM_General_GetCallInstAttr" getCallInstAttr ::+ Ptr Instruction -> CUInt -> IO ParamAttr++foreign import ccall unsafe "LLVM_General_AddCallInstAttr" addCallInstAttr ::+ Ptr Instruction -> CUInt -> ParamAttr -> IO ()++foreign import ccall unsafe "LLVMAddIncoming" addIncoming' ::+ Ptr Instruction -> Ptr (Ptr Value) -> Ptr (Ptr BasicBlock) -> CUInt -> IO ()++addIncoming :: Ptr Instruction -> (CUInt, Ptr (Ptr Value)) -> (CUInt, Ptr (Ptr BasicBlock)) -> IO ()+addIncoming i (nvs, vs) (nbs, bs) | nbs == nvs = addIncoming' i vs bs nbs++foreign import ccall unsafe "LLVMCountIncoming" countIncoming ::+ Ptr Instruction -> IO CUInt++foreign import ccall unsafe "LLVMGetIncomingValue" getIncomingValue ::+ Ptr Instruction -> CUInt -> IO (Ptr Value)++foreign import ccall unsafe "LLVMGetIncomingBlock" getIncomingBlock ::+ Ptr Instruction -> CUInt -> IO (Ptr BasicBlock)+++foreign import ccall unsafe "LLVMAddCase" addCase ::+ Ptr Instruction -> Ptr Constant -> Ptr BasicBlock -> IO ()++foreign import ccall unsafe "LLVM_General_GetSwitchCases" getSwitchCases ::+ Ptr Instruction -> Ptr (Ptr Constant) -> Ptr (Ptr BasicBlock) -> IO ()++foreign import ccall unsafe "LLVMAddDestination" addDestination ::+ Ptr Instruction -> Ptr BasicBlock -> IO ()++foreign import ccall unsafe "LLVM_General_GetIndirectBrDests" getIndirectBrDests ::+ Ptr Instruction -> Ptr (Ptr BasicBlock) -> IO ()+++foreign import ccall unsafe "LLVM_General_GetInstrAlignment" getInstrAlignment ::+ Ptr Instruction -> IO CUInt++foreign import ccall unsafe "LLVM_General_SetInstrAlignment" setInstrAlignment ::+ Ptr Instruction -> CUInt -> IO ()++foreign import ccall unsafe "LLVM_General_GetAllocaNumElements" getAllocaNumElements ::+ Ptr Instruction -> IO (Ptr Value)++foreign import ccall unsafe "LLVM_General_GetAllocatedType" getAllocatedType ::+ Ptr Instruction -> IO (Ptr Type)++foreign import ccall unsafe "LLVM_General_GetAtomicOrdering" getAtomicOrdering ::+ Ptr Instruction -> IO MemoryOrdering++foreign import ccall unsafe "LLVM_General_GetSynchronizationScope" getSynchronizationScope ::+ Ptr Instruction -> IO LLVMBool++getAtomicity i = return (,) `ap` getSynchronizationScope i `ap` getAtomicOrdering i++foreign import ccall unsafe "LLVM_General_GetVolatile" getVolatile ::+ Ptr Instruction -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_GetInBounds" getInBounds ::+ Ptr Value -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_SetInBounds" setInBounds ::+ Ptr Instruction -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVM_General_GetAtomicRMWOperation" getAtomicRMWOperation ::+ Ptr Instruction -> IO RMWOperation++foreign import ccall unsafe "LLVM_General_CountInstStructureIndices" countInstStructureIndices ::+ Ptr Instruction -> IO CUInt++foreign import ccall unsafe "LLVM_General_GetInstStructureIndices" getInstStructureIndices ::+ Ptr Instruction -> Ptr CUInt -> IO ()++foreign import ccall unsafe "LLVMAddClause" addClause ::+ Ptr Instruction -> Ptr Constant -> IO ()++foreign import ccall unsafe "LLVMSetCleanup" setCleanup ::+ Ptr Instruction -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVM_General_IsCleanup" isCleanup ::+ Ptr Instruction -> IO LLVMBool++foreign import ccall unsafe "LLVMSetMetadata" setMetadata ::+ Ptr Instruction -> MDKindID -> Ptr MDNode -> IO ()++foreign import ccall unsafe "LLVM_General_GetMetadata" getMetadata ::+ Ptr Instruction -> Ptr MDKindID -> Ptr (Ptr MDNode) -> CUInt -> IO CUInt
+ src/LLVM/General/Internal/FFI/InstructionC.cpp view
@@ -0,0 +1,241 @@+#define __STDC_LIMIT_MACROS+#include "llvm/LLVMContext.h"+#include "llvm/InstrTypes.h"+#include "llvm/Support/CallSite.h"+#include "llvm/Attributes.h"+#include "llvm/Operator.h"++#include "llvm-c/Core.h"++#include "LLVM/General/Internal/FFI/Instruction.h"++using namespace llvm;++namespace llvm {++static LLVMAtomicOrdering wrap(AtomicOrdering l) {+ switch(l) {+#define ENUM_CASE(x) case x: return LLVM ## x ## AtomicOrdering;+LLVM_GENERAL_FOR_EACH_ATOMIC_ORDERING(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVMAtomicOrdering(0);+ }+}++static LLVMSynchronizationScope wrap(SynchronizationScope l) {+ switch(l) {+#define ENUM_CASE(x) case x: return LLVM ## x ## SynchronizationScope;+LLVM_GENERAL_FOR_EACH_SYNCRONIZATION_SCOPE(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVMSynchronizationScope(0);+ }+}++static LLVMAtomicRMWOperation wrap(AtomicRMWInst::BinOp l) {+ switch(l) {+#define ENUM_CASE(x) case AtomicRMWInst::x: return LLVM ## x ## RMWOperation;+LLVM_GENERAL_FOR_EACH_RMW_OPERATION(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVMAtomicRMWOperation(0);+ }+}++}++extern "C" {++unsigned LLVM_General_GetInstructionDefOpcode(LLVMValueRef val) {+ return unwrap<Instruction>(val)->getOpcode();+}++unsigned LLVM_General_HasNoSignedWrap(LLVMValueRef val) {+ return unwrap<OverflowingBinaryOperator>(val)->hasNoSignedWrap();+}++unsigned LLVM_General_HasNoUnsignedWrap(LLVMValueRef val) {+ return unwrap<OverflowingBinaryOperator>(val)->hasNoUnsignedWrap();+}++int LLVM_General_IsExact(LLVMValueRef val) {+ return unwrap<PossiblyExactOperator>(val)->isExact();+}++LLVMValueRef LLVM_General_GetCallInstCalledValue(+ LLVMValueRef callInst+) {+ return wrap(CallSite(unwrap<Instruction>(callInst)).getCalledValue());+}++LLVMAttribute LLVM_General_GetCallInstAttr(LLVMValueRef callInst, unsigned i) {+ return (LLVMAttribute)CallSite(unwrap<Instruction>(callInst)).getAttributes().getParamAttributes(i).Raw();+}++void LLVM_General_AddCallInstAttr(LLVMValueRef callInst, unsigned i, LLVMAttribute attr) {+ CallSite callSite(unwrap<Instruction>(callInst));+ LLVMContext &context = callSite->getContext();+ AttrBuilder attrBuilder(attr);+ callSite.setAttributes(callSite.getAttributes().addAttr(context, i, Attributes::get(context, attrBuilder)));+}++LLVMAttribute LLVM_General_GetCallInstFunctionAttr(LLVMValueRef callInst) {+ return LLVM_General_GetCallInstAttr(callInst, AttrListPtr::FunctionIndex);+}++void LLVM_General_AddCallInstFunctionAttr(LLVMValueRef callInst, LLVMAttribute attr) {+ LLVM_General_AddCallInstAttr(callInst, AttrListPtr::FunctionIndex, attr);+}++LLVMValueRef LLVM_General_GetAllocaNumElements(LLVMValueRef a) {+ return wrap(unwrap<AllocaInst>(a)->getArraySize());+}++LLVMTypeRef LLVM_General_GetAllocatedType(LLVMValueRef a) {+ return wrap(unwrap<AllocaInst>(a)->getAllocatedType());+}++// ------------------------------------------------------------++#define LLVM_GENERAL_FOR_EACH_ALIGNMENT_INST(macro) \+ macro(Alloca) \+ macro(Load) \+ macro(Store)++unsigned LLVM_General_GetInstrAlignment(LLVMValueRef l) {+ switch(unwrap<Instruction>(l)->getOpcode()) {+#define ENUM_CASE(n) case Instruction::n: return unwrap<n ## Inst>(l)->getAlignment();+ LLVM_GENERAL_FOR_EACH_ALIGNMENT_INST(ENUM_CASE)+#undef ENUM_CASE+ default: return 0;+ }+}++void LLVM_General_SetInstrAlignment(LLVMValueRef l, unsigned a) {+ switch(unwrap<Instruction>(l)->getOpcode()) {+#define ENUM_CASE(n) case Instruction::n: unwrap<n ## Inst>(l)->setAlignment(a);+ LLVM_GENERAL_FOR_EACH_ALIGNMENT_INST(ENUM_CASE)+#undef ENUM_CASE+ }+}++// ------------------------------------------------------------++#define LLVM_GENERAL_FOR_EACH_ATOMIC_INST(macro) \+ macro(Load) \+ macro(Store) \+ macro(Fence) \+ macro(AtomicCmpXchg) \+ macro(AtomicRMW)++LLVMAtomicOrdering LLVM_General_GetAtomicOrdering(LLVMValueRef i) {+ switch(unwrap<Instruction>(i)->getOpcode()) {+#define ENUM_CASE(n) case Instruction::n: return wrap(unwrap<n ## Inst>(i)->getOrdering());+ LLVM_GENERAL_FOR_EACH_ATOMIC_INST(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVMAtomicOrdering(0);+ }+}++LLVMSynchronizationScope LLVM_General_GetSynchronizationScope(LLVMValueRef i) {+ switch(unwrap<Instruction>(i)->getOpcode()) {+#define ENUM_CASE(n) case Instruction::n: return wrap(unwrap<n ## Inst>(i)->getSynchScope());+ LLVM_GENERAL_FOR_EACH_ATOMIC_INST(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVMSynchronizationScope(0);+ }+}++#define LLVM_GENERAL_FOR_EACH_VOLATILITY_INST(macro) \+ macro(Load) \+ macro(Store) \+ macro(AtomicCmpXchg) \+ macro(AtomicRMW)++LLVMBool LLVM_General_GetVolatile(LLVMValueRef i) {+ switch(unwrap<Instruction>(i)->getOpcode()) {+#define ENUM_CASE(n) case Instruction::n: return unwrap<n ## Inst>(i)->isVolatile();+ LLVM_GENERAL_FOR_EACH_VOLATILITY_INST(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVMBool(0);+ }+}++// ------------------------------------------------------------++LLVMBool LLVM_General_GetInBounds(LLVMValueRef i) {+ return unwrap<GEPOperator>(i)->isInBounds();+}++void LLVM_General_SetInBounds(LLVMValueRef i, LLVMBool b) {+ unwrap<GetElementPtrInst>(i)->setIsInBounds(b);+}++LLVMAtomicRMWOperation LLVM_General_GetAtomicRMWOperation(LLVMValueRef i) {+ return wrap(unwrap<AtomicRMWInst>(i)->getOperation());+}++LLVMRealPredicate LLVM_General_GetFCmpPredicate(LLVMValueRef Inst) {+ if (FCmpInst *I = dyn_cast<FCmpInst>(unwrap(Inst)))+ return (LLVMRealPredicate)I->getPredicate();+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(unwrap(Inst)))+ if (CE->getOpcode() == Instruction::FCmp)+ return (LLVMRealPredicate)CE->getPredicate();+ return (LLVMRealPredicate)0;+}++unsigned LLVM_General_CountInstStructureIndices(LLVMValueRef v) {+ if (ExtractValueInst *i = dyn_cast<ExtractValueInst>(unwrap(v))) return i->getNumIndices();+ if (InsertValueInst *i = dyn_cast<InsertValueInst>(unwrap(v))) return i->getNumIndices();+ return 0;+}++void LLVM_General_GetInstStructureIndices(LLVMValueRef v, unsigned *is) {+ ArrayRef<unsigned> a;+ if (ExtractValueInst *i = dyn_cast<ExtractValueInst>(unwrap(v))) a = i->getIndices();+ if (InsertValueInst *i = dyn_cast<InsertValueInst>(unwrap(v))) a = i->getIndices();+ std::copy(a.begin(), a.end(), is);+}++LLVMBool LLVM_General_IsCleanup(LLVMValueRef v) {+ return unwrap<LandingPadInst>(v)->isCleanup();+}++void LLVM_General_GetSwitchCases(+ LLVMValueRef v,+ LLVMValueRef *values,+ LLVMBasicBlockRef *dests+) {+ SwitchInst *s = unwrap<SwitchInst>(v);+ for(SwitchInst::CaseIt i = s->case_begin(); i != s->case_end(); ++i, ++values, ++dests) {+ *values = wrap(i.getCaseValue());+ *dests = wrap(i.getCaseSuccessor());+ }+}++void LLVM_General_GetIndirectBrDests(+ LLVMValueRef v,+ LLVMBasicBlockRef *dests+) {+ IndirectBrInst *ib = unwrap<IndirectBrInst>(v);+ for(unsigned i=0; i != ib->getNumDestinations(); ++i, ++dests)+ *dests = wrap(ib->getDestination(i));+}++unsigned LLVM_General_GetMetadata(+ LLVMValueRef i,+ unsigned *kinds,+ LLVMValueRef *nodes,+ unsigned nKinds+) {+ SmallVector<std::pair<unsigned, MDNode *>, 4> mds;+ unwrap<Instruction>(i)->getAllMetadata(mds);+ if (mds.size() <= nKinds) {+ for(unsigned i=0; i<mds.size(); ++i) {+ kinds[i] = mds[i].first;+ nodes[i] = wrap(mds[i].second);+ }+ }+ return mds.size();+}++}+
+ src/LLVM/General/Internal/FFI/InstructionDefs.hsc view
@@ -0,0 +1,56 @@+{-# LANGUAGE DeriveDataTypeable #-}+-- This module translates the instruction data in "llvm/Instruction.def" into a Haskell data structure,+-- so it may be accessed conveniently with Template Haskell code+module LLVM.General.Internal.FFI.InstructionDefs where++import LLVM.General.Internal.FFI.LLVMCTypes++#define FIRST_TERM_INST(num) struct inst { const char *kind; int opcode; const char *name; const char *clas; } insts[] = { { "Terminator", },++#define FIRST_BINARY_INST(num) { "Binary" },+#define FIRST_MEMORY_INST(num) { "Memory" },+#define FIRST_CAST_INST(num) { "Cast" },+#define FIRST_OTHER_INST(num) { "Other" },++#define HANDLE_INST(num,opcode,class) { 0, num, #opcode, #class, },++#define LAST_OTHER_INST(num) { 0, 0, 0, 0, } };++#include "llvm/Instruction.def"++#{+define hsc_inject() { \+ hsc_printf(" [ "); \+ struct inst *i; \+ const char *kind; \+ int first = 1; \+ for(i = insts; i->kind || i->opcode; ++i) { \+ if (i->kind) { kind = i->kind; continue; } \+ if (!first) { hsc_printf(", "); } else { first = 0; } \+ hsc_printf( \+ " (CPPOpcode %d,\"%s\",\"%s\", %s)", \+ i->opcode, i->name, i->clas, kind \+ ); \+ } \+ hsc_printf(" ] "); \+}+}++data InstructionKind = Terminator | Binary | Memory | Cast | Other+ deriving (Eq, Ord, Show)++data InstructionDef = InstructionDef {+ cppOpcode :: CPPOpcode,+ cAPIName :: String,+ cAPIClassName :: String,+ instructionKind :: InstructionKind+ }+ deriving (Eq, Ord, Show)++instructionDefs :: [InstructionDef]+instructionDefs = [ + InstructionDef o an acn k+ | (o, an, acn, k) <- #{inject},+ an /= "UserOp1" && an /= "UserOp2"+ ]+
+ src/LLVM/General/Internal/FFI/Iterate.hs view
@@ -0,0 +1,13 @@+-- | Functions to help handle LLVM iteration patterns+module LLVM.General.Internal.FFI.Iterate where++import Control.Monad+import Data.Functor+import Foreign.Ptr++-- | retrieve a sequence of objects which form a linked list, given an action to+-- | retrieve the first member and an action to proceed through the list+getXs :: IO (Ptr a) -> (Ptr a -> IO (Ptr a)) -> IO [Ptr a]+getXs firstX nextX = walk =<< firstX+ where walk x | x == nullPtr = return []+ walk x = (x:) <$> (walk <=< nextX) x
+ src/LLVM/General/Internal/FFI/LLVMCTypes.hsc view
@@ -0,0 +1,180 @@+{-# LANGUAGE+ DeriveDataTypeable,+ StandaloneDeriving,+ GeneralizedNewtypeDeriving+ #-}+-- | Define types which correspond cleanly with some simple types on the C/C++ side.+-- Encapsulate hsc macro weirdness here, supporting higher-level tricks elsewhere.+module LLVM.General.Internal.FFI.LLVMCTypes where++#define __STDC_LIMIT_MACROS+#include "llvm-c/Core.h"+#include "llvm-c/Target.h"+#include "llvm-c/TargetMachine.h"+#include "LLVM/General/Internal/FFI/Instruction.h"+#include "LLVM/General/Internal/FFI/Value.h"+#include "LLVM/General/Internal/FFI/SMDiagnostic.h"+#include "LLVM/General/Internal/FFI/InlineAssembly.h"+#include "LLVM/General/Internal/FFI/Target.h"+#include "LLVM/General/Internal/FFI/Function.h"+#include "LLVM/General/Internal/FFI/GlobalValue.h"+#include "LLVM/General/Internal/FFI/Type.h"++import Language.Haskell.TH.Quote++import Data.Data+import Data.Bits+import Foreign.C+import Foreign.Storable++#{+define hsc_inject(l, typ, cons, hprefix, recmac) { \+ struct { const char *s; unsigned n; } *p, list[] = { LLVM_GENERAL_FOR_EACH_ ## l(recmac) }; \+ for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+ hsc_printf(#hprefix "%s :: " #typ "\n", p->s); \+ hsc_printf(#hprefix "%s = " #cons " %u\n", p->s, p->n); \+ } \+ hsc_printf(#hprefix "P = QuasiQuoter {\n" \+ " quoteExp = undefined,\n" \+ " quotePat = \\s -> dataToPatQ (const Nothing) $ case s of"); \+ for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+ hsc_printf("\n \"%s\" -> " #hprefix "%s", p->s, p->s); \+ } \+ hsc_printf("\n x -> error $ \"bad quasiquoted FFI constant for " #hprefix ": \" ++ x"); \+ hsc_printf(",\n" \+ " quoteType = undefined,\n" \+ " quoteDec = undefined\n" \+ " }\n"); \+} +}++deriving instance Data CUInt++newtype LLVMBool = LLVMBool CUInt++newtype CPPOpcode = CPPOpcode CUInt+ deriving (Eq, Ord, Show, Typeable, Data)++newtype ICmpPredicate = ICmpPredicate CUInt+ deriving (Eq, Ord, Show, Typeable, Data)+#{enum ICmpPredicate, ICmpPredicate,+ iCmpPredEQ = LLVMIntEQ,+ iCmpPredNE = LLVMIntNE,+ iCmpPredUGT = LLVMIntUGT,+ iCmpPredUGE = LLVMIntUGE,+ iCmpPredULT = LLVMIntULT,+ iCmpPredULE = LLVMIntULE,+ iCmpPredSGT = LLVMIntSGT,+ iCmpPredSGE = LLVMIntSGE,+ iCmpPredSLT = LLVMIntSLT,+ iCmpPredSLE = LLVMIntSLE+}++newtype FCmpPredicate = FCmpPredicate CUInt+ deriving (Eq, Ord, Show, Typeable, Data)+#{enum FCmpPredicate, FCmpPredicate,+ fCmpPredFalse = LLVMRealPredicateFalse,+ fCmpPredOEQ = LLVMRealOEQ,+ fCmpPredOGT = LLVMRealOGT,+ fCmpPredOGE = LLVMRealOGE,+ fCmpPredOLT = LLVMRealOLT,+ fCmpPredOLE = LLVMRealOLE,+ fCmpPredONE = LLVMRealONE,+ fCmpPredORD = LLVMRealORD,+ fCmpPredUNO = LLVMRealUNO,+ fCmpPredUEQ = LLVMRealUEQ,+ fCmpPredUGT = LLVMRealUGT,+ fCmpPredUGE = LLVMRealUGE,+ fCmpPredULT = LLVMRealULT,+ fCmpPredULE = LLVMRealULE,+ fCmpPredUNE = LLVMRealUNE,+ fcmpPredTrue = LLVMRealPredicateTrue+}++newtype MDKindID = MDKindID CUInt+ deriving (Storable)++newtype MemoryOrdering = MemoryOrdering CUInt+ deriving (Eq, Typeable, Data)+#define MO_Rec(n) { #n, LLVM ## n ## AtomicOrdering },+#{inject ATOMIC_ORDERING, MemoryOrdering, MemoryOrdering, memoryOrdering, MO_Rec}++newtype Linkage = Linkage CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define LK_Rec(n) { #n, LLVM ## n ## Linkage },+#{inject LINKAGE, Linkage, Linkage, linkage, LK_Rec}++newtype Visibility = Visibility CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define VIS_Rec(n) { #n, LLVM ## n ## Visibility },+#{inject VISIBILITY, Visibility, Visibility, visibility, VIS_Rec}++newtype CallConv = CallConv CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define CC_Rec(n) { #n, LLVM ## n ## CallConv },+#{inject CALLCONV, CallConv, CallConv, callConv, CC_Rec}++newtype ValueSubclassId = ValueSubclassId CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define VSID_Rec(n) { #n, LLVM ## n ## SubclassId },+#{inject VALUE_SUBCLASS, ValueSubclassId, ValueSubclassId, valueSubclassId, VSID_Rec}++newtype DiagnosticKind = DiagnosticKind CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define DK_Rec(n) { #n, LLVMDiagnosticKind ## n },+#{inject DIAGNOSTIC_KIND, DiagnosticKind, DiagnosticKind, diagnosticKind, DK_Rec}++newtype AsmDialect = AsmDialect CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define ASM_Rec(n) { #n, LLVMAsmDialect_ ## n },+#{inject ASM_DIALECT, AsmDialect, AsmDialect, asmDialect, ASM_Rec}++newtype RMWOperation = RMWOperation CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define RMWOp_Rec(n) { #n, LLVM ## n ## RMWOperation },+#{inject RMW_OPERATION, RMWOperation, RMWOperation, rmwOperation, RMWOp_Rec}++newtype RelocModel = RelocModel CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define RM_Rec(n,m) { #n, LLVMReloc ## n },+#{inject RELOC_MODEL, RelocModel, RelocModel, relocModel, RM_Rec}++newtype CodeModel = CodeModel CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define CM_Rec(n) { #n, LLVMCodeModel ## n },+#{inject CODE_MODEL, CodeModel, CodeModel, codeModel, CM_Rec}++newtype CodeGenOptLevel = CodeGenOptLevel CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define CGOL_Rec(n) { #n, LLVMCodeGenLevel ## n },+#{inject CODE_GEN_OPT_LEVEL, CodeGenOptLevel, CodeGenOptLevel, codeGenOptLevel, CGOL_Rec}++newtype FloatABIType = FloatABIType CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define FAT_Rec(n) { #n, LLVM_General_FloatABI_ ## n },+#{inject FLOAT_ABI, FloatABIType, FloatABIType, floatABI, FAT_Rec}++newtype FPOpFusionMode = FPOpFusionMode CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define FPOFM_Rec(n) { #n, LLVM_General_FPOpFusionMode_ ## n },+#{inject FP_OP_FUSION_MODE, FPOpFusionMode, FPOpFusionMode, fpOpFusionMode, FPOFM_Rec}++newtype TargetOptionFlag = TargetOptionFlag CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define TOF_Rec(n) { #n, LLVM_General_TargetOptionFlag_ ## n },+#{inject TARGET_OPTION_FLAG, TargetOptionFlag, TargetOptionFlag, targetOptionFlag, TOF_Rec}++newtype TypeKind = TypeKind CUInt+ deriving (Eq, Read, Show, Typeable, Data)+#define TK_Rec(n) { #n, LLVM ## n ## TypeKind },+#{inject TYPE_KIND, TypeKind, TypeKind, typeKind, TK_Rec}++newtype ParamAttr = ParamAttr CUInt+ deriving (Eq, Read, Show, Bits, Typeable, Data)+#define PA_Rec(n) { #n, LLVM ## n ## Attribute },+#{inject PARAM_ATTR, ParamAttr, ParamAttr, paramAttr, PA_Rec}++newtype FunctionAttr = FunctionAttr CUInt+ deriving (Eq, Read, Show, Bits, Typeable, Data)+#define FA_Rec(n,a) { #n, LLVM ## n ## a },+#{inject FUNCTION_ATTR, FunctionAttr, FunctionAttr, functionAttr, FA_Rec}
+ src/LLVM/General/Internal/FFI/Metadata.hs view
@@ -0,0 +1,69 @@+{-#+ LANGUAGE+ ForeignFunctionInterface+ #-}++module LLVM.General.Internal.FFI.Metadata where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.Context+import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.LLVMCTypes++foreign import ccall unsafe "LLVMIsAMDString" isAMDString ::+ Ptr Value -> IO (Ptr MDString)++foreign import ccall unsafe "LLVMIsAMDNode" isAMDNode ::+ Ptr Value -> IO (Ptr MDNode)++foreign import ccall unsafe "LLVMGetMDKindIDInContext" getMDKindIDInContext' ::+ Ptr Context -> Ptr CChar -> CUInt -> IO MDKindID++getMDKindIDInContext ctx (c, n) = getMDKindIDInContext' ctx c n++foreign import ccall unsafe "LLVM_General_GetMDKindNames" getMDKindNames ::+ Ptr Context -> Ptr (Ptr CChar) -> Ptr CUInt -> CUInt -> IO CUInt++foreign import ccall unsafe "LLVMMDStringInContext" mdStringInContext' ::+ Ptr Context -> CString -> CUInt -> IO (Ptr MDString)++mdStringInContext ctx (p, n) = mdStringInContext' ctx p n++foreign import ccall unsafe "LLVMGetMDString" getMDString ::+ Ptr MDString -> Ptr CUInt -> IO CString++foreign import ccall unsafe "LLVMMDNodeInContext" createMDNodeInContext' ::+ Ptr Context -> Ptr (Ptr Value) -> CUInt -> IO (Ptr MDNode)++createMDNodeInContext ctx (n, vs) = createMDNodeInContext' ctx vs n++foreign import ccall unsafe "LLVM_General_CreateTemporaryMDNodeInContext" createTemporaryMDNodeInContext ::+ Ptr Context -> IO (Ptr MDNode)++foreign import ccall unsafe "LLVM_General_DestroyTemporaryMDNode" destroyTemporaryMDNode ::+ Ptr MDNode -> IO ()++foreign import ccall unsafe "LLVM_General_GetMDNodeNumOperands" getMDNodeNumOperands ::+ Ptr MDNode -> IO CUInt++foreign import ccall unsafe "LLVMGetMDNodeOperands" getMDNodeOperands ::+ Ptr MDNode -> Ptr (Ptr Value) -> IO ()++foreign import ccall unsafe "LLVM_General_MDNodeIsFunctionLocal" mdNodeIsFunctionLocal ::+ Ptr MDNode -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_GetNamedMetadataName" getNamedMetadataName ::+ Ptr NamedMetadata -> Ptr CUInt -> IO (Ptr CChar)++foreign import ccall unsafe "LLVM_General_GetNamedMetadataNumOperands" getNamedMetadataNumOperands ::+ Ptr NamedMetadata -> IO CUInt++foreign import ccall unsafe "LLVM_General_GetNamedMetadataOperands" getNamedMetadataOperands ::+ Ptr NamedMetadata -> Ptr (Ptr MDNode) -> IO ()++foreign import ccall unsafe "LLVM_General_NamedMetadataAddOperands" namedMetadataAddOperands' ::+ Ptr NamedMetadata -> Ptr (Ptr MDNode) -> CUInt -> IO ()++namedMetadataAddOperands nm (n, vs) = namedMetadataAddOperands' nm vs n
+ src/LLVM/General/Internal/FFI/MetadataC.cpp view
@@ -0,0 +1,71 @@+#define __STDC_LIMIT_MACROS+#include "llvm/LLVMContext.h"+#include "llvm/Metadata.h"++#include "llvm-c/Core.h"++using namespace llvm;++extern "C" {++unsigned LLVM_General_GetMDKindNames(+ LLVMContextRef c,+ const char **s,+ unsigned *l,+ unsigned n+) {+ SmallVector<StringRef, 16> ns;+ unwrap(c)->getMDKindNames(ns);+ if (ns.size() <= n) {+ for(unsigned i=0; i < ns.size(); ++i) {+ s[i] = ns[i].data();+ l[i] = ns[i].size();+ }+ }+ return ns.size();+}++unsigned LLVM_General_GetMDNodeNumOperands(LLVMValueRef v) {+ return unwrap<MDNode>(v)->getNumOperands();+}++unsigned LLVM_General_MDNodeIsFunctionLocal(LLVMValueRef v) {+ return unwrap<MDNode>(v)->isFunctionLocal();+}++void LLVM_General_NamedMetadataAddOperands(+ NamedMDNode *n,+ LLVMValueRef *ops,+ unsigned nOps+) {+ for(unsigned i = 0; i != nOps; ++i) n->addOperand(unwrap<MDNode>(ops[i]));+}++const char *LLVM_General_GetNamedMetadataName(+ NamedMDNode *n,+ unsigned *len+) {+ StringRef s = n->getName();+ *len = s.size();+ return s.data();+}++unsigned LLVM_General_GetNamedMetadataNumOperands(NamedMDNode *n) {+ return n->getNumOperands();+}++void LLVM_General_GetNamedMetadataOperands(NamedMDNode *n, LLVMValueRef *dest) {+ for(unsigned i = 0; i != n->getNumOperands(); ++i)+ dest[i] = wrap(n->getOperand(i));+}++LLVMValueRef LLVM_General_CreateTemporaryMDNodeInContext(LLVMContextRef c) {+ return wrap(MDNode::getTemporary(*unwrap(c), ArrayRef<Value *>()));+}++void LLVM_General_DestroyTemporaryMDNode(LLVMValueRef v) {+ MDNode::deleteTemporary(unwrap<MDNode>(v));+}++}+
+ src/LLVM/General/Internal/FFI/Module.hs view
@@ -0,0 +1,86 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls+ #-}++module LLVM.General.Internal.FFI.Module where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.Context+import LLVM.General.Internal.FFI.Type++data Module++foreign import ccall unsafe "LLVMModuleCreateWithNameInContext" moduleCreateWithNameInContext ::+ CString -> Ptr Context -> IO (Ptr Module)++foreign import ccall unsafe "LLVMGetModuleContext" getModuleContext ::+ Ptr Module -> IO (Ptr Context)++foreign import ccall unsafe "LLVMDisposeModule" disposeModule ::+ Ptr Module -> IO ()++foreign import ccall unsafe "LLVMGetDataLayout" getDataLayout ::+ Ptr Module -> IO CString++foreign import ccall unsafe "LLVMSetDataLayout" setDataLayout ::+ Ptr Module -> CString -> IO ()++foreign import ccall unsafe "LLVMGetTarget" getTargetTriple ::+ Ptr Module -> IO CString++foreign import ccall unsafe "LLVMSetTarget" setTargetTriple ::+ Ptr Module -> CString -> IO ()++foreign import ccall unsafe "LLVM_General_GetModuleIdentifier" getModuleIdentifier ::+ Ptr Module -> IO CString++foreign import ccall unsafe "LLVMGetFirstGlobal" getFirstGlobal ::+ Ptr Module -> IO (Ptr GlobalVariable)++foreign import ccall unsafe "LLVMGetNextGlobal" getNextGlobal ::+ Ptr GlobalVariable -> IO (Ptr GlobalVariable)++foreign import ccall unsafe "LLVM_General_GetFirstAlias" getFirstAlias ::+ Ptr Module -> IO (Ptr GlobalAlias)++foreign import ccall unsafe "LLVM_General_GetNextAlias" getNextAlias ::+ Ptr GlobalAlias -> IO (Ptr GlobalAlias)++foreign import ccall unsafe "LLVMGetFirstFunction" getFirstFunction ::+ Ptr Module -> IO (Ptr Function)++foreign import ccall unsafe "LLVMGetNextFunction" getNextFunction ::+ Ptr Function -> IO (Ptr Function)++foreign import ccall unsafe "LLVM_General_GetFirstNamedMetadata" getFirstNamedMetadata ::+ Ptr Module -> IO (Ptr NamedMetadata)++foreign import ccall unsafe "LLVM_General_GetNextNamedMetadata" getNextNamedMetadata ::+ Ptr NamedMetadata -> IO (Ptr NamedMetadata)++foreign import ccall unsafe "LLVMAddGlobalInAddressSpace" addGlobalInAddressSpace ::+ Ptr Module -> Ptr Type -> CString -> CUInt -> IO (Ptr GlobalVariable)++foreign import ccall unsafe "LLVM_General_JustAddAlias" justAddAlias ::+ Ptr Module -> Ptr Type -> CString -> IO (Ptr GlobalAlias)+++foreign import ccall unsafe "LLVMAddFunction" addFunction ::+ Ptr Module -> CString -> Ptr Type -> IO (Ptr Function)++foreign import ccall unsafe "LLVM_General_GetOrAddNamedMetadata" getOrAddNamedMetadata ::+ Ptr Module -> CString -> IO (Ptr NamedMetadata)++foreign import ccall unsafe "LLVM_General_ModuleAppendInlineAsm" moduleAppendInlineAsm' ::+ Ptr Module -> Ptr CChar -> CUInt -> IO ()++newtype ModuleAsm a = ModuleAsm a++moduleAppendInlineAsm m (ModuleAsm (c, n)) = moduleAppendInlineAsm' m c n++foreign import ccall unsafe "LLVM_General_ModuleGetInlineAsm" moduleGetInlineAsm ::+ Ptr Module -> IO (ModuleAsm CString)
+ src/LLVM/General/Internal/FFI/ModuleC.cpp view
@@ -0,0 +1,58 @@+#define __STDC_LIMIT_MACROS+#include "llvm/LLVMContext.h"+#include "llvm/Module.h"++#include "llvm-c/Core.h"+#include <iostream>++using namespace llvm;++extern "C" {++char *LLVM_General_GetModuleIdentifier(LLVMModuleRef val) {+ return strdup(unwrap(val)->getModuleIdentifier().c_str());+}++LLVMValueRef LLVM_General_GetFirstAlias(LLVMModuleRef m) {+ Module *mod = unwrap(m);+ Module::alias_iterator i = mod->alias_begin();+ return i == mod->alias_end() ? 0 : wrap(i);+}++LLVMValueRef LLVM_General_GetNextAlias(LLVMValueRef a) {+ GlobalAlias *alias = unwrap<GlobalAlias>(a);+ Module::alias_iterator i = alias;+ if (++i == alias->getParent()->alias_end()) return 0;+ return wrap(i);+}++LLVMValueRef LLVM_General_JustAddAlias(LLVMModuleRef m, LLVMTypeRef ty, const char *name) {+ return wrap(new GlobalAlias(unwrap(ty), GlobalValue::ExternalLinkage, name, 0, unwrap(m)));+}++NamedMDNode *LLVM_General_GetOrAddNamedMetadata(LLVMModuleRef m, const char *name) {+ return unwrap(m)->getOrInsertNamedMetadata(name);+}++NamedMDNode *LLVM_General_GetFirstNamedMetadata(LLVMModuleRef m) {+ Module *mod = unwrap(m);+ Module::named_metadata_iterator i = mod->named_metadata_begin();+ return i == mod->named_metadata_end() ? 0 : i;+}++NamedMDNode *LLVM_General_GetNextNamedMetadata(NamedMDNode *a) {+ Module::named_metadata_iterator i = a;+ if (++i == a->getParent()->named_metadata_end()) return 0;+ return i;+}++void LLVM_General_ModuleAppendInlineAsm(LLVMModuleRef m, const char *s, unsigned l) {+ unwrap(m)->appendModuleInlineAsm(StringRef(s,l));+}++const char *LLVM_General_ModuleGetInlineAsm(LLVMModuleRef m) {+ return unwrap(m)->getModuleInlineAsm().c_str();+}++}+
+ src/LLVM/General/Internal/FFI/PassManager.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE+ TemplateHaskell,+ ForeignFunctionInterface,+ EmptyDataDecls+ #-}++module LLVM.General.Internal.FFI.PassManager where++import Language.Haskell.TH++import Control.Monad++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.LLVMCTypes+import LLVM.General.Internal.FFI.PtrHierarchy+import LLVM.General.Internal.FFI.Cleanup+import LLVM.General.Internal.FFI.Module+import LLVM.General.Internal.FFI.Target+import LLVM.General.Internal.FFI.Transforms++import qualified LLVM.General.Transforms as G++data PassManager++foreign import ccall unsafe "LLVMCreatePassManager" createPassManager ::+ IO (Ptr PassManager)++foreign import ccall unsafe "LLVMDisposePassManager" disposePassManager ::+ Ptr PassManager -> IO ()++foreign import ccall unsafe "LLVMRunPassManager" runPassManager ::+ Ptr PassManager -> Ptr Module -> IO CUInt++foreign import ccall unsafe "LLVMCreateFunctionPassManagerForModule" createFunctionPassManagerForModule ::+ Ptr Module -> IO (Ptr PassManager)++foreign import ccall unsafe "LLVMInitializeFunctionPassManager" initializeFunctionPassManager ::+ Ptr PassManager -> IO CUInt++foreign import ccall unsafe "LLVMRunFunctionPassManager" runFunctionPassManager ::+ Ptr PassManager -> Ptr Value -> IO CUInt++foreign import ccall unsafe "LLVMFinalizeFunctionPassManager" finalizeFunctionPassManager ::+ Ptr PassManager -> IO CUInt++$(do+ let declareForeign :: Name -> [Type] -> DecsQ+ declareForeign hName extraParams = do+ let n = nameBase hName+ foreignDecl + (cName n)+ ("add" ++ n ++ "Pass")+ ([[t| Ptr PassManager |]] + ++ [[t| Ptr TargetLowering |] | needsTargetLowering n]+ ++ map typeMapping extraParams)+ (tupleT 0)++ TyConI (DataD _ _ _ cons _) <- reify ''G.Pass+ liftM concat $ forM cons $ \con -> case con of+ RecC n l -> declareForeign n [ t | (_,_,t) <- l ]+ NormalC n [] -> declareForeign n []+ NormalC n _ -> error "pass descriptor constructors with fields need to be records"+ )++data PassManagerBuilder++foreign import ccall unsafe "LLVMPassManagerBuilderCreate" passManagerBuilderCreate ::+ IO (Ptr PassManagerBuilder) ++foreign import ccall unsafe "LLVMPassManagerBuilderDispose" passManagerBuilderDispose ::+ Ptr PassManagerBuilder -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderSetOptLevel" passManagerBuilderSetOptLevel ::+ Ptr PassManagerBuilder -> CUInt -> IO () ++foreign import ccall unsafe "LLVMPassManagerBuilderSetSizeLevel" passManagerBuilderSetSizeLevel ::+ Ptr PassManagerBuilder -> CUInt -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderSetDisableUnitAtATime" passManagerBuilderSetDisableUnitAtATime ::+ Ptr PassManagerBuilder -> CUInt -> IO () ++foreign import ccall unsafe "LLVMPassManagerBuilderSetDisableUnrollLoops" passManagerBuilderSetDisableUnrollLoops ::+ Ptr PassManagerBuilder -> CUInt -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderSetDisableSimplifyLibCalls" passManagerBuilderSetDisableSimplifyLibCalls ::+ Ptr PassManagerBuilder -> CUInt -> IO () ++foreign import ccall unsafe "LLVMPassManagerBuilderUseInlinerWithThreshold" passManagerBuilderUseInlinerWithThreshold ::+ Ptr PassManagerBuilder -> CUInt -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderPopulateFunctionPassManager" passManagerBuilderPopulateFunctionPassManager ::+ Ptr PassManagerBuilder -> Ptr PassManager -> IO () ++foreign import ccall unsafe "LLVMPassManagerBuilderPopulateModulePassManager" passManagerBuilderPopulateModulePassManager ::+ Ptr PassManagerBuilder -> Ptr PassManager -> IO ()++foreign import ccall unsafe "LLVMPassManagerBuilderPopulateLTOPassManager" passManagerBuilderPopulateLTOPassManager ::+ Ptr PassManagerBuilder -> Ptr PassManager -> CUChar -> CUChar -> IO ()
+ src/LLVM/General/Internal/FFI/PassManagerC.cpp view
@@ -0,0 +1,130 @@+#define __STDC_LIMIT_MACROS+#include "llvm/LLVMContext.h"+#include "llvm/Transforms/Scalar.h"+#include "llvm/Transforms/IPO.h"+#include "llvm/Transforms/Vectorize.h"+#include "llvm/PassManager.h"++#include "llvm-c/Core.h"++using namespace llvm;++extern "C" {+typedef struct LLVMOpaqueVectorizationConfig *LLVMVectorizationConfigRef;+typedef struct LLVMOpaqueTargetLowering *LLVMTargetLoweringRef;+}++namespace llvm {+inline TargetLowering *unwrap(LLVMTargetLoweringRef P) { + return reinterpret_cast<TargetLowering *>(P);+}++inline LLVMTargetLoweringRef wrap(const TargetLowering *P) { + return reinterpret_cast<LLVMTargetLoweringRef>(const_cast<TargetLowering *>(P));+}+}++extern "C" {++#define LLVM_GENERAL_FOR_EACH_PASS_WITHOUT_LLVM_C_BINDING(macro) \+ macro(BlockPlacement) \+ macro(BreakCriticalEdges) \+ macro(DeadCodeElimination) \+ macro(DeadInstElimination) \+ macro(DemoteRegisterToMemory) \+ macro(LCSSA) \+ macro(LoopInstSimplify) \+ macro(LowerAtomic) \+ macro(LowerSwitch) \+ macro(MergeFunctions) \+ macro(PartialInlining) \+ macro(Sinking) \+ macro(StripDeadDebugInfo) \+ macro(StripDebugDeclare) \+ macro(StripNonDebugSymbols) \++#define ENUM_CASE(p) \+void LLVM_General_Add ## p ## Pass(LLVMPassManagerRef PM) { \+ unwrap(PM)->add(create ## p ## Pass()); \+}+LLVM_GENERAL_FOR_EACH_PASS_WITHOUT_LLVM_C_BINDING(ENUM_CASE)+#undef ENUM_CASE++void LLVM_General_AddCodeGenPreparePass(LLVMPassManagerRef PM, LLVMTargetLoweringRef T) {+ unwrap(PM)->add(createCodeGenPreparePass(unwrap(T)));+}+ +void LLVM_General_AddGlobalValueNumberingPass(LLVMPassManagerRef PM, LLVMBool noLoads) {+ unwrap(PM)->add(createGVNPass(noLoads));+}++void LLVM_General_AddInternalizePass(LLVMPassManagerRef PM, unsigned nExports, const char **exports) {+ std::vector<const char *> exportList(exports, exports + nExports);+ unwrap(PM)->add(createInternalizePass(exportList));+}++void LLVM_General_AddLoopStrengthReducePass(LLVMPassManagerRef PM, LLVMTargetLoweringRef T) {+ unwrap(PM)->add(createLoopStrengthReducePass(unwrap(T)));+}++void LLVM_General_AddLowerInvokePass(LLVMPassManagerRef PM, LLVMTargetLoweringRef T, LLVMBool expensiveEH) {+ unwrap(PM)->add(createLowerInvokePass(unwrap(T), expensiveEH));+}+ +void LLVM_General_AddSROAPass(LLVMPassManagerRef PM, LLVMBool RequiresDomTree) {+ unwrap(PM)->add(createSROAPass(RequiresDomTree));+}++void LLVM_General_AddBasicBlockVectorizePass(+ LLVMPassManagerRef PM,+ unsigned vectorBits,+ LLVMBool vectorizeBools,+ LLVMBool vectorizeInts,+ LLVMBool vectorizeFloats,+ LLVMBool vectorizePointers,+ LLVMBool vectorizeCasts,+ LLVMBool vectorizeMath,+ LLVMBool vectorizeFusedMultiplyAdd,+ LLVMBool vectorizeSelect,+ LLVMBool vectorizeCmp,+ LLVMBool vectorizeGetElementPtr,+ LLVMBool vectorizeMemoryOperations,+ LLVMBool alignedOnly,+ unsigned reqChainDepth,+ unsigned searchLimit,+ unsigned maxCandidatePairsForCycleCheck,+ LLVMBool splatBreaksChain,+ unsigned maxInstructions,+ unsigned maxIterations,+ LLVMBool powerOfTwoLengthsOnly,+ LLVMBool noMemoryOperationBoost,+ LLVMBool fastDependencyAnalysis+) {+ VectorizeConfig vectorizeConfig;+ vectorizeConfig.VectorBits = vectorBits;+ vectorizeConfig.VectorizeBools = vectorizeBools;+ vectorizeConfig.VectorizeInts = vectorizeInts;+ vectorizeConfig.VectorizeFloats = vectorizeFloats;+ vectorizeConfig.VectorizePointers = vectorizePointers;+ vectorizeConfig.VectorizeCasts = vectorizeCasts;+ vectorizeConfig.VectorizeMath = vectorizeMath;+ vectorizeConfig.VectorizeFMA = vectorizeFusedMultiplyAdd;+ vectorizeConfig.VectorizeSelect = vectorizeSelect;+ vectorizeConfig.VectorizeCmp = vectorizeCmp;+ vectorizeConfig.VectorizeGEP = vectorizeGetElementPtr;+ vectorizeConfig.VectorizeMemOps = vectorizeMemoryOperations;+ vectorizeConfig.AlignedOnly = alignedOnly;+ vectorizeConfig.ReqChainDepth = reqChainDepth;+ vectorizeConfig.SearchLimit = searchLimit;+ vectorizeConfig.MaxCandPairsForCycleCheck = maxCandidatePairsForCycleCheck;+ vectorizeConfig.SplatBreaksChain = splatBreaksChain;+ vectorizeConfig.MaxInsts = maxInstructions;+ vectorizeConfig.MaxIter = maxIterations;+ vectorizeConfig.Pow2LenOnly = powerOfTwoLengthsOnly;+ vectorizeConfig.NoMemOpBoost = noMemoryOperationBoost;+ vectorizeConfig.FastDep = fastDependencyAnalysis; ++ unwrap(PM)->add(createBBVectorizePass(vectorizeConfig));+} ++}
+ src/LLVM/General/Internal/FFI/PtrHierarchy.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ MultiParamTypeClasses,+ EmptyDataDecls,+ FunctionalDependencies,+ FlexibleInstances,+ UndecidableInstances,+ OverlappingInstances+ #-}++-- | This module defines typeclasses to represent the relationships of an object-oriented inheritance hierarchy+module LLVM.General.Internal.FFI.PtrHierarchy where++import Foreign.Ptr++-- | a class to represent safe casting of pointers to objects of descendant-classes to ancestor-classes.+class DescendentOf a b where+ upCast :: Ptr b -> Ptr a+ upCast = castPtr++-- | trivial casts+instance DescendentOf a a where+ upCast = id++-- | a class to represent direct parent-child relationships+class ChildOf b c | c -> b++-- | ancestor-descentant relationships are build out of parent-child relationships+instance (DescendentOf a b, ChildOf b c) => DescendentOf a c++-- | <http://llvm.org/doxygen/classllvm_1_1Value.html>+data Value++-- | <http://llvm.org/doxygen/classllvm_1_1Constant.html>+data Constant++instance ChildOf User Constant++-- | <http://llvm.org/doxygen/classllvm_1_1GlobalValue.html>+data GlobalValue++instance ChildOf Constant GlobalValue++-- | <http://llvm.org/doxygen/classllvm_1_1GlobalVariable.html>+data GlobalVariable++instance ChildOf GlobalValue GlobalVariable++-- | <http://llvm.org/doxygen/classllvm_1_1GlobalAlias.html>+data GlobalAlias++instance ChildOf GlobalValue GlobalAlias++-- | <http://llvm.org/doxygen/classllvm_1_1Function.html>+data Function++instance ChildOf GlobalValue Function++-- | <http://llvm.org/doxygen/classllvm_1_1BasicBlock.html>+data BasicBlock++instance ChildOf Value BasicBlock++-- | <http://llvm.org/doxygen/classllvm_1_1Argument.html>+data Parameter++instance ChildOf Value Parameter++-- | <http://llvm.org/doxygen/classllvm_1_1Instruction.html>+data Instruction++instance ChildOf User Instruction++-- | <http://llvm.org/doxygen/classllvm_1_1User.html>+data User++instance ChildOf Value User++-- | <http://llvm.org/doxygen/classllvm_1_1MDNode.html>+data MDNode++instance ChildOf Value MDNode++-- | <http://llvm.org/doxygen/classllvm_1_1MDString.html>+data MDString++instance ChildOf Value MDString++-- | <http://llvm.org/doxygen/classllvm_1_1NamedMDNode.html>+data NamedMetadata++-- | <http://llvm.org/doxygen/classllvm_1_1InlineAsm.html>+data InlineAsm++instance ChildOf Value InlineAsm
+ src/LLVM/General/Internal/FFI/SMDiagnostic.h view
@@ -0,0 +1,15 @@+#ifndef __LLVM_GENERAL_INTERNAL_FFI__SMDIAGNOSTIC__+#define __LLVM_GENERAL_INTERNAL_FFI__SMDIAGNOSTIC__++#define LLVM_GENERAL_FOR_EACH_DIAGNOSTIC_KIND(macro) \+ macro(Error) \+ macro(Warning) \+ macro(Note)++typedef enum {+#define ENUM_CASE(k) LLVMDiagnosticKind ## k,+LLVM_GENERAL_FOR_EACH_DIAGNOSTIC_KIND(ENUM_CASE)+#undef ENUM_CASE+} LLVMDiagnosticKind;++#endif
+ src/LLVM/General/Internal/FFI/SMDiagnostic.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls+ #-}++-- | FFI functions for handling the LLVM SMDiagnostic class+module LLVM.General.Internal.FFI.SMDiagnostic where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.LLVMCTypes++data SMDiagnostic++-- | allocate an SMDiagnostic object+foreign import ccall unsafe "LLVM_General_CreateSMDiagnostic" createSMDiagnostic ::+ IO (Ptr SMDiagnostic)++foreign import ccall unsafe "LLVM_General_DisposeSMDiagnostic" disposeSMDiagnostic ::+ Ptr SMDiagnostic -> IO ()++foreign import ccall unsafe "LLVM_General_GetSMDiagnosticKind" getSMDiagnosticKind ::+ Ptr SMDiagnostic -> IO DiagnosticKind++foreign import ccall unsafe "LLVM_General_GetSMDiagnosticLineNo" getSMDiagnosticLineNo ::+ Ptr SMDiagnostic -> IO CInt ++foreign import ccall unsafe "LLVM_General_GetSMDiagnosticColumnNo" getSMDiagnosticColumnNo ::+ Ptr SMDiagnostic -> IO CInt ++foreign import ccall unsafe "LLVM_General_GetSMDiagnosticFilename" getSMDiagnosticFilename ::+ Ptr SMDiagnostic -> IO CString ++foreign import ccall unsafe "LLVM_General_GetSMDiagnosticMessage" getSMDiagnosticMessage ::+ Ptr SMDiagnostic -> IO CString ++foreign import ccall unsafe "LLVM_General_GetSMDiagnosticLineContents" getSMDiagnosticLineContents ::+ Ptr SMDiagnostic -> IO CString +
+ src/LLVM/General/Internal/FFI/SMDiagnosticC.cpp view
@@ -0,0 +1,31 @@+#define __STDC_LIMIT_MACROS+#include "llvm/LLVMContext.h"++#include "llvm/Support/SourceMgr.h"+#include "llvm-c/Core.h"++#include "LLVM/General/Internal/FFI/SMDiagnostic.h"++using namespace llvm;++extern "C" {++SMDiagnostic *LLVM_General_CreateSMDiagnostic() { return new SMDiagnostic(); }+void LLVM_General_DisposeSMDiagnostic(SMDiagnostic *p) { delete p; }++LLVMDiagnosticKind LLVM_General_GetSMDiagnosticKind(SMDiagnostic *p) {+ switch(p->getKind()) {+#define ENUM_CASE(k) case SourceMgr::DK_ ## k: return LLVMDiagnosticKind ## k;+ LLVM_GENERAL_FOR_EACH_DIAGNOSTIC_KIND(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVMDiagnosticKind(0);+ }+}++int LLVM_General_GetSMDiagnosticLineNo(SMDiagnostic *p) { return p->getLineNo(); }+int LLVM_General_GetSMDiagnosticColumnNo(SMDiagnostic *p) { return p->getColumnNo(); }+const char *LLVM_General_GetSMDiagnosticFilename(SMDiagnostic *p) { return p->getFilename().c_str(); }+const char *LLVM_General_GetSMDiagnosticMessage(SMDiagnostic *p) { return p->getMessage().c_str(); }+const char *LLVM_General_GetSMDiagnosticLineContents(SMDiagnostic *p) { return p->getLineContents().c_str(); }++}
+ src/LLVM/General/Internal/FFI/Target.h view
@@ -0,0 +1,74 @@+#ifndef __LLVM_GENERAL_INTERNAL_FFI__TARGET__H__+#define __LLVM_GENERAL_INTERNAL_FFI__TARGET__H__++#define LLVM_GENERAL_FOR_EACH_RELOC_MODEL(macro) \+ macro(Default, Default) \+ macro(Static, Static) \+ macro(PIC, PIC_) \+ macro(DynamicNoPic, DynamicNoPIC)++#define LLVM_GENERAL_FOR_EACH_CODE_MODEL(macro) \+ macro(Default) \+ macro(JITDefault) \+ macro(Small) \+ macro(Kernel) \+ macro(Medium) \+ macro(Large)++#define LLVM_GENERAL_FOR_EACH_CODE_GEN_OPT_LEVEL(macro) \+ macro(None) \+ macro(Less) \+ macro(Default) \+ macro(Aggressive)++#define LLVM_GENERAL_FOR_EACH_TARGET_OPTION_FLAG(macro) \+ macro(PrintMachineCode) \+ macro(NoFramePointerElim) \+ macro(NoFramePointerElimNonLeaf) \+ macro(LessPreciseFPMADOption) \+ macro(UnsafeFPMath) \+ macro(NoInfsFPMath) \+ macro(NoNaNsFPMath) \+ macro(HonorSignDependentRoundingFPMathOption) \+ macro(UseSoftFloat) \+ macro(NoZerosInBSS) \+ macro(JITExceptionHandling) \+ macro(JITEmitDebugInfo) \+ macro(JITEmitDebugInfoToDisk) \+ macro(GuaranteedTailCallOpt) \+ macro(DisableTailCalls) \+ macro(RealignStack) \+ macro(EnableFastISel) \+ macro(PositionIndependentExecutable) \+ macro(EnableSegmentedStacks) \+ macro(UseInitArray)++typedef enum {+#define ENUM_CASE(n) LLVM_General_TargetOptionFlag_ ## n,+ LLVM_GENERAL_FOR_EACH_TARGET_OPTION_FLAG(ENUM_CASE)+#undef ENUM_CASE+} LLVM_General_TargetOptionFlag;++#define LLVM_GENERAL_FOR_EACH_FLOAT_ABI(macro) \+ macro(Default) \+ macro(Soft) \+ macro(Hard) ++typedef enum {+#define ENUM_CASE(n) LLVM_General_FloatABI_ ## n,+ LLVM_GENERAL_FOR_EACH_FLOAT_ABI(ENUM_CASE)+#undef ENUM_CASE+} LLVM_General_FloatABI;++#define LLVM_GENERAL_FOR_EACH_FP_OP_FUSION_MODE(macro) \+ macro(Fast) \+ macro(Standard) \+ macro(Strict)++typedef enum {+#define ENUM_CASE(n) LLVM_General_FPOpFusionMode_ ## n,+ LLVM_GENERAL_FOR_EACH_FP_OP_FUSION_MODE(ENUM_CASE)+#undef ENUM_CASE+} LLVM_General_FPOpFusionMode;++#endif
+ src/LLVM/General/Internal/FFI/Target.hs view
@@ -0,0 +1,85 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ GeneralizedNewtypeDeriving,+ EmptyDataDecls+ #-}++module LLVM.General.Internal.FFI.Target where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.LLVMCTypes++data Target++foreign import ccall unsafe "LLVM_General_InitializeNativeTarget" initializeNativeTarget ::+ IO LLVMBool++foreign import ccall unsafe "LLVM_General_LookupTarget" lookupTarget ::+ CString -> CString -> Ptr CString -> Ptr CString -> IO (Ptr Target)++data TargetOptions++foreign import ccall unsafe "LLVM_General_CreateTargetOptions" createTargetOptions ::+ IO (Ptr TargetOptions)++foreign import ccall unsafe "LLVM_General_SetTargetOptionFlag" setTargetOptionFlag ::+ Ptr TargetOptions -> TargetOptionFlag -> LLVMBool -> IO ()++foreign import ccall unsafe "LLVM_General_GetTargetOptionFlag" getTargetOptionsFlag ::+ Ptr TargetOptions -> TargetOptionFlag -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_SetStackAlignmentOverride" setStackAlignmentOverride ::+ Ptr TargetOptions -> CUInt -> IO ()++foreign import ccall unsafe "LLVM_General_GetStackAlignmentOverride" getStackAlignmentOverride ::+ Ptr TargetOptions -> IO CUInt++foreign import ccall unsafe "LLVM_General_SetTrapFuncName" setTrapFuncName ::+ Ptr TargetOptions -> CString -> IO ()++foreign import ccall unsafe "LLVM_General_GetTrapFuncName" getTrapFuncName ::+ Ptr TargetOptions -> IO CString++foreign import ccall unsafe "LLVM_General_SetFloatABIType" setFloatABIType ::+ Ptr TargetOptions -> FloatABIType -> IO ()++foreign import ccall unsafe "LLVM_General_GetFloatABIType" getFloatABIType ::+ Ptr TargetOptions -> IO FloatABIType++foreign import ccall unsafe "LLVM_General_SetAllowFPOpFusion" setAllowFPOpFusion ::+ Ptr TargetOptions -> FPOpFusionMode -> IO ()++foreign import ccall unsafe "LLVM_General_GetAllowFPOpFusion" getAllowFPOpFusion ::+ Ptr TargetOptions -> IO FPOpFusionMode++foreign import ccall unsafe "LLVM_General_SetSSPBufferSize" setSSPBufferSize ::+ Ptr TargetOptions -> CUInt -> IO ()++foreign import ccall unsafe "LLVM_General_GetSSPBufferSize" getSSPBufferSize ::+ Ptr TargetOptions -> IO CUInt++foreign import ccall unsafe "LLVM_General_DisposeTargetOptions" disposeTargetOptions ::+ Ptr TargetOptions -> IO ()++data TargetMachine++foreign import ccall unsafe "LLVM_General_CreateTargetMachine" createTargetMachine ::+ Ptr Target+ -> CString + -> CString+ -> CString+ -> Ptr TargetOptions+ -> RelocModel+ -> CodeModel+ -> CodeGenOptLevel+ -> IO (Ptr TargetMachine)++foreign import ccall unsafe "LLVMDisposeTargetMachine" disposeTargetMachine ::+ Ptr TargetMachine -> IO ()++data TargetLowering++foreign import ccall unsafe "LLVM_General_GetTargetLowering" getTargetLowering ::+ Ptr TargetMachine -> IO (Ptr TargetLowering)
+ src/LLVM/General/Internal/FFI/TargetC.cpp view
@@ -0,0 +1,201 @@+#define __STDC_LIMIT_MACROS+#include "llvm/Support/TargetRegistry.h"+#include "llvm/Target/TargetMachine.h"+#include "llvm/ADT/Triple.h"+#include "llvm-c/Target.h"+#include "llvm-c/TargetMachine.h"+#include "llvm-c/Core.h"+#include "LLVM/General/Internal/FFI/Target.h"++using namespace llvm;++namespace llvm {+static Reloc::Model unwrap(LLVMRelocMode x) {+ switch(x) {+#define ENUM_CASE(x,y) case LLVMReloc ## x: return Reloc::y;+LLVM_GENERAL_FOR_EACH_RELOC_MODEL(ENUM_CASE)+#undef ENUM_CASE+ default: return Reloc::Model(0);+ }+}++static CodeModel::Model unwrap(LLVMCodeModel x) {+ switch(x) {+#define ENUM_CASE(x) case LLVMCodeModel ## x: return CodeModel::x;+LLVM_GENERAL_FOR_EACH_CODE_MODEL(ENUM_CASE)+#undef ENUM_CASE+ default: return CodeModel::Model(0);+ }+}++static CodeGenOpt::Level unwrap(LLVMCodeGenOptLevel x) {+ switch(x) {+#define ENUM_CASE(x) case LLVMCodeGenLevel ## x: return CodeGenOpt::x;+LLVM_GENERAL_FOR_EACH_CODE_GEN_OPT_LEVEL(ENUM_CASE)+#undef ENUM_CASE+ default: return CodeGenOpt::Level(0);+ }+}++static FloatABI::ABIType unwrap(LLVM_General_FloatABI x) {+ switch(x) {+#define ENUM_CASE(x) case LLVM_General_FloatABI_ ## x: return FloatABI::x;+LLVM_GENERAL_FOR_EACH_FLOAT_ABI(ENUM_CASE)+#undef ENUM_CASE+ default: return FloatABI::ABIType(0);+ }+}++static LLVM_General_FloatABI wrap(FloatABI::ABIType x) {+ switch(x) {+#define ENUM_CASE(x) case FloatABI::x: return LLVM_General_FloatABI_ ## x;+LLVM_GENERAL_FOR_EACH_FLOAT_ABI(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVM_General_FloatABI(0);+ }+}++static FPOpFusion::FPOpFusionMode unwrap(LLVM_General_FPOpFusionMode x) {+ switch(x) {+#define ENUM_CASE(x) case LLVM_General_FPOpFusionMode_ ## x: return FPOpFusion::x;+LLVM_GENERAL_FOR_EACH_FP_OP_FUSION_MODE(ENUM_CASE)+#undef ENUM_CASE+ default: return FPOpFusion::FPOpFusionMode(0);+ }+}++static LLVM_General_FPOpFusionMode wrap(FPOpFusion::FPOpFusionMode x) {+ switch(x) {+#define ENUM_CASE(x) case FPOpFusion::x: return LLVM_General_FPOpFusionMode_ ## x;+LLVM_GENERAL_FOR_EACH_FP_OP_FUSION_MODE(ENUM_CASE)+#undef ENUM_CASE+ default: return LLVM_General_FPOpFusionMode(0);+ }+}+}++extern "C" {++LLVMBool LLVM_General_InitializeNativeTarget() {+ return LLVMInitializeNativeTarget();+}++LLVMTargetRef LLVM_General_LookupTarget(+ const char *arch, + const char *ctriple, + const char **tripleOut, + const char **cerror+) {+ std::string error;+ Triple triple(ctriple);+ if (const Target *result = TargetRegistry::lookupTarget(arch, triple, error)) {+ *tripleOut = strdup(triple.getTriple().c_str());+ return wrap(result);+ }+ *cerror = strdup(error.c_str());+ return 0;+}++TargetOptions *LLVM_General_CreateTargetOptions() {+ TargetOptions *to = new TargetOptions();+ to->SSPBufferSize = 0; // this field was left uninitialized in LLVM 3.2+ return to;+}++void LLVM_General_SetTargetOptionFlag(+ TargetOptions *to,+ LLVM_General_TargetOptionFlag f,+ unsigned v+) {+ switch(f) {+#define ENUM_CASE(op) case LLVM_General_TargetOptionFlag_ ## op: to->op = v ? 1 : 0; break;+ LLVM_GENERAL_FOR_EACH_TARGET_OPTION_FLAG(ENUM_CASE)+#undef ENUM_CASE+ }+}++unsigned LLVM_General_GetTargetOptionFlag(+ TargetOptions *to,+ LLVM_General_TargetOptionFlag f+) {+ switch(f) {+#define ENUM_CASE(op) case LLVM_General_TargetOptionFlag_ ## op: return to->op;+ LLVM_GENERAL_FOR_EACH_TARGET_OPTION_FLAG(ENUM_CASE)+#undef ENUM_CASE+ }+}++void LLVM_General_SetStackAlignmentOverride(TargetOptions *to, unsigned v) {+ to->StackAlignmentOverride = v;+}++unsigned LLVM_General_GetStackAlignmentOverride(TargetOptions *to) {+ return to->StackAlignmentOverride;+}++void LLVM_General_SetTrapFuncName(TargetOptions *to, const char *v) {+ to->TrapFuncName = v;+}++const char *LLVM_General_GetTrapFuncName(TargetOptions *to) {+ return to->TrapFuncName.c_str();+}++void LLVM_General_SetFloatABIType(TargetOptions *to, LLVM_General_FloatABI v) {+ to->FloatABIType = unwrap(v);+}++LLVM_General_FloatABI LLVM_General_GetFloatABIType(TargetOptions *to) {+ return wrap(to->FloatABIType);+}++void LLVM_General_SetAllowFPOpFusion(TargetOptions *to, LLVM_General_FPOpFusionMode v) {+ to->AllowFPOpFusion = unwrap(v);+}++LLVM_General_FPOpFusionMode LLVM_General_GetAllowFPOpFusion(TargetOptions *to) {+ return wrap(to->AllowFPOpFusion);+}++void LLVM_General_SetSSPBufferSize(TargetOptions *to, unsigned v) {+ to->SSPBufferSize = v;+}++unsigned LLVM_General_GetSSPBufferSize(TargetOptions *to) {+ return to->SSPBufferSize;+}++void LLVM_General_DisposeTargetOptions(TargetOptions *t) {+ delete t;+}+++LLVMTargetMachineRef LLVM_General_CreateTargetMachine(+ LLVMTargetRef target,+ const char *triple,+ const char *cpu,+ const char *features,+ const TargetOptions *targetOptions,+ LLVMRelocMode relocModel,+ LLVMCodeModel codeModel,+ LLVMCodeGenOptLevel codeGenOptLevel+) {+ return wrap(+ unwrap(target)->createTargetMachine(+ triple,+ cpu,+ features,+ *targetOptions, + unwrap(relocModel),+ unwrap(codeModel),+ unwrap(codeGenOptLevel)+ )+ );+}+ +const TargetLowering *LLVM_General_GetTargetLowering(LLVMTargetMachineRef t) {+ return unwrap(t)->getTargetLowering();+}++}+
+ src/LLVM/General/Internal/FFI/Transforms.hs view
@@ -0,0 +1,62 @@+-- | Code used with Template Haskell to build the FFI for transform passes.+module LLVM.General.Internal.FFI.Transforms where++-- | does the constructor for this pass require a TargetLowering object+needsTargetLowering "CodeGenPrepare" = True+needsTargetLowering "LoopStrengthReduce" = True+needsTargetLowering "LowerInvoke" = True+needsTargetLowering _ = False++-- | Translate a Haskell name (used in the public Haskell interface, typically not abbreviated)+-- | for a pass into the (sometimes obscure, sometimes abbreviated) name used in the LLVM C interface.+-- | This translation includes, by choice of prefix, whether the C interface implementation is found in+-- | the LLVM distribution ("LLVM" prefix) or either not available or broken there and so implemented+-- | as part of this Haskell package ("LLVM_General_" prefix).+cName n = + let core = case n of+ "AggressiveDeadCodeElimination" -> "AggressiveDCE"+ "AlwaysInline" -> "AlwaysInliner"+ "DeadInstructionElimination" -> "DeadInstElimination"+ "EarlyCommonSubexpressionElimination" -> "EarlyCSE"+ "FunctionAttributes" -> "FunctionAttrs"+ "GlobalDeadCodeElimination" -> "GlobalDCE"+ "InductionVariableSimplify" -> "IndVarSimplify"+ "InternalizeFunctions" -> "Internalize"+ "InterproceduralConstantPropagation" -> "IPConstantPropagation"+ "InterproceduralSparseConditionalConstantPropagation" -> "IPSCCP"+ "LoopClosedSingleStaticAssignment" -> "LCSSA"+ "LoopInvariantCodeMotion" -> "LICM"+ "LoopInstructionSimplify" -> "LoopInstSimplify"+ "MemcpyOptimization" -> "MemCpyOpt"+ "PruneExceptionHandling" -> "PruneEH"+ "ScalarReplacementOfAggregates" -> "SROA"+ "OldScalarReplacementOfAggregates" -> "ScalarReplAggregates"+ "SimplifyControlFlowGraph" -> "CFGSimplification"+ "SparseConditionalConstantPropagation" -> "SCCP"+ h -> h+ patchImpls = [+ "CodeGenPrepare",+ "GlobalValueNumbering",+ "InternalizeFunctions",+ "BasicBlockVectorize",+ "BlockPlacement",+ "BreakCriticalEdges",+ "DeadCodeElimination",+ "DeadInstructionElimination",+ "DemoteRegisterToMemory",+ "LoopClosedSingleStaticAssignment",+ "LoopInstructionSimplify",+ "LoopStrengthReduce",+ "LowerAtomic",+ "LowerInvoke",+ "LowerSwitch",+ "MergeFunctions",+ "PartialInlining",+ "ScalarReplacementOfAggregates",+ "Sinking",+ "StripDeadDebugInfo",+ "StripDebugDeclare",+ "StripNonDebugSymbols"+ ]+ in+ (if (n `elem` patchImpls) then "LLVM_General_" else "LLVM") ++ "Add" ++ core ++ "Pass"
+ src/LLVM/General/Internal/FFI/Type.h view
@@ -0,0 +1,22 @@+#ifndef __LLVM_GENERAL_INTERNAL_FFI__TYPE__H__+#define __LLVM_GENERAL_INTERNAL_FFI__TYPE__H__++#define LLVM_GENERAL_FOR_EACH_TYPE_KIND(macro) \+ macro(Void) \+ macro(Half) \+ macro(Float) \+ macro(Double) \+ macro(X86_FP80) \+ macro(FP128) \+ macro(PPC_FP128) \+ macro(Label) \+ macro(Integer) \+ macro(Function) \+ macro(Struct) \+ macro(Array) \+ macro(Pointer) \+ macro(Vector) \+ macro(Metadata) \+ macro(X86_MMX) ++#endif
+ src/LLVM/General/Internal/FFI/Type.hs view
@@ -0,0 +1,143 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls+ #-}++-- | Functions for handling the LLVM types+module LLVM.General.Internal.FFI.Type where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.LLVMCTypes+import LLVM.General.Internal.FFI.Context++-- | a blind type to correspond to llvm::Type+data Type++-- | <http://llvm.org/doxygen/group__LLVMCCoreType.html#ga112756467f0988613faa6043d674d843>+foreign import ccall unsafe "LLVMGetTypeKind" getTypeKind ::+ Ptr Type -> IO TypeKind++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeInt.html#gadfb8ba2f605f0860a4bf2e3c480ab6a2>+foreign import ccall unsafe "LLVMGetIntTypeWidth" getIntTypeWidth ::+ Ptr Type -> IO (CUInt)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#ga2970f0f4d9ee8a0f811f762fb2fa7f82>+foreign import ccall unsafe "LLVMIsFunctionVarArg" isFunctionVarArg ::+ Ptr Type -> IO LLVMBool++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#gacfa4594cbff421733add602a413cae9f>+foreign import ccall unsafe "LLVMGetReturnType" getReturnType ::+ Ptr Type -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#ga44fa41d22ed1f589b8202272f54aad77>+foreign import ccall unsafe "LLVMCountParamTypes" countParamTypes ::+ Ptr Type -> IO CUInt++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#ga83dd3a49a0f3f017f4233fc0d667bda2>+foreign import ccall unsafe "LLVMGetParamTypes" getParamTypes ::+ Ptr Type -> Ptr (Ptr Type) -> IO ()++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga0b03e26a2d254530a9b5c279cdf52257>+foreign import ccall unsafe "LLVMGetElementType" getElementType ::+ Ptr Type -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeInt.html#ga2e5db8cbc30daa156083f2c42989138d>+foreign import ccall unsafe "LLVMIntTypeInContext" intTypeInContext ::+ Ptr Context -> CUInt -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFunction.html#ga8b0c32e7322e5c6c1bf7eb95b0961707>+foreign import ccall unsafe "LLVMFunctionType" functionType' ::+ Ptr Type -> Ptr (Ptr Type) -> CUInt -> LLVMBool -> IO (Ptr Type)++functionType rt (n, ats) va = functionType' rt ats n va++newtype AddrSpace = AddrSpace CUInt+-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga299fe6147083678d0494b1b875f542fae>+foreign import ccall unsafe "LLVMPointerType" pointerType ::+ Ptr Type -> AddrSpace -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga124b162b69b5def41dde2fda3668cbd9>+foreign import ccall unsafe "LLVMGetPointerAddressSpace" getPointerAddressSpace ::+ Ptr Type -> IO AddrSpace++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga5ec731adf74fb40bc3b401956d0c6ff2>+foreign import ccall unsafe "LLVMVectorType" vectorType ::+ Ptr Type -> CUInt -> IO (Ptr Type)++-- | what <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#gabd1666e080f693e1af0b4018005cd927>+-- | would be if it supported 64-bit array sizes, as the C++ type does.+foreign import ccall unsafe "LLVM_General_ArrayType" arrayType ::+ Ptr Type -> CULong -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeStruct.html#gaff2af74740a22f7d18701f0d8c3e5a6f>+foreign import ccall unsafe "LLVMStructTypeInContext" structTypeInContext' ::+ Ptr Context -> Ptr (Ptr Type) -> CUInt -> LLVMBool -> IO (Ptr Type)++structTypeInContext ctx (n, ts) p = structTypeInContext' ctx ts n p++foreign import ccall unsafe "LLVM_General_StructCreateNamed" structCreateNamed ::+ Ptr Context -> CString -> IO (Ptr Type)++foreign import ccall unsafe "LLVMGetStructName" getStructName ::+ Ptr Type -> IO CString++foreign import ccall unsafe "LLVM_General_StructIsLiteral" structIsLiteral ::+ Ptr Type -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_StructIsOpaque" structIsOpaque ::+ Ptr Type -> IO LLVMBool++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeStruct.html#ga3e940e660375ae0cbdde81c0d8ec91e3>+foreign import ccall unsafe "LLVMIsPackedStruct" isPackedStruct ::+ Ptr Type -> IO LLVMBool++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeStruct.html#gaf32e6d6bcec38b786efbef689b0dddf7>+foreign import ccall unsafe "LLVMCountStructElementTypes" countStructElementTypes ::+ Ptr Type -> IO CUInt++foreign import ccall unsafe "LLVMGetStructElementTypes" getStructElementTypes ::+ Ptr Type -> Ptr (Ptr Type) -> IO ()++foreign import ccall unsafe "LLVMStructSetBody" structSetBody' ::+ Ptr Type -> Ptr (Ptr Type) -> CUInt -> LLVMBool -> IO ()++structSetBody s (n,ts) p = structSetBody' s ts n p++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#gafb88a5ebd2a8062e105854910dc7ca17>+foreign import ccall unsafe "LLVMGetVectorSize" getVectorSize ::+ Ptr Type -> IO CUInt++-- | what <http://llvm.org/doxygen/group__LLVMCCoreTypeSequential.html#ga02dc08041a12265cb700ee469497df63>+-- | would be if it supported 64 bit lengths+foreign import ccall unsafe "LLVM_General_GetArrayLength" getArrayLength ::+ Ptr Type -> IO CULong++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeOther.html#ga1c78ca6d7bf279330b9195fa52f23828>+foreign import ccall unsafe "LLVMVoidTypeInContext" voidTypeInContext ::+ Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga3a5332a1d075602bccad7576d1a8e36f>+foreign import ccall unsafe "LLVMHalfTypeInContext" halfTypeInContext ::+ Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga529c83a8a5461e5beac19eb867216e3c>+foreign import ccall unsafe "LLVMFloatTypeInContext" floatTypeInContext ::+ Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga200527010747eab31b73d3e3f6d94935>+foreign import ccall unsafe "LLVMDoubleTypeInContext" doubleTypeInContext ::+ Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga24f77b84b625ed3dd516b52480606093>+foreign import ccall unsafe "LLVMX86FP80TypeInContext" x86FP80TypeInContext ::+ Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#ga1c02fb08f9ae12a719ed42099d42ccd8>+foreign import ccall unsafe "LLVMFP128TypeInContext" fP128TypeInContext ::+ Ptr Context -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#gac2491184fc3d8631c7b264c067f2f761>+foreign import ccall unsafe "LLVMPPCFP128TypeInContext" ppcFP128TypeInContext ::+ Ptr Context -> IO (Ptr Type)
+ src/LLVM/General/Internal/FFI/TypeC.cpp view
@@ -0,0 +1,34 @@+#define __STDC_LIMIT_MACROS+#include "llvm-c/Core.h"+#include "llvm/Type.h"++using namespace llvm;++extern "C" {++LLVMTypeRef LLVM_General_StructCreateNamed(LLVMContextRef C, const char *Name) {+ if (Name) {+ return wrap(StructType::create(*unwrap(C), Name));+ } else {+ return wrap(StructType::create(*unwrap(C)));+ }+}++LLVMBool LLVM_General_StructIsLiteral(LLVMTypeRef t) {+ return unwrap<StructType>(t)->isLiteral();+}++LLVMBool LLVM_General_StructIsOpaque(LLVMTypeRef t) {+ return unwrap<StructType>(t)->isOpaque();+}++LLVMTypeRef LLVM_General_ArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {+ return wrap(ArrayType::get(unwrap(ElementType), ElementCount));+}++uint64_t LLVM_General_GetArrayLength(LLVMTypeRef ArrayTy) {+ return unwrap<ArrayType>(ArrayTy)->getNumElements();+}+++}
+ src/LLVM/General/Internal/FFI/User.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses,+ FlexibleInstances,+ UndecidableInstances,+ OverlappingInstances+ #-}++-- | FFI functions for handling the LLVM User class+module LLVM.General.Internal.FFI.User where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.PtrHierarchy++-- | a blind type to correspond to llvm::Use+data Use++-- | test if a 'Value' is a 'User'+foreign import ccall unsafe "LLVMIsAUser" isAUser ::+ Ptr Value -> IO (Ptr User)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueUses.html#ga66a226d3d06ffada5c929656f4d97d35>+foreign import ccall unsafe "LLVMGetFirstUse" getFirstUse ::+ Ptr User -> IO (Ptr Use)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueUses.html#ga6ea72661bcca2b77bea57173317ec942>+foreign import ccall unsafe "LLVMGetNextUse" getNextUse ::+ Ptr Use -> IO (Ptr Use)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueUser.html#ga2ad633a6afc7906f1afe329f244240f6>+foreign import ccall unsafe "LLVMGetNumOperands" getNumOperands ::+ Ptr User -> IO CUInt++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueUser.html#ga799d58a361054323cb457945071cbfdb>+foreign import ccall unsafe "LLVMGetOperand" getOperand ::+ Ptr User -> CUInt -> IO (Ptr Value)+
+ src/LLVM/General/Internal/FFI/Value.h view
@@ -0,0 +1,35 @@+#ifndef __LLVM_GENERAL_INTERNAL_FFI__VALUE__H__+#define __LLVM_GENERAL_INTERNAL_FFI__VALUE__H__++#define LLVM_GENERAL_FOR_EACH_VALUE_SUBCLASS(macro) \+ macro(Argument) \+ macro(BasicBlock) \+ macro(Function) \+ macro(GlobalAlias) \+ macro(GlobalVariable) \+ macro(UndefValue) \+ macro(BlockAddress) \+ macro(ConstantExpr) \+ macro(ConstantAggregateZero) \+ macro(ConstantDataArray) \+ macro(ConstantDataVector) \+ macro(ConstantInt) \+ macro(ConstantFP) \+ macro(ConstantArray) \+ macro(ConstantStruct) \+ macro(ConstantVector) \+ macro(ConstantPointerNull) \+ macro(MDNode) \+ macro(MDString) \+ macro(InlineAsm) \+ macro(PseudoSourceValue) \+ macro(FixedStackPseudoSourceValue) \+ macro(Instruction)++typedef enum {+#define ENUM_CASE(class) LLVM ## class ## SubclassId,+LLVM_GENERAL_FOR_EACH_VALUE_SUBCLASS(ENUM_CASE)+#undef ENUM_CASE+} LLVMValueSubclassId;++#endif
+ src/LLVM/General/Internal/FFI/Value.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE+ ForeignFunctionInterface,+ EmptyDataDecls,+ MultiParamTypeClasses,+ FlexibleContexts,+ FlexibleInstances,+ UndecidableInstances,+ OverlappingInstances+ #-}++-- | FFI functions for handling the LLVM Value class+module LLVM.General.Internal.FFI.Value where++import Foreign.Ptr+import Foreign.C++import LLVM.General.Internal.FFI.LLVMCTypes+import LLVM.General.Internal.FFI.Type +import LLVM.General.Internal.FFI.PtrHierarchy++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueGeneral.html#ga12179f46b79de8436852a4189d4451e0>+foreign import ccall unsafe "LLVMTypeOf" typeOf ::+ Ptr Value -> IO (Ptr Type)++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueGeneral.html#ga70948786725c43968d15225dd584e5a9>+foreign import ccall unsafe "LLVMGetValueName" getValueName ::+ Ptr Value -> IO CString++-- | <http://llvm.org/doxygen/group__LLVMCCoreValueGeneral.html#gac1f61f74d83d218d4943c018e8fd8d13>+foreign import ccall unsafe "LLVMSetValueName" setValueName ::+ Ptr Value -> CString -> IO ()++-- | This function exposes the ID returned by llvm::Value::getValueID()+-- | <http://llvm.org/doxygen/classllvm_1_1Value.html#a2983b7b4998ef5b9f51b18c01588af3c>. +foreign import ccall unsafe "LLVM_General_GetValueSubclassId" getValueSubclassId ::+ Ptr Value -> IO ValueSubclassId++foreign import ccall unsafe "LLVMReplaceAllUsesWith" replaceAllUsesWith ::+ Ptr Value -> Ptr Value -> IO ()
+ src/LLVM/General/Internal/FFI/ValueC.cpp view
@@ -0,0 +1,20 @@+#define __STDC_LIMIT_MACROS+#include "llvm-c/Core.h"+#include "llvm/Value.h"+#include "LLVM/General/Internal/FFI/Value.h"++using namespace llvm;++extern "C" {++LLVMValueSubclassId LLVM_General_GetValueSubclassId(LLVMValueRef v) {+ switch(unwrap(v)->getValueID()) {+#define VALUE_SUBCLASS_ID_CASE(class) case Value::class ## Val: return LLVM ## class ## SubclassId;+LLVM_GENERAL_FOR_EACH_VALUE_SUBCLASS(VALUE_SUBCLASS_ID_CASE)+#undef VALUE_SUBCLASS_ID_CASE+ default: break;+ }+ return LLVMValueSubclassId(0);+}++}
+ src/LLVM/General/Internal/FloatingPointPredicate.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE+ MultiParamTypeClasses,+ TemplateHaskell,+ FlexibleInstances+ #-}++module LLVM.General.Internal.FloatingPointPredicate where++import LLVM.General.Internal.Coding++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.General.AST.FloatingPointPredicate as A.FPPred++genCodingInstance' [t| A.FPPred.FloatingPointPredicate |] ''FFI.FCmpPredicate [+ (FFI.fCmpPredFalse, A.FPPred.False),+ (FFI.fCmpPredOEQ, A.FPPred.OEQ),+ (FFI.fCmpPredOGT, A.FPPred.OGT),+ (FFI.fCmpPredOGE, A.FPPred.OGE),+ (FFI.fCmpPredOLT, A.FPPred.OLT),+ (FFI.fCmpPredOLE, A.FPPred.OLE),+ (FFI.fCmpPredONE, A.FPPred.ONE),+ (FFI.fCmpPredORD, A.FPPred.ORD),+ (FFI.fCmpPredUNO, A.FPPred.UNO),+ (FFI.fCmpPredUEQ, A.FPPred.UEQ),+ (FFI.fCmpPredUGT, A.FPPred.UGT),+ (FFI.fCmpPredUGE, A.FPPred.UGE),+ (FFI.fCmpPredULT, A.FPPred.ULT),+ (FFI.fCmpPredULE, A.FPPred.ULE),+ (FFI.fCmpPredUNE, A.FPPred.UNE),+ (FFI.fcmpPredTrue, A.FPPred.True)+ ]
+ src/LLVM/General/Internal/Function.hs view
@@ -0,0 +1,40 @@+module LLVM.General.Internal.Function where++import Control.Monad+import Control.Monad.Trans+import Control.Monad.AnyCont++import Foreign.Ptr++import qualified LLVM.General.Internal.FFI.Function as FFI+import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI++import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.Value+import LLVM.General.Internal.Coding+import LLVM.General.Internal.Attribute ()++import qualified LLVM.General.AST as A+import qualified LLVM.General.AST.Attribute as A.A++getFunctionAttrs :: Ptr FFI.Function -> IO [A.A.FunctionAttribute]+getFunctionAttrs = decodeM <=< FFI.getFunctionAttr++setFunctionAttrs :: Ptr FFI.Function -> [A.A.FunctionAttribute] -> IO ()+setFunctionAttrs f = FFI.addFunctionAttr f <=< encodeM ++getParameterAttrs :: Ptr FFI.Parameter -> IO [A.A.ParameterAttribute]+getParameterAttrs = decodeM <=< FFI.getAttribute++getParameters :: Ptr FFI.Function -> DecodeAST [A.Parameter]+getParameters f = scopeAnyCont $ do+ n <- liftIO (FFI.countParams f)+ ps <- allocaArray n+ liftIO $ FFI.getParams f ps+ params <- peekArray n ps+ forM params $ \param -> + return A.Parameter + `ap` typeOf param+ `ap` getLocalName param+ `ap` (liftIO $ getParameterAttrs param)+
+ src/LLVM/General/Internal/Global.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE+ TemplateHaskell,+ FlexibleInstances,+ MultiParamTypeClasses,+ FlexibleContexts+ #-}+module LLVM.General.Internal.Global where++import Control.Monad.IO.Class+import Data.Functor+import Foreign.Ptr+import Control.Monad.AnyCont++import Data.Word++import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.General.Internal.FFI.GlobalValue as FFI++import LLVM.General.Internal.Coding+import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.EncodeAST++import qualified LLVM.General.AST.Linkage as A.L+import qualified LLVM.General.AST.Visibility as A.V++genCodingInstance' [t| A.L.Linkage |] ''FFI.Linkage [+ (FFI.linkageExternal, A.L.External),+ (FFI.linkageAvailableExternally, A.L.AvailableExternally),+ (FFI.linkageLinkOnceAny, A.L.LinkOnce),+ (FFI.linkageLinkOnceODR, A.L.LinkOnceODR),+ (FFI.linkageWeakAny, A.L.Weak),+ (FFI.linkageWeakODR, A.L.WeakODR),+ (FFI.linkageAppending, A.L.Appending),+ (FFI.linkageInternal, A.L.Internal),+ (FFI.linkagePrivate, A.L.Private),+ (FFI.linkageDLLImport, A.L.DLLImport),+ (FFI.linkageDLLExport, A.L.DLLExport),+ (FFI.linkageExternalWeak, A.L.ExternWeak),+ (FFI.linkageCommon, A.L.Common),+ (FFI.linkageLinkerPrivate, A.L.LinkerPrivate),+ (FFI.linkageLinkerPrivateWeak, A.L.LinkerPrivateWeak)+ ]++getLinkage :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST A.L.Linkage+getLinkage g = liftIO $ decodeM =<< FFI.getLinkage (FFI.upCast g)++setLinkage :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> A.L.Linkage -> EncodeAST ()+setLinkage g l = liftIO . FFI.setLinkage (FFI.upCast g) =<< encodeM l+ +genCodingInstance' [t| A.V.Visibility |] ''FFI.Visibility [+ (FFI.visibilityDefault, A.V.Default),+ (FFI.visibilityHidden, A.V.Hidden),+ (FFI.visibilityProtected, A.V.Protected)+ ]++getVisibility :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST A.V.Visibility+getVisibility g = liftIO $ decodeM =<< FFI.getVisibility (FFI.upCast g)++setVisibility :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> A.V.Visibility -> EncodeAST ()+setVisibility g v = liftIO . FFI.setVisibility (FFI.upCast g) =<< encodeM v++getSection :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST (Maybe String)+getSection g = liftIO $ do+ s <- decodeM =<< FFI.getSection (FFI.upCast g)+ return $ if (s == "") then Nothing else Just s++setSection :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> Maybe String -> EncodeAST ()+setSection g s = scopeAnyCont $ do+ s <- encodeM (maybe "" id s)+ liftIO $ FFI.setSection (FFI.upCast g) s++setAlignment :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> Word32 -> EncodeAST ()+setAlignment g i = liftIO $ FFI.setAlignment (FFI.upCast g) (fromIntegral i)++getAlignment :: FFI.DescendentOf FFI.GlobalValue v => Ptr v -> DecodeAST Word32+getAlignment g = liftIO $ fromIntegral <$> FFI.getAlignment (FFI.upCast g)
+ src/LLVM/General/Internal/InlineAssembly.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE+ TemplateHaskell,+ MultiParamTypeClasses,+ FlexibleInstances+ #-}+module LLVM.General.Internal.InlineAssembly where+ +import Control.Monad+import Control.Monad.IO.Class++import Foreign.C+import Foreign.Ptr++import qualified LLVM.General.Internal.FFI.InlineAssembly as FFI+import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.General.Internal.FFI.Module as FFI+import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI++import qualified LLVM.General.AST as A (Definition(..))+import qualified LLVM.General.AST.InlineAssembly as A+import qualified LLVM.General.AST.Type as A++import LLVM.General.Internal.Coding +import LLVM.General.Internal.EncodeAST+import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.Value++genCodingInstance' [t| A.Dialect |] ''FFI.AsmDialect [+ (FFI.asmDialectATT, A.ATTDialect),+ (FFI.asmDialectIntel, A.IntelDialect)+ ]++instance EncodeM EncodeAST A.InlineAssembly (Ptr FFI.InlineAsm) where+ encodeM (A.InlineAssembly {+ A.type' = t,+ A.assembly = assembly,+ A.constraints = constraints,+ A.hasSideEffects = hasSideEffects,+ A.alignStack = alignStack,+ A.dialect = dialect+ }) = do+ t <- encodeM t+ assembly <- encodeM assembly+ constraints <- encodeM constraints+ hasSideEffects <- encodeM hasSideEffects+ alignStack <- encodeM alignStack+ dialect <- encodeM dialect+ liftIO $ FFI.createInlineAsm t assembly constraints hasSideEffects alignStack dialect++instance DecodeM DecodeAST A.InlineAssembly (Ptr FFI.InlineAsm) where+ decodeM p = do+ return A.InlineAssembly+ `ap` (liftM (\(A.PointerType f _) -> f) (typeOf p))+ `ap` (decodeM =<< liftIO (FFI.getInlineAsmAssemblyString p))+ `ap` (decodeM =<< liftIO (FFI.getInlineAsmConstraintString p))+ `ap` (decodeM =<< liftIO (FFI.inlineAsmHasSideEffects p))+ `ap` (decodeM =<< liftIO (FFI.inlineAsmIsAlignStack p))+ `ap` (decodeM =<< liftIO (FFI.getInlineAsmDialect p))++instance DecodeM DecodeAST [A.Definition] (FFI.ModuleAsm CString) where+ decodeM (FFI.ModuleAsm s) = do+ s <- decodeM s+ let takeModIA "" = []+ takeModIA s =+ let (a,r) = break (== '\n') s+ in A.ModuleInlineAssembly a : takeModIA (dropWhile (== '\n') r)+ return $ takeModIA s+
+ src/LLVM/General/Internal/Instruction.hs view
@@ -0,0 +1,614 @@+{-# LANGUAGE + TemplateHaskell,+ QuasiQuotes,+ TupleSections,+ MultiParamTypeClasses,+ FlexibleContexts,+ FlexibleInstances+ #-}+module LLVM.General.Internal.Instruction where++import qualified Language.Haskell.TH as TH+import qualified Language.Haskell.TH.Quote as TH+import qualified LLVM.General.Internal.InstructionDefs as ID++import Data.Functor+import Control.Monad+import Control.Monad.Trans+import Control.Monad.AnyCont+import Control.Monad.State+import Control.Monad.Phased++import Foreign.Ptr++import qualified Data.Map as Map+import qualified Data.List as List++import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.General.Internal.FFI.BinaryOperator as FFI+import qualified LLVM.General.Internal.FFI.Instruction as FFI+import qualified LLVM.General.Internal.FFI.Value as FFI+import qualified LLVM.General.Internal.FFI.User as FFI+import qualified LLVM.General.Internal.FFI.Builder as FFI+import qualified LLVM.General.Internal.FFI.Constant as FFI+import qualified LLVM.General.Internal.FFI.BasicBlock as FFI++import LLVM.General.Internal.Atomicity ()+import LLVM.General.Internal.Attribute ()+import LLVM.General.Internal.CallingConvention ()+import LLVM.General.Internal.Coding+import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.EncodeAST+import LLVM.General.Internal.Metadata ()+import LLVM.General.Internal.Operand ()+import LLVM.General.Internal.RMWOperation ()+import LLVM.General.Internal.Type+import LLVM.General.Internal.Value++import qualified LLVM.General.AST as A+import qualified LLVM.General.AST.Constant as A.C++callInstAttr i j = liftIO $ decodeM =<< FFI.getCallInstAttr i j++meta :: Ptr FFI.Instruction -> DecodeAST A.InstructionMetadata+meta i = do+ let getMetadata n = scopeAnyCont $ do+ ks <- allocaArray n+ ps <- allocaArray n+ n' <- liftIO $ FFI.getMetadata i ks ps n+ if (n' > n) + then getMetadata n'+ else return zip `ap` decodeM (n', ks) `ap` decodeM (n', ps)+ getMetadata 4++instance DecodeM DecodeAST A.Terminator (Ptr FFI.Instruction) where+ decodeM i = scopeAnyCont $ do+ n <- liftIO $ FFI.getInstructionDefOpcode i+ nOps <- liftIO $ FFI.getNumOperands (FFI.upCast i)+ md <- meta i+ let op n = decodeM =<< (liftIO $ FFI.getOperand (FFI.upCast i) n)+ successor n = decodeM =<< (liftIO $ FFI.isABasicBlock =<< FFI.getOperand (FFI.upCast i) n)+ case n of+ [ID.instrP|Ret|] -> do+ returnOperand' <- if nOps == 0 then return Nothing else Just <$> op 0+ return $ A.Ret { A.returnOperand = returnOperand', A.metadata' = md }+ [ID.instrP|Br|] -> do+ n <- liftIO $ FFI.getNumOperands (FFI.upCast i)+ case n of+ 1 -> do+ dest <- successor 0+ return $ A.Br { A.dest = dest, A.metadata' = md }+ 3 -> do+ condition <- op 0+ falseDest <- successor 1+ trueDest <- successor 2+ return $ A.CondBr {+ A.condition = condition,+ A.falseDest = falseDest, + A.trueDest = trueDest,+ A.metadata' = md+ }+ [ID.instrP|Switch|] -> do+ op0 <- op 0+ dd <- successor 1+ let nCases = (nOps - 2) `div` 2+ values <- allocaArray nCases+ dests <- allocaArray nCases+ liftIO $ FFI.getSwitchCases i values dests+ cases <- return zip `ap` peekArray nCases values `ap` peekArray nCases dests+ dests <- forM cases $ \(c, d) -> return (,) `ap` decodeM c `ap` decodeM d+ return A.Switch {+ A.operand0' = op0,+ A.defaultDest = dd,+ A.dests = dests,+ A.metadata' = md+ }+ [ID.instrP|IndirectBr|] -> do+ op0 <- op 0+ let nDests = nOps - 1+ dests <- allocaArray nDests+ liftIO $ FFI.getIndirectBrDests i dests+ dests <- decodeM (nDests, dests)+ return A.IndirectBr {+ A.operand0' = op0,+ A.possibleDests = dests,+ A.metadata' = md+ }+ [ID.instrP|Invoke|] -> do+ cc <- decodeM =<< liftIO (FFI.getInstructionCallConv i)+ rAttrs <- callInstAttr i 0+ fv <- liftIO $ FFI.getCallInstCalledValue i+ f <- decodeM fv+ args <- forM [1..nOps-3] $ \j -> return (,) `ap` op (j-1) `ap` callInstAttr i j+ fAttrs <- decodeM =<< liftIO (FFI.getCallInstFunctionAttr i)+ rd <- successor (nOps - 2)+ ed <- successor (nOps - 1)+ return A.Invoke {+ A.callingConvention' = cc,+ A.returnAttributes' = rAttrs,+ A.function' = f,+ A.arguments' = args,+ A.functionAttributes' = fAttrs,+ A.returnDest = rd,+ A.exceptionDest = ed,+ A.metadata' = md+ }+ [ID.instrP|Resume|] -> do+ op0 <- op 0+ return A.Resume {+ A.operand0' = op0,+ A.metadata' = md+ }+ [ID.instrP|Unreachable|] -> do+ return A.Unreachable {+ A.metadata' = md+ }++instance EncodeM EncodeAST A.Terminator (Ptr FFI.Instruction) where+ encodeM t = scopeAnyCont $ do+ builder <- gets encodeStateBuilder+ s <- encodeM ""+ t' <- case t of+ A.Ret { A.returnOperand = r } -> do+ rv <- maybe (return nullPtr) encodeM r+ FFI.upCast <$> do liftIO $ FFI.buildRet builder rv+ A.Br { A.dest = d } -> do+ db <- encodeM d+ FFI.upCast <$> do liftIO $ FFI.buildBr builder db+ A.CondBr { A.condition = c, A.trueDest = t, A.falseDest = f } -> do+ cv <- encodeM c+ tb <- encodeM t+ fb <- encodeM f+ FFI.upCast <$> do liftIO $ FFI.buildCondBr builder cv tb fb+ A.Switch {+ A.operand0' = op0,+ A.defaultDest = dd,+ A.dests = ds+ } -> do+ op0' <- encodeM op0+ dd' <- encodeM dd+ i <- liftIO $ FFI.buildSwitch builder op0' dd' (fromIntegral $ length ds)+ forM ds $ \(v,d) -> do+ v' <- encodeM v+ d' <- encodeM d+ liftIO $ FFI.addCase i v' d'+ return $ FFI.upCast i+ A.IndirectBr { + A.operand0' = op0,+ A.possibleDests = dests+ } -> do+ op0' <- encodeM op0+ i <- liftIO $ FFI.buildIndirectBr builder op0' (fromIntegral $ length dests)+ forM dests $ \dest -> do+ d <- encodeM dest+ liftIO $ FFI.addDestination i d+ return $ FFI.upCast i+ A.Invoke {+ A.callingConvention' = cc,+ A.returnAttributes' = rAttrs,+ A.function' = fun,+ A.arguments' = args,+ A.functionAttributes' = fAttrs,+ A.returnDest = rd,+ A.exceptionDest = ed+ } -> do+ fv <- encodeM fun+ rb <- encodeM rd+ eb <- encodeM ed+ let (argvs, argAttrs) = unzip args+ (n, argvs) <- encodeM argvs+ i <- liftIO $ FFI.buildInvoke builder fv argvs n rb eb s+ forM (zip (rAttrs : argAttrs) [0..]) $ \(attrs, j) -> do+ attrs <- encodeM attrs+ liftIO $ FFI.addCallInstAttr i j attrs+ fAttrs <- encodeM fAttrs+ liftIO $ FFI.addCallInstFunctionAttr i fAttrs+ cc <- encodeM cc+ liftIO $ FFI.setInstructionCallConv i cc+ return $ FFI.upCast i+ A.Resume { + A.operand0' = op0+ } -> do+ op0' <- encodeM op0+ i <- liftIO $ FFI.buildResume builder op0'+ return $ FFI.upCast i+ A.Unreachable {+ } -> do+ i <- liftIO $ FFI.buildUnreachable builder+ return $ FFI.upCast i+ forM (A.metadata' t) $ \(k, mdn) -> do+ k <- encodeM k+ mdn <- encodeM mdn+ liftIO $ FFI.setMetadata t' k mdn+ return t' ++$(do+ let findInstrFields s = Map.findWithDefault (error $ "instruction missing from AST: " ++ show s) s+ ID.astInstructionRecs++ [d|+ instance DecodeM DecodeAST A.Instruction (Ptr FFI.Instruction) where+ decodeM i = scopeAnyCont $ do+ t <- typeOf i+ nOps <- liftIO $ FFI.getNumOperands (FFI.upCast i)+ let op n = decodeM =<< (liftIO $ FFI.getOperand (FFI.upCast i) n)+ cop n = decodeM =<< (liftIO $ FFI.isAConstant =<< FFI.getOperand (FFI.upCast i) n)+ get_nsw b = liftIO $ decodeM =<< FFI.hasNoSignedWrap b+ get_nuw b = liftIO $ decodeM =<< FFI.hasNoUnsignedWrap b+ get_exact b = liftIO $ decodeM =<< FFI.isExact b++ n <- liftIO $ FFI.getInstructionDefOpcode i+ $(+ let fieldDecoders :: String -> String -> ([String], TH.ExpQ)+ fieldDecoders lrn s = case s of+ "b" -> ([], [| liftIO $ FFI.isABinaryOperator (FFI.upCast i) |])+ "nsw" -> (["b"], [| get_nsw $(TH.dyn "b") |])+ "nuw" -> (["b"], [| get_nuw $(TH.dyn "b") |])+ "exact" -> (["b"], [| get_exact $(TH.dyn "b") |])+ "operand0" -> ([], [| op 0 |])+ "operand1" -> ([], [| op 1 |])+ "address" -> ([], [| op 0 |])+ "value" -> ([], [| op 1 |])+ "expected" -> ([], [| op 1 |])+ "replacement" -> ([], [| op 2 |])+ "condition'" -> ([], [| op 0 |])+ "trueValue" -> ([], [| op 1 |])+ "falseValue" -> ([], [| op 2 |])+ "argList" -> ([], [| op 0 |])+ "vector" -> ([], [| op 0 |])+ "element" -> ([], [| op 1 |])+ "index" -> ([], case lrn of "ExtractElement" -> [| op 1 |]; "InsertElement" -> [| op 2 |])+ "personalityFunction" -> ([], [| op 0 |])+ "mask" -> ([], [| cop 2 |])+ "aggregate" -> ([], [| op 0 |])+ "metadata" -> ([], [| meta i |])+ "iPredicate" -> ([], [| decodeM =<< liftIO (FFI.getICmpPredicate i) |])+ "fpPredicate" -> ([], [| decodeM =<< liftIO (FFI.getFCmpPredicate i) |])+ "isTailCall" -> ([], [| decodeM =<< liftIO (FFI.isTailCall i) |])+ "callingConvention" -> ([], [| decodeM =<< liftIO (FFI.getInstructionCallConv i) |])+ "returnAttributes" -> ([], [| callInstAttr i 0 |])+ "f" -> ([], [| liftIO $ FFI.getCallInstCalledValue i |])+ "function" -> (["f"], [| decodeM $(TH.dyn "f") |])+ "arguments" -> ([], [| forM [1..nOps-1] $ \j -> return (,) `ap` op (j-1) `ap` callInstAttr i j |])+ "clauses" -> + ([], [| forM [1..nOps-1] $ \j -> do+ v <- liftIO $ FFI.getOperand (FFI.upCast i) j+ c <- decodeM =<< (liftIO $ FFI.isAConstant v)+ t <- typeOf v+ return $ case t of { A.ArrayType _ _ -> A.Filter; _ -> A.Catch} $ c |])+ "functionAttributes" ->+ ([], [| decodeM =<< liftIO (FFI.getCallInstFunctionAttr i) |])+ "type'" -> ([], [| return t |])+ "incomingValues" ->+ ([], [| do+ n <- liftIO $ FFI.countIncoming i+ forM [0..n-1] $ \m -> do+ iv <- decodeM =<< (liftIO $ FFI.getIncomingValue i m)+ ib <- decodeM =<< (liftIO $ FFI.getIncomingBlock i m)+ return (iv,ib) |])+ "allocatedType" -> ([], [| decodeM =<< liftIO (FFI.getAllocatedType i) |])+ "numElements" -> + ([], [| do+ n <- decodeM =<< (liftIO $ FFI.getAllocaNumElements i)+ return $ case n of+ A.ConstantOperand (A.C.Int { A.C.integerValue = 1 }) -> Nothing+ _ -> Just n+ |]) + "alignment" -> ([], [| decodeM =<< liftIO (FFI.getInstrAlignment i) |])+ "maybeAtomicity" -> ([], [| decodeM =<< liftIO (FFI.getAtomicity i) |])+ "atomicity" -> ([], [| decodeM =<< liftIO (FFI.getAtomicity i) |])+ "volatile" -> ([], [| decodeM =<< liftIO (FFI.getVolatile i) |])+ "inBounds" -> ([], [| decodeM =<< liftIO (FFI.getInBounds (FFI.upCast i)) |])+ "indices" -> ([], [| mapM op [1..nOps-1] |])+ "indices'" ->+ ([], [| do+ n <- liftIO $ FFI.countInstStructureIndices i+ a <- allocaArray n+ liftIO $ FFI.getInstStructureIndices i a+ decodeM (n, a) |])+ "rmwOperation" -> ([], [| decodeM =<< liftIO (FFI.getAtomicRMWOperation i) |])+ "cleanup" -> ([], [| decodeM =<< liftIO (FFI.isCleanup i) |])+ _ -> ([], [| error $ "unrecognized instruction field or depenency thereof: " ++ show s |])+ in+ TH.caseE [| n |] [ + TH.match opcodeP (TH.normalB (TH.doE handlerBody)) []+ | (lrn, iDef) <- Map.toList ID.instructionDefs,+ ID.instructionKind iDef /= ID.Terminator,+ let opcodeP = TH.dataToPatQ (const Nothing) (ID.cppOpcode iDef)+ handlerBody = + let TH.RecC fullName fields = findInstrFields lrn+ (fieldNames,_,_) = unzip3 fields+ allNames ns = List.nub $ [ d | n <- ns, d <- allNames . fst . fieldDecoders lrn $ n ] ++ ns+ in+ [ + TH.bindS (TH.varP (TH.mkName n)) (snd . fieldDecoders lrn $ n)+ | n <- allNames . map TH.nameBase $ fieldNames + ] ++ [ + TH.noBindS [| + return $(TH.recConE + fullName+ [ (f,) <$> (TH.varE . TH.mkName . TH.nameBase $ f) | f <- fieldNames ])+ |]+ ]+ ]+ )++ instance EncodeM EncodeAST A.Instruction (Ptr FFI.Instruction) where+ encodeM o = scopeAnyCont $ do+ builder <- gets encodeStateBuilder+ s <- encodeM ""+ $(+ [|+ case o of+ A.ICmp { + A.iPredicate = pred, + A.operand0 = op0, + A.operand1 = op1, + A.metadata = [] + } -> do+ op0' <- encodeM op0+ op1' <- encodeM op1+ pred <- encodeM pred+ i <- liftIO $ FFI.buildICmp builder pred op0' op1' s+ return $ FFI.upCast i+ A.FCmp {+ A.fpPredicate = pred, + A.operand0 = op0, + A.operand1 = op1, + A.metadata = [] + } -> do+ op0' <- encodeM op0+ op1' <- encodeM op1+ pred <- encodeM pred+ i <- liftIO $ FFI.buildFCmp builder pred op0' op1' s+ return $ FFI.upCast i+ A.Phi { A.type' = t, A.incomingValues = ivs } -> do+ t' <- encodeM t+ i <- liftIO $ FFI.buildPhi builder t' s+ defer+ let (ivs3, bs3) = unzip ivs+ ivs3' <- encodeM ivs3+ bs3' <- encodeM bs3+ liftIO $ FFI.addIncoming i ivs3' bs3'+ return $ FFI.upCast i+ A.Call {+ A.isTailCall = tc,+ A.callingConvention = cc,+ A.returnAttributes = rAttrs,+ A.function = f,+ A.arguments = args,+ A.functionAttributes = fAttrs,+ A.metadata = []+ } -> do+ fv <- encodeM f+ let (argvs, argAttrs) = unzip args+ (n, argvs) <- encodeM argvs+ i <- liftIO $ FFI.buildCall builder fv argvs n s+ forM (zip (rAttrs : argAttrs) [0..]) $ \(attrs, j) -> do+ attrs <- encodeM attrs+ liftIO $ FFI.addCallInstAttr i j attrs+ fAttrs <- encodeM fAttrs+ liftIO $ FFI.addCallInstFunctionAttr i fAttrs+ when tc $ do+ tc <- encodeM tc+ liftIO $ FFI.setTailCall i tc+ cc <- encodeM cc+ liftIO $ FFI.setInstructionCallConv i cc+ return $ FFI.upCast i+ A.Select { A.condition' = c, A.trueValue = t, A.falseValue = f } -> do+ c' <- encodeM c+ t' <- encodeM t+ f' <- encodeM f+ i <- liftIO $ FFI.buildSelect builder c' t' f' s+ return $ FFI.upCast i+ A.VAArg { A.argList = al, A.type' = t } -> do+ al' <- encodeM al+ t' <- encodeM t+ i <- liftIO $ FFI.buildVAArg builder al' t' s+ return $ FFI.upCast i+ A.ExtractElement { A.vector = v, A.index = idx } -> do+ v' <- encodeM v+ idx' <- encodeM idx+ i <- liftIO $ FFI.buildExtractElement builder v' idx' s+ return $ FFI.upCast i+ A.InsertElement { A.vector = v, A.element = e, A.index = idx } -> do+ v' <- encodeM v+ e' <- encodeM e+ idx' <- encodeM idx+ i <- liftIO $ FFI.buildInsertElement builder v' e' idx' s+ return $ FFI.upCast i+ A.ShuffleVector { A.operand0 = o0, A.operand1 = o1, A.mask = mask } -> do+ o0' <- encodeM o0+ o1' <- encodeM o1+ mask' <- encodeM mask+ i <- liftIO $ FFI.buildShuffleVector builder o0' o1' mask' s+ return $ FFI.upCast i+ A.ExtractValue { A.aggregate = a, A.indices' = is } -> do+ a' <- encodeM a+ (n, is') <- encodeM is+ i <- liftIO $ FFI.buildExtractValue builder a' is' n s+ return $ FFI.upCast i+ A.InsertValue { A.aggregate = a, A.element = e, A.indices' = is } -> do+ a' <- encodeM a+ e' <- encodeM e+ (n, is') <- encodeM is+ i <- liftIO $ FFI.buildInsertValue builder a' e' is' n s+ return $ FFI.upCast i+ A.LandingPad { + A.type' = t,+ A.personalityFunction = pf,+ A.cleanup = cl, + A.clauses = cs+ } -> do+ t' <- encodeM t+ pf' <- encodeM pf+ i <- liftIO $ FFI.buildLandingPad builder t' pf' (fromIntegral $ length cs) s+ forM cs $ \c -> + case c of+ A.Catch a -> do+ cn <- encodeM a+ isArray <- liftIO $ isArrayType =<< FFI.typeOf (FFI.upCast cn)+ when isArray $ fail $ "Catch clause cannot take an array: " ++ show c+ liftIO $ FFI.addClause i cn+ A.Filter a -> do+ cn <- encodeM a+ isArray <- liftIO $ isArrayType =<< FFI.typeOf (FFI.upCast cn)+ unless isArray $ fail $ "filter clause must take an array: " ++ show c+ liftIO $ FFI.addClause i cn+ when cl $ do+ cl <- encodeM cl+ liftIO $ FFI.setCleanup i cl+ return $ FFI.upCast i+ A.Alloca { A.allocatedType = alt, A.numElements = n, A.alignment = alignment } -> do + alt' <- encodeM alt+ n' <- maybe (return nullPtr) encodeM n+ i <- liftIO $ FFI.buildAlloca builder alt' n' s+ unless (alignment == 0) $ liftIO $ FFI.setInstrAlignment i (fromIntegral alignment)+ return $ FFI.upCast i+ A.Load {+ A.volatile = vol,+ A.address = a,+ A.alignment = al,+ A.maybeAtomicity = mat,+ A.metadata = []+ } -> do+ a' <- encodeM a+ al <- encodeM al+ vol <- encodeM vol+ (ss, mo) <- encodeM mat+ i <- liftIO $ FFI.buildLoad builder a' al vol mo ss s+ return $ FFI.upCast i+ A.Store { + A.volatile = vol, + A.address = a, + A.value = v, + A.maybeAtomicity = mat, + A.alignment = al, + A.metadata = []+ } -> do+ a' <- encodeM a+ v' <- encodeM v+ al <- encodeM al+ vol <- encodeM vol+ (ss, mo) <- encodeM mat+ i <- liftIO $ FFI.buildStore builder a' v' al vol mo ss s+ return $ FFI.upCast i+ A.GetElementPtr { A.address = a, A.indices = is, A.inBounds = ib } -> do+ a' <- encodeM a+ (n, is') <- encodeM is+ i <- liftIO $ FFI.buildGetElementPtr builder a' is' n s+ when ib $ do+ ib <- encodeM ib + liftIO $ FFI.setInBounds i ib+ return $ FFI.upCast i+ A.Fence { A.atomicity = at } -> do+ (ss, mo) <- encodeM at+ i <- liftIO $ FFI.buildFence builder mo ss s+ return $ FFI.upCast i+ A.CmpXchg { + A.volatile = vol, + A.address = a, A.expected = e, A.replacement = r,+ A.atomicity = at,+ A.metadata = []+ } -> do+ a' <- encodeM a+ e' <- encodeM e+ r' <- encodeM r+ vol <- encodeM vol+ (ss, mo) <- encodeM at+ i <- liftIO $ FFI.buildCmpXchg builder a' e' r' vol mo ss s+ return $ FFI.upCast i+ A.AtomicRMW {+ A.volatile = vol,+ A.rmwOperation = rmwOp,+ A.address = a,+ A.value = v,+ A.atomicity = at,+ A.metadata = []+ } -> do+ a' <- encodeM a+ v' <- encodeM v+ rmwOp <- encodeM rmwOp+ vol <- encodeM vol+ (ss, mo) <- encodeM at+ i <- liftIO $ FFI.buildAtomicRMW builder rmwOp a' v' vol mo ss s+ return $ FFI.upCast i+ o -> $(+ let+ fieldData :: String -> [Either TH.ExpQ TH.ExpQ]+ fieldData s = case s of+ "operand0" -> [Left [| encodeM $(TH.dyn s) |] ]+ "operand1" -> [Left [| encodeM $(TH.dyn s) |] ]+ "type'" -> [Left [| encodeM $(TH.dyn s) |] ]+ "nsw" -> [Left [| encodeM $(TH.dyn s) |] ]+ "nuw" -> [Left [| encodeM $(TH.dyn s) |] ]+ "exact" -> [Left [| encodeM $(TH.dyn s) |] ]+ "metadata" -> + [Right [| unless (List.null $(TH.dyn s)) $ error "can't handle metadata yet" |]]+ _ -> error $ "unhandled instruction field " ++ show s+ in+ TH.caseE [| o |] [+ TH.match + (TH.recP fullName [ (f,) <$> (TH.varP . TH.mkName . TH.nameBase $ f) | f <- fieldNames ])+ (TH.normalB (TH.doE handlerBody))+ []+ |+ (name, ID.InstructionDef { ID.instructionKind = k }) <- Map.toList ID.instructionDefs,+ k `List.elem` [ID.Binary, ID.Cast],+ let+ TH.RecC fullName fields = findInstrFields name+ (fieldNames, _, _) = unzip3 fields+ cTorFields = [+ (s, binding)+ | f <- fieldNames,+ let s = TH.nameBase f,+ Left binding <- fieldData s+ ]+ handlerBody = (+ [ TH.bindS (TH.varP (TH.mkName s)) binding | (s, binding) <- cTorFields ]+ ++ [+ TH.bindS + (TH.varP (TH.mkName "i"))+ [| liftIO $ $(foldl1 TH.appE . map TH.dyn $ [ + "FFI.build" ++ name,+ "builder"+ ] ++ [+ s | (s, _) <- cTorFields, s /= "metadata"+ ] ++ [+ "s"+ ] ) |]++ ] ++ [+ TH.noBindS action+ | f <- fieldNames,+ let s = TH.nameBase f,+ Right action <- fieldData s+ ] ++ [+ TH.noBindS [| return $ FFI.upCast $(TH.dyn "i") |]+ ]+ )+ ]+ )++ |]+ )+ |]+ )+++instance DecodeM DecodeAST a (Ptr FFI.Instruction) => DecodeM DecodeAST (A.Named a) (Ptr FFI.Instruction) where+ decodeM i = do+ t <- typeOf i+ (if t == A.VoidType then (return A.Do) else (return (A.:=) `ap` getLocalName i)) `ap` (do defer; decodeM i)++instance EncodeM EncodeAST a (Ptr FFI.Instruction) => EncodeM EncodeAST (A.Named a) (Ptr FFI.Instruction) where+ encodeM (A.Do o) = encodeM o+ encodeM (n A.:= o) = do+ i <- encodeM o+ let v = FFI.upCast i+ n' <- encodeM n+ liftIO $ FFI.setValueName v n'+ defineLocal n v+ return i++
+ src/LLVM/General/Internal/InstructionDefs.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE+ TemplateHaskell+ #-}++module LLVM.General.Internal.InstructionDefs (+ astInstructionRecs,+ astConstantRecs,+ instructionDefs,+ ID.InstructionKind(..),+ ID.InstructionDef(..),+ instrP,+ innerJoin,+ outerJoin+ ) where++import qualified Language.Haskell.TH as TH+import qualified Language.Haskell.TH.Quote as TH++import Data.Map (Map)+import qualified Data.Map as Map++import qualified LLVM.General.Internal.FFI.InstructionDefs as ID++import qualified LLVM.General.AST.Instruction as A+import qualified LLVM.General.AST.Constant as A.C++$(do+ let ctorRecs t = do+ TH.TyConI (TH.DataD _ _ _ cons _) <- TH.reify t+ TH.dataToExpQ (const Nothing) $ [ (TH.nameBase n, rec) | rec@(TH.RecC n _) <- cons ]++ [d| + astInstructionRecs = Map.fromList $(ctorRecs ''A.Instruction)+ astConstantRecs = Map.fromList $(ctorRecs ''A.C.Constant)+ |]+ )++instructionDefs = Map.fromList [ ((refName . ID.cAPIName $ i), i) | i <- ID.instructionDefs ]+ where+ refName "AtomicCmpXchg" = "CmpXchg"+ refName "PHI" = "Phi"+ refName x = x++innerJoin :: Ord k => Map k a -> Map k b -> Map k (a,b)+innerJoin = Map.mergeWithKey (\_ a b -> Just (a,b)) (const Map.empty) (const Map.empty)+ +outerJoin :: Ord k => Map k a -> Map k b -> Map k (Maybe a, Maybe b)+outerJoin = Map.mergeWithKey + (\_ a b -> Just (Just a, Just b))+ (Map.map $ \a -> (Just a, Nothing))+ (Map.map $ \b -> (Nothing, Just b))++instrP = TH.QuasiQuoter { + TH.quoteExp = undefined,+ TH.quotePat = let m = Map.fromList [ (ID.cAPIName i, ID.cppOpcode i) | i <- ID.instructionDefs ]+ in TH.dataToPatQ (const Nothing) . (m Map.!),+ TH.quoteType = undefined,+ TH.quoteDec = undefined+ }
+ src/LLVM/General/Internal/IntegerPredicate.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE+ TemplateHaskell,+ MultiParamTypeClasses,+ FlexibleInstances+ #-}++module LLVM.General.Internal.IntegerPredicate where++import LLVM.General.Internal.Coding++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.General.AST.IntegerPredicate as A.IPred++genCodingInstance' [t| A.IPred.IntegerPredicate |] ''FFI.ICmpPredicate [+ (FFI.iCmpPredEQ, A.IPred.EQ),+ (FFI.iCmpPredNE, A.IPred.NE),+ (FFI.iCmpPredUGT, A.IPred.UGT),+ (FFI.iCmpPredUGE, A.IPred.UGE),+ (FFI.iCmpPredULT, A.IPred.ULT),+ (FFI.iCmpPredULE, A.IPred.ULE),+ (FFI.iCmpPredSGT, A.IPred.SGT),+ (FFI.iCmpPredSGE, A.IPred.SGE),+ (FFI.iCmpPredSLT, A.IPred.SLT),+ (FFI.iCmpPredSLE, A.IPred.SLE)+ ]
+ src/LLVM/General/Internal/Metadata.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE+ MultiParamTypeClasses,+ FlexibleInstances+ #-}+module LLVM.General.Internal.Metadata where++import Control.Monad.State+import Control.Monad.AnyCont++import Foreign.Ptr++import qualified Foreign.Marshal.Array as FMA+import qualified Data.Array as Array++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.General.Internal.FFI.Metadata as FFI+import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI++import LLVM.General.Internal.Context+import LLVM.General.Internal.Coding+import LLVM.General.Internal.EncodeAST+import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.Value ()++instance EncodeM EncodeAST String FFI.MDKindID where+ encodeM s = do+ Context c <- gets encodeStateContext+ s <- encodeM s+ liftIO $ FFI.getMDKindIDInContext c s++getMetadataKindNames :: Context -> DecodeAST ()+getMetadataKindNames (Context c) = scopeAnyCont $ do+ let g n = do+ ps <- allocaArray n+ ls <- allocaArray n+ n' <- liftIO $ FFI.getMDKindNames c ps ls n+ if n' > n+ then g n'+ else do+ csls <- return zip+ `ap` liftIO (FMA.peekArray (fromIntegral n') ps)+ `ap` liftIO (FMA.peekArray (fromIntegral n') ls)+ mapM decodeM csls+ strs <- g 16+ modify $ \s -> s { metadataKinds = Array.listArray (0, fromIntegral (length strs) - 1) strs }++instance DecodeM DecodeAST String FFI.MDKindID where+ decodeM (FFI.MDKindID k) = gets $ (Array.! (fromIntegral k)) . metadataKinds++instance DecodeM DecodeAST String (Ptr FFI.MDString) where+ decodeM p = do+ np <- alloca+ s <- liftIO $ FFI.getMDString p np+ n <- peek np+ decodeM (s, n)
+ src/LLVM/General/Internal/Module.hs view
@@ -0,0 +1,281 @@+{-#+ LANGUAGE+ TupleSections,+ ScopedTypeVariables+ #-}++-- | This Haskell module is for/of functions for handling LLVM modules.+module LLVM.General.Internal.Module where++import Control.Monad.Trans+import Control.Monad.State+import Control.Monad.Phased+import Control.Monad.AnyCont+import Control.Applicative+import Control.Exception++import Foreign.Ptr+import Foreign.Marshal.Alloc (free)++import qualified LLVM.General.Internal.FFI.Assembly as FFI+import qualified LLVM.General.Internal.FFI.Builder as FFI+import qualified LLVM.General.Internal.FFI.Function as FFI+import qualified LLVM.General.Internal.FFI.GlobalAlias as FFI+import qualified LLVM.General.Internal.FFI.GlobalValue as FFI+import qualified LLVM.General.Internal.FFI.GlobalVariable as FFI+import qualified LLVM.General.Internal.FFI.Iterate as FFI+import qualified LLVM.General.Internal.FFI.Module as FFI+import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.General.Internal.FFI.Value as FFI+import qualified LLVM.General.Internal.FFI.Metadata as FFI++import LLVM.General.Internal.BasicBlock+import LLVM.General.Internal.Coding+import LLVM.General.Internal.Context+import LLVM.General.Internal.DataLayout+import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.Diagnostic+import LLVM.General.Internal.EncodeAST+import LLVM.General.Internal.Function+import LLVM.General.Internal.Global+import LLVM.General.Internal.Metadata+import LLVM.General.Internal.Operand+import LLVM.General.Internal.Type+import LLVM.General.Internal.Value++import LLVM.General.Diagnostic++import qualified LLVM.General.AST as A+import qualified LLVM.General.AST.DataLayout as A+import qualified LLVM.General.AST.AddrSpace as A+import qualified LLVM.General.AST.Global as A.G++-- | <http://llvm.org/doxygen/classllvm_1_1Module.html>+newtype Module = Module (Ptr FFI.Module)++-- | parse 'Module' from LLVM assembly+withModuleFromString :: Context -> String -> (Module -> IO a) -> IO (Either Diagnostic a)+withModuleFromString (Context c) s f = flip runAnyContT return $ do+ s <- encodeM s+ liftIO $ withSMDiagnostic $ \smDiag -> do+ m <- FFI.getModuleFromAssemblyInContext c s smDiag+ if m == nullPtr then+ Left <$> getDiagnostic smDiag+ else+ Right <$> finally (f (Module m)) (FFI.disposeModule m)++-- | generate LLVM assembly from a 'Module'+moduleString :: Module -> IO String+moduleString (Module m) = bracket (FFI.getModuleAssembly m) free $ decodeM++setTargetTriple :: Ptr FFI.Module -> String -> IO ()+setTargetTriple m t = flip runAnyContT return $ do+ t <- encodeM t+ liftIO $ FFI.setTargetTriple m t++getTargetTriple :: Ptr FFI.Module -> IO (Maybe String)+getTargetTriple m = do+ s <- decodeM =<< liftIO (FFI.getTargetTriple m)+ return $ if s == "" then Nothing else Just s++setDataLayout :: Ptr FFI.Module -> A.DataLayout -> IO ()+setDataLayout m dl = flip runAnyContT return $ do+ s <- encodeM (dataLayoutToString dl)+ liftIO $ FFI.setDataLayout m s++getDataLayout :: Ptr FFI.Module -> IO (Maybe A.DataLayout)+getDataLayout m = parseDataLayout <$> (decodeM =<< FFI.getDataLayout m)++-- | Build a 'Module' from a 'LLVM.General.AST.Module'.+withModuleFromAST :: Context -> A.Module -> (Module -> IO a) -> IO (Either String a)+withModuleFromAST context@(Context c) (A.Module moduleId dataLayout triple definitions) f = do+ let makeModule = flip runAnyContT return $ do+ moduleId <- encodeM moduleId+ liftIO $ FFI.moduleCreateWithNameInContext moduleId c+ bracket makeModule FFI.disposeModule $ \m -> do+ maybe (return ()) (setDataLayout m) dataLayout+ maybe (return ()) (setTargetTriple m) triple+ r <- runEncodeAST context $ forInterleavedM definitions $ \d -> case d of+ A.TypeDefinition n t -> do+ t' <- createNamedType n+ defineType n t'+ defer+ maybe (return ()) (setNamedType t') t++ A.MetadataNodeDefinition i os -> do+ replicateM_ 2 defer+ t <- liftIO $ FFI.createTemporaryMDNodeInContext c+ defineMDNode i t+ defer+ n <- encodeM (A.MetadataNode os)+ liftIO $ FFI.replaceAllUsesWith (FFI.upCast t) (FFI.upCast n)+ defineMDNode i n+ liftIO $ FFI.destroyTemporaryMDNode t++ A.NamedMetadataDefinition n ids -> do+ replicateM_ 4 defer+ n <- encodeM n+ ids <- encodeM (map A.MetadataNodeReference ids)+ nm <- liftIO $ FFI.getOrAddNamedMetadata m n+ liftIO $ FFI.namedMetadataAddOperands nm ids++ A.ModuleInlineAssembly s -> do+ s <- encodeM s+ liftIO $ FFI.moduleAppendInlineAsm m (FFI.ModuleAsm s)++ A.GlobalDefinition g -> do+ replicateM_ 2 defer+ g' :: Ptr FFI.GlobalValue <- case g of+ g@(A.GlobalVariable { A.G.name = n }) -> do+ typ <- encodeM (A.G.type' g)+ g' <- liftIO $ withName n $ \gName -> + FFI.addGlobalInAddressSpace m typ gName + (fromIntegral ((\(A.AddrSpace a) -> a) $ A.G.addrSpace g))+ defineGlobal n g'+ liftIO $ do+ tl <- encodeM (A.G.isThreadLocal g)+ FFI.setThreadLocal g' tl+ hua <- encodeM (A.G.hasUnnamedAddr g)+ FFI.setUnnamedAddr (FFI.upCast g') hua+ ic <- encodeM (A.G.isConstant g)+ FFI.setGlobalConstant g' ic+ defer+ maybe (return ()) ((liftIO . FFI.setInitializer g') <=< encodeM) (A.G.initializer g)+ setSection g' (A.G.section g)+ setAlignment g' (A.G.alignment g)+ return (FFI.upCast g')+ (a@A.G.GlobalAlias { A.G.name = n }) -> do+ typ <- encodeM (A.G.type' a)+ a' <- liftIO $ withName n $ \name -> FFI.justAddAlias m typ name+ defineGlobal n a'+ defer+ (liftIO . FFI.setAliasee a') =<< encodeM (A.G.aliasee a)+ return (FFI.upCast a')+ (A.Function _ _ cc rAttrs resultType fName (args,isVarArgs) attrs _ _ blocks) -> do+ typ <- encodeM $ A.FunctionType resultType (map (\(A.Parameter t _ _) -> t) args) isVarArgs+ f <- liftIO . withName fName $ \fName -> FFI.addFunction m fName typ+ defineGlobal fName f+ cc <- encodeM cc+ liftIO $ FFI.setFunctionCallConv f cc+ rAttrs <- encodeM rAttrs+ liftIO $ FFI.addFunctionRetAttr f rAttrs+ liftIO $ setFunctionAttrs f attrs+ setSection f (A.G.section g)+ setAlignment f (A.G.alignment g)+ encodeScope $ do+ forM blocks $ \(A.BasicBlock bName _ _) -> do+ b <- liftIO $ withName bName $ \bName -> FFI.appendBasicBlockInContext c f bName+ defineBasicBlock fName bName b+ defer+ let nParams = length args+ ps <- allocaArray nParams+ liftIO $ FFI.getParams f ps+ params <- peekArray nParams ps+ forM (zip args params) $ \(A.Parameter _ n attrs, p) -> do+ defineLocal n p+ n <- encodeM n+ liftIO $ FFI.setValueName (FFI.upCast p) n+ attrs <- encodeM attrs+ liftIO $ FFI.addAttribute p attrs+ return ()+ forInterleavedM blocks $ \(A.BasicBlock bName namedInstrs term) -> do+ b <- encodeM bName+ (do builder <- gets encodeStateBuilder; liftIO $ FFI.positionBuilderAtEnd builder b)+ (mapM encodeM namedInstrs :: EncodeAST [Ptr FFI.Instruction])+ encodeM term :: EncodeAST (Ptr FFI.Instruction)+ return (FFI.upCast f)+ setLinkage g' (A.G.linkage g)+ setVisibility g' (A.G.visibility g)++ either (return . Left) (const $ Right <$> f (Module m)) r++-- | Get a 'LLVM.General.AST.Module' from a 'Module'.+moduleAST :: Module -> IO A.Module+moduleAST (Module mod) = runDecodeAST $ do+ c <- return Context `ap` liftIO (FFI.getModuleContext mod)+ getMetadataKindNames c+ return A.Module + `ap` (liftIO $ bracket (FFI.getModuleIdentifier mod) free decodeM)+ `ap` (liftIO $ getDataLayout mod)+ `ap` (liftIO $ do+ s <- decodeM <=< FFI.getTargetTriple $ mod+ return $ if s == "" then Nothing else Just s)+ `ap` (+ do+ gs <- map A.GlobalDefinition . concat <$> runInterleaved [+ do+ ffiGlobals <- liftIO $ FFI.getXs (FFI.getFirstGlobal mod) FFI.getNextGlobal+ forM ffiGlobals $ \g -> do+ A.PointerType t as <- typeOf g+ return A.GlobalVariable+ `ap` getGlobalName g+ `ap` getLinkage g+ `ap` getVisibility g+ `ap` (liftIO $ decodeM =<< FFI.isThreadLocal g)+ `ap` return as+ `ap` (liftIO $ decodeM =<< FFI.hasUnnamedAddr (FFI.upCast g))+ `ap` (liftIO $ decodeM =<< FFI.isGlobalConstant g)+ `ap` return t+ `ap` (do+ defer+ i <- liftIO $ FFI.getInitializer g+ if i == nullPtr then return Nothing else Just <$> decodeM i)+ `ap` getSection g+ `ap` getAlignment g,++ do+ ffiAliases <- liftIO $ FFI.getXs (FFI.getFirstAlias mod) FFI.getNextAlias+ forM ffiAliases $ \a -> do+ return A.G.GlobalAlias+ `ap` (do n <- getGlobalName a; defer; return n)+ `ap` getLinkage a+ `ap` getVisibility a+ `ap` typeOf a+ `ap` (decodeM =<< (liftIO $ FFI.getAliasee a)),++ do+ ffiFunctions <- liftIO $ FFI.getXs (FFI.getFirstFunction mod) FFI.getNextFunction+ forM ffiFunctions $ \f -> localScope $ do+ A.PointerType (A.FunctionType returnType _ isVarArg) _ <- typeOf f+ return A.Function+ `ap` getLinkage f+ `ap` getVisibility f+ `ap` (liftIO $ decodeM =<< FFI.getFunctionCallConv f)+ `ap` (liftIO $ decodeM =<< FFI.getFunctionRetAttr f)+ `ap` return returnType+ `ap` (getGlobalName f)+ `ap` ((, isVarArg) <$> getParameters f)+ `ap` (liftIO $ getFunctionAttrs f)+ `ap` getSection f+ `ap` getAlignment f+ `ap` (do+ ffiBasicBlocks <- liftIO $ FFI.getXs (FFI.getFirstBasicBlock f) FFI.getNextBasicBlock+ runInterleaved . flip map ffiBasicBlocks $ \b -> + return A.BasicBlock+ `ap` (do n <- getLocalName b; defer; return n)+ `iap` getNamedInstructions b+ `iap` getBasicBlockTerminator b+ )+ ]++ tds <- getStructDefinitions++ ias <- decodeM =<< liftIO (FFI.moduleGetInlineAsm mod)++ nmds <- do+ ffiNamedMetadataNodes <- liftIO $ FFI.getXs (FFI.getFirstNamedMetadata mod) FFI.getNextNamedMetadata+ forM ffiNamedMetadataNodes $ \nm -> scopeAnyCont $ do+ n <- liftIO $ FFI.getNamedMetadataNumOperands nm+ os <- allocaArray n+ liftIO $ FFI.getNamedMetadataOperands nm os+ l <- alloca+ cs <- liftIO $ FFI.getNamedMetadataName nm l+ l <- peek l+ return A.NamedMetadataDefinition+ `ap` decodeM (cs, l)+ `ap` liftM (map (\(A.MetadataNodeReference mid) -> mid)) (decodeM (n, os))+ + mds <- getMetadataDefinitions++ return $ tds ++ ias ++ gs ++ nmds ++ mds+ )
+ src/LLVM/General/Internal/Operand.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE+ MultiParamTypeClasses,+ FlexibleInstances+ #-}+module LLVM.General.Internal.Operand where++import Data.Functor+import Control.Monad.State+import Control.Monad.AnyCont++import Foreign.Ptr++import qualified LLVM.General.Internal.FFI.Constant as FFI+import qualified LLVM.General.Internal.FFI.InlineAssembly as FFI+import qualified LLVM.General.Internal.FFI.Metadata as FFI+import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI++import LLVM.General.Internal.Coding+import LLVM.General.Internal.Constant ()+import LLVM.General.Internal.Context+import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.EncodeAST+import LLVM.General.Internal.InlineAssembly ()+import LLVM.General.Internal.Metadata ()++import qualified LLVM.General.AST as A++instance DecodeM DecodeAST A.Operand (Ptr FFI.Value) where+ decodeM v = do+ c <- liftIO $ FFI.isAConstant v+ if (c /= nullPtr) + then+ return A.ConstantOperand `ap` decodeM c+ else+ do+ mds <- liftIO $ FFI.isAMDString v+ if mds /= nullPtr + then return A.MetadataStringOperand `ap` decodeM mds+ else+ do+ mdn <- liftIO $ FFI.isAMDNode v+ if mdn /= nullPtr+ then return A.MetadataNodeOperand `ap` decodeM mdn+ else+ return A.LocalReference `ap` getLocalName v++instance DecodeM DecodeAST A.CallableOperand (Ptr FFI.Value) where+ decodeM v = do+ ia <- liftIO $ FFI.isAInlineAsm v+ if ia /= nullPtr+ then liftM Left (decodeM ia)+ else liftM Right (decodeM v)++instance EncodeM EncodeAST A.Operand (Ptr FFI.Value) where+ encodeM (A.ConstantOperand c) = (FFI.upCast :: Ptr FFI.Constant -> Ptr FFI.Value) <$> encodeM c+ encodeM (A.LocalReference n) = referLocal n+ encodeM (A.MetadataStringOperand s) = do+ Context c <- gets encodeStateContext+ s <- encodeM s+ liftM FFI.upCast $ liftIO $ FFI.mdStringInContext c s+ encodeM (A.MetadataNodeOperand mdn) = (FFI.upCast :: Ptr FFI.MDNode -> Ptr FFI.Value) <$> encodeM mdn++instance EncodeM EncodeAST A.CallableOperand (Ptr FFI.Value) where+ encodeM (Right o) = encodeM o+ encodeM (Left i) = liftM (FFI.upCast :: Ptr FFI.InlineAsm -> Ptr FFI.Value) (encodeM i)++instance EncodeM EncodeAST A.MetadataNode (Ptr FFI.MDNode) where+ encodeM (A.MetadataNode ops) = scopeAnyCont $ do+ Context c <- gets encodeStateContext+ ops <- encodeM ops+ liftIO $ FFI.createMDNodeInContext c ops+ encodeM (A.MetadataNodeReference n) = referMDNode n++instance DecodeM DecodeAST [A.Operand] (Ptr FFI.MDNode) where+ decodeM p = scopeAnyCont $ do+ n <- liftIO $ FFI.getMDNodeNumOperands p+ ops <- allocaArray n+ liftIO $ FFI.getMDNodeOperands p ops+ decodeM (n, ops)++instance DecodeM DecodeAST A.MetadataNode (Ptr FFI.MDNode) where+ decodeM p = scopeAnyCont $ do+ fl <- decodeM =<< liftIO (FFI.mdNodeIsFunctionLocal p)+ if fl+ then+ return A.MetadataNode `ap` decodeM p+ else+ return A.MetadataNodeReference `ap` getMetadataNodeID p++getMetadataDefinitions :: DecodeAST [A.Definition]+getMetadataDefinitions = fix $ \continue -> do+ mdntd <- takeMetadataNodeToDefine+ flip (maybe (return [])) mdntd $ \(mid, p) -> do+ return (:)+ `ap` (return A.MetadataNodeDefinition `ap` return mid `ap` decodeM p)+ `ap` continue
+ src/LLVM/General/Internal/PassManager.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE+ TemplateHaskell,+ FlexibleInstances+ #-}++module LLVM.General.Internal.PassManager where++import qualified Language.Haskell.TH as TH++import Control.Exception+import Control.Monad+import Control.Monad.IO.Class+import Control.Applicative++import Control.Monad.AnyCont++import Foreign.Ptr++import qualified LLVM.General.Internal.FFI.PassManager as FFI+import qualified LLVM.General.Internal.FFI.Transforms as FFI++import LLVM.General.Internal.Module+import LLVM.General.Internal.Target+import LLVM.General.Internal.Coding+import LLVM.General.Transforms++-- | <http://llvm.org/doxygen/classllvm_1_1PassManager.html>+newtype PassManager = PassManager (Ptr FFI.PassManager)++-- | There are different ways to get a 'PassManager'. This class embodies them.+class PassManagerSpecification s where+ -- | make a 'PassManager'+ createPassManager :: s -> IO (Ptr FFI.PassManager)++-- | This type is a high-level specification of a set of passes. It uses the same+-- collection of passes chosen by the LLVM team in the command line tool 'opt'. The fields+-- of this spec are much like typical compiler command-line flags - e.g. -O\<n\>, etc.+data CuratedPassSetSpec = CuratedPassSetSpec {+ optLevel :: Maybe Int,+ sizeLevel :: Maybe Int,+ unitAtATime :: Maybe Bool,+ simplifyLibCalls :: Maybe Bool,+ useInlinerWithThreshold :: Maybe Int+ }++-- | Helper to make a 'CuratedPassSetSpec'+defaultCuratedPassSetSpec = CuratedPassSetSpec {+ optLevel = Nothing,+ sizeLevel = Nothing,+ unitAtATime = Nothing,+ simplifyLibCalls = Nothing,+ useInlinerWithThreshold = Nothing+ }++instance PassManagerSpecification CuratedPassSetSpec where+ createPassManager s = bracket FFI.passManagerBuilderCreate FFI.passManagerBuilderDispose $ \b -> do+ let handleOption g m = maybe (return ()) (g b . fromIntegral . fromEnum) (m s)+ handleOption FFI.passManagerBuilderSetOptLevel optLevel+ handleOption FFI.passManagerBuilderSetSizeLevel sizeLevel+ handleOption FFI.passManagerBuilderSetDisableUnitAtATime (liftM not . unitAtATime)+ handleOption FFI.passManagerBuilderSetDisableSimplifyLibCalls (liftM not . simplifyLibCalls)+ handleOption FFI.passManagerBuilderUseInlinerWithThreshold useInlinerWithThreshold+ pm <- FFI.createPassManager+ FFI.passManagerBuilderPopulateModulePassManager b pm+ return pm++data PassSetSpec = PassSetSpec [Pass] (Maybe TargetLowering)++instance PassManagerSpecification PassSetSpec where+ createPassManager (PassSetSpec ps tl') = flip runAnyContT return $ do+ let tl = maybe nullPtr (\(TargetLowering tl) -> tl) tl'+ pm <- liftIO $ FFI.createPassManager+ forM ps $ \p -> $(+ do+ TH.TyConI (TH.DataD _ _ _ cons _) <- TH.reify ''Pass+ TH.caseE [| p |] $ flip map cons $ \con -> do+ let+ (n, fns) = case con of+ TH.RecC n fs -> (n, [ TH.nameBase fn | (fn, _, _) <- fs ])+ TH.NormalC n [] -> (n, [])+ actions = + [ TH.bindS (TH.varP . TH.mkName $ fn) [| encodeM $(TH.dyn fn) |] | fn <- fns ]+ ++ [+ TH.noBindS [|+ liftIO $(+ foldl1 TH.appE+ (map TH.dyn $+ ["FFI.add" ++ TH.nameBase n ++ "Pass", "pm"]+ ++ ["tl" | FFI.needsTargetLowering (TH.nameBase n)]+ ++ fns)+ )+ |]+ ]+ TH.match (TH.conP n $ map (TH.varP . TH.mkName) fns) (TH.normalB (TH.doE actions)) []+ )+ return pm++instance PassManagerSpecification [Pass] where+ createPassManager ps = createPassManager (PassSetSpec ps Nothing)++instance PassManagerSpecification ([Pass], TargetLowering) where+ createPassManager (ps, tl) = createPassManager (PassSetSpec ps (Just tl))++-- | bracket the creation of a 'PassManager'+withPassManager :: PassManagerSpecification s => s -> (PassManager -> IO a) -> IO a+withPassManager s = bracket (createPassManager s) FFI.disposePassManager . (. PassManager)++-- | run the passes in a 'PassManager' on a 'Module', modifying the 'Module'.+runPassManager :: PassManager -> Module -> IO Bool+runPassManager (PassManager p) (Module m) = toEnum . fromIntegral <$> FFI.runPassManager p m
+ src/LLVM/General/Internal/RMWOperation.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE+ TemplateHaskell,+ MultiParamTypeClasses,+ FlexibleInstances+ #-}++module LLVM.General.Internal.RMWOperation where++import LLVM.General.AST.RMWOperation++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI++import LLVM.General.Internal.Coding++genCodingInstance' [t| RMWOperation |] ''FFI.RMWOperation [+ (FFI.rmwOperationXchg, Xchg),+ (FFI.rmwOperationAdd, Add),+ (FFI.rmwOperationSub, Sub),+ (FFI.rmwOperationAnd, And),+ (FFI.rmwOperationNand, Nand),+ (FFI.rmwOperationOr, Or),+ (FFI.rmwOperationXor, Xor),+ (FFI.rmwOperationMax, Max),+ (FFI.rmwOperationMin, Min),+ (FFI.rmwOperationUMax, UMax),+ (FFI.rmwOperationUMin, UMin)+ ]
+ src/LLVM/General/Internal/String.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE+ MultiParamTypeClasses,+ FlexibleInstances,+ UndecidableInstances+ #-}+module LLVM.General.Internal.String where++import Control.Arrow+import Control.Monad+import Foreign.C (CString, CChar)+import Foreign.Ptr+import Control.Monad.AnyCont+import Control.Monad.IO.Class++import LLVM.General.Internal.Coding++import qualified Data.ByteString as BS+import qualified Data.Text as T+import qualified Data.Text.Encoding as T++instance (MonadAnyCont IO e) => EncodeM e String CString where+ encodeM s = anyContToM (BS.useAsCString . T.encodeUtf8 . T.pack $ s)++instance (Integral i, MonadAnyCont IO e) => EncodeM e String (Ptr CChar, i) where+ encodeM s = anyContToM ((. (. second fromIntegral)) . BS.useAsCStringLen . T.encodeUtf8 . T.pack $ s)++instance (MonadIO d) => DecodeM d String CString where+ decodeM = liftIO . liftM (T.unpack . T.decodeUtf8) . BS.packCString++instance (Integral i, MonadIO d) => DecodeM d String (Ptr CChar, i) where+ decodeM = liftIO . liftM (T.unpack . T.decodeUtf8) . BS.packCStringLen . second fromIntegral
+ src/LLVM/General/Internal/Target.hs view
@@ -0,0 +1,229 @@+{-# LANGUAGE+ TemplateHaskell,+ FlexibleInstances,+ MultiParamTypeClasses,+ TupleSections,+ RecordWildCards+ #-}+module LLVM.General.Internal.Target where++import Control.Monad+import Control.Exception+import Data.Functor+import Control.Monad.IO.Class+import Control.Monad.AnyCont++import Foreign.Ptr+import Foreign.Marshal.Alloc (free)++import LLVM.General.Internal.Coding+import LLVM.General.Internal.String ()++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.General.Internal.FFI.Target as FFI++import qualified LLVM.General.Relocation as Reloc+import qualified LLVM.General.Target.Options as TO+import qualified LLVM.General.CodeModel as CodeModel+import qualified LLVM.General.CodeGenOpt as CodeGenOpt++genCodingInstance' [t| Reloc.Model |] ''FFI.RelocModel [+ (FFI.relocModelDefault, Reloc.Default),+ (FFI.relocModelStatic, Reloc.Static),+ (FFI.relocModelPIC, Reloc.PIC),+ (FFI.relocModelDynamicNoPic, Reloc.DynamicNoPIC)+ ]++genCodingInstance' [t| CodeModel.Model |] ''FFI.CodeModel [+ (FFI.codeModelDefault,CodeModel.Default),+ (FFI.codeModelJITDefault, CodeModel.JITDefault),+ (FFI.codeModelSmall, CodeModel.Small),+ (FFI.codeModelKernel, CodeModel.Kernel),+ (FFI.codeModelMedium, CodeModel.Medium),+ (FFI.codeModelLarge, CodeModel.Large)+ ]++genCodingInstance' [t| CodeGenOpt.Level |] ''FFI.CodeGenOptLevel [+ (FFI.codeGenOptLevelNone, CodeGenOpt.None),+ (FFI.codeGenOptLevelLess, CodeGenOpt.Less),+ (FFI.codeGenOptLevelDefault, CodeGenOpt.Default),+ (FFI.codeGenOptLevelAggressive, CodeGenOpt.Aggressive)+ ]++genCodingInstance' [t| TO.FloatABI |] ''FFI.FloatABIType [+ (FFI.floatABIDefault, TO.FloatABIDefault),+ (FFI.floatABISoft, TO.FloatABISoft),+ (FFI.floatABIHard, TO.FloatABIHard)+ ]++genCodingInstance' [t| TO.FloatingPointOperationFusionMode |] ''FFI.FPOpFusionMode [+ (FFI.fpOpFusionModeFast, TO.FloatingPointOperationFusionFast),+ (FFI.fpOpFusionModeStandard, TO.FloatingPointOperationFusionStandard),+ (FFI.fpOpFusionModeStrict, TO.FloatingPointOperationFusionStrict)+ ]++newtype Target = Target (Ptr FFI.Target)++-- | Find a Target given an architecture and/or a \"triple\".+-- | <http://llvm.org/doxygen/structllvm_1_1TargetRegistry.html#a3105b45e546c9cc3cf78d0f2ec18ad89>+lookupTarget :: + Maybe String -- ^ arch+ -> String -- ^ \"triple\" - e.g. x86_64-unknown-linux-gnu+ -> IO (Either String (Target, String))+lookupTarget arch triple = flip runAnyContT return $ do+ cErrorP <- alloca+ cNewTripleP <- alloca+ arch <- encodeM (maybe "" id arch)+ triple <- encodeM triple+ target <- liftIO $ FFI.lookupTarget arch triple cNewTripleP cErrorP+ let readString p = do+ s <- peek p+ r <- decodeM s+ liftIO $ free s+ return r+ if (target == nullPtr) then+ Left <$> readString cErrorP+ else+ Right . (Target target, ) <$> readString cNewTripleP++-- | <http://llvm.org/doxygen/classllvm_1_1TargetOptions.html>+newtype TargetOptions = TargetOptions (Ptr FFI.TargetOptions)++-- | bracket creation and destruction of a 'TargetOptions' object+withTargetOptions :: (TargetOptions -> IO a) -> IO a+withTargetOptions = bracket FFI.createTargetOptions FFI.disposeTargetOptions . (. TargetOptions)++-- | set all target options+pokeTargetOptions :: TO.Options -> TargetOptions -> IO ()+pokeTargetOptions hOpts (TargetOptions cOpts) = do+ mapM_ (\(c, ha) -> FFI.setTargetOptionFlag cOpts c =<< encodeM (ha hOpts)) [+ (FFI.targetOptionFlagPrintMachineCode, TO.printMachineCode),+ (FFI.targetOptionFlagNoFramePointerElim, TO.noFramePointerElimination),+ (FFI.targetOptionFlagNoFramePointerElimNonLeaf, TO.noFramePointerEliminationNonLeaf),+ (FFI.targetOptionFlagLessPreciseFPMADOption, TO.lessPreciseFloatingPointMultiplyAddOption),+ (FFI.targetOptionFlagUnsafeFPMath, TO.unsafeFloatingPointMath),+ (FFI.targetOptionFlagNoInfsFPMath, TO.noInfinitiesFloatingPointMath),+ (FFI.targetOptionFlagNoNaNsFPMath, TO.noNaNsFloatingPointMath),+ (FFI.targetOptionFlagHonorSignDependentRoundingFPMathOption, TO.honorSignDependentRoundingFloatingPointMathOption),+ (FFI.targetOptionFlagUseSoftFloat, TO.useSoftFloat),+ (FFI.targetOptionFlagNoZerosInBSS, TO.noZerosInBSS),+ (FFI.targetOptionFlagJITExceptionHandling, TO.jITExceptionHandling),+ (FFI.targetOptionFlagJITEmitDebugInfo, TO.jITEmitDebugInfo),+ (FFI.targetOptionFlagJITEmitDebugInfoToDisk, TO.jITEmitDebugInfoToDisk),+ (FFI.targetOptionFlagGuaranteedTailCallOpt, TO.guaranteedTailCallOptimization),+ (FFI.targetOptionFlagDisableTailCalls, TO.disableTailCalls),+ (FFI.targetOptionFlagEnableFastISel, TO.enableFastInstructionSelection),+ (FFI.targetOptionFlagPositionIndependentExecutable, TO.positionIndependentExecutable),+ (FFI.targetOptionFlagEnableSegmentedStacks, TO.enableSegmentedStacks),+ (FFI.targetOptionFlagUseInitArray, TO.useInitArray),+ (FFI.targetOptionFlagRealignStack, TO.realignStack) + ]+ FFI.setStackAlignmentOverride cOpts =<< encodeM (TO.stackAlignmentOverride hOpts)+ flip runAnyContT return $ do+ n <- encodeM (TO.trapFunctionName hOpts)+ liftIO $ FFI.setTrapFuncName cOpts n+ FFI.setFloatABIType cOpts =<< encodeM (TO.floatABIType hOpts)+ FFI.setAllowFPOpFusion cOpts =<< encodeM (TO.allowFloatingPointOperationFusion hOpts)+ FFI.setSSPBufferSize cOpts =<< encodeM (TO.stackSmashingProtectionBufferSize hOpts)+ +-- | get all target options+peekTargetOptions :: TargetOptions -> IO TO.Options+peekTargetOptions (TargetOptions tOpts) = do+ let gof = decodeM <=< FFI.getTargetOptionsFlag tOpts + printMachineCode+ <- gof FFI.targetOptionFlagPrintMachineCode+ noFramePointerElimination+ <- gof FFI.targetOptionFlagNoFramePointerElim+ noFramePointerEliminationNonLeaf+ <- gof FFI.targetOptionFlagNoFramePointerElimNonLeaf+ lessPreciseFloatingPointMultiplyAddOption+ <- gof FFI.targetOptionFlagLessPreciseFPMADOption+ unsafeFloatingPointMath+ <- gof FFI.targetOptionFlagUnsafeFPMath+ noInfinitiesFloatingPointMath+ <- gof FFI.targetOptionFlagNoInfsFPMath+ noNaNsFloatingPointMath+ <- gof FFI.targetOptionFlagNoNaNsFPMath+ honorSignDependentRoundingFloatingPointMathOption+ <- gof FFI.targetOptionFlagHonorSignDependentRoundingFPMathOption+ useSoftFloat+ <- gof FFI.targetOptionFlagUseSoftFloat+ noZerosInBSS+ <- gof FFI.targetOptionFlagNoZerosInBSS+ jITExceptionHandling+ <- gof FFI.targetOptionFlagJITExceptionHandling+ jITEmitDebugInfo+ <- gof FFI.targetOptionFlagJITEmitDebugInfo+ jITEmitDebugInfoToDisk+ <- gof FFI.targetOptionFlagJITEmitDebugInfoToDisk+ guaranteedTailCallOptimization+ <- gof FFI.targetOptionFlagGuaranteedTailCallOpt+ disableTailCalls+ <- gof FFI.targetOptionFlagDisableTailCalls+ enableFastInstructionSelection+ <- gof FFI.targetOptionFlagEnableFastISel+ positionIndependentExecutable+ <- gof FFI.targetOptionFlagPositionIndependentExecutable+ enableSegmentedStacks+ <- gof FFI.targetOptionFlagEnableSegmentedStacks+ useInitArray+ <- gof FFI.targetOptionFlagUseInitArray+ realignStack+ <- decodeM =<< FFI.getTargetOptionsFlag tOpts FFI.targetOptionFlagRealignStack+ stackAlignmentOverride <- decodeM =<< FFI.getStackAlignmentOverride tOpts+ trapFunctionName <- decodeM =<< FFI.getTrapFuncName tOpts+ floatABIType <- decodeM =<< FFI.getFloatABIType tOpts+ allowFloatingPointOperationFusion <- decodeM =<< FFI.getAllowFPOpFusion tOpts+ stackSmashingProtectionBufferSize <- decodeM =<< FFI.getSSPBufferSize tOpts+ return TO.Options { .. }++-- | <http://llvm.org/doxygen/classllvm_1_1TargetMachine.html>+newtype TargetMachine = TargetMachine (Ptr FFI.TargetMachine)++-- | bracket creation and destruction of a 'TargetMachine'+withTargetMachine :: + Target+ -> String -- ^ triple+ -> String -- ^ cpu+ -> String -- ^ features+ -> TargetOptions+ -> Reloc.Model+ -> CodeModel.Model+ -> CodeGenOpt.Level+ -> (TargetMachine -> IO a)+ -> IO a+withTargetMachine+ (Target target)+ triple+ cpu+ features+ (TargetOptions targetOptions)+ relocModel+ codeModel+ codeGenOptLevel = runAnyContT $ do+ triple <- encodeM triple+ cpu <- encodeM cpu+ features <- encodeM features+ relocModel <- encodeM relocModel+ codeModel <- encodeM codeModel+ codeGenOptLevel <- encodeM codeGenOptLevel+ anyContT $ bracket (+ FFI.createTargetMachine+ target+ triple+ cpu+ features+ targetOptions+ relocModel+ codeModel+ codeGenOptLevel+ )+ FFI.disposeTargetMachine+ . (. TargetMachine)++-- | <http://llvm.org/doxygen/classllvm_1_1TargetLowering.html>+newtype TargetLowering = TargetLowering (Ptr FFI.TargetLowering)++-- | get the 'TargetLowering' of a 'TargetMachine'+getTargetLowering :: TargetMachine -> IO TargetLowering+getTargetLowering (TargetMachine tm) = TargetLowering <$> FFI.getTargetLowering tm
+ src/LLVM/General/Internal/Type.hs view
@@ -0,0 +1,158 @@+{-# LANGUAGE+ QuasiQuotes,+ FlexibleInstances,+ MultiParamTypeClasses+ #-}+module LLVM.General.Internal.Type where++import Control.Applicative+import Control.Monad.State+import Control.Monad.AnyCont++import qualified Data.Set as Set++import Foreign.Ptr++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI+import qualified LLVM.General.Internal.FFI.Type as FFI++import qualified LLVM.General.AST as A+import qualified LLVM.General.AST.AddrSpace as A++import LLVM.General.Internal.Context+import LLVM.General.Internal.Coding+import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.EncodeAST++getStructure :: Ptr FFI.Type -> DecodeAST A.Type+getStructure t = scopeAnyCont $ do+ return A.StructureType + `ap` (decodeM =<< liftIO (FFI.isPackedStruct t))+ `ap` do+ n <- liftIO (FFI.countStructElementTypes t)+ ts <- allocaArray n+ liftIO $ FFI.getStructElementTypes t ts+ decodeM (n, ts)++getStructDefinitions :: DecodeAST [A.Definition]+getStructDefinitions = do+ let getStructDefinition t = do+ opaque <- decodeM =<< liftIO (FFI.structIsOpaque t)+ if opaque then return Nothing else Just <$> getStructure t+ flip fix Set.empty $ \continue done -> do+ t <- takeTypeToDefine+ flip (maybe (return [])) t $ \t -> do+ if t `Set.member` done+ then+ continue done+ else+ return (:)+ `ap` (return A.TypeDefinition `ap` getTypeName t `ap` getStructDefinition t)+ `ap` (continue $ Set.insert t done)++isArrayType :: Ptr FFI.Type -> IO Bool+isArrayType t = do+ k <- liftIO $ FFI.getTypeKind t+ return $ k == FFI.typeKindArray+ +instance Monad m => EncodeM m A.AddrSpace FFI.AddrSpace where+ encodeM (A.AddrSpace a) = return FFI.AddrSpace `ap` encodeM a++instance Monad m => DecodeM m A.AddrSpace FFI.AddrSpace where+ decodeM (FFI.AddrSpace a) = return A.AddrSpace `ap` decodeM a++instance EncodeM EncodeAST A.Type (Ptr FFI.Type) where+ encodeM f = scopeAnyCont $ do+ Context context <- gets encodeStateContext+ case f of+ A.IntegerType bits -> do+ bits <- encodeM bits+ liftIO $ FFI.intTypeInContext context bits+ A.FunctionType returnTypeAST argTypeASTs isVarArg -> do+ returnType <- encodeM returnTypeAST+ argTypes <- encodeM argTypeASTs+ isVarArg <- encodeM isVarArg+ liftIO $ FFI.functionType returnType argTypes isVarArg+ A.PointerType elementType addressSpace -> do+ e <- encodeM elementType+ a <- encodeM addressSpace+ liftIO $ FFI.pointerType e a+ A.VoidType -> liftIO $ FFI.voidTypeInContext context+ A.FloatingPointType 16 A.IEEE -> liftIO $ FFI.halfTypeInContext context+ A.FloatingPointType 32 A.IEEE -> liftIO $ FFI.floatTypeInContext context+ A.FloatingPointType 64 A.IEEE -> liftIO $ FFI.doubleTypeInContext context+ A.FloatingPointType 80 A.DoubleExtended -> liftIO $ FFI.x86FP80TypeInContext context+ A.FloatingPointType 128 A.IEEE -> liftIO $ FFI.fP128TypeInContext context+ A.FloatingPointType 128 A.PairOfFloats -> liftIO $ FFI.ppcFP128TypeInContext context+ A.FloatingPointType _ _ -> fail $ "unsupported floating point type: " ++ show f+ A.VectorType sz e -> do+ e <- encodeM e+ sz <- encodeM sz+ liftIO $ FFI.vectorType e sz+ A.ArrayType sz e -> do+ e <- encodeM e+ sz <- encodeM sz+ liftIO $ FFI.arrayType e sz+ A.StructureType packed ets -> do+ ets <- encodeM ets+ packed <- encodeM packed+ liftIO $ FFI.structTypeInContext context ets packed+ A.NamedTypeReference n -> lookupNamedType n++instance DecodeM DecodeAST A.Type (Ptr FFI.Type) where+ decodeM t = scopeAnyCont $ do+ k <- liftIO $ FFI.getTypeKind t+ case k of+ [FFI.typeKindP|Void|] -> return A.VoidType+ [FFI.typeKindP|Integer|] -> A.IntegerType <$> (decodeM =<< liftIO (FFI.getIntTypeWidth t))+ [FFI.typeKindP|Function|] -> + return A.FunctionType+ `ap` (decodeM =<< liftIO (FFI.getReturnType t))+ `ap` (do+ n <- liftIO (FFI.countParamTypes t)+ ts <- allocaArray n+ liftIO $ FFI.getParamTypes t ts+ decodeM (n, ts)+ )+ `ap` (decodeM =<< liftIO (FFI.isFunctionVarArg t))+ [FFI.typeKindP|Pointer|] ->+ return A.PointerType+ `ap` (decodeM =<< liftIO (FFI.getElementType t))+ `ap` (decodeM =<< liftIO (FFI.getPointerAddressSpace t))+ [FFI.typeKindP|Half|] -> return $ A.FloatingPointType 16 A.IEEE+ [FFI.typeKindP|Float|] -> return $ A.FloatingPointType 32 A.IEEE+ [FFI.typeKindP|Double|] -> return $ A.FloatingPointType 64 A.IEEE+ [FFI.typeKindP|FP128|] -> return $ A.FloatingPointType 128 A.IEEE+ [FFI.typeKindP|X86_FP80|] -> return $ A.FloatingPointType 80 A.DoubleExtended+ [FFI.typeKindP|PPC_FP128|] -> return $ A.FloatingPointType 128 A.PairOfFloats+ [FFI.typeKindP|Vector|] -> + return A.VectorType+ `ap` (decodeM =<< liftIO (FFI.getVectorSize t))+ `ap` (decodeM =<< liftIO (FFI.getElementType t))+ [FFI.typeKindP|Struct|] -> do+ let ifM c a b = c >>= \x -> if x then a else b+ ifM (decodeM =<< liftIO (FFI.structIsLiteral t)) + (getStructure t)+ (saveNamedType t >> return A.NamedTypeReference `ap` getTypeName t)++ [FFI.typeKindP|Array|] -> + return A.ArrayType+ `ap` (decodeM =<< liftIO (FFI.getArrayLength t))+ `ap` (decodeM =<< liftIO (FFI.getElementType t))+ _ -> error $ "unhandled type kind " ++ show k++createNamedType :: A.Name -> EncodeAST (Ptr FFI.Type)+createNamedType n = do+ Context c <- gets encodeStateContext+ n <- case n of { A.Name n -> encodeM n; _ -> return nullPtr }+ liftIO $ FFI.structCreateNamed c n+ ++setNamedType :: Ptr FFI.Type -> A.Type -> EncodeAST ()+setNamedType t (A.StructureType packed ets) = do+ ets <- encodeM ets+ packed <- encodeM packed+ liftIO $ FFI.structSetBody t ets packed++ +
+ src/LLVM/General/Internal/Value.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE+ FlexibleContexts,+ FlexibleInstances,+ MultiParamTypeClasses+ #-}+module LLVM.General.Internal.Value where++import Control.Monad.State++import Foreign.Ptr++import qualified LLVM.General.Internal.FFI.PtrHierarchy as FFI+import qualified LLVM.General.Internal.FFI.Value as FFI++import LLVM.General.Internal.Coding+import LLVM.General.Internal.DecodeAST+import LLVM.General.Internal.Type () +import LLVM.General.Internal.Constant () ++import qualified LLVM.General.AST.Type as A++typeOf :: FFI.DescendentOf FFI.Value v => Ptr v -> DecodeAST A.Type+typeOf = decodeM <=< liftIO . FFI.typeOf . FFI.upCast+
+ src/LLVM/General/Module.hs view
@@ -0,0 +1,11 @@+-- | A 'Module' holds a C++ LLVM IR module. 'Module's may be converted to or from strings or Haskell ASTs, or+-- added to an 'LLVM.General.ExecutionEngine' and so JIT compiled to get funciton pointers.+module LLVM.General.Module (+ Module,+ withModuleFromAST,+ moduleAST,+ withModuleFromString,+ moduleString+ ) where++import LLVM.General.Internal.Module
+ src/LLVM/General/PassManager.hs view
@@ -0,0 +1,19 @@+-- | A 'PassManager' holds collection of passes, to be run on 'Module's.+-- Build one with 'createPassManager':+-- +-- * from a 'CuratedPassSetSpec' if you want optimization but not to play with your compiler+--+-- * from a ['LLVM.General.Transform.Pass'] if you do want to play with your compiler+--+-- * from a (['LLVM.General.Transform.Pass'], 'LLVM.General.Target.TargetLowering') if you+-- want to provide target-specific information (e.g. instruction costs) to the few passes+-- that use it (see comments on 'LLVM.General.Transforms.Pass').+module LLVM.General.PassManager (+ PassManager,+ PassManagerSpecification,+ CuratedPassSetSpec(..), defaultCuratedPassSetSpec,+ withPassManager,+ runPassManager+ ) where++import LLVM.General.Internal.PassManager
+ src/LLVM/General/Relocation.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+-- | Relocations, used in specifying TargetMachine+module LLVM.General.Relocation where++import Data.Data++-- | <http://llvm.org/doxygen/namespacellvm_1_1Reloc.html>+data Model + = Default+ | Static+ | PIC+ | DynamicNoPIC+ deriving (Eq, Read, Show, Typeable, Data)
+ src/LLVM/General/Target.hs view
@@ -0,0 +1,13 @@+-- | A Target describes that for which code may be intended. Targets are used both during actual+-- | lowering of LLVM IR to machine code and by some optimization passes which use the target to+-- | judge costs.+module LLVM.General.Target (+ lookupTarget,+ TargetOptions,+ withTargetOptions, peekTargetOptions, pokeTargetOptions,+ withTargetMachine,+ getTargetLowering+ ) where++import LLVM.General.Internal.Target+
+ src/LLVM/General/Target/Options.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE+ DeriveDataTypeable + #-}+-- | <http://llvm.org/doxygen/classllvm_1_1TargetOptions.html>+module LLVM.General.Target.Options where++import Data.Data+import Data.Word++-- | <http://llvm.org/doxygen/namespacellvm_1_1FloatABI.html#aea077c52d84934aabf9445cef9eab2e2>+data FloatABI+ = FloatABIDefault+ | FloatABISoft+ | FloatABIHard+ deriving (Eq, Ord, Read, Show, Enum, Bounded, Typeable, Data)++-- | <http://llvm.org/doxygen/namespacellvm_1_1FPOpFusion.html#a9c71bae9f02af273833fde586d529fc5>+data FloatingPointOperationFusionMode+ = FloatingPointOperationFusionFast+ | FloatingPointOperationFusionStandard+ | FloatingPointOperationFusionStrict+ deriving (Eq, Ord, Read, Show, Enum, Bounded, Typeable, Data)++-- | The options of a 'LLVM.General.Target.TargetOptions'+-- <http://llvm.org/doxygen/classllvm_1_1TargetOptions.html>+data Options = Options {+ printMachineCode :: Bool,+ noFramePointerElimination :: Bool,+ noFramePointerEliminationNonLeaf :: Bool,+ lessPreciseFloatingPointMultiplyAddOption :: Bool,+ unsafeFloatingPointMath :: Bool,+ noInfinitiesFloatingPointMath :: Bool,+ noNaNsFloatingPointMath :: Bool,+ honorSignDependentRoundingFloatingPointMathOption :: Bool,+ useSoftFloat :: Bool,+ noZerosInBSS :: Bool,+ jITExceptionHandling :: Bool,+ jITEmitDebugInfo :: Bool,+ jITEmitDebugInfoToDisk :: Bool,+ guaranteedTailCallOptimization :: Bool,+ disableTailCalls :: Bool,+ realignStack :: Bool,+ enableFastInstructionSelection :: Bool,+ positionIndependentExecutable :: Bool,+ enableSegmentedStacks :: Bool,+ useInitArray :: Bool,+ stackAlignmentOverride :: Word32,+ trapFunctionName :: String,+ floatABIType :: FloatABI,+ allowFloatingPointOperationFusion :: FloatingPointOperationFusionMode,+ stackSmashingProtectionBufferSize :: Word32+ }+ deriving (Eq, Ord, Read, Show)+
+ src/LLVM/General/Transforms.hs view
@@ -0,0 +1,143 @@+{-# LANGUAGE+ DeriveDataTypeable+ #-}+-- | This module provides an enumeration of the various transformation (e.g. optimization) passes+-- provided by LLVM. They can be used to create a 'LLVM.General.PassManager.PassManager' to, in turn,+-- run the passes on 'LLVM.General.Module.Module's. If you don't know what passes you want, consider+-- instead using 'LLVM.General.PassManager.CuratedPassSetSpec'.+module LLVM.General.Transforms where++import Data.Data+import Data.Int+import Data.Word++-- | <http://llvm.org/docs/Passes.html#transform-passes>+-- A few passes can make use of information in a 'LLVM.General.Target.TargetLowering' if one+-- is provided to 'LLVM.General.PassManager.createPassManager'.+-- <http://llvm.org/doxygen/classllvm_1_1Pass.html>+data Pass+ -- here begin the Scalar passes+ = AggressiveDeadCodeElimination+ | BlockPlacement+ | BreakCriticalEdges+ -- | can use a 'LLVM.General.Target.TargetLowering'+ | CodeGenPrepare+ | ConstantPropagation+ | CorrelatedValuePropagation+ | DeadCodeElimination+ | DeadInstructionElimination+ | DeadStoreElimination+ | DemoteRegisterToMemory+ | EarlyCommonSubexpressionElimination+ | GlobalValueNumbering { noLoads :: Bool }+ | InductionVariableSimplify+ | InstructionCombining+ | JumpThreading+ | LoopClosedSingleStaticAssignment+ | LoopInvariantCodeMotion+ | LoopDeletion+ | LoopIdiom+ | LoopInstructionSimplify+ | LoopRotate+ -- | can use a 'LLVM.General.Target.TargetLowering'+ | LoopStrengthReduce+ | LoopUnroll { loopUnrollThreshold :: Int32, count :: Int32, allowPartial :: Int32 }+ | LoopUnswitch { optimizeForSize :: Bool }+ | LowerAtomic+ -- | can use a 'LLVM.General.Target.TargetLowering'+ | LowerInvoke { useExpensiveExceptionHandlingSupport :: Bool } + | LowerSwitch+ | LowerExpectIntrinsic+ | MemcpyOptimization+ | PromoteMemoryToRegister+ | Reassociate+ | ScalarReplacementOfAggregates { requiresDominatorTree :: Bool }+ | OldScalarReplacementOfAggregates { + oldScalarReplacementOfAggregatesThreshold :: Int32, + useDominatorTree :: Bool, + structMemberThreshold :: Int32,+ arrayElementThreshold :: Int32,+ scalarLoadThreshold :: Int32+ }+ | SparseConditionalConstantPropagation+ | SimplifyLibCalls+ | SimplifyControlFlowGraph+ | Sinking+ | TailCallElimination++ -- here begin the Interprocedural passes+ | AlwaysInline { insertLifetime :: Bool }+ | ArgumentPromotion+ | ConstantMerge+ | FunctionAttributes+ | FunctionInlining { + functionInliningThreshold :: Int32+ }+ | GlobalDeadCodeElimination+ | InternalizeFunctions { exportList :: [String] }+ | InterproceduralConstantPropagation+ | InterproceduralSparseConditionalConstantPropagation+ | MergeFunctions+ | PartialInlining+ | PruneExceptionHandling+ | StripDeadDebugInfo+ | StripDebugDeclare+ | StripNonDebugSymbols+ | StripSymbols { onlyDebugInfo :: Bool }++ -- here begin the vectorization passes+ | BasicBlockVectorize { + vectorBits :: Word32,+ vectorizeBools :: Bool,+ vectorizeInts :: Bool,+ vectorizeFloats :: Bool,+ vectorizePointers :: Bool,+ vectorizeCasts :: Bool,+ vectorizeMath :: Bool,+ vectorizeFusedMultiplyAdd :: Bool,+ vectorizeSelect :: Bool,+ vectorizeCmp :: Bool,+ vectorizeGetElementPtr :: Bool,+ vectorizeMemoryOperations :: Bool,+ alignedOnly :: Bool,+ requiredChainDepth :: Word32,+ searchLimit :: Word32,+ maxCandidatePairsForCycleCheck :: Word32,+ splatBreaksChain :: Bool,+ maxInstructions :: Word32,+ maxIterations :: Word32,+ powerOfTwoLengthsOnly :: Bool,+ noMemoryOperationBoost :: Bool,+ fastDependencyAnalysis :: Bool+ }+ | LoopVectorize+ deriving (Eq, Ord, Read, Show, Typeable, Data)++-- | Defaults for the 'BasicBlockVectorize' pass - copied from the C++ code to keep these defaults+-- constant. (The C++ defaults are modifiable through global objects used for command-line processing,+-- in a design apparently oblivious to uses of LLVM besides the standard command-line tools).+defaultVectorizeBasicBlocks = BasicBlockVectorize {+ vectorBits = 128,+ vectorizeBools = True,+ vectorizeInts = True,+ vectorizeFloats = True,+ vectorizePointers = True,+ vectorizeCasts = True,+ vectorizeMath = True,+ vectorizeFusedMultiplyAdd = True,+ vectorizeSelect = True,+ vectorizeCmp = True,+ vectorizeGetElementPtr = True,+ vectorizeMemoryOperations = True,+ alignedOnly = True,++ requiredChainDepth = 6,+ searchLimit = 400,+ maxCandidatePairsForCycleCheck = 200,+ splatBreaksChain = False,+ maxInstructions = 500,+ maxIterations = 0,+ powerOfTwoLengthsOnly = False,+ noMemoryOperationBoost = False,+ fastDependencyAnalysis = False+ }
+ test/LLVM/General/Test/Constants.hs view
@@ -0,0 +1,170 @@+module LLVM.General.Test.Constants where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import LLVM.General.Test.Support++import Control.Monad+import Data.Functor+import Data.Maybe+import Foreign.Ptr+import Data.Word++import LLVM.General.Context+import LLVM.General.Module+import LLVM.General.Diagnostic+import LLVM.General.AST+import LLVM.General.AST.Type+import LLVM.General.AST.Name+import LLVM.General.AST.AddrSpace+import qualified LLVM.General.AST.Linkage as L+import qualified LLVM.General.AST.Visibility as V+import qualified LLVM.General.AST.CallingConvention as CC+import qualified LLVM.General.AST.Attribute as A+import qualified LLVM.General.AST.Global as G+import qualified LLVM.General.AST.Constant as C+import qualified LLVM.General.AST.Float as F+import qualified LLVM.General.AST.IntegerPredicate as IPred++tests = testGroup "Constants" [+ testCase name $ strCheck mAST mStr+ | (name, type', value, str) <- [+ (+ "integer",+ IntegerType 32,+ C.Int 32 1,+ "global i32 1"+ ), (+ "wide integer",+ IntegerType 65,+ C.Int 65 1,+ "global i65 1"+ ), (+ "big wide integer",+ IntegerType 66,+ C.Int 66 20000000000000000000,+ "global i66 20000000000000000000"+ ), (+ "negative wide integer",+ IntegerType 65,+ C.Int 65 36893488147419103231,+ "global i65 -1"+ ), (+ "half",+ FloatingPointType 16 IEEE,+ C.Float (F.Half 0x1234),+ "global half 0xH1234"+ ), (+ "float",+ FloatingPointType 32 IEEE,+ C.Float (F.Single 1),+ "global float 1.000000e+00"+ ), (+ "double",+ FloatingPointType 64 IEEE,+ C.Float (F.Double 1),+ "global double 1.000000e+00"+ ), (+ "quad",+ FloatingPointType 128 IEEE,+ C.Float (F.Quadruple 0x0007000600050004 0x0003000200010000),+ "global fp128 0xL00030002000100000007000600050004" -- yes, this order is weird+ ), (+ "quad 1.0",+ FloatingPointType 128 IEEE,+ C.Float (F.Quadruple 0x3fff000000000000 0x0000000000000000),+ "global fp128 0xL00000000000000003FFF000000000000" -- yes, this order is weird+ ), (+ "x86_fp80",+ FloatingPointType 80 DoubleExtended,+ C.Float (F.X86_FP80 0x0004 0x0003000200010000),+ "global x86_fp80 0xK00040003000200010000"+{- don't know how to test this - LLVM's handling of this weird type is even weirder+ ), (+ "ppc_fp128",+ FloatingPointType 128 PairOfFloats,+ C.Float (F.PPC_FP128 0x0007000600050004 0x0003000200010000),+ "global ppc_fp128 0xM????????????????"+-}+ ), (+ "struct",+ StructureType False (replicate 2 (IntegerType 32)),+ C.Struct False (replicate 2 (C.Int 32 1)),+ "global { i32, i32 } { i32 1, i32 1 }"+ ), (+ "dataarray",+ ArrayType 3 (IntegerType 32),+ C.Array (IntegerType 32) [C.Int 32 i | i <- [1,2,1]],+ "global [3 x i32] [i32 1, i32 2, i32 1]"+ ), (+ "array",+ ArrayType 3 (StructureType False [IntegerType 32]),+ C.Array (StructureType False [IntegerType 32]) [C.Struct False [C.Int 32 i] | i <- [1,2,1]],+ "global [3 x { i32 }] [{ i32 } { i32 1 }, { i32 } { i32 2 }, { i32 } { i32 1 }]"+ ), (+ "datavector",+ VectorType 3 (IntegerType 32),+ C.Vector [C.Int 32 i | i <- [1,2,1]],+ "global <3 x i32> <i32 1, i32 2, i32 1>"+ ), (+ "binop/cast",+ IntegerType 64,+ C.Add (C.PtrToInt (C.GlobalReference (UnName 1)) (IntegerType 64)) (C.Int 64 2),+ "global i64 add (i64 ptrtoint (i32* @1 to i64), i64 2)"+ ), (+ "icmp",+ IntegerType 1,+ C.ICmp IPred.SGE (C.GlobalReference (UnName 1)) (C.GlobalReference (UnName 2)),+ "global i1 icmp sge (i32* @1, i32* @2)"+ ), (+ "getelementptr",+ PointerType (IntegerType 32) (AddrSpace 0),+ C.GetElementPtr True (C.GlobalReference (UnName 1)) [C.Int 64 27],+ "global i32* getelementptr inbounds (i32* @1, i64 27)"+ ), (+ "selectvalue",+ IntegerType 32,+ C.Select (C.PtrToInt (C.GlobalReference (UnName 1)) (IntegerType 1)) + (C.Int 32 1)+ (C.Int 32 2),+ "global i32 select (i1 ptrtoint (i32* @1 to i1), i32 1, i32 2)"+ ), (+ "extractelement",+ IntegerType 32,+ C.ExtractElement+ (C.BitCast+ (C.PtrToInt (C.GlobalReference (UnName 1)) (IntegerType 64))+ (VectorType 2 (IntegerType 32)))+ (C.Int 32 1),+ "global i32 extractelement (<2 x i32> bitcast (i64 ptrtoint (i32* @1 to i64) to <2 x i32>), i32 1)"+{-+ ), (+-- This test make llvm abort, as of llvm-3.2.+ "extractvalue",+ IntegerType 8,+ C.ExtractValue+ (C.Select (C.PtrToInt (C.GlobalReference (UnName 1)) (IntegerType 1)) + (C.Array (IntegerType 8) [C.Int 8 0])+ (C.Array (IntegerType 8) [C.Int 8 1]))+ [0],+ "global i8 extractvalue ([1 x i8] select (i1 ptrtoint (i32* @1 to i1), [1 x i8] [ i8 1 ], [1 x i8] [ i8 2 ]), 0)"+-}+ )+ ],+ let mAST = Module "<string>" Nothing Nothing [+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 0, G.type' = type', G.initializer = Just value + },+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 1, G.type' = IntegerType 32, G.initializer = Nothing + },+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 2, G.type' = IntegerType 32, G.initializer = Nothing + }+ ]+ mStr = "; ModuleID = '<string>'\n\n@0 = " ++ str ++ "\n\+ \@1 = external global i32\n\+ \@2 = external global i32\n"+ ]
+ test/LLVM/General/Test/DataLayout.hs view
@@ -0,0 +1,29 @@+module LLVM.General.Test.DataLayout where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import LLVM.General.Test.Support++import qualified Data.Set as Set++import LLVM.General.Context+import LLVM.General.Module+import LLVM.General.AST+import LLVM.General.AST.DataLayout+import qualified LLVM.General.AST.Global as G++tests = testGroup "DataLayout" [+ testCase name $ strCheck (Module "<string>" mdl Nothing []) ("; ModuleID = '<string>'\n" ++ sdl)+ | (name, mdl, sdl) <- [+ ("none",Nothing, "")+ ] ++ [+ (name, Just mdl, "target datalayout = \"" ++ sdl ++ "\"\n")+ | (name, mdl, sdl) <- [+ ("little-endian", defaultDataLayout { endianness = Just LittleEndian }, "e"),+ ("big-endian", defaultDataLayout { endianness = Just BigEndian }, "E"),+ ("native", defaultDataLayout { nativeSizes = Just (Set.fromList [8,32]) }, "n8:32")+ ]+ ]+ ]
+ test/LLVM/General/Test/ExecutionEngine.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE ForeignFunctionInterface #-}+module LLVM.General.Test.ExecutionEngine where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import Control.Monad+import Data.Functor+import Data.Maybe++import Foreign.Ptr+import Data.Word++import LLVM.General.Context+import LLVM.General.Module+import LLVM.General.ExecutionEngine+import LLVM.General.AST+import LLVM.General.AST.Type+import LLVM.General.AST.Name+import LLVM.General.AST.AddrSpace+import qualified LLVM.General.AST.IntegerPredicate as IPred++import qualified LLVM.General.AST.Linkage as L+import qualified LLVM.General.AST.Visibility as V+import qualified LLVM.General.AST.CallingConvention as CC+import qualified LLVM.General.AST.Attribute as A+import qualified LLVM.General.AST.Global as G+import qualified LLVM.General.AST.Constant as C++foreign import ccall "dynamic" mkIO32Stub :: FunPtr (Word32 -> IO Word32) -> (Word32 -> IO Word32)++tests = testGroup "ExecutionEngine" [++ testCase "runSomething" $ withContext $ \context -> withExecutionEngine context $ \executionEngine -> do+ let mAST = Module "runSomethingModule" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ Parameter (IntegerType 32) (Name "foo") []+ ],False) [] + Nothing 0+ [+ BasicBlock (UnName 0) [] (+ Do $ Ret (Just (ConstantOperand (C.Int 32 42))) []+ )+ ]+ ]+ s <- withModuleFromAST context mAST $ \m -> do+ withModuleInEngine executionEngine m $ do+ Just p <- findFunction executionEngine (Name "foo")+ (mkIO32Stub ((castPtrToFunPtr p) :: FunPtr (Word32 -> IO Word32))) 7+ s @?= Right 42+ ]
+ test/LLVM/General/Test/Global.hs view
@@ -0,0 +1,40 @@+module LLVM.General.Test.Global where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import LLVM.General.Context+import LLVM.General.Module+import LLVM.General.AST+import qualified LLVM.General.AST.Global as G++tests = testGroup "Global" [+ testGroup "Alignment" [+ testCase name $ withContext $ \context -> do+ let ast = Module "<string>" Nothing Nothing [ GlobalDefinition g ]+ Right ast' <- withModuleFromAST context ast moduleAST+ ast' @?= ast+ | a <- [0,1],+ s <- [Nothing, Just "foo"],+ g <- [+ globalVariableDefaults {+ G.name = UnName 0,+ G.type' = IntegerType 32,+ G.alignment = a,+ G.section = s+ },+ functionDefaults {+ G.returnType = VoidType,+ G.name = UnName 0,+ G.parameters = ([], False),+ G.alignment = a,+ G.section = s+ }+ ],+ let+ gn (G.Function {}) = "function"+ gn (G.GlobalVariable {}) = "variable"+ name = gn g ++ ", align " ++ show a ++ (maybe "" (" section " ++ ) s)+ ]+ ]
+ test/LLVM/General/Test/InlineAssembly.hs view
@@ -0,0 +1,76 @@+module LLVM.General.Test.InlineAssembly where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import LLVM.General.Test.Support++import LLVM.General.Context+import LLVM.General.Module++import LLVM.General.AST+import LLVM.General.AST.InlineAssembly as IA+import qualified LLVM.General.AST.Linkage as L+import qualified LLVM.General.AST.Visibility as V+import qualified LLVM.General.AST.CallingConvention as CC+import qualified LLVM.General.AST.Constant as C+import qualified LLVM.General.AST.Global as G++tests = testGroup "InlineAssembly" [+ testCase "expression" $ do+ let ast = Module "<string>" Nothing Nothing [+ GlobalDefinition $ + Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo")+ ([Parameter (IntegerType 32) (Name "x") []],False)+ [] Nothing 0 [+ BasicBlock (UnName 0) [+ UnName 1 := Call {+ isTailCall = False,+ callingConvention = CC.C,+ returnAttributes = [],+ function = Left $ InlineAssembly {+ IA.type' = FunctionType (IntegerType 32) [IntegerType 32] False,+ assembly = "bswap $0",+ constraints = "=r,r",+ hasSideEffects = False,+ alignStack = False,+ dialect = ATTDialect+ },+ arguments = [+ (LocalReference (Name "x"), [])+ ],+ functionAttributes = [],+ metadata = []+ }+ ] (+ Do $ Ret (Just (LocalReference (UnName 1))) []+ )+ ]++ ]+ s = "; ModuleID = '<string>'\n\+ \\n\+ \define i32 @foo(i32 %x) {\n\+ \ %1 = call i32 asm \"bswap $0\", \"=r,r\"(i32 %x)\n\+ \ ret i32 %1\n\+ \}\n"+ strCheck ast s,++ testCase "module" $ do+ let ast = Module "<string>" Nothing Nothing [+ ModuleInlineAssembly "foo",+ ModuleInlineAssembly "bar",+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 0,+ G.type' = IntegerType 32+ }+ ]+ s = "; ModuleID = '<string>'\n\+ \\n\+ \module asm \"foo\"\n\+ \module asm \"bar\"\n\+ \\n\+ \@0 = external global i32\n"+ strCheck ast s+ ]
+ test/LLVM/General/Test/Instructions.hs view
@@ -0,0 +1,777 @@+module LLVM.General.Test.Instructions where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import LLVM.General.Test.Support++import Control.Monad+import Data.Functor+import Data.Maybe+import Foreign.Ptr+import Data.Word++import LLVM.General.Context+import LLVM.General.Module+import LLVM.General.Diagnostic+import LLVM.General.AST+import LLVM.General.AST.Type+import LLVM.General.AST.Name+import LLVM.General.AST.AddrSpace+import qualified LLVM.General.AST.IntegerPredicate as IPred+import qualified LLVM.General.AST.FloatingPointPredicate as FPPred+import qualified LLVM.General.AST.Linkage as L+import qualified LLVM.General.AST.Visibility as V+import qualified LLVM.General.AST.CallingConvention as CC+import qualified LLVM.General.AST.Attribute as A+import qualified LLVM.General.AST.Global as G+import qualified LLVM.General.AST.Constant as C+import qualified LLVM.General.AST.RMWOperation as RMWOp++tests = testGroup "Instructions" [+ testGroup "regular" [+ testCase name $ do+ let mAST = Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (VoidType) (UnName 0) ([+ Parameter (IntegerType 32) (UnName 0) [],+ Parameter (FloatingPointType 32 IEEE) (UnName 1) [],+ Parameter (PointerType (IntegerType 32) (AddrSpace 0)) (UnName 2) [],+ Parameter (IntegerType 64) (UnName 3) [],+ Parameter (IntegerType 1) (UnName 4) [],+ Parameter (VectorType 2 (IntegerType 32)) (UnName 5) [],+ Parameter (StructureType False [IntegerType 32, IntegerType 32]) (UnName 6) []+ ],False) [] Nothing 0 [+ BasicBlock (UnName 7) [+ namedInstr+ ] (+ Do $ Ret Nothing []+ )+ ]+ ]+ mStr = "; ModuleID = '<string>'\n\+ \\n\+ \define void @0(i32, float, i32*, i64, i1, <2 x i32>, { i32, i32 }) {\n\+ \ " ++ namedInstrS ++ "\n\+ \ ret void\n\+ \}\n"+ strCheck mAST mStr+ | let a = LocalReference . UnName,+ (name, namedInstr, namedInstrS) <- (+ [+ (name, UnName 8 := instr, "%8 = " ++ instrS)+ | (name, instr, instrS) <- [+ ("add",+ Add {+ nsw = False,+ nuw = False,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "add i32 %0, %0"),+ ("nsw",+ Add {+ nsw = True,+ nuw = False,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "add nsw i32 %0, %0"),+ ("nuw",+ Add {+ nsw = False,+ nuw = True,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "add nuw i32 %0, %0"),+ ("fadd",+ FAdd {+ operand0 = a 1,+ operand1 = a 1,+ metadata = [] + },+ "fadd float %1, %1"),+ ("sub",+ Sub {+ nsw = False,+ nuw = False,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "sub i32 %0, %0"),+ ("fsub",+ FSub {+ operand0 = a 1,+ operand1 = a 1,+ metadata = [] + },+ "fsub float %1, %1"),+ ("mul",+ Mul {+ nsw = False,+ nuw = False,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "mul i32 %0, %0"),+ ("fmul",+ FMul {+ operand0 = a 1,+ operand1 = a 1,+ metadata = [] + },+ "fmul float %1, %1"),+ ("udiv",+ UDiv {+ exact = False,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "udiv i32 %0, %0"),+ ("exact",+ UDiv {+ exact = True,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "udiv exact i32 %0, %0"),+ ("sdiv",+ SDiv {+ exact = False,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "sdiv i32 %0, %0"),+ ("fdiv",+ FDiv {+ operand0 = a 1,+ operand1 = a 1,+ metadata = [] + },+ "fdiv float %1, %1"),+ ("urem",+ URem {+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "urem i32 %0, %0"),+ ("srem",+ SRem {+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "srem i32 %0, %0"),+ ("frem",+ FRem {+ operand0 = a 1,+ operand1 = a 1,+ metadata = [] + },+ "frem float %1, %1"),+ ("shl",+ Shl {+ nsw = False,+ nuw = False,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "shl i32 %0, %0"),+ ("ashr",+ AShr {+ exact = False,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "ashr i32 %0, %0"),+ ("lshr",+ LShr {+ exact = False,+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "lshr i32 %0, %0"),+ ("and",+ And {+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "and i32 %0, %0"),+ ("or",+ Or {+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "or i32 %0, %0"),+ ("xor",+ Xor {+ operand0 = a 0,+ operand1 = a 0,+ metadata = [] + },+ "xor i32 %0, %0"),++ ("alloca",+ Alloca {+ allocatedType = IntegerType 32,+ numElements = Nothing,+ alignment = 0,+ metadata = [] + },+ "alloca i32"),+ ("load",+ Load {+ volatile = False,+ address = a 2,+ maybeAtomicity = Nothing,+ alignment = 0,+ metadata = [] + },+ "load i32* %2"),+ ("volatile",+ Load {+ volatile = True,+ address = a 2,+ maybeAtomicity = Nothing,+ alignment = 0,+ metadata = [] + },+ "load volatile i32* %2"),+ ("acquire",+ Load {+ volatile = False,+ address = a 2,+ maybeAtomicity = Just (Atomicity { crossThread = True, memoryOrdering = Acquire }),+ alignment = 1,+ metadata = [] + },+ "load atomic i32* %2 acquire, align 1"),+ ("singlethread",+ Load {+ volatile = False,+ address = a 2,+ maybeAtomicity = Just (Atomicity { crossThread = False, memoryOrdering = Monotonic }),+ alignment = 1,+ metadata = [] + },+ "load atomic i32* %2 singlethread monotonic, align 1"),+ ("GEP",+ GetElementPtr {+ inBounds = False,+ address = a 2,+ indices = [ a 0 ],+ metadata = [] + },+ "getelementptr i32* %2, i32 %0"),+ ("inBounds",+ GetElementPtr {+ inBounds = True,+ address = a 2,+ indices = [ a 0 ],+ metadata = [] + },+ "getelementptr inbounds i32* %2, i32 %0"),+ ("cmpxchg",+ CmpXchg {+ volatile = False,+ address = a 2,+ expected = a 0,+ replacement = a 0,+ atomicity = Atomicity { crossThread = True, memoryOrdering = Monotonic },+ metadata = [] + },+ "cmpxchg i32* %2, i32 %0, i32 %0 monotonic"),+ ("atomicrmw",+ AtomicRMW {+ volatile = False,+ rmwOperation = RMWOp.UMax,+ address = a 2,+ value = a 0,+ atomicity = Atomicity { crossThread = True, memoryOrdering = Release },+ metadata = []+ },+ "atomicrmw umax i32* %2, i32 %0 release"),++ ("trunc",+ Trunc {+ operand0 = a 0,+ type' = IntegerType 16,+ metadata = [] + },+ "trunc i32 %0 to i16"),+ ("zext",+ ZExt {+ operand0 = a 0,+ type' = IntegerType 64,+ metadata = [] + },+ "zext i32 %0 to i64"),+ ("sext",+ SExt {+ operand0 = a 0,+ type' = IntegerType 64,+ metadata = [] + },+ "sext i32 %0 to i64"),+ ("fptoui",+ FPToUI {+ operand0 = a 1,+ type' = IntegerType 64,+ metadata = [] + },+ "fptoui float %1 to i64"),+ ("fptosi",+ FPToSI {+ operand0 = a 1,+ type' = IntegerType 64,+ metadata = [] + },+ "fptosi float %1 to i64"),+ ("uitofp",+ UIToFP {+ operand0 = a 0,+ type' = FloatingPointType 32 IEEE,+ metadata = [] + },+ "uitofp i32 %0 to float"),+ ("sitofp",+ SIToFP {+ operand0 = a 0,+ type' = FloatingPointType 32 IEEE,+ metadata = [] + },+ "sitofp i32 %0 to float"),+ ("fptrunc",+ FPTrunc {+ operand0 = a 1,+ type' = FloatingPointType 16 IEEE,+ metadata = [] + },+ "fptrunc float %1 to half"),+ ("fpext",+ FPExt {+ operand0 = a 1,+ type' = FloatingPointType 64 IEEE,+ metadata = [] + },+ "fpext float %1 to double"),+ ("ptrtoint",+ PtrToInt {+ operand0 = a 2,+ type' = IntegerType 32,+ metadata = [] + },+ "ptrtoint i32* %2 to i32"),+ ("inttoptr",+ IntToPtr {+ operand0 = a 0,+ type' = PointerType (IntegerType 32) (AddrSpace 0),+ metadata = [] + },+ "inttoptr i32 %0 to i32*"),+ ("bitcast",+ BitCast {+ operand0 = a 0,+ type' = FloatingPointType 32 IEEE,+ metadata = [] + },+ "bitcast i32 %0 to float"),+ ("select",+ Select {+ condition' = a 4,+ trueValue = a 0,+ falseValue = a 0,+ metadata = []+ },+ "select i1 %4, i32 %0, i32 %0"),+ ("vaarg",+ VAArg {+ argList = a 2,+ type' = IntegerType 16,+ metadata = []+ },+ "va_arg i32* %2, i16"),+ ("extractelement",+ ExtractElement {+ vector = a 5,+ index = a 0,+ metadata = []+ },+ "extractelement <2 x i32> %5, i32 %0"),+ ("insertelement",+ InsertElement {+ vector = a 5,+ element = a 0,+ index = a 0,+ metadata = []+ },+ "insertelement <2 x i32> %5, i32 %0, i32 %0"),+ ("shufflevector",+ ShuffleVector {+ operand0 = a 5,+ operand1 = a 5,+ mask = C.Vector [ C.Int 32 p | p <- [0..1] ],+ metadata = []+ },+ "shufflevector <2 x i32> %5, <2 x i32> %5, <2 x i32> <i32 0, i32 1>"),+ ("extractvalue",+ ExtractValue {+ aggregate = a 6,+ indices' = [0],+ metadata = []+ },+ "extractvalue { i32, i32 } %6, 0"),+ ("insertvalue",+ InsertValue {+ aggregate = a 6,+ element = a 0,+ indices' = [0],+ metadata = []+ },+ "insertvalue { i32, i32 } %6, i32 %0, 0")+ ] ++ [+ ("landingpad-" ++ n,+ LandingPad {+ type' = StructureType False [ + PointerType (IntegerType 8) (AddrSpace 0),+ IntegerType 32+ ],+ personalityFunction = ConstantOperand (C.GlobalReference (UnName 0)),+ cleanup = cp,+ clauses = cls,+ metadata = []+ },+ "landingpad { i8*, i32 } personality void (i32, float, i32*, i64, i1, <2 x i32>, { i32, i32 })* @0" ++ s)+ | (clsn,cls,clss) <- [+ ("catch",+ [Catch (C.Null (PointerType (IntegerType 8) (AddrSpace 0)))],+ "\n catch i8* null"),+ ("filter",+ [Filter (C.Null (ArrayType 1 (PointerType (IntegerType 8) (AddrSpace 0))))],+ "\n filter [1 x i8*] zeroinitializer")+ ],+ (cpn, cp, cps) <- [ ("-cleanup", True, "\n cleanup"), ("", False, "") ],+ let s = cps ++ clss+ n = clsn ++ cpn+ ] ++ [+ ("icmp-" ++ ps,+ ICmp { iPredicate = p, operand0 = a 0, operand1 = a 0, metadata = [] },+ "icmp " ++ ps ++ " i32 %0, %0")+ | (ps, p) <- [+ ("eq", IPred.EQ),+ ("ne", IPred.NE),+ ("ugt", IPred.UGT),+ ("uge", IPred.UGE),+ ("ult", IPred.ULT),+ ("ule", IPred.ULE),+ ("sgt", IPred.SGT),+ ("sge", IPred.SGE),+ ("slt", IPred.SLT),+ ("sle", IPred.SLE)+ ]+ ] ++ [+ ("fcmp-" ++ ps,+ FCmp { fpPredicate = p, operand0 = a 1, operand1 = a 1, metadata = [] },+ "fcmp " ++ ps ++ " float %1, %1")+ | (ps, p) <- [+ ("false", FPPred.False),+ ("oeq", FPPred.OEQ),+ ("ogt", FPPred.OGT),+ ("oge", FPPred.OGE),+ ("olt", FPPred.OLT),+ ("ole", FPPred.OLE),+ ("one", FPPred.ONE),+ ("ord", FPPred.ORD),+ ("uno", FPPred.UNO),+ ("ueq", FPPred.UEQ),+ ("ugt", FPPred.UGT),+ ("uge", FPPred.UGE),+ ("ult", FPPred.ULT),+ ("ule", FPPred.ULE),+ ("une", FPPred.UNE),+ ("true", FPPred.True)+ ]+ ]+ ] ++ [+ ("store",+ Do $ Store {+ volatile = False,+ address = a 0,+ value = a 2,+ maybeAtomicity = Nothing,+ alignment = 0,+ metadata = [] + },+ "store i32 %0, i32* %2"),+ ("fence",+ Do $ Fence {+ atomicity = Atomicity { crossThread = True, memoryOrdering = Acquire },+ metadata = [] + },+ "fence acquire"),+ ("call",+ Do $ Call {+ isTailCall = False,+ callingConvention = CC.C,+ returnAttributes = [],+ function = Right (ConstantOperand (C.GlobalReference (UnName 0))),+ arguments = [ (LocalReference (UnName i), []) | i <- [0..6] ],+ functionAttributes = [],+ metadata = []+ },+ "call void @0(i32 %0, float %1, i32* %2, i64 %3, i1 %4, <2 x i32> %5, { i32, i32 } %6)")+ ]+ )+ ],+ testGroup "terminators" [+ testCase name $ strCheck mAST mStr+ | (name, mAST, mStr) <- [+ (+ "ret",+ Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (VoidType) (UnName 0) ([+ ],False) [] Nothing 0+ [+ BasicBlock (UnName 0) [+ ] (+ Do $ Ret Nothing []+ )+ ]+ ],+ "; ModuleID = '<string>'\n\+ \\n\+ \define void @0() {\n\+ \ ret void\n\+ \}\n"+ ), (+ "br",+ Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (VoidType) (UnName 0) ([+ ],False) [] Nothing 0+ [+ BasicBlock (UnName 0) [] (+ Do $ Br (Name "foo") []+ ),+ BasicBlock (Name "foo") [] (+ Do $ Ret Nothing []+ )+ ]+ ],+ "; ModuleID = '<string>'\n\+ \\n\+ \define void @0() {\n\+ \ br label %foo\n\+ \\n\+ \foo: ; preds = %0\n\+ \ ret void\n\+ \}\n"+ ), (+ "condbr",+ Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (VoidType) (UnName 0) ([+ ],False) [] Nothing 0+ [+ BasicBlock (Name "bar") [] (+ Do $ CondBr (ConstantOperand (C.Int 1 1)) (Name "foo") (Name "bar") []+ ),+ BasicBlock (Name "foo") [] (+ Do $ Ret Nothing []+ )+ ]+ ],+ "; ModuleID = '<string>'\n\+ \\n\+ \define void @0() {\n\+ \bar:\n\+ \ br i1 true, label %foo, label %bar\n\+ \\n\+ \foo: ; preds = %bar\n\+ \ ret void\n\+ \}\n"+ ), (+ "switch",+ Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (VoidType) (UnName 0) ([+ ],False) [] Nothing 0+ [+ BasicBlock (UnName 0) [] (+ Do $ Switch {+ operand0' = ConstantOperand (C.Int 16 2),+ defaultDest = Name "foo",+ dests = [+ (C.Int 16 0, UnName 0),+ (C.Int 16 2, Name "foo"),+ (C.Int 16 3, UnName 0)+ ],+ metadata' = []+ }+ ),+ BasicBlock (Name "foo") [] (+ Do $ Ret Nothing []+ )+ ]+ ],+ "; ModuleID = '<string>'\n\+ \\n\+ \define void @0() {\n\+ \; <label>:0\n\+ \ switch i16 2, label %foo [\n\+ \ i16 0, label %0\n\+ \ i16 2, label %foo\n\+ \ i16 3, label %0\n\+ \ ]\n\+ \\n\+ \foo: ; preds = %0, %0\n\+ \ ret void\n\+ \}\n"+ ), (+ "indirectbr",+ Module "<string>" Nothing Nothing [+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 0,+ G.type' = PointerType (IntegerType 8) (AddrSpace 0),+ G.initializer = Just (C.BlockAddress (Name "foo") (UnName 2))+ },+ GlobalDefinition $ Function L.External V.Default CC.C [] (VoidType) (Name "foo") ([+ ],False) [] Nothing 0+ [+ BasicBlock (UnName 0) [+ UnName 1 := Load {+ volatile = False,+ address = ConstantOperand (C.GlobalReference (UnName 0)),+ maybeAtomicity = Nothing,+ alignment = 0,+ metadata = [] + }+ ] (+ Do $ IndirectBr {+ operand0' = LocalReference (UnName 1),+ possibleDests = [UnName 2],+ metadata' = []+ }+ ),+ BasicBlock (UnName 2) [] (+ Do $ Ret Nothing []+ )+ ]+ ],+-- \ indirectbr i8* null, [label %foo]\n\+ "; ModuleID = '<string>'\n\+ \\n\+ \@0 = global i8* blockaddress(@foo, %2)\n\+ \\n\+ \define void @foo() {\n\+ \ %1 = load i8** @0\n\+ \ indirectbr i8* %1, [label %2]\n\+ \\n\+ \; <label>:2 ; preds = %0\n\+ \ ret void\n\+ \}\n"+ ), (+ "invoke",+ Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (VoidType) (UnName 0) ([+ Parameter (IntegerType 32) (UnName 0) [],+ Parameter (IntegerType 16) (UnName 1) []+ ],False) [] Nothing 0+ [+ BasicBlock (UnName 2) [] (+ Do $ Invoke {+ callingConvention' = CC.C,+ returnAttributes' = [],+ function' = Right (ConstantOperand (C.GlobalReference (UnName 0))),+ arguments' = [+ (ConstantOperand (C.Int 32 4), []),+ (ConstantOperand (C.Int 16 8), [])+ ],+ functionAttributes' = [],+ returnDest = Name "foo",+ exceptionDest = Name "bar",+ metadata' = []+ }+ ),+ BasicBlock (Name "foo") [] (+ Do $ Ret Nothing []+ ),+ BasicBlock (Name "bar") [+ UnName 3 := LandingPad {+ type' = StructureType False [ + PointerType (IntegerType 8) (AddrSpace 0),+ IntegerType 32+ ],+ personalityFunction = ConstantOperand (C.GlobalReference (UnName 0)),+ cleanup = True,+ clauses = [Catch (C.Null (PointerType (IntegerType 8) (AddrSpace 0)))],+ metadata = []+ }+ ] (+ Do $ Ret Nothing []+ )+ ]+ ],+ "; ModuleID = '<string>'\n\+ \\n\+ \define void @0(i32, i16) {\n\+ \ invoke void @0(i32 4, i16 8)\n\+ \ to label %foo unwind label %bar\n\+ \\n\+ \foo: ; preds = %2\n\+ \ ret void\n\+ \\n\+ \bar: ; preds = %2\n\+ \ %3 = landingpad { i8*, i32 } personality void (i32, i16)* @0\n\+ \ cleanup\n\+ \ catch i8* null\n\+ \ ret void\n\+ \}\n"+ ), (+ "resume",+ Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (VoidType) (UnName 0) ([+ ],False) [] Nothing 0+ [+ BasicBlock (UnName 0) [] (+ Do $ Resume (ConstantOperand (C.Int 32 1)) []+ )+ ]+ ],+ "; ModuleID = '<string>'\n\+ \\n\+ \define void @0() {\n\+ \ resume i32 1\n\+ \}\n"+ ), (+ "unreachable",+ Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (VoidType) (UnName 0) ([+ ],False) [] Nothing 0+ [+ BasicBlock (UnName 0) [] (+ Do $ Unreachable []+ )+ ]+ ],+ "; ModuleID = '<string>'\n\+ \\n\+ \define void @0() {\n\+ \ unreachable\n\+ \}\n"+ )+ ]+ ]+ ]
+ test/LLVM/General/Test/Metadata.hs view
@@ -0,0 +1,138 @@+module LLVM.General.Test.Metadata where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import LLVM.General.Test.Support++import LLVM.General.AST as A+import qualified LLVM.General.AST.Linkage as L+import qualified LLVM.General.AST.Visibility as V+import qualified LLVM.General.AST.CallingConvention as CC+import qualified LLVM.General.AST.Constant as C+import LLVM.General.AST.Global as G++tests = testGroup "Metadata" [+ testCase "local" $ do+ let ast = Module "<string>" Nothing Nothing [+ GlobalDefinition $ globalVariableDefaults { G.name = UnName 0, G.type' = IntegerType 32 },+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ ],False)+ [] + Nothing 0 + [+ BasicBlock (UnName 0) [+ UnName 1 := Load {+ volatile = False,+ address = ConstantOperand (C.GlobalReference (UnName 0)),+ maybeAtomicity = Nothing,+ A.alignment = 0,+ metadata = []+ }+ ] (+ Do $ Ret (Just (ConstantOperand (C.Int 32 0))) [+ (+ "my-metadatum", + MetadataNode [+ LocalReference (UnName 1),+ MetadataStringOperand "super hyper"+ ]+ )+ ]+ )+ ]+ ]+ let s = "; ModuleID = '<string>'\n\+ \\n\+ \@0 = external global i32\n\+ \\n\+ \define i32 @foo() {\n\+ \ %1 = load i32* @0\n\+ \ ret i32 0, !my-metadatum !{i32 %1, metadata !\"super hyper\"}\n\+ \}\n"+ strCheck ast s,++ testCase "global" $ do+ let ast = Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ ],False)+ [] + Nothing 0 + [+ BasicBlock (UnName 0) [+ ] (+ Do $ Ret (Just (ConstantOperand (C.Int 32 0))) [+ ("my-metadatum", MetadataNodeReference (MetadataNodeID 0))+ ]+ )+ ],+ MetadataNodeDefinition (MetadataNodeID 0) [ ConstantOperand (C.Int 32 1) ]+ ]+ let s = "; ModuleID = '<string>'\n\+ \\n\+ \define i32 @foo() {\n\+ \ ret i32 0, !my-metadatum !0\n\+ \}\n\+ \\n\+ \!0 = metadata !{i32 1}\n"+ strCheck ast s,++ testCase "named" $ do+ let ast = Module "<string>" Nothing Nothing [+ NamedMetadataDefinition "my-module-metadata" [MetadataNodeID 0],+ MetadataNodeDefinition (MetadataNodeID 0) [ ConstantOperand (C.Int 32 1) ]+ ]+ let s = "; ModuleID = '<string>'\n\+ \\n\+ \!my-module-metadata = !{!0}\n\+ \\n\+ \!0 = metadata !{i32 1}\n"+ strCheck ast s,++ testGroup "cyclic" [+ testCase "metadata-only" $ do+ let ast = Module "<string>" Nothing Nothing [+ NamedMetadataDefinition "my-module-metadata" [MetadataNodeID 0],+ MetadataNodeDefinition (MetadataNodeID 0) [+ MetadataNodeOperand (MetadataNodeReference (MetadataNodeID 1)) + ],+ MetadataNodeDefinition (MetadataNodeID 1) [+ MetadataNodeOperand (MetadataNodeReference (MetadataNodeID 0)) + ]+ ]+ let s = "; ModuleID = '<string>'\n\+ \\n\+ \!my-module-metadata = !{!0}\n\+ \\n\+ \!0 = metadata !{metadata !1}\n\+ \!1 = metadata !{metadata !0}\n"+ strCheck ast s,++ testCase "metadata-global" $ do+ let ast = Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] VoidType (Name "foo") ([+ ],False)+ [] + Nothing 0 + [+ BasicBlock (UnName 0) [+ ] (+ Do $ Ret Nothing [ ("my-metadatum", MetadataNodeReference (MetadataNodeID 0)) ]+ )+ ],+ MetadataNodeDefinition (MetadataNodeID 0) [+ ConstantOperand (C.GlobalReference (Name "foo"))+ ]+ ]+ let s = "; ModuleID = '<string>'\n\+ \\n\+ \define void @foo() {\n\+ \ ret void, !my-metadatum !0\n\+ \}\n\+ \\n\+ \!0 = metadata !{void ()* @foo}\n"+ strCheck ast s+ ]++ ]
+ test/LLVM/General/Test/Module.hs view
@@ -0,0 +1,281 @@+module LLVM.General.Test.Module where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import LLVM.General.Test.Support++import Data.Bits+import Data.Functor++import LLVM.General.Context+import LLVM.General.Module+import LLVM.General.Diagnostic+import LLVM.General.AST+import LLVM.General.AST.AddrSpace+import qualified LLVM.General.AST.IntegerPredicate as IPred++import qualified LLVM.General.AST.Linkage as L+import qualified LLVM.General.AST.Visibility as V+import qualified LLVM.General.AST.CallingConvention as CC+import qualified LLVM.General.AST.Attribute as A+import qualified LLVM.General.AST.Global as G+import qualified LLVM.General.AST.Constant as C++handString = "; ModuleID = '<string>'\n\+ \\n\+ \%0 = type { i32, %1*, %0* }\n\+ \%1 = type opaque\n\+ \\n\+ \@0 = global i32 1\n\+ \@1 = external protected addrspace(3) global i32, section \"foo\"\n\+ \@2 = unnamed_addr global i8 2\n\+ \@3 = external global %0\n\+ \@4 = external global [4294967296 x i32]\n\+ \@.argyle = thread_local global i32 0\n\+ \\n\+ \@three = alias private i32 addrspace(3)* @1\n\+ \@two = alias i32 addrspace(3)* @three\n\+ \\n\+ \define i32 @bar() {\n\+ \ %1 = call zeroext i32 @foo(i32 inreg 1, i8 signext 4) nounwind uwtable readnone\n\+ \ ret i32 %1\n\+ \}\n\+ \\n\+ \define zeroext i32 @foo(i32 inreg %x, i8 signext %y) nounwind uwtable readnone {\n\+ \ %1 = mul nsw i32 %x, %x\n\+ \ br label %here\n\+ \\n\+ \here: ; preds = %0\n\+ \ %go = icmp eq i32 %1, %x\n\+ \ br i1 %go, label %there, label %elsewhere\n\+ \\n\+ \there: ; preds = %here\n\+ \ %2 = add nsw i32 %1, 3\n\+ \ br label %elsewhere\n\+ \\n\+ \elsewhere: ; preds = %there, %here\n\+ \ %r = phi i32 [ 2, %there ], [ 57, %here ]\n\+ \ ret i32 %r\n\+ \}\n"++handAST = Module "<string>" Nothing Nothing [+ TypeDefinition (UnName 0) (+ Just $ StructureType False [+ IntegerType 32,+ PointerType (NamedTypeReference (UnName 1)) (AddrSpace 0),+ PointerType (NamedTypeReference (UnName 0)) (AddrSpace 0)+ ]),+ TypeDefinition (UnName 1) Nothing,+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 0,+ G.type' = IntegerType 32,+ G.initializer = Just (C.Int 32 1)+ },+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 1,+ G.visibility = V.Protected,+ G.type' = IntegerType 32,+ G.addrSpace = AddrSpace 3,+ G.section = Just "foo"+ },+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 2,+ G.hasUnnamedAddr = True,+ G.type' = IntegerType 8,+ G.initializer = Just (C.Int 8 2)+ },+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 3,+ G.type' = NamedTypeReference (UnName 0)+ },+ GlobalDefinition $ globalVariableDefaults {+ G.name = UnName 4,+ G.type' = ArrayType (1 `shift` 32) (IntegerType 32)+ },+ GlobalDefinition $ globalVariableDefaults {+ G.name = Name ".argyle",+ G.type' = IntegerType 32,+ G.initializer = Just (C.Int 32 0),+ G.isThreadLocal = True+ },+ GlobalDefinition $ globalAliasDefaults {+ G.name = Name "three", + G.linkage = L.Private,+ G.type' = PointerType (IntegerType 32) (AddrSpace 3),+ G.aliasee = C.GlobalReference (UnName 1)+ },+ GlobalDefinition $ globalAliasDefaults {+ G.name = Name "two",+ G.type' = PointerType (IntegerType 32) (AddrSpace 3),+ G.aliasee = C.GlobalReference (Name "three")+ },+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "bar") ([],False) [] Nothing 0 [+ BasicBlock (UnName 0) [+ UnName 1 := Call {+ isTailCall = False,+ callingConvention = CC.C,+ returnAttributes = [A.ZeroExt],+ function = Right (ConstantOperand (C.GlobalReference (Name "foo"))),+ arguments = [+ (ConstantOperand (C.Int 32 1), [A.InReg]),+ (ConstantOperand (C.Int 8 4), [A.SignExt])+ ],+ functionAttributes = [A.NoUnwind, A.ReadNone, A.UWTable],+ metadata = []+ }+ ] (+ Do $ Ret (Just (LocalReference (UnName 1))) []+ )+ ],+ GlobalDefinition $ Function L.External V.Default CC.C [A.ZeroExt] (IntegerType 32) (Name "foo") ([+ Parameter (IntegerType 32) (Name "x") [A.InReg],+ Parameter (IntegerType 8) (Name "y") [A.SignExt]+ ],False)+ [A.NoUnwind, A.ReadNone, A.UWTable] Nothing 0 + [+ BasicBlock (UnName 0) [+ UnName 1 := Mul {+ nsw = True,+ nuw = False,+ operand0 = LocalReference (Name "x"),+ operand1 = LocalReference (Name "x"),+ metadata = []+ }+ ] (+ Do $ Br (Name "here") []+ ),+ BasicBlock (Name "here") [+ Name "go" := ICmp {+ iPredicate = IPred.EQ,+ operand0 = LocalReference (UnName 1),+ operand1 = LocalReference (Name "x"),+ metadata = []+ }+ ] (+ Do $ CondBr {+ condition = LocalReference (Name "go"),+ trueDest = Name "there",+ falseDest = Name "elsewhere",+ metadata' = []+ }+ ),+ BasicBlock (Name "there") [+ UnName 2 := Add {+ nsw = True,+ nuw = False,+ operand0 = LocalReference (UnName 1),+ operand1 = ConstantOperand (C.Int 32 3),+ metadata = []+ }+ ] (+ Do $ Br (Name "elsewhere") []+ ),+ BasicBlock (Name "elsewhere") [+ Name "r" := Phi {+ type' = IntegerType 32,+ incomingValues = [+ (ConstantOperand (C.Int 32 2), Name "there"),+ (ConstantOperand (C.Int 32 57), Name "here")+ ],+ metadata = []+ }+ ] (+ Do $ Ret (Just (LocalReference (Name "r"))) []+ )+ ]+ ]++tests = testGroup "Module" [+ testGroup "withModuleFromString" [+ testCase "basic" $ withContext $ \context -> do+ z <- withModuleFromString' context handString (const $ return 0)+ z @?= 0,+ testCase "numbering" $ withContext $ \context -> do+ let s = "@0 = global i32 3\+ \define i32 @1(i32 %x) {\n\+ \ %1 = mul i32 %x, %x\n\+ \ %2 = add i32 %1, 3\n\+ \ ret i32 %2\n\+ \}\n"+ z <- withModuleFromString' context s (const $ return 0)+ z @?= 0+ ],++ testCase "handStringIsCanonical" $ withContext $ \context -> do+ s <- withModuleFromString' context handString moduleString+ s @?= handString,++ testCase "moduleAST" $ withContext $ \context -> do+ ast <- withModuleFromString' context handString moduleAST+ ast @?= handAST,+ + testCase "withModuleFromAST" $ withContext $ \context -> do+ s <- withModuleFromAST context handAST moduleString+ s @?= Right handString,++ testCase "triple" $ withContext $ \context -> do+ let hAST = "; ModuleID = '<string>'\n\+ \target triple = \"x86_64-unknown-linux\"\n"+ ast <- withModuleFromString' context hAST moduleAST+ ast @?= defaultModule { moduleTargetTriple = Just "x86_64-unknown-linux" },++ testGroup "regression" [+ testCase "set flag on constant expr" $ withContext $ \context -> do+ let ast = Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ Parameter (IntegerType 32) (Name "x") []+ ],False)+ [] Nothing 0 + [+ BasicBlock (UnName 0) [+ UnName 1 := Mul {+ nsw = True,+ nuw = False,+ operand0 = ConstantOperand (C.Int 32 1),+ operand1 = ConstantOperand (C.Int 32 1),+ metadata = []+ }+ ] (+ Do $ Br (Name "here") []+ ),+ BasicBlock (Name "here") [+ ] (+ Do $ Ret (Just (LocalReference (UnName 1))) []+ )+ ]+ ]+ t <- withModuleFromAST context ast $ \_ -> return True+ t @?= Right True+ ],++ testGroup "failures" [+ testCase "bad block reference" $ withContext $ \context -> do+ let badAST = Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ Parameter (IntegerType 32) (Name "x") []+ ],False)+ [] Nothing 0 + [+ BasicBlock (UnName 0) [+ UnName 1 := Mul {+ nsw = True,+ nuw = False,+ operand0 = ConstantOperand (C.Int 32 1),+ operand1 = ConstantOperand (C.Int 32 1),+ metadata = []+ }+ ] (+ Do $ Br (Name "not here") []+ ),+ BasicBlock (Name "here") [+ ] (+ Do $ Ret (Just (LocalReference (UnName 1))) []+ )+ ]+ ]+ t <- withModuleFromAST context badAST $ \_ -> return True+ t @?= Left "reference to undefined block: Name \"not here\""+ ]+ ]
+ test/LLVM/General/Test/Optimization.hs view
@@ -0,0 +1,327 @@+module LLVM.General.Test.Optimization where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import Data.Functor+import qualified Data.Map as Map++import LLVM.General.Module+import LLVM.General.Context+import LLVM.General.PassManager+import LLVM.General.Transforms+import LLVM.General.Target++import LLVM.General.AST as A+import LLVM.General.AST.Type+import LLVM.General.AST.Name+import LLVM.General.AST.AddrSpace+import LLVM.General.AST.DataLayout+import qualified LLVM.General.AST.IntegerPredicate as IPred+import qualified LLVM.General.AST.Linkage as L+import qualified LLVM.General.AST.Visibility as V+import qualified LLVM.General.AST.CallingConvention as CC+import qualified LLVM.General.AST.Attribute as A+import qualified LLVM.General.AST.Global as G+import qualified LLVM.General.AST.Constant as C++import qualified LLVM.General.Relocation as R+import qualified LLVM.General.CodeModel as CM+import qualified LLVM.General.CodeGenOpt as CGO++handAST = + Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ Parameter (IntegerType 32) (Name "x") []+ ],False)+ [A.NoUnwind, A.ReadNone, A.UWTable] + Nothing 0+ [+ BasicBlock (UnName 0) [+ UnName 1 := Mul {+ nsw = False,+ nuw = False,+ operand0 = ConstantOperand (C.Int 32 6),+ operand1 = ConstantOperand (C.Int 32 7),+ metadata = []+ }+ ] (+ Do $ Br (Name "here") []+ ),+ BasicBlock (Name "here") [+ Name "go" := ICmp {+ iPredicate = IPred.EQ,+ operand0 = LocalReference (UnName 1),+ operand1 = ConstantOperand (C.Int 32 42),+ metadata = []+ }+ ] (+ Do $ CondBr {+ condition = LocalReference (Name "go"),+ trueDest = Name "take",+ falseDest = Name "done",+ metadata' = []+ }+ ),+ BasicBlock (Name "take") [+ UnName 2 := Sub {+ nsw = False,+ nuw = False,+ operand0 = LocalReference (Name "x"),+ operand1 = LocalReference (Name "x"),+ metadata = []+ }+ ] (+ Do $ Br (Name "done") []+ ),+ BasicBlock (Name "done") [+ Name "r" := Phi {+ type' = IntegerType 32,+ incomingValues = [+ (LocalReference (UnName 2), Name "take"),+ (ConstantOperand (C.Int 32 57), Name "here")+ ],+ metadata = []+ }+ ] (+ Do $ Ret (Just (LocalReference (Name "r"))) []+ )+ ]+ ]++optimize :: PassManagerSpecification s => s -> A.Module -> IO A.Module+optimize s m = do+ mOut <- withContext $ \context -> withModuleFromAST context m $ \mIn' -> do+ withPassManager s $ \pm -> runPassManager pm mIn'+ moduleAST mIn'+ either fail return mOut++tests = testGroup "Optimization" [+ testCase "curated" $ do+ mOut <- optimize defaultCuratedPassSetSpec handAST++ mOut @?= Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ Parameter (IntegerType 32) (Name "x") []+ ],False)+ [A.NoUnwind, A.ReadNone, A.UWTable] + Nothing 0 + [+ BasicBlock (Name "here") [+ ] (+ Do $ Ret (Just (ConstantOperand (C.Int 32 0))) []+ )+ ]+ ],++ testGroup "individual" [+ testCase "ConstantPropagation" $ do+ mOut <- optimize [ConstantPropagation] handAST++ mOut @?= Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ Parameter (IntegerType 32) (Name "x") []+ ],False)+ [A.NoUnwind, A.ReadNone, A.UWTable] + Nothing 0 + [+ BasicBlock (UnName 0) [] (Do $ Br (Name "here") []),+ BasicBlock (Name "here") [] (+ Do $ CondBr {+ condition = ConstantOperand (C.Int 1 1),+ trueDest = Name "take", + falseDest = Name "done",+ metadata' = []+ }+ ),+ BasicBlock (Name "take") [+ UnName 1 := Sub {+ nsw = False,+ nuw = False,+ operand0 = LocalReference (Name "x"),+ operand1 = LocalReference (Name "x"),+ metadata = []+ }+ ] (+ Do $ Br (Name "done") []+ ),+ BasicBlock (Name "done") [+ Name "r" := Phi {type' = IntegerType 32, incomingValues = [(LocalReference (UnName 1),Name "take"),(ConstantOperand (C.Int 32 57), Name "here")], metadata = []}+ ] (+ Do $ Ret (Just (LocalReference (Name "r"))) []+ )+ ]+ ],++ testCase "BasicBlockVectorization" $ do+ let+ mIn = Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (FloatingPointType 64 IEEE) (Name "foo") ([+ Parameter (FloatingPointType 64 IEEE) (Name "a1") [],+ Parameter (FloatingPointType 64 IEEE) (Name "a2") [],+ Parameter (FloatingPointType 64 IEEE) (Name "b1") [],+ Parameter (FloatingPointType 64 IEEE) (Name "b2") []+ ],False)+ [] + Nothing 0 + [+ BasicBlock (UnName 0) [+ Name "x1" := FSub { + operand0 = LocalReference (Name "a1"), + operand1 = LocalReference (Name "b1"),+ metadata = []+ },+ Name "x2" := FSub { + operand0 = LocalReference (Name "a2"), + operand1 = LocalReference (Name "b2"),+ metadata = []+ },+ Name "y1" := FMul { + operand0 = LocalReference (Name "x1"), + operand1 = LocalReference (Name "a1"),+ metadata = []+ },+ Name "y2" := FMul { + operand0 = LocalReference (Name "x2"), + operand1 = LocalReference (Name "a2"),+ metadata = []+ },+ Name "z1" := FAdd { + operand0 = LocalReference (Name "y1"), + operand1 = LocalReference (Name "b1"),+ metadata = []+ },+ Name "z2" := FAdd { + operand0 = LocalReference (Name "y2"), + operand1 = LocalReference (Name "b2"),+ metadata = []+ },+ Name "r" := FMul {+ operand0 = LocalReference (Name "z1"), + operand1 = LocalReference (Name "z2"),+ metadata = []+ }+ ] (Do $ Ret (Just (LocalReference (Name "r"))) [])+ ]+ ]+ mOut <- optimize [ + defaultVectorizeBasicBlocks {+ vectorizePointers = False,+ requiredChainDepth = 3+ },+ InstructionCombining,+ GlobalValueNumbering False+ ] mIn+ mOut @?= Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function + L.External V.Default CC.C [] (FloatingPointType 64 IEEE) (Name "foo") ([+ Parameter (FloatingPointType 64 IEEE) (Name "a1") [],+ Parameter (FloatingPointType 64 IEEE) (Name "a2") [],+ Parameter (FloatingPointType 64 IEEE) (Name "b1") [],+ Parameter (FloatingPointType 64 IEEE) (Name "b2") []+ ],False)+ []+ Nothing 0+ [+ BasicBlock (UnName 0) [+ Name "x1.v.i1.1" := InsertElement {+ vector = ConstantOperand (C.Undef (VectorType 2 (FloatingPointType 64 IEEE))),+ element = LocalReference (Name "b1"),+ index = ConstantOperand (C.Int 32 0),+ metadata = []+ },+ Name "x1.v.i1.2" := InsertElement {+ vector = LocalReference (Name "x1.v.i1.1"),+ element = LocalReference (Name "b2"),+ index = ConstantOperand (C.Int 32 1),+ metadata = []+ },+ Name "x1.v.i0.1" := InsertElement {+ vector = ConstantOperand (C.Undef (VectorType 2 (FloatingPointType 64 IEEE))),+ element = LocalReference (Name "a1"),+ index = ConstantOperand (C.Int 32 0),+ metadata = []+ },+ Name "x1.v.i0.2" := InsertElement {+ vector = LocalReference (Name "x1.v.i0.1"),+ element = LocalReference (Name "a2"),+ index = ConstantOperand (C.Int 32 1),+ metadata = []+ },+ Name "x1" := FSub {+ operand0 = LocalReference (Name "x1.v.i0.2"),+ operand1 = LocalReference (Name "x1.v.i1.2"),+ metadata = []+ },+ Name "y1" := FMul {+ operand0 = LocalReference (Name "x1"),+ operand1 = LocalReference (Name "x1.v.i0.2"),+ metadata = []+ },+ Name "z1" := FAdd {+ operand0 = LocalReference (Name "y1"),+ operand1 = LocalReference (Name "x1.v.i1.2"),+ metadata = []+ },+ Name "z1.v.r1" := ExtractElement {+ vector = LocalReference (Name "z1"),+ index = ConstantOperand (C.Int 32 0),+ metadata = []+ },+ Name "z1.v.r2" := ExtractElement {+ vector = LocalReference (Name "z1"),+ index = ConstantOperand (C.Int 32 1),+ metadata = []+ },+ Name "r" := FMul {+ operand0 = LocalReference (Name "z1.v.r1"),+ operand1 = LocalReference (Name "z1.v.r2"),+ metadata = []+ }+ ] (+ Do $ Ret (Just (LocalReference (Name "r"))) []+ )+ ]+ ],+ + testCase "LowerInvoke" $ do+ -- This test doesn't test much about what LowerInvoke does, just that it seems to work.+ -- The pass seems to be quite deeply dependent on weakly documented presumptions about+ -- how unwinding works (as is the invoke instruction)+ withContext $ \context -> do+ let triple = "x86_64-apple-darwin"+ Right (target, _) <- lookupTarget Nothing triple+ withTargetOptions $ \targetOptions -> do+ withTargetMachine target triple "" "" targetOptions+ R.Default CM.Default CGO.Default $ \targetMachine -> do+ targetLowering <- getTargetLowering targetMachine+ withPassManager ([LowerInvoke False], targetLowering) $ \passManager -> do+ let astIn = + Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ Parameter (IntegerType 32) (Name "x") []+ ],False) [] Nothing 0 [+ BasicBlock (Name "here") [+ ] (+ Do $ Ret (Just (ConstantOperand (C.Int 32 0))) []+ )+ ]+ ] + Right astOut <- withModuleFromAST context astIn $ \mIn -> do+ runPassManager passManager mIn+ moduleAST mIn+ astOut @?= Module "<string>" Nothing Nothing [+ GlobalDefinition $ Function L.External V.Default CC.C [] (IntegerType 32) (Name "foo") ([+ Parameter (IntegerType 32) (Name "x") []+ ],False) [] Nothing 0 [+ BasicBlock (Name "here") [+ ] (+ Do $ Ret (Just (ConstantOperand (C.Int 32 0))) []+ )+ ],+ GlobalDefinition $ Function L.External V.Default CC.C [] VoidType (Name "abort") ([],False)+ [] Nothing 0 []+ ]+ ]+ ]
+ test/LLVM/General/Test/Support.hs view
@@ -0,0 +1,27 @@+module LLVM.General.Test.Support where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import Data.Functor++import LLVM.General.Context+import LLVM.General.Module+import LLVM.General.Diagnostic++withModuleFromString' c s f = do+ e <- withModuleFromString c s f+ case e of+ Right r -> return r+ Left d -> do+ let e = diagnosticDisplay d+ putStrLn e+ fail e++strCheck mAST mStr = withContext $ \context -> do+ a <- withModuleFromString' context mStr moduleAST+ s <- either error id <$> withModuleFromAST context mAST moduleString+ (a,s) @?= (mAST, mStr)++
+ test/LLVM/General/Test/Target.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE+ RecordWildCards+ #-}+module LLVM.General.Test.Target where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit+import Test.Framework.Providers.QuickCheck2+import Test.QuickCheck+import Test.QuickCheck.Property++import Control.Monad++import LLVM.General.Target+import LLVM.General.Target.Options++instance Arbitrary FloatABI where+ arbitrary = elements [minBound .. maxBound]++instance Arbitrary FloatingPointOperationFusionMode where+ arbitrary = elements [minBound .. maxBound]++instance Arbitrary Options where+ arbitrary = do+ printMachineCode <- arbitrary+ noFramePointerElimination <- arbitrary+ noFramePointerEliminationNonLeaf <- arbitrary+ lessPreciseFloatingPointMultiplyAddOption <- arbitrary+ unsafeFloatingPointMath <- arbitrary+ noInfinitiesFloatingPointMath <- arbitrary+ noNaNsFloatingPointMath <- arbitrary+ honorSignDependentRoundingFloatingPointMathOption <- arbitrary+ useSoftFloat <- arbitrary+ noZerosInBSS <- arbitrary+ jITExceptionHandling <- arbitrary+ jITEmitDebugInfo <- arbitrary+ jITEmitDebugInfoToDisk <- arbitrary+ guaranteedTailCallOptimization <- arbitrary+ disableTailCalls <- arbitrary+ realignStack <- arbitrary+ enableFastInstructionSelection <- arbitrary+ positionIndependentExecutable <- arbitrary+ enableSegmentedStacks <- arbitrary+ useInitArray <- arbitrary+ stackAlignmentOverride <- arbitrary+ trapFunctionName <- elements [ "foo", "bar", "baz" ]+ floatABIType <- arbitrary+ allowFloatingPointOperationFusion <- arbitrary+ stackSmashingProtectionBufferSize <- arbitrary+ return Options { .. }++tests = testGroup "Target" [+ testGroup "Options" [+ testGroup "regressions" [+ testCase "hurm" $ do+ withTargetOptions $ \to -> do+ let o = Options {printMachineCode = True, noFramePointerElimination = False, noFramePointerEliminationNonLeaf = True, lessPreciseFloatingPointMultiplyAddOption = True, unsafeFloatingPointMath = True, noInfinitiesFloatingPointMath = True, noNaNsFloatingPointMath = False, honorSignDependentRoundingFloatingPointMathOption = True, useSoftFloat = True, noZerosInBSS = False, jITExceptionHandling = True, jITEmitDebugInfo = True, jITEmitDebugInfoToDisk = False, guaranteedTailCallOptimization = False, disableTailCalls = False, realignStack = False, enableFastInstructionSelection = True, positionIndependentExecutable = True, enableSegmentedStacks = False, useInitArray = True, stackAlignmentOverride = 9432851444, trapFunctionName = "baz", floatABIType = FloatABISoft, allowFloatingPointOperationFusion = FloatingPointOperationFusionStrict, stackSmashingProtectionBufferSize = 2650013862}+ pokeTargetOptions o to+ o' <- peekTargetOptions to+ o' @?= o+ ],+ testProperty "basic" $ \options -> morallyDubiousIOProperty $ do+ withTargetOptions $ \to -> do+ pokeTargetOptions options to+ options' <- peekTargetOptions to+ return $ options == options'+ ]+ ]
+ test/LLVM/General/Test/Tests.hs view
@@ -0,0 +1,28 @@+module LLVM.General.Test.Tests where++import Test.Framework++import qualified LLVM.General.Test.Constants as Constants+import qualified LLVM.General.Test.DataLayout as DataLayout+import qualified LLVM.General.Test.ExecutionEngine as ExecutionEngine+import qualified LLVM.General.Test.Global as Global+import qualified LLVM.General.Test.InlineAssembly as InlineAssembly+import qualified LLVM.General.Test.Instructions as Instructions+import qualified LLVM.General.Test.Metadata as Metadata+import qualified LLVM.General.Test.Module as Module+import qualified LLVM.General.Test.Optimization as Optimization+import qualified LLVM.General.Test.Target as Target+++tests = testGroup "llvm-general" [+ Constants.tests,+ DataLayout.tests,+ ExecutionEngine.tests,+ Global.tests,+ InlineAssembly.tests,+ Instructions.tests,+ Metadata.tests,+ Module.tests,+ Optimization.tests,+ Target.tests+ ]
+ test/Test.hs view
@@ -0,0 +1,6 @@+import Test.Framework+import qualified LLVM.General.Test.Tests as LLVM.General++main = defaultMain [+ LLVM.General.tests+ ]