Coder Social home page Coder Social logo

bscarlet / llvm-general Goto Github PK

View Code? Open in Web Editor NEW
131.0 131.0 38.0 3.07 MB

Rich LLVM bindings for Haskell (with transfer of LLVM IR to and from C++, detailed compilation pass control, etc.)

Home Page: http://hackage.haskell.org/package/llvm-general

Haskell 85.01% C 4.58% C++ 10.41%

llvm-general's People

Contributors

bgamari avatar bscarlet avatar cartazio avatar expipiplus1 avatar jwiegley avatar ralith avatar rybak avatar tvh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

llvm-general's Issues

Missing setenv dependency

I'm getting error

Setup.hs:14:8:
    Could not find module `System.SetEnv'
    Use -v to see a list of the files searched for.

while trying to build llvm-general-pure-3.2.7.2 under nix.

Probably, setenv dependency should be returned back, if it is used in package explicitly.

ambiguous haddocks because haddock doesn't render qualified names

LLVM-General-Module is the issue

the haddocks render as


withModuleFromAST :: Context -> Module -> (Module -> IO a) -> IO (Either String a)

Build a Module from a Module.

but the haddock source in the Internal module
https://github.com/bscarlet/llvm-general/blob/master/src/LLVM/General/Internal/Module.hs#L89-L98
is writ as

-- | Build a 'Module' from a 'LLVM.General.AST.Module'.
withModuleFromAST :: Context -> A.Module -> (Module -> IO a) -> IO (Either String a)

llvm/defs.c refers to gc.h

Idris doesn't build in my environment(Wheezy x86_64) because i dont have a gc.h which is referred to in llvm/defs.c

Runtime link error on Linux

I'm having trouble running a program using the llvm-general library. Both this library and my program compile fine, but upon running I get this error:

myprogram.hs: /usr/local/lib/libLLVMSupport.a: unknown symbol `_ZTVN4llvm14error_categoryE'
myprogram.hs: myprogram.hs: unable to load package `llvm-general-3.3.5.0'

I've tried both building LLVM 3.3 from source as well as installing the same version from the system's package manager, with this error consistently produced.

I'm not sure if this is related to llvm-general or a problem with LLVM itself, but I felt it would be best to raise the issue here first.

Thanks in advance.


uname -a: Linux renegade 3.9-1-amd64 #1 SMP Debian 3.9.8-1 x86_64 GNU/Linux
LLVM version: 3.3
llvm-general version: 3.3.5.0 (from Hackage)


Edit: Since mentioning what the program does normally helps in these situations, at the moment it simply constructs an AST from a small input program and pretty-prints it to the console; tools such as the code generator or optimisation passes are not being used yet.

missing returns in nonvoid typed c++ functions

     warning: control reaches end of non-void function [-Wreturn-type]
}
^
1 warning generated.

src/LLVM/General/Internal/FFI/AssemblyC.cpp:21:1:
     warning: control reaches end of non-void function [-Wreturn-type]
}
^
1 warning generated.

src/LLVM/General/Internal/FFI/ConstantC.cpp:13:1:
     warning: control reaches end of non-void function [-Wreturn-type]```

in particular 
https://github.com/bscarlet/llvm-general/blob/master/src/LLVM/General/Internal/FFI/ConstantC.cpp#L12
https://github.com/bscarlet/llvm-general/blob/master/src/LLVM/General/Internal/FFI/AssemblyC.cpp#L20

i'll open a mini pull request for those?

Very large phi instructions cause wrong and/or corrupted value arrays passed to addIncoming

The following program either segfaults, asserts, or runs successfully depending on the value of count. I've had successes as high as 500 and failures as low as 256 (there doesn't appear to be any connection to powers of 2, that was just the lowest one I tried that failed). Inspection in gdb shows the second argument (the value) passed to PHINode::addIncoming is either garbage or equal to the first argument (the basic block).

module Main where

import LLVM.General.Context
import LLVM.General.AST
import qualified LLVM.General.Module as M
import qualified LLVM.General.AST.Global as G
import qualified LLVM.General.AST.Constant as C

import Data.Word
import Debug.Trace

main :: IO ()
main = do
  str <- withContext $ \context -> M.withModuleFromAST context (traceShow ast ast) M.moduleString
  case str of
    Left s -> putStrLn s
    Right s -> putStrLn s

spamBBs :: Int -> Word -> Name -> [BasicBlock]
spamBBs count nameStart end = spamBBs' count nameStart
    where
      spamBBs' 0 _ = []
      spamBBs' n c =
          BasicBlock (UnName c) [] (Do $ Br end []) : spamBBs' (n - 1) (c + 1)

ast :: Module
ast = Module "test" Nothing Nothing
      [ GlobalDefinition $ functionDefaults
        { G.name = Name "foo"
        , G.returnType = IntegerType 32
        , G.parameters = ([Parameter (IntegerType 32) (UnName 0) []], False)
        , G.basicBlocks =
            [ BasicBlock (UnName 1) [] (Do $ Switch (LocalReference $ UnName 0) (Name "end") cbps [])
            ] ++ spamBBs (fromIntegral count) start (Name "end")
          ++[ BasicBlock (Name "end")
                [ Name "val" := Phi (IntegerType 32) vbps [] ]
                (Do $ Ret (Just (LocalReference (Name "val"))) []) ]
        }
      ]
    where
      count = 450
      start = 4
      vbps = (zip (map (ConstantOperand . C.Int 32) [0..]) (map UnName (1:[start..count + start - 1])))
      cbps = (zip (map (C.Int 32) [0..]) (map UnName ([start..count + start - 1])))

can't pick up llvm-3.2 on my mac installed via homebrew

I'm getting the following error

setup: Missing dependency on a foreign library:
* Missing C library: LLVM-3.2svn
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.

but I have llvm-3.2 installed!

I'm still exploring the llvm-general code base, but what might be the issue here?

I'm looking at this lib and it looks pretty nicely done! (i've been helping maintain llvm-base lately, but this might better fit my needs, and looks like it may have less cruft too!)

proposal: expose building in directory llvm as a cabal flag (of by default)

eg a cabal flag, something like mylittlellvm, with the default off, so that folks who have complicated build setups, can just have an isolated llvm just built locally.

(seems like it would help with people who are using client tools of llvm-general, such as idris, and have weird paths / build prefs about llvm itself)

add a changelog file?

would be kinda cool! (especially since theres a lot of changes going on continually)

LLVM patch for DYLD_LIBRARY_PATH

The LLVM build could make better use of the way OS X handles dynamic library paths, to allow third party code (like the Haskell bindings) to use a relative path to find the LLVM dynamic libraries. Someone appropriate on the LLVM team once told me a patch for such would probably be acceptable.

test suite failure on os x

cabal test 1 ↵
Building llvm-general-0.1...
Preprocessing library llvm-general-0.1...
In-place registering llvm-general-0.1...
Preprocessing test suite 'test' for llvm-general-0.1...
Linking dist/build/test/test ...
Running 1 test suites...
Test suite test: RUNNING...
test(59010) malloc: *** error for object 0x10e90f7c0: pointer being freed was not allocated
** set a breakpoint in malloc_error_break to debug
Test suite test: FAIL
Test suite logged to: dist/test/llvm-general-0.1-test.log
0 of 1 test suites (0 of 1 test cases) passed.
carter repoScratcher/llvm-general ‹master
› »

using ghc 7.6.3 and llvm 3.2 build from source.

Unification errors on GHC 7.7

I've only tested on ARM so far but I don't see any reason why this shouldn't be reproducible elsewhere.

[28 of 96] Compiling Control.Monad.AnyCont.Class ( src/Control/Monad/AnyCont/Class.hs, dist/build/Control/Monad/AnyCont/Class.o )

src/Control/Monad/AnyCont/Class.hs:29:16:
    Cannot instantiate unification variable ‛a1’
    with a type involving foralls: forall r. (a -> b r) -> b r
      Perhaps you want -XImpredicativeTypes
    In the expression: lift . anyContToM
    In an equation for ‛anyContToM’: anyContToM = lift . anyContToM
    In the instance declaration for ‛MonadAnyCont b (StateT s m)’

src/Control/Monad/AnyCont/Class.hs:29:23:
    Cannot instantiate unification variable ‛a1’
    with a type involving foralls: forall r. (a -> b1 r) -> b1 r
      Perhaps you want -XImpredicativeTypes
    In the second argument of ‛(.)’, namely ‛anyContToM’
    In the expression: lift . anyContToM

src/Control/Monad/AnyCont/Class.hs:36:16:
    Cannot instantiate unification variable ‛a0’
    with a type involving foralls: forall r. (a -> b r) -> b r
      Perhaps you want -XImpredicativeTypes
    In the expression: lift . anyContToM
    In an equation for ‛anyContToM’: anyContToM = lift . anyContToM
    In the instance declaration for ‛MonadAnyCont b (ErrorT e m)’

