Commit 4b21be46 authored by Dave Cheney's avatar Dave Cheney

cmd/internal/gc: clean up Componentgen

Update #9855

In preparation for introducing direct use of a zero register on
platforms that support it, take the opportunity to clean up
Componentgen a bit.

Change-Id: I120ce1ffcca8c4f7603bfe76bfa1aedd27ebb4d2
Reviewed-on: https://go-review.googlesource.com/8691
Run-TryBot: Dave Cheney <dave@cheney.net>
Reviewed-by: default avatarMinux Ma <minux@golang.org>
parent a1f57598
...@@ -1116,26 +1116,16 @@ func checklabels() { ...@@ -1116,26 +1116,16 @@ func checklabels() {
} }
} }
/* // Componentgen copies a composite value by moving its individual components.
* copy a composite value by moving its individual components. // Slices, strings and interfaces are supported. Small structs or arrays with
* Slices, strings and interfaces are supported. // elements of basic type are also supported.
* Small structs or arrays with elements of basic type are // nr is nil when assigning a zero value.
* also supported.
* nr is N when assigning a zero value.
* return 1 if can do, 0 if can't.
*/
func Componentgen(nr *Node, nl *Node) bool { func Componentgen(nr *Node, nl *Node) bool {
var nodl Node var nodl, nodr Node
var nodr Node
freel := 0
freer := 0
var isConstString bool
switch nl.Type.Etype { switch nl.Type.Etype {
default: default:
goto no return false
case TARRAY: case TARRAY:
t := nl.Type t := nl.Type
...@@ -1150,16 +1140,16 @@ func Componentgen(nr *Node, nl *Node) bool { ...@@ -1150,16 +1140,16 @@ func Componentgen(nr *Node, nl *Node) bool {
break break
} }
goto no return false
case TSTRUCT:
// Small structs with non-fat types are ok. // Small structs with non-fat types are ok.
// Zero-sized structs are treated separately elsewhere. // Zero-sized structs are treated separately elsewhere.
case TSTRUCT:
fldcount := int64(0) fldcount := int64(0)
for t := nl.Type.Type; t != nil; t = t.Down { for t := nl.Type.Type; t != nil; t = t.Down {
if Isfat(t.Type) && !Isslice(t) { if Isfat(t.Type) && !Isslice(t) {
goto no return false
} }
if t.Etype != TFIELD { if t.Etype != TFIELD {
Fatal("componentgen: not a TFIELD: %v", Tconv(t, obj.FmtLong)) Fatal("componentgen: not a TFIELD: %v", Tconv(t, obj.FmtLong))
...@@ -1168,28 +1158,28 @@ func Componentgen(nr *Node, nl *Node) bool { ...@@ -1168,28 +1158,28 @@ func Componentgen(nr *Node, nl *Node) bool {
} }
if fldcount == 0 || fldcount > 4 { if fldcount == 0 || fldcount > 4 {
goto no return false
} }
case TSTRING, TINTER: case TSTRING, TINTER:
break break
} }
isConstString = Isconst(nr, CTSTR) isConstString := Isconst(nr, CTSTR)
nodl = *nl nodl = *nl
if !cadable(nl) { if !cadable(nl) {
if nr != nil && !cadable(nr) && !isConstString { if nr != nil && !cadable(nr) && !isConstString {
goto no return false
} }
Igen(nl, &nodl, nil) Igen(nl, &nodl, nil)
freel = 1 defer Regfree(&nodl)
} }
if nr != nil { if nr != nil {
nodr = *nr nodr = *nr
if !cadable(nr) && !isConstString { if !cadable(nr) && !isConstString {
Igen(nr, &nodr, nil) Igen(nr, &nodr, nil)
freer = 1 defer Regfree(&nodr)
} }
} else { } else {
// When zeroing, prepare a register containing zero. // When zeroing, prepare a register containing zero.
...@@ -1198,7 +1188,7 @@ func Componentgen(nr *Node, nl *Node) bool { ...@@ -1198,7 +1188,7 @@ func Componentgen(nr *Node, nl *Node) bool {
Regalloc(&nodr, Types[TUINT], nil) Regalloc(&nodr, Types[TUINT], nil)
Thearch.Gmove(&tmp, &nodr) Thearch.Gmove(&tmp, &nodr)
freer = 1 defer Regfree(&nodr)
} }
// nl and nr are 'cadable' which basically means they are names (variables) now. // nl and nr are 'cadable' which basically means they are names (variables) now.
...@@ -1206,12 +1196,15 @@ func Componentgen(nr *Node, nl *Node) bool { ...@@ -1206,12 +1196,15 @@ func Componentgen(nr *Node, nl *Node) bool {
// VARDEF we generate will mark the old value as dead incorrectly. // VARDEF we generate will mark the old value as dead incorrectly.
// (And also the assignments are useless.) // (And also the assignments are useless.)
if nr != nil && nl.Op == ONAME && nr.Op == ONAME && nl == nr { if nr != nil && nl.Op == ONAME && nr.Op == ONAME && nl == nr {
goto yes return true
} }
switch nl.Type.Etype { switch nl.Type.Etype {
// componentgen for arrays. default:
return false
case TARRAY: case TARRAY:
// componentgen for arrays.
if nl.Op == ONAME { if nl.Op == ONAME {
Gvardef(nl) Gvardef(nl)
} }
...@@ -1228,8 +1221,7 @@ func Componentgen(nr *Node, nl *Node) bool { ...@@ -1228,8 +1221,7 @@ func Componentgen(nr *Node, nl *Node) bool {
nodl.Xoffset += t.Type.Width nodl.Xoffset += t.Type.Width
nodr.Xoffset += t.Type.Width nodr.Xoffset += t.Type.Width
} }
return true
goto yes
} }
// componentgen for slices. // componentgen for slices.
...@@ -1263,8 +1255,7 @@ func Componentgen(nr *Node, nl *Node) bool { ...@@ -1263,8 +1255,7 @@ func Componentgen(nr *Node, nl *Node) bool {
} }
Thearch.Gmove(&nodr, &nodl) Thearch.Gmove(&nodr, &nodl)
return true
goto yes
case TSTRING: case TSTRING:
if nl.Op == ONAME { if nl.Op == ONAME {
...@@ -1297,8 +1288,7 @@ func Componentgen(nr *Node, nl *Node) bool { ...@@ -1297,8 +1288,7 @@ func Componentgen(nr *Node, nl *Node) bool {
} }
Thearch.Gmove(&nodr, &nodl) Thearch.Gmove(&nodr, &nodl)
return true
goto yes
case TINTER: case TINTER:
if nl.Op == ONAME { if nl.Op == ONAME {
...@@ -1323,8 +1313,7 @@ func Componentgen(nr *Node, nl *Node) bool { ...@@ -1323,8 +1313,7 @@ func Componentgen(nr *Node, nl *Node) bool {
} }
Thearch.Gmove(&nodr, &nodl) Thearch.Gmove(&nodr, &nodl)
return true
goto yes
case TSTRUCT: case TSTRUCT:
if nl.Op == ONAME { if nl.Op == ONAME {
...@@ -1353,27 +1342,8 @@ func Componentgen(nr *Node, nl *Node) bool { ...@@ -1353,27 +1342,8 @@ func Componentgen(nr *Node, nl *Node) bool {
Thearch.Gmove(&nodr, &nodl) Thearch.Gmove(&nodr, &nodl)
} }
} }
goto yes
}
no:
if freer != 0 {
Regfree(&nodr)
}
if freel != 0 {
Regfree(&nodl)
}
return false
yes:
if freer != 0 {
Regfree(&nodr)
}
if freel != 0 {
Regfree(&nodl)
}
return true return true
}
} }
func cadable(n *Node) bool { func cadable(n *Node) bool {
......
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