]> gcc.gnu.org Git - gcc.git/commitdiff
Makefile.in (INTREGRATE_H): Rename to INTEGRATE_H.
authorMark Mitchell <mark@codesourcery.com>
Thu, 16 Dec 1999 17:50:29 +0000 (17:50 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 16 Dec 1999 17:50:29 +0000 (17:50 +0000)
* Makefile.in (INTREGRATE_H): Rename to INTEGRATE_H.
* function.c (insert_block_after_note): Remove.
(retrofit_block): Likewise.
(identify_blocks): Fix indentation.
(reorder_blocks): Don't NULL out NOTE_SOURCE_FILE for a
NOTE_INSN_BLOCK_BEG or NOTE_INSN_BLOCK_END.
* function.h (insert_block_after_note): Remove prototype.
(retrofit_block): Likewise.
* integrate.c (expand_inline_function): Don't call
find_loop_tree_blocks.  Use expand_start_bindings_and_block, not
just expand_start_bindings.  Use the block_map to remap old
NOTE_BLOCKs to new ones.
(integrate_decl_tree): Keep track of remapped blocks.
* integrate.h (struct inline_remap): Add block_map.
* stmt.c (expand_fixup): Don't try to retrofit_blocks.  Just set
NOTE_BLOCK on the notes.
(expand_start_bindings): Rename to ...
(expand_start_bindings_and_block): Add parameter.  Set NOTE_BLOCK.
(expand_end_bindings): Set NOTE_BLOCK.
* toplev.c (rest_of_compilation): In function-at-a-time-mode,
reconstruct the BLOCK tree.
* tree.h (expand_start_bindings): Macroize.  Call ...
(expand_start_bindings_and_block): New function.

* optimize.c (struct inline_data): Remove scope_stmt.
(remap_block): Don't use insert_block_after_note.  Don't update
scope_stmt.
(expand_call_inline): Don't update scope_stmt.
(optimize_function): Don't initialize scope_stmt.
* semantics.c (expand_stmt): Set NOTE_BLOCK for newly emitted
NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END notes.

From-SVN: r30982

12 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/cp/ChangeLog
gcc/cp/optimize.c
gcc/cp/semantics.c
gcc/function.c
gcc/function.h
gcc/integrate.c
gcc/integrate.h
gcc/stmt.c
gcc/toplev.c
gcc/tree.h

index d2a65821335d1bbcf3ac683d5c2bfb275f60c110..5473179ef5488d199475c308bf182d6d23240605 100644 (file)
@@ -1,3 +1,29 @@
+1999-12-16  Mark Mitchell  <mark@codesourcery.com>
+
+       * Makefile.in (INTREGRATE_H): Rename to INTEGRATE_H.
+       * function.c (insert_block_after_note): Remove.
+       (retrofit_block): Likewise.
+       (identify_blocks): Fix indentation.
+       (reorder_blocks): Don't NULL out NOTE_SOURCE_FILE for a
+       NOTE_INSN_BLOCK_BEG or NOTE_INSN_BLOCK_END.
+       * function.h (insert_block_after_note): Remove prototype.
+       (retrofit_block): Likewise.
+       * integrate.c (expand_inline_function): Don't call
+       find_loop_tree_blocks.  Use expand_start_bindings_and_block, not
+       just expand_start_bindings.  Use the block_map to remap old
+       NOTE_BLOCKs to new ones.
+       (integrate_decl_tree): Keep track of remapped blocks.
+       * integrate.h (struct inline_remap): Add block_map.
+       * stmt.c (expand_fixup): Don't try to retrofit_blocks.  Just set
+       NOTE_BLOCK on the notes.
+       (expand_start_bindings): Rename to ...
+       (expand_start_bindings_and_block): Add parameter.  Set NOTE_BLOCK.
+       (expand_end_bindings): Set NOTE_BLOCK.
+       * toplev.c (rest_of_compilation): In function-at-a-time-mode,
+       reconstruct the BLOCK tree.
+       * tree.h (expand_start_bindings): Macroize.  Call ...
+       (expand_start_bindings_and_block): New function.
+       
 1999-12-16  Jakub Jelinek  <jakub@redhat.com>
 
        * config/sparc/sparc.c (print_operand): Cast fprintf arguments
index 6e63925c91a8e1d6c359a465cb6d14d892384cb6..6f367cb26b031f97a5166d044843c5da5177c70d 100644 (file)
@@ -748,7 +748,7 @@ DEMANGLE_H = $(srcdir)/../include/demangle.h
 RECOG_H = recog.h
 EXPR_H = expr.h insn-codes.h
 REGS_H = regs.h varray.h $(MACHMODE_H)
-INTREGRATE_H = integrate.h varray.h
+INTEGRATE_H = integrate.h varray.h
 LOOP_H = loop.h varray.h
 #\f
 # Language makefile fragments.
index ff70df40b346ac4067b8a1f36037ce86ae556b61..05f1618310e3ab92ffbba1bb33b248fae17e0d85 100644 (file)
@@ -1,3 +1,13 @@
+1999-12-16  Mark Mitchell  <mark@codesourcery.com>
+
+       * optimize.c (struct inline_data): Remove scope_stmt.
+       (remap_block): Don't use insert_block_after_note.  Don't update
+       scope_stmt.
+       (expand_call_inline): Don't update scope_stmt.
+       (optimize_function): Don't initialize scope_stmt.
+       * semantics.c (expand_stmt): Set NOTE_BLOCK for newly emitted
+       NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END notes.
+
 1999-12-15  Mark Mitchell  <mark@codesourcery.com>
 
        * class.c (handle_using_decl): Get TYPE_FIELDS and TYPE_METHODS
index 7eae09df3fc2cbaea1d13154bee638437236d26a..2dd151ccb010bcbc0bc933ec39e7d3ae961e01cc 100644 (file)
@@ -53,8 +53,6 @@ typedef struct inline_data
      inlining the body of `h', the stack will contain, `h', followed
      by `g', followed by `f'.  */
   varray_type fns;
-  /* The last SCOPE_STMT we have encountered.  */
-  tree scope_stmt;
   /* The label to jump to when a return statement is encountered.  */
   tree ret_label;
   /* The map from local declarations in the inlined function to
@@ -146,6 +144,7 @@ remap_block (scope_stmt, decls, id)
       tree old_block;
       tree new_block;
       tree old_var;
+      tree fn;
 
       /* Make the new block.  */
       old_block = SCOPE_STMT_BLOCK (scope_stmt);
@@ -175,13 +174,12 @@ remap_block (scope_stmt, decls, id)
        }
       /* We put the BLOCK_VARS in reverse order; fix that now.  */
       BLOCK_VARS (new_block) = nreverse (BLOCK_VARS (new_block));
