functiion.h (struct function): Add x_whole_function_mode_p.
authorMark Mitchell <mark@codesourcery.com>
Fri, 17 Sep 1999 22:18:59 +0000 (22:18 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 17 Sep 1999 22:18:59 +0000 (22:18 +0000)
* 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.

From-SVN: r29487

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

index 3a9d61aeefae0c025f1d73cbb9225e1796bbcf9b..1f0d6e67bbb716ebed85798e0dfff5b0c254df47 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 dd4fa3dc6cddf25518d61143f24ceb59723d5c5f..428f4f5d2553e181dfa75572fde8c1aa712748c6 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 81a1ef16170d9ec4b183e5a88dd0d868a9491808..ffbcd0185c4b14cc00ae1f4c81843a7dd013e300 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 0d70b7d6aed662f3ee65065ead1756958f5d082f..80053d20c3076a292f8400c21e7eccd7c2859a02 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 3c278767ce021719f2ea51e62819377499865fce..e1b7990f21aee37b5345e46dec86dac31ce1ce1e 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 51110b8a78ddb475ecbf80e53df32f42a7cd3f19..5a9a25e11800079c39ecffe511c50c00f15325a2 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);
       }