[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/14254
Reviewed-by: David Chase <drchase@google.com>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 77c8227..f0cad90 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -562,6 +562,7 @@
 	case ORETURN:
 		s.stmtList(n.List)
 		b := s.endBlock()
+		b.Kind = ssa.BlockRet
 		b.AddEdgeTo(s.exit)
 
 	case OCONTINUE, OBREAK:
@@ -3358,6 +3359,7 @@
 			branches = append(branches, branch{p, b.Succs[0]})
 		}
 	case ssa.BlockExit:
+	case ssa.BlockRet:
 		Prog(obj.ARET)
 	case ssa.BlockCall:
 		if b.Succs[0] != next {