cmd/compile: generalize racewalk to instrument (naming change)

This is mechanical change that is a step toward reusing the racewalk
pass for a more general instrumentation pass.  The first use will be to
add support for the memory sanitizer.

Change-Id: I75b93b814ac60c1db1660e0b9a9a7d7977d86939
Reviewed-on: https://go-review.googlesource.com/16105
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index f250c95..79b9d9f 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -647,6 +647,10 @@
 
 var flag_largemodel int
 
+// Whether we are adding any sort of code instrumentation, such as
+// when the race detector is enabled.
+var instrumenting bool
+
 // Pending annotations for next func declaration.
 var (
 	noescape       bool
diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go
index 1f9b473..cb165f4 100644
--- a/src/cmd/compile/internal/gc/inl.go
+++ b/src/cmd/compile/internal/gc/inl.go
@@ -124,13 +124,13 @@
 		}
 	}
 
-	// Runtime package must not be race instrumented.
-	// Racewalk skips runtime package. However, some runtime code can be
+	// Runtime package must not be instrumented.
+	// Instrument skips runtime package. However, some runtime code can be
 	// inlined into other packages and instrumented there. To avoid this,
-	// we disable inlining of runtime functions in race mode.
+	// we disable inlining of runtime functions when instrumenting.
 	// The example that we observed is inlining of LockOSThread,
 	// which lead to false race reports on m contents.
