~mpu/qbe

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
2 2

[PATCH v5] implement line number info tracking

Details
Message ID
<20230126110943.14927-1-t@laumann.xyz>
DKIM signature
missing
Download raw message
Patch: +81 -7
Support "line" and "loc" directives. "line" takes a string (a file name)
assigns it a number, sets the current file to that number and records
the string for later. "loc" takes a single number and outputs location
information with a reference to the current file.
---

v4 -> v5:

 * Rename emitfile()/emitloc() to dbgfile()/dbgloc()

 * This version keeps track of seen file names. Calling dbgfile() sets a global
   current file and optionally emits a .file n <filename> directive once per
   file name.

 * Removes the "file number" from Fn and calls to dbgfile() and dbgloc(). Calls
   to dbgloc() just use the current file number

The result is that something like:

    file "x.ha"
    file "y.ha"
    loc 1
    loc 2
    file "x.ha"
    loc 3

produces:

    .file 1 "x.ha"
    .file 2 "y.ha"
    .loc 2 1
    .loc 2 2
    .loc 1 3

So for qbe, you need to emit "file" to set the current file for subsequent
occurrences of "loc", but the .file directive is only emitted once per file.

I'd appreciate feedback on the string vector setup (dbgfiles), I'm not sure it's
the right way to go about it.
    
 all.h        |  8 +++++++-
 amd64/emit.c |  3 +++
 amd64/isel.c |  3 +++
 arm64/emit.c |  3 +++
 arm64/isel.c |  4 ++++
 emit.c       | 37 +++++++++++++++++++++++++++++++++++++
 main.c       |  4 +++-
 ops.h        |  2 ++
 parse.c      | 11 +++++++++--
 rv64/emit.c  |  3 +++
 rv64/isel.c  |  4 ++++
 tools/lexh.c |  6 +++---
 12 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/all.h b/all.h
index 7eba443..3c5b460 100644
--- a/all.h
+++ b/all.h
@@ -501,7 +501,7 @@ bshas(BSet *bs, uint elt)

/* parse.c */
extern Op optab[NOp];
void parse(FILE *, char *, void (Dat *), void (Fn *));
void parse(FILE *, char *, FILE *, void (Dat *), void (Fn *));
void printfn(Fn *, FILE *);
void printref(Ref, Fn *, FILE *);
void err(char *, ...) __attribute__((noreturn));
@@ -571,3 +571,9 @@ int stashbits(void *, int);
void elf_emitfnfin(char *, FILE *);
void elf_emitfin(FILE *);
void macho_emitfin(FILE *);

extern uint curfile;
extern char **dbgfiles;
void dbgfile(char *, FILE *);
void dbgloc(long int, FILE *);
void freedbgfiles();
diff --git a/amd64/emit.c b/amd64/emit.c
index 9b8bb5d..15f7c1e 100644
--- a/amd64/emit.c
+++ b/amd64/emit.c
@@ -525,6 +525,9 @@ emitins(Ins i, Fn *fn, FILE *f)
		emitcopy(i.arg[0], i.arg[1], i.cls, fn, f);
		emitcopy(i.arg[1], TMP(XMM0+15), i.cls, fn, f);
		break;
	case Oloc:
		dbgloc(fn->con[i.arg[0].val].bits.i, f);
		break;
	}
}

diff --git a/amd64/isel.c b/amd64/isel.c
index 3e3fe62..caf10d2 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -371,6 +371,9 @@ sel(Ins i, ANum *an, Fn *fn)
	case_Oload:
		seladdr(&i.arg[0], an, fn);
		goto Emit;
	case Oloc:
		emiti(i);
		break;
	case Ocall:
	case Osalloc:
	case Ocopy:
diff --git a/arm64/emit.c b/arm64/emit.c
index 5113c66..1b9e417 100644
--- a/arm64/emit.c
+++ b/arm64/emit.c
@@ -446,6 +446,9 @@ emitins(Ins *i, E *e)
		if (!req(i->to, R))
			emitf("mov %=, sp", i, e);
		break;
	case Oloc:
		dbgloc(e->fn->con[i->arg[0].val].bits.i, e->f);
		break;
	}
}

