mirror of
https://github.com/golang/go
synced 2024-11-16 16:54:39 -07:00
cmd/compile,sync: make accessing address of zero offset struct field inline cost 0
Accessing the address of something often needs the same (or even less) number of instructions as accessing the content of the thing. That would help us rolling back the hack of CL 429766 to lower sync atomic types inline cost. Compiled objects size increase a bit: file before after Δ % addr2line 3729827 3733958 +4131 +0.111% api 5457224 5456267 -957 -0.018% asm 4806486 4808993 +2507 +0.052% buildid 2480271 2480562 +291 +0.012% cgo 4593496 4593947 +451 +0.010% compile 23906958 23910086 +3128 +0.013% cover 4680870 4681461 +591 +0.013% dist 3341333 3341692 +359 +0.011% doc 3879927 3880409 +482 +0.012% fix 3298081 3298979 +898 +0.027% link 6500098 6499873 -225 -0.003% nm 3654362 3656997 +2635 +0.072% objdump 4108300 4108671 +371 +0.009% pack 2255445 2256391 +946 +0.042% pprof 14364561 14379475 +14914 +0.104% test2json 2550942 2555333 +4391 +0.172% trace 13573199 13578409 +5210 +0.038% vet 7430923 7430094 -829 -0.011% total 114612303 114651597 +39294 +0.034% file before after Δ % archive/tar.a 905032 905560 +528 +0.058% archive/zip.a 853464 853916 +452 +0.053% cmd/asm/internal/lex.a 359388 367418 +8030 +2.234% cmd/compile/internal/importer.a 947206 947734 +528 +0.056% cmd/compile/internal/inline.a 563390 566828 +3438 +0.610% cmd/compile/internal/types2.a 5761990 5764274 +2284 +0.040% cmd/go/internal/cfg.a 234892 235342 +450 +0.192% cmd/go/internal/envcmd.a 257166 257694 +528 +0.205% cmd/go/internal/fix.a 93522 94052 +530 +0.567% cmd/go/internal/generate.a 201308 201838 +530 +0.263% cmd/go/internal/get.a 207862 208390 +528 +0.254% cmd/go/internal/imports.a 230266 230794 +528 +0.229% cmd/go/internal/list.a 385044 386632 +1588 +0.412% cmd/go/internal/load.a 1164508 1165566 +1058 +0.091% cmd/go/internal/modcmd.a 627582 629168 +1586 +0.253% cmd/go/internal/modfetch/codehost.a 1031962 1032490 +528 +0.051% cmd/go/internal/modfetch.a 1289294 1289822 +528 +0.041% cmd/go/internal/modget.a 674566 675624 +1058 +0.157% cmd/go/internal/modindex.a 935598 936576 +978 +0.105% cmd/go/internal/modload.a 2640784 2642058 +1274 +0.048% cmd/go/internal/par.a 135858 136476 +618 +0.455% cmd/go/internal/run.a 127158 127688 +530 +0.417% cmd/go/internal/search.a 242918 243446 +528 +0.217% cmd/go/internal/trace.a 113216 113188 -28 -0.025% cmd/go/internal/vcs.a 517280 517810 +530 +0.102% cmd/go/internal/work.a 2389522 2390580 +1058 +0.044% cmd/go/internal/workcmd.a 311118 311452 +334 +0.107% cmd/vendor/github.com/google/pprof/internal/driver.a 1714950 1715478 +528 +0.031% cmd/vendor/golang.org/x/mod/sumdb.a 453840 454290 +450 +0.099% cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags.a 326162 326610 +448 +0.137% cmd/vendor/golang.org/x/tools/go/analysis/internal/facts.a 302476 303006 +530 +0.175% cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl.a 366580 367030 +450 +0.123% cmd/vendor/golang.org/x/tools/go/analysis/passes/assign.a 129556 130006 +450 +0.347% cmd/vendor/golang.org/x/tools/go/analysis/passes/atomic.a 133466 133916 +450 +0.337% cmd/vendor/golang.org/x/tools/go/analysis/passes/bools.a 193558 194006 +448 +0.231% cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag.a 177984 178434 +450 +0.253% cmd/vendor/golang.org/x/tools/go/analysis/passes/cgocall.a 221226 221674 +448 +0.203% cmd/vendor/golang.org/x/tools/go/analysis/passes/composite.a 168572 169022 +450 +0.267% cmd/vendor/golang.org/x/tools/go/analysis/passes/copylock.a 227040 227490 +450 +0.198% cmd/vendor/golang.org/x/tools/go/analysis/passes/ctrlflow.a 204650 205098 +448 +0.219% cmd/vendor/golang.org/x/tools/go/analysis/passes/errorsas.a 138020 138468 +448 +0.325% cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer.a 119030 119480 +450 +0.378% cmd/vendor/golang.org/x/tools/go/analysis/passes/httpresponse.a 165006 165454 +448 +0.272% cmd/vendor/golang.org/x/tools/go/analysis/passes/ifaceassert.a 180850 181300 +450 +0.249% cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect.a 103876 104326 +450 +0.433% cmd/vendor/golang.org/x/tools/go/analysis/passes/internal/analysisutil.a 116070 116516 +446 +0.384% cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure.a 153068 153518 +450 +0.294% cmd/vendor/golang.org/x/tools/go/analysis/passes/lostcancel.a 244936 245384 +448 +0.183% cmd/vendor/golang.org/x/tools/go/analysis/passes/nilfunc.a 135720 136168 +448 +0.330% cmd/vendor/golang.org/x/tools/go/analysis/passes/printf.a 527134 527584 +450 +0.085% cmd/vendor/golang.org/x/tools/go/analysis/passes/shift.a 172026 172476 +450 +0.262% cmd/vendor/golang.org/x/tools/go/analysis/passes/sigchanyzer.a 151690 152138 +448 +0.295% cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods.a 187494 187944 +450 +0.240% cmd/vendor/golang.org/x/tools/go/analysis/passes/stringintconv.a 164752 165200 +448 +0.272% cmd/vendor/golang.org/x/tools/go/analysis/passes/structtag.a 200144 200594 +450 +0.225% cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine.a 161146 161596 +450 +0.279% cmd/vendor/golang.org/x/tools/go/analysis/passes/tests.a 270252 270702 +450 +0.167% cmd/vendor/golang.org/x/tools/go/analysis/passes/unmarshal.a 130646 131094 +448 +0.343% cmd/vendor/golang.org/x/tools/go/analysis/passes/unreachable.a 182130 182580 +450 +0.247% cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr.a 153646 154094 +448 +0.292% cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult.a 179800 180248 +448 +0.249% cmd/vendor/golang.org/x/tools/go/analysis/unitchecker.a 303838 304286 +448 +0.147% cmd/vendor/golang.org/x/tools/go/analysis.a 217930 218380 +450 +0.206% cmd/vendor/golang.org/x/tools/go/ast/astutil.a 539428 539874 +446 +0.083% cmd/vendor/golang.org/x/tools/go/cfg.a 286820 287270 +450 +0.157% cmd/vendor/golang.org/x/tools/go/types/objectpath.a 236144 236674 +530 +0.224% cmd/vendor/golang.org/x/tools/go/types/typeutil.a 412728 413176 +448 +0.109% cmd/vendor/golang.org/x/tools/internal/analysisinternal.a 223256 223704 +448 +0.201% cmd/vendor/golang.org/x/tools/internal/typeparams.a 419498 419946 +448 +0.107% context.a 210000 209972 -28 -0.013% crypto/internal/boring/bcache.a 8652 8568 -84 -0.971% crypto/tls.a 3295282 3295202 -80 -0.002% database/sql.a 1365892 1365762 -130 -0.010% encoding/base64.a 131572 136228 +4656 +3.539% encoding/binary.a 452546 453076 +530 +0.117% encoding/gob.a 1690728 1691672 +944 +0.056% encoding/json.a 1198834 1199276 +442 +0.037% encoding/xml.a 1035784 1036314 +530 +0.051% expvar.a 285282 285678 +396 +0.139% go/ast.a 1175212 1175662 +450 +0.038% go/build.a 657802 658252 +450 +0.068% go/doc.a 808002 808452 +450 +0.056% go/format.a 101378 101824 +446 +0.440% go/importer.a 101816 102266 +450 +0.442% go/internal/gccgoimporter.a 593828 594358 +530 +0.089% go/internal/gcimporter.a 974178 974626 +448 +0.046% go/internal/srcimporter.a 196600 197050 +450 +0.229% go/parser.a 1152502 1152946 +444 +0.039% go/printer.a 910744 911194 +450 +0.049% go/token.a 299624 299768 +144 +0.048% go/types.a 5763222 5766118 +2896 +0.050% hash/crc32.a 128130 128098 -32 -0.025% internal/fuzz.a 1058644 1059174 +530 +0.050% internal/poll.a 660412 660382 -30 -0.005% internal/testenv.a 212792 213320 +528 +0.248% log/syslog.a 128718 128654 -64 -0.050% log.a 157330 157274 -56 -0.036% mime.a 383058 383588 +530 +0.138% net/http/httptest.a 430550 431000 +450 +0.105% net/http/pprof.a 306918 307448 +530 +0.173% net/http.a 7413852 7414074 +222 +0.003% net/internal/socktest.a 258934 258900 -34 -0.013% net/rpc/jsonrpc.a 173158 172962 -196 -0.113% net/rpc.a 634464 634914 +450 +0.071% net.a 3539574 3541348 +1774 +0.050% os.a 891416 891390 -26 -0.003% reflect.a 3956224 3956666 +442 +0.011% runtime/cgo.a 187406 187852 +446 +0.238% runtime/trace.a 85720 85616 -104 -0.121% runtime.a 9357520 9371302 +13782 +0.147% sync/atomic.a 232512 232376 -136 -0.058% sync.a 353112 355068 +1956 +0.554% syscall.a 1660308 1660222 -86 -0.005% testing.a 1399348 1399198 -150 -0.011% text/template.a 1384750 1384726 -24 -0.002% total 265209524 265294628 +85104 +0.032% Change-Id: I21114dcddeb4fc2c56e781ea2f6e732fe3da2b01 Reviewed-on: https://go-review.googlesource.com/c/go/+/431095 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
63d05642d4
commit
638c9aad5f
@ -381,6 +381,15 @@ func (v *hairyVisitor) doNode(n ir.Node) bool {
|
||||
case ir.OAPPEND:
|
||||
v.budget -= inlineExtraAppendCost
|
||||
|
||||
case ir.OADDR:
|
||||
n := n.(*ir.AddrExpr)
|
||||
// Make "&s.f" cost 0 when f's offset is zero.
|
||||
if dot, ok := n.X.(*ir.SelectorExpr); ok && (dot.Op() == ir.ODOT || dot.Op() == ir.ODOTPTR) {
|
||||
if _, ok := dot.X.(*ir.Name); ok && dot.Selection.Offset == 0 {
|
||||
v.budget += 2 // undo ir.OADDR+ir.ODOT/ir.ODOTPTR
|
||||
}
|
||||
}
|
||||
|
||||
case ir.ODEREF:
|
||||
// *(*X)(unsafe.Pointer(&x)) is low-cost
|
||||
n := n.(*ir.StarExpr)
|
||||
|
@ -14,19 +14,17 @@ type Bool struct {
|
||||
}
|
||||
|
||||
// Load atomically loads and returns the value stored in x.
|
||||
func (x *Bool) Load() bool { return LoadUint32((*uint32)(unsafe.Pointer(x))) != 0 }
|
||||
func (x *Bool) Load() bool { return LoadUint32(&x.v) != 0 }
|
||||
|
||||
// Store atomically stores val into x.
|
||||
func (x *Bool) Store(val bool) { StoreUint32((*uint32)(unsafe.Pointer(x)), b32(val)) }
|
||||
func (x *Bool) Store(val bool) { StoreUint32(&x.v, b32(val)) }
|
||||
|
||||
// Swap atomically stores new into x and returns the previous value.
|
||||
func (x *Bool) Swap(new bool) (old bool) {
|
||||
return SwapUint32((*uint32)(unsafe.Pointer(x)), b32(new)) != 0
|
||||
}
|
||||
func (x *Bool) Swap(new bool) (old bool) { return SwapUint32(&x.v, b32(new)) != 0 }
|
||||
|
||||
// CompareAndSwap executes the compare-and-swap operation for the boolean value x.
|
||||
func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) {
|
||||
return CompareAndSwapUint32((*uint32)(unsafe.Pointer(x)), b32(old), b32(new))
|
||||
return CompareAndSwapUint32(&x.v, b32(old), b32(new))
|
||||
}
|
||||
|
||||
// b32 returns a uint32 0 or 1 representing b.
|
||||
@ -48,21 +46,17 @@ type Pointer[T any] struct {
|
||||
}
|
||||
|
||||
// Load atomically loads and returns the value stored in x.
|
||||
func (x *Pointer[T]) Load() *T { return (*T)(LoadPointer((*unsafe.Pointer)(unsafe.Pointer(x)))) }
|
||||
func (x *Pointer[T]) Load() *T { return (*T)(LoadPointer(&x.v)) }
|
||||
|
||||
// Store atomically stores val into x.
|
||||
func (x *Pointer[T]) Store(val *T) {
|
||||
StorePointer((*unsafe.Pointer)(unsafe.Pointer(x)), unsafe.Pointer(val))
|
||||
}
|
||||
func (x *Pointer[T]) Store(val *T) { StorePointer(&x.v, unsafe.Pointer(val)) }
|
||||
|
||||
// Swap atomically stores new into x and returns the previous value.
|
||||
func (x *Pointer[T]) Swap(new *T) (old *T) {
|
||||
return (*T)(SwapPointer((*unsafe.Pointer)(unsafe.Pointer(x)), unsafe.Pointer(new)))
|
||||
}
|
||||
func (x *Pointer[T]) Swap(new *T) (old *T) { return (*T)(SwapPointer(&x.v, unsafe.Pointer(new))) }
|
||||
|
||||
// CompareAndSwap executes the compare-and-swap operation for x.
|
||||
func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) {
|
||||
return CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(x)), unsafe.Pointer(old), unsafe.Pointer(new))
|
||||
return CompareAndSwapPointer(&x.v, unsafe.Pointer(old), unsafe.Pointer(new))
|
||||
}
|
||||
|
||||
// An Int32 is an atomic int32. The zero value is zero.
|
||||
@ -72,21 +66,21 @@ type Int32 struct {
|
||||
}
|
||||
|
||||
// Load atomically loads and returns the value stored in x.
|
||||
func (x *Int32) Load() int32 { return LoadInt32((*int32)(unsafe.Pointer(x))) }
|
||||
func (x *Int32) Load() int32 { return LoadInt32(&x.v) }
|
||||
|
||||
// Store atomically stores val into x.
|
||||
func (x *Int32) Store(val int32) { StoreInt32((*int32)(unsafe.Pointer(x)), val) }
|
||||
func (x *Int32) Store(val int32) { StoreInt32(&x.v, val) }
|
||||
|
||||
// Swap atomically stores new into x and returns the previous value.
|
||||
func (x *Int32) Swap(new int32) (old int32) { return SwapInt32((*int32)(unsafe.Pointer(x)), new) }
|
||||
func (x *Int32) Swap(new int32) (old int32) { return SwapInt32(&x.v, new) }
|
||||
|
||||
// CompareAndSwap executes the compare-and-swap operation for x.
|
||||
func (x *Int32) CompareAndSwap(old, new int32) (swapped bool) {
|
||||
return CompareAndSwapInt32((*int32)(unsafe.Pointer(x)), old, new)
|
||||
return CompareAndSwapInt32(&x.v, old, new)
|
||||
}
|
||||
|
||||
// Add atomically adds delta to x and returns the new value.
|
||||
func (x *Int32) Add(delta int32) (new int32) { return AddInt32((*int32)(unsafe.Pointer(x)), delta) }
|
||||
func (x *Int32) Add(delta int32) (new int32) { return AddInt32(&x.v, delta) }
|
||||
|
||||
// An Int64 is an atomic int64. The zero value is zero.
|
||||
type Int64 struct {
|
||||
@ -96,21 +90,21 @@ type Int64 struct {
|
||||
}
|
||||
|
||||
// Load atomically loads and returns the value stored in x.
|
||||
func (x *Int64) Load() int64 { return LoadInt64((*int64)(unsafe.Pointer(x))) }
|
||||
func (x *Int64) Load() int64 { return LoadInt64(&x.v) }
|
||||
|
||||
// Store atomically stores val into x.
|
||||
func (x *Int64) Store(val int64) { StoreInt64((*int64)(unsafe.Pointer(x)), val) }
|
||||
func (x *Int64) Store(val int64) { StoreInt64(&x.v, val) }
|
||||
|
||||
// Swap atomically stores new into x and returns the previous value.
|
||||
func (x *Int64) Swap(new int64) (old int64) { return SwapInt64((*int64)(unsafe.Pointer(x)), new) }
|
||||
func (x *Int64) Swap(new int64) (old int64) { return SwapInt64(&x.v, new) }
|
||||
|
||||
// CompareAndSwap executes the compare-and-swap operation for x.
|
||||
func (x *Int64) CompareAndSwap(old, new int64) (swapped bool) {
|
||||
return CompareAndSwapInt64((*int64)(unsafe.Pointer(x)), old, new)
|
||||
return CompareAndSwapInt64(&x.v, old, new)
|
||||
}
|
||||
|
||||
// Add atomically adds delta to x and returns the new value.
|
||||
func (x *Int64) Add(delta int64) (new int64) { return AddInt64((*int64)(unsafe.Pointer(x)), delta) }
|
||||
func (x *Int64) Add(delta int64) (new int64) { return AddInt64(&x.v, delta) }
|
||||
|
||||
// An Uint32 is an atomic uint32. The zero value is zero.
|
||||
type Uint32 struct {
|
||||
@ -119,23 +113,21 @@ type Uint32 struct {
|
||||
}
|
||||
|
||||
// Load atomically loads and returns the value stored in x.
|
||||
func (x *Uint32) Load() uint32 { return LoadUint32((*uint32)(unsafe.Pointer(x))) }
|
||||
func (x *Uint32) Load() uint32 { return LoadUint32(&x.v) }
|
||||
|
||||
// Store atomically stores val into x.
|
||||
func (x *Uint32) Store(val uint32) { StoreUint32((*uint32)(unsafe.Pointer(x)), val) }
|
||||
func (x *Uint32) Store(val uint32) { StoreUint32(&x.v, val) }
|
||||
|
||||
// Swap atomically stores new into x and returns the previous value.
|
||||
func (x *Uint32) Swap(new uint32) (old uint32) { return SwapUint32((*uint32)(unsafe.Pointer(x)), new) }
|
||||
func (x *Uint32) Swap(new uint32) (old uint32) { return SwapUint32(&x.v, new) }
|
||||
|
||||
// CompareAndSwap executes the compare-and-swap operation for x.
|
||||
func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool) {
|
||||
return CompareAndSwapUint32((*uint32)(unsafe.Pointer(x)), old, new)
|
||||
return CompareAndSwapUint32(&x.v, old, new)
|
||||
}
|
||||
|
||||
// Add atomically adds delta to x and returns the new value.
|
||||
func (x *Uint32) Add(delta uint32) (new uint32) {
|
||||
return AddUint32((*uint32)(unsafe.Pointer(x)), delta)
|
||||
}
|
||||
func (x *Uint32) Add(delta uint32) (new uint32) { return AddUint32(&x.v, delta) }
|
||||
|
||||
// An Uint64 is an atomic uint64. The zero value is zero.
|
||||
type Uint64 struct {
|
||||
@ -145,23 +137,21 @@ type Uint64 struct {
|
||||
}
|
||||
|
||||
// Load atomically loads and returns the value stored in x.
|
||||
func (x *Uint64) Load() uint64 { return LoadUint64((*uint64)(unsafe.Pointer(x))) }
|
||||
func (x *Uint64) Load() uint64 { return LoadUint64(&x.v) }
|
||||
|
||||
// Store atomically stores val into x.
|
||||
func (x *Uint64) Store(val uint64) { StoreUint64((*uint64)(unsafe.Pointer(x)), val) }
|
||||
func (x *Uint64) Store(val uint64) { StoreUint64(&x.v, val) }
|
||||
|
||||
// Swap atomically stores new into x and returns the previous value.
|
||||
func (x *Uint64) Swap(new uint64) (old uint64) { return SwapUint64((*uint64)(unsafe.Pointer(x)), new) }
|
||||
func (x *Uint64) Swap(new uint64) (old uint64) { return SwapUint64(&x.v, new) }
|
||||
|
||||
// CompareAndSwap executes the compare-and-swap operation for x.
|
||||
func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool) {
|
||||
return CompareAndSwapUint64((*uint64)(unsafe.Pointer(x)), old, new)
|
||||
return CompareAndSwapUint64(&x.v, old, new)
|
||||
}
|
||||
|
||||
// Add atomically adds delta to x and returns the new value.
|
||||
func (x *Uint64) Add(delta uint64) (new uint64) {
|
||||
return AddUint64((*uint64)(unsafe.Pointer(x)), delta)
|
||||
}
|
||||
func (x *Uint64) Add(delta uint64) (new uint64) { return AddUint64(&x.v, delta) }
|
||||
|
||||
// An Uintptr is an atomic uintptr. The zero value is zero.
|
||||
type Uintptr struct {
|
||||
@ -170,25 +160,21 @@ type Uintptr struct {
|
||||
}
|
||||
|
||||
// Load atomically loads and returns the value stored in x.
|
||||
func (x *Uintptr) Load() uintptr { return LoadUintptr((*uintptr)(unsafe.Pointer(x))) }
|
||||
func (x *Uintptr) Load() uintptr { return LoadUintptr(&x.v) }
|
||||
|
||||
// Store atomically stores val into x.
|
||||
func (x *Uintptr) Store(val uintptr) { StoreUintptr((*uintptr)(unsafe.Pointer(x)), val) }
|
||||
func (x *Uintptr) Store(val uintptr) { StoreUintptr(&x.v, val) }
|
||||
|
||||
// Swap atomically stores new into x and returns the previous value.
|
||||
func (x *Uintptr) Swap(new uintptr) (old uintptr) {
|
||||
return SwapUintptr((*uintptr)(unsafe.Pointer(x)), new)
|
||||
}
|
||||
func (x *Uintptr) Swap(new uintptr) (old uintptr) { return SwapUintptr(&x.v, new) }
|
||||
|
||||
// CompareAndSwap executes the compare-and-swap operation for x.
|
||||
func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) {
|
||||
return CompareAndSwapUintptr((*uintptr)(unsafe.Pointer(x)), old, new)
|
||||
return CompareAndSwapUintptr(&x.v, old, new)
|
||||
}
|
||||
|
||||
// Add atomically adds delta to x and returns the new value.
|
||||
func (x *Uintptr) Add(delta uintptr) (new uintptr) {
|
||||
return AddUintptr((*uintptr)(unsafe.Pointer(x)), delta)
|
||||
}
|
||||
func (x *Uintptr) Add(delta uintptr) (new uintptr) { return AddUintptr(&x.v, delta) }
|
||||
|
||||
// noCopy may be added to structs which must not be copied
|
||||
// after the first use.
|
||||
|
Loading…
Reference in New Issue
Block a user