]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: add ConstExpr
authorMatthew Dempsky <mdempsky@google.com>
Thu, 3 Dec 2020 03:26:56 +0000 (19:26 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 3 Dec 2020 18:04:03 +0000 (18:04 +0000)
Currently, we represent constant-folded expressions with Name, which
is suboptimal because Name has a lot of fields to support declared
names (which are irrelevant to constant-folded expressions), while
constant expressions are fairly common.

This CL introduces a new lightweight ConstExpr type that simply wraps
an existing expression and associates it with a value.

Passes buildall w/ toolstash -cmp.

name                      old time/op       new time/op       delta
Template                        252ms ± 3%        254ms ± 1%     ~     (p=0.821 n=12+10)
Unicode                         120ms ± 2%        107ms ± 7%  -11.09%  (p=0.000 n=12+12)
GoTypes                         918ms ± 2%        918ms ± 1%     ~     (p=0.974 n=12+10)
Compiler                        5.19s ± 1%        5.18s ± 0%     ~     (p=0.190 n=12+11)
SSA                             12.4s ± 1%        12.3s ± 1%     ~     (p=0.283 n=10+12)
Flate                           152ms ± 2%        148ms ± 4%   -2.68%  (p=0.007 n=10+12)
GoParser                        212ms ± 1%        211ms ± 2%     ~     (p=0.674 n=10+12)
Reflect                         543ms ± 3%        542ms ± 3%     ~     (p=0.799 n=12+12)
Tar                             224ms ± 2%        225ms ± 2%     ~     (p=0.378 n=12+12)
XML                             292ms ± 1%        299ms ± 3%   +2.18%  (p=0.006 n=10+12)

name                      old user-time/op  new user-time/op  delta
Template                        243ms ± 4%        244ms ± 5%     ~     (p=0.887 n=12+12)
Unicode                         112ms ± 6%        100ms ±10%  -10.76%  (p=0.000 n=12+12)
GoTypes                         898ms ± 3%        895ms ± 3%     ~     (p=0.671 n=12+12)
Compiler                        5.10s ± 1%        5.08s ± 1%     ~     (p=0.104 n=12+11)
SSA                             12.2s ± 2%        12.1s ± 1%     ~     (p=0.487 n=11+12)
Flate                           144ms ± 6%        145ms ± 5%     ~     (p=0.695 n=12+11)
GoParser                        205ms ± 5%        204ms ± 3%     ~     (p=0.514 n=12+12)
Reflect                         528ms ± 3%        531ms ± 4%     ~     (p=0.630 n=12+12)
Tar                             218ms ± 4%        219ms ± 3%     ~     (p=0.843 n=12+12)
XML                             284ms ± 5%        291ms ± 5%     ~     (p=0.069 n=11+12)

name                      old alloc/op      new alloc/op      delta
Template                       37.0MB ± 0%       36.7MB ± 0%   -0.72%  (p=0.000 n=12+12)
Unicode                        31.9MB ± 0%       29.5MB ± 0%   -7.60%  (p=0.000 n=12+12)
GoTypes                         119MB ± 0%        118MB ± 0%   -0.40%  (p=0.000 n=12+12)
Compiler                        629MB ± 0%        626MB ± 0%   -0.36%  (p=0.000 n=11+12)
SSA                            1.45GB ± 0%       1.43GB ± 0%   -0.78%  (p=0.000 n=12+12)
Flate                          22.2MB ± 0%       21.9MB ± 0%   -1.12%  (p=0.000 n=12+12)
GoParser                       29.4MB ± 0%       29.3MB ± 0%   -0.36%  (p=0.000 n=12+12)
Reflect                        76.1MB ± 0%       75.8MB ± 0%   -0.38%  (p=0.000 n=12+12)
Tar                            33.4MB ± 0%       33.2MB ± 0%   -0.61%  (p=0.000 n=12+12)
XML                            43.2MB ± 0%       42.8MB ± 0%   -1.03%  (p=0.000 n=11+12)

name                      old allocs/op     new allocs/op     delta
Template                         375k ± 0%         375k ± 0%     ~     (p=0.854 n=12+12)
Unicode                          300k ± 0%         300k ± 0%     ~     (p=0.766 n=12+12)
GoTypes                         1.30M ± 0%        1.30M ± 0%     ~     (p=0.272 n=12+12)
Compiler                        5.89M ± 0%        5.89M ± 0%     ~     (p=0.478 n=12+12)
SSA                             14.0M ± 0%        14.0M ± 0%     ~     (p=0.266 n=12+12)
Flate                            226k ± 0%         226k ± 0%     ~     (p=0.898 n=12+12)
GoParser                         313k ± 0%         313k ± 0%   -0.01%  (p=0.042 n=12+11)
Reflect                          971k ± 0%         971k ± 0%     ~     (p=0.080 n=12+12)
Tar                              342k ± 0%         342k ± 0%     ~     (p=0.600 n=12+12)
XML                              416k ± 0%         416k ± 0%     ~     (p=0.217 n=11+12)

name                      old maxRSS/op     new maxRSS/op     delta
Template                        43.1M ± 5%        42.5M ± 5%     ~     (p=0.086 n=12+12)
Unicode                         49.4M ± 2%        47.0M ± 2%   -4.88%  (p=0.000 n=12+12)
GoTypes                         85.3M ± 2%        84.6M ± 2%   -0.84%  (p=0.047 n=11+11)
Compiler                         394M ± 3%         386M ± 2%   -1.97%  (p=0.000 n=10+11)
SSA                              847M ± 4%         821M ± 2%   -2.98%  (p=0.000 n=11+12)
Flate                           36.0M ± 7%        35.2M ± 7%     ~     (p=0.128 n=12+12)
GoParser                        39.4M ± 7%        39.5M ± 4%     ~     (p=0.413 n=12+11)
Reflect                         64.0M ± 3%        63.6M ± 3%     ~     (p=0.413 n=11+12)
Tar                             43.3M ± 5%        43.3M ± 5%     ~     (p=0.503 n=12+12)
XML                             47.6M ± 4%        46.4M ± 2%   -2.46%  (p=0.013 n=11+12)

Change-Id: If5781be346351c30b2228807211b5e57f777c506
Reviewed-on: https://go-review.googlesource.com/c/go/+/275033
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/gc/const.go
src/cmd/compile/internal/ir/expr.go

index 8771d82cfa009a38dc274b36f58b42d0f3625f21..9aa65f97b6fe78cf98b522205cddbfe8b5ff0ddc 100644 (file)
@@ -115,22 +115,12 @@ func convlit1(n ir.Node, t *types.Type, explicit bool, context func() string) ir
                return n
        }
 
-       if n.Op() == ir.OLITERAL || n.Op() == ir.ONIL {
-               // Can't always set n.Type directly on OLITERAL nodes.
-               // See discussion on CL 20813.
-               old := n
-               n = ir.Copy(old)
-               if old.Op() == ir.OLITERAL {
-                       // Keep untyped constants in their original untyped syntax for error messages.
-                       n.(ir.OrigNode).SetOrig(old)
-               }
-       }
-
        // Nil is technically not a constant, so handle it specially.
        if n.Type().Kind() == types.TNIL {
                if n.Op() != ir.ONIL {
                        base.Fatalf("unexpected op: %v (%v)", n, n.Op())
                }
+               n = ir.Copy(n)
                if t == nil {
                        base.Errorf("use of untyped nil")
                        n.SetDiag(true)
@@ -158,10 +148,11 @@ func convlit1(n ir.Node, t *types.Type, explicit bool, context func() string) ir
        case ir.OLITERAL:
                v := convertVal(n.Val(), t, explicit)
                if v.Kind() == constant.Unknown {
+                       n = ir.NewConstExpr(n.Val(), n)
                        break
                }
+               n = ir.NewConstExpr(v, n)
                n.SetType(t)
-               n.SetVal(v)
                return n
 
        case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.OREAL, ir.OIMAG:
@@ -541,8 +532,9 @@ func evalConst(n ir.Node) ir.Node {
                                        i2++
                                }
 
-                               nl := origConst(s[i], constant.MakeString(strings.Join(strs, "")))
-                               nl.(ir.OrigNode).SetOrig(nl) // it's bigger than just s[i]
+                               nl := ir.Copy(n)
+                               nl.PtrList().Set(s[i:i2])
+                               nl = origConst(nl, constant.MakeString(strings.Join(strs, "")))
                                newList = append(newList, nl)
                                i = i2 - 1
                        } else {
@@ -645,12 +637,7 @@ func origConst(n ir.Node, v constant.Value) ir.Node {
                return n
        }
 
-       orig := n
-       n = ir.NodAt(orig.Pos(), ir.OLITERAL, nil, nil)
-       n.(ir.OrigNode).SetOrig(orig)
-       n.SetType(orig.Type())
-       n.SetVal(v)
-       return n
+       return ir.NewConstExpr(v, n)
 }
 
 func origBoolConst(n ir.Node, v bool) ir.Node {
index 2a7211cfdac36a29babcc97a57d5d4b631c49709..412b7a18f014a02d7d9f543475d71d94f763d05d 100644 (file)
@@ -9,6 +9,7 @@ import (
        "cmd/compile/internal/types"
        "cmd/internal/src"
        "fmt"
+       "go/constant"
 )
 
 // A miniStmt is a miniNode with extra fields common to expressions.
@@ -300,6 +301,30 @@ func (n *CompLitExpr) SetOp(op Op) {
        }
 }
 
+type ConstExpr struct {
+       miniExpr
+       val  constant.Value
+       orig Node
+}
+
+func NewConstExpr(val constant.Value, orig Node) Node {
+       n := &ConstExpr{orig: orig, val: val}
+       n.op = OLITERAL
+       n.pos = orig.Pos()
+       n.SetType(orig.Type())
+       n.SetTypecheck(orig.Typecheck())
+       n.SetDiag(orig.Diag())
+       return n
+}
+
+func (n *ConstExpr) String() string                { return fmt.Sprint(n) }
+func (n *ConstExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
+func (n *ConstExpr) rawCopy() Node                 { c := *n; return &c }
+func (n *ConstExpr) Sym() *types.Sym               { return n.orig.Sym() }
+func (n *ConstExpr) Orig() Node                    { return n.orig }
+func (n *ConstExpr) SetOrig(orig Node)             { n.orig = orig }
+func (n *ConstExpr) Val() constant.Value           { return n.val }
+
 // A ConvExpr is a conversion Type(X).
 // It may end up being a value or a type.
 type ConvExpr struct {