aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-09-17 22:18:59 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-09-17 22:18:59 +0000
commite6fd097efca2e3f76d3fe51c55cd124998b7fd42 (patch)
tree746da641a670a45baec442090a6d5de50aee6389 /gcc/function.c
parentba7166773bd7a4d1e0da5bad0a61c20fac3bef78 (diff)
downloadgcc-e6fd097efca2e3f76d3fe51c55cd124998b7fd42.zip
gcc-e6fd097efca2e3f76d3fe51c55cd124998b7fd42.tar.gz
gcc-e6fd097efca2e3f76d3fe51c55cd124998b7fd42.tar.bz2
functiion.h (struct function): Add x_whole_function_mode_p.
* 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
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 81a1ef1..ffbcd01 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5381,6 +5381,49 @@ round_trampoline_addr (tramp)
return tramp;
}
+/* 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);