Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,19 @@ func init() {

// Configure the compiler.
type Config struct {
Triple string // LLVM target triple, e.g. x86_64-unknown-linux-gnu (empty string means default)
CPU string // LLVM CPU name, e.g. atmega328p (empty string means default)
GOOS string //
GOARCH string //
GC string // garbage collection strategy
CFlags []string // cflags to pass to cgo
LDFlags []string // ldflags to pass to cgo
DumpSSA bool // dump Go SSA, for compiler debugging
Debug bool // add debug symbols for gdb
RootDir string // GOROOT for TinyGo
GOPATH string // GOPATH, like `go env GOPATH`
BuildTags []string // build tags for TinyGo (empty means {Config.GOOS/Config.GOARCH})
Triple string // LLVM target triple, e.g. x86_64-unknown-linux-gnu (empty string means default)
CPU string // LLVM CPU name, e.g. atmega328p (empty string means default)
GOOS string //
GOARCH string //
GC string // garbage collection strategy
PanicStrategy string // panic strategy ("abort" or "trap")
CFlags []string // cflags to pass to cgo
LDFlags []string // ldflags to pass to cgo
DumpSSA bool // dump Go SSA, for compiler debugging
Debug bool // add debug symbols for gdb
RootDir string // GOROOT for TinyGo
GOPATH string // GOPATH, like `go env GOPATH`
BuildTags []string // build tags for TinyGo (empty means {Config.GOOS/Config.GOARCH})
}

type Compiler struct {
Expand Down
23 changes: 23 additions & 0 deletions compiler/optimizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ func (c *Compiler) Optimize(optLevel, sizeLevel int, inlinerThreshold uint) erro
}
builder.AddCoroutinePassesToExtensionPoints()

if c.PanicStrategy == "trap" {
c.replacePanicsWithTrap() // -panic=trap
}

// Run function passes for each function.
funcPasses := llvm.NewFunctionPassManagerForModule(c.mod)
defer funcPasses.Dispose()
Expand Down Expand Up @@ -113,6 +117,25 @@ func (c *Compiler) Optimize(optLevel, sizeLevel int, inlinerThreshold uint) erro
return nil
}

// Replace panic calls with calls to llvm.trap, to reduce code size. This is the
// -panic=trap intrinsic.
func (c *Compiler) replacePanicsWithTrap() {
trap := c.mod.NamedFunction("llvm.trap")
for _, name := range []string{"runtime._panic", "runtime.runtimePanic"} {
fn := c.mod.NamedFunction(name)
if fn.IsNil() {
continue
}
for _, use := range getUses(fn) {
if use.IsACallInst().IsNil() || use.CalledValue() != fn {
panic("expected use of a panic function to be a call")
}
c.builder.SetInsertPointBefore(use)
c.builder.CreateCall(trap, nil, "")
}
}
}

// Eliminate created but not used maps.
//
// In the future, this should statically allocate created but never modified
Expand Down
66 changes: 38 additions & 28 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ func (e *commandError) Error() string {
}

type BuildConfig struct {
opt string
gc string
printIR bool
dumpSSA bool
debug bool
printSizes string
cFlags []string
ldFlags []string
wasmAbi string
opt string
gc string
panicStrategy string
printIR bool
dumpSSA bool
debug bool
printSizes string
cFlags []string
ldFlags []string
wasmAbi string
}

// Helper function for Compiler object.
Expand All @@ -56,18 +57,19 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
spec.LDFlags = append(spec.LDFlags, config.ldFlags...)

compilerConfig := compiler.Config{
Triple: spec.Triple,
CPU: spec.CPU,
GOOS: spec.GOOS,
GOARCH: spec.GOARCH,
GC: config.gc,
CFlags: spec.CFlags,
LDFlags: spec.LDFlags,
Debug: config.debug,
DumpSSA: config.dumpSSA,
RootDir: sourceDir(),
GOPATH: getGopath(),
BuildTags: spec.BuildTags,
Triple: spec.Triple,
CPU: spec.CPU,
GOOS: spec.GOOS,
GOARCH: spec.GOARCH,
GC: config.gc,
PanicStrategy: config.panicStrategy,
CFlags: spec.CFlags,
LDFlags: spec.LDFlags,
Debug: config.debug,
DumpSSA: config.dumpSSA,
RootDir: sourceDir(),
GOPATH: getGopath(),
BuildTags: spec.BuildTags,
}
c, err := compiler.NewCompiler(pkgName, compilerConfig)
if err != nil {
Expand Down Expand Up @@ -507,6 +509,7 @@ func main() {
outpath := flag.String("o", "", "output filename")
opt := flag.String("opt", "z", "optimization level: 0, 1, 2, s, z")
gc := flag.String("gc", "", "garbage collector to use (none, dumb, marksweep)")
panicStrategy := flag.String("panic", "print", "panic strategy (abort, trap)")
printIR := flag.Bool("printir", false, "print LLVM IR")
dumpSSA := flag.Bool("dumpssa", false, "dump internal Go SSA")
target := flag.String("target", "", "LLVM target")
Expand All @@ -527,13 +530,14 @@ func main() {

flag.CommandLine.Parse(os.Args[2:])
config := &BuildConfig{
opt: *opt,
gc: *gc,
printIR: *printIR,
dumpSSA: *dumpSSA,
debug: !*nodebug,
printSizes: *printSize,
wasmAbi: *wasmAbi,
opt: *opt,
gc: *gc,
panicStrategy: *panicStrategy,
printIR: *printIR,
dumpSSA: *dumpSSA,
debug: !*nodebug,
printSizes: *printSize,
wasmAbi: *wasmAbi,
}

if *cFlags != "" {
Expand All @@ -544,6 +548,12 @@ func main() {
config.ldFlags = strings.Split(*ldFlags, " ")
}

if *panicStrategy != "print" && *panicStrategy != "trap" {
fmt.Fprintln(os.Stderr, "Panic strategy must be either print or trap.")
usage()
os.Exit(1)
}

os.Setenv("CC", "clang -target="+*target)

switch command {
Expand Down