OSDN Git Service

* functiion.h (struct function): Add x_whole_function_mode_p.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Sep 1999 22:18:59 +0000 (22:18 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Sep 1999 22:18:59 +0000 (22:18 +0000)
(retrofit_block): Declare.
* function.c (retrofit_block): New function.
(identify_blocks): Add assertions.  Allow an incomplete set of
block notes if we're still generating code for the function.
* integrate.c: Include loop.h.
(expand_inline_function): Call find_loop_tree_blocks to map block
notes to blocks when in whole-function mode.  Use retrofit_block
to insert new BLOCKs for the inlined function, rather than
insert_block.
* stmt.c (expand_fixup): Likewise.  Don't use pushlevel/polevel.
* Makefile.in (integrate.o): Depend on loop.h.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29487 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/function.c
gcc/function.h
gcc/integrate.c
gcc/stmt.c

index 3a9d61a..1f0d6e6 100644 (file)
@@ -1,3 +1,18 @@
+Fri Sep 17 15:19:01 1999  Mark Mitchell  <mark@codesourcery.com>
+
+       * functiion.h (struct function): Add x_whole_function_mode_p.
+       (retrofit_block): Declare.
+       * function.c (retrofit_block): New function.
+       (identify_blocks): Add assertions.  Allow an incomplete set of
+       block notes if we're still generating code for the function.
+       * integrate.c: Include loop.h.
+       (expand_inline_function): Call find_loop_tree_blocks to map block
+       notes to blocks when in whole-function mode.  Use retrofit_block
+       to insert new BLOCKs for the inlined function, rather than
+       insert_block.
+       * stmt.c (expand_fixup): Likewise.  Don't use pushlevel/polevel.
+       * Makefile.in (integrate.o): Depend on loop.h.
+
 Fri Sep 17 15:11:20 1999  Mark Mitchell  <mark@codesourcery.com>
 
        * tree.h (warn_about_unused_variables): Declare.
index dd4fa3d..428f4f5 100644 (file)
@@ -1519,7 +1519,7 @@ emit-rtl.o : emit-rtl.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
 real.o : real.c $(CONFIG_H) system.h $(TREE_H) toplev.h
 integrate.o : integrate.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
    integrate.h insn-flags.h insn-config.h $(EXPR_H) real.h $(REGS_H) \
-   intl.h function.h output.h $(RECOG_H) except.h toplev.h
+   intl.h function.h output.h $(RECOG_H) except.h toplev.h loop.h
 jump.o : jump.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
    insn-config.h insn-flags.h $(RECOG_H) $(EXPR_H) real.h except.h function.h \
    toplev.h insn-attr.h
index 81a1ef1..ffbcd01 100644 (file)
@@ -5381,6 +5381,49 @@ round_trampoline_addr (tramp)
   return tramp;
 }
 \f
+/* 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 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
+    {
+      tree superblock;
+
+      if (insn)
+       superblock = NOTE_BLOCK (insn);
+      else
+       superblock = DECL_INITIAL (current_function_decl);
+
+      BLOCK_SUPERCONTEXT (block) = superblock;
+      BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (superblock);
+      BLOCK_SUBBLOCKS (superblock) = block;
+    }
+  else
+    {
+      tree prevblock = NOTE_BLOCK (insn);
+
+      BLOCK_SUPERCONTEXT (block) = BLOCK_SUPERCONTEXT (prevblock);
+      BLOCK_CHAIN (block) = BLOCK_CHAIN (prevblock);
+      BLOCK_CHAIN (prevblock) = block;
+    }
+}
+
 /* 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
@@ -5423,15 +5466,30 @@ identify_blocks (block, insns)
          {
            tree b;
 
+             /* If there are more block notes than BLOCKs, something
+                is badly wrong.  */
+           if (current_block_number == n_blocks)
+             abort ();
+
            b = block_vector[current_block_number++];
            NOTE_BLOCK (insn) = b;
            block_stack[depth++] = b;
          }
-       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
-         NOTE_BLOCK (insn) = block_stack[--depth];
+       else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
+         {
+           if (depth == 0)
+             /* There are more NOTE_INSN_BLOCK_ENDs that
+                NOTE_INSN_BLOCK_BEGs.  Something is badly wrong.  */
+             abort ();
+
+           NOTE_BLOCK (insn) = block_stack[--depth];
+         }
       }
 
-  if (n_blocks != current_block_number)
+  /* In whole-function mode, we might not have seen the whole function
+     yet, so we might not use up all the blocks.  */
+  if (n_blocks != current_block_number 
+      && !current_function->x_whole_function_mode_p)
     abort ();
 
   free (block_vector);
index 0d70b7d..80053d2 100644 (file)
@@ -293,6 +293,12 @@ struct function
   /* Number of function calls seen so far in current function.  */
   int x_function_call_count;
 
+  /* Nonzero if this function is being processed in function-at-a-time
+     mode.  In other words, if all tree structure for this function,
+     including the BLOCK tree is created, before RTL generation
+     commences.  */
+  int x_whole_function_mode_p;
+
   /* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels
      (labels to which there can be nonlocal gotos from nested functions)
      in this function.  */
@@ -521,6 +527,8 @@ 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 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 3c27876..e1b7990 100644 (file)
@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "toplev.h"
 #include "intl.h"
+#include "loop.h"
 
 #include "obstack.h"
 #define        obstack_chunk_alloc     xmalloc
@@ -74,8 +75,6 @@ static void set_decl_origin_self      PROTO((tree));
 static void set_block_abstract_flags   PROTO((tree, int));
 static void process_reg_param          PROTO((struct inline_remap *, rtx,
                                               rtx));
-
-
 void set_decl_abstract_flags           PROTO((tree, int));
 static tree copy_and_set_decl_abstract_origin PROTO((tree));
 
@@ -742,6 +741,11 @@ 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
@@ -1279,7 +1283,16 @@ expand_inline_function (fndecl, parms, target, ignore, type,
   BLOCK_ABSTRACT_ORIGIN (block) = (DECL_ABSTRACT_ORIGIN (fndecl) == NULL
                                   ? fndecl : DECL_ABSTRACT_ORIGIN (fndecl));
   inline_function_decl = 0;
-  insert_block (block);
+
+  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
+    /* 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);
 
   /* End the scope containing the copied formal parameter variables
      and copied LABEL_DECLs.  We pass NULL_TREE for the variables list
index 51110b8..5a9a25e 100644 (file)
@@ -1016,13 +1016,24 @@ expand_fixup (tree_label, rtl_label, last_insn)
         register rtx original_before_jump
           = last_insn ? last_insn : get_last_insn ();
        rtx start;
+       tree block;
+
+       block = make_node (BLOCK);
+       TREE_USED (block) = 1;
+
+       if (current_function->x_whole_function_mode_p)
+         {
+           find_loop_tree_blocks ();
+           retrofit_block (block, original_before_jump);
+         }
+       else
+         insert_block (block);
 
         start_sequence ();
-        pushlevel (0);
         start = emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG);
        fixup->before_jump = emit_note (NULL_PTR, NOTE_INSN_DELETED);
         last_block_end_note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
-        fixup->context = poplevel (1, 0, 0);  /* Create the BLOCK node now! */
+        fixup->context = block;
         end_sequence ();
         emit_insns_after (start, original_before_jump);
       }