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:
parent
ba7166773b
commit
e6fd097efc
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
15
gcc/stmt.c
15
gcc/stmt.c
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user