-      /* Graft the new block into the tree.  */
-      insert_block_after_note (new_block,
-                              SCOPE_STMT_BLOCK (id->scope_stmt),
-                              SCOPE_BEGIN_P (id->scope_stmt));
-      /* Remember that this is now the last scope statement with
-        an associated block.  */
-      id->scope_stmt = scope_stmt;
+      /* Attach this new block after the DECL_INITIAL block for the
+        function into which this block is being inlined.  In
+        rest_of_compilation we will straighten out the BLOCK tree.  */
+      fn = VARRAY_TREE (id->fns, 0);
+      BLOCK_CHAIN (new_block) = BLOCK_CHAIN (DECL_INITIAL (fn));
+      BLOCK_CHAIN (DECL_INITIAL (fn)) = new_block;
       /* Remember the remapped block.  */
       splay_tree_insert (id->decl_map,
                         (splay_tree_key) old_block,
@@ -198,10 +196,6 @@ remap_block (scope_stmt, decls, id)
                             (splay_tree_key) SCOPE_STMT_BLOCK (scope_stmt));
       my_friendly_assert (n != NULL, 19991203);
       SCOPE_STMT_BLOCK (scope_stmt) = (tree) n->value;
-
-      /* Remember that this is now the last scope statement with an
-        associated block.  */
-      id->scope_stmt = scope_stmt;
     }
 }
 
@@ -520,14 +514,6 @@ expand_call_inline (tp, walk_subtrees, data)
   id = (inline_data *) data;
   t = *tp;  
 
