qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

commit a9a70e30a8205a8f835c59fd8297e4a4483cc8d4
parent 0b26cd4f5ecff8a01fb3f0adb902c14e043581e9
Author: Quentin Carbonneaux <quentin@c9x.me>
Date:   Wed, 31 Aug 2022 17:09:04 +0200

add new target-specific abi0 pass

The general idea is to give abis a
chance to talk before we've done all
the optimizations. Currently, all
targets eliminate {par,arg,ret}{sb,ub,...}
during this pass. The forthcoming
arm64_apple will, however, insert
proper extensions during abi0.

Moving forward abis can, for example,
lower small-aggregates passing there
so that memory optimizations can
interact better with function calls.

Diffstat:
MMakefile | 4++--
Aabi.c | 25+++++++++++++++++++++++++
Mall.h | 9++++++++-
Mamd64/targ.c | 3++-
Marm64/targ.c | 3++-
Mmain.c | 3++-
Mrv64/targ.c | 3++-
7 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,8 +4,8 @@ PREFIX = /usr/local BINDIR = $(PREFIX)/bin -COMMOBJ = main.o util.o parse.o cfg.o mem.o ssa.o alias.o load.o copy.o \ - fold.o live.o spill.o rega.o emit.o +COMMOBJ = main.o util.o parse.o abi.o cfg.o mem.o ssa.o alias.o load.o \ + copy.o fold.o live.o spill.o rega.o emit.o AMD64OBJ = amd64/targ.o amd64/sysv.o amd64/isel.o amd64/emit.o ARM64OBJ = arm64/targ.o arm64/abi.o arm64/isel.o arm64/emit.o RV64OBJ = rv64/targ.o rv64/abi.o rv64/isel.o rv64/emit.o diff --git a/abi.c b/abi.c @@ -0,0 +1,25 @@ +#include "all.h" + +/* eliminate sub-word abi op + * variants for targets that + * treat char/short/... as + * words with arbitrary high + * bits + */ +void +elimsb(Fn *fn) +{ + Blk *b; + Ins *i; + + for (b=fn->start; b; b=b->link) { + for (i=b->ins; i<&b->ins[b->nins]; i++) { + if (isargbh(i->op)) + i->op = Oarg; + if (isparbh(i->op)) + i->op = Opar; + } + if (isretbh(b->jmp.type)) + b->jmp.type = Jretw; + } +} diff --git a/all.h b/all.h @@ -52,7 +52,8 @@ struct Target { bits (*retregs)(Ref, int[2]); bits (*argregs)(Ref, int[2]); int (*memargs)(int); - void (*abi)(Fn *); + void (*abi0)(Fn *); + void (*abi1)(Fn *); void (*isel)(Fn *); void (*emitfn)(Fn *, FILE *); void (*emitfin)(FILE *); @@ -183,6 +184,9 @@ enum { #define ispar(o) INRANGE(o, Opar, Opare) #define isarg(o) INRANGE(o, Oarg, Oargv) #define isret(j) INRANGE(j, Jretw, Jret0) +#define isparbh(o) INRANGE(o, Oparsb, Oparuh) +#define isargbh(o) INRANGE(o, Oargsb, Oarguh) +#define isretbh(j) INRANGE(j, Jretsb, Jretuh) enum { Kx = -1, /* "top" class (see usecheck() and clsmerge()) */ @@ -478,6 +482,9 @@ void printfn(Fn *, FILE *); void printref(Ref, Fn *, FILE *); void err(char *, ...) __attribute__((noreturn)); +/* abi.c */ +void elimsb(Fn *); + /* cfg.c */ Blk *blknew(void); void edgedel(Blk *, Blk **); diff --git a/amd64/targ.c b/amd64/targ.c @@ -24,7 +24,8 @@ amd64_memargs(int op) .retregs = amd64_sysv_retregs, \ .argregs = amd64_sysv_argregs, \ .memargs = amd64_memargs, \ - .abi = amd64_sysv_abi, \ + .abi0 = elimsb, \ + .abi1 = amd64_sysv_abi, \ .isel = amd64_isel, \ Target T_amd64_sysv = { diff --git a/arm64/targ.c b/arm64/targ.c @@ -38,7 +38,8 @@ Target T_arm64 = { .retregs = arm64_retregs, .argregs = arm64_argregs, .memargs = arm64_memargs, - .abi = arm64_abi, + .abi0 = elimsb, + .abi1 = arm64_abi, .isel = arm64_isel, .emitfn = arm64_emitfn, .emitfin = elf_emitfin, diff --git a/main.c b/main.c @@ -56,6 +56,7 @@ func(Fn *fn) fprintf(stderr, "\n> After parsing:\n"); printfn(fn, stderr); } + T.abi0(fn); fillrpo(fn); fillpreds(fn); filluse(fn); @@ -71,7 +72,7 @@ func(Fn *fn) copy(fn); filluse(fn); fold(fn); - T.abi(fn); + T.abi1(fn); fillpreds(fn); filluse(fn); T.isel(fn); diff --git a/rv64/targ.c b/rv64/targ.c @@ -44,7 +44,8 @@ Target T_rv64 = { .retregs = rv64_retregs, .argregs = rv64_argregs, .memargs = rv64_memargs, - .abi = rv64_abi, + .abi0 = elimsb, + .abi1 = rv64_abi, .isel = rv64_isel, .emitfn = rv64_emitfn, .emitfin = elf_emitfin,