diff --git a/arm64/isel.c b/arm64/isel.c
index 062beb3..a2c53aa 100644
--- a/arm64/isel.c
+++ b/arm64/isel.c
@@ -224,6 +224,10 @@ sel(Ins i, Fn *fn)
		emiti(i);
		return;
	}
	if (i.op == Oloc) {
		emiti(i);
		return;
	}
	if (i.op != Onop) {
		emiti(i);
		iarg = curi->arg; /* fixarg() can change curi */
diff --git a/emit.c b/emit.c
index 017c461..45b80cb 100644
--- a/emit.c
+++ b/emit.c
@@ -207,3 +207,40 @@ macho_emitfin(FILE *f)

	emitfin(f, sec);
}

uint curfile = 0;
static uint nfiles = 0;
char **dbgfiles = NULL;

// Emit a ".file" line and set the current file for subsequent calls to dbgloc()
void
dbgfile(char *fname, FILE *f)
{
	uint i;

	for (i = 0; i < nfiles; i++)
		if (!strcmp(fname, dbgfiles[i]))
			break;

	curfile = i + 1;
	if (i == nfiles) {
		vgrow(&dbgfiles, ++nfiles);
		dbgfiles[i] = emalloc(strlen(fname)+1);
		strcpy(dbgfiles[i], fname);
		fprintf(f, ".file %u %s\n", curfile, fname);
	}
}

void
dbgloc(long int line, FILE *f)
{
	fprintf(f, "\t.loc %u %ld\n", curfile, line);
}

void
freedbgfiles()
{
	for (uint i = 0; i < nfiles; i++)
		free(dbgfiles[i]);
	vfree(dbgfiles);
}
diff --git a/main.c b/main.c
index abfe03e..8e11b90 100644
--- a/main.c
+++ b/main.c
@@ -169,6 +169,7 @@ main(int ac, char *av[])
			exit(c != 'h');
		}

	dbgfiles = vnew(0, sizeof(char *), PHeap);
	do {
		f = av[optind];
		if (!f || strcmp(f, "-") == 0) {
@@ -181,9 +182,10 @@ main(int ac, char *av[])
				exit(1);
			}
		}
		parse(inf, f, data, func);
		parse(inf, f, outf, data, func);
		fclose(inf);
	} while (++optind < ac);
	freedbgfiles();

	if (!dbg)
		T.emitfin(outf);
diff --git a/ops.h b/ops.h
index fbcc2a8..6a7fb3b 100644
--- a/ops.h
+++ b/ops.h
@@ -121,6 +121,8 @@ O(vastart, T(m,e,e,e, x,e,e,e), 0) X(0, 0, 0) V(0)

O(copy,    T(w,l,s,d, x,x,x,x), 0) X(0, 0, 1) V(0)

/* Debug info */
O(loc,     T(w,l,s,d, x,x,x,x), 0) X(0, 0, 1) V(0)

