* integrate.c (get_label_from_map): New function.
(expand_inline_function): Use it. Initialize the label_map to
NULL_RTX instead of gen_label_rtx.
(copy_rtx_and_substitute): Use get_label_from_map.
* integrate.h (get_label_from_map): New function.
(set_label_from_map): New macro.
* unroll.c (unroll_loop): Use them.
(copy_loop_body): Ditto.
* toplev.c (rest_of_compilation): Don't call save_for_inline_copy
if all we're doing is dealing with -Wreturn-type.
From-SVN: r17795
+Mon Feb 9 01:15:08 1998 Mark Mitchell <mmitchell@usa.net>
+
+ * integrate.c (get_label_from_map): New function.
+ (expand_inline_function): Use it. Initialize the label_map to
+ NULL_RTX instead of gen_label_rtx.
+ (copy_rtx_and_substitute): Use get_label_from_map.
+ * integrate.h (get_label_from_map): New function.
+ (set_label_from_map): New macro.
+ * unroll.c (unroll_loop): Use them.
+ (copy_loop_body): Ditto.
+
+ * toplev.c (rest_of_compilation): Don't call save_for_inline_copy
+ if all we're doing is dealing with -Wreturn-type.
+
Mon Feb 9 01:07:41 1998 Jeffrey A Law (law@cygnus.com)
* i386/x-sco5 (CC): Remove trailing whitespace.
void set_decl_abstract_flags PROTO((tree, int));
\f
+/* Returns the Ith entry in the label_map contained in MAP. If the
+ Ith entry has not yet been set, it is assumed to be a fresh label.
+ Essentially, we use this function to perform a lazy initialization
+ of label_map, thereby avoiding huge memory explosions when the
+ label_map gets very large. */
+rtx
+get_label_from_map (map, i)
+ struct inline_remap* map;
+ int i;
+{
+ rtx x = map->label_map[i];
+
+ if (x == NULL_RTX)
+ x = map->label_map[i] = gen_label_rtx();
+
+ return x;
+}
+
+
/* Zero if the current function (whose FUNCTION_DECL is FNDECL)
is safe and reasonable to integrate into other functions.
Nonzero means value is a warning message with a single %s
/* Make new label equivalences for the labels in the called function. */
for (i = min_labelno; i < max_labelno; i++)
- map->label_map[i] = gen_label_rtx ();
+ map->label_map[i] = NULL_RTX;
/* Perform postincrements before actually calling the function. */
emit_queue ();
break;
case CODE_LABEL:
- copy = emit_label (map->label_map[CODE_LABEL_NUMBER (insn)]);
+ copy =
+ emit_label (get_label_from_map(map,
+ CODE_LABEL_NUMBER (insn)));
LABEL_NAME (copy) = LABEL_NAME (insn);
map->const_age++;
break;
if (copy && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG
|| NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_END))
{
- rtx label = map->label_map[NOTE_BLOCK_NUMBER (copy)];
+ rtx label =
+ get_label_from_map (map, NOTE_BLOCK_NUMBER (copy));
/* We have to forward these both to match the new exception
region. */
return gen_rtx (code, VOIDmode, copy);
case CODE_LABEL:
- LABEL_PRESERVE_P (map->label_map[CODE_LABEL_NUMBER (orig)])
+ LABEL_PRESERVE_P (get_label_from_map (map, CODE_LABEL_NUMBER (orig)))
= LABEL_PRESERVE_P (orig);
- return map->label_map[CODE_LABEL_NUMBER (orig)];
+ return get_label_from_map (map, CODE_LABEL_NUMBER (orig));
case LABEL_REF:
copy = gen_rtx (LABEL_REF, mode,
LABEL_REF_NONLOCAL_P (orig) ? XEXP (orig, 0)
- : map->label_map[CODE_LABEL_NUMBER (XEXP (orig, 0))]);
+ : get_label_from_map (map,
+ CODE_LABEL_NUMBER (XEXP (orig, 0))));
LABEL_OUTSIDE_LOOP_P (copy) = LABEL_OUTSIDE_LOOP_P (orig);
/* The fact that this label was previously nonlocal does not mean
extern void mark_stores PROTO((rtx, rtx));
+/* Return the label indicated. */
+extern rtx get_label_from_map PROTO((struct inline_remap *, int));
+
+/* Set the label indicated. */
+#define set_label_in_map(map, i, x) \
+ ((map)->label_map[i] = (x))
+
/* Unfortunately, we need a global copy of const_equiv map for communication
with a function called from note_stores. Be *very* careful that this
is used properly in the presence of recursion. */
{
DECL_DEFER_OUTPUT (decl) = 1;
- /* If -Wreturn-type, we have to do a bit of compilation. */
- if (! warn_return_type)
+ /* If -Wreturn-type, we have to do a bit of compilation.
+ However, if we just fall through we will call
+ save_for_inline_copying() which results in excessive
+ memory use. Instead, we just want to call
+ jump_optimize() to figure out whether or not we can fall
+ off the end of the function; we do the minimum amount of
+ work necessary to make that safe. And, we set optimize
+ to zero to keep jump_optimize from working too hard. */
+ if (warn_return_type)
{
+ int saved_optimize = optimize;
+ optimize = 0;
+ find_exception_handler_labels ();
+ jump_optimize (get_insns(), 0, 0, 0);
+ optimize = saved_optimize;
+ }
+
#ifdef DWARF_DEBUGGING_INFO
- /* Generate the DWARF info for the "abstract" instance
- of a function which we may later generate inlined and/or
- out-of-line instances of. */
- if (write_symbols == DWARF_DEBUG)
- {
- set_decl_abstract_flags (decl, 1);
- TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
- set_decl_abstract_flags (decl, 0);
- }
+ /* Generate the DWARF info for the "abstract" instance
+ of a function which we may later generate inlined and/or
+ out-of-line instances of. */
+ if (write_symbols == DWARF_DEBUG)
+ {
+ set_decl_abstract_flags (decl, 1);
+ TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
+ set_decl_abstract_flags (decl, 0);
+ }
#endif
#ifdef DWARF2_DEBUGGING_INFO
- /* Generate the DWARF2 info for the "abstract" instance
- of a function which we may later generate inlined and/or
- out-of-line instances of. */
- if (write_symbols == DWARF2_DEBUG)
- {
- set_decl_abstract_flags (decl, 1);
- TIMEVAR (symout_time, dwarf2out_decl (decl));
- set_decl_abstract_flags (decl, 0);
- }
-#endif
- TIMEVAR (integration_time, save_for_inline_nocopy (decl));
- RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlineable;
- goto exit_rest_of_compilation;
+ /* Generate the DWARF2 info for the "abstract" instance
+ of a function which we may later generate inlined and/or
+ out-of-line instances of. */
+ if (write_symbols == DWARF2_DEBUG)
+ {
+ set_decl_abstract_flags (decl, 1);
+ TIMEVAR (symout_time, dwarf2out_decl (decl));
+ set_decl_abstract_flags (decl, 0);
}
+#endif
+ TIMEVAR (integration_time, save_for_inline_nocopy (decl));
+ RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
+ goto exit_rest_of_compilation;
}
/* If we have to compile the function now, save its rtl and subdecls
else if (GET_CODE (insn) == JUMP_INSN)
{
if (JUMP_LABEL (insn))
- map->label_map[CODE_LABEL_NUMBER (JUMP_LABEL (insn))]
- = JUMP_LABEL (insn);
+ set_label_in_map (map,
+ CODE_LABEL_NUMBER (JUMP_LABEL (insn)),
+ JUMP_LABEL (insn));
else if (GET_CODE (PATTERN (insn)) == ADDR_VEC
|| GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
{
for (i = 0; i < len; i++)
{
label = XEXP (XVECEXP (pat, diff_vec_p, i), 0);
- map->label_map[CODE_LABEL_NUMBER (label)] = label;
+ set_label_in_map (map,
+ CODE_LABEL_NUMBER (label),
+ label);
}
}
}
for (j = 0; j < max_labelno; j++)
if (local_label[j])
- map->label_map[j] = gen_label_rtx ();
+ set_label_in_map (map, j, gen_label_rtx ());
for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
if (local_regno[j])
for (j = 0; j < max_labelno; j++)
if (local_label[j])
- map->label_map[j] = gen_label_rtx ();
+ set_label_in_map (map, j, gen_label_rtx ());
for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
if (local_regno[j])
insn = PREV_INSN (copy_start);
pattern = PATTERN (insn);
- tem = map->label_map[CODE_LABEL_NUMBER
- (XEXP (SET_SRC (pattern), 0))];
+ tem = get_label_from_map (map,
+ CODE_LABEL_NUMBER
+ (XEXP (SET_SRC (pattern), 0)));
SET_SRC (pattern) = gen_rtx (LABEL_REF, VOIDmode, tem);
/* Set the jump label so that it can be used by later loop unrolling
if (! last_iteration)
{
final_label = gen_label_rtx ();
- map->label_map[CODE_LABEL_NUMBER (start_label)] = final_label;
+ set_label_in_map (map, CODE_LABEL_NUMBER (start_label),
+ final_label);
}
else
- map->label_map[CODE_LABEL_NUMBER (start_label)] = start_label;
+ set_label_in_map (map, CODE_LABEL_NUMBER (start_label), start_label);
start_sequence ();
if (invert_exp (pattern, copy))
{
if (! redirect_exp (&pattern,
- map->label_map[CODE_LABEL_NUMBER
- (JUMP_LABEL (insn))],
+ get_label_from_map (map,
+ CODE_LABEL_NUMBER
+ (JUMP_LABEL (insn))),
exit_label, copy))
abort ();
}
emit_label_after (lab, jmp);
LABEL_NUSES (lab) = 0;
if (! redirect_exp (&pattern,
- map->label_map[CODE_LABEL_NUMBER
- (JUMP_LABEL (insn))],
+ get_label_from_map (map,
+ CODE_LABEL_NUMBER
+ (JUMP_LABEL (insn))),
lab, copy))
abort ();
}
for a switch statement. This label must have been mapped,
so just use the label_map to get the new jump label. */
JUMP_LABEL (copy)
- = map->label_map[CODE_LABEL_NUMBER (JUMP_LABEL (insn))];
+ = get_label_from_map (map,
+ CODE_LABEL_NUMBER (JUMP_LABEL (insn)));
}
/* If this is a non-local jump, then must increase the label
if (insn != start_label)
{
- copy = emit_label (map->label_map[CODE_LABEL_NUMBER (insn)]);
+ copy = emit_label (get_label_from_map (map,
+ CODE_LABEL_NUMBER (insn)));
map->const_age++;
}
break;