diff options
author | Mark Mitchell <mark@codesourcery.com> | 1999-09-17 22:18:59 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-09-17 22:18:59 +0000 |
commit | e6fd097efca2e3f76d3fe51c55cd124998b7fd42 (patch) | |
tree | 746da641a670a45baec442090a6d5de50aee6389 /gcc/function.c | |
parent | ba7166773bd7a4d1e0da5bad0a61c20fac3bef78 (diff) | |
download | gcc-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.c | 64 |
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); |