7 "honnef.co/go/tools/go/ir"
8 "honnef.co/go/tools/go/types/typeutil"
11 func Reachable(from, to *ir.BasicBlock) bool {
15 if from.Dominates(to) {
20 Walk(from, func(b *ir.BasicBlock) bool {
30 func Walk(b *ir.BasicBlock, fn func(*ir.BasicBlock) bool) {
31 seen := map[*ir.BasicBlock]bool{}
32 wl := []*ir.BasicBlock{b}
43 wl = append(wl, b.Succs...)
47 func Vararg(x *ir.Slice) ([]ir.Value, bool) {
49 slice, ok := x.X.(*ir.Alloc)
53 for _, ref := range *slice.Referrers() {
57 if ref.Block() != x.Block() {
60 idx, ok := ref.(*ir.IndexAddr)
64 if len(*idx.Referrers()) != 1 {
67 store, ok := (*idx.Referrers())[0].(*ir.Store)
71 out = append(out, store.Val)
76 func CallName(call *ir.CallCommon) string {
80 switch v := call.Value.(type) {
82 fn, ok := v.Object().(*types.Func)
86 return typeutil.FuncName(fn)
93 func IsCallTo(call *ir.CallCommon, name string) bool { return CallName(call) == name }
95 func IsCallToAny(call *ir.CallCommon, names ...string) bool {
97 for _, name := range names {
105 func FilterDebug(instr []ir.Instruction) []ir.Instruction {
106 var out []ir.Instruction
107 for _, ins := range instr {
108 if _, ok := ins.(*ir.DebugRef); !ok {
109 out = append(out, ins)
115 func IsExample(fn *ir.Function) bool {
116 if !strings.HasPrefix(fn.Name(), "Example") {
119 f := fn.Prog.Fset.File(fn.Pos())
123 return strings.HasSuffix(f.Name(), "_test.go")
126 // Flatten recursively returns the underlying value of an ir.Sigma or
127 // ir.Phi node. If all edges in an ir.Phi node are the same (after
128 // flattening), the flattened edge will get returned. If flattening is
129 // not possible, nil is returned.
130 func Flatten(v ir.Value) ir.Value {
132 seen := map[ir.Value]struct{}{}
134 var dfs func(v ir.Value)
135 dfs = func(v ir.Value) {
139 if _, ok := seen[v]; ok {
144 switch v := v.(type) {
148 for _, e := range v.Edges {