Sv: Sv: [PATCH 1/2 v2] jit : Generate debug info for variables

Message ID 57cd0673c512469ab9bf0a6b2bdc1cb2@kth.se
State New
Headers show
Series
  • Sv: Sv: [PATCH 1/2 v2] jit : Generate debug info for variables
Related show

Commit Message

Ard Biesheuvel via Gcc-patches Sept. 9, 2021, 7:45 a.m.
Hi,

I tested it on another machine over ssh and newer gdb:s (8.3+) clobbers the output with color escapes so I had to disable colors
for the gdb session in jit.exp for the regex matching to work properly:

+    verbose "Disable color styling in GDB newer then 8.3 (errors on older)"
+    send "set style enabled off\n"

On pre 8.3 gdb:s that will be an ignored syntax error.

With that change it passes the check-jit test on that machine too. 

	=== jit Summary ===

	# of expected passes		12073

I squashed the patches and attached it to this mail (with the above change).


No, I don't have push rights to the GCC repo. Should I request it?

Regards,
Petter


-----Ursprungligt meddelande-----
Från: David Malcolm <dmalcolm@redhat.com> 
Skickat: den 8 september 2021 14:49
Till: Petter Tomner <tomner@kth.se>; gcc-patches@gcc.gnu.org; jit@gcc.gnu.org
Ämne: Re: Sv: [PATCH 1/2 v2] jit : Generate debug info for variables

On Tue, 2021-09-07 at 16:18 +0000, Petter Tomner via Gcc-patches wrote:
> I realized I still managed to mess up some WS. I have attached a patch 

> that is the same, except fixes the WS issue underneath.

> 

> Regards, Petter

> 

> +      FOR_EACH_VEC_ELT (m_globals, i, global)

> +    rest_of_decl_compilation (global, true, true);


Thanks for the updated patch.

Looks good to me, assuming it's been tested successfully.  It should be combined with the testcase into a single commit when pushed.

Do you have push rights to the GCC git repo?

Dave

Comments

Ard Biesheuvel via Gcc-patches Sept. 9, 2021, 12:41 p.m. | #1
On Thu, 2021-09-09 at 07:45 +0000, Petter Tomner wrote:
> Hi,

> 

> I tested it on another machine over ssh and newer gdb:s (8.3+) clobbers

> the output with color escapes so I had to disable colors

> for the gdb session in jit.exp for the regex matching to work properly:

> 

> +    verbose "Disable color styling in GDB newer then 8.3 (errors on

> older)"

> +    send "set style enabled off\n"

> 

> On pre 8.3 gdb:s that will be an ignored syntax error.

> 

> With that change it passes the check-jit test on that machine too. 

> 

>         === jit Summary ===

> 

>         # of expected passes            12073

> 

> I squashed the patches and attached it to this mail (with the above

> change).


Great, thanks.

> 

> 

> No, I don't have push rights to the GCC repo. Should I request it?


In theory I can push the patch on your behalf, but I'm hoping that
you'll want to contribute other patches to libgccjit/GCC, so I'd prefer
it if you got push rights and did it yourself.

I'm happy to sponsor you for access; see:
  https://gcc.gnu.org/gitwrite.html#authenticated

Thanks again for the patch
Dave

> 

> Regards,

> Petter

> 

> 

> -----Ursprungligt meddelande-----

> Från: David Malcolm <dmalcolm@redhat.com> 

> Skickat: den 8 september 2021 14:49

> Till: Petter Tomner <tomner@kth.se>; gcc-patches@gcc.gnu.org; 

> jit@gcc.gnu.org

> Ämne: Re: Sv: [PATCH 1/2 v2] jit : Generate debug info for variables

> 

> On Tue, 2021-09-07 at 16:18 +0000, Petter Tomner via Gcc-patches wrote:

> > I realized I still managed to mess up some WS. I have attached a

> > patch 

> > that is the same, except fixes the WS issue underneath.

> > 

> > Regards, Petter

> > 

> > +      FOR_EACH_VEC_ELT (m_globals, i, global)

> > +    rest_of_decl_compilation (global, true, true);

> 

> Thanks for the updated patch.

> 

> Looks good to me, assuming it's been tested successfully.  It should be

> combined with the testcase into a single commit when pushed.

> 

> Do you have push rights to the GCC git repo?

> 

> Dave

> 

>

Patch

From ef4c2885f0d693254b9ba4a6c8eca6e2f1c4fc62 Mon Sep 17 00:00:00 2001
From: Petter Tomner <tomner@kth.se>
Date: Thu, 9 Sep 2021 00:50:06 +0200
Subject: [PATCH] libgccjit: Generate debug info for variables

Finalize declares via available helpers after location is set. Set
TYPE_NAME of primitives and friends to "int" etc. Debug info is now
set properly for variables.

Signed-off-by:
2021-09-09	Petter Tomner	<tomner@kth.se>

gcc/jit/
	* jit-playback.c: Moved global var processing to after loc handling.
	  Setting TYPE_NAME for fundamental types.
	  Using common functions for finalizing globals.
	* jit-playback.h: New method init_types().
	  Changed get_tree_node_for_type() to method.

gcc/testsuite/jit.dg/
	* test-error-array-bounds.c: Array is not unsigned
	* jit.exp: Helper function
	* test-debuginfo.c: New testcase
---
 gcc/jit/jit-playback.c                        | 70 ++++++++++++++----
 gcc/jit/jit-playback.h                        |  5 ++
 gcc/testsuite/jit.dg/jit.exp                  | 28 ++++++++
 gcc/testsuite/jit.dg/test-debuginfo.c         | 72 +++++++++++++++++++
 .../jit.dg/test-error-array-bounds.c          |  2 +-
 5 files changed, 162 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-debuginfo.c

diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index 79ac525e5df..59399dee251 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -165,7 +165,8 @@  gt_ggc_mx ()
 
 /* Given an enum gcc_jit_types value, get a "tree" type.  */
 
