[M3devel] m3cc static chain stuff

Jay K jay.krell at cornell.edu
Wed May 26 08:05:25 CEST 2010


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