-	if flag_race != 0 && myimportpath == "runtime" {
+	if instrumenting && myimportpath == "runtime" {
 		return
 	}
 
diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 81198f3..b9ce4cb 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -249,6 +249,7 @@
 	if flag_race != 0 {
 		racepkg = mkpkg("runtime/race")
 		racepkg.Name = "race"
+		instrumenting = true
 	}
 
 	// parse -d argument
diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go
index c783d64..f996ce2 100644
--- a/src/cmd/compile/internal/gc/order.go
+++ b/src/cmd/compile/internal/gc/order.go
@@ -434,7 +434,7 @@
 				a = Nod(OAS, m, l.N)
 				typecheck(&a, Etop)
 				post = list(post, a)
-			} else if flag_race != 0 && n.Op == OAS2FUNC && !isblank(l.N) {
+			} else if instrumenting && n.Op == OAS2FUNC && !isblank(l.N) {
 				m = l.N
 				l.N = ordertemp(m.Type, order, false)
 				a = Nod(OAS, m, l.N)
@@ -1093,7 +1093,7 @@
 		OREAL,
 		ORECOVER:
 		ordercall(n, order)
-		if lhs == nil || lhs.Op != ONAME || flag_race != 0 {
+		if lhs == nil || lhs.Op != ONAME || instrumenting {
 			n = ordercopyexpr(n, n.Type, order, 0)
 		}
 
@@ -1153,7 +1153,7 @@
 		// TODO(rsc): The Isfat is for consistency with componentgen and walkexpr.
 		// It needs to be removed in all three places.
 		// That would allow inlining x.(struct{*int}) the same as x.(*int).
-		if !isdirectiface(n.Type) || Isfat(n.Type) || flag_race != 0 {
+		if !isdirectiface(n.Type) || Isfat(n.Type) || instrumenting {
 			n = ordercopyexpr(n, n.Type, order, 1)
 		}
 
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
index cd8e66c..015d2fd 100644
--- a/src/cmd/compile/internal/gc/pgen.go
+++ b/src/cmd/compile/internal/gc/pgen.go
@@ -399,8 +399,8 @@
 	if nerrors != 0 {
 		goto ret
 	}
-	if flag_race != 0 {
-		racewalk(Curfn)
+	if instrumenting {
+		instrument(Curfn)
 	}
 	if nerrors != 0 {
 		goto ret
diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go
index 5d10fc1..a2b09cd 100644
--- a/src/cmd/compile/internal/gc/racewalk.go
+++ b/src/cmd/compile/internal/gc/racewalk.go
@@ -9,7 +9,9 @@
 	"strings"
 )
 
-// The racewalk pass modifies the code tree for the function as follows:
+// The instrument pass modifies the code tree for instrumentation.
+//
+// For flag_race it modifies the function as follows:
 //
 // 1. It inserts a call to racefuncenter at the beginning of each function.
 // 2. It inserts a call to racefuncexit at the end of each function.
@@ -42,16 +44,16 @@
 	return false
 }
 
-func racewalk(fn *Node) {
+func instrument(fn *Node) {
 	if ispkgin(omit_pkgs) || fn.Func.Norace {
 		return
 	}
 
 	if !ispkgin(noinst_pkgs) {
-		racewalklist(fn.Nbody, nil)
+		instrumentlist(fn.Nbody, nil)
 
 		// nothing interesting for race detector in fn->enter
-		racewalklist(fn.Func.Exit, nil)
+		instrumentlist(fn.Func.Exit, nil)
 	}
 
 	// nodpc is the PC of the caller as extracted by
@@ -68,7 +70,7 @@
 	fn.Func.Exit = list(fn.Func.Exit, nd)
 
 	if Debug['W'] != 0 {
-		s := fmt.Sprintf("after racewalk %v", fn.Func.Nname.Sym)
+		s := fmt.Sprintf("after instrument %v", fn.Func.Nname.Sym)
 		dumplist(s, fn.Nbody)
 		s = fmt.Sprintf("enter %v", fn.Func.Nname.Sym)
 		dumplist(s, fn.Func.Enter)
@@ -77,12 +79,12 @@
 	}
 }
 
-func racewalklist(l *NodeList, init **NodeList) {
+func instrumentlist(l *NodeList, init **NodeList) {
 	var instr *NodeList
 
 	for ; l != nil; l = l.Next {
 		instr = nil
-		racewalknode(&l.N, &instr, 0, 0)
+		instrumentnode(&l.N, &instr, 0, 0)
 		if init == nil {
 			l.N.Ninit = concat(l.N.Ninit, instr)
 		} else {
@@ -94,7 +96,7 @@
 // walkexpr and walkstmt combined
 // walks the tree and adds calls to the
 // instrumentation code to top-level (statement) nodes' init
-func racewalknode(np **Node, init **NodeList, wr int, skip int) {
+func instrumentnode(np **Node, init **NodeList, wr int, skip int) {
 	n := *np
 
 	if n == nil {
@@ -102,35 +104,35 @@
 	}
 
 	if Debug['w'] > 1 {
-		Dump("racewalk-before", n)
+		Dump("instrument-before", n)
 	}
 	setlineno(n)
 	if init == nil {
-		Fatalf("racewalk: bad init list")
+		Fatalf("instrument: bad init list")
 	}
 	if init == &n.Ninit {
 		// If init == &n->ninit and n->ninit is non-nil,
-		// racewalknode might append it to itself.
+		// instrumentnode might append it to itself.
 		// nil it out and handle it separately before putting it back.
 		l := n.Ninit
 
 		n.Ninit = nil
-		racewalklist(l, nil)
-		racewalknode(&n, &l, wr, skip) // recurse with nil n->ninit
+		instrumentlist(l, nil)
+		instrumentnode(&n, &l, wr, skip) // recurse with nil n->ninit
 		appendinit(&n, l)
 		*np = n
 		return
 	}
 
-	racewalklist(n.Ninit, nil)
+	instrumentlist(n.Ninit, nil)
 
 	switch n.Op {
 	default:
-		Fatalf("racewalk: unknown node type %v", Oconv(int(n.Op), 0))
+		Fatalf("instrument: unknown node type %v", Oconv(int(n.Op), 0))
 
 	case OAS, OASWB, OAS2FUNC:
-		racewalknode(&n.Left, init, 1, 0)
-		racewalknode(&n.Right, init, 0, 0)
+		instrumentnode(&n.Left, init, 1, 0)
+		instrumentnode(&n.Right, init, 0, 0)
 		goto ret
 
 		// can't matter
@@ -142,7 +144,7 @@
 		for l := n.List; l != nil; l = l.Next {
 			switch l.N.Op {
 			case OCALLFUNC, OCALLMETH, OCALLINTER:
-				racewalknode(&l.N, &out, 0, 0)
+				instrumentnode(&l.N, &out, 0, 0)
 				out = list(out, l.N)
 				// Scan past OAS nodes copying results off stack.
 				// Those must not be instrumented, because the
@@ -154,7 +156,7 @@
 					out = list(out, l.N)
 				}
 			default:
-				racewalknode(&l.N, &out, 0, 0)
+				instrumentnode(&l.N, &out, 0, 0)
 				out = list(out, l.N)
 			}
 		}
@@ -162,22 +164,22 @@
 		goto ret
 
 	case ODEFER:
-		racewalknode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
 		goto ret
 
 	case OPROC:
-		racewalknode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
 		goto ret
 
 	case OCALLINTER:
-		racewalknode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
 		goto ret
 
 		// Instrument dst argument of runtime.writebarrier* calls
 	// as we do not instrument runtime code.
 	// typedslicecopy is instrumented in runtime.
 	case OCALLFUNC:
-		racewalknode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
 		goto ret
 
 	case ONOT,
@@ -187,32 +189,32 @@
 		OIMAG,
 		OCOM,
 		OSQRT:
-		racewalknode(&n.Left, init, wr, 0)
+		instrumentnode(&n.Left, init, wr, 0)
 		goto ret
 
 	case ODOTINTER:
-		racewalknode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
 		goto ret
 
 	case ODOT:
-		racewalknode(&n.Left, init, 0, 1)
+		instrumentnode(&n.Left, init, 0, 1)
 		callinstr(&n, init, wr, skip)
 		goto ret
 
 	case ODOTPTR: // dst = (*x).f with implicit *; otherwise it's ODOT+OIND
-		racewalknode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
 
 		callinstr(&n, init, wr, skip)
 		goto ret
 
 	case OIND: // *p
-		racewalknode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
 
 		callinstr(&n, init, wr, skip)
 		goto ret
 
 	case OSPTR, OLEN, OCAP:
-		racewalknode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
 		if Istype(n.Left.Type, TMAP) {
 			n1 := Nod(OCONVNOP, n.Left, nil)
 			n1.Type = Ptrto(Types[TUINT8])
@@ -241,18 +243,18 @@
 		OGT,
 		OADD,
 		OCOMPLEX:
-		racewalknode(&n.Left, init, wr, 0)
-		racewalknode(&n.Right, init, wr, 0)
+		instrumentnode(&n.Left, init, wr, 0)
+		instrumentnode(&n.Right, init, wr, 0)
 		goto ret
 
 	case OANDAND, OOROR:
-		racewalknode(&n.Left, init, wr, 0)
+		instrumentnode(&n.Left, init, wr, 0)
 
 		// walk has ensured the node has moved to a location where
 		// side effects are safe.
 		// n->right may not be executed,
 		// so instrumentation goes to n->right->ninit, not init.
-		racewalknode(&n.Right, &n.Right.Ninit, wr, 0)
+		instrumentnode(&n.Right, &n.Right.Ninit, wr, 0)
 
 		goto ret
 
@@ -261,57 +263,57 @@
 		goto ret
 
 	case OCONV:
-		racewalknode(&n.Left, init, wr, 0)
+		instrumentnode(&n.Left, init, wr, 0)
 		goto ret
 
 	case OCONVNOP:
-		racewalknode(&n.Left, init, wr, 0)
+		instrumentnode(&n.Left, init, wr, 0)
 		goto ret
 
 	case ODIV, OMOD:
-		racewalknode(&n.Left, init, wr, 0)
-		racewalknode(&n.Right, init, wr, 0)
+		instrumentnode(&n.Left, init, wr, 0)
+		instrumentnode(&n.Right, init, wr, 0)
 		goto ret
 
 	case OINDEX:
 		if !Isfixedarray(n.Left.Type) {
-			racewalknode(&n.Left, init, 0, 0)
+			instrumentnode(&n.Left, init, 0, 0)
 		} else if !islvalue(n.Left) {
 			// index of unaddressable array, like Map[k][i].
-			racewalknode(&n.Left, init, wr, 0)
+			instrumentnode(&n.Left, init, wr, 0)
 
-			racewalknode(&n.Right, init, 0, 0)
+			instrumentnode(&n.Right, init, 0, 0)
 			goto ret
 		}
 
-		racewalknode(&n.Right, init, 0, 0)
+		instrumentnode(&n.Right, init, 0, 0)
 		if n.Left.Type.Etype != TSTRING {
 			callinstr(&n, init, wr, skip)
 		}
 		goto ret
 
 	case OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR:
-		racewalknode(&n.Left, init, 0, 0)
-		racewalknode(&n.Right, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Right, init, 0, 0)
 		goto ret
 
 	case OKEY:
-		racewalknode(&n.Left, init, 0, 0)
-		racewalknode(&n.Right, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Right, init, 0, 0)
 		goto ret
 
 	case OADDR:
-		racewalknode(&n.Left, init, 0, 1)
+		instrumentnode(&n.Left, init, 0, 1)
 		goto ret
 
 		// n->left is Type* which is not interesting.
 	case OEFACE:
-		racewalknode(&n.Right, init, 0, 0)
+		instrumentnode(&n.Right, init, 0, 0)
 
 		goto ret
 
 	case OITAB:
-		racewalknode(&n.Left, init, 0, 0)
+		instrumentnode(&n.Left, init, 0, 0)
 		goto ret
 
 		// should not appear in AST by now
@@ -355,31 +357,31 @@
 		OAS2RECV,
 		OAS2MAPR,
 		OASOP:
-		Yyerror("racewalk: %v must be lowered by now", Oconv(int(n.Op), 0))
+		Yyerror("instrument: %v must be lowered by now", Oconv(int(n.Op), 0))
 
 		goto ret
 
 		// impossible nodes: only appear in backend.
 	case ORROTC, OEXTEND:
-		Yyerror("racewalk: %v cannot exist now", Oconv(int(n.Op), 0))
+		Yyerror("instrument: %v cannot exist now", Oconv(int(n.Op), 0))
 		goto ret
 
 	case OGETG:
-		Yyerror("racewalk: OGETG can happen only in runtime which we don't instrument")
+		Yyerror("instrument: OGETG can happen only in runtime which we don't instrument")
 		goto ret
 
 	case OFOR:
 		if n.Left != nil {
-			racewalknode(&n.Left, &n.Left.Ninit, 0, 0)
+			instrumentnode(&n.Left, &n.Left.Ninit, 0, 0)
 		}
 		if n.Right != nil {
-			racewalknode(&n.Right, &n.Right.Ninit, 0, 0)
+			instrumentnode(&n.Right, &n.Right.Ninit, 0, 0)
 		}
 		goto ret
 
 	case OIF, OSWITCH:
 		if n.Left != nil {
-			racewalknode(&n.Left, &n.Left.Ninit, 0, 0)
+			instrumentnode(&n.Left, &n.Left.Ninit, 0, 0)
 		}
 		goto ret
 
@@ -416,10 +418,10 @@
 
 ret:
 	if n.Op != OBLOCK { // OBLOCK is handled above in a special way.
-		racewalklist(n.List, init)
+		instrumentlist(n.List, init)
 	}
-	racewalklist(n.Nbody, nil)
-	racewalklist(n.Rlist, nil)
+	instrumentlist(n.Nbody, nil)
+	instrumentlist(n.Rlist, nil)
 	*np = n
 }
 
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go
index 59f7d40..0beee4e 100644
--- a/src/cmd/compile/internal/gc/range.go
+++ b/src/cmd/compile/internal/gc/range.go
@@ -340,7 +340,7 @@
 //
 // Parameters are as in walkrange: "for v1, v2 = range a".
 func memclrrange(n, v1, v2, a *Node) bool {
-	if Debug['N'] != 0 || flag_race != 0 {
+	if Debug['N'] != 0 || instrumenting {
 		return false
 	}
 	if v1 == nil || v2 != nil {
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index df6b6f6..c73c675 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -1645,7 +1645,7 @@
 
 		// hard with race detector
 	case OANDAND, OOROR:
-		if flag_race != 0 {
+		if instrumenting {
 			ul = UINF
 			goto out
 		}
@@ -2405,7 +2405,7 @@
 	dot := adddot(Nod(OXDOT, this.Left, newname(method.Sym)))
 
 	// generate call
-	if flag_race == 0 && Isptr[rcvr.Etype] && Isptr[methodrcvr.Etype] && method.Embedded != 0 && !isifacemethod(method.Type) {
+	if !instrumenting && Isptr[rcvr.Etype] && Isptr[methodrcvr.Etype] && method.Embedded != 0 && !isifacemethod(method.Type) {
 		// generate tail call: adjust pointer receiver and jump to embedded method.
 		dot = dot.Left // skip final .M
 		if !Isptr[dotlist[0].field.Type.Etype] {
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 2afa05c6..f0a1ddc 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -237,7 +237,7 @@
 			walkprintfunc(&n.Left, &n.Ninit)
 
 		case OCOPY:
-			n.Left = copyany(n.Left, &n.Ninit, 1)
+			n.Left = copyany(n.Left, &n.Ninit, true)
 
 		default:
 			walkexpr(&n.Left, &n.Ninit)
@@ -269,7 +269,7 @@
 			walkprintfunc(&n.Left, &n.Ninit)
 
 		case OCOPY:
-			n.Left = copyany(n.Left, &n.Ninit, 1)
+			n.Left = copyany(n.Left, &n.Ninit, true)
 
 		default:
 			walkexpr(&n.Left, &n.Ninit)
@@ -678,7 +678,7 @@
 			goto ret
 		}
 
-		if n.Right == nil || iszero(n.Right) && flag_race == 0 {
+		if n.Right == nil || iszero(n.Right) && !instrumenting {
 			goto ret
 		}
 
@@ -690,7 +690,7 @@
 			// TODO(rsc): The Isfat is for consistency with componentgen and orderexpr.
 			// It needs to be removed in all three places.
 			// That would allow inlining x.(struct{*int}) the same as x.(*int).
-			if isdirectiface(n.Right.Type) && !Isfat(n.Right.Type) && flag_race == 0 {
+			if isdirectiface(n.Right.Type) && !Isfat(n.Right.Type) && !instrumenting {
 				// handled directly during cgen
 				walkexpr(&n.Right, init)
 				break
@@ -895,7 +895,7 @@
 		// TODO(rsc): The Isfat is for consistency with componentgen and orderexpr.
 		// It needs to be removed in all three places.
 		// That would allow inlining x.(struct{*int}) the same as x.(*int).
-		if isdirectiface(e.Type) && !Isfat(e.Type) && flag_race == 0 {
+		if isdirectiface(e.Type) && !Isfat(e.Type) && !instrumenting {
 			// handled directly during gen.
 			walkexprlistsafe(n.List, init)
 			walkexpr(&e.Left, init)
@@ -1412,7 +1412,7 @@
 		Fatalf("append outside assignment")
 
 	case OCOPY:
-		n = copyany(n, init, flag_race)
+		n = copyany(n, init, instrumenting)
 		goto ret
 
 		// cannot use chanfn - closechan takes any, not chan any
@@ -2938,7 +2938,7 @@
 		substArgTypes(fn, l1.Type, l2.Type)
 		nt := mkcall1(fn, Types[TINT], &l, typename(l1.Type.Type), nptr1, nptr2)
 		l = list(l, nt)
-	} else if flag_race != 0 {
+	} else if instrumenting {
 		// rely on runtime to instrument copy.
 		// copy(s[len(l1):len(l1)+len(l2)], l2)
 		nptr1 := Nod(OSLICE, s, Nod(OKEY, Nod(OLEN, l1, nil), Nod(OADD, Nod(OLEN, l1, nil), Nod(OLEN, l2, nil))))
@@ -3038,7 +3038,7 @@
 
 	// General case, with no function calls left as arguments.
 	// Leave for gen, except that race detector requires old form
-	if flag_race == 0 {
+	if !instrumenting {
 		return n
 	}
 
@@ -3091,13 +3091,13 @@
 //
 // Also works if b is a string.
 //
-func copyany(n *Node, init **NodeList, runtimecall int) *Node {
+func copyany(n *Node, init **NodeList, runtimecall bool) *Node {
 	if haspointers(n.Left.Type.Type) {
 		fn := writebarrierfn("typedslicecopy", n.Left.Type, n.Right.Type)
 		return mkcall1(fn, n.Type, init, typename(n.Left.Type.Type), n.Left, n.Right)
 	}
 
-	if runtimecall != 0 {
+	if runtimecall {
 		var fn *Node
 		if n.Right.Type.Etype == TSTRING {
 			fn = syslook("slicestringcopy", 1)