-  /* Keep track of the last SCOPE_STMT we've seen.  */
-  if (TREE_CODE (t) == SCOPE_STMT)
-    {
-      if (SCOPE_STMT_BLOCK (t) && !id->in_target_cleanup_p)
-       id->scope_stmt = t;
-      return NULL_TREE;
-    }
-
   /* Recurse, but letting recursive invocations know that we are
      inside the body of a TARGET_EXPR.  */
   if (TREE_CODE (*tp) == TARGET_EXPR)
@@ -608,11 +594,9 @@ expand_call_inline (tp, walk_subtrees, data)
   remap_block (scope_stmt, DECL_ARGUMENTS (fn), id);
   TREE_CHAIN (scope_stmt) = STMT_EXPR_STMT (expr);
   STMT_EXPR_STMT (expr) = scope_stmt;
-  id->scope_stmt = scope_stmt;
 
   /* Tell the debugging backends that this block represents the
-     outermost scope of the inlined function.  FIXME what to do for
-     inlines in cleanups?  */
+     outermost scope of the inlined function.  */
   if (SCOPE_STMT_BLOCK (scope_stmt))
     BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope_stmt)) = DECL_ORIGIN (fn);
 
@@ -723,12 +707,6 @@ optimize_function (fn)
            prev_fn = s->function_decl;
          }
 
-      /* Initialize id->scope_stmt with a fake SCOPE_STMT for the outermost
-        block of the function (i.e. the BLOCK with __FUNCTION__ et al).  */
-      id.scope_stmt = build_min_nt (SCOPE_STMT,
-                                   BLOCK_SUBBLOCKS (DECL_INITIAL (fn)));
-      SCOPE_BEGIN_P (id.scope_stmt) = 1;
-
       /* Replace all calls to inline functions with the bodies of those
         functions.  */
       expand_calls_inline (&DECL_SAVED_TREE (fn), &id);
index 339726fe7ed52d483af7c98a10a309b7501038e4..5ac7bdb83f702043822961a5ad0f4c24622f00b8 100644 (file)
@@ -2514,16 +2514,21 @@ expand_stmt (t)
          if (!SCOPE_NO_CLEANUPS_P (t))
            {
              if (SCOPE_BEGIN_P (t))
-               expand_start_bindings (2 * SCOPE_NULLIFIED_P (t));
+               expand_start_bindings_and_block (2 * SCOPE_NULLIFIED_P (t),
+                                                SCOPE_STMT_BLOCK (t));
              else if (SCOPE_END_P (t))
                expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 
                                     SCOPE_PARTIAL_P (t));
            }
          else if (!SCOPE_NULLIFIED_P (t))
-           emit_note (NULL,
-                      (SCOPE_BEGIN_P (t) 
-                       ? NOTE_INSN_BLOCK_BEG
-                       : NOTE_INSN_BLOCK_END));
+           {
+             rtx note = emit_note (NULL,
+                                   (SCOPE_BEGIN_P (t) 
+                                    ? NOTE_INSN_BLOCK_BEG
+                                    : NOTE_INSN_BLOCK_END));
+             NOTE_BLOCK (note) = SCOPE_STMT_BLOCK (t);
+           }
+             
          break;
 
        case RETURN_INIT:
index 321120457b971eea681f0f30f0b09767e0348ef7..02ee9fb14eb01f4bf9d4ba925ef849b52312c320 100644 (file)
@@ -5493,66 +5493,6 @@ round_trampoline_addr (tramp)
   return tramp;
 }
 \f
-/* Insert the BLOCK in the block-tree, knowing that the previous
-   block-note is for OLD_BLOCK.  BEGIN_P is non-zero if the previous
-   block-note was the for the beginning of a BLOCK.  */
-
-void 
-insert_block_after_note (block, old_block, begin_p)
-     tree block;
-     tree old_block;
-     int begin_p;
-{
-  if (begin_p)
-    {
-      /* If there was no previous block, something's gone terribly
-         wrong.  We used to try to use DECL_INITIAL for the current
-         function, but that will never be correct, and completely
-         hoses the block structure.  */
-      if (!old_block)
-       abort ();
-
-      BLOCK_SUPERCONTEXT (block) = old_block;
-      BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (old_block);
-      BLOCK_SUBBLOCKS (old_block) = block;
-    }
-  else
-    {
-      BLOCK_SUPERCONTEXT (block) = BLOCK_SUPERCONTEXT (old_block);
-      BLOCK_CHAIN (block) = BLOCK_CHAIN (old_block);
-      BLOCK_CHAIN (old_block) = block;
-    }
-}
-
-/* Insert the BLOCK in the block-tree before LAST_INSN.  */
-
-void
-retrofit_block (block, last_insn)
-     tree block;
-     rtx last_insn;
-{
-  rtx insn;
-
-  /* Now insert the new BLOCK at the right place in the block trees
-     for the function which called the inline function.  We just look
-     backwards for a NOTE_INSN_BLOCK_{BEG,END}.  If we find the
-     beginning of a block, then this new block becomes the first
-     subblock of that block.  If we find the end of a block, then this
-     new block follows that block in the list of blocks.  */
-  for (insn = last_insn; insn; insn = PREV_INSN (insn))
-    if (GET_CODE (insn) == NOTE
-       && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
-           || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
-      break;
-
-  if (insn == NULL_RTX)
-    abort ();
-
-  insert_block_after_note (block, 
-                          NOTE_BLOCK (insn),
-                          NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG);
-}
-
 /* The functions identify_blocks and reorder_blocks provide a way to
    reorder the tree of BLOCK nodes, for optimizers that reshuffle or
    duplicate portions of the RTL code.  Call identify_blocks before
@@ -5595,8 +5535,8 @@ identify_blocks (block, insns)
          {
            tree b;
 
-             /* If there are more block notes than BLOCKs, something
-                is badly wrong.  */
+           /* If there are more block notes than BLOCKs, something
+              is badly wrong.  */
            if (current_block_number == n_blocks)
              abort ();
 
@@ -5660,14 +5600,12 @@ reorder_blocks (block, insns)
            BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
            BLOCK_SUBBLOCKS (current_block) = block;
            current_block = block;
-           NOTE_SOURCE_FILE (insn) = 0;
          }
        if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
          {
            BLOCK_SUBBLOCKS (current_block)
              = blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
            current_block = BLOCK_SUPERCONTEXT (current_block);
-           NOTE_SOURCE_FILE (insn) = 0;
          }
       }
 
index 0e2b7b8bf3aa1f0ce6e2294977d5d00a1a281416..a641189e5d1e1df9501c2ed8953e46424dcb1fcc 100644 (file)
@@ -543,12 +543,6 @@ extern struct function *outer_function_chain;
    Also store in each NOTE for the beginning or end of a block
    the index of that block in the vector.  */
 extern void identify_blocks PROTO((tree, rtx));
