]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: allow static init for unsafe.Pointer(&x) where x is global
authorRuss Cox <rsc@golang.org>
Mon, 29 Jun 2015 16:49:25 +0000 (12:49 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 7 Jul 2015 21:51:57 +0000 (21:51 +0000)
This avoids both a write barrier and then dynamic initialization
globals of the form

var x something
var xp = unsafe.Pointer(&x)

Using static initialization avoids emitting a relocation for &x,
which helps cgo.

Fixes #9411.

Change-Id: I0dbf480859cce6ab57ab805d1b8609c45b48f156
Reviewed-on: https://go-review.googlesource.com/11693
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>

src/cmd/compile/internal/gc/sinit.go
src/cmd/compile/internal/gc/walk.go
test/sinit.go

index e1a99d4ca0ee681297bb3c4d393b8b799529ddc4..0ced4ef3b0928bf3cd97fe98db2f5f4a24e2e5b6 100644 (file)
@@ -302,6 +302,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool {
        orig := r
        r = r.Name.Defn.Right
 
+       for r.Op == OCONVNOP {
+               r = r.Left
+       }
+
        switch r.Op {
        case ONAME:
                if staticcopy(l, r, out) {
@@ -395,6 +399,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool {
 func staticassign(l *Node, r *Node, out **NodeList) bool {
        var n1 Node
 
+       for r.Op == OCONVNOP {
+               r = r.Left
+       }
+
        switch r.Op {
        //dump("not static", r);
        default:
index 626b26fec7f3462676656a6eee7f47ca72ab3c52..d89d25efdd8c90f9effe6211ab95c016ff258763 100644 (file)
@@ -2194,13 +2194,20 @@ func needwritebarrier(l *Node, r *Node) bool {
                return false
        }
 
-       // No write barrier for implicit or explicit zeroing.
-       if r == nil || iszero(r) {
+       // No write barrier for implicit zeroing.
+       if r == nil {
                return false
        }
 
-       // No write barrier for initialization to constant.
-       if r.Op == OLITERAL {
+       // Ignore no-op conversions when making decision.
+       // Ensures that xp = unsafe.Pointer(&x) is treated
+       // the same as xp = &x.
+       for r.Op == OCONVNOP {
+               r = r.Left
+       }
+
+       // No write barrier for zeroing or initialization to constant.
+       if iszero(r) || r.Op == OLITERAL {
                return false
        }
 
index df1a4cc930ca784b3ae166f71db16f9f03ab54a5..188a5301a2f35d41e949dea0b26deee61c834898 100644 (file)
@@ -10,6 +10,8 @@
 
 package p
 
+import "unsafe"
+
 // Should be no init func in the assembly.
 // All these initializations should be done at link time.
 
@@ -284,3 +286,6 @@ type Mer interface {
 }
 
 var _ Mer = (*T1)(nil)
+
+var Byte byte
+var PtrByte unsafe.Pointer = unsafe.Pointer(&Byte)