/****************************************/
/* INTERNAL OPERATIONS (keep nop first) */
diff --git a/parse.c b/parse.c
index aed9427..0afeac0 100644
--- a/parse.c
+++ b/parse.c
@@ -53,6 +53,7 @@ enum Token {
	Tdata,
	Tsection,
	Talign,
	Tfile,
	Tl,
	Tw,
	Tsh,
@@ -110,6 +111,7 @@ static char *kwmap[Ntok] = {
	[Tdata] = "data",
	[Tsection] = "section",
	[Talign] = "align",
	[Tfile] = "file",
	[Tsb] = "sb",
	[Tub] = "ub",
	[Tsh] = "sh",
@@ -130,7 +132,7 @@ enum {
	TMask = 16383, /* for temps hash */
	BMask = 8191, /* for blocks hash */

	K = 9583425, /* found using tools/lexh.c */
	K = 10525445, /* found using tools/lexh.c */
	M = 23,
};

@@ -592,6 +594,7 @@ parseline(PState ps)
		case Tblit:
		case Tcall:
		case Ovastart:
		case Oloc:
			/* operations without result */
			r = R;
			k = Kw;
@@ -1160,7 +1163,7 @@ parselnk(Lnk *lnk)
}

void
parse(FILE *f, char *path, void data(Dat *), void func(Fn *))
parse(FILE *f, char *path, FILE *outf, void data(Dat *), void func(Fn *))
{
	Lnk lnk;
	uint n;
@@ -1177,6 +1180,10 @@ parse(FILE *f, char *path, void data(Dat *), void func(Fn *))
		switch (parselnk(&lnk)) {
		default:
			err("top-level definition expected");
		case Tfile:
			expect(Tstr);
			dbgfile(tokval.str, outf);
			break;
		case Tfunc:
			func(parsefn(&lnk));
			break;
diff --git a/rv64/emit.c b/rv64/emit.c
index f9df146..2643b66 100644
--- a/rv64/emit.c
+++ b/rv64/emit.c
@@ -405,6 +405,9 @@ emitins(Ins *i, Fn *fn, FILE *f)
		if (!req(i->to, R))
			emitf("mv %=, sp", i, fn, f);
		break;
	case Oloc:
		dbgloc(fn->con[i->arg[0].val].bits.i, f);
		break;
	}
}

diff --git a/rv64/isel.c b/rv64/isel.c
index 8921a07..d9bbefe 100644
--- a/rv64/isel.c
+++ b/rv64/isel.c
@@ -187,6 +187,10 @@ sel(Ins i, Fn *fn)
		selcmp(i, ck, cc, fn);
		return;
	}
	if (i.op == Oloc) {
		emiti(i);
		return;
	}
	if (i.op != Onop) {
		emiti(i);
		i0 = curi; /* fixarg() can change curi */
diff --git a/tools/lexh.c b/tools/lexh.c
index 5ceb4ee..8883976 100644
--- a/tools/lexh.c
+++ b/tools/lexh.c
@@ -23,11 +23,11 @@ char *tok[] = {
	"ceql", "cnel", "cles", "clts", "cgts", "cges",
	"cnes", "ceqs", "cos", "cuos", "cled", "cltd",
	"cgtd", "cged", "cned", "ceqd", "cod", "cuod",
	"vaarg", "vastart", "...", "env",
	"vaarg", "vastart", "...", "env", "loc",

	"call", "phi", "jmp", "jnz", "ret", "hlt", "export",
	"function", "type", "data", "section", "align", "blit",
	"l", "w", "sh", "uh", "h", "sb", "ub", "b",
	"function", "type", "data", "section", "align", "file",
	"blit", "l", "w", "sh", "uh", "h", "sb", "ub", "b",
	"d", "s", "z", "loadw", "loadl", "loads", "loadd",
	"alloc1", "alloc2",

-- 
2.38.2
Details
Message ID
<CT2JKZ43ZU7K.240Y1G3QROCR5@sylphrena.radiant.pixelhero.dev>
In-Reply-To
<20230126110943.14927-1-t@laumann.xyz> (view parent)
DKIM signature
missing
Download raw message
Ping!

What's the status of this patch? Any changes needed?
Details
Message ID
<94fdb287-7d72-4af9-8358-e06590024c82@app.fastmail.com>
In-Reply-To
<CT2JKZ43ZU7K.240Y1G3QROCR5@sylphrena.radiant.pixelhero.dev> (view parent)
DKIM signature
missing
Download raw message
On Sat, Jun 3, 2023, at 01:11, Noam Preil wrote:
> What's the status of this patch? Any changes needed?

Phew, it gathered quite a bit of dust... I pushed a
modified version on the dev branch. I consider this
new syntax experimental, so it remains undocumented.
In particular, I don't think I'm very keen on the
"file" and "loc" keywords, so expect change.

A couple things I tweaked before pushing it:
 - do not export the globals in emit.c and instead
   lazy-initialize them; do not free them since they
   live for the whole qbe run
 - use the intern() function instead of duplicating
   strings in emit.c; this also makes the linear
   search for previous files cheaper (int equality
   instead of string equality)
 - make the style more uniform with the rest of qbe
   (x/nx for an array x with its size; tweak spacing
    in for() loops)
 - make the parsing of Oloc stricter and use an INT()
   ref instead of using a constant
 - remove unnecessary (I think) additions in */isel.c
Reply to thread Export thread (mbox)