Skip to content

Commit 23b476a

Browse files
committed
cmd/compile: port callnew to ssa conversion
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent fd270d8 commit 23b476a

File tree

5 files changed

+24
-20
lines changed

5 files changed

+24
-20
lines changed

src/cmd/compile/internal/gc/go.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ var (
295295
growslice,
296296
msanread,
297297
msanwrite,
298+
newobject,
298299
newproc,
299300
panicdivide,
300301
panicshift,
@@ -312,7 +313,8 @@ var (
312313
typedmemclr,
313314
typedmemmove,
314315
Udiv,
315-
writeBarrier *obj.LSym
316+
writeBarrier,
317+
zerobaseSym *obj.LSym
316318

317319
BoundsCheckFunc [ssa.BoundsKindCount]*obj.LSym
318320
ExtendCheckFunc [ssa.BoundsKindCount]*obj.LSym

src/cmd/compile/internal/gc/op_string.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/gc/ssa.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func initssaconfig() {
7676
growslice = sysfunc("growslice")
7777
msanread = sysfunc("msanread")
7878
msanwrite = sysfunc("msanwrite")
79+
newobject = sysfunc("newobject")
7980
newproc = sysfunc("newproc")
8081
panicdivide = sysfunc("panicdivide")
8182
panicdottypeE = sysfunc("panicdottypeE")
@@ -94,6 +95,8 @@ func initssaconfig() {
9495
typedmemmove = sysfunc("typedmemmove")
9596
Udiv = sysvar("udiv") // asm func with special ABI
9697
writeBarrier = sysvar("writeBarrier") // struct { bool; ... }
98+
zerobaseSym = sysvar("zerobase")
99+
97100
if thearch.LinkArch.Family == sys.Wasm {
98101
BoundsCheckFunc[ssa.BoundsIndex] = sysvar("goPanicIndex")
99102
BoundsCheckFunc[ssa.BoundsIndexU] = sysvar("goPanicIndexU")
@@ -2453,6 +2456,14 @@ func (s *state) expr(n *Node) *ssa.Value {
24532456
}
24542457
return s.zeroVal(n.Type)
24552458

2459+
case ONEWOBJ:
2460+
if n.Type.Elem().Size() == 0 {
2461+
return s.newValue1A(ssa.OpAddr, n.Type, zerobaseSym, s.sb)
2462+
}
2463+
typ := s.expr(n.Left)
2464+
vv := s.rtcall(newobject, true, []*types.Type{n.Type}, typ)
2465+
return vv[0]
2466+
24562467
default:
24572468
s.Fatalf("unhandled expr %v", n.Op)
24582469
return nil

src/cmd/compile/internal/gc/syntax.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,8 @@ const (
668668
ORSH // Left >> Right
669669
OAND // Left & Right
670670
OANDNOT // Left &^ Right
671-
ONEW // new(Left)
671+
ONEW // new(Left); corresponds to calls to new in source code
672+
ONEWOBJ // runtime.newobject(n.Type); introduced by walk; Left is type descriptor
672673
ONOT // !Left
673674
OBITNOT // ^Left
674675
OPLUS // +Left

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

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ opswitch:
481481
Dump("walk", n)
482482
Fatalf("walkexpr: switch 1 unknown op %+S", n)
483483

484-
case ONONAME, OINDREGSP, OEMPTY, OGETG:
484+
case ONONAME, OINDREGSP, OEMPTY, OGETG, ONEWOBJ:
485485

486486
case OTYPE, ONAME, OLITERAL:
487487
// TODO(mdempsky): Just return n; see discussion on CL 38655.
@@ -1944,21 +1944,11 @@ func callnew(t *types.Type) *Node {
19441944
yyerror("%v is go:notinheap; heap allocation disallowed", t)
19451945
}
19461946
dowidth(t)
1947-
1948-
if t.Size() == 0 {
1949-
// Return &runtime.zerobase if we know that the requested size is 0.
1950-
// This is what runtime.mallocgc would return.
1951-
z := newname(Runtimepkg.Lookup("zerobase"))
1952-
z.SetClass(PEXTERN)
1953-
z.Type = t
1954-
return typecheck(nod(OADDR, z, nil), ctxExpr)
1955-
}
1956-
1957-
fn := syslook("newobject")
1958-
fn = substArgTypes(fn, t)
1959-
v := mkcall1(fn, types.NewPtr(t), nil, typename(t))
1960-
v.SetNonNil(true)
1961-
return v
1947+
n := nod(ONEWOBJ, typename(t), nil)
1948+
n.Type = types.NewPtr(t)
1949+
n.SetTypecheck(1)
1950+
n.SetNonNil(true)
1951+
return n
19621952
}
19631953

19641954
// isReflectHeaderDataField reports whether l is an expression p.Data

0 commit comments

Comments
 (0)