summaryrefslogtreecommitdiff
path: root/gcc/integrate.c
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-12-16 17:50:29 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-12-16 17:50:29 +0000
commit89689e23d8f4b3d0647da42364b9d943cb3ba91a (patch)
tree0e496457c98d2aabb71fdf3add8cb1bb884dc210 /gcc/integrate.c
parentf27284b4420df797f8363d4f9218011a5424c9a5 (diff)
downloadgcc-89689e23d8f4b3d0647da42364b9d943cb3ba91a.tar.gz
* Makefile.in (INTREGRATE_H): Rename to INTEGRATE_H.
* function.c (insert_block_after_note): Remove. (retrofit_block): Likewise. (identify_blocks): Fix indentation. (reorder_blocks): Don't NULL out NOTE_SOURCE_FILE for a NOTE_INSN_BLOCK_BEG or NOTE_INSN_BLOCK_END. * function.h (insert_block_after_note): Remove prototype. (retrofit_block): Likewise. * integrate.c (expand_inline_function): Don't call find_loop_tree_blocks. Use expand_start_bindings_and_block, not just expand_start_bindings. Use the block_map to remap old NOTE_BLOCKs to new ones. (integrate_decl_tree): Keep track of remapped blocks. * integrate.h (struct inline_remap): Add block_map. * stmt.c (expand_fixup): Don't try to retrofit_blocks. Just set NOTE_BLOCK on the notes. (expand_start_bindings): Rename to ... (expand_start_bindings_and_block): Add parameter. Set NOTE_BLOCK. (expand_end_bindings): Set NOTE_BLOCK. * toplev.c (rest_of_compilation): In function-at-a-time-mode, reconstruct the BLOCK tree. * tree.h (expand_start_bindings): Macroize. Call ... (expand_start_bindings_and_block): New function. * optimize.c (struct inline_data): Remove scope_stmt. (remap_block): Don't use insert_block_after_note. Don't update scope_stmt. (expand_call_inline): Don't update scope_stmt. (optimize_function): Don't initialize scope_stmt. * semantics.c (expand_stmt): Set NOTE_BLOCK for newly emitted NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END notes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30982 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/integrate.c')
-rw-r--r--gcc/integrate.c106
1 files changed, 81 insertions, 25 deletions
diff --git a/gcc/integrate.c b/gcc/integrate.c
index f8253095872..c50c1d4923c 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -78,6 +78,8 @@ static void process_reg_param PROTO((struct inline_remap *, rtx,
void set_decl_abstract_flags PROTO((tree, int));
static rtx expand_inline_function_eh_labelmap PROTO((rtx));
static void mark_stores PROTO((rtx, rtx, void *));
+static int compare_blocks PROTO((const PTR, const PTR));
+static int find_block PROTO((const PTR, const PTR));
/* The maximum number of instructions accepted for inlining a
function. Increasing values mean more agressive inlining.
@@ -505,6 +507,35 @@ expand_inline_function_eh_labelmap (label)
return get_label_from_map (eif_eh_map, index);
}
+/* Compare two BLOCKs for qsort. The key we sort on is the
+ BLOCK_ABSTRACT_ORIGIN of the blocks. */
+
+static int
+compare_blocks (v1, v2)
+ const PTR v1;
+ const PTR v2;
+{
+ tree b1 = *((tree *) v1);
+ tree b2 = *((tree *) v2);
+
+ return ((char *) BLOCK_ABSTRACT_ORIGIN (b1)
+ - (char *) BLOCK_ABSTRACT_ORIGIN (b2));
+}
+
+/* Compare two BLOCKs for bsearch. The first pointer corresponds to
+ an original block; the second to a remapped equivalent. */
+
+static int
+find_block (v1, v2)
+ const PTR v1;
+ const PTR v2;
+{
+ tree b1 = (tree) v1;
+ tree b2 = *((tree *) v2);
+
+ return ((char *) b1 - (char *) BLOCK_ABSTRACT_ORIGIN (b2));
+}
+
/* Integrate the procedure defined by FNDECL. Note that this function
may wind up calling itself. Since the static variables are not
reentrant, we do not assign them until after the possibility
@@ -687,6 +718,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
map = (struct inline_remap *) xmalloc (sizeof (struct inline_remap));
map->fndecl = fndecl;
+ VARRAY_TREE_INIT (map->block_map, 10, "block_map");
map->reg_map = (rtx *) xcalloc (max_regno, sizeof (rtx));
/* We used to use alloca here, but the size of what it would try to
@@ -757,11 +789,6 @@ 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
@@ -1006,15 +1033,32 @@ expand_inline_function (fndecl, parms, target, ignore, type,
else
abort ();
- /* Make a fresh binding contour that we can easily remove. Do this after
- expanding our arguments so cleanups are properly scoped. */
- expand_start_bindings (0);
-
/* Initialize label_map. get_label_from_map will actually make
the labels. */
bzero ((char *) &map->label_map [min_labelno],
(max_labelno - min_labelno) * sizeof (rtx));
+ /* Make copies of the decls of the symbols in the inline function, so that
+ the copies of the variables get declared in the current function. Set
+ up things so that lookup_static_chain knows that to interpret registers
+ in SAVE_EXPRs for TYPE_SIZEs as local. */
+ inline_function_decl = fndecl;
+ integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
+ block = integrate_decl_tree (inl_f->original_decl_initial, map);
+ BLOCK_ABSTRACT_ORIGIN (block) = DECL_ORIGIN (fndecl);
+ inline_function_decl = 0;
+
+ /* Make a fresh binding contour that we can easily remove. Do this after
+ expanding our arguments so cleanups are properly scoped. */
+ expand_start_bindings_and_block (0, block);
+
+ /* Sort the block-map so that it will be easy to find remapped
+ blocks later. */
+ qsort (&VARRAY_TREE (map->block_map, 0),
+ map->block_map->elements_used,
+ sizeof (tree),
+ compare_blocks);
+
/* Perform postincrements before actually calling the function. */
emit_queue ();
@@ -1292,6 +1336,25 @@ expand_inline_function (fndecl, parms, target, ignore, type,
region. */
NOTE_EH_HANDLER (copy) = CODE_LABEL_NUMBER (label);
}
+ else if (copy
+ && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG
+ || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END)
+ && NOTE_BLOCK (insn))
+ {
+ tree *mapped_block_p;
+
+ mapped_block_p
+ = (tree *) bsearch (NOTE_BLOCK (insn),
+ &VARRAY_TREE (map->block_map, 0),
+ map->block_map->elements_used,
+ sizeof (tree),
+ find_block);
+
+ if (!mapped_block_p)
+ abort ();
+ else
+ NOTE_BLOCK (copy) = *mapped_block_p;
+ }
}
else
copy = 0;
@@ -1332,27 +1395,18 @@ expand_inline_function (fndecl, parms, target, ignore, type,
if (inl_f->calls_alloca)
emit_stack_restore (SAVE_BLOCK, stack_save, NULL_RTX);
- /* Make copies of the decls of the symbols in the inline function, so that
- the copies of the variables get declared in the current function. Set
- up things so that lookup_static_chain knows that to interpret registers
- in SAVE_EXPRs for TYPE_SIZEs as local. */
-
- inline_function_decl = fndecl;
- integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
- block = integrate_decl_tree (inl_f->original_decl_initial, map);
- BLOCK_ABSTRACT_ORIGIN (block) = (DECL_ABSTRACT_ORIGIN (fndecl) == NULL
- ? fndecl : DECL_ABSTRACT_ORIGIN (fndecl));
- inline_function_decl = 0;
-
- 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
+ if (!current_function->x_whole_function_mode_p)
/* 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);
+ else
+ {
+ BLOCK_CHAIN (block)
+ = BLOCK_CHAIN (DECL_INITIAL (current_function_decl));
+ BLOCK_CHAIN (DECL_INITIAL (current_function_decl)) = block;
+ }
/* End the scope containing the copied formal parameter variables
and copied LABEL_DECLs. We pass NULL_TREE for the variables list
@@ -1392,6 +1446,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
free (real_label_map);
VARRAY_FREE (map->const_equiv_varray);
free (map->reg_map);
+ VARRAY_FREE (map->block_map);
free (map->insn_map);
free (map);
free (arg_vals);
@@ -1451,6 +1506,7 @@ integrate_decl_tree (let, map)
tree *next;
new_block = make_node (BLOCK);
+ VARRAY_PUSH_TREE (map->block_map, new_block);
next = &BLOCK_VARS (new_block);
for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))