cmd/internal/gc, cmd/internal/ld, cmd/internal/obj: teach compiler about local symbols

This lets us avoid loading string constants via the GOT and (together with
http://golang.org/cl/9102) results in the fannkuch benchmark having very similar
register usage with -dynlink as without.

Change-Id: Ic3892b399074982b76773c3e547cfbba5dabb6f9
Reviewed-on: https://go-review.googlesource.com/9103
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
diff --git a/src/cmd/internal/gc/gsubr.go b/src/cmd/internal/gc/gsubr.go
index 1f6b7d2..53b3f6c 100644
--- a/src/cmd/internal/gc/gsubr.go
+++ b/src/cmd/internal/gc/gsubr.go
@@ -218,11 +218,15 @@
 	}
 }
 
-func ggloblsym(s *Sym, width int32, flags int8) {
+func ggloblsym(s *Sym, width int32, flags int16) {
 	p := Thearch.Gins(obj.AGLOBL, nil, nil)
 	p.From.Type = obj.TYPE_MEM
 	p.From.Name = obj.NAME_EXTERN
 	p.From.Sym = Linksym(s)
+	if flags&obj.LOCAL != 0 {
+		p.From.Sym.Local = true
+		flags &= ^obj.LOCAL
+	}
 	p.To.Type = obj.TYPE_CONST
 	p.To.Offset = int64(width)
 	p.From3.Offset = int64(flags)
diff --git a/src/cmd/internal/gc/obj.go b/src/cmd/internal/gc/obj.go
index 5885eb5..891f554 100644
--- a/src/cmd/internal/gc/obj.go
+++ b/src/cmd/internal/gc/obj.go
@@ -245,7 +245,7 @@
 
 	off = duint8(sym, off, 0)                    // terminating NUL for runtime
 	off = (off + Widthptr - 1) &^ (Widthptr - 1) // round to pointer alignment
-	ggloblsym(sym, int32(off), obj.DUPOK|obj.RODATA)
+	ggloblsym(sym, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)
 
 	return sym
 }
@@ -269,7 +269,7 @@
 		off = dsname(sym, off, s[n:n+m])
 	}
 
-	ggloblsym(sym, int32(off), obj.NOPTR)
+	ggloblsym(sym, int32(off), obj.NOPTR|obj.LOCAL)
 
 	if nam.Op != ONAME {
 		Fatal("slicebytes %v", nam)
diff --git a/src/cmd/internal/gc/pgen.go b/src/cmd/internal/gc/pgen.go
index 5848f98a..1667a5c 100644
--- a/src/cmd/internal/gc/pgen.go
+++ b/src/cmd/internal/gc/pgen.go
@@ -161,7 +161,7 @@
 		}
 	}
 
-	ggloblsym(sym, int32(off), obj.RODATA)
+	ggloblsym(sym, int32(off), obj.RODATA|obj.LOCAL)
 }
 
 // Sort the list of stack variables. Autos after anything else,
diff --git a/src/cmd/internal/gc/reflect.go b/src/cmd/internal/gc/reflect.go
index 47697be..824ed0b 100644
--- a/src/cmd/internal/gc/reflect.go
+++ b/src/cmd/internal/gc/reflect.go
@@ -814,7 +814,7 @@
 			for i := 0; i < 2*Widthptr; i++ {
 				duint8(sbits, i, gcmask[i])
 			}
-			ggloblsym(sbits, 2*int32(Widthptr), obj.DUPOK|obj.RODATA)
+			ggloblsym(sbits, 2*int32(Widthptr), obj.DUPOK|obj.RODATA|obj.LOCAL)
 		}
 
 		ot = dsymptr(s, ot, sbits, 0)
@@ -1203,7 +1203,7 @@
 	}
 
 	ot = dextratype(s, ot, t, xt)
-	ggloblsym(s, int32(ot), int8(dupok|obj.RODATA))
+	ggloblsym(s, int32(ot), int16(dupok|obj.RODATA))
 
 	// generate typelink.foo pointing at s = type.foo.
 	// The linker will leave a table of all the typelinks for
@@ -1229,7 +1229,7 @@
 		case TARRAY, TCHAN, TFUNC, TMAP:
 			slink := typelinksym(t)
 			dsymptr(slink, 0, s, 0)
-			ggloblsym(slink, int32(Widthptr), int8(dupok|obj.RODATA))
+			ggloblsym(slink, int32(Widthptr), int16(dupok|obj.RODATA))
 		}
 	}