]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: get rid of unnecessary inline marks
authorKeith Randall <keithr@alum.mit.edu>
Tue, 2 Apr 2019 22:00:54 +0000 (15:00 -0700)
committerKeith Randall <khr@golang.org>
Mon, 8 Apr 2019 16:46:20 +0000 (16:46 +0000)
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>
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/ssa/deadcode.go

index 88c294173b6b4455abcb47572f06bf3ea1b4b9f4..38be394bfb791cb93b6d26090c5a43f314bee3c2 100644 (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)
 
index 3c0f8f858aca9b16d71f975c925ac2646b628317..ceb29337667605b532c564c1560f6d7286839f77 100644 (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 {