summaryrefslogtreecommitdiff
path: root/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
diff options
context:
space:
mode:
authorAustin Seipp <austin@well-typed.com>2013-10-01 21:13:14 -0500
committerAustin Seipp <austin@well-typed.com>2013-10-01 21:26:47 -0500
commitfd74014079f14bd3ab50e328e52c44ef97d40e05 (patch)
treeda31c992a76d3816a4f1012ceb1eb4e68d0fb556 /compiler/llvmGen/LlvmCodeGen/CodeGen.hs
parent627d1e008cbe4d9318b2466394420a968d1659da (diff)
downloadhaskell-fd74014079f14bd3ab50e328e52c44ef97d40e05.tar.gz
Add support for prefetch with locality levels.
This patch adds support for several new primitive operations which support using processor-specific instructions to help guide data and cache locality decisions. We have levels ranging from [0..3] For LLVM, we generate llvm.prefetch intrinsics at the proper locality level (similar to GCC.) For x86 we generate prefetch{NTA, t2, t1, t0} instructions. On SPARC and PowerPC, the locality levels are ignored. This closes #8256. Authored-by: Carter Tazio Schonwald <carter.schonwald@gmail.com> Signed-off-by: Austin Seipp <austin@well-typed.com>
Diffstat (limited to 'compiler/llvmGen/LlvmCodeGen/CodeGen.hs')
-rw-r--r--compiler/llvmGen/LlvmCodeGen/CodeGen.hs11
1 files changed, 7 insertions, 4 deletions
diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index 5002b89b72..808c591d92 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -200,7 +200,8 @@ genCall (PrimTarget (MO_UF_Conv _)) [_] args =
"Can only handle 1, given" ++ show (length args) ++ "."
-- Handle prefetching data
-genCall t@(PrimTarget MO_Prefetch_Data) [] args = do
+genCall t@(PrimTarget (MO_Prefetch_Data localityInt)) [] args
+ | 0 <= localityInt && localityInt <= 3 = do
ver <- getLlvmVer
let argTy | ver <= 29 = [i8Ptr, i32, i32]
| otherwise = [i8Ptr, i32, i32, i32]
@@ -214,12 +215,13 @@ genCall t@(PrimTarget MO_Prefetch_Data) [] args = do
(argVars', stmts3) <- castVars $ zip argVars argTy
trash <- getTrashStmts
- let argSuffix | ver <= 29 = [mkIntLit i32 0, mkIntLit i32 3]
- | otherwise = [mkIntLit i32 0, mkIntLit i32 3, mkIntLit i32 1]
+ let argSuffix | ver <= 29 = [mkIntLit i32 0, mkIntLit i32 localityInt]
+ | otherwise = [mkIntLit i32 0, mkIntLit i32 localityInt, mkIntLit i32 1]
call = Expr $ Call StdCall fptr (argVars' ++ argSuffix) []
stmts = stmts1 `appOL` stmts2 `appOL` stmts3
`appOL` trash `snocOL` call
return (stmts, top1 ++ top2)
+ | otherwise = panic $ "prefetch locality level integer must be between 0 and 3, given: " ++ (show localityInt)
-- Handle PopCnt and BSwap that need to only convert arg and return types
genCall t@(PrimTarget (MO_PopCnt w)) dsts args =
@@ -545,7 +547,8 @@ cmmPrimOpFunctions mop = do
(MO_PopCnt w) -> fsLit $ "llvm.ctpop." ++ showSDoc dflags (ppr $ widthToLlvmInt w)
(MO_BSwap w) -> fsLit $ "llvm.bswap." ++ showSDoc dflags (ppr $ widthToLlvmInt w)
- MO_Prefetch_Data -> fsLit "llvm.prefetch"
+ (MO_Prefetch_Data _ )-> fsLit "llvm.prefetch"
+
MO_S_QuotRem {} -> unsupported
MO_U_QuotRem {} -> unsupported