mirror of
https://github.com/golang/go
synced 2024-10-05 22:21:23 -06:00
[dev.ssa] cmd/compile/ssa: place for loop incr in a separate block
This is a prerequisite for implementing break and continue; blocks ending in break or continue need to have the increment block as a successor. While we're here, implement for loops with no condition. Change-Id: I85d8ba020628d805bfd0bd583dfd16e1be6f6fae Reviewed-on: https://go-review.googlesource.com/11941 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
41dafe6ecc
commit
5173868325
@ -379,8 +379,10 @@ func (s *state) stmt(n *Node) {
|
|||||||
addEdge(b, s.exit)
|
addEdge(b, s.exit)
|
||||||
|
|
||||||
case OFOR:
|
case OFOR:
|
||||||
|
// OFOR: for Ninit; Left; Right { Nbody }
|
||||||
bCond := s.f.NewBlock(ssa.BlockPlain)
|
bCond := s.f.NewBlock(ssa.BlockPlain)
|
||||||
bBody := s.f.NewBlock(ssa.BlockPlain)
|
bBody := s.f.NewBlock(ssa.BlockPlain)
|
||||||
|
bIncr := s.f.NewBlock(ssa.BlockPlain)
|
||||||
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
||||||
|
|
||||||
// first, jump to condition test
|
// first, jump to condition test
|
||||||
@ -388,13 +390,14 @@ func (s *state) stmt(n *Node) {
|
|||||||
addEdge(b, bCond)
|
addEdge(b, bCond)
|
||||||
|
|
||||||
// generate code to test condition
|
// generate code to test condition
|
||||||
// TODO(khr): Left == nil exception
|
|
||||||
if n.Left == nil {
|
|
||||||
s.Unimplementedf("cond n.Left == nil: %v", n)
|
|
||||||
}
|
|
||||||
s.startBlock(bCond)
|
s.startBlock(bCond)
|
||||||
|
var cond *ssa.Value
|
||||||
|
if n.Left != nil {
|
||||||
s.stmtList(n.Left.Ninit)
|
s.stmtList(n.Left.Ninit)
|
||||||
cond := s.expr(n.Left)
|
cond = s.expr(n.Left)
|
||||||
|
} else {
|
||||||
|
cond = s.entryNewValue0A(ssa.OpConst, Types[TBOOL], true)
|
||||||
|
}
|
||||||
b = s.endBlock()
|
b = s.endBlock()
|
||||||
b.Kind = ssa.BlockIf
|
b.Kind = ssa.BlockIf
|
||||||
b.Control = cond
|
b.Control = cond
|
||||||
@ -405,13 +408,16 @@ func (s *state) stmt(n *Node) {
|
|||||||
// generate body
|
// generate body
|
||||||
s.startBlock(bBody)
|
s.startBlock(bBody)
|
||||||
s.stmtList(n.Nbody)
|
s.stmtList(n.Nbody)
|
||||||
|
if b := s.endBlock(); b != nil {
|
||||||
|
addEdge(b, bIncr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate incr
|
||||||
|
s.startBlock(bIncr)
|
||||||
if n.Right != nil {
|
if n.Right != nil {
|
||||||
s.stmt(n.Right)
|
s.stmt(n.Right)
|
||||||
}
|
}
|
||||||
b = s.endBlock()
|
if b := s.endBlock(); b != nil {
|
||||||
// If the body ends in a return statement,
|
|
||||||
// the condition check and loop are unreachable.
|
|
||||||
if b != nil {
|
|
||||||
addEdge(b, bCond)
|
addEdge(b, bCond)
|
||||||
}
|
}
|
||||||
s.startBlock(bEnd)
|
s.startBlock(bEnd)
|
||||||
|
Loading…
Reference in New Issue
Block a user