goism
goism copied to clipboard
Variadic ops optimization
x + y + z translated to:
eval x
eval y
concat 2
eval z
concat 2
But it is better to emit:
eval x
eval y
eval z
concat 3
It also makes it easier to constant fold string concatenation sequences.
Note that lisp.Concat(x, y, z) generates optimal code.
This implementation is bad, but can give starting approximation:
func weakenConcat(form *sexp.InstrCall) sexp.Form {
switch len(form.Args) {
case 0:
return sexp.Str("")
case 1:
return form.Args[0]
}
// This code should be re-written.
args := make([]sexp.Form, 0, len(form.Args))
for _, arg := range form.Args {
arg = ReduceStrength(arg)
if arg, ok := arg.(*sexp.InstrCall); ok {
if bytes.Equal([]byte("concat"), arg.Instr.Name) {
args = append(args, arg.Args...)
continue
}
}
args = append(args, arg)
}
form.Args = args
form.Instr = instr.Concat(len(args))
return form
}