-static tree
+tree
+playback::context::
 get_tree_node_for_type (enum gcc_jit_types type_)
 {
   switch (type_)
@@ -192,11 +193,7 @@  get_tree_node_for_type (enum gcc_jit_types type_)
       return short_unsigned_type_node;
 
     case GCC_JIT_TYPE_CONST_CHAR_PTR:
-      {
-	tree const_char = build_qualified_type (char_type_node,
-						TYPE_QUAL_CONST);
-	return build_pointer_type (const_char);
-      }
+      return m_const_char_ptr;
 
     case GCC_JIT_TYPE_INT:
       return integer_type_node;
@@ -579,10 +576,6 @@  playback::lvalue *
 playback::context::
 global_finalize_lvalue (tree inner)
 {
-  varpool_node::get_create (inner);
-
-  varpool_node::finalize_decl (inner);
-
   m_globals.safe_push (inner);
 
   return new lvalue (this, inner);
@@ -2952,9 +2945,7 @@  replay ()
 {
   JIT_LOG_SCOPE (get_logger ());
 
-  m_const_char_ptr
-    = build_pointer_type (build_qualified_type (char_type_node,
-						TYPE_QUAL_CONST));
+  init_types ();
 
   /* Replay the recorded events:  */
   timevar_push (TV_JIT_REPLAY);
@@ -2984,10 +2975,17 @@  replay ()
     {
       int i;
       function *func;
-
+      tree global;
       /* No GC can happen yet; process the cached source locations.  */
       handle_locations ();
 
+      /* Finalize globals. See how FORTRAN 95 does it in gfc_be_parse_file()
+         for a simple reference. */
+      FOR_EACH_VEC_ELT (m_globals, i, global)
+        rest_of_decl_compilation (global, true, true);
+
+      wrapup_global_declarations (m_globals.address(), m_globals.length());
+
       /* We've now created tree nodes for the stmts in the various blocks
 	 in each function, but we haven't built each function's single stmt
 	 list yet.  Do so now.  */
@@ -3081,6 +3079,50 @@  location_comparator (const void *lhs, const void *rhs)
   return loc_lhs->get_column_num () - loc_rhs->get_column_num ();
 }
 
+/* Initialize the NAME_TYPE of the primitive types as well as some
+   others. */
+void
+playback::context::
+init_types ()
+{
+  /* See lto_init() in lto-lang.c or void visit (TypeBasic *t) in D's types.cc 
+     for reference. If TYPE_NAME is not set, debug info will not contain types */
+#define NAME_TYPE(t,n) \
+if (t) \
+  TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, \
+                              get_identifier (n), t)
+
+  NAME_TYPE (integer_type_node, "int");
+  NAME_TYPE (char_type_node, "char");
+  NAME_TYPE (long_integer_type_node, "long int");
+  NAME_TYPE (unsigned_type_node, "unsigned int");
+  NAME_TYPE (long_unsigned_type_node, "long unsigned int");
+  NAME_TYPE (long_long_integer_type_node, "long long int");
+  NAME_TYPE (long_long_unsigned_type_node, "long long unsigned int");
+  NAME_TYPE (short_integer_type_node, "short int");
+  NAME_TYPE (short_unsigned_type_node, "short unsigned int");
+  if (signed_char_type_node != char_type_node)
+    NAME_TYPE (signed_char_type_node, "signed char");
+  if (unsigned_char_type_node != char_type_node)
+    NAME_TYPE (unsigned_char_type_node, "unsigned char");
+  NAME_TYPE (float_type_node, "float");
+  NAME_TYPE (double_type_node, "double");
+  NAME_TYPE (long_double_type_node, "long double");
+  NAME_TYPE (void_type_node, "void");
+  NAME_TYPE (boolean_type_node, "bool");
+  NAME_TYPE (complex_float_type_node, "complex float");
+  NAME_TYPE (complex_double_type_node, "complex double");
+  NAME_TYPE (complex_long_double_type_node, "complex long double");
+  
+  m_const_char_ptr = build_pointer_type(
+    build_qualified_type (char_type_node, TYPE_QUAL_CONST));
+
+  NAME_TYPE (m_const_char_ptr, "char");
+  NAME_TYPE (size_type_node, "size_t");
+  NAME_TYPE (fileptr_type_node, "FILE");
+#undef NAME_TYPE
+}
+
 /* Our API allows locations to be created in arbitrary orders, but the
    linemap API requires locations to be created in ascending order
    as if we were tokenizing files.
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 825a3e172e9..f670c9e81df 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -271,8 +271,13 @@  private:
   source_file *
   get_source_file (const char *filename);
 
+  tree
+  get_tree_node_for_type (enum gcc_jit_types type_);
+
   void handle_locations ();
 
+  void init_types ();
+
   const char * get_path_c_file () const;
   const char * get_path_s_file () const;
   const char * get_path_so_file () const;
diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
index 005ba01601a..4459dbc3f1a 100644
--- a/gcc/testsuite/jit.dg/jit.exp
+++ b/gcc/testsuite/jit.dg/jit.exp
@@ -377,6 +377,34 @@  proc dg-jit-set-exe-params { args } {
     }
 }
 
+# For test-debuginfo.c. Starts gdb, does cmds and checks the output against match
+proc jit-check-debug-info { obj_file cmds match } {
+    verbose "Checking debug info for $obj_file with match: $match"
+
+    if { [catch {exec gdb -v} fid] } {
+        verbose "No gdb seems to be in path. Can't check debug info. Reporting 'unsupported'."
+        unsupported "No gdb seems to be in path. Can't check debug info"
+        return
+    }
+
+    spawn gdb $obj_file
+
+    verbose "Disable color styling in GDB newer then 8.3 (errors on older)"
+    send "set style enabled off\n"
+
+    foreach cmd $cmds {
+        send $cmd
+    }
+    expect {
+        -re $match { pass OK }
+        default { fail FAIL }
+    }
+
+    # Quit gdb
+    send "set confirm off\n"
+    send "q\n"
+}
+
 proc jit-dg-test { prog do_what extra_tool_flags } {
     verbose "within jit-dg-test..."
     verbose "  prog: $prog"
diff --git a/gcc/testsuite/jit.dg/test-debuginfo.c b/gcc/testsuite/jit.dg/test-debuginfo.c
new file mode 100644
index 00000000000..49e8834a0ba
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-debuginfo.c
@@ -0,0 +1,72 @@ 
+/* Essentially this test checks that debug info are generated for globals
+   locals and functions, including type info. The comment bellow is used
+   as fake code (does not affect the test, use for manual debugging). */
+/*
+int a_global_for_test_debuginfo;
+int main (int argc, char **argv)
+{
+    int a_local_for_test_debuginfo = 2;
+    return a_global_for_test_debuginfo + a_local_for_test_debuginfo;
+}
+*/
+#include "libgccjit.h"
+
+/* We don't want set_options() in harness.h to set -O3 so our little local
+   is optimized away. */
+#define TEST_ESCHEWS_SET_OPTIONS
+static void set_options (gcc_jit_context *ctxt, const char *argv0)
+{
+    gcc_jit_context_set_bool_option(ctxt, GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
+}
+
+#define TEST_COMPILING_TO_FILE
+#define OUTPUT_KIND      GCC_JIT_OUTPUT_KIND_EXECUTABLE
+#define OUTPUT_FILENAME  "jit-debuginfo.o"
+#include "harness.h"
+
+#define LOC(row, col) gcc_jit_context_new_location(ctxt, "test-debuginfo.c", row, col)
+
+void
+create_code (gcc_jit_context *ctxt, void* p)
+{
+  gcc_jit_type *int_type = gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_INT);
+
+  gcc_jit_lvalue *bar = gcc_jit_context_new_global(ctxt, 
+    LOC(5,1), GCC_JIT_GLOBAL_EXPORTED, 
+    int_type, "a_global_for_test_debuginfo");
+
+  gcc_jit_param *argc_para = gcc_jit_context_new_param(ctxt, LOC(6,15), 
+    int_type, "argc");
+  gcc_jit_param *argv_para = gcc_jit_context_new_param(ctxt, LOC(6,28), 
+    gcc_jit_type_get_pointer(
+      gcc_jit_type_get_pointer(
+        gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_CHAR))),
+    "argc");
+
+  gcc_jit_param *params[] = {argc_para, argv_para};
+
+  gcc_jit_function *foo_fn = gcc_jit_context_new_function(ctxt, LOC(6,5), 
+    GCC_JIT_FUNCTION_EXPORTED, int_type, "main", 2, params, 0);
+  gcc_jit_block *start_block = gcc_jit_function_new_block(foo_fn, 
+    "start_block");
+
+  gcc_jit_lvalue *a = gcc_jit_function_new_local(foo_fn, LOC(8,5), 
+    int_type, "a_local_for_test_debuginfo");
+  gcc_jit_block_add_assignment(start_block, LOC(8,36), a, 
+    gcc_jit_context_new_rvalue_from_int(ctxt, int_type, 2));
+  gcc_jit_rvalue *add = gcc_jit_context_new_binary_op(ctxt, LOC(9,40), 
+    GCC_JIT_BINARY_OP_PLUS, int_type, 
+    gcc_jit_lvalue_as_rvalue(a), gcc_jit_lvalue_as_rvalue(bar));
+
+  gcc_jit_block_end_with_return(start_block, LOC(9,5), add);
+}
+
+#undef LOC
+
+/* jit-check-debug-info fires up gdb and checks that the variables have 
+   debug info */
+
+/*  { dg-final { jit-check-debug-info "jit-debuginfo.o" {"info variables\n"} "int\\s+a_global_for_test_debuginfo;" } } */
+/*  { dg-final { jit-check-debug-info "jit-debuginfo.o" {"pt main\n"} "int\\s*\\(\\s*int\\s*,\\s*char\\s*\\*\\*\\s*\\)"} } */
+/*  { dg-final { jit-check-debug-info "jit-debuginfo.o" {"start\n" "info locals\n"} "a_local_for_test_debuginfo"} } */
+/*  { dg-final { jit-check-debug-info "jit-debuginfo.o" {"start\n" "pt a_local_for_test_debuginfo\n"} "int"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/jit.dg/test-error-array-bounds.c b/gcc/testsuite/jit.dg/test-error-array-bounds.c
index cd9361fba1d..b6c0ee526d4 100644
--- a/gcc/testsuite/jit.dg/test-error-array-bounds.c
+++ b/gcc/testsuite/jit.dg/test-error-array-bounds.c
@@ -70,5 +70,5 @@  verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
   /* ...and that the message was captured by the API.  */
   CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
 		      "array subscript 10 is above array bounds of"
-		      " 'unsigned char[10]' [-Warray-bounds]");
+		      " 'char[10]' [-Warray-bounds]");
 }
-- 
2.30.2