Committed to branch dmalcolm/jit:

With this commit, it's possible to inspect local variables in the debugger
when stepping through a JIT-generated function.

gcc/jit/
        * internal-api.h (gcc::jit::playback::function): Add field
        m_inner_block.

        * internal-api.c (gcc::jit::playback::function::function):
        Create BLOCK here and link it to the BIND_EXPR.
        (gcc::jit::playback::function::gt_ggc_mx): Walk m_inner_block.
        (gcc::jit::playback::function::postprocess): Set up BLOCK_VARS on
        the block, so that the local variables make it into the debuginfo.
---
 gcc/jit/ChangeLog.jit  | 11 +++++++++++
 gcc/jit/internal-api.c | 12 ++++++++++--
 gcc/jit/internal-api.h |  1 +
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index f59b258..40d445e 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,3 +1,14 @@
+2014-02-25  David Malcolm  <dmalc...@redhat.com>
+
+       * internal-api.h (gcc::jit::playback::function): Add field
+       m_inner_block.
+
+       * internal-api.c (gcc::jit::playback::function::function):
+       Create BLOCK here and link it to the BIND_EXPR.
+       (gcc::jit::playback::function::gt_ggc_mx): Walk m_inner_block.
+       (gcc::jit::playback::function::postprocess): Set up BLOCK_VARS on
+       the block, so that the local variables make it into the debuginfo.
+
 2014-02-24  Philip Herron <redbr...@gcc.gnu.org>
 
        * Make-lang.in (jit.install-common): Implement.
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 957edb7..43de7cd 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -2832,11 +2832,13 @@ function (context *ctxt,
       /* Create a BIND_EXPR, and within it, a statement list.  */
       m_stmt_list = alloc_stmt_list ();
       m_stmt_iter = tsi_start (m_stmt_list);
+      m_inner_block = make_node (BLOCK);
       m_inner_bind_expr =
-       build3 (BIND_EXPR, void_type_node, NULL, m_stmt_list, NULL);
+       build3 (BIND_EXPR, void_type_node, NULL, m_stmt_list, m_inner_block);
     }
   else
     {
+      m_inner_block = NULL;
       m_stmt_list = NULL;
     }
 }
@@ -2848,6 +2850,7 @@ gt_ggc_mx ()
   gt_ggc_m_9tree_node (m_inner_fndecl);
   gt_ggc_m_9tree_node (m_inner_bind_expr);
   gt_ggc_m_9tree_node (m_stmt_list);
+  gt_ggc_m_9tree_node (m_inner_block);
 }
 
 tree
@@ -2904,11 +2907,16 @@ postprocess ()
   if (m_kind != GCC_JIT_FUNCTION_IMPORTED)
     {
       /* Seem to need this in gimple-low.c: */
-      DECL_INITIAL (m_inner_fndecl) = make_node (BLOCK);
+      gcc_assert (m_inner_block);
+      DECL_INITIAL (m_inner_fndecl) = m_inner_block;
 
       /* how to add to function? the following appears to be how to
         set the body of a m_inner_fndecl: */
       DECL_SAVED_TREE(m_inner_fndecl) = m_inner_bind_expr;
+
+      /* Ensure that locals appear in the debuginfo.  */
+      BLOCK_VARS (m_inner_block) = BIND_EXPR_VARS (m_inner_bind_expr);
+
       //debug_tree (m_inner_fndecl);
 
       /* Convert to gimple: */
diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h
index 83bda17..0017f6c 100644
--- a/gcc/jit/internal-api.h
+++ b/gcc/jit/internal-api.h
@@ -1887,6 +1887,7 @@ private:
 
 private:
   tree m_inner_fndecl;
+  tree m_inner_block;
   tree m_inner_bind_expr;
   enum gcc_jit_function_kind m_kind;
   tree m_stmt_list;
-- 
1.7.11.7

Reply via email to