diff --git a/cmd/ssadump/main.go b/cmd/ssadump/main.go index 773b573d4e..f955783b40 100644 --- a/cmd/ssadump/main.go +++ b/cmd/ssadump/main.go @@ -23,8 +23,8 @@ var buildFlag = flag.String("build", "", `Options controlling the SSA builder. The value is a sequence of zero or more of these letters: C perform sanity [C]hecking of the SSA form. D include [D]ebug info for every function. -P log [P]ackage inventory. -F log [F]unction SSA code. +P print [P]ackage inventory. +F print [F]unction SSA code. S log [S]ource locations as SSA builder progresses. G use binary object files from gc to provide imports (no code). L build distinct packages seria[L]ly instead of in parallel. @@ -105,9 +105,9 @@ func doMain() error { case 'D': mode |= ssa.GlobalDebug case 'P': - mode |= ssa.LogPackages | ssa.BuildSerially + mode |= ssa.PrintPackages case 'F': - mode |= ssa.LogFunctions | ssa.BuildSerially + mode |= ssa.PrintFunctions case 'S': mode |= ssa.LogSource | ssa.BuildSerially case 'C': diff --git a/go/ssa/create.go b/go/ssa/create.go index d48b2d3c86..7a3629edfe 100644 --- a/go/ssa/create.go +++ b/go/ssa/create.go @@ -11,6 +11,7 @@ import ( "go/ast" "go/token" "os" + "sync" "code.google.com/p/go.tools/go/loader" "code.google.com/p/go.tools/go/types" @@ -20,9 +21,9 @@ import ( type BuilderMode uint const ( - LogPackages BuilderMode = 1 << iota // Dump package inventory to stderr - LogFunctions // Dump function SSA code to stderr - LogSource // Show source locations as SSA builder progresses + PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout + PrintFunctions // Print function SSA code to stdout + LogSource // Log source locations as SSA builder progresses SanityCheckFunctions // Perform sanity checking of function bodies NaiveForm // Build naïve SSA form: don't replace local loads/stores with registers BuildSerially // Build packages serially, not in parallel. @@ -237,8 +238,10 @@ func (prog *Program) CreatePackage(info *loader.PackageInfo) *Package { p.SetDebugMode(true) } - if prog.mode&LogPackages != 0 { - p.WriteTo(os.Stderr) + if prog.mode&PrintPackages != 0 { + printMu.Lock() + p.WriteTo(os.Stdout) + printMu.Unlock() } if info.Importable { @@ -249,6 +252,9 @@ func (prog *Program) CreatePackage(info *loader.PackageInfo) *Package { return p } +// printMu serializes printing of Packages/Functions to stdout +var printMu sync.Mutex + // AllPackages returns a new slice containing all packages in the // program prog in unspecified order. // diff --git a/go/ssa/func.go b/go/ssa/func.go index 3c9b5559f1..52c49917a2 100644 --- a/go/ssa/func.go +++ b/go/ssa/func.go @@ -338,8 +338,10 @@ func (f *Function) finishBody() { numberRegisters(f) - if f.Prog.mode&LogFunctions != 0 { - f.WriteTo(os.Stderr) + if f.Prog.mode&PrintFunctions != 0 { + printMu.Lock() + f.WriteTo(os.Stdout) + printMu.Unlock() } if f.Prog.mode&SanityCheckFunctions != 0 { @@ -439,9 +441,7 @@ func (f *Function) lookup(obj types.Object, escaping bool) Value { return v } -// emit emits the specified instruction to function f, updating the -// control-flow graph if required. -// +// emit emits the specified instruction to function f. func (f *Function) emit(instr Instruction) Value { return f.currentBlock.emit(instr) } diff --git a/go/ssa/source_test.go b/go/ssa/source_test.go index 85631c2a73..0fa68d89d8 100644 --- a/go/ssa/source_test.go +++ b/go/ssa/source_test.go @@ -54,7 +54,7 @@ func TestObjValueLookup(t *testing.T) { return } - prog := ssa.Create(iprog, 0 /*|ssa.LogFunctions*/) + prog := ssa.Create(iprog, 0 /*|ssa.PrintFunctions*/) mainInfo := iprog.Created[0] mainPkg := prog.Package(mainInfo.Pkg) mainPkg.SetDebugMode(true) diff --git a/go/ssa/ssa.go b/go/ssa/ssa.go index 99417b316a..3131f84977 100644 --- a/go/ssa/ssa.go +++ b/go/ssa/ssa.go @@ -288,6 +288,7 @@ type Node interface { // of the ast.FuncDecl.Name, if the function was explicit in the // source. Synthetic wrappers, for which Synthetic != "", may share // the same position as the function they wrap. +// Syntax.Pos() always returns the position of the declaring "func" token. // // Type() returns the function's Signature. // @@ -1371,7 +1372,7 @@ func (c *CallCommon) Description() string { } // The CallInstruction interface, implemented by *Go, *Defer and *Call, -// exposes the common parts of function calling instructions, +// exposes the common parts of function-calling instructions, // yet provides a way back to the Value defined by *Call alone. // type CallInstruction interface { diff --git a/go/ssa/testmain.go b/go/ssa/testmain.go index 0d915a2b98..242207b003 100644 --- a/go/ssa/testmain.go +++ b/go/ssa/testmain.go @@ -149,8 +149,10 @@ func (prog *Program) CreateTestMainPackage(pkgs ...*Package) *Package { testmain.Members["main"] = main - if prog.mode&LogPackages != 0 { - testmain.WriteTo(os.Stderr) + if prog.mode&PrintPackages != 0 { + printMu.Lock() + testmain.WriteTo(os.Stdout) + printMu.Unlock() } if prog.mode&SanityCheckFunctions != 0 {