github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/ssa/print.go (about)

     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  }