diff options
author | Rob Findley <rfindley@google.com> | 2020-09-11 14:23:34 -0400 |
---|---|---|
committer | Rob Findley <rfindley@google.com> | 2020-09-11 14:23:34 -0400 |
commit | f8b1c17aced24a1618c6984794be9770c5d260be (patch) | |
tree | 45af8d39b5c3d9f43d439ebec0a2ba42b49efe70 /src/cmd/compile/internal/ssa/func.go | |
parent | e5d91ab096a9ff9673311f1a7f3f860a7f9c2062 (diff) | |
parent | 07c1788357cfe6a4ee5f6f6a54d4fe9f579fa844 (diff) | |
download | go-dev.types.tar.gz go-dev.types.zip |
[dev.types] all: merge master into dev.typesdev.types
Change-Id: Ia6964cb4e09153c15cc9c5b441373d1b3cb8f757
Diffstat (limited to 'src/cmd/compile/internal/ssa/func.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/func.go | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go index 6718b778e1..32df0c06f3 100644 --- a/src/cmd/compile/internal/ssa/func.go +++ b/src/cmd/compile/internal/ssa/func.go @@ -257,6 +257,49 @@ func (f *Func) LogStat(key string, args ...interface{}) { f.Warnl(f.Entry.Pos, "\t%s\t%s%s\t%s", n, key, value, f.Name) } +// unCacheLine removes v from f's constant cache "line" for aux, +// resets v.InCache when it is found (and removed), +// and returns whether v was found in that line. +func (f *Func) unCacheLine(v *Value, aux int64) bool { + vv := f.constants[aux] + for i, cv := range vv { + if v == cv { + vv[i] = vv[len(vv)-1] + vv[len(vv)-1] = nil + f.constants[aux] = vv[0 : len(vv)-1] + v.InCache = false + return true + } + } + return false +} + +// unCache removes v from f's constant cache. +func (f *Func) unCache(v *Value) { + if v.InCache { + aux := v.AuxInt + if f.unCacheLine(v, aux) { + return + } + if aux == 0 { + switch v.Op { + case OpConstNil: + aux = constNilMagic + case OpConstSlice: + aux = constSliceMagic + case OpConstString: + aux = constEmptyStringMagic + case OpConstInterface: + aux = constInterfaceMagic + } + if aux != 0 && f.unCacheLine(v, aux) { + return + } + } + f.Fatalf("unCached value %s not found in cache, auxInt=0x%x, adjusted aux=0x%x", v.LongString(), v.AuxInt, aux) + } +} + // freeValue frees a value. It must no longer be referenced or have any args. func (f *Func) freeValue(v *Value) { if v.Block == nil { @@ -270,19 +313,8 @@ func (f *Func) freeValue(v *Value) { } // Clear everything but ID (which we reuse). id := v.ID - - // Values with zero arguments and OpOffPtr values might be cached, so remove them there. - nArgs := opcodeTable[v.Op].argLen - if nArgs == 0 || v.Op == OpOffPtr { - vv := f.constants[v.AuxInt] - for i, cv := range vv { - if v == cv { - vv[i] = vv[len(vv)-1] - vv[len(vv)-1] = nil - f.constants[v.AuxInt] = vv[0 : len(vv)-1] - break - } - } + if v.InCache { + f.unCache(v) } *v = Value{} v.ID = id @@ -548,6 +580,7 @@ func (f *Func) constVal(op Op, t *types.Type, c int64, setAuxInt bool) *Value { v = f.Entry.NewValue0(src.NoXPos, op, t) } f.constants[c] = append(vv, v) + v.InCache = true return v } |