-/* Insert the BLOCK in the block-tree, knowing that the previous
-   block-note is for OLD_BLOCK.  BEGIN_P is non-zero if the previous
-   block-note was the for the beginning of a BLOCK.  */
-extern void insert_block_after_note PROTO((tree, tree, int));
-/* Insert a new BLOCK at an appropriate place in the block tree.  */
-extern void retrofit_block PROTO((tree, rtx));
 
 /* Return size needed for stack frame based on slots so far allocated.
    This size counts from zero.  It is not rounded to STACK_BOUNDARY;
index f8253095872b03e3b11a8ba053da96b30cb10440..c50c1d4923c996cef81e090e3179d2728ca8cc89 100644 (file)
@@ -78,6 +78,8 @@ static void process_reg_param         PROTO((struct inline_remap *, rtx,
 void set_decl_abstract_flags           PROTO((tree, int));
 static rtx expand_inline_function_eh_labelmap PROTO((rtx));
 static void mark_stores                 PROTO((rtx, rtx, void *));
+static int compare_blocks               PROTO((const PTR, const PTR));
+static int find_block                   PROTO((const PTR, const PTR));
 
 /* The maximum number of instructions accepted for inlining a
    function.  Increasing values mean more agressive inlining.
@@ -505,6 +507,35 @@ expand_inline_function_eh_labelmap (label)
   return get_label_from_map (eif_eh_map, index);
 }
 
+/* Compare two BLOCKs for qsort.  The key we sort on is the
+   BLOCK_ABSTRACT_ORIGIN of the blocks.  */
+
+static int
+compare_blocks (v1, v2)
+     const PTR v1;
+     const PTR v2;
+{
+  tree b1 = *((tree *) v1);
+  tree b2 = *((tree *) v2);
+
+  return ((char *) BLOCK_ABSTRACT_ORIGIN (b1) 
+         - (char *) BLOCK_ABSTRACT_ORIGIN (b2));
+}
+
+/* Compare two BLOCKs for bsearch.  The first pointer corresponds to
+   an original block; the second to a remapped equivalent.  */
+
+static int
+find_block (v1, v2)
+     const PTR v1;
+     const PTR v2;
+{
+  tree b1 = (tree) v1;
+  tree b2 = *((tree *) v2);
+
+  return ((char *) b1 - (char *) BLOCK_ABSTRACT_ORIGIN (b2));
+}
+
 /* Integrate the procedure defined by FNDECL.  Note that this function
    may wind up calling itself.  Since the static variables are not
    reentrant, we do not assign them until after the possibility
@@ -687,6 +718,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
   map = (struct inline_remap *) xmalloc (sizeof (struct inline_remap));
   map->fndecl = fndecl;
 
+  VARRAY_TREE_INIT (map->block_map, 10, "block_map");
   map->reg_map = (rtx *) xcalloc (max_regno, sizeof (rtx));
 
   /* We used to use alloca here, but the size of what it would try to
@@ -757,11 +789,6 @@ expand_inline_function (fndecl, parms, target, ignore, type,
        RTX_INTEGRATED_P (note) = 1;
     }
 
-  /* Figure out where the blocks are if we're going to have to insert
-     new BLOCKs into the existing block tree.  */
-  if (current_function->x_whole_function_mode_p)
-    find_loop_tree_blocks ();
-
   /* Process each argument.  For each, set up things so that the function's
      reference to the argument will refer to the argument being passed.
      We only replace REG with REG here.  Any simplifications are done
@@ -1006,15 +1033,32 @@ expand_inline_function (fndecl, parms, target, ignore, type,
   else
     abort ();
 
-  /* Make a fresh binding contour that we can easily remove.  Do this after
-     expanding our arguments so cleanups are properly scoped.  */
-  expand_start_bindings (0);
-
   /* Initialize label_map.  get_label_from_map will actually make
      the labels.  */
   bzero ((char *) &map->label_map [min_labelno],
         (max_labelno - min_labelno) * sizeof (rtx));
 
+  /* Make copies of the decls of the symbols in the inline function, so that
+     the copies of the variables get declared in the current function.  Set
+     up things so that lookup_static_chain knows that to interpret registers
+     in SAVE_EXPRs for TYPE_SIZEs as local.  */
+  inline_function_decl = fndecl;
+  integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
+  block = integrate_decl_tree (inl_f->original_decl_initial, map);
+  BLOCK_ABSTRACT_ORIGIN (block) = DECL_ORIGIN (fndecl);
+  inline_function_decl = 0;
+
+  /* Make a fresh binding contour that we can easily remove.  Do this after
+     expanding our arguments so cleanups are properly scoped.  */
+  expand_start_bindings_and_block (0, block);
+
+  /* Sort the block-map so that it will be easy to find remapped
+     blocks later.  */
+  qsort (&VARRAY_TREE (map->block_map, 0), 
+        map->block_map->elements_used,
+        sizeof (tree),
+        compare_blocks);
+
   /* Perform postincrements before actually calling the function.  */
   emit_queue ();
 
@@ -1292,6 +1336,25 @@ expand_inline_function (fndecl, parms, target, ignore, type,
                     region.  */
                  NOTE_EH_HANDLER (copy) = CODE_LABEL_NUMBER (label);
                }
