aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/cache.go
diff options
context:
space:
mode:
authorHeschi Kreinick <heschi@google.com>2017-10-26 15:40:17 -0400
committerHeschi Kreinick <heschi@google.com>2018-02-14 18:29:19 +0000
commit2075a9323d8d496e4738a6f4038c6dfb7c623130 (patch)
tree38f9f8ad7ad1e7b235321e92f05346ca4f757ea1 /src/cmd/compile/internal/ssa/cache.go
parent7d7af6106f7ce7fb112f754cd1d991c74552247c (diff)
downloadgo-2075a9323d8d496e4738a6f4038c6dfb7c623130.tar.gz
go-2075a9323d8d496e4738a6f4038c6dfb7c623130.zip
cmd/compile: reimplement location list generation
Completely redesign and reimplement location list generation to be more efficient, and hopefully not too hard to understand. RegKills are gone. Instead of using the regalloc's liveness calculations, redo them using the Ops' clobber information. Besides saving a lot of Values, this avoids adding RegKills to blocks that would be empty otherwise, which was messing up optimizations. This does mean that it's much harder to tell whether the generation process is buggy (there's nothing to cross-check it with), and there may be disagreements with GC liveness. But the performance gain is significant, and it's nice not to be messing with earlier compiler phases. The intermediate representations are gone. Instead of producing ssa.BlockDebugs, then dwarf.LocationLists, and then finally real location lists, go directly from the SSA to a (mostly) real location list. Because the SSA analysis happens before assembly, it stores encoded block/value IDs where PCs would normally go. It would be easier to do the SSA analysis after assembly, but I didn't want to retain the SSA just for that. Generation proceeds in two phases: first, it traverses the function in CFG order, storing the state of the block at the beginning and end. End states are used to produce the start states of the successor blocks. In the second phase, it traverses in program text order and produces the location lists. The processing in the second phase is redundant, but much cheaper than storing the intermediate representation. It might be possible to combine the two phases somewhat to take advantage of cases where the CFG matches the block layout, but I haven't tried. Location lists are finalized by adding a base address selection entry, translating each encoded block/value ID to a real PC, and adding the terminating zero entry. This probably won't work on OSX, where dsymutil will choke on the base address selection. I tried emitting CU-relative relocations for each address, and it was *very* bad for performance -- it uses more memory storing all the relocations than it does for the actual location list bytes. I think I'm going to end up synthesizing the relocations in the linker only on OSX, but TBD. TestNexting needs updating: with more optimizations working, the debugger doesn't stop on the continue (line 88) any more, and the test's duplicate suppression kicks in. Also, dx and dy live a little longer now, but they have the correct values. Change-Id: Ie772dfe23a4e389ca573624fac4d05401ae32307 Reviewed-on: https://go-review.googlesource.com/89356 Run-TryBot: Heschi Kreinick <heschi@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/cache.go')
-rw-r--r--src/cmd/compile/internal/ssa/cache.go22
1 files changed, 0 insertions, 22 deletions
diff --git a/src/cmd/compile/internal/ssa/cache.go b/src/cmd/compile/internal/ssa/cache.go
index 8434084bde..f1018da497 100644
--- a/src/cmd/compile/internal/ssa/cache.go
+++ b/src/cmd/compile/internal/ssa/cache.go
@@ -14,11 +14,6 @@ type Cache struct {
blocks [200]Block
locs [2000]Location
- // Storage for DWARF variable locations. Lazily allocated
- // since location lists are off by default.
- varLocs []VarLoc
- curVarLoc int
-
// Reusable stackAllocState.
// See stackalloc.go's {new,put}StackAllocState.
stackAllocState *stackAllocState
@@ -43,21 +38,4 @@ func (c *Cache) Reset() {
for i := range xl {
xl[i] = nil
}
- xvl := c.varLocs[:c.curVarLoc]
- for i := range xvl {
- xvl[i] = VarLoc{}
- }
- c.curVarLoc = 0
-}
-
-func (c *Cache) NewVarLoc() *VarLoc {
- if c.varLocs == nil {
- c.varLocs = make([]VarLoc, 4000)
- }
- if c.curVarLoc == len(c.varLocs) {
- return &VarLoc{}
- }
- vl := &c.varLocs[c.curVarLoc]
- c.curVarLoc++
- return vl
}