
#13014: Seemingly unnecessary marking of a SpecConstr specialization as a loopbreaker -------------------------------------+------------------------------------- Reporter: nfrisby | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Resolution: | Keywords: SpecConstr 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 nfrisby): Replying to [comment:9 simonpj]:
Can you be more specific about "try very hard"? The thing is, as far as I can see, it ''is'' loop breaker, as my comment shows. That is, not marking it as such would allow arbitrary inlining.
My basic thought is that `DEEP_SPEC` is to `SPEC` as `SPECIALIZE INLINE` is to `SPECIALIZE`. (Thus, `SPEC_INLINE` might be a better/more consistent name than `DEEP_SPEC`.) The hypothetical power user would intentionally choose `DEEP_SPEC` instead of `SPEC` specifically to allow arbitrary inlining. With `SPEC` (i.e. normal `-fspec-constr`), GHC assumes the burden of ensuring that the specialization cannot lead to an infinite loop. By choosing `DEEP_SPEC`, the user intentionally transfers this burden from GHC to themselves. The docs for `DEEP_SPEC` would include a warning similar to those already present for `SPECIALIZE INLINE` ("Warning: you can make GHC diverge by using SPECIALISE INLINE on an ordinarily-recursive function") and `RULES` ("GHC makes no attempt to make sure that the rules are confluent or terminating. For example: ... This rule will cause the compiler to go into an infinite loop."). `DEEP_SPEC` would be a tool for the power user who wrote the `f` and `boo` functions you came up with and ''did'' want GHC to inline `f` 7 times so that `boo` was identified as `0` at compile-time. In terms of mechanism, I don't have enough command of `OccAnal` to be much more specific. My basic idea is that it wouldn't mark the specializations as a loopbreaker unless 1) the specialization ''directly calls itself by name'' or 2) for whatever reason, `OccAnal` has no other choice. In other words, GHC would only mark a `DEEP_SPEC` specialization as a loopbreaker if it concluded that not doing so would ''always'' lead to an infinite inlining --- "possibly infinite inlining" would no longer be cause enough to mark a particular specialization as a loopbreaker. I'll mention one last time that I do not have a real-world motivation for this new behavior in-hand. It doesn't seem like an obviously bad idea (buoyed by saying "power user" and "warnings in the docs"). But it's also not obviously better than all currently existing choices for this hypothetical power user! I just haven't thought about this long enough yet. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13014#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler