go/ssa: use sync.Once instead of sync.atomic

This adds a missing memory barrier at the end of Package.Build.

Change-Id: Ife35d5ad5a48ba121f35656fef682863d4f2aef6
Reviewed-on: https://go-review.googlesource.com/14761
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/go/ssa/builder.go b/go/ssa/builder.go
index c2a4a89..3f760d2 100644
--- a/go/ssa/builder.go
+++ b/go/ssa/builder.go
@@ -35,7 +35,6 @@
 	"go/token"
 	"os"
 	"sync"
-	"sync/atomic"
 
 	"golang.org/x/tools/go/exact"
 	"golang.org/x/tools/go/types"
@@ -2241,10 +2240,9 @@
 //
 // Build is idempotent and thread-safe.
 //
-func (p *Package) Build() {
-	if !atomic.CompareAndSwapInt32(&p.started, 0, 1) {
-		return // already started
-	}
+func (p *Package) Build() { p.buildOnce.Do(p.build) }
+
+func (p *Package) build() {
 	if p.info == nil {
 		return // synthetic package, e.g. "testmain"
 	}
diff --git a/go/ssa/ssa.go b/go/ssa/ssa.go
index b24c195..6ea33f5 100644
--- a/go/ssa/ssa.go
+++ b/go/ssa/ssa.go
@@ -53,10 +53,10 @@
 
 	// The following fields are set transiently, then cleared
 	// after building.
-	started int32       // atomically tested and set at start of build phase
-	ninit   int32       // number of init functions
-	info    *types.Info // package type information
-	files   []*ast.File // package ASTs
+	buildOnce sync.Once   // ensures package building occurs once
+	ninit     int32       // number of init functions
+	info      *types.Info // package type information
+	files     []*ast.File // package ASTs
 }
 
 // A Member is a member of a Go package, implemented by *NamedConst,