1
0
mirror of https://github.com/golang/go synced 2024-09-25 03:10:12 -06:00

cmd/compile: get rid of unnecessary inline marks

If no other instruction mentions an inline mark, we can get rid of it.
This normally happens when the inlined function is empty, or when all
of its code is folded into other instructions.

Also use consistent statement-ness for inline mark positions, so that
more of them can be removed in favor of existing instructions.

Update #29571
Fixes #31172

Change-Id: I71f84d355101f37a27960d9e8528f42f92767496
Reviewed-on: https://go-review.googlesource.com/c/go/+/170445
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
Keith Randall 2019-04-02 15:00:54 -07:00 committed by Keith Randall
parent 7bb8fc1033
commit c46ebec322
2 changed files with 32 additions and 1 deletions

View File

@ -1054,7 +1054,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {
// to put a breakpoint. Not sure if that's really necessary or not
// (in which case it could go at the end of the function instead).
inlMark := nod(OINLMARK, nil, nil)
inlMark.Pos = n.Pos
inlMark.Pos = n.Pos.WithDefaultStmt()
inlMark.Xoffset = int64(newIndex)
ninit.Append(inlMark)

View File

@ -76,6 +76,30 @@ func liveValues(f *Func, reachable []bool) (live []bool, liveOrderStmts []*Value
return
}
// Record all the inline indexes we need
var liveInlIdx map[int]bool
pt := f.Config.ctxt.PosTable
for _, b := range f.Blocks {
for _, v := range b.Values {
i := pt.Pos(v.Pos).Base().InliningIndex()
if i < 0 {
continue
}
if liveInlIdx == nil {
liveInlIdx = map[int]bool{}
}
liveInlIdx[i] = true
}
i := pt.Pos(b.Pos).Base().InliningIndex()
if i < 0 {
continue
}
if liveInlIdx == nil {
liveInlIdx = map[int]bool{}
}
liveInlIdx[i] = true
}
// Find all live values
q := f.Cache.deadcode.q[:0]
defer func() { f.Cache.deadcode.q = q }()
@ -103,6 +127,13 @@ func liveValues(f *Func, reachable []bool) (live []bool, liveOrderStmts []*Value
}
if v.Type.IsVoid() && !live[v.ID] {
// The only Void ops are nil checks and inline marks. We must keep these.
if v.Op == OpInlMark && !liveInlIdx[int(v.AuxInt)] {
// We don't need marks for bodies that
// have been completely optimized away.
// TODO: save marks only for bodies which
// have a faulting instruction or a call?
continue
}
live[v.ID] = true
q = append(q, v)
if v.Pos.IsStmt() != src.PosNotStmt {