
#13873: Adding a SPECIALIZE at a callsite in Main.hs is causing a regression -------------------------------------+------------------------------------- Reporter: jberryman | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.2.2 Component: Compiler | Version: 8.2.1-rc2 Resolution: | Keywords: Specialise Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by mpickering): That's right Simon. How this happens is that the `SPECIALISE` pragma creates a rule which looks like {{{ "SPEC insertWith" forall (@ k) (@ s) (@ v) ($dHashable :: Hashable k) ($dEq :: Eq k) ($dPrimMonad :: PrimMonad (ST s)). insertWith @ k @ (ST s) @ v $dHashable $dEq $dPrimMonad = $sinsertWith @ k @ s @ v $dHashable $dEq }}} which fires at quite an early stage in optimisation. Then any function in `$sinsertWith` which mentions `s` won't be specialised as it is lambda bound. If you remove the pragma you just get one specialisation rule which probably arises after a lot of inlining has happened. {{{ "SPEC/Main insert @ ByteString @ (ST RealWorld) _" forall (@ v) ($dPrimMonad :: PrimMonad (ST RealWorld)) ($dEq :: Eq ByteString) ($dHashable :: Hashable ByteString). insert @ ByteString @ (ST RealWorld) @ v $dHashable $dEq $dPrimMonad = $scheckResize_$sinsert @ v }}} and if you fix `s = RealWorld` with the specialisation pragma then both occur. {{{ "SPEC insertWith" forall (@ k) (@ v) ($dHashable :: Hashable k) ($dEq :: Eq k) ($dPrimMonad :: PrimMonad (ST RealWorld)). insertWith @ k @ (ST RealWorld) @ v $dHashable $dEq $dPrimMonad = $sinsertWith @ k @ v $dHashable $dEq "SPEC/Main insert @ ByteString @ (ST RealWorld) _" forall (@ v) ($dPrimMonad :: PrimMonad (ST RealWorld)) ($dEq :: Eq ByteString) ($dHashable :: Hashable ByteString). insert @ ByteString @ (ST RealWorld) @ v $dHashable $dEq $dPrimMonad = $scheckResize_$sinsert @ v }}} Seeing as you also ask for the type of `g`, it is defined in another module as is marked `INLINABLE`. {{{ checkResize::(Hashable k,Eq k,PrimMonad m) => HashTable_ (PrimState m) k v -> m (Maybe (HashTable (PrimState m) k v)) }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13873#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler