1
0
mirror of https://github.com/golang/go synced 2024-10-05 18:31:28 -06:00

[dev.ssa] cmd/compile: move addEdge function to ssa

addEdge had two identical implementations so make it an exported method
on Block.

Change-Id: I8c21655a9dc5074fefd7f63b2f5b51897571e608
Reviewed-on: https://go-review.googlesource.com/14040
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Todd Neal 2015-08-28 21:36:29 -05:00
parent 67e43c1e3b
commit 47d6799b0f
3 changed files with 53 additions and 57 deletions

View File

@ -114,7 +114,7 @@ func buildssa(fn *Node) (ssafn *ssa.Func, usessa bool) {
// fallthrough to exit // fallthrough to exit
if b := s.endBlock(); b != nil { if b := s.endBlock(); b != nil {
addEdge(b, s.exit) b.AddEdgeTo(s.exit)
} }
// Finish up exit block // Finish up exit block
@ -487,7 +487,7 @@ func (s *state) stmt(n *Node) {
// go to that label (we pretend "label:" is preceded by "goto label") // go to that label (we pretend "label:" is preceded by "goto label")
b := s.endBlock() b := s.endBlock()
addEdge(b, lab.target) b.AddEdgeTo(lab.target)
s.startBlock(lab.target) s.startBlock(lab.target)
case OGOTO: case OGOTO:
@ -508,7 +508,7 @@ func (s *state) stmt(n *Node) {
} }
b := s.endBlock() b := s.endBlock()
addEdge(b, lab.target) b.AddEdgeTo(lab.target)
case OAS, OASWB: case OAS, OASWB:
// Check whether we can generate static data rather than code. // Check whether we can generate static data rather than code.
@ -536,25 +536,25 @@ func (s *state) stmt(n *Node) {
var bElse *ssa.Block var bElse *ssa.Block
if n.Rlist == nil { if n.Rlist == nil {
addEdge(b, bThen) b.AddEdgeTo(bThen)
addEdge(b, bEnd) b.AddEdgeTo(bEnd)
} else { } else {
bElse = s.f.NewBlock(ssa.BlockPlain) bElse = s.f.NewBlock(ssa.BlockPlain)
addEdge(b, bThen) b.AddEdgeTo(bThen)
addEdge(b, bElse) b.AddEdgeTo(bElse)
} }
s.startBlock(bThen) s.startBlock(bThen)
s.stmtList(n.Nbody) s.stmtList(n.Nbody)
if b := s.endBlock(); b != nil { if b := s.endBlock(); b != nil {
addEdge(b, bEnd) b.AddEdgeTo(bEnd)
} }
if n.Rlist != nil { if n.Rlist != nil {
s.startBlock(bElse) s.startBlock(bElse)
s.stmtList(n.Rlist) s.stmtList(n.Rlist)
if b := s.endBlock(); b != nil { if b := s.endBlock(); b != nil {
addEdge(b, bEnd) b.AddEdgeTo(bEnd)
} }
} }
s.startBlock(bEnd) s.startBlock(bEnd)
@ -562,7 +562,7 @@ func (s *state) stmt(n *Node) {
case ORETURN: case ORETURN:
s.stmtList(n.List) s.stmtList(n.List)
b := s.endBlock() b := s.endBlock()
addEdge(b, s.exit) b.AddEdgeTo(s.exit)
case OCONTINUE, OBREAK: case OCONTINUE, OBREAK:
var op string var op string
@ -614,7 +614,7 @@ func (s *state) stmt(n *Node) {
} }
b := s.endBlock() b := s.endBlock()
addEdge(b, to) b.AddEdgeTo(to)
case OFOR: case OFOR:
// OFOR: for Ninit; Left; Right { Nbody } // OFOR: for Ninit; Left; Right { Nbody }
@ -625,7 +625,7 @@ func (s *state) stmt(n *Node) {
// first, jump to condition test // first, jump to condition test
b := s.endBlock() b := s.endBlock()
addEdge(b, bCond) b.AddEdgeTo(bCond)
// generate code to test condition // generate code to test condition
s.startBlock(bCond) s.startBlock(bCond)
@ -639,8 +639,8 @@ func (s *state) stmt(n *Node) {
b.Kind = ssa.BlockIf b.Kind = ssa.BlockIf
b.Control = cond b.Control = cond
b.Likely = ssa.BranchLikely b.Likely = ssa.BranchLikely
addEdge(b, bBody) b.AddEdgeTo(bBody)
addEdge(b, bEnd) b.AddEdgeTo(bEnd)
// set up for continue/break in body // set up for continue/break in body
prevContinue := s.continueTo prevContinue := s.continueTo
@ -668,7 +668,7 @@ func (s *state) stmt(n *Node) {
// done with body, goto incr // done with body, goto incr
if b := s.endBlock(); b != nil { if b := s.endBlock(); b != nil {
addEdge(b, bIncr) b.AddEdgeTo(bIncr)
} }
// generate incr // generate incr
@ -677,7 +677,7 @@ func (s *state) stmt(n *Node) {
s.stmt(n.Right) s.stmt(n.Right)
} }
if b := s.endBlock(); b != nil { if b := s.endBlock(); b != nil {
addEdge(b, bCond) b.AddEdgeTo(bCond)
} }
s.startBlock(bEnd) s.startBlock(bEnd)
@ -703,7 +703,7 @@ func (s *state) stmt(n *Node) {
} }
if b := s.endBlock(); b != nil { if b := s.endBlock(); b != nil {
addEdge(b, bEnd) b.AddEdgeTo(bEnd)
} }
s.startBlock(bEnd) s.startBlock(bEnd)
@ -1447,11 +1447,11 @@ func (s *state) expr(n *Node) *ssa.Value {
bRight := s.f.NewBlock(ssa.BlockPlain) bRight := s.f.NewBlock(ssa.BlockPlain)
bResult := s.f.NewBlock(ssa.BlockPlain) bResult := s.f.NewBlock(ssa.BlockPlain)
if n.Op == OANDAND { if n.Op == OANDAND {
addEdge(b, bRight) b.AddEdgeTo(bRight)
addEdge(b, bResult) b.AddEdgeTo(bResult)
} else if n.Op == OOROR { } else if n.Op == OOROR {
addEdge(b, bResult) b.AddEdgeTo(bResult)
addEdge(b, bRight) b.AddEdgeTo(bRight)
} }
s.startBlock(bRight) s.startBlock(bRight)
@ -1459,7 +1459,7 @@ func (s *state) expr(n *Node) *ssa.Value {
s.vars[n] = er s.vars[n] = er
b = s.endBlock() b = s.endBlock()
addEdge(b, bResult) b.AddEdgeTo(bResult)
s.startBlock(bResult) s.startBlock(bResult)
return s.variable(n, Types[TBOOL]) return s.variable(n, Types[TBOOL])
@ -1599,15 +1599,15 @@ func (s *state) expr(n *Node) *ssa.Value {
// Generate code for non-zero length slice case. // Generate code for non-zero length slice case.
nz := s.f.NewBlock(ssa.BlockPlain) nz := s.f.NewBlock(ssa.BlockPlain)
addEdge(b, nz) b.AddEdgeTo(nz)
s.startBlock(nz) s.startBlock(nz)
s.vars[n] = s.newValue2(ssa.OpAddPtr, Ptrto(Types[TUINT8]), ptr, low) s.vars[n] = s.newValue2(ssa.OpAddPtr, Ptrto(Types[TUINT8]), ptr, low)
s.endBlock() s.endBlock()
// All done. // All done.
merge := s.f.NewBlock(ssa.BlockPlain) merge := s.f.NewBlock(ssa.BlockPlain)
addEdge(b, merge) b.AddEdgeTo(merge)
addEdge(nz, merge) nz.AddEdgeTo(merge)
s.startBlock(merge) s.startBlock(merge)
return s.newValue2(ssa.OpStringMake, Types[TSTRING], s.variable(n, Ptrto(Types[TUINT8])), rlen) return s.newValue2(ssa.OpStringMake, Types[TSTRING], s.variable(n, Ptrto(Types[TUINT8])), rlen)
@ -1654,8 +1654,8 @@ func (s *state) expr(n *Node) *ssa.Value {
b := s.endBlock() b := s.endBlock()
b.Kind = ssa.BlockCall b.Kind = ssa.BlockCall
b.Control = call b.Control = call
addEdge(b, bNext) b.AddEdgeTo(bNext)
addEdge(b, s.exit) b.AddEdgeTo(s.exit)
// read result from stack at the start of the fallthrough block // read result from stack at the start of the fallthrough block
s.startBlock(bNext) s.startBlock(bNext)
@ -1928,9 +1928,9 @@ func (s *state) nilCheck(ptr *ssa.Value) {
b.Likely = ssa.BranchLikely b.Likely = ssa.BranchLikely
bNext := s.f.NewBlock(ssa.BlockPlain) bNext := s.f.NewBlock(ssa.BlockPlain)
bPanic := s.f.NewBlock(ssa.BlockPlain) bPanic := s.f.NewBlock(ssa.BlockPlain)
addEdge(b, bNext) b.AddEdgeTo(bNext)
addEdge(b, bPanic) b.AddEdgeTo(bPanic)
addEdge(bPanic, s.exit) bPanic.AddEdgeTo(s.exit)
s.startBlock(bPanic) s.startBlock(bPanic)
// TODO: implicit nil checks somehow? // TODO: implicit nil checks somehow?
s.vars[&memvar] = s.newValue2(ssa.OpPanicNilCheck, ssa.TypeMem, ptr, s.mem()) s.vars[&memvar] = s.newValue2(ssa.OpPanicNilCheck, ssa.TypeMem, ptr, s.mem())
@ -1974,9 +1974,9 @@ func (s *state) check(cmp *ssa.Value, panicOp ssa.Op) {
b.Likely = ssa.BranchLikely b.Likely = ssa.BranchLikely
bNext := s.f.NewBlock(ssa.BlockPlain) bNext := s.f.NewBlock(ssa.BlockPlain)
bPanic := s.f.NewBlock(ssa.BlockPlain) bPanic := s.f.NewBlock(ssa.BlockPlain)
addEdge(b, bNext) b.AddEdgeTo(bNext)
addEdge(b, bPanic) b.AddEdgeTo(bPanic)
addEdge(bPanic, s.exit) bPanic.AddEdgeTo(s.exit)
s.startBlock(bPanic) s.startBlock(bPanic)
// The panic check takes/returns memory to ensure that the right // The panic check takes/returns memory to ensure that the right
// memory state is observed if the panic happens. // memory state is observed if the panic happens.
@ -2068,14 +2068,14 @@ func (s *state) uintTofloat(cvttab *u2fcvtTab, n *Node, x *ssa.Value, ft, tt *Ty
bElse := s.f.NewBlock(ssa.BlockPlain) bElse := s.f.NewBlock(ssa.BlockPlain)
bAfter := s.f.NewBlock(ssa.BlockPlain) bAfter := s.f.NewBlock(ssa.BlockPlain)
addEdge(b, bThen) b.AddEdgeTo(bThen)
s.startBlock(bThen) s.startBlock(bThen)
a0 := s.newValue1(cvttab.cvt2F, tt, x) a0 := s.newValue1(cvttab.cvt2F, tt, x)
s.vars[n] = a0 s.vars[n] = a0
s.endBlock() s.endBlock()
addEdge(bThen, bAfter) bThen.AddEdgeTo(bAfter)
addEdge(b, bElse) b.AddEdgeTo(bElse)
s.startBlock(bElse) s.startBlock(bElse)
one := cvttab.one(s, ft, 1) one := cvttab.one(s, ft, 1)
y := s.newValue2(cvttab.and, ft, x, one) y := s.newValue2(cvttab.and, ft, x, one)
@ -2085,7 +2085,7 @@ func (s *state) uintTofloat(cvttab *u2fcvtTab, n *Node, x *ssa.Value, ft, tt *Ty
a1 := s.newValue2(cvttab.add, tt, a, a) a1 := s.newValue2(cvttab.add, tt, a, a)
s.vars[n] = a1 s.vars[n] = a1
s.endBlock() s.endBlock()
addEdge(bElse, bAfter) bElse.AddEdgeTo(bAfter)
s.startBlock(bAfter) s.startBlock(bAfter)
return s.variable(n, n.Type) return s.variable(n, n.Type)
@ -2117,13 +2117,13 @@ func (s *state) referenceTypeBuiltin(n *Node, x *ssa.Value) *ssa.Value {
bAfter := s.f.NewBlock(ssa.BlockPlain) bAfter := s.f.NewBlock(ssa.BlockPlain)
// length/capacity of a nil map/chan is zero // length/capacity of a nil map/chan is zero
addEdge(b, bThen) b.AddEdgeTo(bThen)
s.startBlock(bThen) s.startBlock(bThen)
s.vars[n] = s.zeroVal(lenType) s.vars[n] = s.zeroVal(lenType)
s.endBlock() s.endBlock()
addEdge(bThen, bAfter) bThen.AddEdgeTo(bAfter)
addEdge(b, bElse) b.AddEdgeTo(bElse)
s.startBlock(bElse) s.startBlock(bElse)
if n.Op == OLEN { if n.Op == OLEN {
// length is stored in the first word for map/chan // length is stored in the first word for map/chan
@ -2136,7 +2136,7 @@ func (s *state) referenceTypeBuiltin(n *Node, x *ssa.Value) *ssa.Value {
s.Fatalf("op must be OLEN or OCAP") s.Fatalf("op must be OLEN or OCAP")
} }
s.endBlock() s.endBlock()
addEdge(bElse, bAfter) bElse.AddEdgeTo(bAfter)
s.startBlock(bAfter) s.startBlock(bAfter)
return s.variable(n, lenType) return s.variable(n, lenType)
@ -2187,14 +2187,14 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *Ty
bElse := s.f.NewBlock(ssa.BlockPlain) bElse := s.f.NewBlock(ssa.BlockPlain)
bAfter := s.f.NewBlock(ssa.BlockPlain) bAfter := s.f.NewBlock(ssa.BlockPlain)
addEdge(b, bThen) b.AddEdgeTo(bThen)
s.startBlock(bThen) s.startBlock(bThen)
a0 := s.newValue1(cvttab.cvt2U, tt, x) a0 := s.newValue1(cvttab.cvt2U, tt, x)
s.vars[n] = a0 s.vars[n] = a0
s.endBlock() s.endBlock()
addEdge(bThen, bAfter) bThen.AddEdgeTo(bAfter)
addEdge(b, bElse) b.AddEdgeTo(bElse)
s.startBlock(bElse) s.startBlock(bElse)
y := s.newValue2(cvttab.subf, ft, x, twoToThe63) y := s.newValue2(cvttab.subf, ft, x, twoToThe63)
y = s.newValue1(cvttab.cvt2U, tt, y) y = s.newValue1(cvttab.cvt2U, tt, y)
@ -2202,7 +2202,7 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *Ty
a1 := s.newValue2(ssa.OpOr64, tt, y, z) a1 := s.newValue2(ssa.OpOr64, tt, y, z)
s.vars[n] = a1 s.vars[n] = a1
s.endBlock() s.endBlock()
addEdge(bElse, bAfter) bElse.AddEdgeTo(bAfter)
s.startBlock(bAfter) s.startBlock(bAfter)
return s.variable(n, n.Type) return s.variable(n, n.Type)
@ -2366,12 +2366,6 @@ func (s *state) lookupVarOutgoing(b *ssa.Block, t ssa.Type, name *Node) *ssa.Val
// TODO: the above mutually recursive functions can lead to very deep stacks. Fix that. // TODO: the above mutually recursive functions can lead to very deep stacks. Fix that.
// addEdge adds an edge from b to c.
func addEdge(b, c *ssa.Block) {
b.Succs = append(b.Succs, c)
c.Preds = append(c.Preds, b)
}
// an unresolved branch // an unresolved branch
type branch struct { type branch struct {
p *obj.Prog // branch instruction p *obj.Prog // branch instruction

View File

@ -83,6 +83,13 @@ func (b *Block) LongString() string {
return s return s
} }
// AddEdgeTo adds an edge from block b to block c. Used during building of the
// SSA graph; do not use on an already-completed SSA graph.
func (b *Block) AddEdgeTo(c *Block) {
b.Succs = append(b.Succs, c)
c.Preds = append(c.Preds, b)
}
func (b *Block) Logf(msg string, args ...interface{}) { b.Func.Logf(msg, args...) } func (b *Block) Logf(msg string, args ...interface{}) { b.Func.Logf(msg, args...) }
func (b *Block) Fatalf(msg string, args ...interface{}) { b.Func.Fatalf(msg, args...) } func (b *Block) Fatalf(msg string, args ...interface{}) { b.Func.Fatalf(msg, args...) }
func (b *Block) Unimplementedf(msg string, args ...interface{}) { b.Func.Unimplementedf(msg, args...) } func (b *Block) Unimplementedf(msg string, args ...interface{}) { b.Func.Unimplementedf(msg, args...) }

View File

@ -179,7 +179,7 @@ func Fun(c *Config, entry string, blocs ...bloc) fun {
} }
// Connect to successors. // Connect to successors.
for _, succ := range c.succs { for _, succ := range c.succs {
addEdge(b, blocks[succ]) b.AddEdgeTo(blocks[succ])
} }
} }
return fun{f, blocks, values} return fun{f, blocks, values}
@ -256,11 +256,6 @@ type valu struct {
args []string args []string
} }
func addEdge(b, c *Block) {
b.Succs = append(b.Succs, c)
c.Preds = append(c.Preds, b)
}
func TestArgs(t *testing.T) { func TestArgs(t *testing.T) {
c := testConfig(t) c := testConfig(t)
fun := Fun(c, "entry", fun := Fun(c, "entry",