
#9157: cmm common block not eliminated -------------------------------------+------------------------------------ Reporter: wojteknar | Owner: jstolarek Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: Other | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Changes (by jstolarek): * cc: simonmar (added) Comment: I confirmed that this bug exists in HEAD and found the reason. I suspect that Common Block Elimination as implemented now might not work as intended. Here's what's happening. Code attached in the bug report generates 8 identical blocks (showing only 2 here for brevity): {{{ c1Dm: _s1CG::I64 = I64[_s1Cy::P64 + 7]; _g1CN::I64 = _s1CG::I64; goto c1Dd; c1Dl: _s1CF::I64 = I64[_s1Cy::P64 + 7]; _g1CN::I64 = _s1CF::I64; goto c1Dd; }}} We hash these block ignoring the labels and we get identical hashes as expected. Then we get to the point when we attempt to actually eliminate common blocks. [https://github.com/ghc/ghc/blob/master/compiler/cmm/CmmCommonBlockElim.hs#L6... We check these two block for equality], except that this time we don't ignore the labels and other unique identifiers (eg. [https://github.com/ghc/ghc/blob/master/compiler/cmm/CmmCommonBlockElim.hs#L1... here]). We conclude that these two block are different because local registers `_s1CG` are `_s1CF` are different. Later the sinking pass makes these two blocks identical. The result that we see in the Cmm output are 8 identical blocks: {{{ c1Dm: _g1CN::I64 = I64[_s1Cy::P64 + 7]; goto c1Dd; c1Dl: _g1CN::I64 = I64[_s1Cy::P64 + 7]; goto c1Dd; }}} I suspect that this is not how CBE was intended to work. I mean if we ignore the labels during hashing then we should probably be smarter when actually comparing the blocks. Except that this is not trivial. I wonder if we could simply move CBE to the end of Cmm pipeline, so that it is run after sinking and other optimizations? Or is there A Good Reason to have CBE at the beginning of the pipeline and not at the end? CCing Simon Marlow - perhaps he can tell. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9157#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler