I may be missing an obvious workaround, but it seems we currently emit a #line directive when including lines from machine description files in C files, but never emit a second directive when switching back to the generated C file. This makes stepping through the backend in gdb somewhat painful, because gdb thinks it should display lines from the md file even after leaving the included fragment.
The attached patch is a proof of concept which unconditionally emits a line containing "/* #unline */" after such fragments, and runs all generated C files through a trivial filter which replaces those lines by #line directives pointing back to the original file. It appears to work.
From c1c85da2b5d029b730f98906abda6c73bb7352d3 Mon Sep 17 00:00:00 2001 From: Pip Cet <pip...@gmail.com> Date: Thu, 27 Aug 2020 22:02:40 +0000 Subject: [PATCH] Add paired #line directives pointing back to the generated C file. --- gcc/Makefile.in | 15 ++++++++------- gcc/genemit.c | 1 + gcc/genline.c | 36 ++++++++++++++++++++++++++++++++++++ gcc/read-md.c | 19 +++++++++++++++++++ gcc/read-md.h | 2 ++ 5 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 gcc/genline.c diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 79e854aa938..fb03031d038 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2354,16 +2354,16 @@ $(simple_rtl_generated_c:insn-%.c=s-%): s-%: insn-conditions.md $(simple_generated_h): insn-%.h: s-%; @true -$(simple_generated_h:insn-%.h=s-%): s-%: build/gen%$(build_exeext) +$(simple_generated_h:insn-%.h=s-%): s-%: build/gen%$(build_exeext) build/genline$(build_exeext) $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \ - $(filter insn-conditions.md,$^) > tmp-$*.h + $(filter insn-conditions.md,$^) | $(RUN_GEN) build/genline insn-$*.h > tmp-$*.h $(SHELL) $(srcdir)/../move-if-change tmp-$*.h insn-$*.h $(STAMP) s-$* $(simple_generated_c): insn-%.c: s-%; @true -$(simple_generated_c:insn-%.c=s-%): s-%: build/gen%$(build_exeext) +$(simple_generated_c:insn-%.c=s-%): s-%: build/gen%$(build_exeext) build/genline $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \ - $(filter insn-conditions.md,$^) > tmp-$*.c + $(filter insn-conditions.md,$^) | $(RUN_GEN) build/genline insn-$*.c > tmp-$*.c $(SHELL) $(srcdir)/../move-if-change tmp-$*.c insn-$*.c $(STAMP) s-$* @@ -2397,8 +2397,8 @@ s-opinit: $(MD_DEPS) build/genopinit$(build_exeext) insn-conditions.md # gencondmd doesn't use the standard naming convention. build/gencondmd.c: s-conditions; @true -s-conditions: $(MD_DEPS) build/genconditions$(build_exeext) - $(RUN_GEN) build/genconditions$(build_exeext) $(md_file) > tmp-condmd.c +s-conditions: $(MD_DEPS) build/genconditions$(build_exeext) build/genline$(build_exeext) + $(RUN_GEN) build/genconditions$(build_exeext) $(md_file) | $(RUN_GEN) build/genline$(build_exeext) gencondmd.c > tmp-condmd.c $(SHELL) $(srcdir)/../move-if-change tmp-condmd.c build/gencondmd.c $(STAMP) s-conditions @@ -2783,6 +2783,7 @@ build/genextract.o : genextract.c $(RTL_BASE_H) $(BCONFIG_H) \ $(SYSTEM_H) $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H) build/genflags.o : genflags.c $(RTL_BASE_H) $(OBSTACK_H) $(BCONFIG_H) \ $(SYSTEM_H) $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H) +build/genline.o : genline.c build/gentarget-def.o : gentarget-def.c $(BCONFIG_H) $(SYSTEM_H) \ $(CORETYPES_H) $(GTM_H) $(RTL_BASE_H) errors.h $(READ_MD_H) \ $(GENSUPPORT_H) $(HASH_TABLE_H) target-insns.def @@ -2867,7 +2868,7 @@ genprogerr = $(genprogmd) genrtl modes gtype hooks cfn-macros condmd $(genprogerr:%=build/gen%$(build_exeext)): $(BUILD_ERRORS) # Remaining build programs. -genprog = $(genprogerr) check checksum match +genprog = $(genprogerr) check checksum line match # These programs need libs over and above what they get from the above list. build/genautomata$(build_exeext) : BUILD_LIBS += -lm diff --git a/gcc/genemit.c b/gcc/genemit.c index 84d07d388ee..5e4b82fe3de 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -310,6 +310,7 @@ emit_c_code (const char *code, bool can_fail_p, const char *name) rtx_reader_ptr->print_md_ptr_loc (code); printf ("%s\n", code); + rtx_reader_ptr->print_md_ptr_unloc (code); printf ("#undef DONE\n"); printf ("#undef FAIL\n"); diff --git a/gcc/genline.c b/gcc/genline.c new file mode 100644 index 00000000000..49ecf27a76c --- /dev/null +++ b/gcc/genline.c @@ -0,0 +1,36 @@ +#include <stdio.h> + +int main(int argc, char **argv) +{ + if (argc < 2) + return -1; + + const char *state = "/* #unline */\n"; + const char *p = state; + int line = 1; + + int c; + do + { + c = getchar (); + if (c == '\n') + line++; + if (!*p) + { + printf ("#line %d \"%s\"\n", line, argv[1]); + p = state; + } + if (*p == c) + p++; + else + { + printf ("%.*s", (int)(p - state), state); + p = state; + if (c != EOF) + putchar (c); + } + } + while (c != EOF); + + return 0; +} diff --git a/gcc/read-md.c b/gcc/read-md.c index 40690a86dbc..c935d152b80 100644 --- a/gcc/read-md.c +++ b/gcc/read-md.c @@ -137,6 +137,24 @@ md_reader::print_md_ptr_loc (const void *ptr) fprint_md_ptr_loc (stdout, ptr); } +/* If PTR is associated with a known file position, print an #unline + comment to OUTF. */ + +void +md_reader::fprint_md_ptr_unloc (FILE *outf, const void *ptr) +{ + const struct ptr_loc *loc = get_md_ptr_loc (ptr); + if (loc != 0) + fprintf (outf, "\n/* #unline */\n"); +} + +/* Special fprint_md_ptr_unloc for writing to STDOUT. */ +void +md_reader::print_md_ptr_unloc (const void *ptr) +{ + fprint_md_ptr_unloc (stdout, ptr); +} + /* Return a condition that satisfies both COND1 and COND2. Either string may be null or empty. */ @@ -186,6 +204,7 @@ md_reader::fprint_c_condition (FILE *outf, const char *cond) fputc ('\n', outf); fprint_md_ptr_loc (outf, cond); fprintf (outf, "(%s)", cond); + fprint_md_ptr_unloc (outf, cond); } } diff --git a/gcc/read-md.h b/gcc/read-md.h index b43afb9be86..937b1697d24 100644 --- a/gcc/read-md.h +++ b/gcc/read-md.h @@ -195,6 +195,8 @@ class md_reader void copy_md_ptr_loc (const void *new_ptr, const void *old_ptr); void fprint_md_ptr_loc (FILE *outf, const void *ptr); void print_md_ptr_loc (const void *ptr); + void fprint_md_ptr_unloc (FILE *outf, const void *ptr); + void print_md_ptr_unloc (const void *ptr); struct enum_type *lookup_enum_type (const char *name); void traverse_enum_types (htab_trav callback, void *info); -- 2.28.0