mirror of
https://github.com/golang/go
synced 2024-10-05 20:31:20 -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)
|
||||
|
||||
case OFOR:
|
||||
// OFOR: for Ninit; Left; Right { Nbody }
|
||||
bCond := s.f.NewBlock(ssa.BlockPlain)
|
||||
bBody := s.f.NewBlock(ssa.BlockPlain)
|
||||
bIncr := s.f.NewBlock(ssa.BlockPlain)
|
||||
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
||||
|
||||
// first, jump to condition test
|
||||
@ -388,13 +390,14 @@ func (s *state) stmt(n *Node) {
|
||||
addEdge(b, bCond)
|
||||
|
||||
// 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.stmtList(n.Left.Ninit)
|
||||
cond := s.expr(n.Left)
|
||||
var cond *ssa.Value
|
||||
if n.Left != nil {
|
||||
s.stmtList(n.Left.Ninit)
|
||||
cond = s.expr(n.Left)
|
||||
} else {
|
||||
cond = s.entryNewValue0A(ssa.OpConst, Types[TBOOL], true)
|
||||
}
|
||||
b = s.endBlock()
|
||||
b.Kind = ssa.BlockIf
|
||||
b.Control = cond
|
||||
@ -405,13 +408,16 @@ func (s *state) stmt(n *Node) {
|
||||
// generate body
|
||||
s.startBlock(bBody)
|
||||
s.stmtList(n.Nbody)
|
||||
if b := s.endBlock(); b != nil {
|
||||
addEdge(b, bIncr)
|
||||
}
|
||||
|
||||
// generate incr
|
||||
s.startBlock(bIncr)
|
||||
if n.Right != nil {
|
||||
s.stmt(n.Right)
|
||||
}
|
||||
b = s.endBlock()
|
||||
// If the body ends in a return statement,
|
||||
// the condition check and loop are unreachable.
|
||||
if b != nil {
|
||||
if b := s.endBlock(); b != nil {
|
||||
addEdge(b, bCond)
|
||||
}
|
||||
s.startBlock(bEnd)
|
||||
|
Loading…
Reference in New Issue
Block a user