From 30166088e46389150ed2e766c1fb02bd3c0d8e6a Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Wed, 11 Jun 2014 16:33:25 -0400 Subject: [PATCH] go/ssa: remove optimization of 'rundefers'. The SSA builder shouldn't be in the business of interprocedural optimization, especially in the presence of concurrency. This causes the instruction count to increase by 0.03%. LGTM=gri R=gri, pcc CC=golang-codereviews https://golang.org/cl/105020045 --- go/ssa/builder.go | 19 +------------------ go/ssa/util.go | 16 ---------------- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/go/ssa/builder.go b/go/ssa/builder.go index be55bdb67cf..fcf320edc7b 100644 --- a/go/ssa/builder.go +++ b/go/ssa/builder.go @@ -1918,24 +1918,7 @@ start: // locals (which may be mutated by the deferred call) // and return them. if fn.namedResults != nil { - // Optimization: if we can prove the deferred call - // won't cause recovery from panic, we can avoid a - // Recover block. - // We scan the callee for calls to recover() iff: - // - it's a static call - // - to a function in the same package - // (other packages' SSA building happens concurrently) - // - whose SSA building has started (Blocks != nil) - // - and finished (i.e. not this function) - // NB, this is always true for: defer func() { ... } () - // - // TODO(adonovan): optimize interpackage cases, e.g. - // (sync.Mutex).Unlock(), (io.Closer).Close - if callee, ok := v.Call.Value.(*Function); ok && callee.Pkg == fn.Pkg && callee != fn && callee.Blocks != nil && !callsRecover(callee) { - // Deferred call cannot cause recovery from panic. - } else { - createRecoverBlock(fn) - } + createRecoverBlock(fn) } case *ast.ReturnStmt: diff --git a/go/ssa/util.go b/go/ssa/util.go index 3c661c360c8..56220aba4ff 100644 --- a/go/ssa/util.go +++ b/go/ssa/util.go @@ -103,22 +103,6 @@ func logStack(format string, args ...interface{}) func() { } } -// callsRecover reports whether f contains a direct call to recover(). -func callsRecover(f *Function) bool { - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - if call, ok := instr.(*Call); ok { - if blt, ok := call.Call.Value.(*Builtin); ok { - if blt.Name() == "recover" { - return true - } - } - } - } - } - return false -} - // newVar creates a 'var' for use in a types.Tuple. func newVar(name string, typ types.Type) *types.Var { return types.NewParam(token.NoPos, nil, name, typ)