Commit 10f38f51 authored by Keith Randall's avatar Keith Randall

[dev.ssa] cmd/compile/internal/ssa: distinguish exit and return blocks

It is confusing to have exceptional edges jump back into
real code.  Distinguish return blocks, which execute acutal
code, and the exit block, which is a merge point for the regular
and exceptional return flow.

Prevent critical edge insertion from adding blocks on edges
into the exit block.  These added blocks serve no purpose and
add a bunch of dead jumps to the assembly output.  Furthermore,
live variable analysis is confused by these jumps.

Change-Id: Ifd69e6c00e90338ed147e7cb351b5100dc0364df
Reviewed-on: https://go-review.googlesource.com/14254Reviewed-by: default avatarDavid Chase <drchase@google.com>
parent 73024083
...@@ -562,6 +562,7 @@ func (s *state) stmt(n *Node) { ...@@ -562,6 +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()
b.Kind = ssa.BlockRet
b.AddEdgeTo(s.exit) b.AddEdgeTo(s.exit)
case OCONTINUE, OBREAK: case OCONTINUE, OBREAK:
...@@ -3358,6 +3359,7 @@ func genBlock(b, next *ssa.Block, branches []branch) []branch { ...@@ -3358,6 +3359,7 @@ func genBlock(b, next *ssa.Block, branches []branch) []branch {
branches = append(branches, branch{p, b.Succs[0]}) branches = append(branches, branch{p, b.Succs[0]})
} }
case ssa.BlockExit: case ssa.BlockExit:
case ssa.BlockRet:
Prog(obj.ARET) Prog(obj.ARET)
case ssa.BlockCall: case ssa.BlockCall:
if b.Succs[0] != next { if b.Succs[0] != next {
......
...@@ -59,6 +59,16 @@ func checkFunc(f *Func) { ...@@ -59,6 +59,16 @@ func checkFunc(f *Func) {
if !b.Control.Type.IsMemory() { if !b.Control.Type.IsMemory() {
f.Fatalf("exit block %s has non-memory control value %s", b, b.Control.LongString()) f.Fatalf("exit block %s has non-memory control value %s", b, b.Control.LongString())
} }
case BlockRet:
if len(b.Succs) != 1 {
f.Fatalf("ret block %s len(Succs)==%d, want 1", b, len(b.Succs))
}
if b.Control != nil {
f.Fatalf("ret block %s has non-nil control %s", b, b.Control.LongString())
}
if b.Succs[0].Kind != BlockExit {
f.Fatalf("ret block %s has successor %s, not Exit", b, b.Succs[0].Kind)
}
case BlockDead: case BlockDead:
if len(b.Succs) != 0 { if len(b.Succs) != 0 {
f.Fatalf("dead block %s has successors", b) f.Fatalf("dead block %s has successors", b)
......
...@@ -9,7 +9,7 @@ package ssa ...@@ -9,7 +9,7 @@ package ssa
// Regalloc wants a critical-edge-free CFG so it can implement phi values. // Regalloc wants a critical-edge-free CFG so it can implement phi values.
func critical(f *Func) { func critical(f *Func) {
for _, b := range f.Blocks { for _, b := range f.Blocks {
if len(b.Preds) <= 1 { if len(b.Preds) <= 1 || b.Kind == BlockExit {
continue continue
} }
......
...@@ -375,6 +375,7 @@ var genericBlocks = []blockData{ ...@@ -375,6 +375,7 @@ var genericBlocks = []blockData{
{name: "If"}, // 2 successors, if control goto Succs[0] else goto Succs[1] {name: "If"}, // 2 successors, if control goto Succs[0] else goto Succs[1]
{name: "Call"}, // 2 successors, normal return and panic {name: "Call"}, // 2 successors, normal return and panic
{name: "First"}, // 2 successors, always takes the first one (second is dead) {name: "First"}, // 2 successors, always takes the first one (second is dead)
{name: "Ret"}, // 1 successor, branches to exit
} }
func init() { func init() {
......
...@@ -28,6 +28,7 @@ const ( ...@@ -28,6 +28,7 @@ const (
BlockIf BlockIf
BlockCall BlockCall
BlockFirst BlockFirst
BlockRet
) )
var blockString = [...]string{ var blockString = [...]string{
...@@ -54,6 +55,7 @@ var blockString = [...]string{ ...@@ -54,6 +55,7 @@ var blockString = [...]string{
BlockIf: "If", BlockIf: "If",
BlockCall: "Call", BlockCall: "Call",
BlockFirst: "First", BlockFirst: "First",
BlockRet: "Ret",
} }
func (k BlockKind) String() string { return blockString[k] } func (k BlockKind) String() string { return blockString[k] }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment