Commit 9f90f31c authored by Russ Cox's avatar Russ Cox

cmd/compile: allow static init for unsafe.Pointer(&x) where x is global

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/11693Reviewed-by: default avatarAustin Clements <austin@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
parent d6e6baa7
...@@ -302,6 +302,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool { ...@@ -302,6 +302,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool {
orig := r orig := r
r = r.Name.Defn.Right r = r.Name.Defn.Right
for r.Op == OCONVNOP {
r = r.Left
}
switch r.Op { switch r.Op {
case ONAME: case ONAME:
if staticcopy(l, r, out) { if staticcopy(l, r, out) {
...@@ -395,6 +399,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool { ...@@ -395,6 +399,10 @@ func staticcopy(l *Node, r *Node, out **NodeList) bool {
func staticassign(l *Node, r *Node, out **NodeList) bool { func staticassign(l *Node, r *Node, out **NodeList) bool {
var n1 Node var n1 Node
for r.Op == OCONVNOP {
r = r.Left
}
switch r.Op { switch r.Op {
//dump("not static", r); //dump("not static", r);
default: default:
......
...@@ -2194,13 +2194,20 @@ func needwritebarrier(l *Node, r *Node) bool { ...@@ -2194,13 +2194,20 @@ func needwritebarrier(l *Node, r *Node) bool {
return false return false
} }
// No write barrier for implicit or explicit zeroing. // No write barrier for implicit zeroing.
if r == nil || iszero(r) { if r == nil {
return false return false
} }
// No write barrier for initialization to constant. // Ignore no-op conversions when making decision.
if r.Op == OLITERAL { // 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 return false
} }
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
package p package p
import "unsafe"
// Should be no init func in the assembly. // Should be no init func in the assembly.
// All these initializations should be done at link time. // All these initializations should be done at link time.
...@@ -284,3 +286,6 @@ type Mer interface { ...@@ -284,3 +286,6 @@ type Mer interface {
} }
var _ Mer = (*T1)(nil) var _ Mer = (*T1)(nil)
var Byte byte
var PtrByte unsafe.Pointer = unsafe.Pointer(&Byte)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment