From: Josh Bleecher Snyder Date: Mon, 6 Jul 2015 22:29:39 +0000 (-0700) Subject: [dev.ssa] cmd/compile/ssa: place for loop incr in a separate block X-Git-Tag: go1.7beta1~1623^2^2~405 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=517386832582a54e6b4170252e52f1a13c001e83;p=gostls13.git [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 --- diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 866db610b8..96ae49a179 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -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)