...

Source file src/pkg/cmd/compile/internal/ssa/print.go

     1	// Copyright 2015 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package ssa
     6	
     7	import (
     8		"bytes"
     9		"fmt"
    10		"io"
    11	)
    12	
    13	func printFunc(f *Func) {
    14		f.Logf("%s", f)
    15	}
    16	
    17	func (f *Func) String() string {
    18		var buf bytes.Buffer
    19		p := stringFuncPrinter{w: &buf}
    20		fprintFunc(p, f)
    21		return buf.String()
    22	}
    23	
    24	type funcPrinter interface {
    25		header(f *Func)
    26		startBlock(b *Block, reachable bool)
    27		endBlock(b *Block)
    28		value(v *Value, live bool)
    29		startDepCycle()
    30		endDepCycle()
    31		named(n LocalSlot, vals []*Value)
    32	}
    33	
    34	type stringFuncPrinter struct {
    35		w io.Writer
    36	}
    37	
    38	func (p stringFuncPrinter) header(f *Func) {
    39		fmt.Fprint(p.w, f.Name)
    40		fmt.Fprint(p.w, " ")
    41		fmt.Fprintln(p.w, f.Type)
    42	}
    43	
    44	func (p stringFuncPrinter) startBlock(b *Block, reachable bool) {
    45		fmt.Fprintf(p.w, "  b%d:", b.ID)
    46		if len(b.Preds) > 0 {
    47			io.WriteString(p.w, " <-")
    48			for _, e := range b.Preds {
    49				pred := e.b
    50				fmt.Fprintf(p.w, " b%d", pred.ID)
    51			}
    52		}
    53		if !reachable {
    54			fmt.Fprint(p.w, " DEAD")
    55		}
    56		io.WriteString(p.w, "\n")
    57	}
    58	
    59	func (p stringFuncPrinter) endBlock(b *Block) {
    60		fmt.Fprintln(p.w, "    "+b.LongString())
    61	}
    62	
    63	func (p stringFuncPrinter) value(v *Value, live bool) {
    64		fmt.Fprint(p.w, "    ")
    65		//fmt.Fprint(p.w, v.Block.Func.fe.Pos(v.Pos))
    66		//fmt.Fprint(p.w, ": ")
    67		fmt.Fprint(p.w, v.LongString())
    68		if !live {
    69			fmt.Fprint(p.w, " DEAD")
    70		}
    71		fmt.Fprintln(p.w)
    72	}
    73	
    74	func (p stringFuncPrinter) startDepCycle() {
    75		fmt.Fprintln(p.w, "dependency cycle!")
    76	}
    77	
    78	func (p stringFuncPrinter) endDepCycle() {}
    79	
    80	func (p stringFuncPrinter) named(n LocalSlot, vals []*Value) {
    81		fmt.Fprintf(p.w, "name %s: %v\n", n, vals)
    82	}
    83	
    84	func fprintFunc(p funcPrinter, f *Func) {
    85		reachable, live := findlive(f)
    86		defer f.retDeadcodeLive(live)
    87		p.header(f)
    88		printed := make([]bool, f.NumValues())
    89		for _, b := range f.Blocks {
    90			p.startBlock(b, reachable[b.ID])
    91	
    92			if f.scheduled {
    93				// Order of Values has been decided - print in that order.
    94				for _, v := range b.Values {
    95					p.value(v, live[v.ID])
    96					printed[v.ID] = true
    97				}
    98				p.endBlock(b)
    99				continue
   100			}
   101	
   102			// print phis first since all value cycles contain a phi
   103			n := 0
   104			for _, v := range b.Values {
   105				if v.Op != OpPhi {
   106					continue
   107				}
   108				p.value(v, live[v.ID])
   109				printed[v.ID] = true
   110				n++
   111			}
   112	
   113			// print rest of values in dependency order
   114			for n < len(b.Values) {
   115				m := n
   116			outer:
   117				for _, v := range b.Values {
   118					if printed[v.ID] {
   119						continue
   120					}
   121					for _, w := range v.Args {
   122						// w == nil shouldn't happen, but if it does,
   123						// don't panic; we'll get a better diagnosis later.
   124						if w != nil && w.Block == b && !printed[w.ID] {
   125							continue outer
   126						}
   127					}
   128					p.value(v, live[v.ID])
   129					printed[v.ID] = true
   130					n++
   131				}
   132				if m == n {
   133					p.startDepCycle()
   134					for _, v := range b.Values {
   135						if printed[v.ID] {
   136							continue
   137						}
   138						p.value(v, live[v.ID])
   139						printed[v.ID] = true
   140						n++
   141					}
   142					p.endDepCycle()
   143				}
   144			}
   145	
   146			p.endBlock(b)
   147		}
   148		for _, name := range f.Names {
   149			p.named(name, f.NamedValues[name])
   150		}
   151	}
   152	

View as plain text