compiler: make panic configurable
Currently defined: abort and trap. -panic=unwind should be implemented in the future.
Этот коммит содержится в:
родитель
d1efffe96b
коммит
0fd90c49cc
3 изменённых файлов: 74 добавлений и 40 удалений
|
@ -34,6 +34,7 @@ type Config struct {
|
|||
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
|
||||
|
|
|
@ -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()
|
||||
|
@ -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
|
||||
|
|
10
main.go
10
main.go
|
@ -36,6 +36,7 @@ func (e *commandError) Error() string {
|
|||
type BuildConfig struct {
|
||||
opt string
|
||||
gc string
|
||||
panicStrategy string
|
||||
printIR bool
|
||||
dumpSSA bool
|
||||
debug bool
|
||||
|
@ -61,6 +62,7 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
|
|||
GOOS: spec.GOOS,
|
||||
GOARCH: spec.GOARCH,
|
||||
GC: config.gc,
|
||||
PanicStrategy: config.panicStrategy,
|
||||
CFlags: spec.CFlags,
|
||||
LDFlags: spec.LDFlags,
|
||||
Debug: config.debug,
|
||||
|
@ -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")
|
||||
|
@ -529,6 +532,7 @@ func main() {
|
|||
config := &BuildConfig{
|
||||
opt: *opt,
|
||||
gc: *gc,
|
||||
panicStrategy: *panicStrategy,
|
||||
printIR: *printIR,
|
||||
dumpSSA: *dumpSSA,
|
||||
debug: !*nodebug,
|
||||
|
@ -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 {
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче