1package transform
2
3import (
4	"tinygo.org/x/go-llvm"
5)
6
7// ReplacePanicsWithTrap replaces each call to panic (or similar functions) with
8// calls to llvm.trap, to reduce code size. This is the -panic=trap command-line
9// option.
10func ReplacePanicsWithTrap(mod llvm.Module) {
11	ctx := mod.Context()
12	builder := ctx.NewBuilder()
13	defer builder.Dispose()
14
15	trap := mod.NamedFunction("llvm.trap")
16	if trap.IsNil() {
17		trapType := llvm.FunctionType(ctx.VoidType(), nil, false)
18		trap = llvm.AddFunction(mod, "llvm.trap", trapType)
19	}
20	for _, name := range []string{"runtime._panic", "runtime.runtimePanic"} {
21		fn := mod.NamedFunction(name)
22		if fn.IsNil() {
23			continue
24		}
25		for _, use := range getUses(fn) {
26			if use.IsACallInst().IsNil() || use.CalledValue() != fn {
27				panic("expected use of a panic function to be a call")
28			}
29			builder.SetInsertPointBefore(use)
30			builder.CreateCall(trap, nil, "")
31		}
32	}
33}
34