// fallthrough to exit
if b := s.endBlock(); b != nil {
- addEdge(b, s.exit)
+ b.AddEdgeTo(s.exit)
}
// Finish up exit block
// go to that label (we pretend "label:" is preceded by "goto label")
b := s.endBlock()
- addEdge(b, lab.target)
+ b.AddEdgeTo(lab.target)
s.startBlock(lab.target)
case OGOTO:
}
b := s.endBlock()
- addEdge(b, lab.target)
+ b.AddEdgeTo(lab.target)
case OAS, OASWB:
// Check whether we can generate static data rather than code.
var bElse *ssa.Block
if n.Rlist == nil {
- addEdge(b, bThen)
- addEdge(b, bEnd)
+ b.AddEdgeTo(bThen)
+ b.AddEdgeTo(bEnd)
} else {
bElse = s.f.NewBlock(ssa.BlockPlain)
- addEdge(b, bThen)
- addEdge(b, bElse)
+ b.AddEdgeTo(bThen)
+ b.AddEdgeTo(bElse)
}
s.startBlock(bThen)
s.stmtList(n.Nbody)
if b := s.endBlock(); b != nil {
- addEdge(b, bEnd)
+ b.AddEdgeTo(bEnd)
}
if n.Rlist != nil {
s.startBlock(bElse)
s.stmtList(n.Rlist)
if b := s.endBlock(); b != nil {
- addEdge(b, bEnd)
+ b.AddEdgeTo(bEnd)
}
}
s.startBlock(bEnd)
case ORETURN:
s.stmtList(n.List)
b := s.endBlock()
- addEdge(b, s.exit)
+ b.AddEdgeTo(s.exit)
case OCONTINUE, OBREAK:
var op string
}
b := s.endBlock()
- addEdge(b, to)
+ b.AddEdgeTo(to)
case OFOR:
// OFOR: for Ninit; Left; Right { Nbody }
// first, jump to condition test
b := s.endBlock()
- addEdge(b, bCond)
+ b.AddEdgeTo(bCond)
// generate code to test condition
s.startBlock(bCond)
b.Kind = ssa.BlockIf
b.Control = cond
b.Likely = ssa.BranchLikely
- addEdge(b, bBody)
- addEdge(b, bEnd)
+ b.AddEdgeTo(bBody)
+ b.AddEdgeTo(bEnd)
// set up for continue/break in body
prevContinue := s.continueTo
// done with body, goto incr
if b := s.endBlock(); b != nil {
- addEdge(b, bIncr)
+ b.AddEdgeTo(bIncr)
}
// generate incr
s.stmt(n.Right)
}
if b := s.endBlock(); b != nil {
- addEdge(b, bCond)
+ b.AddEdgeTo(bCond)
}
s.startBlock(bEnd)
}
if b := s.endBlock(); b != nil {
- addEdge(b, bEnd)
+ b.AddEdgeTo(bEnd)
}
s.startBlock(bEnd)
bRight := s.f.NewBlock(ssa.BlockPlain)
bResult := s.f.NewBlock(ssa.BlockPlain)
if n.Op == OANDAND {
- addEdge(b, bRight)
- addEdge(b, bResult)
+ b.AddEdgeTo(bRight)
+ b.AddEdgeTo(bResult)
} else if n.Op == OOROR {
- addEdge(b, bResult)
- addEdge(b, bRight)
+ b.AddEdgeTo(bResult)
+ b.AddEdgeTo(bRight)
}
s.startBlock(bRight)
s.vars[n] = er
b = s.endBlock()
- addEdge(b, bResult)
+ b.AddEdgeTo(bResult)
s.startBlock(bResult)
return s.variable(n, Types[TBOOL])
// Generate code for non-zero length slice case.
nz := s.f.NewBlock(ssa.BlockPlain)
- addEdge(b, nz)
+ b.AddEdgeTo(nz)
s.startBlock(nz)
s.vars[n] = s.newValue2(ssa.OpAddPtr, Ptrto(Types[TUINT8]), ptr, low)
s.endBlock()
// All done.
merge := s.f.NewBlock(ssa.BlockPlain)
- addEdge(b, merge)
- addEdge(nz, merge)
+ b.AddEdgeTo(merge)
+ nz.AddEdgeTo(merge)
s.startBlock(merge)
return s.newValue2(ssa.OpStringMake, Types[TSTRING], s.variable(n, Ptrto(Types[TUINT8])), rlen)
b := s.endBlock()
b.Kind = ssa.BlockCall
b.Control = call
- addEdge(b, bNext)
- addEdge(b, s.exit)
+ b.AddEdgeTo(bNext)
+ b.AddEdgeTo(s.exit)
// read result from stack at the start of the fallthrough block
s.startBlock(bNext)
b.Likely = ssa.BranchLikely
bNext := s.f.NewBlock(ssa.BlockPlain)
bPanic := s.f.NewBlock(ssa.BlockPlain)
- addEdge(b, bNext)
- addEdge(b, bPanic)
- addEdge(bPanic, s.exit)
+ b.AddEdgeTo(bNext)
+ b.AddEdgeTo(bPanic)
+ bPanic.AddEdgeTo(s.exit)
s.startBlock(bPanic)
// TODO: implicit nil checks somehow?
s.vars[&memvar] = s.newValue2(ssa.OpPanicNilCheck, ssa.TypeMem, ptr, s.mem())
b.Likely = ssa.BranchLikely
bNext := s.f.NewBlock(ssa.BlockPlain)
bPanic := s.f.NewBlock(ssa.BlockPlain)
- addEdge(b, bNext)
- addEdge(b, bPanic)
- addEdge(bPanic, s.exit)
+ b.AddEdgeTo(bNext)
+ b.AddEdgeTo(bPanic)
+ bPanic.AddEdgeTo(s.exit)
s.startBlock(bPanic)
// The panic check takes/returns memory to ensure that the right
// memory state is observed if the panic happens.
bElse := s.f.NewBlock(ssa.BlockPlain)
bAfter := s.f.NewBlock(ssa.BlockPlain)
- addEdge(b, bThen)
+ b.AddEdgeTo(bThen)
s.startBlock(bThen)
a0 := s.newValue1(cvttab.cvt2F, tt, x)
s.vars[n] = a0
s.endBlock()
- addEdge(bThen, bAfter)
+ bThen.AddEdgeTo(bAfter)
- addEdge(b, bElse)
+ b.AddEdgeTo(bElse)
s.startBlock(bElse)
one := cvttab.one(s, ft, 1)
y := s.newValue2(cvttab.and, ft, x, one)
a1 := s.newValue2(cvttab.add, tt, a, a)
s.vars[n] = a1
s.endBlock()
- addEdge(bElse, bAfter)
+ bElse.AddEdgeTo(bAfter)
s.startBlock(bAfter)
return s.variable(n, n.Type)
bAfter := s.f.NewBlock(ssa.BlockPlain)
// length/capacity of a nil map/chan is zero
- addEdge(b, bThen)
+ b.AddEdgeTo(bThen)
s.startBlock(bThen)
s.vars[n] = s.zeroVal(lenType)
s.endBlock()
- addEdge(bThen, bAfter)
+ bThen.AddEdgeTo(bAfter)
- addEdge(b, bElse)
+ b.AddEdgeTo(bElse)
s.startBlock(bElse)
if n.Op == OLEN {
// length is stored in the first word for map/chan
s.Fatalf("op must be OLEN or OCAP")
}
s.endBlock()
- addEdge(bElse, bAfter)
+ bElse.AddEdgeTo(bAfter)
s.startBlock(bAfter)
return s.variable(n, lenType)
bElse := s.f.NewBlock(ssa.BlockPlain)
bAfter := s.f.NewBlock(ssa.BlockPlain)
- addEdge(b, bThen)
+ b.AddEdgeTo(bThen)
s.startBlock(bThen)
a0 := s.newValue1(cvttab.cvt2U, tt, x)
s.vars[n] = a0
s.endBlock()
- addEdge(bThen, bAfter)
+ bThen.AddEdgeTo(bAfter)
- addEdge(b, bElse)
+ b.AddEdgeTo(bElse)
s.startBlock(bElse)
y := s.newValue2(cvttab.subf, ft, x, twoToThe63)
y = s.newValue1(cvttab.cvt2U, tt, y)
a1 := s.newValue2(ssa.OpOr64, tt, y, z)
s.vars[n] = a1
s.endBlock()
- addEdge(bElse, bAfter)
+ bElse.AddEdgeTo(bAfter)
s.startBlock(bAfter)
return s.variable(n, n.Type)
// 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
type branch struct {
p *obj.Prog // branch instruction