llvm-general 3.2.4.5 → 3.2.4.6
raw patch · 8 files changed
+124/−6 lines, 8 files
Files
- llvm-general.cabal +5/−3
- src/LLVM/General/Internal/FFI/LLVMCTypes.hsc +7/−0
- src/LLVM/General/Internal/FFI/Module.h +8/−0
- src/LLVM/General/Internal/FFI/Module.hs +3/−0
- src/LLVM/General/Internal/Module.hs +23/−1
- src/LLVM/General/Module.hs +3/−1
- test/LLVM/General/Test/Linking.hs +72/−0
- test/LLVM/General/Test/Tests.hs +3/−1
llvm-general.cabal view
@@ -1,5 +1,5 @@ name: llvm-general-version: 3.2.4.5+version: 3.2.4.6 license: BSD3 license-file: LICENSE author: Benjamin S.Scarlet <fgthb0@greynode.net>@@ -16,13 +16,14 @@ 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. .- For haddock, see <http://bscarlet.github.io/llvm-general/3.2.4.5/doc/html/llvm-general/index.html>.+ For haddock, see <http://bscarlet.github.io/llvm-general/3.2.4.6/doc/html/llvm-general/index.html>. extra-source-files: src/LLVM/General/Internal/FFI/Analysis.h src/LLVM/General/Internal/FFI/Function.h src/LLVM/General/Internal/FFI/GlobalValue.h src/LLVM/General/Internal/FFI/InlineAssembly.h src/LLVM/General/Internal/FFI/Instruction.h+ src/LLVM/General/Internal/FFI/Module.h src/LLVM/General/Internal/FFI/SMDiagnostic.h src/LLVM/General/Internal/FFI/Target.h src/LLVM/General/Internal/FFI/Type.h@@ -36,7 +37,7 @@ type: git location: git://github.com/bscarlet/llvm-general.git branch: llvm-3.2- tag: v3.2.4.5+ tag: v3.2.4.6 flag shared-llvm description: link against llvm shared rather than static library@@ -218,6 +219,7 @@ LLVM.General.Test.Global LLVM.General.Test.InlineAssembly LLVM.General.Test.Instructions+ LLVM.General.Test.Linking LLVM.General.Test.Metadata LLVM.General.Test.Module LLVM.General.Test.Optimization
src/LLVM/General/Internal/FFI/LLVMCTypes.hsc view
@@ -9,6 +9,7 @@ #include "llvm-c/Core.h" #include "llvm-c/Target.h" #include "llvm-c/TargetMachine.h"+#include "llvm-c/Linker.h" #include "LLVM/General/Internal/FFI/Instruction.h" #include "LLVM/General/Internal/FFI/Value.h" #include "LLVM/General/Internal/FFI/SMDiagnostic.h"@@ -18,6 +19,7 @@ #include "LLVM/General/Internal/FFI/GlobalValue.h" #include "LLVM/General/Internal/FFI/Type.h" #include "LLVM/General/Internal/FFI/Analysis.h"+#include "LLVM/General/Internal/FFI/Module.h" import Language.Haskell.TH.Quote @@ -190,3 +192,8 @@ deriving (Eq, Read, Show, Bits, Typeable, Data, Num) #define VFA_Rec(n) { #n, LLVM ## n ## Action }, #{inject VERIFIER_FAILURE_ACTION, VerifierFailureAction, VerifierFailureAction, verifierFailureAction, VFA_Rec}++newtype LinkerMode = LinkerMode CUInt+ deriving (Eq, Read, Show, Bits, Typeable, Data, Num)+#define LM_Rec(n) { #n, LLVMLinker ## n },+#{inject LINKER_MODE, LinkerMode, LinkerMode, linkerMode, LM_Rec}
+ src/LLVM/General/Internal/FFI/Module.h view
@@ -0,0 +1,8 @@+#ifndef __LLVM_GENERAL_INTERNAL_FFI__MODULE__H__+#define __LLVM_GENERAL_INTERNAL_FFI__MODULE__H__++#define LLVM_GENERAL_FOR_EACH_LINKER_MODE(macro) \+ macro(DestroySource) \+ macro(PreserveSource) ++#endif
src/LLVM/General/Internal/FFI/Module.hs view
@@ -88,3 +88,6 @@ foreign import ccall unsafe "LLVM_General_WriteBitcodeToFile" writeBitcodeToFile :: Ptr Module -> CString -> Ptr MallocedCString -> IO LLVMBool++foreign import ccall unsafe "LLVMLinkModules" linkModules ::+ Ptr Module -> Ptr Module -> LinkerMode -> Ptr MallocedCString -> IO LLVMBool
src/LLVM/General/Internal/Module.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE- ScopedTypeVariables+ TemplateHaskell,+ ScopedTypeVariables,+ MultiParamTypeClasses #-} -- | This Haskell module is for/of functions for handling LLVM modules. module LLVM.General.Internal.Module where@@ -56,6 +58,26 @@ instance Error (Either String Diagnostic) where strMsg = Left++genCodingInstance' [t| Bool |] ''FFI.LinkerMode [+ (FFI.linkerModeDestroySource, False),+ (FFI.linkerModePreserveSource, True)+ ]++-- | link LLVM modules - move or copy parts of a source module into a destination module.+-- Note that this operation is not commutative - not only concretely (e.g. the destination module+-- is modified, becoming the result) but abstractly (e.g. unused private globals in the source+-- module do not appear in the result, but similar globals in the destination remain).+linkModules :: + Bool -- ^ True to leave the right module unmodified, False to cannibalize it (for efficiency's sake).+ -> Module -- ^ The module into which to link+ -> Module -- ^ The module to link into the other (and cannibalize or not)+ -> ErrorT String IO ()+linkModules preserveRight (Module m) (Module m') = flip runAnyContT return $ do+ preserveRight <- encodeM preserveRight+ msgPtr <- alloca+ result <- decodeM =<< (liftIO $ FFI.linkModules m m' preserveRight msgPtr)+ when result $ fail =<< decodeM msgPtr -- | parse 'Module' from LLVM assembly withModuleFromString :: Context -> String -> (Module -> IO a) -> ErrorT (Either String Diagnostic) IO a
src/LLVM/General/Module.hs view
@@ -9,7 +9,9 @@ writeBitcodeToFile, writeAssemblyToFile,- writeObjectToFile+ writeObjectToFile,++ linkModules ) where import LLVM.General.Internal.Module
+ test/LLVM/General/Test/Linking.hs view
@@ -0,0 +1,72 @@+module LLVM.General.Test.Linking where++import Test.Framework+import Test.Framework.Providers.HUnit+import Test.HUnit++import LLVM.General.Test.Support++import Control.Monad.Error+import Data.Functor+import qualified Data.Set as Set+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++optimize :: PassManagerSpecification s => s -> A.Module -> IO A.Module+optimize s m = withContext $ \context -> withModuleFromAST' context m $ \mIn' -> do+ withPassManager s $ \pm -> runPassManager pm mIn'+ moduleAST mIn'++tests = testGroup "Linking" [+ testCase "basic" $ do+ let + ast0 = Module "<string>" Nothing Nothing [+ GlobalDefinition $ functionDefaults {+ G.linkage = L.Private,+ G.returnType = IntegerType 32,+ G.name = Name "private0"+ },+ GlobalDefinition $ functionDefaults {+ G.linkage = L.External,+ G.returnType = IntegerType 32,+ G.name = Name "external0"+ }+ ]+ ast1 = Module "<string>" Nothing Nothing [+ GlobalDefinition $ functionDefaults {+ G.linkage = L.Private,+ G.returnType = IntegerType 32,+ G.name = Name "private1"+ },+ GlobalDefinition $ functionDefaults {+ G.linkage = L.External,+ G.returnType = IntegerType 32,+ G.name = Name "external1"+ }+ ] ++ Module { moduleDefinitions = defs } <- withContext $ \context -> + withModuleFromAST' context ast0 $ \m0 ->+ withModuleFromAST' context ast1 $ \m1 -> do+ runErrorT $ linkModules False m0 m1+ moduleAST m0+ [ n | GlobalDefinition g <- defs, let Name n = G.name g ] @?= [ "private0", "external0", "external1" ]+ ]
test/LLVM/General/Test/Tests.hs view
@@ -14,6 +14,7 @@ import qualified LLVM.General.Test.Target as Target import qualified LLVM.General.Test.Analysis as Analysis import qualified LLVM.General.Test.PrettyPrint as PrettyPrint+import qualified LLVM.General.Test.Linking as Linking tests = testGroup "llvm-general" [ Constants.tests,@@ -27,5 +28,6 @@ Optimization.tests, Target.tests, Analysis.tests,- PrettyPrint.tests+ PrettyPrint.tests,+ Linking.tests ]