[M3devel] m3cc static chain stuff

Jay K jay.krell at cornell.edu
Wed May 26 09:55:19 CEST 2010


I'm going to try to keep the code that seems to do anything, however:

1) if (false && 

 I plan to remove that.


2)
+      if (root->outer && !root->chain_decl && !root->chain_field
+/* REMOVE ME: */ 
+          /* && !debug_static_links () */ 
+         )


I can't find where that would apply, and it is commented out anyway so I'll remove it.


I'm open to arguments though. :)

dbxout.c
+#if 0
+/* Code copied from 1.4.2.2: */ 


I can cheaply enough keep that...should we really though?


I really think we can reduce our changes.
Enough type information should be passed around so that regular gdb works. Imho.
 And so that we can use Dwarf or regular -g -- ie. so various -g options other than -gstabs
  don't cause internal compiler errors. So that debug info might be generated on systems
  that don't support stabs though granted they are few and minor (hppa64-hpux).
Nested functions should be transformed to not be nested. Imho.
Optimization should be allowed to inhibit debugging as much as it does for any other language.


I realize the type information getting around is probably a lot of work.
And it is needed in m3back also, and probably not shared work.


 - Jay

----------------------------------------
> From: jay.krell at cornell.edu
> To: m3devel at elegosoft.com
> Subject: m3cc static chain stuff
> Date: Wed, 26 May 2010 06:05:25 +0000
>
>
> Can any of this be removed?
> Can we really not just use "unfold-nested-procs" like NT386?
> We'd just lose a little bit of optimization, in rare cases, stop paying a bad cost/benefit ratio?
> Part of this is actually *deoptimization*. If the compiler decides the values aren't used, then it should
> be allowed to remove them. That is normal. Wanting to unused stuff in the debugger isn't
> generally a considered the responsibility of optimizers.
>
> Therefore -- we could "unfold", remove our diffs, and gain some optimization and some deoptimization.
> Maybe I'll try without.
>
>
> diff -ur /src/orig/gcc-4.3.0/gcc/tree-nested.c /dev2/cm3/m3-sys/m3cc/gcc/gcc/tree-nested.c
> --- /src/orig/gcc-4.3.0/gcc/tree-nested.c    2008-02-15 09:36:43.000000000 -0800
> +++ /dev2/cm3/m3-sys/m3cc/gcc/gcc/tree-nested.c    2010-05-09 22:27:58.000000000 -0700
>
>
> -/* Build or return the RECORD_TYPE that describes the frame state that is
> -   shared between INFO->CONTEXT and its nested functions.  This record will
> -   not be complete until finalize_nesting_tree; up until that point we'll
> +/* This must agree with the string defined by the same name in m3gdb, file
> +   m3-util.c */
> +static const char * nonlocal_var_rec_name = "_nonlocal_var_rec";
> +
> +/* Build or return the RECORD_TYPE that describes the non-local frame struct
> +   that is shared between INFO->CONTEXT and its nested functions.  This record
> +   will not be complete until finalize_nesting_tree; up until that point we'll
>     be adding fields as necessary.
>
>     We also build the DECL that represents this frame in the function.  */
> @@ -209,7 +224,8 @@
>        free (name);
>
>        info->frame_type = type;
> -      info->frame_decl = create_tmp_var_for (info, type, "FRAME");
> +      info->frame_decl
> +        = create_tmp_var_for (info, type, nonlocal_var_rec_name);
>
>        /* ??? Always make it addressable for now, since it is meant to
>       be pointed to by the static chain pointer.  This pessimizes
> @@ -218,6 +234,8 @@
>       reachable, but the true pessimization is to create the non-
>       local frame structure in the first place.  */
>        TREE_ADDRESSABLE (info->frame_decl) = 1;
> +      /* m3gdb needs to know about this variable. */
> +      DECL_IGNORED_P (info->frame_decl) = 0;
>      }
>    return type;
>  }
> @@ -290,6 +308,10 @@
>    return *slot;
>  }
>
> +/* This must agree with the string defined by the same name in m3gdb, file
> +   m3_util.c */
> +static const char * static_link_var_name = "_static_link_var";
> +
>  /* Build or return the variable that holds the static chain within
>     INFO->CONTEXT.  This variable may only be used within INFO->CONTEXT.  */
>
> @@ -310,9 +332,14 @@
>       Note also that it's represented as a parameter.  This is more
>       close to the truth, since the initial value does come from
>       the caller.  */
> -      decl = build_decl (PARM_DECL, create_tmp_var_name ("CHAIN"), type);
> +      decl = build_decl
> +               (PARM_DECL, get_identifier (static_link_var_name), type);
> +      TREE_CHAIN (decl) = NULL; /* Possibly redundant, but dbxout needs it. */
>        DECL_ARTIFICIAL (decl) = 1;
> -      DECL_IGNORED_P (decl) = 1;
> +
> +      /* m3gdb needs to know about this variable. */
> +      DECL_IGNORED_P (decl) = 0;
> +
>        TREE_USED (decl) = 1;
>        DECL_CONTEXT (decl) = info->context;
>        DECL_ARG_TYPE (decl) = type;
> @@ -326,7 +353,11 @@
>    return decl;
>  }
>
> -/* Build or return the field within the non-local frame state that holds
> +/* This must agree with the string defined by the same name in m3gdb, file
> +   m3_util.c */
> +static const char * static_link_copy_field_name = "_static_link_copy_field";
> +
> +/* Build or return the field within the non-local frame struct that holds
>     the static chain for INFO->CONTEXT.  This is the way to walk back up
>     multiple nesting levels.  */
>
> @@ -339,10 +370,12 @@
>        tree type = build_pointer_type (get_frame_type (info->outer));
>
>        field = make_node (FIELD_DECL);
> -      DECL_NAME (field) = get_identifier ("__chain");
> +      DECL_NAME (field) = get_identifier (static_link_copy_field_name);
>        TREE_TYPE (field) = type;
>        DECL_ALIGN (field) = TYPE_ALIGN (type);
>        DECL_NONADDRESSABLE_P (field) = 1;
> +      /* m3gdb should know about this field. */
> +      DECL_IGNORED_P (field) = 0;
>
>        insert_field_into_struct (get_frame_type (info), field);
>
> @@ -465,7 +498,7 @@
>    return *slot;
>  }
>
> -/* Build or return the field within the non-local frame state that holds
> +/* Build or return the field within the non-local frame struct that holds
>     the non-local goto "jmp_buf".  The buffer itself is maintained by the
>     rtl middle-end as dynamic stack space is allocated.  */
>
> @@ -1620,6 +1653,9 @@
>    switch (TREE_CODE (t))
>      {
>      case ADDR_EXPR:
> +      if (TREE_STATIC (t))
> +    break;
> +
>        /* Build
>         T.1 = &CHAIN->tramp;
>         T.2 = __builtin_adjust_trampoline (T.1);
> @@ -1714,6 +1750,22 @@
>      }
>        break;
>
> +    case STATIC_CHAIN_EXPR:
> +      decl = TREE_OPERAND (t, 0);
> +      target_context = decl_function_context (decl);
> +      if (target_context)
> +    {
> +      if (info->context == target_context)
> +        {
> +          /* Make sure frame_decl gets created.  */
> +          (void) get_frame_type (info);
> +        }
> +      *tp = get_static_chain (info, target_context, &wi->tsi);
> +    }
> +      else
> +    *tp = null_pointer_node;
> +      break;
> +
>      case RETURN_EXPR:
>      case GIMPLE_MODIFY_STMT:
>      case WITH_SIZE_EXPR:
> @@ -1768,13 +1820,22 @@
>    return NULL_TREE;
>  }
>
> +static bool
> +debug_static_links (void)
> +{ return
> +    write_symbols != NO_DEBUG
> +    && debug_info_level != DINFO_LEVEL_NONE
> +    && debug_info_level != DINFO_LEVEL_TERSE;
> +
> +} /* debug_static_links */
> +
>  /* Walk the nesting tree starting with ROOT, depth first.  Convert all
>     trampolines and call expressions.  On the way back up, determine if
>     a nested function actually uses its static chain; if not, remember that.  */
>
>  static void
>  convert_all_function_calls (struct nesting_info *root)
> -{
> +{
>    do
>      {
>        if (root->inner)
> @@ -1784,7 +1845,10 @@
>        walk_function (convert_call_expr, root);
>
>        /* If the function does not use a static chain, then remember that.  */
> -      if (root->outer && !root->chain_decl && !root->chain_field)
> +      if (root->outer && !root->chain_decl && !root->chain_field
> +/* REMOVE ME: */
> +          /* && !debug_static_links () */
> +         )
>      DECL_NO_STATIC_CHAIN (root->context) = 1;
>        else
>      gcc_assert (!DECL_NO_STATIC_CHAIN (root->context));
> @@ -1806,6 +1870,21 @@
>    tree context = root->context;
>    struct function *sf;
>
> +/* REMOVEME: */
> +  /* If this is a nested function and we are supporting debugging via
> +     m3gdb, we always need a chain_decl, so m3gdb can find the static
> +     chain, even if the programmer's code doesn't use it. */
> +  if (false && root->outer && debug_static_links () )
> +    { tree static_chain_decl, temp, stmt;
> +      /* This is a desperate attempt to get later code generation to
> +         store the static link.  If it works, it'll be a miracle. */
> +      static_chain_decl = get_chain_decl (root);
> +      stmt = build_addr (static_chain_decl, root->context);
> +      temp = create_tmp_var_for (root, TREE_TYPE (static_chain_decl), NULL);
> +      stmt = build_gimple_modify_stmt (temp, static_chain_decl);
> +      append_to_statement_list (stmt, &stmt_list);
> +    }
> +
>    /* If we created a non-local frame type or decl, we need to lay them
>       out at this time.  */
>    if (root->frame_type)
> @@ -1912,7 +1991,7 @@
>       proper BIND_EXPR.  */
>    if (root->new_local_var_chain)
>      declare_vars (root->new_local_var_chain, DECL_SAVED_TREE (root->context),
> -          false);
> +          true);
>    if (root->debug_var_chain)
>      declare_vars (root->debug_var_chain, DECL_SAVED_TREE (root->context),
>            true);
>
>
>
 		 	   		  


More information about the M3devel mailing list