From 2563b6f9fe76da6c9f95c7766986f4684b80ae6d Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Sun, 3 Apr 2016 14:44:29 -0700 Subject: [PATCH] cmd/compile/internal/ssa: use Compare instead of Equal They have different semantics. Equal is stricter and is designed for the front-end. Compare is looser and cheaper and is designed for the back-end. To avoid possible regression, remove Equal from ssa.Type. Updates #15043 Change-Id: Ie23ce75ff6b4d01b7982e0a89e6f81b5d099d8d6 Reviewed-on: https://go-review.googlesource.com/21483 Reviewed-by: David Chase Run-TryBot: Josh Bleecher Snyder --- src/cmd/compile/internal/gc/type.go | 13 +++---------- src/cmd/compile/internal/ssa/TODO | 2 -- src/cmd/compile/internal/ssa/cse.go | 2 +- src/cmd/compile/internal/ssa/func.go | 2 +- src/cmd/compile/internal/ssa/stackalloc.go | 4 ++-- src/cmd/compile/internal/ssa/type.go | 11 +---------- 6 files changed, 8 insertions(+), 26 deletions(-) diff --git a/src/cmd/compile/internal/gc/type.go b/src/cmd/compile/internal/gc/type.go index a44a85bed8..855b070af6 100644 --- a/src/cmd/compile/internal/gc/type.go +++ b/src/cmd/compile/internal/gc/type.go @@ -863,19 +863,12 @@ func (t *Type) SimpleString() string { return Econv(t.Etype) } -func (t *Type) Equal(u ssa.Type) bool { - x, ok := u.(*Type) - return ok && Eqtype(t, x) -} - // Compare compares types for purposes of the SSA back // end, returning an ssa.Cmp (one of CMPlt, CMPeq, CMPgt). // The answers are correct for an optimizer -// or code generator, but not for Go source. -// For example, "type gcDrainFlags int" results in -// two Go-different types that Compare equal. -// The order chosen is also arbitrary, only division into -// equivalence classes (Types that compare CMPeq) matters. +// or code generator, but not necessarily typechecking. +// The order chosen is arbitrary, only consistency and division +// into equivalence classes (Types that compare CMPeq) matters. func (t *Type) Compare(u ssa.Type) ssa.Cmp { x, ok := u.(*Type) // ssa.CompilerType is smaller than gc.Type diff --git a/src/cmd/compile/internal/ssa/TODO b/src/cmd/compile/internal/ssa/TODO index e081856bd3..dad4880994 100644 --- a/src/cmd/compile/internal/ssa/TODO +++ b/src/cmd/compile/internal/ssa/TODO @@ -41,8 +41,6 @@ Future/other ------------ - Start another architecture (arm?) - 64-bit ops on 32-bit machines -- Investigate type equality. During SSA generation, should we use n.Type or (say) TypeBool? - Should we get rid of named types in favor of underlying types during SSA generation? -- Should we introduce a new type equality routine that is less strict than the frontend's? - Infrastructure for enabling/disabling/configuring passes - Modify logging for at least pass=1, to be Warnl compatible diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go index e3f1a1d07d..d501f75e02 100644 --- a/src/cmd/compile/internal/ssa/cse.go +++ b/src/cmd/compile/internal/ssa/cse.go @@ -108,7 +108,7 @@ func cse(f *Func) { break } } - if !equivalent || !v.Type.Equal(w.Type) { + if !equivalent || v.Type.Compare(w.Type) != CMPeq { // w is not equivalent to v. // move it to the end and shrink e. e[j], e[len(e)-1] = e[len(e)-1], e[j] diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go index da44f26106..11ff8d3792 100644 --- a/src/cmd/compile/internal/ssa/func.go +++ b/src/cmd/compile/internal/ssa/func.go @@ -318,7 +318,7 @@ func (f *Func) constVal(line int32, op Op, t Type, c int64, setAux bool) *Value } vv := f.constants[c] for _, v := range vv { - if v.Op == op && v.Type.Equal(t) { + if v.Op == op && v.Type.Compare(t) == CMPeq { if setAux && v.AuxInt != c { panic(fmt.Sprintf("cached const %s should have AuxInt of %d", v.LongString(), c)) } diff --git a/src/cmd/compile/internal/ssa/stackalloc.go b/src/cmd/compile/internal/ssa/stackalloc.go index e3ef66ab1b..44f4096cb2 100644 --- a/src/cmd/compile/internal/ssa/stackalloc.go +++ b/src/cmd/compile/internal/ssa/stackalloc.go @@ -201,7 +201,7 @@ func (s *stackAllocState) stackalloc() { } else { name = names[v.ID] } - if name.N != nil && v.Type.Equal(name.Type) { + if name.N != nil && v.Type.Compare(name.Type) == CMPeq { for _, id := range s.interfere[v.ID] { h := f.getHome(id) if h != nil && h.(LocalSlot).N == name.N && h.(LocalSlot).Off == name.Off { @@ -372,7 +372,7 @@ func (s *stackAllocState) buildInterferenceGraph() { if s.values[v.ID].needSlot { live.remove(v.ID) for _, id := range live.contents() { - if s.values[v.ID].typ.Equal(s.values[id].typ) { + if s.values[v.ID].typ.Compare(s.values[id].typ) == CMPeq { s.interfere[v.ID] = append(s.interfere[v.ID], id) s.interfere[id] = append(s.interfere[id], v.ID) } diff --git a/src/cmd/compile/internal/ssa/type.go b/src/cmd/compile/internal/ssa/type.go index 2a3de282cb..91a4efe78f 100644 --- a/src/cmd/compile/internal/ssa/type.go +++ b/src/cmd/compile/internal/ssa/type.go @@ -40,8 +40,7 @@ type Type interface { String() string SimpleString() string // a coarser generic description of T, e.g. T's underlying type - Equal(Type) bool - Compare(Type) Cmp // compare types, returning one of CMPlt, CMPeq, CMPgt. + Compare(Type) Cmp // compare types, returning one of CMPlt, CMPeq, CMPgt. } // Special compiler-only types. @@ -117,14 +116,6 @@ func (t *CompilerType) Compare(u Type) Cmp { return CMPlt } -func (t *CompilerType) Equal(u Type) bool { - x, ok := u.(*CompilerType) - if !ok { - return false - } - return x == t -} - var ( TypeInvalid = &CompilerType{Name: "invalid"} TypeMem = &CompilerType{Name: "mem", Memory: true} -- 2.48.1