mirror of
https://github.com/golang/go
synced 2024-09-29 22:34:33 -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
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"strings"
|
||||
@ -256,17 +255,12 @@ type hairyVisitor struct {
|
||||
reason string
|
||||
extraCallCost int32
|
||||
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 {
|
||||
v.do = v.doNode // cache closure
|
||||
|
||||
err := errChildren(fn, v.do)
|
||||
if err != nil {
|
||||
v.reason = err.Error()
|
||||
if ir.DoChildren(fn, v.do) {
|
||||
return true
|
||||
}
|
||||
if v.budget < 0 {
|
||||
@ -276,11 +270,10 @@ func (v *hairyVisitor) tooHairy(fn *ir.Func) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (v *hairyVisitor) doNode(n ir.Node) error {
|
||||
func (v *hairyVisitor) doNode(n ir.Node) bool {
|
||||
if n == nil {
|
||||
return nil
|
||||
return false
|
||||
}
|
||||
|
||||
switch n.Op() {
|
||||
// Call is okay if inlinable and we have the budget for the body.
|
||||
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) {
|
||||
fn := name.Sym().Name
|
||||
if fn == "getcallerpc" || fn == "getcallersp" {
|
||||
return errors.New("call to " + fn)
|
||||
v.reason = "call to " + fn
|
||||
return true
|
||||
}
|
||||
if fn == "throw" {
|
||||
v.budget -= inlineExtraThrowCost
|
||||
@ -357,7 +351,8 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
|
||||
case ir.ORECOVER:
|
||||
// recover matches the argument frame pointer to find
|
||||
// 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:
|
||||
// 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.ODCLTYPE, // can't print yet
|
||||
ir.OTAILCALL:
|
||||
return errors.New("unhandled op " + n.Op().String())
|
||||
v.reason = "unhandled op " + n.Op().String()
|
||||
return true
|
||||
|
||||
case ir.OAPPEND:
|
||||
v.budget -= inlineExtraAppendCost
|
||||
|
||||
case ir.ODCLCONST, ir.OFALL:
|
||||
// These nodes don't produce code; omit from inlining budget.
|
||||
return nil
|
||||
return false
|
||||
|
||||
case ir.OFOR, ir.OFORUNTIL:
|
||||
n := n.(*ir.ForStmt)
|
||||
if n.Label != nil {
|
||||
return errors.New("labeled control")
|
||||
v.reason = "labeled control"
|
||||
return true
|
||||
}
|
||||
case ir.OSWITCH:
|
||||
n := n.(*ir.SwitchStmt)
|
||||
if n.Label != nil {
|
||||
return errors.New("labeled control")
|
||||
v.reason = "labeled control"
|
||||
return true
|
||||
}
|
||||
// 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) {
|
||||
// This if and the condition cost nothing.
|
||||
// TODO(rsc): It seems strange that we visit the dead branch.
|
||||
if err := errList(n.Init(), v.do); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := errList(n.Body, v.do); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := errList(n.Else, v.do); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return doList(n.Init(), v.do) ||
|
||||
doList(n.Body, v.do) ||
|
||||
doList(n.Else, v.do)
|
||||
}
|
||||
|
||||
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
|
||||
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 {
|
||||
@ -1411,21 +1403,13 @@ func numNonClosures(list []*ir.Func) int {
|
||||
return count
|
||||
}
|
||||
|
||||
// TODO(mdempsky): Update inl.go to use ir.DoChildren directly.
|
||||
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 {
|
||||
func doList(list []ir.Node, do func(ir.Node) bool) bool {
|
||||
for _, x := range list {
|
||||
if x != nil {
|
||||
if err := do(x); err != nil {
|
||||
return err
|
||||
if do(x) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user