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 +7/−5
- src/LLVM/General/Internal/FFI/LLVMCTypes.hsc +6/−0
- src/LLVM/General/Internal/FFI/PassManager.hs +6/−0
- src/LLVM/General/Internal/FFI/PassManagerC.cpp +28/−0
- src/LLVM/General/Internal/FFI/Target.hs +9/−0
- src/LLVM/General/Internal/FFI/TargetC.cpp +48/−0
- src/LLVM/General/Internal/LibraryFunction.hsc +35/−0
- src/LLVM/General/Internal/Module.hs +1/−0
- src/LLVM/General/Internal/PassManager.hs +8/−2
- src/LLVM/General/Internal/Target.hs +30/−3
- src/LLVM/General/Target.hs +4/−1
- src/LLVM/General/Target/LibraryFunction.hs +7/−0
- test/LLVM/General/Test/Optimization.hs +82/−115
- test/LLVM/General/Test/Target.hs +17/−0
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 ] ]