]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: port callnew to ssa conversion
authorJosh Bleecher Snyder <josharian@gmail.com>
Sun, 17 Mar 2019 14:14:12 +0000 (07:14 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 20 Mar 2019 19:38:50 +0000 (19:38 +0000)
This is part of a general effort to shrink walk.
In an ideal world, we'd have an SSA op for allocation,
but we don't yet have a good mechanism for introducing
function calling during SSA compilation.
In the meantime, SSA conversion is a better place for it.

This also makes it easier to introduce new optimizations;
instead of doing the typecheck walk dance,
we can simply write what we want the backend to do.

I introduced a new opcode in this change because:

(a) It avoids a class of bugs involving correctly detecting
    whether this ONEW is a "before walk" ONEW or an "after walk" ONEW.
    It also means that using ONEW or ONEWOBJ in the wrong context
    will generally result in a faster failure.
(b) Opcodes are cheap.
(c) It provides a better place to put documentation.

This change also is also marginally more performant:

name        old alloc/op      new alloc/op      delta
Template         39.1MB ± 0%       39.0MB ± 0%  -0.14%  (p=0.008 n=5+5)
Unicode          28.4MB ± 0%       28.4MB ± 0%    ~     (p=0.421 n=5+5)
GoTypes           132MB ± 0%        132MB ± 0%  -0.23%  (p=0.008 n=5+5)
Compiler          608MB ± 0%        607MB ± 0%  -0.25%  (p=0.008 n=5+5)
SSA              2.04GB ± 0%       2.04GB ± 0%  -0.01%  (p=0.008 n=5+5)
Flate            24.4MB ± 0%       24.3MB ± 0%  -0.13%  (p=0.008 n=5+5)
GoParser         29.3MB ± 0%       29.1MB ± 0%  -0.54%  (p=0.008 n=5+5)
Reflect          84.8MB ± 0%       84.7MB ± 0%  -0.21%  (p=0.008 n=5+5)
Tar              36.7MB ± 0%       36.6MB ± 0%  -0.10%  (p=0.008 n=5+5)
XML              48.7MB ± 0%       48.6MB ± 0%  -0.24%  (p=0.008 n=5+5)
[Geo mean]       85.0MB            84.8MB       -0.19%

name        old allocs/op     new allocs/op     delta
Template           383k ± 0%         382k ± 0%  -0.26%  (p=0.008 n=5+5)
Unicode            341k ± 0%         341k ± 0%    ~     (p=0.579 n=5+5)
GoTypes           1.37M ± 0%        1.36M ± 0%  -0.39%  (p=0.008 n=5+5)
Compiler          5.59M ± 0%        5.56M ± 0%  -0.49%  (p=0.008 n=5+5)
SSA               16.9M ± 0%        16.9M ± 0%  -0.03%  (p=0.008 n=5+5)
Flate              238k ± 0%         238k ± 0%  -0.23%  (p=0.008 n=5+5)
GoParser           306k ± 0%         303k ± 0%  -0.93%  (p=0.008 n=5+5)
Reflect            990k ± 0%         987k ± 0%  -0.33%  (p=0.008 n=5+5)
Tar                356k ± 0%         355k ± 0%  -0.20%  (p=0.008 n=5+5)
XML                444k ± 0%         442k ± 0%  -0.45%  (p=0.008 n=5+5)
[Geo mean]         848k              845k       -0.33%

Change-Id: I2c36003a7cbf71b53857b7de734852b698f49310
Reviewed-on: https://go-review.googlesource.com/c/go/+/167957
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/op_string.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/syntax.go
src/cmd/compile/internal/gc/walk.go

index 5f2c3289095434a46d24f25dc1c4424dc2da50c6..6123e6acc17c5190c06535e76f924789677e059c 100644 (file)
@@ -295,6 +295,7 @@ var (
        growslice,
        msanread,
        msanwrite,
+       newobject,
        newproc,
        panicdivide,
        panicshift,
@@ -312,7 +313,8 @@ var (
        typedmemclr,
        typedmemmove,
        Udiv,
-       writeBarrier *obj.LSym
+       writeBarrier,
+       zerobaseSym *obj.LSym
 
        BoundsCheckFunc [ssa.BoundsKindCount]*obj.LSym
        ExtendCheckFunc [ssa.BoundsKindCount]*obj.LSym
index 54fce2409eb0a42ff7ce636de4d1d68b361ad6f5..af55df68a3360270498caf436f0e9815beeb69b9 100644 (file)
@@ -4,9 +4,9 @@ package gc
 
 import "strconv"
 
-const _Op_name = "XXXNAMENONAMETYPEPACKLITERALADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2FUNCAS2RECVAS2MAPRAS2DOTTYPEASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFBLOCKBREAKCASEXCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDDDDARGINLCALLEFACEITABIDATASPTRCLOSUREVARCFUNCCHECKNILVARDEFVARKILLVARLIVEINDREGSPINLMARKRETJMPGETGEND"
+const _Op_name = "XXXNAMENONAMETYPEPACKLITERALADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2FUNCAS2RECVAS2MAPRAS2DOTTYPEASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLFIELDDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMULDIVMODLSHRSHANDANDNOTNEWNEWOBJNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECVSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFBLOCKBREAKCASEXCASECONTINUEDEFEREMPTYFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYDDDDDDARGINLCALLEFACEITABIDATASPTRCLOSUREVARCFUNCCHECKNILVARDEFVARKILLVARLIVEINDREGSPINLMARKRETJMPGETGEND"
 
-var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 36, 39, 45, 49, 55, 61, 70, 82, 91, 100, 112, 121, 123, 126, 133, 140, 147, 157, 161, 165, 173, 181, 190, 198, 201, 206, 213, 220, 226, 235, 243, 251, 257, 261, 270, 277, 281, 284, 291, 299, 307, 314, 320, 323, 329, 336, 344, 348, 355, 363, 365, 367, 369, 371, 373, 375, 380, 385, 393, 396, 405, 408, 412, 420, 427, 436, 439, 442, 445, 448, 451, 454, 460, 463, 466, 472, 476, 479, 483, 488, 493, 499, 504, 508, 513, 521, 529, 535, 544, 555, 562, 566, 573, 580, 588, 592, 596, 600, 607, 614, 622, 628, 633, 638, 642, 647, 655, 660, 665, 669, 672, 680, 684, 686, 691, 693, 698, 704, 710, 716, 722, 727, 731, 738, 744, 749, 755, 758, 764, 771, 776, 780, 785, 789, 799, 804, 812, 818, 825, 832, 840, 847, 853, 857, 860}
+var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 36, 39, 45, 49, 55, 61, 70, 82, 91, 100, 112, 121, 123, 126, 133, 140, 147, 157, 161, 165, 173, 181, 190, 198, 201, 206, 213, 220, 226, 235, 243, 251, 257, 261, 270, 277, 281, 284, 291, 299, 307, 314, 320, 323, 329, 336, 344, 348, 355, 363, 365, 367, 369, 371, 373, 375, 380, 385, 393, 396, 405, 408, 412, 420, 427, 436, 439, 442, 445, 448, 451, 454, 460, 463, 469, 472, 478, 482, 485, 489, 494, 499, 505, 510, 514, 519, 527, 535, 541, 550, 561, 568, 572, 579, 586, 594, 598, 602, 606, 613, 620, 628, 634, 639, 644, 648, 653, 661, 666, 671, 675, 678, 686, 690, 692, 697, 699, 704, 710, 716, 722, 728, 733, 737, 744, 750, 755, 761, 764, 770, 777, 782, 786, 791, 795, 805, 810, 818, 824, 831, 838, 846, 853, 859, 863, 866}
 
 func (i Op) String() string {
        if i >= Op(len(_Op_index)-1) {
index aa2e2c19c9597ae6b23f7199a347c03d767b1fcb..52515bdb1da1426d64a280c71fea07e2565d2c80 100644 (file)
@@ -76,6 +76,7 @@ func initssaconfig() {
        growslice = sysfunc("growslice")
        msanread = sysfunc("msanread")
        msanwrite = sysfunc("msanwrite")
+       newobject = sysfunc("newobject")
        newproc = sysfunc("newproc")
        panicdivide = sysfunc("panicdivide")
        panicdottypeE = sysfunc("panicdottypeE")
@@ -94,6 +95,8 @@ func initssaconfig() {
        typedmemmove = sysfunc("typedmemmove")
        Udiv = sysvar("udiv")                 // asm func with special ABI
        writeBarrier = sysvar("writeBarrier") // struct { bool; ... }
+       zerobaseSym = sysvar("zerobase")
+
        if thearch.LinkArch.Family == sys.Wasm {
                BoundsCheckFunc[ssa.BoundsIndex] = sysvar("goPanicIndex")
                BoundsCheckFunc[ssa.BoundsIndexU] = sysvar("goPanicIndexU")
@@ -2453,6 +2456,14 @@ func (s *state) expr(n *Node) *ssa.Value {
                }
                return s.zeroVal(n.Type)
 
+       case ONEWOBJ:
+               if n.Type.Elem().Size() == 0 {
+                       return s.newValue1A(ssa.OpAddr, n.Type, zerobaseSym, s.sb)
+               }
+               typ := s.expr(n.Left)
+               vv := s.rtcall(newobject, true, []*types.Type{n.Type}, typ)
+               return vv[0]
+
        default:
                s.Fatalf("unhandled expr %v", n.Op)
                return nil
index 5f07c6c52ad25e8b60591d7b8ee8758bd32d34e2..278633489e4b40c35ccce6f64a5b112ce19bea75 100644 (file)
@@ -668,7 +668,8 @@ const (
        ORSH         // Left >> Right
        OAND         // Left & Right
        OANDNOT      // Left &^ Right
-       ONEW         // new(Left)
+       ONEW         // new(Left); corresponds to calls to new in source code
+       ONEWOBJ      // runtime.newobject(n.Type); introduced by walk; Left is type descriptor
        ONOT         // !Left
        OBITNOT      // ^Left
        OPLUS        // +Left
index 77f578197cef53581b973c836d2ea6be5ab90a8d..3533a3e230e3f7a4720ba8b87e8102f7a41b7fd4 100644 (file)
@@ -481,7 +481,7 @@ opswitch:
                Dump("walk", n)
                Fatalf("walkexpr: switch 1 unknown op %+S", n)
 
-       case ONONAME, OINDREGSP, OEMPTY, OGETG:
+       case ONONAME, OINDREGSP, OEMPTY, OGETG, ONEWOBJ:
 
        case OTYPE, ONAME, OLITERAL:
                // TODO(mdempsky): Just return n; see discussion on CL 38655.
@@ -1944,21 +1944,11 @@ func callnew(t *types.Type) *Node {
                yyerror("%v is go:notinheap; heap allocation disallowed", t)
        }
        dowidth(t)
-
-       if t.Size() == 0 {
-               // Return &runtime.zerobase if we know that the requested size is 0.
-               // This is what runtime.mallocgc would return.
-               z := newname(Runtimepkg.Lookup("zerobase"))
-               z.SetClass(PEXTERN)
-               z.Type = t
-               return typecheck(nod(OADDR, z, nil), ctxExpr)
-       }
-
-       fn := syslook("newobject")
-       fn = substArgTypes(fn, t)
-       v := mkcall1(fn, types.NewPtr(t), nil, typename(t))
-       v.SetNonNil(true)
-       return v
+       n := nod(ONEWOBJ, typename(t), nil)
+       n.Type = types.NewPtr(t)
+       n.SetTypecheck(1)
+       n.SetNonNil(true)
+       return n
 }
 
 // isReflectHeaderDataField reports whether l is an expression p.Data