[GHC] #14989: "Each block should be reachable from only one ProcPoint" compiling `integer` with `-fllvm`
GHC
ghc-devs at haskell.org
Sat Mar 31 14:19:53 UTC 2018
#14989: "Each block should be reachable from only one ProcPoint" compiling
`integer` with `-fllvm`
-------------------------------------+-------------------------------------
Reporter: sgraf | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.5
Resolution: | Keywords:
Operating System: Windows | Architecture: x86_64
Type of failure: Compile-time | (amd64)
crash or panic | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by sgraf):
I blame common block elimination. This is the output post sink
assignments:
{{{
...
c2m1: // global
call (I64[R1])(R1) returns to c2m0, args: 8, res: 8, upd: 8;
c2m0: // global
switch [1 .. 2] (R1 & 7) {
case 1 : goto u2mH;
case 2 : goto c2m5;
}
...
c2mi: // global
call (I64[R1])(R1) returns to c2mg, args: 8, res: 8, upd: 8;
c2mg: // global
switch [1 .. 2] (R1 & 7) {
case 1 : goto u2mI;
case 2 : goto c2mt;
}
...
c2mu: // global
call (I64[R1])(R1) returns to c2mr, args: 8, res: 8, upd: 8;
c2mr: // global
switch [1 .. 2] (R1 & 7) {
case 1 : goto c2mA;
case 2 : goto u2mJ;
}
u2mJ: // global
Sp = Sp + 8;
goto c2mE;
...
u2mI: // global
Sp = Sp + 8;
goto c2mE;
u2mH: // global
Sp = Sp + 8;
goto c2mE;
c2mE: // global
call Main.$wfail_info() args: 8, res: 0, upd: 8;
}}}
And this is post common block elimination 2:
{{{
...
c2m1: // global
call (I64[R1])(R1) returns to c2m0, args: 8, res: 8, upd: 8;
c2m0: // global
switch [1 .. 2] (R1 & 7) {
case 1 : goto u2mJ;
case 2 : goto c2m5;
}
...
c2mi: // global
call (I64[R1])(R1) returns to c2mg, args: 8, res: 8, upd: 8;
c2mg: // global
switch [1 .. 2] (R1 & 7) {
case 1 : goto u2mJ;
case 2 : goto c2mt;
}
...
c2mu: // global
call (I64[R1])(R1) returns to c2mr, args: 8, res: 8, upd: 8;
c2mr: // global
switch [1 .. 2] (R1 & 7) {
case 1 : goto c2mA;
case 2 : goto u2mJ;
}
...
u2mJ: // global
Sp = Sp + 8;
goto c2mE;
c2mE: // global
call Main.$wfail_info() args: 8, res: 0, upd: 8;
}}}
The non-proc-point blocks u2m* have been merged into a single block u2MJ,
which should have become a proc point in turn, because c2m{0,g,r} are
multiple proc points (they are continuations) the block now "belongs" to.
This is essentially diamond control flow introduced by the merging of
blocks.
{{{
c2m0 c2mg c2mr
| | |
u2mJ u2mI u2mH
\ | /
c2mE
===>
c2m0 c2mg c2mr
\ | /
u2mJ
|
c2mE
}}}
In SSA world, this could entail inserting new Phi functions into the
merged block, which corresponds to our notion of proc points, if I
understand right. I find the parallels to SSA form very helpful.
To stay in that analogy, c2mE was a proc point before common block
elimination, but is no longer, because the dominance frontier of defs
visible in c2m* changed from c2mE to u2mJ.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14989#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list