From: Keith Randall Date: Tue, 10 Nov 2015 05:35:40 +0000 (-0800) Subject: [dev.ssa] cmd/compile: Deduplicate panic{index,slice,divide} calls X-Git-Tag: go1.7beta1~1623^2^2~109 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=74e568f43a8dc5a2d52fe4b761ae256dadded8ce;p=gostls13.git [dev.ssa] cmd/compile: Deduplicate panic{index,slice,divide} calls Panics are only distinguished by their type and line number, so if we can trigger two of those panics in the same line, use the same panic call. For example, in a[i]+b[j] we need only one panicindex call that both bounds checks can use. Change-Id: Ia2b6d3b1a67f2775df05fb72b8a1b149833572b7 Reviewed-on: https://go-review.googlesource.com/16772 Run-TryBot: Keith Randall Reviewed-by: David Chase --- diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 90abd8e05d..0b674806fe 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -73,6 +73,7 @@ func buildssa(fn *Node) (ssafn *ssa.Func, usessa bool) { s.f = s.config.NewFunc() s.f.Name = name s.exitCode = fn.Func.Exit + s.panics = map[funcLine]*ssa.Block{} if name == os.Getenv("GOSSAFUNC") { // TODO: tempfile? it is handy to have the location @@ -270,6 +271,15 @@ type state struct { // line number stack. The current line number is top of stack line []int32 + + // list of panic calls by function name and line number. + // Used to deduplicate panic calls. + panics map[funcLine]*ssa.Block +} + +type funcLine struct { + f *Node + line int32 } type ssaLabel struct { @@ -2517,14 +2527,18 @@ func (s *state) check(cmp *ssa.Value, fn *Node) { b.Control = cmp b.Likely = ssa.BranchLikely bNext := s.f.NewBlock(ssa.BlockPlain) - bPanic := s.f.NewBlock(ssa.BlockPlain) + line := s.peekLine() + bPanic := s.panics[funcLine{fn, line}] + if bPanic == nil { + bPanic = s.f.NewBlock(ssa.BlockPlain) + s.panics[funcLine{fn, line}] = bPanic + s.startBlock(bPanic) + // The panic call takes/returns memory to ensure that the right + // memory state is observed if the panic happens. + s.rtcall(fn, false, nil) + } b.AddEdgeTo(bNext) b.AddEdgeTo(bPanic) - s.startBlock(bPanic) - // The panic call takes/returns memory to ensure that the right - // memory state is observed if the panic happens. - s.rtcall(fn, false, nil) - s.startBlock(bNext) }