+             else if (copy
+                      && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG
+                          || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END)
+                      && NOTE_BLOCK (insn))
+               {
+                 tree *mapped_block_p;
+
+                 mapped_block_p
+                   = (tree *) bsearch (NOTE_BLOCK (insn), 
+                                       &VARRAY_TREE (map->block_map, 0),
+                                       map->block_map->elements_used,
+                                       sizeof (tree),
+                                       find_block);
+                 
+                 if (!mapped_block_p)
+                   abort ();
+                 else
+                   NOTE_BLOCK (copy) = *mapped_block_p;
+               }
            }
          else
            copy = 0;
@@ -1332,27 +1395,18 @@ expand_inline_function (fndecl, parms, target, ignore, type,
   if (inl_f->calls_alloca)
     emit_stack_restore (SAVE_BLOCK, stack_save, NULL_RTX);
 
-  /* Make copies of the decls of the symbols in the inline function, so that
-     the copies of the variables get declared in the current function.  Set
-     up things so that lookup_static_chain knows that to interpret registers
-     in SAVE_EXPRs for TYPE_SIZEs as local.  */
-
-  inline_function_decl = fndecl;
-  integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
-  block = integrate_decl_tree (inl_f->original_decl_initial, map);
-  BLOCK_ABSTRACT_ORIGIN (block) = (DECL_ABSTRACT_ORIGIN (fndecl) == NULL
-                                  ? fndecl : DECL_ABSTRACT_ORIGIN (fndecl));
-  inline_function_decl = 0;
-
-  if (current_function->x_whole_function_mode_p)
-    /* Insert the block into the already existing block-tree.  */
-    retrofit_block (block, map->insns_at_start);
-  else
+  if (!current_function->x_whole_function_mode_p)
     /* In statement-at-a-time mode, we just tell the front-end to add
        this block to the list of blocks at this binding level.  We
        can't do it the way it's done for function-at-a-time mode the
        superblocks have not been created yet.  */
     insert_block (block);
+  else
+    {
+      BLOCK_CHAIN (block) 
+       = BLOCK_CHAIN (DECL_INITIAL (current_function_decl));
+      BLOCK_CHAIN (DECL_INITIAL (current_function_decl)) = block;
+    }
 
   /* End the scope containing the copied formal parameter variables
      and copied LABEL_DECLs.  We pass NULL_TREE for the variables list
@@ -1392,6 +1446,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
     free (real_label_map);
   VARRAY_FREE (map->const_equiv_varray);
   free (map->reg_map);
+  VARRAY_FREE (map->block_map);
   free (map->insn_map);
   free (map);
   free (arg_vals);
@@ -1451,6 +1506,7 @@ integrate_decl_tree (let, map)
   tree *next;
 
   new_block = make_node (BLOCK);
+  VARRAY_PUSH_TREE (map->block_map, new_block);
   next = &BLOCK_VARS (new_block);
 
   for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
index 88bcd53960b2040edc0b82a284b6d54e58f30f3f..4cc75fabbdce62a8b322a88e9e8c7c3b6a8a3c27 100644 (file)
@@ -42,6 +42,8 @@ struct inline_remap
   union tree_node *fndecl;
   /* Place to put insns needed at start of function.  */
   rtx insns_at_start;
+  /* Mapping from old BLOCKs to new BLOCKs.  */
+  varray_type block_map;
   /* Mapping from old registers to new registers.
      It is allocated and deallocated in `expand_inline_function' */
   rtx *reg_map;
index e94c1e8a87adb807b007848ab027a331204c6783..826295ba5bbd48a1df26e34b2a0c7473d0838d64 100644 (file)
@@ -1024,23 +1024,30 @@ expand_fixup (tree_label, rtl_label, last_insn)
         register rtx original_before_jump
           = last_insn ? last_insn : get_last_insn ();
        rtx start;
+       rtx end;
        tree block;
 
        block = make_node (BLOCK);
        TREE_USED (block) = 1;
 
-       if (current_function->x_whole_function_mode_p)
+       if (!current_function->x_whole_function_mode_p)
+         insert_block (block);
+       else
          {
-           find_loop_tree_blocks ();
-           retrofit_block (block, original_before_jump);
+           BLOCK_CHAIN (block) 
+             = BLOCK_CHAIN (DECL_INITIAL (current_function_decl));
+           BLOCK_CHAIN (DECL_INITIAL (current_function_decl))
+             = block;
          }
-       else
-         insert_block (block);
 
         start_sequence ();
         start = emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG);
+       if (current_function->x_whole_function_mode_p)
+         NOTE_BLOCK (start) = block;
        fixup->before_jump = emit_note (NULL_PTR, NOTE_INSN_DELETED);
-       emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
+       end = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
+       if (current_function->x_whole_function_mode_p)
+         NOTE_BLOCK (end) = block;
         fixup->context = block;
         end_sequence ();
         emit_insns_after (start, original_before_jump);
@@ -3198,20 +3205,36 @@ tail_recursion_args (actuals, formals)
         will not create corresponding BLOCK nodes.  (There should be
         a one-to-one correspondence between NOTE_INSN_BLOCK_BEG notes
         and BLOCKs.)  If this flag is set, MARK_ENDS should be zero
-        when expand_end_bindings is called.  */
+        when expand_end_bindings is called.  
+
+    If we are creating a NOTE_INSN_BLOCK_BEG note, a BLOCK may
+    optionally be supplied.  If so, it becomes the NOTE_BLOCK for the
+    note.  */
 
 void
-expand_start_bindings (flags)
+expand_start_bindings_and_block (flags, block)
      int flags;
+     tree block;
 {
   struct nesting *thisblock = ALLOC_NESTING ();
   rtx note;
   int exit_flag = ((flags & 1) != 0);
   int block_flag = ((flags & 2) == 0);
+  
+  /* If a BLOCK is supplied, then the caller should be requesting a
+     NOTE_INSN_BLOCK_BEG note.  */
+  if (!block_flag && block)
+    abort ();
 
-  note = emit_note (NULL_PTR, 
-                   block_flag ? NOTE_INSN_BLOCK_BEG : NOTE_INSN_DELETED);
-
+  /* Create a note to mark the beginning of the block.  */
+  if (block_flag)
+    {
+      note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG);
+      NOTE_BLOCK (note) = block;
+    }
+  else
+    note = emit_note (NULL_PTR, NOTE_INSN_DELETED);
+    
   /* Make an entry on block_stack for the block we are entering.  */
 
   thisblock->next = block_stack;
@@ -3659,7 +3682,10 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
      just going out of scope, so they are in scope for their cleanups.  */
 
   if (mark_ends)
-    emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
+    {
+      rtx note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
+      NOTE_BLOCK (note) = NOTE_BLOCK (thisblock->data.block.first_insn);
+    }
   else
     /* Get rid of the beginning-mark if we don't make an end-mark.  */
     NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED;
index a880812daf8d6006383504a091302b217c85d7a6..892149fc4af490467b81be3b85d0d5cdcefb3880 100644 (file)
@@ -3605,6 +3605,14 @@ rest_of_compilation (decl)
      collector to reclaim the memory used by the notes.  */
   remove_unncessary_notes ();
 
+  /* In function-at-a-time mode, we do not attempt to keep the BLOCK
+     tree in sensible shape.  So, we just recalculate it here.  */
+  if (current_function->x_whole_function_mode_p)
+    {
+      find_loop_tree_blocks ();
+      unroll_block_trees ();
+    }
+
   /* If we are reconsidering an inline function
      at the end of compilation, skip the stuff for making it inline.  */
 
index 4108042114c338e0be663dfc6daca7ab9c378438..e802e0ccc041719901988ec0be76c1cf37840e24 100644 (file)
@@ -2100,7 +2100,9 @@ extern int expand_exit_something          PROTO((void));
 extern void expand_null_return                 PROTO((void));
 extern void expand_return                      PROTO((tree));
 extern int optimize_tail_recursion             PROTO((tree, struct rtx_def *));
-extern void expand_start_bindings              PROTO((int));
+extern void expand_start_bindings_and_block     PROTO((int, tree));
+#define expand_start_bindings(flags) \
+  expand_start_bindings_and_block(flags, NULL_TREE)
 extern void expand_end_bindings                        PROTO((tree, int, int));
 extern void warn_about_unused_variables         PROTO((tree));
 extern void start_cleanup_deferral             PROTO((void));
This page took 0.124344 seconds and 5 git commands to generate.