Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(413)

Delta Between Two Patch Sets: src/pkg/exp/ssa/ssadump.go

Issue 7392053: code review 7392053: exp/ssa: a number of bug fixes. (Closed)
Left Patch Set: Created 12 years ago
Right Patch Set: diff -r 1a366df36e95 https://code.google.com/p/go/ Created 12 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/exp/ssa/interp/value.go ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // +build ignore 1 // +build ignore
2 2
3 package main 3 package main
4 4
5 // ssadump: a tool for displaying and interpreting the SSA form of Go programs. 5 // ssadump: a tool for displaying and interpreting the SSA form of Go programs.
6 6
7 import ( 7 import (
8 "exp/ssa" 8 "exp/ssa"
9 "exp/ssa/interp" 9 "exp/ssa/interp"
10 "flag" 10 "flag"
11 "fmt" 11 "fmt"
12 "go/ast"
12 "log" 13 "log"
13 "os" 14 "os"
14 "runtime/pprof" 15 "runtime/pprof"
15 "strings" 16 "strings"
16 ) 17 )
17 18
18 // TODO(adonovan): perhaps these should each be separate flags? 19 // TODO(adonovan): perhaps these should each be separate flags?
19 var buildFlag = flag.String("build", "", `Options controlling the SSA builder. 20 var buildFlag = flag.String("build", "", `Options controlling the SSA builder.
20 The value is a sequence of zero or more of these letters: 21 The value is a sequence of zero or more of these letters:
21 C perform sanity [C]hecking of the SSA form. 22 C perform sanity [C]hecking of the SSA form.
22 P log [P]ackage inventory. 23 P log [P]ackage inventory.
23 F log [F]unction SSA code. 24 F log [F]unction SSA code.
24 S log [S]ource locations as SSA builder progresses. 25 S log [S]ource locations as SSA builder progresses.
25 G use binary object files from gc to provide imports (no code). 26 G use binary object files from gc to provide imports (no code).
26 L build distinct packages seria[L]ly instead of in parallel. 27 L build distinct packages seria[L]ly instead of in parallel.
27 N build [N]aive SSA form: don't replace local loads/stores with registers. 28 N build [N]aive SSA form: don't replace local loads/stores with registers.
28 `) 29 `)
29 30
30 var runFlag = flag.Bool("run", false, "Invokes the SSA interpreter on the progra m.") 31 var runFlag = flag.Bool("run", false, "Invokes the SSA interpreter on the progra m.")
31 32
32 var interpFlag = flag.String("interp", "", `Options controlling the SSA test int erpreter. 33 var interpFlag = flag.String("interp", "", `Options controlling the SSA test int erpreter.
33 The value is a sequence of zero or more more of these letters: 34 The value is a sequence of zero or more more of these letters:
34 R disable [R]ecover() from panic; show interpreter crash instead. 35 R disable [R]ecover() from panic; show interpreter crash instead.
35 T [T]race execution of the program. Best for single-threaded programs! 36 T [T]race execution of the program. Best for single-threaded programs!
36 `) 37 `)
37 38
38 const usage = `SSA builder and interpreter. 39 const usage = `SSA builder and interpreter.
39 Usage: ssadump [<flag> ...] <file.go> ... 40 Usage: ssadump [<flag> ...] [<file.go> ...] [<arg> ...]
41 ssadump [<flag> ...] <import/path> [<arg> ...]
40 Use -help flag to display options. 42 Use -help flag to display options.
41 43
42 Examples: 44 Examples:
43 % ssadump -run -interp=T hello.go # interpret a program, with tracing 45 % ssadump -run -interp=T hello.go # interpret a program, with tracing
44 % ssadump -build=FPG hello.go # quickly dump SSA form of a single packag e 46 % ssadump -build=FPG hello.go # quickly dump SSA form of a single packag e
45 ` 47 `
46 48
47 var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") 49 var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
48 50
49 func main() { 51 func main() {
50 flag.Parse() 52 flag.Parse()
51 args := flag.Args() 53 args := flag.Args()
52 54
53 // TODO(adonovan): perhaps we need a more extensible option 55 // TODO(adonovan): perhaps we need a more extensible option
54 // API than a bitset, e.g. a struct with a sane zero value? 56 // API than a bitset, e.g. a struct with a sane zero value?
55 var mode ssa.BuilderMode 57 var mode ssa.BuilderMode
56 for _, c := range *buildFlag { 58 for _, c := range *buildFlag {
57 switch c { 59 switch c {
58 case 'P': 60 case 'P':
59 » » » mode |= ssa.LogPackages 61 » » » mode |= ssa.LogPackages | ssa.BuildSerially
60 case 'F': 62 case 'F':
61 » » » mode |= ssa.LogFunctions 63 » » » mode |= ssa.LogFunctions | ssa.BuildSerially
62 case 'S': 64 case 'S':
63 » » » mode |= ssa.LogSource 65 » » » mode |= ssa.LogSource | ssa.BuildSerially
64 case 'C': 66 case 'C':
65 mode |= ssa.SanityCheckFunctions 67 mode |= ssa.SanityCheckFunctions
66 case 'N': 68 case 'N':
67 mode |= ssa.NaiveForm 69 mode |= ssa.NaiveForm
68 case 'G': 70 case 'G':
69 mode |= ssa.UseGCImporter 71 mode |= ssa.UseGCImporter
70 case 'L': 72 case 'L':
71 mode |= ssa.BuildSerially 73 mode |= ssa.BuildSerially
72 default: 74 default:
73 log.Fatalf("Unknown -build option: '%c'.", c) 75 log.Fatalf("Unknown -build option: '%c'.", c)
(...skipping 10 matching lines...) Expand all
84 default: 86 default:
85 log.Fatalf("Unknown -interp option: '%c'.", c) 87 log.Fatalf("Unknown -interp option: '%c'.", c)
86 } 88 }
87 } 89 }
88 90
89 if len(args) == 0 { 91 if len(args) == 0 {
90 fmt.Fprint(os.Stderr, usage) 92 fmt.Fprint(os.Stderr, usage)
91 os.Exit(1) 93 os.Exit(1)
92 } 94 }
93 95
94 // Treat all leading consecutive "*.go" arguments as a single package.
95 //
96 // TODO(gri): make it a typechecker error for there to be
97 // duplicate (e.g.) main functions in the same package.
98 var gofiles []string
99 for len(args) > 0 && strings.HasSuffix(args[0], ".go") {
100 gofiles = append(gofiles, args[0])
101 args = args[1:]
102 }
103 if gofiles == nil {
104 log.Fatal("No *.go source files specified.")
105 }
106
107 // Profiling support. 96 // Profiling support.
108 if *cpuprofile != "" { 97 if *cpuprofile != "" {
109 f, err := os.Create(*cpuprofile) 98 f, err := os.Create(*cpuprofile)
110 if err != nil { 99 if err != nil {
111 log.Fatal(err) 100 log.Fatal(err)
112 } 101 }
113 pprof.StartCPUProfile(f) 102 pprof.StartCPUProfile(f)
114 defer pprof.StopCPUProfile() 103 defer pprof.StopCPUProfile()
115 } 104 }
116 105
117 // TODO(adonovan): permit naming a package directly instead of
118 // a list of .go files.
119
120 // TODO(adonovan/gri): the cascade of errors is confusing due 106 // TODO(adonovan/gri): the cascade of errors is confusing due
121 // to reentrant control flow. Disable for now and re-think. 107 // to reentrant control flow. Disable for now and re-think.
122 var errh func(error) 108 var errh func(error)
123 // errh = func(err error) { fmt.Println(err.Error()) } 109 // errh = func(err error) { fmt.Println(err.Error()) }
124 110
125 » b := ssa.NewBuilder(mode, ssa.GorootLoader, errh) 111 » loader := ssa.GorootLoader
126 » files, err := ssa.ParseFiles(b.Prog.Files, ".", gofiles...) 112 » b := ssa.NewBuilder(mode, loader, errh)
113
114 » var pkgname string
115 » var files []*ast.File
116 » var err error
117
118 » switch {
119 » case len(args) == 0:
120 » » log.Fatal("No *.go source files nor package name was specified." )
121
122 » case strings.HasSuffix(args[0], ".go"):
123 » » // % ssadump a.go b.go ...
124 » » // Leading consecutive *.go arguments constitute main package.
125 » » i := 1
126 » » for ; i < len(args) && strings.HasSuffix(args[i], ".go"); i++ {
127 » » }
128 » » files, err = ssa.ParseFiles(b.Prog.Files, ".", args[:i]...)
129 » » pkgname = "main"
130 » » args = args[i:]
131
132 » default:
133 » » // % ssadump my/package ...
134 » » // First argument is import path of main package.
135 » » pkgname = args[0]
136 » » args = args[1:]
137 » » files, err = loader(b.Prog.Files, pkgname)
138 » }
127 if err != nil { 139 if err != nil {
128 log.Fatalf(err.Error()) 140 log.Fatalf(err.Error())
129 } 141 }
130 » mainpkg, err := b.CreatePackage("main", files) 142
143 » // TODO(gri): make it a typechecker error for there to be
144 » // duplicate (e.g.) main functions in the same package.
145 » mainpkg, err := b.CreatePackage(pkgname, files)
131 if err != nil { 146 if err != nil {
132 log.Fatalf(err.Error()) 147 log.Fatalf(err.Error())
133 } 148 }
134 b.BuildAllPackages() 149 b.BuildAllPackages()
135 b = nil // discard Builder 150 b = nil // discard Builder
136 151
137 if *runFlag { 152 if *runFlag {
138 » » interp.Interpret(mainpkg, interpMode, gofiles[0], args) 153 » » interp.Interpret(mainpkg, interpMode, pkgname, args)
139 } 154 }
140 } 155 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b