aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/func.go
diff options
context:
space:
mode:
authorRob Findley <rfindley@google.com>2020-09-11 14:23:34 -0400
committerRob Findley <rfindley@google.com>2020-09-11 14:23:34 -0400
commitf8b1c17aced24a1618c6984794be9770c5d260be (patch)
tree45af8d39b5c3d9f43d439ebec0a2ba42b49efe70 /src/cmd/compile/internal/ssa/func.go
parente5d91ab096a9ff9673311f1a7f3f860a7f9c2062 (diff)
parent07c1788357cfe6a4ee5f6f6a54d4fe9f579fa844 (diff)
downloadgo-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.go59
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
}