mirror of
https://github.com/golang/go
synced 2024-09-30 02:34:40 -06:00
[dev.regabi] cmd/compile: use ir.DoChildren directly in inlining
Passes toolstash -cmp. Change-Id: Ie35e8163fa0e61ed9e1b259929c8cbe82ee5301e Reviewed-on: https://go-review.googlesource.com/c/go/+/282212 Run-TryBot: Baokun Lee <bk@golangcn.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Trust: Baokun Lee <bk@golangcn.org>
This commit is contained in:
parent
213c3905e9
commit
9f036844db
@ -27,7 +27,6 @@
|
|||||||
package inline
|
package inline
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/constant"
|
"go/constant"
|
||||||
"strings"
|
"strings"
|
||||||
@ -256,17 +255,12 @@ type hairyVisitor struct {
|
|||||||
reason string
|
reason string
|
||||||
extraCallCost int32
|
extraCallCost int32
|
||||||
usedLocals map[*ir.Name]bool
|
usedLocals map[*ir.Name]bool
|
||||||
do func(ir.Node) error
|
do func(ir.Node) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var errBudget = errors.New("too expensive")
|
|
||||||
|
|
||||||
func (v *hairyVisitor) tooHairy(fn *ir.Func) bool {
|
func (v *hairyVisitor) tooHairy(fn *ir.Func) bool {
|
||||||
v.do = v.doNode // cache closure
|
v.do = v.doNode // cache closure
|
||||||
|
if ir.DoChildren(fn, v.do) {
|
||||||
err := errChildren(fn, v.do)
|
|
||||||
if err != nil {
|
|
||||||
v.reason = err.Error()
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if v.budget < 0 {
|
if v.budget < 0 {
|
||||||
@ -276,11 +270,10 @@ func (v *hairyVisitor) tooHairy(fn *ir.Func) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *hairyVisitor) doNode(n ir.Node) error {
|
func (v *hairyVisitor) doNode(n ir.Node) bool {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return nil
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op() {
|
switch n.Op() {
|
||||||
// Call is okay if inlinable and we have the budget for the body.
|
// Call is okay if inlinable and we have the budget for the body.
|
||||||
case ir.OCALLFUNC:
|
case ir.OCALLFUNC:
|
||||||
@ -294,7 +287,8 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
|
|||||||
if name.Class == ir.PFUNC && types.IsRuntimePkg(name.Sym().Pkg) {
|
if name.Class == ir.PFUNC && types.IsRuntimePkg(name.Sym().Pkg) {
|
||||||
fn := name.Sym().Name
|
fn := name.Sym().Name
|
||||||
if fn == "getcallerpc" || fn == "getcallersp" {
|
if fn == "getcallerpc" || fn == "getcallersp" {
|
||||||
return errors.New("call to " + fn)
|
v.reason = "call to " + fn
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if fn == "throw" {
|
if fn == "throw" {
|
||||||
v.budget -= inlineExtraThrowCost
|
v.budget -= inlineExtraThrowCost
|
||||||
@ -357,7 +351,8 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
|
|||||||
case ir.ORECOVER:
|
case ir.ORECOVER:
|
||||||
// recover matches the argument frame pointer to find
|
// recover matches the argument frame pointer to find
|
||||||
// the right panic value, so it needs an argument frame.
|
// the right panic value, so it needs an argument frame.
|
||||||
return errors.New("call to recover")
|
v.reason = "call to recover"
|
||||||
|
return true
|
||||||
|
|
||||||
case ir.OCLOSURE:
|
case ir.OCLOSURE:
|
||||||
// TODO(danscales) - fix some bugs when budget is lowered below 30
|
// TODO(danscales) - fix some bugs when budget is lowered below 30
|
||||||
@ -371,24 +366,27 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
|
|||||||
ir.ODEFER,
|
ir.ODEFER,
|
||||||
ir.ODCLTYPE, // can't print yet
|
ir.ODCLTYPE, // can't print yet
|
||||||
ir.OTAILCALL:
|
ir.OTAILCALL:
|
||||||
return errors.New("unhandled op " + n.Op().String())
|
v.reason = "unhandled op " + n.Op().String()
|
||||||
|
return true
|
||||||
|
|
||||||
case ir.OAPPEND:
|
case ir.OAPPEND:
|
||||||
v.budget -= inlineExtraAppendCost
|
v.budget -= inlineExtraAppendCost
|
||||||
|
|
||||||
case ir.ODCLCONST, ir.OFALL:
|
case ir.ODCLCONST, ir.OFALL:
|
||||||
// These nodes don't produce code; omit from inlining budget.
|
// These nodes don't produce code; omit from inlining budget.
|
||||||
return nil
|
return false
|
||||||
|
|
||||||
case ir.OFOR, ir.OFORUNTIL:
|
case ir.OFOR, ir.OFORUNTIL:
|
||||||
n := n.(*ir.ForStmt)
|
n := n.(*ir.ForStmt)
|
||||||
if n.Label != nil {
|
if n.Label != nil {
|
||||||
return errors.New("labeled control")
|
v.reason = "labeled control"
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
case ir.OSWITCH:
|
case ir.OSWITCH:
|
||||||
n := n.(*ir.SwitchStmt)
|
n := n.(*ir.SwitchStmt)
|
||||||
if n.Label != nil {
|
if n.Label != nil {
|
||||||
return errors.New("labeled control")
|
v.reason = "labeled control"
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
// case ir.ORANGE, ir.OSELECT in "unhandled" above
|
// case ir.ORANGE, ir.OSELECT in "unhandled" above
|
||||||
|
|
||||||
@ -404,16 +402,9 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
|
|||||||
if ir.IsConst(n.Cond, constant.Bool) {
|
if ir.IsConst(n.Cond, constant.Bool) {
|
||||||
// This if and the condition cost nothing.
|
// This if and the condition cost nothing.
|
||||||
// TODO(rsc): It seems strange that we visit the dead branch.
|
// TODO(rsc): It seems strange that we visit the dead branch.
|
||||||
if err := errList(n.Init(), v.do); err != nil {
|
return doList(n.Init(), v.do) ||
|
||||||
return err
|
doList(n.Body, v.do) ||
|
||||||
}
|
doList(n.Else, v.do)
|
||||||
if err := errList(n.Body, v.do); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := errList(n.Else, v.do); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
@ -439,10 +430,11 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
|
|||||||
|
|
||||||
// When debugging, don't stop early, to get full cost of inlining this function
|
// When debugging, don't stop early, to get full cost of inlining this function
|
||||||
if v.budget < 0 && base.Flag.LowerM < 2 && !logopt.Enabled() {
|
if v.budget < 0 && base.Flag.LowerM < 2 && !logopt.Enabled() {
|
||||||
return errBudget
|
v.reason = "too expensive"
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return errChildren(n, v.do)
|
return ir.DoChildren(n, v.do)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isBigFunc(fn *ir.Func) bool {
|
func isBigFunc(fn *ir.Func) bool {
|
||||||
@ -1411,21 +1403,13 @@ func numNonClosures(list []*ir.Func) int {
|
|||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mdempsky): Update inl.go to use ir.DoChildren directly.
|
func doList(list []ir.Node, do func(ir.Node) bool) bool {
|
||||||
func errChildren(n ir.Node, do func(ir.Node) error) (err error) {
|
|
||||||
ir.DoChildren(n, func(x ir.Node) bool {
|
|
||||||
err = do(x)
|
|
||||||
return err != nil
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func errList(list []ir.Node, do func(ir.Node) error) error {
|
|
||||||
for _, x := range list {
|
for _, x := range list {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
if err := do(x); err != nil {
|
if do(x) {
|
||||||
return err
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return false
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user