
#8107: need types to express constant argument for primop correctness ------------------------------------+------------------------------------- Reporter: carter | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.6.3 Keywords: | Operating System: Unknown/Multiple Architecture: Unknown/Multiple | Type of failure: None/Unknown Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | ------------------------------------+------------------------------------- (not sure if this is a bug or a feature request, or a task, or a dialogue, filing as a bug for now) a number of compiler intrinsics that GHC has started to support (prefetch) and will come to support (concurrent memory operations a la http://ghc.haskell.org/trac/ghc/ticket/7883), require certain arguments to be statically fixed at compile time {{{ primop PrefetchAddrOp "prefetchAddr#" GenPrimOp Addr# -> Int# -> Addr# with llvm_only = True }}} consider the specification on the llvm side for prefetch http://llvm.org/docs/LangRef.html#llvm-prefetch-intrinsic {{{ Syntax:¶ declare void @llvm.prefetch(i8* <address>, i32 <rw>, i32 <locality>, i32 <cache type>) Overview: The ‘llvm.prefetch‘ intrinsic is a hint to the code generator to insert a prefetch instruction if supported; otherwise, it is a noop. Prefetches have no effect on the behavior of the program but can change its performance characteristics. Arguments: address is the address to be prefetched, rw is the specifier determining if the fetch should be for a read (0) or write (1), and locality is a temporal locality specifier ranging from (0) - no locality, to (3) - extremely local keep in cache. The cache type specifies whether the prefetch is performed on the data (1) or instruction (0) cache. The rw, locality and cache type arguments must be constant integers. }}} the punch line is that we're starting add primops that REALLY require certain arguments to be compile time constants to work correctly, otherwise there will by definition be compiler errors after the c-- phase when operations are passed along to the llvm backend and friends. (for the atomicity ops, i'll be looking into adding them to the native code gen, but the point being it will likely trigger an error at code gen time). a strawman approach would look like adding a type {{{ ReallyActuallyConstant :: * or unliftedtype -> * unliftedtype}}} roughly, then prefetch could have the type {{{ primop PrefetchAddrOp "prefetchAddr#" GenPrimOp Addr# ->ReallyActuallyConstant Int# -> Addr# with llvm_only = True }}} a way of emulating something like this functionality now, would be some template haskell that lets you lift a compile time constant of type t into the type ReallyActuallyConstant t, and is the only way to build a value of that type "ReallyActuallyConstant t". That said, that approach seems like a bad way of providing type safetype for making sure primops actually compile! Point being, some sort of way of nicely enforcing that a value needs to be available at compile time, that doesn't require doing abusing template haskell, is the idea i'm pointing at. Might also be useful for other things, but for now, i'm merely remarking on an invariant these primops have -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8107 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler