mirror of
https://github.com/golang/go.git
synced 2025-11-11 14:11:04 +00:00
[dev.regabi] cmd/compile: improve ascompatee
order.go has already ordered function calls, so ascompatee only needs to worry about expressions that might access a variable after it's already been re-assigned. It already handles this, so the safeExpr calls simply result in unnecessarily pessimistic code. Does not pass toolstash -cmp, because it allows more efficient code generation. E.g., cmd/go on linux/ppc64le is about 2kB smaller. Change-Id: Idde0588eabe7850fa13c4e281fc46bbeffb4f68c Reviewed-on: https://go-review.googlesource.com/c/go/+/281152 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
5d80a590a2
commit
a317067d65
1 changed files with 9 additions and 29 deletions
|
|
@ -325,22 +325,6 @@ func ascompatee(op ir.Op, nl, nr []ir.Node, init *ir.Nodes) []ir.Node {
|
||||||
base.Fatalf("assignment operands mismatch: %+v / %+v", ir.Nodes(nl), ir.Nodes(nr))
|
base.Fatalf("assignment operands mismatch: %+v / %+v", ir.Nodes(nl), ir.Nodes(nr))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mdempsky): Simplify this code. Not only is it redundant to
|
|
||||||
// call safeExpr on the operands twice, but ensuring order of
|
|
||||||
// evaluation for function calls was already handled by order.go.
|
|
||||||
|
|
||||||
// move function calls out, to make ascompatee's job easier.
|
|
||||||
walkExprListSafe(nl, init)
|
|
||||||
walkExprListSafe(nr, init)
|
|
||||||
|
|
||||||
// ensure order of evaluation for function calls
|
|
||||||
for i := range nl {
|
|
||||||
nl[i] = safeExpr(nl[i], init)
|
|
||||||
}
|
|
||||||
for i := range nr {
|
|
||||||
nr[i] = safeExpr(nr[i], init)
|
|
||||||
}
|
|
||||||
|
|
||||||
var assigned ir.NameSet
|
var assigned ir.NameSet
|
||||||
var memWrite bool
|
var memWrite bool
|
||||||
|
|
||||||
|
|
@ -361,27 +345,22 @@ func ascompatee(op ir.Op, nl, nr []ir.Node, init *ir.Nodes) []ir.Node {
|
||||||
// If a needed expression may be affected by an
|
// If a needed expression may be affected by an
|
||||||
// earlier assignment, make an early copy of that
|
// earlier assignment, make an early copy of that
|
||||||
// expression and use the copy instead.
|
// expression and use the copy instead.
|
||||||
var early []ir.Node
|
var early ir.Nodes
|
||||||
save := func(np *ir.Node) {
|
save := func(np *ir.Node) {
|
||||||
if n := *np; affected(n) {
|
if n := *np; affected(n) {
|
||||||
tmp := ir.Node(typecheck.Temp(n.Type()))
|
*np = copyExpr(n, n.Type(), &early)
|
||||||
as := typecheck.Stmt(ir.NewAssignStmt(base.Pos, tmp, n))
|
|
||||||
early = append(early, as)
|
|
||||||
*np = tmp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var late []ir.Node
|
var late ir.Nodes
|
||||||
for i, l := range nl {
|
for i, lorig := range nl {
|
||||||
r := nr[i]
|
l, r := lorig, nr[i]
|
||||||
|
|
||||||
// Do not generate 'x = x' during return. See issue 4014.
|
// Do not generate 'x = x' during return. See issue 4014.
|
||||||
if op == ir.ORETURN && ir.SameSafeExpr(l, r) {
|
if op == ir.ORETURN && ir.SameSafeExpr(l, r) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
as := ir.NewAssignStmt(base.Pos, l, r)
|
|
||||||
|
|
||||||
// Save subexpressions needed on left side.
|
// Save subexpressions needed on left side.
|
||||||
// Drill through non-dereferences.
|
// Drill through non-dereferences.
|
||||||
for {
|
for {
|
||||||
|
|
@ -423,9 +402,9 @@ func ascompatee(op ir.Op, nl, nr []ir.Node, init *ir.Nodes) []ir.Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save expression on right side.
|
// Save expression on right side.
|
||||||
save(&as.Y)
|
save(&r)
|
||||||
|
|
||||||
late = append(late, convas(as, init))
|
appendWalkStmt(&late, convas(ir.NewAssignStmt(base.Pos, lorig, r), &late))
|
||||||
|
|
||||||
if name == nil || name.Addrtaken() || name.Class_ == ir.PEXTERN || name.Class_ == ir.PAUTOHEAP {
|
if name == nil || name.Addrtaken() || name.Class_ == ir.PEXTERN || name.Class_ == ir.PAUTOHEAP {
|
||||||
memWrite = true
|
memWrite = true
|
||||||
|
|
@ -438,7 +417,8 @@ func ascompatee(op ir.Op, nl, nr []ir.Node, init *ir.Nodes) []ir.Node {
|
||||||
assigned.Add(name)
|
assigned.Add(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(early, late...)
|
early.Append(late.Take()...)
|
||||||
|
return early
|
||||||
}
|
}
|
||||||
|
|
||||||
// readsMemory reports whether the evaluation n directly reads from
|
// readsMemory reports whether the evaluation n directly reads from
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue