<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">We should endeavour to use the same functionality that the C compiler uses for its own nested functions, whereever possible.  The only thing is that we also build closures, so the trampoline mechanisms should be avoided.<div><br></div><div><br><div>
<span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; -webkit-text-decorations-in-effect: none; text-indent: 0px; -webkit-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div><font class="Apple-style-span" color="#0000FF"><font class="Apple-style-span" face="Gill Sans"><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: 'Gill Sans'; "><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: 'Gill Sans'; ">Antony Hosking</span></span></font></font><font class="Apple-style-span" face="Gill Sans"><span class="Apple-style-span" style="font-family: 'Gill Sans'; "><span class="Apple-style-span" style="font-family: 'Gill Sans'; "><span class="Apple-converted-space"> </span>|<span class="Apple-converted-space"> </span></span></span><span class="Apple-style-span" style="font-family: 'Gill Sans'; "><span class="Apple-style-span" style="font-family: 'Gill Sans'; ">Associate Professor</span></span><span class="Apple-style-span" style="font-family: 'Gill Sans'; "><span class="Apple-style-span" style="font-family: 'Gill Sans'; "> | Computer Science | Purdue University</span></span></font></div><div><font class="Apple-style-span" face="GillSans-Light"><span class="Apple-style-span" style="font-family: GillSans-Light; ">305 N. University Street | West Lafayette | IN 47907 | USA</span></font></div><div><font class="Apple-style-span" color="#0000FF" face="Gill Sans"><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: 'Gill Sans'; "><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: 'Gill Sans'; ">Office</span></span></font><font class="Apple-style-span" face="GillSans-Light"><span class="Apple-style-span" style="font-family: GillSans-Light; "><span class="Apple-style-span" style="font-family: GillSans-Light; "> +1 765 494 6001 |<span class="Apple-converted-space"> </span></span></span></font><font class="Apple-style-span" color="#0000FF" face="Gill Sans"><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: 'Gill Sans'; "><span class="Apple-style-span" style="color: rgb(0, 0, 255); font-family: 'Gill Sans'; ">Mobile</span></span></font><font class="Apple-style-span" face="GillSans-Light"><span class="Apple-style-span" style="font-family: GillSans-Light; "><span class="Apple-style-span" style="font-family: GillSans-Light; "><span class="Apple-converted-space"> </span>+1 765 427 5484</span></span></font></div><div><font class="Apple-style-span" face="GillSans-Light"><br class="khtml-block-placeholder"></font></div></span></span></span></span></span></span></span><br class="Apple-interchange-newline"></span></div></span></span><br class="Apple-interchange-newline">
</div>
<br><div><div>On 26 May 2010, at 02:05, Jay K wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div><br>Can any of this be removed?<br>Can we really not just use "unfold-nested-procs" like NT386?<br>We'd just lose a little bit of optimization, in rare cases, stop paying a bad cost/benefit ratio?<br>Part of this is actually *deoptimization*. If the compiler decides the values aren't used, then it should<br>be allowed to remove them. That is normal. Wanting to unused stuff in the debugger isn't<br>generally a considered the responsibility of optimizers.<br><br>Therefore -- we could "unfold", remove our diffs, and gain some optimization and some deoptimization.<br>Maybe I'll try without.<br><br><br>diff -ur /src/orig/gcc-4.3.0/gcc/tree-nested.c /dev2/cm3/m3-sys/m3cc/gcc/gcc/tree-nested.c<br>--- /src/orig/gcc-4.3.0/gcc/tree-nested.c    2008-02-15 09:36:43.000000000 -0800<br>+++ /dev2/cm3/m3-sys/m3cc/gcc/gcc/tree-nested.c    2010-05-09 22:27:58.000000000 -0700<br><br><br>-/* Build or return the RECORD_TYPE that describes the frame state that is<br>-   shared between INFO->CONTEXT and its nested functions.  This record will<br>-   not be complete until finalize_nesting_tree; up until that point we'll<br>+/* This must agree with the string defined by the same name in m3gdb, file<br>+   m3-util.c */ <br>+static const char * nonlocal_var_rec_name = "_nonlocal_var_rec"; <br>+<br>+/* Build or return the RECORD_TYPE that describes the non-local frame struct <br>+   that is shared between INFO->CONTEXT and its nested functions.  This record <br>+   will not be complete until finalize_nesting_tree; up until that point we'll<br>    be adding fields as necessary.<br> <br>    We also build the DECL that represents this frame in the function.  */<br>@@ -209,7 +224,8 @@<br>       free (name);<br> <br>       info->frame_type = type;<br>-      info->frame_decl = create_tmp_var_for (info, type, "FRAME");<br>+      info->frame_decl <br>+        = create_tmp_var_for (info, type, nonlocal_var_rec_name);<br> <br>       /* ??? Always make it addressable for now, since it is meant to<br>      be pointed to by the static chain pointer.  This pessimizes<br>@@ -218,6 +234,8 @@<br>      reachable, but the true pessimization is to create the non-<br>      local frame structure in the first place.  */<br>       TREE_ADDRESSABLE (info->frame_decl) = 1;<br>+      /* m3gdb needs to know about this variable. */ <br>+      DECL_IGNORED_P (info->frame_decl) = 0;  <br>     }<br>   return type;<br> }<br>@@ -290,6 +308,10 @@<br>   return *slot;<br> }<br> <br>+/* This must agree with the string defined by the same name in m3gdb, file<br>+   m3_util.c */ <br>+static const char * static_link_var_name = "_static_link_var"; <br>+<br> /* Build or return the variable that holds the static chain within<br>    INFO->CONTEXT.  This variable may only be used within INFO->CONTEXT.  */<br> <br>@@ -310,9 +332,14 @@<br>      Note also that it's represented as a parameter.  This is more<br>      close to the truth, since the initial value does come from <br>      the caller.  */<br>-      decl = build_decl (PARM_DECL, create_tmp_var_name ("CHAIN"), type);<br>+      decl = build_decl <br>+               (PARM_DECL, get_identifier (static_link_var_name), type);<br>+      TREE_CHAIN (decl) = NULL; /* Possibly redundant, but dbxout needs it. */ <br>       DECL_ARTIFICIAL (decl) = 1;<br>-      DECL_IGNORED_P (decl) = 1;<br>+<br>+      /* m3gdb needs to know about this variable. */ <br>+      DECL_IGNORED_P (decl) = 0;<br>+<br>       TREE_USED (decl) = 1;<br>       DECL_CONTEXT (decl) = info->context;<br>       DECL_ARG_TYPE (decl) = type;<br>@@ -326,7 +353,11 @@<br>   return decl;<br> }<br> <br>-/* Build or return the field within the non-local frame state that holds<br>+/* This must agree with the string defined by the same name in m3gdb, file<br>+   m3_util.c */ <br>+static const char * static_link_copy_field_name = "_static_link_copy_field"; <br>+<br>+/* Build or return the field within the non-local frame struct that holds<br>    the static chain for INFO->CONTEXT.  This is the way to walk back up<br>    multiple nesting levels.  */<br> <br>@@ -339,10 +370,12 @@<br>       tree type = build_pointer_type (get_frame_type (info->outer));<br> <br>       field = make_node (FIELD_DECL);<br>-      DECL_NAME (field) = get_identifier ("__chain");<br>+      DECL_NAME (field) = get_identifier (static_link_copy_field_name);<br>       TREE_TYPE (field) = type;<br>       DECL_ALIGN (field) = TYPE_ALIGN (type);<br>       DECL_NONADDRESSABLE_P (field) = 1;<br>+      /* m3gdb should know about this field. */ <br>+      DECL_IGNORED_P (field) = 0;  <br> <br>       insert_field_into_struct (get_frame_type (info), field);<br> <br>@@ -465,7 +498,7 @@<br>   return *slot;<br> } <br> <br>-/* Build or return the field within the non-local frame state that holds<br>+/* Build or return the field within the non-local frame struct that holds<br>    the non-local goto "jmp_buf".  The buffer itself is maintained by the<br>    rtl middle-end as dynamic stack space is allocated.  */<br> <br>@@ -1620,6 +1653,9 @@<br>   switch (TREE_CODE (t))<br>     {<br>     case ADDR_EXPR:<br>+      if (TREE_STATIC (t))<br>+    break;<br>+<br>       /* Build<br>        T.1 = &CHAIN->tramp;<br>        T.2 = __builtin_adjust_trampoline (T.1);<br>@@ -1714,6 +1750,22 @@<br>     }<br>       break;<br> <br>+    case STATIC_CHAIN_EXPR:<br>+      decl = TREE_OPERAND (t, 0);<br>+      target_context = decl_function_context (decl);<br>+      if (target_context)<br>+    {<br>+      if (info->context == target_context)<br>+        {<br>+          /* Make sure frame_decl gets created.  */<br>+          (void) get_frame_type (info);<br>+        }<br>+      *tp = get_static_chain (info, target_context, &wi->tsi);<br>+    }<br>+      else<br>+    *tp = null_pointer_node;<br>+      break;<br>+<br>     case RETURN_EXPR:<br>     case GIMPLE_MODIFY_STMT:<br>     case WITH_SIZE_EXPR:<br>@@ -1768,13 +1820,22 @@<br>   return NULL_TREE;<br> }<br> <br>+static bool<br>+debug_static_links (void) <br>+{ return<br>+    write_symbols != NO_DEBUG<br>+    && debug_info_level != DINFO_LEVEL_NONE<br>+    && debug_info_level != DINFO_LEVEL_TERSE;<br>+<br>+} /* debug_static_links */ <br>+<br> /* Walk the nesting tree starting with ROOT, depth first.  Convert all<br>    trampolines and call expressions.  On the way back up, determine if<br>    a nested function actually uses its static chain; if not, remember that.  */<br> <br> static void<br> convert_all_function_calls (struct nesting_info *root)<br>-{<br>+{ <br>   do<br>     {<br>       if (root->inner)<br>@@ -1784,7 +1845,10 @@<br>       walk_function (convert_call_expr, root);<br> <br>       /* If the function does not use a static chain, then remember that.  */<br>-      if (root->outer && !root->chain_decl && !root->chain_field)<br>+      if (root->outer && !root->chain_decl && !root->chain_field<br>+/* REMOVE ME: */ <br>+          /* && !debug_static_links () */ <br>+         )<br>     DECL_NO_STATIC_CHAIN (root->context) = 1;<br>       else<br>     gcc_assert (!DECL_NO_STATIC_CHAIN (root->context));<br>@@ -1806,6 +1870,21 @@<br>   tree context = root->context;<br>   struct function *sf;<br> <br>+/* REMOVEME: */ <br>+  /* If this is a nested function and we are supporting debugging via<br>+     m3gdb, we always need a chain_decl, so m3gdb can find the static <br>+     chain, even if the programmer's code doesn't use it. */ <br>+  if (false && root->outer && debug_static_links () )<br>+    { tree static_chain_decl, temp, stmt;<br>+      /* This is a desperate attempt to get later code generation to <br>+         store the static link.  If it works, it'll be a miracle. */ <br>+      static_chain_decl = get_chain_decl (root); <br>+      stmt = build_addr (static_chain_decl, root->context); <br>+      temp = create_tmp_var_for (root, TREE_TYPE (static_chain_decl), NULL);<br>+      stmt = build_gimple_modify_stmt (temp, static_chain_decl);<br>+      append_to_statement_list (stmt, &stmt_list);<br>+    } <br>+<br>   /* If we created a non-local frame type or decl, we need to lay them<br>      out at this time.  */<br>   if (root->frame_type)<br>@@ -1912,7 +1991,7 @@<br>      proper BIND_EXPR.  */<br>   if (root->new_local_var_chain)<br>     declare_vars (root->new_local_var_chain, DECL_SAVED_TREE (root->context),<br>-          false);<br>+          true);<br>   if (root->debug_var_chain)<br>     declare_vars (root->debug_var_chain, DECL_SAVED_TREE (root->context),<br>           true);<br><br><br> <span class="Apple-tab-span" style="white-space:pre">   </span><span class="Apple-tab-span" style="white-space:pre">    </span> <span class="Apple-tab-span" style="white-space:pre">   </span>   <span class="Apple-tab-span" style="white-space:pre">       </span><span class="Apple-tab-span" style="white-space:pre">    </span>  <br></div></blockquote></div><br></div></body></html>