mirror of https://github.com/golang/go.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 <khr@golang.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
170589ee1c
commit
74e568f43a
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue