mirror of
git://c9x.me/qbe.git
synced 2026-04-05 18:09:47 +00:00
- Many stylistic nits. - Removed blkmerge(). - Some minor bug fixes. - GCM reassoc is now "sink"; a pass that moves trivial ops in their target block with the same goal of reducing register pressure, but starting from instructions that benefit from having their inputs close.
202 lines
3.5 KiB
C
202 lines
3.5 KiB
C
#include "all.h"
|
|
#include "config.h"
|
|
#include <ctype.h>
|
|
#include <getopt.h>
|
|
|
|
Target T;
|
|
|
|
char debug['Z'+1] = {
|
|
['P'] = 0, /* parsing */
|
|
['M'] = 0, /* memory optimization */
|
|
['N'] = 0, /* ssa construction */
|
|
['C'] = 0, /* copy elimination */
|
|
['F'] = 0, /* constant folding */
|
|
['A'] = 0, /* abi lowering */
|
|
['I'] = 0, /* instruction selection */
|
|
['L'] = 0, /* liveness */
|
|
['S'] = 0, /* spilling */
|
|
['R'] = 0, /* reg. allocation */
|
|
};
|
|
|
|
extern Target T_amd64_sysv;
|
|
extern Target T_amd64_apple;
|
|
extern Target T_arm64;
|
|
extern Target T_arm64_apple;
|
|
extern Target T_rv64;
|
|
|
|
static Target *tlist[] = {
|
|
&T_amd64_sysv,
|
|
&T_amd64_apple,
|
|
&T_arm64,
|
|
&T_arm64_apple,
|
|
&T_rv64,
|
|
0
|
|
};
|
|
static FILE *outf;
|
|
static int dbg;
|
|
|
|
static void
|
|
data(Dat *d)
|
|
{
|
|
if (dbg)
|
|
return;
|
|
emitdat(d, outf);
|
|
if (d->type == DEnd) {
|
|
fputs("/* end data */\n\n", outf);
|
|
freeall();
|
|
}
|
|
}
|
|
|
|
static void
|
|
func(Fn *fn)
|
|
{
|
|
uint n;
|
|
|
|
if (dbg)
|
|
fprintf(stderr, "**** Function %s ****", fn->name);
|
|
if (debug['P']) {
|
|
fprintf(stderr, "\n> After parsing:\n");
|
|
printfn(fn, stderr);
|
|
}
|
|
T.abi0(fn);
|
|
fillcfg(fn);
|
|
filluse(fn);
|
|
promote(fn);
|
|
filluse(fn);
|
|
ssa(fn);
|
|
filluse(fn);
|
|
ssacheck(fn);
|
|
fillalias(fn);
|
|
loadopt(fn);
|
|
filluse(fn);
|
|
fillalias(fn);
|
|
coalesce(fn);
|
|
filluse(fn);
|
|
filldom(fn);
|
|
ssacheck(fn);
|
|
gvn(fn);
|
|
fillcfg(fn);
|
|
filluse(fn);
|
|
filldom(fn);
|
|
gcm(fn);
|
|
filluse(fn);
|
|
ssacheck(fn);
|
|
T.abi1(fn);
|
|
simpl(fn);
|
|
fillcfg(fn);
|
|
filluse(fn);
|
|
T.isel(fn);
|
|
fillcfg(fn);
|
|
filllive(fn);
|
|
fillloop(fn);
|
|
fillcost(fn);
|
|
spill(fn);
|
|
rega(fn);
|
|
fillcfg(fn);
|
|
simpljmp(fn);
|
|
fillcfg(fn);
|
|
assert(fn->rpo[0] == fn->start);
|
|
for (n=0;; n++)
|
|
if (n == fn->nblk-1) {
|
|
fn->rpo[n]->link = 0;
|
|
break;
|
|
} else
|
|
fn->rpo[n]->link = fn->rpo[n+1];
|
|
if (!dbg) {
|
|
T.emitfn(fn, outf);
|
|
fprintf(outf, "/* end function %s */\n\n", fn->name);
|
|
} else
|
|
fprintf(stderr, "\n");
|
|
freeall();
|
|
}
|
|
|
|
static void
|
|
dbgfile(char *fn)
|
|
{
|
|
emitdbgfile(fn, outf);
|
|
}
|
|
|
|
int
|
|
main(int ac, char *av[])
|
|
{
|
|
Target **t;
|
|
FILE *inf, *hf;
|
|
char *f, *sep;
|
|
int c;
|
|
|
|
T = Deftgt;
|
|
outf = stdout;
|
|
while ((c = getopt(ac, av, "hd:o:t:")) != -1)
|
|
switch (c) {
|
|
case 'd':
|
|
for (; *optarg; optarg++)
|
|
if (isalpha(*optarg)) {
|
|
debug[toupper(*optarg)] = 1;
|
|
dbg = 1;
|
|
}
|
|
break;
|
|
case 'o':
|
|
if (strcmp(optarg, "-") != 0) {
|
|
outf = fopen(optarg, "w");
|
|
if (!outf) {
|
|
fprintf(stderr, "cannot open '%s'\n", optarg);
|
|
exit(1);
|
|
}
|
|
}
|
|
break;
|
|
case 't':
|
|
if (strcmp(optarg, "?") == 0) {
|
|
puts(T.name);
|
|
exit(0);
|
|
}
|
|
for (t=tlist;; t++) {
|
|
if (!*t) {
|
|
fprintf(stderr, "unknown target '%s'\n", optarg);
|
|
exit(1);
|
|
}
|
|
if (strcmp(optarg, (*t)->name) == 0) {
|
|
T = **t;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case 'h':
|
|
default:
|
|
hf = c != 'h' ? stderr : stdout;
|
|
fprintf(hf, "%s [OPTIONS] {file.ssa, -}\n", av[0]);
|
|
fprintf(hf, "\t%-11s prints this help\n", "-h");
|
|
fprintf(hf, "\t%-11s output to file\n", "-o file");
|
|
fprintf(hf, "\t%-11s generate for a target among:\n", "-t <target>");
|
|
fprintf(hf, "\t%-11s ", "");
|
|
for (t=tlist, sep=""; *t; t++, sep=", ") {
|
|
fprintf(hf, "%s%s", sep, (*t)->name);
|
|
if (*t == &Deftgt)
|
|
fputs(" (default)", hf);
|
|
}
|
|
fprintf(hf, "\n");
|
|
fprintf(hf, "\t%-11s dump debug information\n", "-d <flags>");
|
|
exit(c != 'h');
|
|
}
|
|
|
|
do {
|
|
f = av[optind];
|
|
if (!f || strcmp(f, "-") == 0) {
|
|
inf = stdin;
|
|
f = "-";
|
|
} else {
|
|
inf = fopen(f, "r");
|
|
if (!inf) {
|
|
fprintf(stderr, "cannot open '%s'\n", f);
|
|
exit(1);
|
|
}
|
|
}
|
|
parse(inf, f, dbgfile, data, func);
|
|
fclose(inf);
|
|
} while (++optind < ac);
|
|
|
|
if (!dbg)
|
|
T.emitfin(outf);
|
|
|
|
exit(0);
|
|
}
|