]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: call fninit earlier
authorMatthew Dempsky <mdempsky@google.com>
Mon, 14 Sep 2020 19:56:37 +0000 (12:56 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Mon, 14 Sep 2020 23:42:44 +0000 (23:42 +0000)
This allows the global initializers function to go through normal
mid-end optimizations (e.g., inlining, escape analysis) like any other
function.

Updates #33485.

Change-Id: I9bcfe98b8628d1aca09b4c238d8d3b74c69010a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/254839
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/gc/init.go
src/cmd/compile/internal/gc/main.go
test/inline.go

index 94cbcf98467254dec26d8d8efcd63ced6efe354c..ec9cc4bddc54bcc320401f79bf09cec694ad0075 100644 (file)
@@ -59,7 +59,7 @@ func fninit(n []*Node) {
                Curfn = fn
                typecheckslice(nf, ctxStmt)
                Curfn = nil
-               funccompile(fn)
+               xtop = append(xtop, fn)
                fns = append(fns, initializers.Linksym())
        }
        if dummyInitFn.Func.Dcl != nil {
@@ -68,16 +68,14 @@ func fninit(n []*Node) {
                // something's weird if we get here.
                Fatalf("dummyInitFn still has declarations")
        }
+       dummyInitFn = nil
 
        // Record user init functions.
        for i := 0; i < renameinitgen; i++ {
                s := lookupN("init.", i)
                fn := asNode(s.Def).Name.Defn
                // Skip init functions with empty bodies.
-               // noder.go doesn't allow external init functions, and
-               // order.go has already removed any OEMPTY nodes, so
-               // checking Len() == 0 is sufficient here.
-               if fn.Nbody.Len() == 0 {
+               if fn.Nbody.Len() == 1 && fn.Nbody.First().Op == OEMPTY {
                        continue
                }
                fns = append(fns, s.Linksym())
index 9bce6cf8cb461ef715596a99065bdfcf86ca4c47..8783cb4e4636a1ede30f6be1ae6508dbbbbbafe8 100644 (file)
@@ -642,6 +642,8 @@ func Main(archInit func(*Arch)) {
                errorexit()
        }
 
+       fninit(xtop)
+
        // Phase 4: Decide how to capture closed variables.
        // This needs to run before escape analysis,
        // because variables captured by value do not escape.
@@ -751,10 +753,6 @@ func Main(archInit func(*Arch)) {
        }
        timings.AddEvent(fcount, "funcs")
 
-       if nsavederrors+nerrors == 0 {
-               fninit(xtop)
-       }
-
        compileFunctions()
 
        if nowritebarrierrecCheck != nil {
index 0b3ad55d466f3c02b10262a98541cbe6b5f96ab2..1c5c1bc8d36ebc317cee129687b6f54b14fdf012 100644 (file)
@@ -50,7 +50,7 @@ func j(x int) int { // ERROR "can inline j"
        }
 }
 
-var somethingWrong error = errors.New("something went wrong")
+var somethingWrong error = errors.New("something went wrong") // ERROR "can inline init" "inlining call to errors.New" "errors.errorString.* escapes to heap"
 
 // local closures can be inlined
 func l(x, y int) (int, int, error) {