1
0
mirror of https://github.com/golang/go synced 2024-11-18 13:24:39 -07:00

go/ssa: standardize parsing of BuilderMode flags.

ssadump's -build=G option is now spelled -import; it was never related to ssa.

Change-Id: Ic21cd8b6990c0ffd25651c17a842a63bfa5019cf
Reviewed-on: https://go-review.googlesource.com/5172
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Alan Donovan 2015-02-18 12:53:21 -05:00
parent 10d7cacb91
commit 9bdc591373
3 changed files with 120 additions and 58 deletions

View File

@ -19,28 +19,23 @@ import (
"golang.org/x/tools/go/types"
)
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 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.
N build [N]aive SSA form: don't replace local loads/stores with registers.
I build bare [I]nit functions: no init guards or calls to dependent inits.
`)
var (
importbinFlag = flag.Bool("importbin", false,
"Import binary export data from gc's object files, not source. "+
"Imported functions will have no bodies.")
var testFlag = flag.Bool("test", false, "Loads test code (*_test.go) for imported packages.")
modeFlag = ssa.BuilderModeFlag(flag.CommandLine, "build", 0)
var runFlag = flag.Bool("run", false, "Invokes the SSA interpreter on the program.")
testFlag = flag.Bool("test", false, "Loads test code (*_test.go) for imported packages.")
var interpFlag = flag.String("interp", "", `Options controlling the SSA test interpreter.
runFlag = flag.Bool("run", false, "Invokes the SSA interpreter on the program.")
interpFlag = flag.String("interp", "", `Options controlling the SSA test interpreter.
The value is a sequence of zero or more more of these letters:
R disable [R]ecover() from panic; show interpreter crash instead.
T [T]race execution of the program. Best for single-threaded programs!
`)
)
const usage = `SSA builder and interpreter.
Usage: ssadump [<flag> ...] <args> ...
@ -85,7 +80,7 @@ func doMain() error {
conf := loader.Config{
Build: &build.Default,
SourceImports: true,
SourceImports: !*importbinFlag,
}
// TODO(adonovan): make go/types choose its default Sizes from
// build.Default or a specified *build.Context.
@ -99,32 +94,6 @@ func doMain() error {
WordSize: wordSize,
}
var mode ssa.BuilderMode
for _, c := range *buildFlag {
switch c {
case 'D':
mode |= ssa.GlobalDebug
case 'P':
mode |= ssa.PrintPackages
case 'F':
mode |= ssa.PrintFunctions
case 'S':
mode |= ssa.LogSource | ssa.BuildSerially
case 'C':
mode |= ssa.SanityCheckFunctions
case 'N':
mode |= ssa.NaiveForm
case 'G':
conf.SourceImports = false
case 'L':
mode |= ssa.BuildSerially
case 'I':
mode |= ssa.BareInits
default:
return fmt.Errorf("unknown -build option: '%c'", c)
}
}
var interpMode interp.Mode
for _, c := range *interpFlag {
switch c {
@ -171,7 +140,7 @@ func doMain() error {
}
// Create and build SSA-form program representation.
prog := ssa.Create(iprog, mode)
prog := ssa.Create(iprog, *modeFlag)
prog.BuildAll()
// Run the interpreter.

View File

@ -18,20 +18,6 @@ import (
"golang.org/x/tools/go/types/typeutil"
)
// BuilderMode is a bitmask of options for diagnostics and checking.
type BuilderMode uint
const (
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.
GlobalDebug // Enable debug info for all packages
BareInits // Build init functions without guards or calls to dependent inits
)
// Create returns a new SSA Program. An SSA Package is created for
// each transitively error-free package of iprog.
//
@ -257,7 +243,7 @@ func (prog *Program) CreatePackage(info *loader.PackageInfo) *Package {
return p
}
// printMu serializes printing of Packages/Functions to stdout
// printMu serializes printing of Packages/Functions to stdout.
var printMu sync.Mutex
// AllPackages returns a new slice containing all packages in the

107
go/ssa/mode.go Normal file
View File

@ -0,0 +1,107 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ssa
// This file defines the BuilderMode type and its command-line flag.
import (
"bytes"
"flag"
"fmt"
)
// BuilderMode is a bitmask of options for diagnostics and checking.
type BuilderMode uint
const (
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.
GlobalDebug // Enable debug info for all packages
BareInits // Build init functions without guards or calls to dependent inits
)
const modeFlagUsage = `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 print [P]ackage inventory.
F print [F]unction SSA code.
S log [S]ource locations as SSA builder progresses.
L build distinct packages seria[L]ly instead of in parallel.
N build [N]aive SSA form: don't replace local loads/stores with registers.
I build bare [I]nit functions: no init guards or calls to dependent inits.
`
// BuilderModeFlag creates a new command line flag of type BuilderMode,
// adds it to the specified flag set, and returns it.
//
// Example:
// var ssabuild = BuilderModeFlag(flag.CommandLine, "ssabuild", 0)
//
func BuilderModeFlag(set *flag.FlagSet, name string, value BuilderMode) *BuilderMode {
set.Var((*builderModeValue)(&value), name, modeFlagUsage)
return &value
}
type builderModeValue BuilderMode // satisfies flag.Value and flag.Getter.
func (v *builderModeValue) Set(s string) error {
var mode BuilderMode
for _, c := range s {
switch c {
case 'D':
mode |= GlobalDebug
case 'P':
mode |= PrintPackages
case 'F':
mode |= PrintFunctions
case 'S':
mode |= LogSource | BuildSerially
case 'C':
mode |= SanityCheckFunctions
case 'N':
mode |= NaiveForm
case 'L':
mode |= BuildSerially
default:
return fmt.Errorf("unknown BuilderMode option: %q", c)
}
}
*v = builderModeValue(mode)
return nil
}
func (v *builderModeValue) Get() interface{} { return BuilderMode(*v) }
func (v *builderModeValue) String() string {
mode := BuilderMode(*v)
var buf bytes.Buffer
if mode&GlobalDebug != 0 {
buf.WriteByte('D')
}
if mode&PrintPackages != 0 {
buf.WriteByte('P')
}
if mode&PrintFunctions != 0 {
buf.WriteByte('F')
}
if mode&LogSource != 0 {
buf.WriteByte('S')
}
if mode&SanityCheckFunctions != 0 {
buf.WriteByte('C')
}
if mode&NaiveForm != 0 {
buf.WriteByte('N')
}
if mode&BuildSerially != 0 {
buf.WriteByte('L')
}
return buf.String()
}