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:
parent
cc3f031a31
commit
7d10a2c04a
@ -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())
|
||||
|
@ -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})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user