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
This commit is contained in:
Mark Mitchell 1999-09-17 22:18:59 +00:00 committed by Mark Mitchell
parent ba7166773b
commit e6fd097efc
6 changed files with 114 additions and 9 deletions

View 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.

View 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

View File

@ -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);

View 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;

View 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

View 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);
}