packages feed

llvm-general 3.4.1.0 → 3.4.2.0

raw patch · 14 files changed

+288/−126 lines, 14 filesdep ~llvm-generaldep ~llvm-general-pure

Dependency ranges changed: llvm-general, llvm-general-pure

Files

llvm-general.cabal view
@@ -1,5 +1,5 @@ name: llvm-general-version: 3.4.1.0+version: 3.4.2.0 license: BSD3 license-file: LICENSE author: Benjamin S.Scarlet <fgthb0@greynode.net>@@ -16,7 +16,7 @@ 	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.4.1.0/doc/html/llvm-general/index.html>.+  For haddock, see <http://bscarlet.github.io/llvm-general/3.4.2.0/doc/html/llvm-general/index.html>. extra-source-files:   src/LLVM/General/Internal/FFI/Analysis.h   src/LLVM/General/Internal/FFI/Constant.h@@ -56,7 +56,7 @@     parsec >= 3.1.3,     array >= 0.4.0.0,     setenv >= 0.1.0,-    llvm-general-pure == 3.4.1.0+    llvm-general-pure == 3.4.2.0   extra-libraries: stdc++   hs-source-dirs: src   extensions:@@ -80,6 +80,7 @@     LLVM.General.PassManager     LLVM.General.Relocation     LLVM.General.Target+    LLVM.General.Target.LibraryFunction     LLVM.General.Target.Options     LLVM.General.Transforms @@ -108,6 +109,7 @@     LLVM.General.Internal.Instruction     LLVM.General.Internal.InstructionDefs     LLVM.General.Internal.IntegerPredicate+    LLVM.General.Internal.LibraryFunction     LLVM.General.Internal.MemoryBuffer     LLVM.General.Internal.Metadata     LLVM.General.Internal.Module@@ -188,8 +190,8 @@     HUnit >= 1.2.4.2,     test-framework-quickcheck2 >= 0.3.0.1,     QuickCheck >= 2.5.1.1,-    llvm-general == 3.4.1.0,-    llvm-general-pure == 3.4.1.0,+    llvm-general == 3.4.2.0,+    llvm-general-pure == 3.4.2.0,     containers >= 0.4.2.1,     mtl >= 2.0.1.0   hs-source-dirs: test
src/LLVM/General/Internal/FFI/LLVMCTypes.hsc view
@@ -21,6 +21,7 @@ #include "LLVM/General/Internal/FFI/Constant.h" #include "LLVM/General/Internal/FFI/Analysis.h" #include "LLVM/General/Internal/FFI/Module.h"+#include "LLVM/General/Internal/FFI/LibFunc.h"  import Language.Haskell.TH.Quote @@ -209,3 +210,8 @@   deriving (Eq, Read, Show, Bits, Typeable, Data, Num) #define LM_Rec(n) { #n, LLVMLinker ## n }, #{inject LINKER_MODE, LinkerMode, LinkerMode, linkerMode, LM_Rec}++newtype LibFunc = LibFunc CUInt+  deriving (Eq, Read, Show, Bits, Typeable, Data, Num, Storable)+#define LF_Rec(n) { #n, LLVMLibFunc__ ## n },+#{inject LIB_FUNC, LibFunc, LibFunc, libFunc__, LF_Rec}
src/LLVM/General/Internal/FFI/PassManager.hs view
@@ -52,6 +52,9 @@  addDataLayoutPass = flip addDataLayoutPass' +foreign import ccall unsafe "LLVM_General_LLVMAddAnalysisPasses" addAnalysisPasses ::+  Ptr TargetMachine -> Ptr PassManager -> IO ()+ foreign import ccall unsafe "LLVMAddTargetLibraryInfo" addTargetLibraryInfoPass' ::   Ptr TargetLibraryInfo -> Ptr PassManager -> IO () @@ -123,3 +126,6 @@  foreign import ccall unsafe "LLVMPassManagerBuilderPopulateLTOPassManager" passManagerBuilderPopulateLTOPassManager ::     Ptr PassManagerBuilder -> Ptr PassManager -> CUChar -> CUChar -> IO () ++foreign import ccall unsafe "LLVM_General_PassManagerBuilderSetLibraryInfo" passManagerBuilderSetLibraryInfo ::+    Ptr PassManagerBuilder -> Ptr TargetLibraryInfo -> IO ()
src/LLVM/General/Internal/FFI/PassManagerC.cpp view
@@ -6,6 +6,10 @@ #include "llvm/Transforms/Vectorize.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/PassManager.h"+#include "llvm-c/Target.h"+#include "llvm-c/Transforms/PassManagerBuilder.h"+#include "llvm/Target/TargetLibraryInfo.h"+#include "llvm/Target/TargetMachine.h"  #include "llvm-c/Core.h" @@ -33,14 +37,28 @@ inline LLVMTargetMachineRef wrap(const TargetMachine *P) { 	return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P)); }++// Taken from llvm/lib/Target/Target.cpp+inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {+  return reinterpret_cast<TargetLibraryInfo*>(P); } +// Taken from llvm/lib/Transforms/IPO/PassManagerBuilder.cpp+inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {+    return reinterpret_cast<PassManagerBuilder*>(P);+}+}+ extern "C" {  void LLVM_General_AddDataLayoutPass(LLVMPassManagerRef PM, const char *dl) { 	unwrap(PM)->add(new DataLayout(dl)); } +void LLVM_General_LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {+	unwrap(T)->addAnalysisPasses(*unwrap(PM));+}+ #define LLVM_GENERAL_FOR_EACH_PASS_WITHOUT_LLVM_C_BINDING(macro) \ 	macro(BreakCriticalEdges) \ 	macro(DeadCodeElimination) \@@ -226,6 +244,16 @@  void LLVM_General_AddDebugExistingIRPass(LLVMPassManagerRef PM) { 	unwrap(PM)->add(createDebugIRPass());+}++void+LLVM_General_PassManagerBuilderSetLibraryInfo(+    LLVMPassManagerBuilderRef PMB,+    LLVMTargetLibraryInfoRef l+) {+  // The PassManager frees the TargetLibraryInfo when done,+  // but we also free our ref, so give it a new copy.+  unwrap(PMB)->LibraryInfo = new TargetLibraryInfo(*unwrap(l)); }  }
src/LLVM/General/Internal/FFI/Target.hs view
@@ -106,6 +106,15 @@ foreign import ccall unsafe "LLVM_General_CreateTargetLibraryInfo" createTargetLibraryInfo ::   CString -> IO (Ptr TargetLibraryInfo) +foreign import ccall unsafe "LLVM_General_GetLibFunc" getLibFunc ::+  Ptr TargetLibraryInfo -> CString -> Ptr LibFunc -> IO LLVMBool++foreign import ccall unsafe "LLVM_General_LibFuncGetName" libFuncGetName ::+  Ptr TargetLibraryInfo -> LibFunc -> Ptr CSize -> IO CString++foreign import ccall unsafe "LLVM_General_LibFuncSetAvailableWithName" libFuncSetAvailableWithName ::+  Ptr TargetLibraryInfo -> LibFunc -> CString -> IO ()+ foreign import ccall unsafe "LLVM_General_DisposeTargetLibraryInfo" disposeTargetLibraryInfo ::   Ptr TargetLibraryInfo -> IO () 
src/LLVM/General/Internal/FFI/TargetC.cpp view
@@ -14,6 +14,7 @@ #include "llvm-c/TargetMachine.h" #include "llvm-c/Core.h" #include "LLVM/General/Internal/FFI/Target.h"+#include "LLVM/General/Internal/FFI/LibFunc.h"  using namespace llvm; @@ -74,6 +75,24 @@ 	} } +static LibFunc::Func unwrap(LLVMLibFunc x) {+	switch(x) {+#define ENUM_CASE(x) case LLVMLibFunc__ ## x: return LibFunc::x;+LLVM_GENERAL_FOR_EACH_LIB_FUNC(ENUM_CASE)+#undef ENUM_CASE+	default: return LibFunc::Func(0);+	}+}++static LLVMLibFunc wrap(LibFunc::Func x) {+	switch(x) {+#define ENUM_CASE(x) case LibFunc::x : return LLVMLibFunc__ ## x;+LLVM_GENERAL_FOR_EACH_LIB_FUNC(ENUM_CASE)+#undef ENUM_CASE+	default: return LLVMLibFunc(0);+	}+}+ static LLVM_General_FloatABI wrap(FloatABI::ABIType x) { 	switch(x) { #define ENUM_CASE(x) case FloatABI::x: return LLVM_General_FloatABI_ ## x;@@ -260,6 +279,35 @@ 	const char *triple ) { 	return wrap(new TargetLibraryInfo(Triple(triple)));+}++LLVMBool LLVM_General_GetLibFunc(+	LLVMTargetLibraryInfoRef l,+	const char *funcName,+	LLVMLibFunc *f+) {+	LibFunc::Func func;+	LLVMBool result = unwrap(l)->getLibFunc(funcName, func);+	*f = wrap(func);+	return result;+}++const char *LLVM_General_LibFuncGetName(+	LLVMTargetLibraryInfoRef l,+	LLVMLibFunc f,+	size_t *nameSize+) {+	StringRef s = unwrap(l)->getName(unwrap(f));+	*nameSize = s.size();+	return s.data();+}++void LLVM_General_LibFuncSetAvailableWithName(+	LLVMTargetLibraryInfoRef l,+	LLVMLibFunc f,+	const char *name+) {+	unwrap(l)->setAvailableWithName(unwrap(f), name); }  void LLVM_General_DisposeTargetLibraryInfo(LLVMTargetLibraryInfoRef l) {
+ src/LLVM/General/Internal/LibraryFunction.hsc view
@@ -0,0 +1,35 @@+{-# LANGUAGE+  MultiParamTypeClasses+ #-}+module LLVM.General.Internal.LibraryFunction where++import qualified LLVM.General.Internal.FFI.LLVMCTypes as FFI++import LLVM.General.Internal.Coding++#include "LLVM/General/Internal/FFI/LibFunc.h"++#{+define hsc_inject(m) { \+  struct { const char *s; unsigned n; } *p, list[] = { LLVM_GENERAL_FOR_EACH_LIB_FUNC(m) }; \+  hsc_printf("data LibraryFunction\n"); \+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+    hsc_printf("  %s LF__%s\n", (p == list ? "=" : "|"), p->s); \+  } \+  hsc_printf("  deriving (Eq, Ord, Enum, Bounded, Read, Show)"); \+  hsc_printf("\n"); \+  hsc_printf("instance Monad m => EncodeM m LibraryFunction FFI.LibFunc where\n"); \+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+    hsc_printf("  encodeM LF__%s = return (FFI.LibFunc %u)\n", p->s, p->n); \+  } \+  hsc_printf("\n"); \+  hsc_printf("instance Monad m => DecodeM m LibraryFunction FFI.LibFunc where\n"); \+  for(p = list; p < list + sizeof(list)/sizeof(list[0]); ++p) { \+    hsc_printf("  decodeM (FFI.LibFunc %u) = return LF__%s \n", p->n, p->s); \+  } \+}+}++-- | <http://llvm.org/doxygen/namespacellvm_1_1LibFunc.html#abf8f6830387f338fed0bce2e65108c6f>+#define Mac(n) { #n, LLVMLibFunc__ ## n },+#{inject Mac}
src/LLVM/General/Internal/Module.hs view
@@ -65,6 +65,7 @@ -- | <http://llvm.org/doxygen/classllvm_1_1Module.html> newtype Module = Module (Ptr FFI.Module) +-- | A newtype to distinguish strings used for paths from other strings newtype File = File FilePath   deriving (Eq, Ord, Read, Show) 
src/LLVM/General/Internal/PassManager.hs view
@@ -54,7 +54,8 @@       sizeLevel :: Maybe Word,       unitAtATime :: Maybe Bool,       simplifyLibCalls :: Maybe Bool,-      useInlinerWithThreshold :: Maybe Word+      useInlinerWithThreshold :: Maybe Word,+      curatedTargetLibraryInfo :: Maybe TargetLibraryInfo     }  -- | Helper to make a curated 'PassSetSpec'@@ -63,7 +64,8 @@   sizeLevel = Nothing,   unitAtATime = Nothing,   simplifyLibCalls = Nothing,-  useInlinerWithThreshold = Nothing+  useInlinerWithThreshold = Nothing,+  curatedTargetLibraryInfo = Nothing }  -- | an empty 'PassSetSpec'@@ -89,12 +91,16 @@         handleOption FFI.passManagerBuilderSetDisableUnitAtATime (liftM not . unitAtATime)         handleOption FFI.passManagerBuilderSetDisableSimplifyLibCalls (liftM not . simplifyLibCalls)         handleOption FFI.passManagerBuilderUseInlinerWithThreshold useInlinerWithThreshold+        case (curatedTargetLibraryInfo s) of+          (Just (TargetLibraryInfo tl)) -> FFI.passManagerBuilderSetLibraryInfo b tl+          Nothing -> return ()         FFI.passManagerBuilderPopulateModulePassManager b pm     PassSetSpec ps dl tli tm' -> do       let tm = maybe nullPtr (\(TargetMachine tm) -> tm) tm'       forM_ tli $ \(TargetLibraryInfo tli) -> do         liftIO $ FFI.addTargetLibraryInfoPass pm tli       forM_ dl $ \dl -> liftIO $ withFFIDataLayout dl $ FFI.addDataLayoutPass pm +      forM_ tm' $ \(TargetMachine tm) -> liftIO $ FFI.addAnalysisPasses tm pm       forM_ ps $ \p -> $(         do           TH.TyConI (TH.DataD _ _ _ cons _) <- TH.reify ''Pass
src/LLVM/General/Internal/Target.hs view
@@ -6,10 +6,11 @@   #-} module LLVM.General.Internal.Target where -import Control.Monad-import Control.Monad.Error+import Control.Monad hiding (forM)+import Control.Monad.Error hiding (forM) import Control.Exception import Data.Functor+import Data.Traversable (forM) import Control.Monad.AnyCont import Data.Maybe @@ -20,6 +21,7 @@  import LLVM.General.Internal.Coding import LLVM.General.Internal.String ()+import LLVM.General.Internal.LibraryFunction import LLVM.General.DataLayout  import LLVM.General.AST.DataLayout@@ -260,7 +262,7 @@ initializeAllTargets :: IO () initializeAllTargets = FFI.initializeAllTargets --- | Bracket creation and destruction of a TargetMachine configured for the host+-- | Bracket creation and destruction of a 'TargetMachine' configured for the host withDefaultTargetMachine :: (TargetMachine -> IO a) -> ErrorT String IO a withDefaultTargetMachine f = do   liftIO $ initializeAllTargets@@ -273,6 +275,31 @@  -- | <http://llvm.org/docs/doxygen/html/classllvm_1_1TargetLibraryInfo.html> newtype TargetLibraryInfo = TargetLibraryInfo (Ptr FFI.TargetLibraryInfo)++-- | Look up a 'LibraryFunction' by its standard name+getLibraryFunction :: TargetLibraryInfo -> String -> IO (Maybe LibraryFunction)+getLibraryFunction (TargetLibraryInfo f) name = flip runAnyContT return $ do+  libFuncP <- alloca+  name <- encodeM name+  r <- decodeM =<< (liftIO $ FFI.getLibFunc f name libFuncP)+  forM (if r then Just libFuncP else Nothing) $ decodeM <=< peek++-- | Get a the current name to be emitted for a 'LibraryFunction'+getLibraryFunctionName :: TargetLibraryInfo -> LibraryFunction -> IO String+getLibraryFunctionName (TargetLibraryInfo f) l = flip runAnyContT return $ do+  l <- encodeM l+  decodeM $ FFI.libFuncGetName f l++-- | Set the name of the function on the target platform that corresponds to funcName+setLibraryFunctionAvailableWithName ::+  TargetLibraryInfo+  -> LibraryFunction+  -> String -- ^ The function name to be emitted+  -> IO ()+setLibraryFunctionAvailableWithName (TargetLibraryInfo f) libraryFunction name = flip runAnyContT return $ do+  name <- encodeM name+  libraryFunction <- encodeM libraryFunction+  liftIO $ FFI.libFuncSetAvailableWithName f libraryFunction name  -- | look up information about the library functions available on a given platform withTargetLibraryInfo :: 
src/LLVM/General/Target.hs view
@@ -1,4 +1,4 @@--- | A Target describes that for which code may be intended. Targets are used both during actual+-- | 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 (@@ -12,6 +12,9 @@    getDefaultTargetTriple, getProcessTargetTriple, getHostCPUName, getHostCPUFeatures,    getTargetMachineDataLayout, initializeNativeTarget, initializeAllTargets,    TargetLibraryInfo,+   getLibraryFunction,+   getLibraryFunctionName,+   setLibraryFunctionAvailableWithName,    withTargetLibraryInfo  ) where 
+ src/LLVM/General/Target/LibraryFunction.hs view
@@ -0,0 +1,7 @@+-- | A 'LibraryFunction' identifies a function of which LLVM has particular knowledge.+module LLVM.General.Target.LibraryFunction (+  LibraryFunction(..)+ ) where+++import LLVM.General.Internal.LibraryFunction
test/LLVM/General/Test/Optimization.hs view
@@ -94,6 +94,14 @@        }      ] +isVectory :: A.Module -> Assertion+isVectory Module { moduleDefinitions = ds } =+  (@? "Module is not vectory") $ not $ null [ i +    | GlobalDefinition (Function { G.basicBlocks = b }) <- ds,+      BasicBlock _ is _ <- b,+      _ := i@(InsertElement {}) <- is+   ]+ optimize :: PassSetSpec -> A.Module -> IO A.Module optimize pss m = withContext $ \context -> withModuleFromAST' context m $ \mIn' -> do   withPassManager pss $ \pm -> runPassManager pm mIn'@@ -169,127 +177,86 @@            G.returnType = FloatingPointType 64 IEEE,             G.name = Name "foo",             G.parameters = ([-              Parameter (FloatingPointType 64 IEEE) (Name "a1") [],-              Parameter (FloatingPointType 64 IEEE) (Name "a2") [],-              Parameter (FloatingPointType 64 IEEE) (Name "b1") [],-              Parameter (FloatingPointType 64 IEEE) (Name "b2") []+              Parameter (FloatingPointType 64 IEEE) (Name (l ++ n)) []+                | l <- [ "a", "b" ], n <- ["1", "2"]              ], False),             G.basicBlocks = [-              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"))) [])+              BasicBlock (UnName 0) ([+                Name (l ++ n) := op (LocalReference (Name (o1 ++ n))) (LocalReference (Name (o2 ++ n))) []+                | (l, op, o1, o2) <- [+                   ("x", FSub, "a", "b"),+                   ("y", FMul, "x", "a"),+                   ("z", FAdd, "y", "b")],+                  n <- ["1", "2"]+               ] ++ [+                Name "r" := FMul (LocalReference (Name "z1")) (LocalReference (Name "z2")) []+              ]) (Do $ Ret (Just (LocalReference (Name "r"))) [])              ]           }          ]-      mOut <- -        optimize (defaultPassSetSpec { transforms = [ defaultVectorizeBasicBlocks { requiredChainDepth = 3 }, InstructionCombining, GlobalValueNumbering False ] }) mIn-      mOut @?= Module "<string>" Nothing Nothing [-        GlobalDefinition $ functionDefaults {-          G.returnType = FloatingPointType 64 IEEE,-          G.name = Name "foo",-          G.parameters = ([-            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),-          G.basicBlocks = [-            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"))) []-             )-           ]-         }-       ],+      mOut <- optimize (defaultPassSetSpec {+                    transforms = [+                     defaultVectorizeBasicBlocks { requiredChainDepth = 3 },+                     InstructionCombining, +                     GlobalValueNumbering False+                    ] }) mIn+      isVectory mOut,       +    testCase "LoopVectorize" $ do+      let+        mIn = +          Module {+            moduleName = "<string>",+            moduleDataLayout = Just $ defaultDataLayout { +              typeLayouts = Map.singleton (VectorAlign, 128) (AlignmentInfo 128 Nothing)+             },+            moduleTargetTriple = Just "x86_64",+            moduleDefinitions = [+              GlobalDefinition $ functionDefaults {+                G.returnType = VoidType,+                G.name = Name "foo",+                G.parameters = ([Parameter (PointerType (IntegerType 32) (AddrSpace 0)) (Name "x") []], False),+                G.basicBlocks = [+                  BasicBlock (UnName 0) [] (Do $ Br (UnName 1) []),+                  BasicBlock (UnName 1) [+                    Name "i.0" := Phi (IntegerType 32) [ +                      (ConstantOperand (C.Int 32 0), UnName 0),+                      (LocalReference (UnName 8), UnName 7)+                     ] [],+                    Name ".0" := Phi (PointerType (IntegerType 32) (AddrSpace 0)) [ +                      (LocalReference (Name "x"), UnName 0),+                      (LocalReference (UnName 4), UnName 7)+                     ] [],+                    UnName 2 := ICmp IPred.SLT (LocalReference (Name "i.0")) (ConstantOperand (C.Int 32 2048)) []+                   ] (Do $ CondBr (LocalReference (UnName 2)) (UnName 3) (UnName 9) []),+                  BasicBlock (UnName 3) [+                    UnName 4 := GetElementPtr True (LocalReference (Name ".0")) [ +                      ConstantOperand (C.Int 32 1)+                     ] [],+                    UnName 5 := Load False (LocalReference (Name ".0")) Nothing 4 [],+                    UnName 6 := Add True False (LocalReference (UnName 5)) (ConstantOperand (C.Int 32 1)) [],+                    Do $ Store False (LocalReference (Name ".0")) (LocalReference (UnName 6)) Nothing 4 []  +                   ] (Do $ Br (UnName 7) []),+                  BasicBlock (UnName 7) [+                    UnName 8 := Add True False (LocalReference (Name "i.0")) (ConstantOperand (C.Int 32 1)) []+                   ] (Do $ Br (UnName 1) []),+                  BasicBlock (UnName 9) [] (Do $ Ret Nothing [])+                 ]+               }+             ]+           }+      mOut <- do+        let triple = "x86_64"+        (target, _) <- failInIO $ lookupTarget Nothing triple+        withTargetOptions $ \targetOptions -> do+          withTargetMachine target triple "" Set.empty targetOptions R.Default CM.Default CGO.Default $ \tm -> do+            optimize (defaultPassSetSpec { +                        transforms = [ LoopVectorize ],+                        dataLayout = moduleDataLayout mIn,+                        targetMachine = Just tm+                      }) mIn+      isVectory mOut,+     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
test/LLVM/General/Test/Target.hs view
@@ -14,6 +14,7 @@  import LLVM.General.Target import LLVM.General.Target.Options+import LLVM.General.Target.LibraryFunction  instance Arbitrary FloatABI where   arbitrary = elements [minBound .. maxBound]@@ -83,5 +84,21 @@          pokeTargetOptions options to          options' <- peekTargetOptions to          return $ options == options'+   ],+  testGroup "LibraryFunction" [+    testGroup "set-get" [+       testCase (show lf) $ do+         triple <- getDefaultTargetTriple+         withTargetLibraryInfo triple $ \tli -> do+           setLibraryFunctionAvailableWithName tli lf "foo"+           nm <- getLibraryFunctionName tli lf+           nm @?= "foo"+       | lf <- [minBound, maxBound]+     ],+    testCase "get" $ do+      triple <- getDefaultTargetTriple+      withTargetLibraryInfo triple $ \tli -> do+        lf <- getLibraryFunction tli "printf"+        lf @?= Just LF__printf    ]  ]