go.tools/ssa: move AllFunctions to ssautil subpackage

R=gri
CC=golang-dev
https://golang.org/cl/37970043
This commit is contained in:
Alan Donovan 2013-12-05 17:16:00 -05:00
parent d6490fa510
commit d063887ea0
4 changed files with 18 additions and 16 deletions

View File

@ -14,6 +14,7 @@ import (
"code.google.com/p/go.tools/oracle/serial" "code.google.com/p/go.tools/oracle/serial"
"code.google.com/p/go.tools/pointer" "code.google.com/p/go.tools/pointer"
"code.google.com/p/go.tools/ssa" "code.google.com/p/go.tools/ssa"
"code.google.com/p/go.tools/ssa/ssautil"
) )
// peers enumerates, for a given channel send (or receive) operation, // peers enumerates, for a given channel send (or receive) operation,
@ -36,7 +37,7 @@ func peers(o *Oracle, qpos *QueryPos) (queryResult, error) {
// Look at all send/receive instructions in the whole ssa.Program. // Look at all send/receive instructions in the whole ssa.Program.
// Build a list of those of same type to query. // Build a list of those of same type to query.
allFuncs := ssa.AllFunctions(o.prog) allFuncs := ssautil.AllFunctions(o.prog)
for fn := range allFuncs { for fn := range allFuncs {
for _, b := range fn.Blocks { for _, b := range fn.Blocks {
for _, instr := range b.Instrs { for _, instr := range b.Instrs {

View File

@ -114,14 +114,12 @@
// either accurate or unambiguous. The public API exposes a number of // either accurate or unambiguous. The public API exposes a number of
// name-based maps for client convenience. // name-based maps for client convenience.
// //
// The ssa/ssautil package provides various utilities that depend only
// on the public API of this package.
//
// TODO(adonovan): Consider the exceptional control-flow implications // TODO(adonovan): Consider the exceptional control-flow implications
// of defer and recover(). // of defer and recover().
// //
// TODO(adonovan): write an example showing how to visit all functions
// in a Program, including package init functions, methods of named
// and anon types, and functions used as values but never called
// directly. See AllFunctions().
//
// TODO(adonovan): write a how-to document for all the various cases // TODO(adonovan): write a how-to document for all the various cases
// of trying to determine corresponding elements across the four // of trying to determine corresponding elements across the four
// domains of source locations, ast.Nodes, types.Objects, // domains of source locations, ast.Nodes, types.Objects,

View File

@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package ssa package ssautil
import "code.google.com/p/go.tools/ssa"
// This file defines utilities for visiting the SSA representation of // This file defines utilities for visiting the SSA representation of
// a Program. // a Program.
@ -17,24 +19,24 @@ package ssa
// //
// Precondition: all packages are built. // Precondition: all packages are built.
// //
func AllFunctions(prog *Program) map[*Function]bool { func AllFunctions(prog *ssa.Program) map[*ssa.Function]bool {
visit := visitor{ visit := visitor{
prog: prog, prog: prog,
seen: make(map[*Function]bool), seen: make(map[*ssa.Function]bool),
} }
visit.program() visit.program()
return visit.seen return visit.seen
} }
type visitor struct { type visitor struct {
prog *Program prog *ssa.Program
seen map[*Function]bool seen map[*ssa.Function]bool
} }
func (visit *visitor) program() { func (visit *visitor) program() {
for _, pkg := range visit.prog.AllPackages() { for _, pkg := range visit.prog.AllPackages() {
for _, mem := range pkg.Members { for _, mem := range pkg.Members {
if fn, ok := mem.(*Function); ok { if fn, ok := mem.(*ssa.Function); ok {
visit.function(fn) visit.function(fn)
} }
} }
@ -47,14 +49,14 @@ func (visit *visitor) program() {
} }
} }
func (visit *visitor) function(fn *Function) { func (visit *visitor) function(fn *ssa.Function) {
if !visit.seen[fn] { if !visit.seen[fn] {
visit.seen[fn] = true visit.seen[fn] = true
var buf [10]*ssa.Value // avoid alloc in common case
for _, b := range fn.Blocks { for _, b := range fn.Blocks {
for _, instr := range b.Instrs { for _, instr := range b.Instrs {
var buf [10]*Value // avoid alloc in common case
for _, op := range instr.Operands(buf[:0]) { for _, op := range instr.Operands(buf[:0]) {
if fn, ok := (*op).(*Function); ok { if fn, ok := (*op).(*ssa.Function); ok {
visit.function(fn) visit.function(fn)
} }
} }

View File

@ -21,6 +21,7 @@ import (
"code.google.com/p/go.tools/importer" "code.google.com/p/go.tools/importer"
"code.google.com/p/go.tools/ssa" "code.google.com/p/go.tools/ssa"
"code.google.com/p/go.tools/ssa/ssautil"
) )
const debugMode = false const debugMode = false
@ -97,7 +98,7 @@ func TestStdlib(t *testing.T) {
} }
// Dump some statistics. // Dump some statistics.
allFuncs := ssa.AllFunctions(prog) allFuncs := ssautil.AllFunctions(prog)
var numInstrs int var numInstrs int
for fn := range allFuncs { for fn := range allFuncs {
for _, b := range fn.Blocks { for _, b := range fn.Blocks {