src/Control/Monad/AnyCont/Class.hs:36:23:
    Cannot instantiate unification variable ‛a0’
    with a type involving foralls: forall r. (a -> b0 r) -> b0 r
      Perhaps you want -XImpredicativeTypes
    In the second argument of ‛(.)’, namely ‛anyContToM’
    In the expression: lift . anyContToM
Failed to install llvm-general-3.4.0.0

PassManager special values

The current PassManager interface exposes the underlying API use of -1 as a special value. It'd be better to use Maybe's or such.

improve interface for optional TargetLowering

Only a few passes need a TargetLowering and all the target-specific baggage that entails. Right now a TargetLowering is optional in a PassSetSpec, but if it's left out it will just be passed as NULL through FFI.

Check dynamically or make an API change to check statically that a TargetLowering is provided when passes that need it are specified.

maybeAtomicity = Nothing still sets SynchronizationScope

In the Load instruction, I set maybeAtomicity to Nothing but the verifier gives me this error: "Non-atomic load cannot have SynchronizationScope specified"

Here is a failing example which loads an llvm assembly string, converts to an AST, converts back, and verifies:

{-# OPTIONS_GHC -Wall #-}

module Main ( main ) where

import LLVM.General
import LLVM.General.Analysis
import LLVM.General.Context
import Control.Monad.Trans.Error

src :: String
src = unlines [ "; ModuleID = 'come_on_lets_compile'"
              , ""
              , "define double @my_function2(double* %input_0) {"
              , "foo:"
              , "  %tmp_input_w0 = getelementptr inbounds double* %input_0, i64 0"
              , "  %0 = load double* %tmp_input_w0, align 8"
              , "  ret double %0"
              , "}"
              ]

main :: IO ()
main = do
  _ <- withContext $ \context -> do
    runErrorT $ withModuleFromString context src $ \mdl0 -> do
      mdlAst <- moduleAST mdl0
      runErrorT $ withModuleFromAST context mdlAst $ \mdl1 -> do
        putStrLn "here is the module string:\n"
        moduleString mdl1 >>= putStrLn
        vmdl <- runErrorT $ verify mdl1
        case vmdl of Left err -> do
                       putStrLn "verifier fail :(\n"
                       putStrLn err
                     Right _ -> do
                       putStrLn "verifier success!!"
  return ()

the output:

here is the module string:

; ModuleID = '<string>'

define double @my_function2(double* %input_0) {
foo:
  %tmp_input_w0 = getelementptr inbounds double* %input_0, i64 0
  %0 = load double* %tmp_input_w0, align 8
  ret double %0
}

verifier fail :(

Non-atomic load cannot have SynchronizationScope specified
  %0 = load double* %tmp_input_w0, align 8
Broken module found, compilation terminated.
Broken module found, compilation terminated.

The stand-alone llvm optimizer opt will verify that same llvm assembly.

For convenience, here is the AST

import LLVM.General.AST hiding (alignment, address, indices, inBounds)
import LLVM.General.AST.AddrSpace
import LLVM.General.AST.CallingConvention
import LLVM.General.AST.Linkage
import LLVM.General.AST.Instruction
import LLVM.General.AST.Constant hiding ( GetElementPtr, address )
import LLVM.General.AST.Visibility

mdl :: Module
mdl = Module "<string>" Nothing Nothing
      [GlobalDefinition (Function External Default C [] (FloatingPointType 64 IEEE) (Name "my_function2") (([Parameter (PointerType (FloatingPointType 64 IEEE) (AddrSpace 0)) (Name "input_0") []],False)) [] Nothing 0 [bb])]
  where
    bb = BasicBlock (Name "foo") [ getelemptr
                                 , load
                                 ] (Do (Ret (Just (LocalReference (UnName 0))) []))
    getelemptr =
      Name "tmp_input_w0" :=
      GetElementPtr True (LocalReference (Name "input_0")) [ConstantOperand (Int 64 0)] []
    load =
      UnName 0 :=
      Load { volatile = False
           , address = LocalReference (Name "tmp_input_w0")
           , maybeAtomicity = Nothing
           , alignment = 8
           , metadata = []}

ExecutionEngine design is unsafe

The findFunction/LLVMFindFunction interface on ExecutionEngine returns different types for different kinds of execution engines. Notably, if linking isn't right and the current withExecutionEngine winds up creating an interpreter, the pointer returned by findFunction will not be a function pointer but a Function *. I believe the LLVM interface and class structure is weird enough to warrant bringing Haskell static checking into play to keep things safe.

large constants / general literals

Make sure all possible literals are expressible in the ADT, and are handled correctly - e.g. very large integer literals, quad floats, etc.

Illegal terminators appearing after complete BBs

This ast produces illegal functions such as:

define internal fastcc %valTy* @"{runMain0}"() {
entry:
  br label %begin

begin:                                            ; preds = %entry
  %0 = call fastcc %valTy* @Main.main()
  %1 = call fastcc %valTy* @run__IO(%valy* %0)
  %2 = tail call fastcc %valTy* @"{EVAL0}"(%valTy* %1)
  ret %valTy* %2
  br label %caseExit4
  ret %valTy* %15
  br label %value4
  ret %valTy* %6
}

from definitions such as

Function
 { linkage = Internal
 , visibility = Default
 , callingConvention = Fast
 , returnAttributes = []
 , returnType = PointerType {pointerReferent = NamedTypeReference (Name "valTy"), pointerAddrSpace = AddrSpace 0}
 , name = Name "{runMain0}"
 , parameters = ([],False)
 , functionAttributes = []
 , section = Nothing
 , alignment = 0
 , basicBlocks =
     [ BasicBlock (Name "entry") [] (Do (Br {dest = Name "begin", metadata' = []}))
     , BasicBlock (Name "begin")
                      [ UnName 0 := Call { isTailCall = False
                                         , callingConvention = Fast
                                         , returnAttributes = []
                                         , function = Right (ConstantOperand (GlobalReference (Name "Main.main")))
                                         , arguments = []
                                         , functionAttributes = []
                                         , metadata = []
                                         }
                      , UnName 1 := Call { isTailCall = False
                                         , callingConvention = Fast
                                         , returnAttributes = []
                                         , function = Right (ConstantOperand (GlobalReference (Name "run__IO")))
                                         , arguments = [(LocalReference (UnName 0),[])]
                                         , functionAttributes = []
                                         , metadata = []
                                         }
                      , UnName 2 := Call { isTailCall = True
                                         , callingConvention = Fast
                                         , returnAttributes = []
                                         , function = Right (ConstantOperand (GlobalReference (Name "{EVAL0}")))
                                         , arguments = [(LocalReference (UnName 1),[])]
                                         , functionAttributes = []
                                         , metadata = []
                                         }
                      ] (Do (Ret {returnOperand = Just (LocalReference (UnName 2)), metadata' = []}))]})]}

switch ranges

The C++ includes nascent (as of LLVM 3.2) support for ranges of values in switch statements, to avoid needing many duplicate cases all going the same place. Add similar support to the ADT and FFI plumbing.

investigate apparently spurious overlapped pattern warning

dist/build/tmp-17394/src/LLVM/General/Internal/CallingConvention.hs:25:25: Warning:
    Pattern match(es) are overlapped
    In a case alternative:
        FFI.CallConv (Foreign.C.Types.CUInt 0) -> ...
        FFI.CallConv (Foreign.C.Types.CUInt 8) -> ...
        FFI.CallConv (Foreign.C.Types.CUInt 9) -> ...

How do flags like NSW intermix with constants?

It's not clear from the language reference how operation flags like NSW (no signed wrap) interplay with constant expressions. The constant operations don't have the flags, but the internal maps used during constant folding do. That sounds right, but make sure the Haskell version hasn't messed anything up.

Couldn't compile with GCC 7.4

I was trying to compile version 3.3.5.0 with GHC 7.4.2. I got a GHC message that the impossible had happened. Luckily, I'm at a summer school where SPJ is teaching, and he gave me some GHC flags to get a better error message. It seems to be an empty comprehension coming out of some template haskell.

Upgrading to GHC 7.6.3 fixed the issue for me.

Error:

src/LLVM/General/Internal/Diagnostic.hs:18:1:
    Empty stmt list in do-block
    When splicing a TH declaration:
      InstanceD [ClassP GHC.Base.Monad [TupleT 1105529114]] (VarT ) [FunD LLVM.General.Internal.Coding.encodeM [Clause [VarP h_1627693441] (NormalB (InfixE (Just (VarE GHC.Base.return)) (VarE GHC.Base.$) (Just (CompE [])))) []]]
cabal: Error: some packages failed to install:
idris-0.9.9 depends on llvm-general-3.3.5.0 which failed to install.
llvm-general-3.3.5.0 failed during the building phase. The exception was:
ExitFailure 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.