cmmImplementSwitchPlans creates duplicate blocks
Given this c-- code *after* common block elimination and *before* cmmImplementSwitchPlans:
...
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:
...
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.
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |