Commit ad1f2c96 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: use CTNIL for pointer-typed OLITERALs

We used to be more aggressive about constant folding in the frontend,
handling expressions that the Go spec does not consider constant;
e.g., "(*int)(unsafe.Pointer(uintptr(200)))". However, that led to a
lot of subtle Go spec conformance issues, so we've since abandoned
that effort (CL 151320), leaving SSA to handle these cases instead.

As such, the only time we now end up with pointer-typed OLITERALs is
when "nil" is implicitly converted to a pointer-typed variable.
Instead of representing these OLITERALs with an CTINT of 0, we can
just use CTNIL.

Saves a few bytes of memory and lines of code.

Change-Id: Ibc5c756b992fdc89c3bdaf4fda3aa352e8e2b101
Reviewed-on: https://go-review.googlesource.com/c/go/+/193437
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
parent e6ba19f9
...@@ -349,10 +349,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node { ...@@ -349,10 +349,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node {
case TARRAY: case TARRAY:
goto bad goto bad
case TPTR, TUNSAFEPTR: case TCHAN, TFUNC, TINTER, TMAP, TPTR, TSLICE, TUNSAFEPTR:
n.SetVal(Val{new(Mpint)})
case TCHAN, TFUNC, TINTER, TMAP, TSLICE:
break break
} }
...@@ -602,17 +599,8 @@ func evconst(n *Node) { ...@@ -602,17 +599,8 @@ func evconst(n *Node) {
case OEQ, ONE, OLT, OLE, OGT, OGE: case OEQ, ONE, OLT, OLE, OGT, OGE:
if nl.Op == OLITERAL && nr.Op == OLITERAL { if nl.Op == OLITERAL && nr.Op == OLITERAL {
if nl.Type.IsInterface() != nr.Type.IsInterface() {
// Mixed interface/non-interface
// constant comparison means comparing
// nil interface with some typed
// constant, which is always unequal.
// E.g., interface{}(nil) == (*int)(nil).
setboolconst(n, op == ONE)
} else {
setboolconst(n, compareOp(nl.Val(), op, nr.Val())) setboolconst(n, compareOp(nl.Val(), op, nr.Val()))
} }
}
case OLSH, ORSH: case OLSH, ORSH:
if nl.Op == OLITERAL && nr.Op == OLITERAL { if nl.Op == OLITERAL && nr.Op == OLITERAL {
...@@ -732,15 +720,6 @@ func compareOp(x Val, op Op, y Val) bool { ...@@ -732,15 +720,6 @@ func compareOp(x Val, op Op, y Val) bool {
x, y = match(x, y) x, y = match(x, y)
switch x.Ctype() { switch x.Ctype() {
case CTNIL:
_, _ = x.U.(*NilVal), y.U.(*NilVal) // assert dynamic types match
switch op {
case OEQ:
return true
case ONE:
return false
}
case CTBOOL: case CTBOOL:
x, y := x.U.(bool), y.U.(bool) x, y := x.U.(bool), y.U.(bool)
switch op { switch op {
......
...@@ -734,15 +734,14 @@ func constTypeOf(typ *types.Type) Ctype { ...@@ -734,15 +734,14 @@ func constTypeOf(typ *types.Type) Ctype {
} }
switch typ.Etype { switch typ.Etype {
case TCHAN, TFUNC, TMAP, TNIL, TINTER, TSLICE: case TCHAN, TFUNC, TMAP, TNIL, TINTER, TPTR, TSLICE, TUNSAFEPTR:
return CTNIL return CTNIL
case TBOOL: case TBOOL:
return CTBOOL return CTBOOL
case TSTRING: case TSTRING:
return CTSTR return CTSTR
case TINT, TINT8, TINT16, TINT32, TINT64, case TINT, TINT8, TINT16, TINT32, TINT64,
TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR, TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR:
TPTR, TUNSAFEPTR:
return CTINT return CTINT
case TFLOAT32, TFLOAT64: case TFLOAT32, TFLOAT64:
return CTFLT return CTFLT
......
...@@ -509,8 +509,8 @@ func IsGlobalAddr(v *Value) bool { ...@@ -509,8 +509,8 @@ func IsGlobalAddr(v *Value) bool {
if v.Op == OpAddr && v.Args[0].Op == OpSB { if v.Op == OpAddr && v.Args[0].Op == OpSB {
return true // address of a global return true // address of a global
} }
if v.Op == OpConst64 || v.Op == OpConst32 { if v.Op == OpConstNil {
return true // nil, the only possible pointer constant return true
} }
return false return false
} }
...@@ -520,7 +520,7 @@ func IsReadOnlyGlobalAddr(v *Value) bool { ...@@ -520,7 +520,7 @@ func IsReadOnlyGlobalAddr(v *Value) bool {
if !IsGlobalAddr(v) { if !IsGlobalAddr(v) {
return false return false
} }
if v.Op == OpConst64 || v.Op == OpConst32 { if v.Op == OpConstNil {
// Nil pointers are read only. See issue 33438. // Nil pointers are read only. See issue 33438.
return true return true
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment