summaryrefslogtreecommitdiff
path: root/compiler/llvmGen
diff options
context:
space:
mode:
authorDavid Terei <davidterei@gmail.com>2012-01-30 18:24:01 -0800
committerDavid Terei <davidterei@gmail.com>2012-01-30 18:39:41 -0800
commitd2d5ee16cf21c5b32333ff57ba0a65f89ff7e988 (patch)
tree01a01eb8b5066cd340113bd63a3697d71dd9c85c /compiler/llvmGen
parent766da942097613fed56417e3e149997812f83105 (diff)
downloadhaskell-d2d5ee16cf21c5b32333ff57ba0a65f89ff7e988.tar.gz
Improve support for LLVM >= 3.0 write barrier. (#5814)
Diffstat (limited to 'compiler/llvmGen')
-rw-r--r--compiler/llvmGen/Llvm/AbsSyn.hs25
-rw-r--r--compiler/llvmGen/Llvm/PpLlvm.hs14
-rw-r--r--compiler/llvmGen/LlvmCodeGen/CodeGen.hs7
3 files changed, 31 insertions, 15 deletions
diff --git a/compiler/llvmGen/Llvm/AbsSyn.hs b/compiler/llvmGen/Llvm/AbsSyn.hs
index c9c8d3b5d8..9133447331 100644
--- a/compiler/llvmGen/Llvm/AbsSyn.hs
+++ b/compiler/llvmGen/Llvm/AbsSyn.hs
@@ -62,13 +62,24 @@ data LlvmFunction = LlvmFunction {
funcBody :: LlvmBlocks
}
-type LlvmFunctions = [LlvmFunction]
-
-data LlvmSyncOrdering = SyncAcquire
- | SyncRelease
- | SyncAcqRel
- | SyncSeqCst
- deriving (Show, Eq)
+type LlvmFunctions = [LlvmFunction]
+
+-- | LLVM ordering types for synchronization purposes. (Introduced in LLVM
+-- 3.0). Please see the LLVM documentation for a better description.
+data LlvmSyncOrdering
+ -- | Some partial order of operations exists.
+ = SyncUnord
+ -- | A single total order for operations at a single address exists.
+ | SyncMonotonic
+ -- | Acquire synchronization operation.
+ | SyncAcquire
+ -- | Release synchronization operation.
+ | SyncRelease
+ -- | Acquire + Release synchronization operation.
+ | SyncAcqRel
+ -- | Full sequential Consistency operation.
+ | SyncSeqCst
+ deriving (Show, Eq)
-- | Llvm Statements
data LlvmStatement
diff --git a/compiler/llvmGen/Llvm/PpLlvm.hs b/compiler/llvmGen/Llvm/PpLlvm.hs
index bfc037ef55..c2177782f2 100644
--- a/compiler/llvmGen/Llvm/PpLlvm.hs
+++ b/compiler/llvmGen/Llvm/PpLlvm.hs
@@ -211,7 +211,7 @@ ppLlvmStatement stmt =
let ind = (text " " <>)
in case stmt of
Assignment dst expr -> ind $ ppAssignment dst (ppLlvmExpression expr)
- Fence st ord -> ind $ ppFence st ord
+ Fence st ord -> ind $ ppFence st ord
Branch target -> ind $ ppBranch target
BranchIf cond ifT ifF -> ind $ ppBranchIf cond ifT ifF
Comment comments -> ind $ ppLlvmComments comments
@@ -305,14 +305,16 @@ ppAssignment var expr = (text $ getName var) <+> equals <+> expr
ppFence :: Bool -> LlvmSyncOrdering -> Doc
ppFence st ord =
let singleThread = case st of True -> text "singlethread"
- False -> empty
+ False -> empty
in text "fence" <+> singleThread <+> ppSyncOrdering ord
ppSyncOrdering :: LlvmSyncOrdering -> Doc
-ppSyncOrdering SyncAcquire = text "acquire"
-ppSyncOrdering SyncRelease = text "release"
-ppSyncOrdering SyncAcqRel = text "acq_rel"
-ppSyncOrdering SyncSeqCst = text "seq_cst"
+ppSyncOrdering SyncUnord = text "unordered"
+ppSyncOrdering SyncMonotonic = text "monotonic"
+ppSyncOrdering SyncAcquire = text "acquire"
+ppSyncOrdering SyncRelease = text "release"
+ppSyncOrdering SyncAcqRel = text "acq_rel"
+ppSyncOrdering SyncSeqCst = text "seq_cst"
ppLoad :: LlvmVar -> Doc
ppLoad var = text "load" <+> texts var
diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index 75388d383c..059328f868 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -137,11 +137,13 @@ stmtToInstrs env stmt = case stmt of
-> return (env, unitOL $ Return Nothing, [])
+-- | Memory barrier instruction for LLVM >= 3.0
barrier :: LlvmEnv -> UniqSM StmtData
barrier env = do
- let s = Fence False SyncAcqRel
+ let s = Fence False SyncSeqCst
return (env, unitOL s, [])
+-- | Memory barrier instruction for LLVM < 3.0
oldBarrier :: LlvmEnv -> UniqSM StmtData
oldBarrier env = do
let fname = fsLit "llvm.memory.barrier"
@@ -173,7 +175,8 @@ genCall :: LlvmEnv -> CmmCallTarget -> [HintedCmmFormal] -> [HintedCmmActual]
genCall env (CmmPrim MO_WriteBarrier) _ _ _
| platformArch (getLlvmPlatform env) `elem` [ArchX86, ArchX86_64, ArchSPARC]
= return (env, nilOL, [])
- | otherwise = barrier env
+ | getLlvmVer env > 29 = barrier env
+ | otherwise = oldBarrier env
-- Handle popcnt function specifically since GHC only really has i32 and i64
-- types and things like Word8 are backed by an i32 and just present a logical