diff options
| author | Robert Griesemer <gri@google.com> | 2026-03-11 19:02:07 -0700 |
|---|---|---|
| committer | Robert Griesemer <gri@google.com> | 2026-03-19 14:32:34 -0700 |
| commit | d9a600a73bed7b907f7321200650fe5103f47fc9 (patch) | |
| tree | 47e838eb42993fec92442cc20a1cc0d83a52f948 /src/cmd/compile/internal/noder/reader.go | |
| parent | 9f7e98d263f1e496991110f057763a2b4319e1c1 (diff) | |
| download | go-d9a600a73bed7b907f7321200650fe5103f47fc9.tar.xz | |
cmd/compile/internal/noder: encode promoted struct fields for composite literals in UIR
This change requires an encoding format change for struct literals.
Introduce a new UIR version (V3) and use the opportunity to encode
all composite literals more compactly: specifically, when we know
that (composite literal) keys are always present, avoid encoding a
bool value for each key.
Do not yet enable the new format.
For #9859.
Change-Id: Ic6dc9adb1aa494e923eadaf578f8cfc61efd5ea4
Reviewed-on: https://go-review.googlesource.com/c/go/+/754664
Reviewed-by: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/reader.go')
| -rw-r--r-- | src/cmd/compile/internal/noder/reader.go | 99 |
1 files changed, 86 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index a9ed77409b..b30a2a3e86 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -3028,21 +3028,37 @@ func (r *reader) compLit() ir.Node { if typ.IsMap() { rtype = r.rtype(pos) } - isStruct := typ.Kind() == types.TSTRUCT - elems := make([]ir.Node, r.Len()) - for i := range elems { - elemp := &elems[i] - - if isStruct { - sk := ir.NewStructKeyExpr(r.pos(), typ.Field(r.Len()), nil) - *elemp, elemp = sk, &sk.Value - } else if r.Bool() { - kv := ir.NewKeyExpr(r.pos(), r.expr(), nil) - *elemp, elemp = kv, &kv.Value + var elems []ir.Node + if r.Version().Has(pkgbits.CompactCompLiterals) { + n := r.Int() + elems = make([]ir.Node, max(n, -n) /* abs(n) */) + switch typ.Kind() { + default: + base.FatalfAt(pos, "unexpected composite literal type: %v", typ) + case types.TARRAY: + r.arrayElems(n >= 0, elems) + case types.TMAP: + r.mapElems(elems) + case types.TSLICE: + r.arrayElems(n >= 0, elems) + case types.TSTRUCT: + r.structElems(typ, n >= 0, elems) + } + } else { + elems = make([]ir.Node, r.Len()) + isStruct := typ.Kind() == types.TSTRUCT + for i := range elems { + elemp := &elems[i] + if isStruct { + sk := ir.NewStructKeyExpr(r.pos(), typ.Field(r.Len()), nil) + *elemp, elemp = sk, &sk.Value + } else if r.Bool() { + kv := ir.NewKeyExpr(r.pos(), r.expr(), nil) + *elemp, elemp = kv, &kv.Value + } + *elemp = r.expr() } - - *elemp = r.expr() } lit := typecheck.Expr(ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, elems)) @@ -3057,6 +3073,63 @@ func (r *reader) compLit() ir.Node { return lit } +func (r *reader) arrayElems(valuesOnly bool, elems []ir.Node) { + if valuesOnly { + for i := range elems { + elems[i] = r.expr() + } + return + } + // some elements may have a key + for i := range elems { + if r.Bool() { + kv := ir.NewKeyExpr(r.pos(), r.expr(), nil) + kv.Value = r.expr() + elems[i] = kv + } else { + elems[i] = r.expr() + } + } +} + +func (r *reader) mapElems(elems []ir.Node) { + // all elements have a key + for i := range elems { + kv := ir.NewKeyExpr(r.pos(), r.expr(), nil) + kv.Value = r.expr() + elems[i] = kv + } +} + +func (r *reader) structElems(typ *types.Type, valuesOnly bool, elems []ir.Node) { + if valuesOnly { + for i := range elems { + sk := ir.NewStructKeyExpr(r.pos(), typ.Field(i), nil) + sk.Value = r.expr() + elems[i] = sk + } + return + } + + // all elements have a key + for i := range elems { + pos := r.pos() + var fld *types.Field + if n := r.Int(); n < 0 { + // embedded field + for range -n { + fld = typ.Field(r.Int()) + typ = fld.Type + } + } else { // n >= 0 + fld = typ.Field(n) + } + sk := ir.NewStructKeyExpr(pos, fld, nil) + sk.Value = r.expr() + elems[i] = sk + } +} + func (r *reader) funcLit() ir.Node { r.Sync(pkgbits.SyncFuncLit) |
