Commit 29310b62 authored by Erik de Castro Lopo's avatar Erik de Castro Lopo

Switch to LLVM version 3.7

Before this commit, GHC only supported LLVM 3.6. Now it only supports
LLVM 3.7 which was released in August 2015. LLVM version 3.6 and earlier
do not work on AArch64/Arm64, but 3.7 does.

Also:
* Add CC_Ghc constructor to LlvmCallConvention.
* Replace `maxSupportLlvmVersion`/`minSupportLlvmVersion` with
  a single `supportedLlvmVersion` variable.
* Get `supportedLlvmVersion` from version specified in configure.ac.
* Drop llvmVersion field from DynFlags (no longer needed because only
  one version is supported).

Test Plan: Validate on x86_64 and arm

Reviewers: bgamari, austin

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1320

GHC Trac Issues: #10953
parent e8c81739
...@@ -117,6 +117,7 @@ ppLlvmMeta (MetaNamed n m) ...@@ -117,6 +117,7 @@ ppLlvmMeta (MetaNamed n m)
-- | Print out an LLVM metadata value. -- | Print out an LLVM metadata value.
ppLlvmMetaExpr :: MetaExpr -> SDoc ppLlvmMetaExpr :: MetaExpr -> SDoc
ppLlvmMetaExpr (MetaVar (LMLitVar (LMNullLit _))) = text "null"
ppLlvmMetaExpr (MetaStr s ) = text "!" <> doubleQuotes (ftext s) ppLlvmMetaExpr (MetaStr s ) = text "!" <> doubleQuotes (ftext s)
ppLlvmMetaExpr (MetaNode n ) = text "!" <> int n ppLlvmMetaExpr (MetaNode n ) = text "!" <> int n
ppLlvmMetaExpr (MetaVar v ) = ppr v ppLlvmMetaExpr (MetaVar v ) = ppr v
...@@ -280,7 +281,7 @@ ppCall ct fptr args attrs = case fptr of ...@@ -280,7 +281,7 @@ ppCall ct fptr args attrs = case fptr of
(case argTy of (case argTy of
VarArgs -> text ", ..." VarArgs -> text ", ..."
FixedArgs -> empty) FixedArgs -> empty)
fnty = space <> lparen <> ppArgTy <> rparen <> char '*' fnty = space <> lparen <> ppArgTy <> rparen
attrDoc = ppSpaceJoin attrs attrDoc = ppSpaceJoin attrs
in tc <> text "call" <+> ppr cc <+> ppr ret in tc <> text "call" <+> ppr cc <+> ppr ret
<> fnty <+> ppName fptr <> lparen <+> ppValues <> fnty <+> ppName fptr <> lparen <+> ppValues
...@@ -362,8 +363,9 @@ ppCmpXChg addr old new s_ord f_ord = ...@@ -362,8 +363,9 @@ ppCmpXChg addr old new s_ord f_ord =
-- of specifying alignment. -- of specifying alignment.
ppLoad :: LlvmVar -> SDoc ppLoad :: LlvmVar -> SDoc
ppLoad var = text "load" <+> ppr var <> align ppLoad var = text "load" <+> ppr derefType <> comma <+> ppr var <> align
where where
derefType = pLower $ getVarType var
align | isVector . pLower . getVarType $ var = text ", align 1" align | isVector . pLower . getVarType $ var = text ", align 1"
| otherwise = empty | otherwise = empty
...@@ -373,7 +375,9 @@ ppALoad ord st var = sdocWithDynFlags $ \dflags -> ...@@ -373,7 +375,9 @@ ppALoad ord st var = sdocWithDynFlags $ \dflags ->
align = text ", align" <+> ppr alignment align = text ", align" <+> ppr alignment
sThreaded | st = text " singlethread" sThreaded | st = text " singlethread"
| otherwise = empty | otherwise = empty
in text "load atomic" <+> ppr var <> sThreaded <+> ppSyncOrdering ord <> align derefType = pLower $ getVarType var
in text "load atomic" <+> ppr derefType <> comma <+> ppr var <> sThreaded
<+> ppSyncOrdering ord <> align
ppStore :: LlvmVar -> LlvmVar -> SDoc ppStore :: LlvmVar -> LlvmVar -> SDoc
ppStore val dst ppStore val dst
...@@ -409,7 +413,9 @@ ppGetElementPtr :: Bool -> LlvmVar -> [LlvmVar] -> SDoc ...@@ -409,7 +413,9 @@ ppGetElementPtr :: Bool -> LlvmVar -> [LlvmVar] -> SDoc
ppGetElementPtr inb ptr idx = ppGetElementPtr inb ptr idx =
let indexes = comma <+> ppCommaJoin idx let indexes = comma <+> ppCommaJoin idx
inbound = if inb then text "inbounds" else empty inbound = if inb then text "inbounds" else empty
in text "getelementptr" <+> inbound <+> ppr ptr <> indexes derefType = pLower $ getVarType ptr
in text "getelementptr" <+> inbound <+> ppr derefType <> comma <+> ppr ptr
<> indexes
ppReturn :: Maybe LlvmVar -> SDoc ppReturn :: Maybe LlvmVar -> SDoc
......
...@@ -568,6 +568,8 @@ data LlvmCallConvention ...@@ -568,6 +568,8 @@ data LlvmCallConvention
-- does not support varargs and requires the prototype of all callees to -- does not support varargs and requires the prototype of all callees to
-- exactly match the prototype of the function definition. -- exactly match the prototype of the function definition.
| CC_Coldcc | CC_Coldcc
-- | The GHC-specific 'registerised' calling convention.
| CC_Ghc
-- | Any calling convention may be specified by number, allowing -- | Any calling convention may be specified by number, allowing
-- target-specific calling conventions to be used. Target specific calling -- target-specific calling conventions to be used. Target specific calling
-- conventions start at 64. -- conventions start at 64.
...@@ -581,6 +583,7 @@ instance Outputable LlvmCallConvention where ...@@ -581,6 +583,7 @@ instance Outputable LlvmCallConvention where
ppr CC_Ccc = text "ccc" ppr CC_Ccc = text "ccc"
ppr CC_Fastcc = text "fastcc" ppr CC_Fastcc = text "fastcc"
ppr CC_Coldcc = text "coldcc" ppr CC_Coldcc = text "coldcc"
ppr CC_Ghc = text "ghccc"
ppr (CC_Ncc i) = text "cc " <> ppr i ppr (CC_Ncc i) = text "cc " <> ppr i
ppr CC_X86_Stdcc = text "x86_stdcallcc" ppr CC_X86_Stdcc = text "x86_stdcallcc"
......
...@@ -30,7 +30,6 @@ import SysTools ( figureLlvmVersion ) ...@@ -30,7 +30,6 @@ import SysTools ( figureLlvmVersion )
import qualified Stream import qualified Stream
import Control.Monad ( when ) import Control.Monad ( when )
import Data.IORef ( writeIORef )
import Data.Maybe ( fromMaybe, catMaybes ) import Data.Maybe ( fromMaybe, catMaybes )
import System.IO import System.IO
...@@ -47,21 +46,15 @@ llvmCodeGen dflags h us cmm_stream ...@@ -47,21 +46,15 @@ llvmCodeGen dflags h us cmm_stream
showPass dflags "LLVM CodeGen" showPass dflags "LLVM CodeGen"
-- get llvm version, cache for later use -- get llvm version, cache for later use
ver <- (fromMaybe defaultLlvmVersion) `fmap` figureLlvmVersion dflags ver <- (fromMaybe supportedLlvmVersion) `fmap` figureLlvmVersion dflags
writeIORef (llvmVersion dflags) ver
-- warn if unsupported -- warn if unsupported
debugTraceMsg dflags 2 debugTraceMsg dflags 2
(text "Using LLVM version:" <+> text (show ver)) (text "Using LLVM version:" <+> text (show ver))
let doWarn = wopt Opt_WarnUnsupportedLlvmVersion dflags let doWarn = wopt Opt_WarnUnsupportedLlvmVersion dflags
when (ver < minSupportLlvmVersion && doWarn) $ when (ver /= supportedLlvmVersion && doWarn) $
errorMsg dflags (text "You are using an old version of LLVM that" putMsg dflags (text "You are using an unsupported version of LLVM!"
<> text " isn't supported anymore!"
$+$ text "We will try though...") $+$ text "We will try though...")
when (ver > maxSupportLlvmVersion && doWarn) $
putMsg dflags (text "You are using a new version of LLVM that"
<> text " hasn't been tested yet!"
$+$ text "We will try though...")
-- run code generation -- run code generation
runLlvm dflags ver bufh us $ runLlvm dflags ver bufh us $
......
...@@ -12,8 +12,7 @@ module LlvmCodeGen.Base ( ...@@ -12,8 +12,7 @@ module LlvmCodeGen.Base (
LiveGlobalRegs, LiveGlobalRegs,
LlvmUnresData, LlvmData, UnresLabel, UnresStatic, LlvmUnresData, LlvmData, UnresLabel, UnresStatic,
LlvmVersion, defaultLlvmVersion, minSupportLlvmVersion, LlvmVersion, supportedLlvmVersion,
maxSupportLlvmVersion,
LlvmM, LlvmM,
runLlvm, liftStream, withClearVars, varLookup, varInsert, runLlvm, liftStream, withClearVars, varLookup, varInsert,
...@@ -36,6 +35,7 @@ module LlvmCodeGen.Base ( ...@@ -36,6 +35,7 @@ module LlvmCodeGen.Base (
) where ) where
#include "HsVersions.h" #include "HsVersions.h"
#include "ghcautoconf.h"
import Llvm import Llvm
import LlvmCodeGen.Regs import LlvmCodeGen.Regs
...@@ -111,7 +111,7 @@ widthToLlvmInt w = LMInt $ widthInBits w ...@@ -111,7 +111,7 @@ widthToLlvmInt w = LMInt $ widthInBits w
llvmGhcCC :: DynFlags -> LlvmCallConvention llvmGhcCC :: DynFlags -> LlvmCallConvention
llvmGhcCC dflags llvmGhcCC dflags
| platformUnregisterised (targetPlatform dflags) = CC_Ccc | platformUnregisterised (targetPlatform dflags) = CC_Ccc
| otherwise = CC_Ncc 10 | otherwise = CC_Ghc
-- | Llvm Function type for Cmm function -- | Llvm Function type for Cmm function
llvmFunTy :: LiveGlobalRegs -> LlvmM LlvmType llvmFunTy :: LiveGlobalRegs -> LlvmM LlvmType
...@@ -172,17 +172,11 @@ llvmPtrBits dflags = widthInBits $ typeWidth $ gcWord dflags ...@@ -172,17 +172,11 @@ llvmPtrBits dflags = widthInBits $ typeWidth $ gcWord dflags
-- --
-- | LLVM Version Number -- | LLVM Version Number
type LlvmVersion = Int type LlvmVersion = (Int, Int)
-- | The LLVM Version we assume if we don't know -- | The LLVM Version that is currently supported.
defaultLlvmVersion :: LlvmVersion supportedLlvmVersion :: LlvmVersion
defaultLlvmVersion = 36 supportedLlvmVersion = sUPPORTED_LLVM_VERSION
minSupportLlvmVersion :: LlvmVersion
minSupportLlvmVersion = 36
maxSupportLlvmVersion :: LlvmVersion
maxSupportLlvmVersion = 36
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
-- * Environment Handling -- * Environment Handling
......
...@@ -66,7 +66,6 @@ import TcRnTypes ...@@ -66,7 +66,6 @@ import TcRnTypes
import Hooks import Hooks
import Exception import Exception
import Data.IORef ( readIORef )
import System.Directory import System.Directory
import System.FilePath import System.FilePath
import System.IO import System.IO
...@@ -1259,14 +1258,7 @@ runPhase (RealPhase (As with_cpp)) input_fn dflags ...@@ -1259,14 +1258,7 @@ runPhase (RealPhase (As with_cpp)) input_fn dflags
-- assembler, so we use clang as the assembler instead. (#5636) -- assembler, so we use clang as the assembler instead. (#5636)
let whichAsProg | hscTarget dflags == HscLlvm && let whichAsProg | hscTarget dflags == HscLlvm &&
platformOS (targetPlatform dflags) == OSDarwin platformOS (targetPlatform dflags) == OSDarwin
= do = return SysTools.runClang
-- be careful what options we call clang with
-- see #5903 and #7617 for bugs caused by this.
llvmVer <- liftIO $ figureLlvmVersion dflags
return $ case llvmVer of
Just n | n >= 30 -> SysTools.runClang
_ -> SysTools.runAs
| otherwise = return SysTools.runAs | otherwise = return SysTools.runAs
as_prog <- whichAsProg as_prog <- whichAsProg
...@@ -1408,18 +1400,15 @@ runPhase (RealPhase SplitAs) _input_fn dflags ...@@ -1408,18 +1400,15 @@ runPhase (RealPhase SplitAs) _input_fn dflags
runPhase (RealPhase LlvmOpt) input_fn dflags runPhase (RealPhase LlvmOpt) input_fn dflags
= do = do
ver <- liftIO $ readIORef (llvmVersion dflags)
let opt_lvl = max 0 (min 2 $ optLevel dflags) let opt_lvl = max 0 (min 2 $ optLevel dflags)
-- don't specify anything if user has specified commands. We do this -- don't specify anything if user has specified commands. We do this
-- for opt but not llc since opt is very specifically for optimisation -- for opt but not llc since opt is very specifically for optimisation
-- passes only, so if the user is passing us extra options we assume -- passes only, so if the user is passing us extra options we assume
-- they know what they are doing and don't get in the way. -- they know what they are doing and don't get in the way.
optFlag = if null (getOpts dflags opt_lo) optFlag = if null (getOpts dflags opt_lo)
then map SysTools.Option $ words (llvmOpts ver !! opt_lvl) then map SysTools.Option $ words (llvmOpts !! opt_lvl)
else [] else []
tbaa | ver < 29 = "" -- no tbaa in 2.8 and earlier tbaa | gopt Opt_LlvmTBAA dflags = "--enable-tbaa=true"
| gopt Opt_LlvmTBAA dflags = "--enable-tbaa=true"
| otherwise = "--enable-tbaa=false" | otherwise = "--enable-tbaa=false"
...@@ -1433,22 +1422,19 @@ runPhase (RealPhase LlvmOpt) input_fn dflags ...@@ -1433,22 +1422,19 @@ runPhase (RealPhase LlvmOpt) input_fn dflags
++ [SysTools.Option tbaa]) ++ [SysTools.Option tbaa])
return (RealPhase LlvmLlc, output_fn) return (RealPhase LlvmLlc, output_fn)
where where
-- we always (unless -optlo specified) run Opt since we rely on it to -- we always (unless -optlo specified) run Opt since we rely on it to
-- fix up some pretty big deficiencies in the code we generate -- fix up some pretty big deficiencies in the code we generate
llvmOpts ver = [ "-mem2reg -globalopt" llvmOpts = [ "-mem2reg -globalopt"
, if ver >= 34 then "-O1 -globalopt" else "-O1" , "-O1 -globalopt"
-- LLVM 3.4 -O1 doesn't eliminate aliases reliably (bug #8855) , "-O2"
, "-O2" ]
]
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- LlvmLlc phase -- LlvmLlc phase
runPhase (RealPhase LlvmLlc) input_fn dflags runPhase (RealPhase LlvmLlc) input_fn dflags
= do = do
ver <- liftIO $ readIORef (llvmVersion dflags)
let opt_lvl = max 0 (min 2 $ optLevel dflags) let opt_lvl = max 0 (min 2 $ optLevel dflags)
-- iOS requires external references to be loaded indirectly from the -- iOS requires external references to be loaded indirectly from the
-- DATA segment or dyld traps at runtime writing into TEXT: see #7722 -- DATA segment or dyld traps at runtime writing into TEXT: see #7722
...@@ -1456,8 +1442,7 @@ runPhase (RealPhase LlvmLlc) input_fn dflags ...@@ -1456,8 +1442,7 @@ runPhase (RealPhase LlvmLlc) input_fn dflags
| gopt Opt_PIC dflags = "pic" | gopt Opt_PIC dflags = "pic"
| not (gopt Opt_Static dflags) = "dynamic-no-pic" | not (gopt Opt_Static dflags) = "dynamic-no-pic"
| otherwise = "static" | otherwise = "static"
tbaa | ver < 29 = "" -- no tbaa in 2.8 and earlier tbaa | gopt Opt_LlvmTBAA dflags = "--enable-tbaa=true"
| gopt Opt_LlvmTBAA dflags = "--enable-tbaa=true"
| otherwise = "--enable-tbaa=false" | otherwise = "--enable-tbaa=false"
-- hidden debugging flag '-dno-llvm-mangler' to skip mangling -- hidden debugging flag '-dno-llvm-mangler' to skip mangling
...@@ -1465,13 +1450,8 @@ runPhase (RealPhase LlvmLlc) input_fn dflags ...@@ -1465,13 +1450,8 @@ runPhase (RealPhase LlvmLlc) input_fn dflags
False -> LlvmMangle False -> LlvmMangle
True | gopt Opt_SplitObjs dflags -> Splitter True | gopt Opt_SplitObjs dflags -> Splitter
True -> As False True -> As False
output_fn <- phaseOutputFilename next_phase
-- AVX can cause LLVM 3.2 to generate a C-like frame pointer output_fn <- phaseOutputFilename next_phase
-- prelude, see #9391
when (ver == 32 && isAvxEnabled dflags) $ liftIO $ errorMsg dflags $ text
"Note: LLVM 3.2 has known problems with AVX instructions (see trac #9391)"
liftIO $ SysTools.runLlvmLlc dflags liftIO $ SysTools.runLlvmLlc dflags
([ SysTools.Option (llvmOpts !! opt_lvl), ([ SysTools.Option (llvmOpts !! opt_lvl),
...@@ -1482,7 +1462,7 @@ runPhase (RealPhase LlvmLlc) input_fn dflags ...@@ -1482,7 +1462,7 @@ runPhase (RealPhase LlvmLlc) input_fn dflags
++ map SysTools.Option fpOpts ++ map SysTools.Option fpOpts
++ map SysTools.Option abiOpts ++ map SysTools.Option abiOpts
++ map SysTools.Option sseOpts ++ map SysTools.Option sseOpts
++ map SysTools.Option (avxOpts ver) ++ map SysTools.Option avxOpts
++ map SysTools.Option avx512Opts ++ map SysTools.Option avx512Opts
++ map SysTools.Option stackAlignOpts) ++ map SysTools.Option stackAlignOpts)
...@@ -1495,7 +1475,7 @@ runPhase (RealPhase LlvmLlc) input_fn dflags ...@@ -1495,7 +1475,7 @@ runPhase (RealPhase LlvmLlc) input_fn dflags
-- On ARMv7 using LLVM, LLVM fails to allocate floating point registers -- On ARMv7 using LLVM, LLVM fails to allocate floating point registers
-- while compiling GHC source code. It's probably due to fact that it -- while compiling GHC source code. It's probably due to fact that it
-- does not enable VFP by default. Let's do this manually here -- does not enable VFP by default. Let's do this manually here
fpOpts = case platformArch (targetPlatform dflags) of fpOpts = case platformArch (targetPlatform dflags) of
ArchARM ARMv7 ext _ -> if (elem VFPv3 ext) ArchARM ARMv7 ext _ -> if (elem VFPv3 ext)
then ["-mattr=+v7,+vfp3"] then ["-mattr=+v7,+vfp3"]
else if (elem VFPv3D16 ext) else if (elem VFPv3D16 ext)
...@@ -1518,11 +1498,10 @@ runPhase (RealPhase LlvmLlc) input_fn dflags ...@@ -1518,11 +1498,10 @@ runPhase (RealPhase LlvmLlc) input_fn dflags
| isSseEnabled dflags = ["-mattr=+sse"] | isSseEnabled dflags = ["-mattr=+sse"]
| otherwise = [] | otherwise = []
avxOpts ver | isAvx512fEnabled dflags = ["-mattr=+avx512f"] avxOpts | isAvx512fEnabled dflags = ["-mattr=+avx512f"]
| isAvx2Enabled dflags = ["-mattr=+avx2"] | isAvx2Enabled dflags = ["-mattr=+avx2"]
| isAvxEnabled dflags = ["-mattr=+avx"] | isAvxEnabled dflags = ["-mattr=+avx"]
| ver == 32 = ["-mattr=-avx"] -- see #9391 | otherwise = []
| otherwise = []
avx512Opts = avx512Opts =
[ "-mattr=+avx512cd" | isAvx512cdEnabled dflags ] ++ [ "-mattr=+avx512cd" | isAvx512cdEnabled dflags ] ++
......
...@@ -868,8 +868,6 @@ data DynFlags = DynFlags { ...@@ -868,8 +868,6 @@ data DynFlags = DynFlags {
interactivePrint :: Maybe String, interactivePrint :: Maybe String,
llvmVersion :: IORef Int,
nextWrapperNum :: IORef (ModuleEnv Int), nextWrapperNum :: IORef (ModuleEnv Int),
-- | Machine dependant flags (-m<blah> stuff) -- | Machine dependant flags (-m<blah> stuff)
...@@ -1377,7 +1375,6 @@ initDynFlags dflags = do ...@@ -1377,7 +1375,6 @@ initDynFlags dflags = do
refDirsToClean <- newIORef Map.empty refDirsToClean <- newIORef Map.empty
refFilesToNotIntermediateClean <- newIORef [] refFilesToNotIntermediateClean <- newIORef []
refGeneratedDumps <- newIORef Set.empty refGeneratedDumps <- newIORef Set.empty
refLlvmVersion <- newIORef 28
refRtldInfo <- newIORef Nothing refRtldInfo <- newIORef Nothing
refRtccInfo <- newIORef Nothing refRtccInfo <- newIORef Nothing
wrapperNum <- newIORef emptyModuleEnv wrapperNum <- newIORef emptyModuleEnv
...@@ -1394,7 +1391,6 @@ initDynFlags dflags = do ...@@ -1394,7 +1391,6 @@ initDynFlags dflags = do
dirsToClean = refDirsToClean, dirsToClean = refDirsToClean,
filesToNotIntermediateClean = refFilesToNotIntermediateClean, filesToNotIntermediateClean = refFilesToNotIntermediateClean,
generatedDumps = refGeneratedDumps, generatedDumps = refGeneratedDumps,
llvmVersion = refLlvmVersion,
nextWrapperNum = wrapperNum, nextWrapperNum = wrapperNum,
useUnicode = canUseUnicode, useUnicode = canUseUnicode,
rtldInfo = refRtldInfo, rtldInfo = refRtldInfo,
...@@ -1547,7 +1543,6 @@ defaultDynFlags mySettings = ...@@ -1547,7 +1543,6 @@ defaultDynFlags mySettings =
useUnicode = False, useUnicode = False,
traceLevel = 1, traceLevel = 1,
profAuto = NoProfAuto, profAuto = NoProfAuto,
llvmVersion = panic "defaultDynFlags: No llvmVersion",
interactivePrint = Nothing, interactivePrint = Nothing,
nextWrapperNum = panic "defaultDynFlags: No nextWrapperNum", nextWrapperNum = panic "defaultDynFlags: No nextWrapperNum",
sseVersion = Nothing, sseVersion = Nothing,
......
...@@ -613,7 +613,7 @@ runClang dflags args = do ...@@ -613,7 +613,7 @@ runClang dflags args = do
) )
-- | Figure out which version of LLVM we are running this session -- | Figure out which version of LLVM we are running this session
figureLlvmVersion :: DynFlags -> IO (Maybe Int) figureLlvmVersion :: DynFlags -> IO (Maybe (Int, Int))
figureLlvmVersion dflags = do figureLlvmVersion dflags = do
let (pgm,opts) = pgm_lc dflags let (pgm,opts) = pgm_lc dflags
args = filter notNull (map showOpt opts) args = filter notNull (map showOpt opts)
...@@ -626,17 +626,18 @@ figureLlvmVersion dflags = do ...@@ -626,17 +626,18 @@ figureLlvmVersion dflags = do
(pin, pout, perr, _) <- runInteractiveProcess pgm args' (pin, pout, perr, _) <- runInteractiveProcess pgm args'
Nothing Nothing Nothing Nothing
{- > llc -version {- > llc -version
Low Level Virtual Machine (http://llvm.org/): LLVM (http://llvm.org/):
llvm version 2.8 (Ubuntu 2.8-0Ubuntu1) LLVM version 3.5.2
... ...
-} -}
hSetBinaryMode pout False hSetBinaryMode pout False
_ <- hGetLine pout _ <- hGetLine pout
vline <- hGetLine pout vline <- dropWhile (not . isDigit) `fmap` hGetLine pout
v <- case filter isDigit vline of v <- case span (/= '.') vline of
[] -> fail "no digits!" ("",_) -> fail "no digits!"
[x] -> fail $ "only 1 digit! (" ++ show x ++ ")" (x,y) -> return (read x
(x:y:_) -> return ((read [x,y]) :: Int) , read $ takeWhile isDigit $ drop 1 y)
hClose pin hClose pin
hClose pout hClose pout
hClose perr hClose perr
......
...@@ -553,8 +553,10 @@ esac ...@@ -553,8 +553,10 @@ esac
# tools we are looking for. In the past, GHC supported a number of # tools we are looking for. In the past, GHC supported a number of
# versions of LLVM simultaneously, but that stopped working around # versions of LLVM simultaneously, but that stopped working around
# 3.5/3.6 release of LLVM. # 3.5/3.6 release of LLVM.
LlvmVersion=3.6 LlvmVersion=3.7
AC_SUBST([LlvmVersion]) AC_SUBST([LlvmVersion])
sUPPORTED_LLVM_VERSION=$(echo \($LlvmVersion\) | sed 's/\./,/')
AC_DEFINE_UNQUOTED([sUPPORTED_LLVM_VERSION], ${sUPPORTED_LLVM_VERSION}, [The supported LLVM version number])
dnl ** Which LLVM llc to use? dnl ** Which LLVM llc to use?
dnl -------------------------------------------------------------- dnl --------------------------------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment