/* Emit RTL for the GCC expander.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of GCC.
#define first_label_num (cfun->emit->x_first_label_num)
static rtx make_call_insn_raw (rtx);
-static rtx find_line_note (rtx);
static rtx change_address_1 (rtx, enum machine_mode, rtx, int);
static void unshare_all_decls (tree);
static void reset_used_decls (tree);
index, low_bound);
off_tree = size_binop (PLUS_EXPR,
- size_binop (MULT_EXPR, convert (sizetype,
- index),
+ size_binop (MULT_EXPR,
+ fold_convert (sizetype,
+ index),
unit_size),
off_tree);
t2 = TREE_OPERAND (t2, 0);
unshare_all_rtl_1 (cfun->decl, insn);
}
-void
+unsigned int
unshare_all_rtl (void)
{
unshare_all_rtl_1 (current_function_decl, get_insns ());
+ return 0;
}
struct tree_opt_pass pass_unshare_all_rtl =
reset_used_flags (PATTERN (p));
reset_used_flags (REG_NOTES (p));
reset_used_flags (LOG_LINKS (p));
+ if (GET_CODE (PATTERN (p)) == SEQUENCE)
+ {
+ int i;
+ rtx q, sequence = PATTERN (p);
+
+ for (i = 0; i < XVECLEN (sequence, 0); i++)
+ {
+ q = XVECEXP (sequence, 0, i);
+ gcc_assert (INSN_P (q));
+ reset_used_flags (PATTERN (q));
+ reset_used_flags (REG_NOTES (q));
+ reset_used_flags (LOG_LINKS (q));
+ }
+ }
}
for (p = get_insns (); p; p = NEXT_INSN (p))
}
}
-/* Return the line note insn preceding INSN. */
-
-static rtx
-find_line_note (rtx insn)
-{
- if (no_line_numbers)
- return 0;
-
- for (; insn; insn = PREV_INSN (insn))
- if (NOTE_P (insn)
- && NOTE_LINE_NUMBER (insn) >= 0)
- break;
-
- return insn;
-}
-
-/* Remove unnecessary notes from the instruction stream. */
-
-void
-remove_unnecessary_notes (void)
-{
- rtx eh_stack = NULL_RTX;
- rtx insn;
- rtx next;
- rtx tmp;
-
- /* We must not remove the first instruction in the function because
- the compiler depends on the first instruction being a note. */
- for (insn = NEXT_INSN (get_insns ()); insn; insn = next)
- {
- /* Remember what's next. */
- next = NEXT_INSN (insn);
-
- /* We're only interested in notes. */
- if (!NOTE_P (insn))
- continue;
-
- switch (NOTE_LINE_NUMBER (insn))
- {
- case NOTE_INSN_DELETED:
- remove_insn (insn);
- break;
-
- case NOTE_INSN_EH_REGION_BEG:
- eh_stack = alloc_INSN_LIST (insn, eh_stack);
- break;
-
- case NOTE_INSN_EH_REGION_END:
- /* Too many end notes. */
- gcc_assert (eh_stack);
- /* Mismatched nesting. */
- gcc_assert (NOTE_EH_HANDLER (XEXP (eh_stack, 0))
- == NOTE_EH_HANDLER (insn));
- tmp = eh_stack;
- eh_stack = XEXP (eh_stack, 1);
- free_INSN_LIST_node (tmp);
- break;
-
- case NOTE_INSN_BLOCK_BEG:
- case NOTE_INSN_BLOCK_END:
- /* BLOCK_END and BLOCK_BEG notes only exist in the `final' pass. */
- gcc_unreachable ();
-
- default:
- break;
- }
- }
-
- /* Too many EH_REGION_BEG notes. */
- gcc_assert (!eh_stack);
-}
-
-struct tree_opt_pass pass_remove_unnecessary_notes =
-{
- "eunotes", /* name */
- NULL, /* gate */
- remove_unnecessary_notes, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- 0, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_dump_func, /* todo_flags_finish */
- 0 /* letter */
-};
-
\f
/* Emit insn(s) of given code and pattern
at a specified place within the doubly-linked list.
return last;
}
-/* Similar to emit_insn_after, except that line notes are to be inserted so
- as to act as if this insn were at FROM. */
-
-void
-emit_insn_after_with_line_notes (rtx x, rtx after, rtx from)
-{
- rtx from_line = find_line_note (from);
- rtx after_line = find_line_note (after);
- rtx insn = emit_insn_after (x, after);
-
- if (from_line)
- emit_note_copy_after (from_line, after);
-
- if (after_line)
- emit_note_copy_after (after_line, insn);
-}
/* Make an insn of code JUMP_INSN with body X
and output it after the insn AFTER. */
add_insn_after (note, after);
return note;
}
-
-/* Emit a copy of note ORIG after the insn AFTER. */
-
-rtx
-emit_note_copy_after (rtx orig, rtx after)
-{
- rtx note;
-
- if (NOTE_LINE_NUMBER (orig) >= 0 && no_line_numbers)
- {
- cur_insn_uid++;
- return 0;
- }
-
- note = rtx_alloc (NOTE);
- INSN_UID (note) = cur_insn_uid++;
- NOTE_LINE_NUMBER (note) = NOTE_LINE_NUMBER (orig);
- NOTE_DATA (note) = NOTE_DATA (orig);
- BLOCK_FOR_INSN (note) = NULL;
- add_insn_after (note, after);
- return note;
-}
\f
/* Like emit_insn_after_noloc, but set INSN_LOCATOR according to SCOPE. */
rtx
{
rtx note;
- if (NOTE_LINE_NUMBER (orig) >= 0 && no_line_numbers)
- {
- cur_insn_uid++;
- return NULL_RTX;
- }
-
note = rtx_alloc (NOTE);
INSN_UID (note) = cur_insn_uid++;
{
if (GET_CODE (link) == EXPR_LIST)
REG_NOTES (new)
- = copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
- XEXP (link, 0),
- REG_NOTES (new)));
+ = gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
+ copy_insn_1 (XEXP (link, 0)), REG_NOTES (new));
else
REG_NOTES (new)
- = copy_insn_1 (gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
- XEXP (link, 0),
- REG_NOTES (new)));
+ = gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
+ XEXP (link, 0), REG_NOTES (new));
}
/* Fix the libcall sequences. */