mirror of
https://github.com/golang/go.git
synced 2025-05-29 03:11:26 +00: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:
parent
67e43c1e3b
commit
47d6799b0f
@ -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
|
||||||
|
@ -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...) }
|
||||||
|
@ -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",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user