1
0
mirror of https://github.com/golang/go synced 2024-11-23 23:20:08 -07:00

[dev.ssa] cmd/compile/ssa: implement constant booleans

The removal of if false { ... } blocks in the opt
pass exposed that removePredecessor needed
to do more cleaning, on pain of failing later
consistency checks.

Change-Id: I45d4ff7e1f7f1486fdd99f867867ce6ea006a288
Reviewed-on: https://go-review.googlesource.com/11879
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2015-07-06 14:13:17 -07:00
parent cc3f031a31
commit 7d10a2c04a
5 changed files with 47 additions and 34 deletions

View File

@ -464,7 +464,7 @@ func (s *state) expr(n *Node) *ssa.Value {
switch n.Val().Ctype() {
case CTINT:
return s.constInt(n.Type, Mpgetfix(n.Val().U.(*Mpint)))
case CTSTR:
case CTSTR, CTBOOL:
return s.entryNewValue0A(ssa.OpConst, n.Type, n.Val().U)
default:
s.Unimplementedf("unhandled OLITERAL %v", n.Val().Ctype())

View File

@ -98,15 +98,14 @@ func deadcode(f *Func) {
// There was an edge b->c. It has been removed from b's successors.
// Fix up c to handle that fact.
func removePredecessor(b, c *Block) {
func (f *Func) removePredecessor(b, c *Block) {
work := [][2]*Block{{b, c}}
for len(work) > 0 {
b, c := work[0][0], work[0][1]
work = work[1:]
n := len(c.Preds) - 1
if n == 0 {
// c is now dead - don't bother working on it
if c.Preds[0] != b {
b.Fatalf("%s.Preds[0]==%s, want %s", c, c.Preds[0], b)
}
return
}
// find index of b in c's predecessor list
var i int
@ -120,6 +119,7 @@ func removePredecessor(b, c *Block) {
c.Preds[i] = c.Preds[n]
c.Preds[n] = nil // aid GC
c.Preds = c.Preds[:n]
// rewrite phi ops to match the new predecessor list
for _, v := range c.Values {
if v.Op != OpPhi {
@ -132,4 +132,17 @@ func removePredecessor(b, c *Block) {
v.Op = OpCopy
}
}
if n == 0 {
// c is now dead--recycle its values
for _, v := range c.Values {
f.vid.put(v.ID)
}
c.Values = nil
// Also kill any successors of c now, to spare later processing.
for _, succ := range c.Succs {
work = append(work, [2]*Block{c, succ})
}
}
}
}

View File

@ -232,7 +232,7 @@ func genRules(arch arch) {
// Modify predecessor lists for no-longer-reachable blocks
for succ := range m {
fmt.Fprintf(w, "removePredecessor(b, %s)\n", succ)
fmt.Fprintf(w, "v.Block.Func.removePredecessor(b, %s)\n", succ)
}
fmt.Fprintf(w, "b.Kind = %s\n", blockName(t[0], arch))

View File

@ -46,7 +46,7 @@ func nilcheckelim(f *Func) {
// and the fuse pass will join this block with its successor.
b.Kind = BlockPlain
b.Control = nil
removePredecessor(b, b.Succs[1])
f.removePredecessor(b, b.Succs[1])
b.Succs = b.Succs[:1]
}
}

View File

@ -403,7 +403,7 @@ func rewriteBlockgeneric(b *Block) bool {
if !(c.(bool)) {
goto end915e334b6388fed7d63e09aa69ecb05c
}
removePredecessor(b, no)
v.Block.Func.removePredecessor(b, no)
b.Kind = BlockPlain
b.Control = nil
b.Succs = b.Succs[:1]
@ -427,7 +427,7 @@ func rewriteBlockgeneric(b *Block) bool {
if !(!c.(bool)) {
goto end6452ee3a5bb02c708bddc3181c3ea3cb
}
removePredecessor(b, yes)
v.Block.Func.removePredecessor(b, yes)
b.Kind = BlockPlain
b.Control = nil
b.Succs = b.Succs[:1]