cmd/compile: don't export unneeded OAS, OASWB nodes

Also:
- "rewrite" node Op in exporter for some nodes instead of importer
- more comments

Change-Id: I809e6754d14987b28f1da9379951ffa2e690c2a7
Reviewed-on: https://go-review.googlesource.com/22008
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go
index 59a85c2..e0810f9 100644
--- a/src/cmd/compile/internal/gc/bexport.go
+++ b/src/cmd/compile/internal/gc/bexport.go
@@ -783,7 +783,11 @@
 		// supply the parameter package here. We need the package
 		// when the function is inlined so we can properly resolve
 		// the name.
-		// TODO(gri) should do this only once per function/method
+		// TODO(gri) This is compiler-specific. Try using importpkg
+		// here and then update the symbols if we find an inlined
+		// body only. Otherwise, the parameter name is ignored and
+		// the package doesn't matter. This would remove an int
+		// (likely 1 byte) for each named parameter.
 		p.pkg(q.Sym.Pkg)
 	}
 	// TODO(gri) This is compiler-specific (escape info).
@@ -1266,12 +1270,11 @@
 	//	unimplemented - handled by default case
 
 	case OAS, OASWB:
-		p.op(op)
 		// Don't export "v = <N>" initializing statements, hope they're always
 		// preceded by the DCL which will be re-parsed and typecheck to reproduce
 		// the "v = <N>" again.
-		// TODO(gri) if n.Right == nil, don't emit anything
-		if p.bool(n.Right != nil) {
+		if n.Right != nil {
+			p.op(OAS)
 			p.expr(n.Left)
 			p.expr(n.Right)
 		}
@@ -1284,16 +1287,14 @@
 			p.expr(n.Right)
 		}
 
+	case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
+		fallthrough
+
 	case OAS2:
 		p.op(OAS2)
 		p.exprList(n.List)
 		p.exprList(n.Rlist)
 
-	case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
-		p.op(op)
-		p.exprList(n.List)
-		p.exprList(n.Rlist)
-
 	case ORETURN:
 		p.op(ORETURN)
 		p.exprList(n.List)
@@ -1332,11 +1333,15 @@
 		p.stmtList(n.List)
 
 	case OCASE, OXCASE:
-		p.op(op)
+		p.op(OXCASE)
 		p.stmtList(n.List)
 		p.stmtList(n.Nbody)
 
-	case OBREAK, OCONTINUE, OGOTO, OFALL, OXFALL:
+	case OFALL:
+		op = OXFALL
+		fallthrough
+
+	case OBREAK, OCONTINUE, OGOTO, OXFALL:
 		p.op(op)
 		p.exprsOrNil(n.Left, nil)
 
diff --git a/src/cmd/compile/internal/gc/bimport.go b/src/cmd/compile/internal/gc/bimport.go
index 4a93b5a..223cc44 100644
--- a/src/cmd/compile/internal/gc/bimport.go
+++ b/src/cmd/compile/internal/gc/bimport.go
@@ -626,6 +626,10 @@
 // re-establish the syntax tree's invariants. At some future point we might be
 // able to avoid this round-about way and create the rewritten nodes directly,
 // possibly avoiding a lot of duplicate work (name resolution, type checking).
+//
+// Refined nodes (e.g., ODOTPTR as a refinement of OXDOT) are exported as their
+// unrefined nodes (since this is what the importer uses). The respective case
+// entries are unreachable in the importer.
 
 func (p *importer) stmtList() []*Node {
 	var list []*Node
@@ -871,14 +875,11 @@
 	// case ODCLFIELD:
 	//	unimplemented
 
-	case OAS, OASWB:
-		if p.bool() {
-			lhs := p.expr()
-			rhs := p.expr()
-			return Nod(OAS, lhs, rhs)
-		}
-		// TODO(gri) we should not have emitted anything here
-		return Nod(OEMPTY, nil, nil)
+	// case OAS, OASWB:
+	// 	unreachable - mapped to OAS case below by exporter
+
+	case OAS:
+		return Nod(OAS, p.expr(), p.expr())
 
 	case OASOP:
 		n := Nod(OASOP, nil, nil)
@@ -892,15 +893,10 @@
 		}
 		return n
 
-	case OAS2:
-		lhs := p.exprList()
-		rhs := p.exprList()
-		n := Nod(OAS2, nil, nil)
-		n.List.Set(lhs)
-		n.Rlist.Set(rhs)
-		return n
+	// case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
+	// 	unreachable - mapped to OAS2 case below by exporter
 
-	case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
+	case OAS2:
 		n := Nod(OAS2, nil, nil)
 		n.List.Set(p.exprList())
 		n.Rlist.Set(p.exprList())
@@ -954,7 +950,10 @@
 		popdcl()
 		return n
 
-	case OCASE, OXCASE:
+	// case OCASE, OXCASE:
+	// 	unreachable - mapped to OXCASE case below by exporter
+
+	case OXCASE:
 		markdcl()
 		n := Nod(OXCASE, nil, nil)
 		n.List.Set(p.exprList())
@@ -964,10 +963,10 @@
 		popdcl()
 		return n
 
-	case OBREAK, OCONTINUE, OGOTO, OFALL, OXFALL:
-		if op == OFALL {
-			op = OXFALL
-		}
+	// case OFALL:
+	// 	unreachable - mapped to OXFALL case below by exporter
+
+	case OBREAK, OCONTINUE, OGOTO, OXFALL:
 		left, _ := p.exprsOrNil()
 		return Nod(op, left, nil)