[GHC] #12915: cmmImplementSwitchPlans creates duplicate blocks

GHC ghc-devs at haskell.org
Fri Dec 2 14:06:30 UTC 2016


#12915: cmmImplementSwitchPlans creates duplicate blocks
-------------------------------------+-------------------------------------
           Reporter:  alexbiehl      |             Owner:
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:
          Component:  Compiler       |           Version:  8.0.1
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 Given this c-- code *after* common block elimination and *before*
 cmmImplementSwitchPlans:

 {{{#!hs
     ...
 cfzc:
    _sfh3::P64 = R1;
    _cfB7::I64 = %MO_UU_Conv_W32_W64(I32[I64[_sfh3::P64 - 1] - 4]);
    switch [0 .. 20] _cfB7::I64 {
      case 2 : goto cfAR;
      case 4 : goto cfAV;
      case 6 : goto cfAZ;
      default: goto cfAC;
    }
 cfAZ:
    _sfh6::I64 = I64[_sfh3::P64 + 7];
    _sfgp::I64 = 1;
    goto sfgo;
 cfAV:
    _sfh5::I64 = I64[_sfh3::P64 + 7];
    _sfgp::I64 = 1;
    goto sfgo;
 cfAR:
    _sfh4::I64 = I64[_sfh3::P64 + 7];
    _sfgp::I64 = 1;
    goto sfgo;
 sfgo:
   ...
 }}}

 Everything is fine, the blocks cfAZ, cfAV and cfAR are all a little
 different.

 But after cmmImplementSwitchPlans the code becomes:

 {{{#!hs
     ...
 cfzc:
     _sfgl::I64 = I64[Sp + 24];
     _sfgn::P64 = P64[Sp + 16];
     _cfB7::I64 = %MO_UU_Conv_W32_W64(I32[I64[R1 - 1] - 4]);
     if (_cfB7::I64 < 5) goto ufBe; else goto ufBg;
 ufBe:
     if (_cfB7::I64 < 4) goto ufBf; else goto cfAV;
 ufBf:
     if (_cfB7::I64 != 2) goto cfAC; else goto cfAR;
 cfAR:
     _sfgp::I64 = 1;
     goto sfgo;
 cfAV:
     _sfgp::I64 = 1;
     goto sfgo;
 ufBg:
     if (_cfB7::I64 != 6) goto cfAC; else goto cfAZ;
 cfAZ:
     _sfgp::I64 = 1;
     goto sfgo;
 sfgo:
     ...

 }}}

 We can now see that cfAZ, cfAV and cfAR are code duplicates!

 Now,
 https://github.com/ghc/ghc/blob/master/compiler/cmm/CmmPipeline.hs#L72
 states

 {{{
 ...
        ----------- Eliminate common blocks
 -------------------------------------
        g <- {-# SCC "elimCommonBlocks" #-}
             condPass Opt_CmmElimCommonBlocks elimCommonBlocks g
                           Opt_D_dump_cmm_cbe "Post common block
 elimination"

        -- Any work storing block Labels must be performed _after_
        -- elimCommonBlocks

        g <- {-# SCC "createSwitchPlans" #-}
             runUniqSM $ cmmImplementSwitchPlans dflags g
        dump Opt_D_dump_cmm_switch "Post switch plan" g
 ...
 }}}

 For some reason I don't understand cmmImplementSwitchPlans is run *after*
 elimCommonBlocks. Although it seems elimCommonBlocks can deal with the
 constructs introduced in cmmImplementSwitchPlans.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12915>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list