aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-09-21 14:55:18 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-09-21 12:55:18 +0000
commit53c170316f895dc3dfa7173e69fc43b15b7acb1a (patch)
tree270b09662a6e53b3a40319fd6d71ba88ad553f13 /gcc
parentf2d3c02aa02309b6bd102066f4961451fbcfc1bb (diff)
downloadgcc-53c170316f895dc3dfa7173e69fc43b15b7acb1a.zip
gcc-53c170316f895dc3dfa7173e69fc43b15b7acb1a.tar.gz
gcc-53c170316f895dc3dfa7173e69fc43b15b7acb1a.tar.bz2
basic-block.h (flow_delete_insn, [...]): Kill.
* basic-block.h (flow_delete_insn, flow_delete_insn_chain): Kill. * cfg.c (delete_insn): Rename from ....; use remove_insn; do not remove some labels. (flow_delete_insn): This one. (delete_insn_chain): Rename from ...; do not care labels. (flow_delete_insn_chain): ... this one. (flow_delete_block): Remove the insns one BB has been expunged. (merge_blocks_nomove): Likewise. (try_redirect_by_replacing_jump): Use delete_insn[_chain]; do not care updating BB boundaries. (tidy_fallthru_edge): Likewise. (commit_one_edge_insertion): Likewise. * cfgbuild.c (find_basic_block): Likewise. (find_basic_blocks_1): Likewise. * cfgcleanup.c (merge_blocks_move_predecessor_nojumps): Likewise. (try_crossjump_to_edge): Likewise. (try_optimize_cfg): Likewise. * cse.c (delete_trivially_dead_insns): Likewise. * df.c (df_insn_delete): Likewise. * doloop.c (doloop_modify): Use delete_related_insns. * emit-rtl.c (try_split): Likewise. (remove_insn): Update BB boundaries. * expect.c (connect_post_landing_pads): Use delete_related_insns. * flow.c (delete_dead_jumptables): Use delete_insn[_chain]; do not care updating BB boundaries. (propagate_block_delete_insn): Likewise. (propagate_block_delete_libcall): Likewise. * function.c (delete_handlers): Use delete_related_insns. (thread_prologue_and_epilogue_insns): Likewise. * gcse.c (delete_null_pointer_checks): Use delete_related_insns. * genpeep.c (gen_peephole): Use delete_related_insns. * ifcvt.c (noce_process_if_block): Use delete_insn; do not care updating BB boundaries. (find_cond_trap): Likewise. * integrate.c (save_for_inline): Use delete_related_insns. (copy_insn_list): Likewise. * jump.c (pruge_linie_number_notes): Likewise. (duplicate_loop_exit_test): Likewise. (delete_computation): Likewise. (delete_related_insn): Rename from ...; use delete_insn (delete_insn): ... this one. (redirect_jump): Use delete_related_insns. * loop.c (scan_loop): Likewise. (move_movables): Likewise. (find_and_verify_loops): Likewise. (check_dbra_loop): Likewise. * recog.c (peephole2_optimize): Likewise. * reg-stack.c (delete_insn_for_stacker): Remove. (move_for_stack_reg): Use delete_insn. * regmove.c (combine_stack_adjustments_for_block): Likewise. * reload1.c (delete_address_reloads): Use delete_related_insns. (fixup_abnormal_edges): Use delete_insn. * recog.c (emit_delay_sequence): Use delete_related_insns. (delete_from-delay_slot): Likewise. (delete_scheduled_jump): likewise. (optimize_skip): Likewise. (try_merge_delay_insns): Likewise. (full_simple_delay_slots): Likewise. (fill_slots_from_thread): Likewise. (relax_delay_slots): Likewise. (make_return_insns): Likewise. (dbr_schedule): Likewise. * rtl.h (delete_insn): Rename to delete_related_insns. (delete_insn, delete_insn_chain): New prototypes. * ssa-ccp (sse_fast_dce): Remove deleting of DEF, as it is done by df_insn_delete already. * ssa-dce.c (delete_insn_bb): Use delete_insn. * ssa.c (convert_from_ssa): Use delete_related_insns. * unroll.c (unroll_loop): Likewise. (calculate_giv_inc): Likewise. (copy_loop_body): Likewise. * i386-protos.h (ix86_libcall_value, ix86_function_value, ix86_function_arg_regno_p, ix86_function_arg_boundary, ix86_return_in_memory, ix86_function_value): Declare. * i386.c (x86_64_int_parameter_registers, x86_64_int_return_registers): new static valurables. (x86_64_reg_class): New enum (x86_64_reg_class_name): New array. (classify_argument, examine_argument, construct_container, merge_classes): New static functions. (optimization_options): Enable flag_omit_frame_pointer and disable flag_pcc_struct_return on 64bit. (ix86_libcall_value, ix86_function_value, ix86_function_arg_regno_p, ix86_function_arg_boundary, ix86_return_in_memory, ix86_function_value): New global functions. (init_cumulative_args): Refuse regparm on x86_64, set maybe_vaarg. (function_arg_advance): Handle x86_64 passing conventions. (function_arg): Likewise. * i386.h (FUNCTION_ARG_BOUNDARY): New macro. (RETURN_IN_MEMORY): Move offline. (FUNCTION_VALUE, LIBCALL_VALUE): Likewise. (FUNCTION_VALUE_REGNO_P): New macro. (FUNCTION_ARG_REGNO_P): Move offline. (struct ix86_args): Add maybe_vaarg. * next.h (FUNCTION_VALUE_REGNO_P): Delete. * unix.h (FUNCTION_VALUE_REGNO_P): Delete. From-SVN: r45726
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog100
-rw-r--r--gcc/basic-block.h2
-rw-r--r--gcc/cfg.c116
-rw-r--r--gcc/cfgbuild.c4
-rw-r--r--gcc/cfgcleanup.c10
-rw-r--r--gcc/config/i386/i386-protos.h6
-rw-r--r--gcc/config/i386/i386.c727
-rw-r--r--gcc/config/i386/i386.h22
-rw-r--r--gcc/config/i386/next.h5
-rw-r--r--gcc/config/i386/unix.h5
-rw-r--r--gcc/cse.c6
-rw-r--r--gcc/df.c6
-rw-r--r--gcc/doloop.c2
-rw-r--r--gcc/emit-rtl.c19
-rw-r--r--gcc/except.c2
-rw-r--r--gcc/flow.c23
-rw-r--r--gcc/function.c4
-rw-r--r--gcc/gcse.c4
-rw-r--r--gcc/genpeep.c2
-rw-r--r--gcc/ifcvt.c19
-rw-r--r--gcc/integrate.c6
-rw-r--r--gcc/jump.c91
-rw-r--r--gcc/loop.c26
-rw-r--r--gcc/recog.c2
-rw-r--r--gcc/reg-stack.c20
-rw-r--r--gcc/regmove.c11
-rw-r--r--gcc/reload1.c6
-rw-r--r--gcc/reorg.c50
-rw-r--r--gcc/rtl.h4
-rw-r--r--gcc/ssa-ccp.c26
-rw-r--r--gcc/ssa-dce.c15
-rw-r--r--gcc/ssa.c2
-rw-r--r--gcc/unroll.c44
33 files changed, 1013 insertions, 374 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4fed3f7..4dfc2e0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,103 @@
+Fri Sep 21 14:24:29 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (flow_delete_insn, flow_delete_insn_chain): Kill.
+ * cfg.c (delete_insn): Rename from ....; use remove_insn; do not
+ remove some labels.
+ (flow_delete_insn): This one.
+ (delete_insn_chain): Rename from ...; do not care labels.
+ (flow_delete_insn_chain): ... this one.
+ (flow_delete_block): Remove the insns one BB has been expunged.
+ (merge_blocks_nomove): Likewise.
+ (try_redirect_by_replacing_jump): Use delete_insn[_chain]; do not care
+ updating BB boundaries.
+ (tidy_fallthru_edge): Likewise.
+ (commit_one_edge_insertion): Likewise.
+ * cfgbuild.c (find_basic_block): Likewise.
+ (find_basic_blocks_1): Likewise.
+ * cfgcleanup.c (merge_blocks_move_predecessor_nojumps): Likewise.
+ (try_crossjump_to_edge): Likewise.
+ (try_optimize_cfg): Likewise.
+ * cse.c (delete_trivially_dead_insns): Likewise.
+ * df.c (df_insn_delete): Likewise.
+ * doloop.c (doloop_modify): Use delete_related_insns.
+ * emit-rtl.c (try_split): Likewise.
+ (remove_insn): Update BB boundaries.
+ * expect.c (connect_post_landing_pads): Use delete_related_insns.
+ * flow.c (delete_dead_jumptables): Use delete_insn[_chain]; do not care
+ updating BB boundaries.
+ (propagate_block_delete_insn): Likewise.
+ (propagate_block_delete_libcall): Likewise.
+ * function.c (delete_handlers): Use delete_related_insns.
+ (thread_prologue_and_epilogue_insns): Likewise.
+ * gcse.c (delete_null_pointer_checks): Use delete_related_insns.
+ * genpeep.c (gen_peephole): Use delete_related_insns.
+ * ifcvt.c (noce_process_if_block): Use delete_insn; do not care updating
+ BB boundaries.
+ (find_cond_trap): Likewise.
+ * integrate.c (save_for_inline): Use delete_related_insns.
+ (copy_insn_list): Likewise.
+ * jump.c (pruge_linie_number_notes): Likewise.
+ (duplicate_loop_exit_test): Likewise.
+ (delete_computation): Likewise.
+ (delete_related_insn): Rename from ...; use delete_insn
+ (delete_insn): ... this one.
+ (redirect_jump): Use delete_related_insns.
+ * loop.c (scan_loop): Likewise.
+ (move_movables): Likewise.
+ (find_and_verify_loops): Likewise.
+ (check_dbra_loop): Likewise.
+ * recog.c (peephole2_optimize): Likewise.
+ * reg-stack.c (delete_insn_for_stacker): Remove.
+ (move_for_stack_reg): Use delete_insn.
+ * regmove.c (combine_stack_adjustments_for_block): Likewise.
+ * reload1.c (delete_address_reloads): Use delete_related_insns.
+ (fixup_abnormal_edges): Use delete_insn.
+ * recog.c (emit_delay_sequence): Use delete_related_insns.
+ (delete_from-delay_slot): Likewise.
+ (delete_scheduled_jump): likewise.
+ (optimize_skip): Likewise.
+ (try_merge_delay_insns): Likewise.
+ (full_simple_delay_slots): Likewise.
+ (fill_slots_from_thread): Likewise.
+ (relax_delay_slots): Likewise.
+ (make_return_insns): Likewise.
+ (dbr_schedule): Likewise.
+ * rtl.h (delete_insn): Rename to delete_related_insns.
+ (delete_insn, delete_insn_chain): New prototypes.
+ * ssa-ccp (sse_fast_dce): Remove deleting of DEF, as it is done
+ by df_insn_delete already.
+ * ssa-dce.c (delete_insn_bb): Use delete_insn.
+ * ssa.c (convert_from_ssa): Use delete_related_insns.
+ * unroll.c (unroll_loop): Likewise.
+ (calculate_giv_inc): Likewise.
+ (copy_loop_body): Likewise.
+
+ * i386-protos.h (ix86_libcall_value, ix86_function_value,
+ ix86_function_arg_regno_p, ix86_function_arg_boundary,
+ ix86_return_in_memory, ix86_function_value): Declare.
+ * i386.c (x86_64_int_parameter_registers, x86_64_int_return_registers):
+ new static valurables.
+ (x86_64_reg_class): New enum
+ (x86_64_reg_class_name): New array.
+ (classify_argument, examine_argument, construct_container,
+ merge_classes): New static functions.
+ (optimization_options): Enable flag_omit_frame_pointer and disable
+ flag_pcc_struct_return on 64bit.
+ (ix86_libcall_value, ix86_function_value,
+ ix86_function_arg_regno_p, ix86_function_arg_boundary,
+ ix86_return_in_memory, ix86_function_value): New global functions.
+ (init_cumulative_args): Refuse regparm on x86_64, set maybe_vaarg.
+ (function_arg_advance): Handle x86_64 passing conventions.
+ (function_arg): Likewise.
+ * i386.h (FUNCTION_ARG_BOUNDARY): New macro.
+ (RETURN_IN_MEMORY): Move offline.
+ (FUNCTION_VALUE, LIBCALL_VALUE): Likewise.
+ (FUNCTION_VALUE_REGNO_P): New macro.
+ (FUNCTION_ARG_REGNO_P): Move offline.
+ (struct ix86_args): Add maybe_vaarg.
+ * next.h (FUNCTION_VALUE_REGNO_P): Delete.
+ * unix.h (FUNCTION_VALUE_REGNO_P): Delete.
+
2001-09-21 Hartmut Penner <hpenner@de.ibm.com>
* s390.md: Changed attributes for scheduling.
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 8771b78..880d6ee 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -303,8 +303,6 @@ extern void remove_fake_edges PARAMS ((void));
extern void add_noreturn_fake_exit_edges PARAMS ((void));
extern void connect_infinite_loops_to_exit PARAMS ((void));
extern int flow_call_edges_add PARAMS ((sbitmap));
-extern rtx flow_delete_insn PARAMS ((rtx));
-extern void flow_delete_insn_chain PARAMS ((rtx, rtx));
extern edge cached_make_edge PARAMS ((sbitmap *, basic_block,
basic_block, int));
extern edge make_edge PARAMS ((basic_block,
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 9ba752d..9988ecd 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -27,7 +27,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- Initialization/deallocation
init_flow, clear_edges
- CFG aware instruction chain manipulation
- flow_delete_insn, flow_delete_insn_chain
+ delete_insn, delete_insn_chain
- Basic block manipulation
create_basic_block, flow_delete_block, split_block, merge_blocks_nomove
- Infrastructure to determine quickly basic block for instruction.
@@ -242,26 +242,35 @@ can_delete_label_p (label)
/* Delete INSN by patching it out. Return the next insn. */
rtx
-flow_delete_insn (insn)
+delete_insn (insn)
rtx insn;
{
- rtx prev = PREV_INSN (insn);
rtx next = NEXT_INSN (insn);
rtx note;
+ bool really_delete = true;
- PREV_INSN (insn) = NULL_RTX;
- NEXT_INSN (insn) = NULL_RTX;
- INSN_DELETED_P (insn) = 1;
+ if (GET_CODE (insn) == CODE_LABEL)
+ {
+ /* Some labels can't be directly removed from the INSN chain, as they
+ might be references via variables, constant pool etc.
+ Convert them to the special NOTE_INSN_DELETED_LABEL note. */
+ if (! can_delete_label_p (insn))
+ {
+ const char *name = LABEL_NAME (insn);
- if (prev)
- NEXT_INSN (prev) = next;
- if (next)
- PREV_INSN (next) = prev;
- else
- set_last_insn (prev);
+ really_delete = false;
+ PUT_CODE (insn, NOTE);
+ NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED_LABEL;
+ NOTE_SOURCE_FILE (insn) = name;
+ }
+ remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
+ }
- if (GET_CODE (insn) == CODE_LABEL)
- remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
+ if (really_delete)
+ {
+ remove_insn (insn);
+ INSN_DELETED_P (insn) = 1;
+ }
/* If deleting a jump, decrement the use count of the label. Deleting
the label itself should happen in the normal course of block merging. */
@@ -295,7 +304,7 @@ flow_delete_insn (insn)
that must be paired. */
void
-flow_delete_insn_chain (start, finish)
+delete_insn_chain (start, finish)
rtx start, finish;
{
/* Unchain the insns one by one. It would be quicker to delete all
@@ -309,16 +318,8 @@ flow_delete_insn_chain (start, finish)
next = NEXT_INSN (start);
if (GET_CODE (start) == NOTE && !can_delete_note_p (start))
;
- else if (GET_CODE (start) == CODE_LABEL
- && ! can_delete_label_p (start))
- {
- const char *name = LABEL_NAME (start);
- PUT_CODE (start, NOTE);
- NOTE_LINE_NUMBER (start) = NOTE_INSN_DELETED_LABEL;
- NOTE_SOURCE_FILE (start) = name;
- }
else
- next = flow_delete_insn (start);
+ next = delete_insn (start);
if (start == finish)
break;
@@ -510,19 +511,18 @@ flow_delete_block (b)
end = tmp;
/* Selectively delete the entire chain. */
- flow_delete_insn_chain (insn, end);
+ b->head = NULL;
+ delete_insn_chain (insn, end);
/* Remove the edges into and out of this block. Note that there may
indeed be edges in, if we are removing an unreachable loop. */
- {
- while (b->pred != NULL)
- remove_edge (b->pred);
- while (b->succ != NULL)
- remove_edge (b->succ);
+ while (b->pred != NULL)
+ remove_edge (b->pred);
+ while (b->succ != NULL)
+ remove_edge (b->succ);
- b->pred = NULL;
- b->succ = NULL;
- }
+ b->pred = NULL;
+ b->succ = NULL;
/* Remove the basic block from the array, and compact behind it. */
expunge_block (b);
@@ -958,10 +958,6 @@ merge_blocks_nomove (a, b)
else if (GET_CODE (NEXT_INSN (a_end)) == BARRIER)
del_first = NEXT_INSN (a_end);
- /* Delete everything marked above as well as crap that might be
- hanging out between the two blocks. */
- flow_delete_insn_chain (del_first, del_last);
-
/* Normally there should only be one successor of A and that is B, but
partway though the merge of blocks for conditional_execution we'll
be merging a TEST block with THEN and ELSE successors. Free the
@@ -977,6 +973,12 @@ merge_blocks_nomove (a, b)
/* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
b->pred = b->succ = NULL;
+ expunge_block (b);
+
+ /* Delete everything marked above as well as crap that might be
+ hanging out between the two blocks. */
+ delete_insn_chain (del_first, del_last);
+
/* Reassociate the insns of B with A. */
if (!b_empty)
{
@@ -993,8 +995,6 @@ merge_blocks_nomove (a, b)
a_end = b_end;
}
a->end = a_end;
-
- expunge_block (b);
}
/* Return label in the head of basic block. Create one if it doesn't exist. */
@@ -1055,13 +1055,12 @@ try_redirect_by_replacing_jump (e, target)
/* See if we can create the fallthru edge. */
if (can_fallthru (src, target))
{
- src->end = PREV_INSN (kill_from);
if (rtl_dump_file)
fprintf (rtl_dump_file, "Removing jump %i.\n", INSN_UID (insn));
fallthru = 1;
/* Selectivly unlink whole insn chain. */
- flow_delete_insn_chain (kill_from, PREV_INSN (target->head));
+ delete_insn_chain (kill_from, PREV_INSN (target->head));
}
/* If this already is simplejump, redirect it. */
else if (simplejump_p (insn))
@@ -1079,14 +1078,14 @@ try_redirect_by_replacing_jump (e, target)
rtx target_label = block_label (target);
rtx barrier;
- src->end = emit_jump_insn_before (gen_jump (target_label), kill_from);
+ emit_jump_insn_after (gen_jump (target_label), kill_from);
JUMP_LABEL (src->end) = target_label;
LABEL_NUSES (target_label)++;
if (rtl_dump_file)
fprintf (rtl_dump_file, "Replacing insn %i by jump %i\n",
INSN_UID (insn), INSN_UID (src->end));
- flow_delete_insn_chain (kill_from, insn);
+ delete_insn_chain (kill_from, insn);
barrier = next_nonnote_insn (src->end);
if (!barrier || GET_CODE (barrier) != BARRIER)
@@ -1108,11 +1107,7 @@ try_redirect_by_replacing_jump (e, target)
the potential of changing the code between -g and not -g. */
while (GET_CODE (e->src->end) == NOTE
&& NOTE_LINE_NUMBER (e->src->end) >= 0)
- {
- rtx prev = PREV_INSN (e->src->end);
- flow_delete_insn (e->src->end);
- e->src->end = prev;
- }
+ delete_insn (e->src->end);
if (e->dest != target)
redirect_edge_succ (e, target);
@@ -1387,28 +1382,17 @@ tidy_fallthru_edge (e, b, c)
q = PREV_INSN (q);
#endif
- if (b->head == q)
- {
- PUT_CODE (q, NOTE);
- NOTE_LINE_NUMBER (q) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (q) = 0;
- }
- else
- {
- q = PREV_INSN (q);
-
- /* We don't want a block to end on a line-number note since that has
- the potential of changing the code between -g and not -g. */
- while (GET_CODE (q) == NOTE && NOTE_LINE_NUMBER (q) >= 0)
- q = PREV_INSN (q);
- }
+ q = PREV_INSN (q);
- b->end = q;
+ /* We don't want a block to end on a line-number note since that has
+ the potential of changing the code between -g and not -g. */
+ while (GET_CODE (q) == NOTE && NOTE_LINE_NUMBER (q) >= 0)
+ q = PREV_INSN (q);
}
/* Selectively unlink the sequence. */
if (q != PREV_INSN (c->head))
- flow_delete_insn_chain (NEXT_INSN (q), PREV_INSN (c->head));
+ delete_insn_chain (NEXT_INSN (q), PREV_INSN (c->head));
e->flags |= EDGE_FALLTHRU;
}
@@ -1692,7 +1676,7 @@ commit_one_edge_insertion (e)
emit_barrier_after (last);
if (before)
- flow_delete_insn (before);
+ delete_insn (before);
}
else if (GET_CODE (last) == JUMP_INSN)
abort ();
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index d6e96e7..4afab81 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -442,7 +442,7 @@ find_basic_blocks_1 (f)
if (bb_note == NULL_RTX)
bb_note = insn;
else
- next = flow_delete_insn (insn);
+ next = delete_insn (insn);
}
break;
}
@@ -581,7 +581,7 @@ find_basic_blocks_1 (f)
if (head != NULL_RTX)
create_basic_block_structure (i++, head, end, bb_note);
else if (bb_note)
- flow_delete_insn (bb_note);
+ delete_insn (bb_note);
if (i != n_basic_blocks)
abort ();
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 7e227f6..314d9f4 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -277,7 +277,7 @@ merge_blocks_move_predecessor_nojumps (a, b)
barrier = next_nonnote_insn (a->end);
if (GET_CODE (barrier) != BARRIER)
abort ();
- flow_delete_insn (barrier);
+ delete_insn (barrier);
/* Move block and loop notes out of the chain so that we do not
disturb their order.
@@ -337,7 +337,7 @@ merge_blocks_move_successor_nojumps (a, b)
/* There had better have been a barrier there. Delete it. */
if (barrier && GET_CODE (barrier) == BARRIER)
- flow_delete_insn (barrier);
+ delete_insn (barrier);
/* Move block and loop notes out of the chain so that we do not
disturb their order.
@@ -901,12 +901,12 @@ try_crossjump_to_edge (mode, e1, e2)
/* Emit the jump insn. */
label = block_label (redirect_to);
- src1->end = emit_jump_insn_before (gen_jump (label), newpos1);
+ emit_jump_insn_after (gen_jump (label), src1->end);
JUMP_LABEL (src1->end) = label;
LABEL_NUSES (label)++;
/* Delete the now unreachable instructions. */
- flow_delete_insn_chain (newpos1, last);
+ delete_insn_chain (newpos1, last);
/* Make sure there is a barrier after the new jump. */
last = next_nonnote_insn (src1->end);
@@ -1078,7 +1078,7 @@ try_optimize_cfg (mode)
{
rtx label = b->head;
b->head = NEXT_INSN (b->head);
- flow_delete_insn_chain (label, label);
+ delete_insn_chain (label, label);
if (rtl_dump_file)
fprintf (rtl_dump_file, "Deleted label in block %i.\n",
b->index);
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index a81a29b0..f69dd2a 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -135,6 +135,11 @@ extern enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
extern int x86_64_sign_extended_value PARAMS ((rtx));
extern int x86_64_zero_extended_value PARAMS ((rtx));
+extern rtx ix86_libcall_value PARAMS ((enum machine_mode));
+extern bool ix86_function_value_regno_p PARAMS ((int));
+extern bool ix86_function_arg_regno_p PARAMS ((int));
+extern int ix86_function_arg_boundary PARAMS ((enum machine_mode, tree));
+extern int ix86_return_in_memory PARAMS ((tree));
extern rtx ix86_force_to_memory PARAMS ((enum machine_mode, rtx));
extern void ix86_free_from_memory PARAMS ((enum machine_mode));
@@ -160,6 +165,7 @@ extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
extern rtx function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
tree, int));
+extern rtx ix86_function_value PARAMS ((tree));
extern void ix86_init_builtins PARAMS ((void));
extern void ix86_init_mmx_sse_builtins PARAMS ((void));
extern rtx ix86_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 028c1ac..c6c2340 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -404,6 +404,12 @@ int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
-1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */
};
+static int x86_64_int_parameter_registers[6] = {5 /*RDI*/, 4 /*RSI*/,
+ 1 /*RDX*/, 2 /*RCX*/,
+ FIRST_REX_INT_REG /*R8 */,
+ FIRST_REX_INT_REG + 1 /*R9 */};
+static int x86_64_int_return_registers[4] = {0 /*RAX*/, 1 /*RDI*/, 5, 4};
+
/* The "default" register map used in 64bit mode. */
int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
{
@@ -668,6 +674,40 @@ static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int));
static void sco_asm_named_section PARAMS ((const char *, unsigned int));
static void sco_asm_out_constructor PARAMS ((rtx, int));
#endif
+/* Register class used for passing given 64bit part of the argument.
+ These represent classes as documented by the PS ABI, with the exception
+ of SSESF, SSEDF classes, that are basically SSE class, just gcc will
+ use SF or DFmode move instead of DImode to avoid reformating penalties.
+
+ Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+ whenever possible (upper half does contain padding).
+ */
+enum x86_64_reg_class
+ {
+ X86_64_NO_CLASS,
+ X86_64_INTEGER_CLASS,
+ X86_64_INTEGERSI_CLASS,
+ X86_64_SSE_CLASS,
+ X86_64_SSESF_CLASS,
+ X86_64_SSEDF_CLASS,
+ X86_64_SSEUP_CLASS,
+ X86_64_X87_CLASS,
+ X86_64_X87UP_CLASS,
+ X86_64_MEMORY_CLASS
+ };
+const char * const x86_64_reg_class_name[] =
+ {"no", "integer", "integerSI", "sse", "sseSF", "sseDF", "sseup", "x87", "x87up", "no"};
+
+#define MAX_CLASSES 4
+static int classify_argument PARAMS ((enum machine_mode, tree,
+ enum x86_64_reg_class [MAX_CLASSES],
+ int));
+static int examine_argument PARAMS ((enum machine_mode, tree, int, int *,
+ int *));
+static rtx construct_container PARAMS ((enum machine_mode, tree, int, int, int,
+ int *, int));
+static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
+ enum x86_64_reg_class));
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
@@ -974,6 +1014,10 @@ optimization_options (level, size)
if (level > 1)
flag_schedule_insns = 0;
#endif
+ if (TARGET_64BIT && optimize >= 1)
+ flag_omit_frame_pointer = 1;
+ if (TARGET_64BIT)
+ flag_pcc_struct_return = 0;
}
/* Table of valid machine attributes. */
@@ -1236,6 +1280,25 @@ ix86_return_pops_args (fundecl, funtype, size)
/* Argument support functions. */
+/* Return true when register may be used to pass function parameters. */
+bool
+ix86_function_arg_regno_p (regno)
+ int regno;
+{
+ int i;
+ if (!TARGET_64BIT)
+ return regno < REGPARM_MAX || (TARGET_SSE && SSE_REGNO_P (regno));
+ if (SSE_REGNO_P (regno) && TARGET_SSE)
+ return true;
+ /* RAX is used as hidden argument to va_arg functions. */
+ if (!regno)
+ return true;
+ for (i = 0; i < REGPARM_MAX; i++)
+ if (regno == x86_64_int_parameter_registers[i])
+ return true;
+ return false;
+}
+
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
@@ -1267,13 +1330,15 @@ init_cumulative_args (cum, fntype, libname)
/* Set up the number of registers to use for passing arguments. */
cum->nregs = ix86_regparm;
- if (fntype)
+ cum->sse_nregs = SSE_REGPARM_MAX;
+ if (fntype && !TARGET_64BIT)
{
tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
if (attr)
cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
}
+ cum->maybe_vaarg = false;
/* Determine if this function has variable arguments. This is
indicated by the last argument being 'void_type_mode' if there
@@ -1287,9 +1352,16 @@ init_cumulative_args (cum, fntype, libname)
{
next_param = TREE_CHAIN (param);
if (next_param == 0 && TREE_VALUE (param) != void_type_node)
- cum->nregs = 0;
+ {
+ if (!TARGET_64BIT)
+ cum->nregs = 0;
+ cum->maybe_vaarg = true;
+ }
}
}
+ if ((!fntype && !libname)
+ || (fntype && !TYPE_ARG_TYPES (fntype)))
+ cum->maybe_vaarg = 1;
if (TARGET_DEBUG_ARG)
fprintf (stderr, ", nregs=%d )\n", cum->nregs);
@@ -1297,6 +1369,444 @@ init_cumulative_args (cum, fntype, libname)
return;
}
+/* x86-64 register passing impleemntation. See x86-64 ABI for details. Goal
+ of this code is to classify each 8bytes of incomming argument by the register
+ class and assign registers accordingly. */
+
+/* Return the union class of CLASS1 and CLASS2.
+ See the x86-64 PS ABI for details. */
+
+static enum x86_64_reg_class
+merge_classes (class1, class2)
+ enum x86_64_reg_class class1, class2;
+{
+ /* Rule #1: If both classes are equal, this is the resulting class. */
+ if (class1 == class2)
+ return class1;
+
+ /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
+ the other class. */
+ if (class1 == X86_64_NO_CLASS)
+ return class2;
+ if (class2 == X86_64_NO_CLASS)
+ return class1;
+
+ /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
+ if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
+ if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
+ || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
+ return X86_64_INTEGERSI_CLASS;
+ if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
+ || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
+ return X86_64_INTEGER_CLASS;
+
+ /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used. */
+ if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
+ || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #6: Otherwise class SSE is used. */
+ return X86_64_SSE_CLASS;
+}
+
+/* Classify the argument of type TYPE and mode MODE.
+ CLASSES will be filled by the register class used to pass each word
+ of the operand. The number of words is returned. In case the parameter
+ should be passed in memory, 0 is returned. As a special case for zero
+ sized containers, classes[0] will be NO_CLASS and 1 is returned.
+
+ BIT_OFFSET is used internally for handling records and specifies offset
+ of the offset in bits modulo 256 to avoid overflow cases.
+
+ See the x86-64 PS ABI for details.
+*/
+
+static int
+classify_argument (mode, type, classes, bit_offset)
+ enum machine_mode mode;
+ tree type;
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int bit_offset;
+{
+ int bytes =
+ (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
+ int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+
+ if (type && AGGREGATE_TYPE_P (type))
+ {
+ int i;
+ tree field;
+ enum x86_64_reg_class subclasses[MAX_CLASSES];
+
+ /* On x86-64 we pass structures larger than 16 bytes on the stack. */
+ if (bytes > 16)
+ return 0;
+
+ for (i = 0; i < words; i++)
+ classes[i] = X86_64_NO_CLASS;
+
+ /* Zero sized arrays or structures are NO_CLASS. We return 0 to
+ signalize memory class, so handle it as special case. */
+ if (!words)
+ {
+ classes[0] = X86_64_NO_CLASS;
+ return 1;
+ }
+
+ /* Classify each field of record and merge classes. */
+ if (TREE_CODE (type) == RECORD_TYPE)
+ {
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ int num;
+
+ /* Bitfields are always classified as integer. Handle them
+ early, since later code would consider them to be
+ misaligned integers. */
+ if (DECL_BIT_FIELD (field))
+ {
+ for (i = int_bit_position (field) / 8 / 8;
+ i < (int_bit_position (field)
+ + tree_low_cst (DECL_SIZE (field), 0)
+ + 63) / 8 / 8; i++)
+ classes[i] =
+ merge_classes (X86_64_INTEGER_CLASS,
+ classes[i]);
+ }
+ else
+ {
+ num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
+ TREE_TYPE (field), subclasses,
+ (int_bit_position (field)
+ + bit_offset) % 256);
+ if (!num)
+ return 0;
+ for (i = 0; i < num; i++)
+ {
+ int pos =
+ (int_bit_position (field) + bit_offset) / 8 / 8;
+ classes[i + pos] =
+ merge_classes (subclasses[i], classes[i + pos]);
+ }
+ }
+ }
+ }
+ }
+ /* Arrays are handled as small records. */
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ int num;
+ num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
+ TREE_TYPE (type), subclasses, bit_offset);
+ if (!num)
+ return 0;
+
+ /* The partial classes are now full classes. */
+ if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
+ subclasses[0] = X86_64_SSE_CLASS;
+ if (subclasses[0] == X86_64_INTEGERSI_CLASS && bytes != 4)
+ subclasses[0] = X86_64_INTEGER_CLASS;
+
+ for (i = 0; i < words; i++)
+ classes[i] = subclasses[i % num];
+ }
+ /* Unions are similar to RECORD_TYPE but offset is always 0. */
+ else if (TREE_CODE (type) == UNION_TYPE)
+ {
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ int num;
+ num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
+ TREE_TYPE (field), subclasses,
+ bit_offset);
+ if (!num)
+ return 0;
+ for (i = 0; i < num; i++)
+ classes[i] = merge_classes (subclasses[i], classes[i]);
+ }
+ }
+ }
+ else
+ abort ();
+
+ /* Final merger cleanup. */
+ for (i = 0; i < words; i++)
+ {
+ /* If one class is MEMORY, everything should be passed in
+ memory. */
+ if (classes[i] == X86_64_MEMORY_CLASS)
+ return 0;
+
+ /* The X86_64_SSEUP_CLASS should be always preceeded by
+ X86_64_SSE_CLASS. */
+ if (classes[i] == X86_64_SSEUP_CLASS
+ && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
+ classes[i] = X86_64_SSE_CLASS;
+
+ /* X86_64_X87UP_CLASS should be preceeded by X86_64_X87_CLASS. */
+ if (classes[i] == X86_64_X87UP_CLASS
+ && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
+ classes[i] = X86_64_SSE_CLASS;
+ }
+ return words;
+ }
+
+ /* Compute alignment needed. We align all types to natural boundaries with
+ exception of XFmode that is aligned to 64bits. */
+ if (mode != VOIDmode && mode != BLKmode)
+ {
+ int mode_alignment = GET_MODE_BITSIZE (mode);
+
+ if (mode == XFmode)
+ mode_alignment = 128;
+ else if (mode == XCmode)
+ mode_alignment = 256;
+ /* Missalignmed fields are always returned in memory. */
+ if (bit_offset % mode_alignment)
+ return 0;
+ }
+
+ /* Classification of atomic types. */
+ switch (mode)
+ {
+ case DImode:
+ case SImode:
+ case HImode:
+ case QImode:
+ case CSImode:
+ case CHImode:
+ case CQImode:
+ if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
+ classes[0] = X86_64_INTEGERSI_CLASS;
+ else
+ classes[0] = X86_64_INTEGER_CLASS;
+ return 1;
+ case CDImode:
+ case TImode:
+ classes[0] = classes[1] = X86_64_INTEGER_CLASS;
+ return 2;
+ case CTImode:
+ classes[0] = classes[1] = X86_64_INTEGER_CLASS;
+ classes[2] = classes[3] = X86_64_INTEGER_CLASS;
+ return 4;
+ case SFmode:
+ if (!(bit_offset % 64))
+ classes[0] = X86_64_SSESF_CLASS;
+ else
+ classes[0] = X86_64_SSE_CLASS;
+ return 1;
+ case DFmode:
+ classes[0] = X86_64_SSEDF_CLASS;
+ return 1;
+ case TFmode:
+ classes[0] = X86_64_X87_CLASS;
+ classes[1] = X86_64_X87UP_CLASS;
+ return 2;
+ case TCmode:
+ classes[0] = X86_64_X87_CLASS;
+ classes[1] = X86_64_X87UP_CLASS;
+ classes[2] = X86_64_X87_CLASS;
+ classes[3] = X86_64_X87UP_CLASS;
+ return 4;
+ case DCmode:
+ classes[0] = X86_64_SSEDF_CLASS;
+ classes[1] = X86_64_SSEDF_CLASS;
+ return 2;
+ case SCmode:
+ classes[0] = X86_64_SSE_CLASS;
+ return 1;
+ case BLKmode:
+ return 0;
+ default:
+ abort ();
+ }
+}
+
+/* Examine the argument and return set number of register required in each
+ class. Return 0 ifif parameter should be passed in memory. */
+static int
+examine_argument (mode, type, in_return, int_nregs, sse_nregs)
+ enum machine_mode mode;
+ tree type;
+ int *int_nregs, *sse_nregs;
+ int in_return;
+{
+ enum x86_64_reg_class class[MAX_CLASSES];
+ int n = classify_argument (mode, type, class, 0);
+
+ *int_nregs = 0;
+ *sse_nregs = 0;
+ if (!n)
+ return 0;
+ for (n--; n >= 0; n--)
+ switch (class[n])
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ (*int_nregs)++;
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ (*sse_nregs)++;
+ break;
+ case X86_64_NO_CLASS:
+ case X86_64_SSEUP_CLASS:
+ break;
+ case X86_64_X87_CLASS:
+ case X86_64_X87UP_CLASS:
+ if (!in_return)
+ return 0;
+ break;
+ case X86_64_MEMORY_CLASS:
+ abort ();
+ }
+ return 1;
+}
+/* Construct container for the argument used by GCC interface. See
+ FUNCTION_ARG for the detailed description. */
+static rtx
+construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regno)
+ enum machine_mode mode;
+ tree type;
+ int in_return;
+ int nintregs, nsseregs;
+ int *intreg, sse_regno;
+{
+ enum machine_mode tmpmode;
+ int bytes =
+ (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
+ enum x86_64_reg_class class[MAX_CLASSES];
+ int n;
+ int i;
+ int nexps = 0;
+ int needed_sseregs, needed_intregs;
+ rtx exp[MAX_CLASSES];
+ rtx ret;
+
+ n = classify_argument (mode, type, class, 0);
+ if (TARGET_DEBUG_ARG)
+ {
+ if (!n)
+ fprintf (stderr, "Memory class\n");
+ else
+ {
+ fprintf (stderr, "Classes:");
+ for (i = 0; i < n; i++)
+ {
+ fprintf (stderr, " %s", x86_64_reg_class_name[class[i]]);
+ }
+ fprintf (stderr, "\n");
+ }
+ }
+ if (!n)
+ return NULL;
+ if (!examine_argument (mode, type, in_return, &needed_intregs, &needed_sseregs))
+ return NULL;
+ if (needed_intregs > nintregs || needed_sseregs > nsseregs)
+ return NULL;
+
+ /* First construct simple cases. Avoid SCmode, since we want to use
+ single register to pass this type. */
+ if (n == 1 && mode != SCmode)
+ switch (class[0])
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ return gen_rtx_REG (mode, intreg[0]);
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
+ case X86_64_X87_CLASS:
+ return gen_rtx_REG (mode, FIRST_STACK_REG);
+ case X86_64_NO_CLASS:
+ /* Zero sized array, struct or class. */
+ return NULL;
+ default:
+ abort ();
+ }
+ if (n == 2 && class[0] == X86_64_SSE_CLASS && class[1] == X86_64_SSEUP_CLASS)
+ return gen_rtx_REG (TImode, SSE_REGNO (sse_regno));
+ if (n == 2
+ && class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS)
+ return gen_rtx_REG (TFmode, FIRST_STACK_REG);
+ if (n == 2 && class[0] == X86_64_INTEGER_CLASS
+ && class[1] == X86_64_INTEGER_CLASS
+ && (mode == CDImode || mode == TImode)
+ && intreg[0] + 1 == intreg[1])
+ return gen_rtx_REG (mode, intreg[0]);
+ if (n == 4
+ && class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS
+ && class[2] == X86_64_X87_CLASS && class[3] == X86_64_X87UP_CLASS)
+ return gen_rtx_REG (TCmode, FIRST_STACK_REG);
+
+ /* Otherwise figure out the entries of the PARALLEL. */
+ for (i = 0; i < n; i++)
+ {
+ switch (class[i])
+ {
+ case X86_64_NO_CLASS:
+ break;
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ /* Merge TImodes on aligned occassions here too. */
+ if (i * 8 + 8 > bytes)
+ tmpmode = mode_for_size ((bytes - i * 8) * BITS_PER_UNIT, MODE_INT, 0);
+ else if (class[i] == X86_64_INTEGERSI_CLASS)
+ tmpmode = SImode;
+ else
+ tmpmode = DImode;
+ /* We've requested 24 bytes we don't have mode for. Use DImode. */
+ if (tmpmode == BLKmode)
+ tmpmode = DImode;
+ exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (tmpmode, *intreg),
+ GEN_INT (i*8));
+ intreg++;
+ break;
+ case X86_64_SSESF_CLASS:
+ exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SFmode,
+ SSE_REGNO (sse_regno)),
+ GEN_INT (i*8));
+ sse_regno++;
+ break;
+ case X86_64_SSEDF_CLASS:
+ exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (DFmode,
+ SSE_REGNO (sse_regno)),
+ GEN_INT (i*8));
+ sse_regno++;
+ break;
+ case X86_64_SSE_CLASS:
+ if (i < n && class[i + 1] == X86_64_SSEUP_CLASS)
+ tmpmode = TImode, i++;
+ else
+ tmpmode = DImode;
+ exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (tmpmode,
+ SSE_REGNO (sse_regno)),
+ GEN_INT (i*8));
+ sse_regno++;
+ break;
+ default:
+ abort ();
+ }
+ }
+ ret = gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
+ for (i = 0; i < nexps; i++)
+ XVECEXP (ret, 0, i) = exp [i];
+ return ret;
+}
+
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */
@@ -1316,27 +1826,45 @@ function_arg_advance (cum, mode, type, named)
fprintf (stderr,
"function_adv (sz=%d, wds=%2d, nregs=%d, mode=%s, named=%d)\n\n",
words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
- if (TARGET_SSE && mode == TImode)
+ if (TARGET_64BIT)
{
- cum->sse_words += words;
- cum->sse_nregs -= 1;
- cum->sse_regno += 1;
- if (cum->sse_nregs <= 0)
+ int int_nregs, sse_nregs;
+ if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs))
+ cum->words += words;
+ else if (sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
{
- cum->sse_nregs = 0;
- cum->sse_regno = 0;
+ cum->nregs -= int_nregs;
+ cum->sse_nregs -= sse_nregs;
+ cum->regno += int_nregs;
+ cum->sse_regno += sse_nregs;
}
+ else
+ cum->words += words;
}
else
{
- cum->words += words;
- cum->nregs -= words;
- cum->regno += words;
-
- if (cum->nregs <= 0)
+ if (TARGET_SSE && mode == TImode)
{
- cum->nregs = 0;
- cum->regno = 0;
+ cum->sse_words += words;
+ cum->sse_nregs -= 1;
+ cum->sse_regno += 1;
+ if (cum->sse_nregs <= 0)
+ {
+ cum->sse_nregs = 0;
+ cum->sse_regno = 0;
+ }
+ }
+ else
+ {
+ cum->words += words;
+ cum->nregs -= words;
+ cum->regno += words;
+
+ if (cum->nregs <= 0)
+ {
+ cum->nregs = 0;
+ cum->regno = 0;
+ }
}
}
return;
@@ -1367,28 +1895,44 @@ function_arg (cum, mode, type, named)
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ /* Handle an hidden AL argument containing number of registers for varargs
+ x86-64 functions. For i386 ABI just return constm1_rtx to avoid
+ any AL settings. */
if (mode == VOIDmode)
- return constm1_rtx;
-
- switch (mode)
{
- /* For now, pass fp/complex values on the stack. */
- default:
- break;
-
- case BLKmode:
- case DImode:
- case SImode:
- case HImode:
- case QImode:
- if (words <= cum->nregs)
- ret = gen_rtx_REG (mode, cum->regno);
- break;
- case TImode:
- if (cum->sse_nregs)
- ret = gen_rtx_REG (mode, cum->sse_regno);
- break;
+ if (TARGET_64BIT)
+ return GEN_INT (cum->maybe_vaarg
+ ? (cum->sse_nregs < 0
+ ? SSE_REGPARM_MAX
+ : cum->sse_regno)
+ : -1);
+ else
+ return constm1_rtx;
}
+ if (TARGET_64BIT)
+ ret = construct_container (mode, type, 0, cum->nregs, cum->sse_nregs,
+ &x86_64_int_parameter_registers [cum->regno],
+ cum->sse_regno);
+ else
+ switch (mode)
+ {
+ /* For now, pass fp/complex values on the stack. */
+ default:
+ break;
+
+ case BLKmode:
+ case DImode:
+ case SImode:
+ case HImode:
+ case QImode:
+ if (words <= cum->nregs)
+ ret = gen_rtx_REG (mode, cum->regno);
+ break;
+ case TImode:
+ if (cum->sse_nregs)
+ ret = gen_rtx_REG (mode, cum->sse_regno);
+ break;
+ }
if (TARGET_DEBUG_ARG)
{
@@ -1406,6 +1950,119 @@ function_arg (cum, mode, type, named)
return ret;
}
+
+/* Gives the alignment boundary, in bits, of an argument with the specified mode
+ and type. */
+
+int
+ix86_function_arg_boundary (mode, type)
+ enum machine_mode mode;
+ tree type;
+{
+ int align;
+ if (!TARGET_64BIT)
+ return PARM_BOUNDARY;
+ if (type)
+ align = TYPE_ALIGN (type);
+ else
+ align = GET_MODE_ALIGNMENT (mode);
+ if (align < PARM_BOUNDARY)
+ align = PARM_BOUNDARY;
+ if (align > 128)
+ align = 128;
+ return align;
+}
+
+/* Return true if N is a possible register number of function value. */
+bool
+ix86_function_value_regno_p (regno)
+ int regno;
+{
+ if (!TARGET_64BIT)
+ {
+ return ((regno) == 0
+ || ((regno) == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387)
+ || ((regno) == FIRST_SSE_REG && TARGET_SSE));
+ }
+ return ((regno) == 0 || (regno) == FIRST_FLOAT_REG
+ || ((regno) == FIRST_SSE_REG && TARGET_SSE)
+ || ((regno) == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387));
+}
+
+/* Define how to find the value returned by a function.
+ VALTYPE is the data type of the value (as a tree).
+ If the precise function being called is known, FUNC is its FUNCTION_DECL;
+ otherwise, FUNC is 0. */
+rtx
+ix86_function_value (valtype)
+ tree valtype;
+{
+ if (TARGET_64BIT)
+ {
+ rtx ret = construct_container (TYPE_MODE (valtype), valtype, 1,
+ REGPARM_MAX, SSE_REGPARM_MAX,
+ x86_64_int_return_registers, 0);
+ /* For zero sized structures, construct_continer return NULL, but we need
+ to keep rest of compiler happy by returning meaningfull value. */
+ if (!ret)
+ ret = gen_rtx_REG (TYPE_MODE (valtype), 0);
+ return ret;
+ }
+ else
+ return gen_rtx_REG (TYPE_MODE (valtype), VALUE_REGNO (TYPE_MODE (valtype)));
+}
+
+/* Return false ifif type is returned in memory. */
+int
+ix86_return_in_memory (type)
+ tree type;
+{
+ int needed_intregs, needed_sseregs;
+ if (TARGET_64BIT)
+ {
+ return !examine_argument (TYPE_MODE (type), type, 1,
+ &needed_intregs, &needed_sseregs);
+ }
+ else
+ {
+ if (TYPE_MODE (type) == BLKmode
+ || (VECTOR_MODE_P (TYPE_MODE (type))
+ && int_size_in_bytes (type) == 8)
+ || (int_size_in_bytes (type) > 12 && TYPE_MODE (type) != TImode
+ && TYPE_MODE (type) != TFmode
+ && !VECTOR_MODE_P (TYPE_MODE (type))))
+ return 1;
+ return 0;
+ }
+}
+
+/* Define how to find the value returned by a library function
+ assuming the value has mode MODE. */
+rtx
+ix86_libcall_value (mode)
+ enum machine_mode mode;
+{
+ if (TARGET_64BIT)
+ {
+ switch (mode)
+ {
+ case SFmode:
+ case SCmode:
+ case DFmode:
+ case DCmode:
+ return gen_rtx_REG (mode, FIRST_SSE_REG);
+ case TFmode:
+ case TCmode:
+ return gen_rtx_REG (mode, FIRST_FLOAT_REG);
+ default:
+ return gen_rtx_REG (mode, 0);
+ }
+ }
+ else
+ return gen_rtx_REG (mode, VALUE_REGNO (mode));
+}
+
+
/* Return nonzero if OP is general operand representable on x86_64. */
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 86e83df..4d76ac6 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -720,6 +720,12 @@ extern int ix86_arch;
#define LOCAL_ALIGNMENT(TYPE, ALIGN) ix86_local_alignment (TYPE, ALIGN)
+/* If defined, a C expression that gives the alignment boundary, in
+ bits, of an argument with the specified mode and type. If it is
+ not defined, `PARM_BOUNDARY' is used for all arguments. */
+
+#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) ix86_function_arg_boundary (MODE, TYPE)
+
/* Set this non-zero if move instructions will actually fail to work
when given unaligned data. */
#define STRICT_ALIGNMENT 0
@@ -1062,10 +1068,7 @@ extern int ix86_arch;
`DEFAULT_PCC_STRUCT_RETURN' to indicate this. */
#define RETURN_IN_MEMORY(TYPE) \
- ((TYPE_MODE (TYPE) == BLKmode) \
- || (VECTOR_MODE_P (TYPE_MODE (TYPE)) && int_size_in_bytes (TYPE) == 8)\
- || (int_size_in_bytes (TYPE) > 12 && TYPE_MODE (TYPE) != TImode \
- && TYPE_MODE (TYPE) != TFmode && ! VECTOR_MODE_P (TYPE_MODE (TYPE))))
+ ix86_return_in_memory (TYPE)
/* Define the classes of registers for register constraints in the
@@ -1517,14 +1520,16 @@ enum reg_class
If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG (TYPE_MODE (VALTYPE), \
- VALUE_REGNO (TYPE_MODE (VALTYPE)))
+ ix86_function_value (VALTYPE)
+
+#define FUNCTION_VALUE_REGNO_P(N) \
+ ix86_function_value_regno_p (N)
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG (MODE, VALUE_REGNO (MODE))
+ ix86_libcall_value (MODE)
/* Define the size of the result block used for communication between
untyped_call and untyped_return. The block contains a DImode value
@@ -1533,7 +1538,7 @@ enum reg_class
#define APPLY_RESULT_SIZE (8+108)
/* 1 if N is a possible register number for function argument passing. */
-#define FUNCTION_ARG_REGNO_P(N) ((N) < REGPARM_MAX)
+#define FUNCTION_ARG_REGNO_P(N) ix86_function_arg_regno_p (N)
/* Define a data type for recording info about an argument list
during the scan of that argument list. This data type should
@@ -1548,6 +1553,7 @@ typedef struct ix86_args {
int sse_words; /* # sse words passed so far */
int sse_nregs; /* # sse registers available for passing */
int sse_regno; /* next available sse register number */
+ int maybe_vaarg; /* true for calls to possibly vardic fncts. */
} CUMULATIVE_ARGS;
/* Initialize a variable CUM of type CUMULATIVE_ARGS
diff --git a/gcc/config/i386/next.h b/gcc/config/i386/next.h
index 0638dff..729ae4c 100644
--- a/gcc/config/i386/next.h
+++ b/gcc/config/i386/next.h
@@ -42,11 +42,6 @@ Boston, MA 02111-1307, USA. */
((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \
? FIRST_FLOAT_REG : 0)
-/* 1 if N is a possible register number for a function value. */
-
-#undef FUNCTION_VALUE_REGNO_P
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0 || (N)== FIRST_FLOAT_REG)
-
#ifdef REAL_VALUE_TO_TARGET_LONG_DOUBLE
#undef ASM_OUTPUT_LONG_DOUBLE
#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \
diff --git a/gcc/config/i386/unix.h b/gcc/config/i386/unix.h
index 1fe829a..15a0701 100644
--- a/gcc/config/i386/unix.h
+++ b/gcc/config/i386/unix.h
@@ -77,11 +77,6 @@ Boston, MA 02111-1307, USA. */
: (MODE) == TImode || VECTOR_MODE_P (MODE) ? FIRST_SSE_REG \
: 0)
-/* 1 if N is a possible register number for a function value. */
-
-#define FUNCTION_VALUE_REGNO_P(N) \
- ((N) == 0 || ((N)== FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387))
-
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
diff --git a/gcc/cse.c b/gcc/cse.c
index a870919..00019c2 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -7646,7 +7646,7 @@ delete_trivially_dead_insns (insns, nreg, preserve_basic_blocks)
if (! live_insn)
{
count_reg_usage (insn, counts, NULL_RTX, -1);
- delete_insn (insn);
+ delete_related_insns (insn);
}
if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
@@ -7687,9 +7687,7 @@ delete_trivially_dead_insns (insns, nreg, preserve_basic_blocks)
if (! live_insn)
{
count_reg_usage (insn, counts, NULL_RTX, -1);
- if (insn == bb->end)
- bb->end = PREV_INSN (insn);
- flow_delete_insn (insn);
+ delete_insn (insn);
}
if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
diff --git a/gcc/df.c b/gcc/df.c
index 947ea45..6d124a8 100644
--- a/gcc/df.c
+++ b/gcc/df.c
@@ -2593,13 +2593,9 @@ df_insn_delete (df, bb, insn)
/* We should not be deleting the NOTE_INSN_BASIC_BLOCK or label. */
if (insn == bb->head)
abort ();
- if (insn == bb->end)
- bb->end = PREV_INSN (insn);
/* Delete the insn. */
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
+ delete_insn (insn);
df_insn_modify (df, bb, insn);
diff --git a/gcc/doloop.c b/gcc/doloop.c
index caf616c..283080b 100644
--- a/gcc/doloop.c
+++ b/gcc/doloop.c
@@ -423,7 +423,7 @@ doloop_modify (loop, iterations, iterations_max,
/* Discard original jump to continue loop. The original compare
result may still be live, so it cannot be discarded explicitly. */
- delete_insn (jump_insn);
+ delete_related_insns (jump_insn);
counter_reg = XEXP (condition, 0);
if (GET_CODE (counter_reg) == PLUS)
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 4c48797..1c449d6 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -2613,7 +2613,7 @@ try_split (pat, trial, last)
tem = emit_insn_after (seq, trial);
- delete_insn (trial);
+ delete_related_insns (trial);
if (has_barrier)
emit_barrier_after (tem);
@@ -2873,6 +2873,8 @@ remove_insn (insn)
{
rtx next = NEXT_INSN (insn);
rtx prev = PREV_INSN (insn);
+ basic_block bb;
+
if (prev)
{
NEXT_INSN (prev) = next;
@@ -2921,6 +2923,21 @@ remove_insn (insn)
if (stack == 0)
abort ();
}
+ if (basic_block_for_insn
+ && (unsigned int)INSN_UID (insn) < basic_block_for_insn->num_elements
+ && (bb = BLOCK_FOR_INSN (insn)))
+ {
+ if (bb->head == insn)
+ {
+ /* Never ever delete the basic block note without deleting whole basic
+ block. */
+ if (GET_CODE (insn) == NOTE)
+ abort ();
+ bb->head = next;
+ }
+ if (bb->end == insn)
+ bb->end = prev;
+ }
}
/* Delete all insns made since FROM.
diff --git a/gcc/except.c b/gcc/except.c
index bc21b2c..0f0b662 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1850,7 +1850,7 @@ connect_post_landing_pads ()
seq = get_insns ();
end_sequence ();
emit_insns_before (seq, region->resume);
- flow_delete_insn (region->resume);
+ delete_insn (region->resume);
}
}
diff --git a/gcc/flow.c b/gcc/flow.c
index 24352bf..eb1d23a 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -771,7 +771,7 @@ delete_noop_moves (f)
next = NEXT_INSN (insn);
if (INSN_P (insn) && noop_move_p (insn))
{
- /* Do not call flow_delete_insn here to not confuse backward
+ /* Do not call delete_insn here to not confuse backward
pointers of LIBCALL block. */
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
@@ -802,8 +802,8 @@ delete_dead_jumptables ()
{
if (rtl_dump_file)
fprintf (rtl_dump_file, "Dead jumptable %i removed\n", INSN_UID (insn));
- flow_delete_insn (NEXT_INSN (insn));
- flow_delete_insn (insn);
+ delete_insn (NEXT_INSN (insn));
+ delete_insn (insn);
next = NEXT_INSN (next);
}
}
@@ -1323,6 +1323,7 @@ propagate_block_delete_insn (bb, insn)
rtx insn;
{
rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX);
+ bool purge = false;
/* If the insn referred to a label, and that label was attached to
an ADDR_VEC, it's safe to delete the ADDR_VEC. In fact, it's
@@ -1360,16 +1361,15 @@ propagate_block_delete_insn (bb, insn)
for (i = 0; i < len; i++)
LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;
- flow_delete_insn (next);
+ delete_insn (next);
}
}
if (bb->end == insn)
- {
- bb->end = PREV_INSN (insn);
- purge_dead_edges (bb);
- }
- flow_delete_insn (insn);
+ purge = true;
+ delete_insn (insn);
+ if (purge)
+ purge_dead_edges (bb);
}
/* Delete dead libcalls for propagate_block. Return the insn
@@ -1383,10 +1383,7 @@ propagate_block_delete_libcall (bb, insn, note)
rtx first = XEXP (note, 0);
rtx before = PREV_INSN (first);
- if (insn == bb->end)
- bb->end = before;
-
- flow_delete_insn_chain (first, insn);
+ delete_insn_chain (first, insn);
return before;
}
diff --git a/gcc/function.c b/gcc/function.c
index e6a269e..592842e 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -4140,7 +4140,7 @@ delete_handlers ()
|| (nonlocal_goto_stack_level != 0
&& reg_mentioned_p (nonlocal_goto_stack_level,
PATTERN (insn))))
- delete_insn (insn);
+ delete_related_insns (insn);
}
}
}
@@ -7300,7 +7300,7 @@ thread_prologue_and_epilogue_insns (f)
if (simplejump_p (jump))
{
emit_return_into_block (bb, epilogue_line_note);
- flow_delete_insn (jump);
+ delete_insn (jump);
}
/* If we have a conditional jump, we can try to replace
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 8e3187b..6cc915f 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -5456,7 +5456,7 @@ delete_null_pointer_checks (f)
if (delete_list)
{
for (i = 0; i < VARRAY_ACTIVE_SIZE (delete_list); i++)
- delete_insn (VARRAY_RTX (delete_list, i));
+ delete_related_insns (VARRAY_RTX (delete_list, i));
VARRAY_FREE (delete_list);
}
@@ -6836,7 +6836,7 @@ replace_store_insn (reg, del, bb)
fprintf(gcse_file, "\n");
}
- delete_insn (del);
+ delete_related_insns (del);
}
diff --git a/gcc/genpeep.c b/gcc/genpeep.c
index 7211992..6d70cba 100644
--- a/gcc/genpeep.c
+++ b/gcc/genpeep.c
@@ -119,7 +119,7 @@ gen_peephole (peep)
printf (" if (want_jump && GET_CODE (ins1) != JUMP_INSN)\n");
printf (" {\n");
printf (" rtx insn2 = emit_jump_insn_before (PATTERN (ins1), ins1);\n");
- printf (" delete_insn (ins1);\n");
+ printf (" delete_related_insns (ins1);\n");
printf (" ins1 = ins2;\n");
printf (" }\n");
#endif
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 4a76d22..fcbc645 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -1765,9 +1765,7 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb)
success:
/* The original sets may now be killed. */
- if (insn_a == then_bb->end)
- then_bb->end = PREV_INSN (insn_a);
- flow_delete_insn (insn_a);
+ delete_insn (insn_a);
/* Several special cases here: First, we may have reused insn_b above,
in which case insn_b is now NULL. Second, we want to delete insn_b
@@ -1776,17 +1774,12 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb)
the TEST block, it may in fact be loading data needed for the comparison.
We'll let life_analysis remove the insn if it's really dead. */
if (insn_b && else_bb)
- {
- if (insn_b == else_bb->end)
- else_bb->end = PREV_INSN (insn_b);
- flow_delete_insn (insn_b);
- }
+ delete_insn (insn_b);
/* The new insns will have been inserted before cond_earliest. We should
be able to remove the jump with impunity, but the condition itself may
have been modified by gcse to be shared across basic blocks. */
- test_bb->end = PREV_INSN (jump);
- flow_delete_insn (jump);
+ delete_insn (jump);
/* If we used a temporary, fix it up now. */
if (orig_x != x)
@@ -2189,11 +2182,9 @@ find_cond_trap (test_bb, then_edge, else_edge)
emit_insn_before (seq, cond_earliest);
- test_bb->end = PREV_INSN (jump);
- flow_delete_insn (jump);
+ delete_insn (jump);
- trap_bb->end = PREV_INSN (trap);
- flow_delete_insn (trap);
+ delete_insn (trap);
/* Merge the blocks! */
if (trap_bb != then_bb && ! else_bb)
diff --git a/gcc/integrate.c b/gcc/integrate.c
index 7887b36..1bc85b1 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -460,7 +460,7 @@ save_for_inline (fndecl)
for basic_block structures on already freed obstack. */
for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
- delete_insn (insn);
+ delete_related_insns (insn);
/* If there are insns that copy parms from the stack into pseudo registers,
those insns are not copied. `expand_inline_function' must
@@ -1492,13 +1492,13 @@ copy_insn_list (insns, map, static_chain_value)
#ifdef HAVE_cc0
/* If the previous insn set cc0 for us, delete it. */
if (only_sets_cc0_p (PREV_INSN (copy)))
- delete_insn (PREV_INSN (copy));
+ delete_related_insns (PREV_INSN (copy));
#endif
/* If this is now a no-op, delete it. */
if (map->last_pc_value == pc_rtx)
{
- delete_insn (copy);
+ delete_related_insns (copy);
copy = 0;
}
else
diff --git a/gcc/jump.c b/gcc/jump.c
index e8a8594..544b672 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -182,7 +182,7 @@ purge_line_number_notes (f)
&& NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note)
&& NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note))
{
- delete_insn (insn);
+ delete_related_insns (insn);
continue;
}
@@ -529,7 +529,7 @@ duplicate_loop_exit_test (loop_start)
/* Mark the exit code as the virtual top of the converted loop. */
emit_note_before (NOTE_INSN_LOOP_VTOP, exitcode);
- delete_insn (next_nonnote_insn (loop_start));
+ delete_related_insns (next_nonnote_insn (loop_start));
/* Clean up. */
if (reg_map)
@@ -1710,24 +1710,24 @@ delete_computation (insn)
delete_prior_computation (note, insn);
}
- delete_insn (insn);
+ delete_related_insns (insn);
}
-/* Delete insn INSN from the chain of insns and update label ref counts.
- May delete some following insns as a consequence; may even delete
- a label elsewhere and insns that follow it.
+/* Delete insn INSN from the chain of insns and update label ref counts
+ and delete insns now unreachable.
+
+ Returns the first insn after INSN that was not deleted.
- Returns the first insn after INSN that was not deleted. */
+ Usage of this instruction is deprecated. Use delete_insn instead and
+ subsequent cfg_cleanup pass to delete unreachable code if needed. */
rtx
-delete_insn (insn)
+delete_related_insns (insn)
register rtx insn;
{
- register rtx next = NEXT_INSN (insn);
- register rtx prev = PREV_INSN (insn);
register int was_code_label = (GET_CODE (insn) == CODE_LABEL);
- register int dont_really_delete = 0;
rtx note;
+ rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
while (next && INSN_DELETED_P (next))
next = NEXT_INSN (next);
@@ -1736,58 +1736,13 @@ delete_insn (insn)
if (INSN_DELETED_P (insn))
return next;
- if (was_code_label)
- remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
-
- /* Don't delete user-declared labels. When optimizing, convert them
- to special NOTEs instead. When not optimizing, leave them alone. */
- if (was_code_label && LABEL_NAME (insn) != 0)
- {
- if (optimize)
- {
- const char *name = LABEL_NAME (insn);
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED_LABEL;
- NOTE_SOURCE_FILE (insn) = name;
- }
-
- dont_really_delete = 1;
- }
- else
- /* Mark this insn as deleted. */
- INSN_DELETED_P (insn) = 1;
+ delete_insn (insn);
/* If instruction is followed by a barrier,
delete the barrier too. */
if (next != 0 && GET_CODE (next) == BARRIER)
- {
- INSN_DELETED_P (next) = 1;
- next = NEXT_INSN (next);
- }
-
- /* Patch out INSN (and the barrier if any) */
-
- if (! dont_really_delete)
- {
- if (prev)
- {
- NEXT_INSN (prev) = next;
- if (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SEQUENCE)
- NEXT_INSN (XVECEXP (PATTERN (prev), 0,
- XVECLEN (PATTERN (prev), 0) - 1)) = next;
- }
-
- if (next)
- {
- PREV_INSN (next) = prev;
- if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == SEQUENCE)
- PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev;
- }
-
- if (prev && NEXT_INSN (prev) == 0)
- set_last_insn (prev);
- }
+ delete_insn (next);
/* If deleting a jump, decrement the count of the label,
and delete the label if it is now unused. */
@@ -1796,12 +1751,12 @@ delete_insn (insn)
{
rtx lab = JUMP_LABEL (insn), lab_next;
- if (--LABEL_NUSES (lab) == 0)
+ if (LABEL_NUSES (lab) == 0)
{
/* This can delete NEXT or PREV,
either directly if NEXT is JUMP_LABEL (INSN),
or indirectly through more levels of jumps. */
- delete_insn (lab);
+ delete_related_insns (lab);
/* I feel a little doubtful about this loop,
but I see no clean and sure alternative way
@@ -1820,7 +1775,7 @@ delete_insn (insn)
We may not be able to kill the label immediately preceeding
just yet, as it might be referenced in code leading up to
the tablejump. */
- delete_insn (lab_next);
+ delete_related_insns (lab_next);
}
}
@@ -1835,8 +1790,8 @@ delete_insn (insn)
int len = XVECLEN (pat, diff_vec_p);
for (i = 0; i < len; i++)
- if (--LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
- delete_insn (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
+ if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
+ delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
while (next && INSN_DELETED_P (next))
next = NEXT_INSN (next);
return next;
@@ -1848,8 +1803,8 @@ delete_insn (insn)
if (REG_NOTE_KIND (note) == REG_LABEL
/* This could also be a NOTE_INSN_DELETED_LABEL note. */
&& GET_CODE (XEXP (note, 0)) == CODE_LABEL)
- if (--LABEL_NUSES (XEXP (note, 0)) == 0)
- delete_insn (XEXP (note, 0));
+ if (LABEL_NUSES (XEXP (note, 0)) == 0)
+ delete_related_insns (XEXP (note, 0));
while (prev && (INSN_DELETED_P (prev) || GET_CODE (prev) == NOTE))
prev = PREV_INSN (prev);
@@ -1863,7 +1818,7 @@ delete_insn (insn)
&& GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
&& (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
|| GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
- next = delete_insn (NEXT_INSN (insn));
+ next = delete_related_insns (NEXT_INSN (insn));
/* If INSN was a label, delete insns following it if now unreachable. */
@@ -1886,7 +1841,7 @@ delete_insn (insn)
deletion of unreachable code, after a different label.
As long as the value from this recursive call is correct,
this invocation functions correctly. */
- next = delete_insn (next);
+ next = delete_related_insns (next);
}
}
@@ -2128,7 +2083,7 @@ redirect_jump (jump, nlabel, delete_unused)
emit_note_after (NOTE_INSN_FUNCTION_END, nlabel);
if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused)
- delete_insn (olabel);
+ delete_related_insns (olabel);
return 1;
}
diff --git a/gcc/loop.c b/gcc/loop.c
index e20e059..d27e058 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -1047,7 +1047,7 @@ scan_loop (loop, flags)
if (update_end && GET_CODE (update_end) == CODE_LABEL
&& --LABEL_NUSES (update_end) == 0)
- delete_insn (update_end);
+ delete_related_insns (update_end);
}
@@ -1774,7 +1774,7 @@ move_movables (loop, movables, threshold, insn_count)
= gen_rtx_EXPR_LIST (VOIDmode, r1,
gen_rtx_EXPR_LIST (VOIDmode, r2,
regs_may_share));
- delete_insn (m->insn);
+ delete_related_insns (m->insn);
if (new_start == 0)
new_start = i1;
@@ -1805,11 +1805,11 @@ move_movables (loop, movables, threshold, insn_count)
{
temp = XEXP (temp, 0);
while (temp != p)
- temp = delete_insn (temp);
+ temp = delete_related_insns (temp);
}
temp = p;
- p = delete_insn (p);
+ p = delete_related_insns (p);
/* simplify_giv_expr expects that it can walk the insns
at m->insn forwards and see this old sequence we are
@@ -1936,7 +1936,7 @@ move_movables (loop, movables, threshold, insn_count)
if (temp == fn_address_insn)
fn_address_insn = i1;
REG_NOTES (i1) = REG_NOTES (temp);
- delete_insn (temp);
+ delete_related_insns (temp);
}
if (new_start == 0)
new_start = first;
@@ -2031,7 +2031,7 @@ move_movables (loop, movables, threshold, insn_count)
}
temp = p;
- delete_insn (p);
+ delete_related_insns (p);
p = NEXT_INSN (p);
/* simplify_giv_expr expects that it can walk the insns
@@ -2110,9 +2110,9 @@ move_movables (loop, movables, threshold, insn_count)
{
for (temp = XEXP (temp, 0); temp != m1->insn;
temp = NEXT_INSN (temp))
- delete_insn (temp);
+ delete_related_insns (temp);
}
- delete_insn (m1->insn);
+ delete_related_insns (m1->insn);
/* Any other movable that loads the same register
MUST be moved. */
@@ -2799,7 +2799,7 @@ find_and_verify_loops (f, loops)
if (JUMP_LABEL (insn) != 0
&& (next_real_insn (JUMP_LABEL (insn))
== next_real_insn (insn)))
- delete_insn (insn);
+ delete_related_insns (insn);
}
/* Continue the loop after where the conditional
@@ -2809,7 +2809,7 @@ find_and_verify_loops (f, loops)
insn = NEXT_INSN (cond_label);
if (--LABEL_NUSES (cond_label) == 0)
- delete_insn (cond_label);
+ delete_related_insns (cond_label);
/* This loop will be continued with NEXT_INSN (insn). */
insn = PREV_INSN (insn);
@@ -7628,7 +7628,7 @@ check_dbra_loop (loop, insn_count)
end_sequence ();
p = loop_insn_emit_before (loop, 0, bl->biv->insn, tem);
- delete_insn (bl->biv->insn);
+ delete_related_insns (bl->biv->insn);
/* Update biv info to reflect its new status. */
bl->biv->insn = p;
@@ -7656,9 +7656,9 @@ check_dbra_loop (loop, insn_count)
loop_insn_sink (loop, gen_move_insn (reg, final_value));
/* Delete compare/branch at end of loop. */
- delete_insn (PREV_INSN (loop_end));
+ delete_related_insns (PREV_INSN (loop_end));
if (compare_and_branch == 2)
- delete_insn (first_compare);
+ delete_related_insns (first_compare);
/* Add new compare/branch insn at end of loop. */
start_sequence ();
diff --git a/gcc/recog.c b/gcc/recog.c
index c0b60f8..7f723f9 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3128,7 +3128,7 @@ peephole2_optimize (dump_file)
/* Replace the old sequence with the new. */
try = emit_insn_after (try, peep2_insn_data[i].insn);
- flow_delete_insn_chain (insn, peep2_insn_data[i].insn);
+ delete_insn_chain (insn, peep2_insn_data[i].insn);
#ifdef HAVE_conditional_execution
/* With conditional execution, we cannot back up the
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index a8a9ef1..c247048 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -245,7 +245,6 @@ static void replace_reg PARAMS ((rtx *, int));
static void remove_regno_note PARAMS ((rtx, enum reg_note,
unsigned int));
static int get_hard_regnum PARAMS ((stack, rtx));
-static void delete_insn_for_stacker PARAMS ((rtx));
static rtx emit_pop_insn PARAMS ((rtx, stack, rtx,
enum emit_where));
static void emit_swap_insn PARAMS ((rtx, stack, rtx));
@@ -907,19 +906,6 @@ get_hard_regnum (regstack, reg)
return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1;
}
-
-/* Delete INSN from the RTL. Mark the insn, but don't remove it from
- the chain of insns. Doing so could confuse block_begin and block_end
- if this were the only insn in the block. */
-
-static void
-delete_insn_for_stacker (insn)
- rtx insn;
-{
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
-}
/* Emit an insn to pop virtual register REG before or after INSN.
REGSTACK is the stack state after INSN and is updated to reflect this
@@ -1114,7 +1100,7 @@ move_for_stack_reg (insn, regstack, pat)
{
emit_pop_insn (insn, regstack, src, EMIT_AFTER);
- delete_insn_for_stacker (insn);
+ delete_insn (insn);
return;
}
@@ -1123,7 +1109,7 @@ move_for_stack_reg (insn, regstack, pat)
SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
- delete_insn_for_stacker (insn);
+ delete_insn (insn);
return;
}
@@ -1140,7 +1126,7 @@ move_for_stack_reg (insn, regstack, pat)
if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
emit_pop_insn (insn, regstack, dest, EMIT_AFTER);
- delete_insn_for_stacker (insn);
+ delete_insn (insn);
return;
}
diff --git a/gcc/regmove.c b/gcc/regmove.c
index d26430a..48f9764 100644
--- a/gcc/regmove.c
+++ b/gcc/regmove.c
@@ -2408,7 +2408,7 @@ combine_stack_adjustments_for_block (bb)
-last_sp_adjust))
{
/* It worked! */
- flow_delete_insn (last_sp_set);
+ delete_insn (last_sp_set);
last_sp_set = insn;
last_sp_adjust += this_adjust;
free_csa_memlist (memlist);
@@ -2450,7 +2450,7 @@ combine_stack_adjustments_for_block (bb)
{
if (last_sp_set == bb->head)
bb->head = NEXT_INSN (last_sp_set);
- flow_delete_insn (last_sp_set);
+ delete_insn (last_sp_set);
free_csa_memlist (memlist);
memlist = NULL;
@@ -2487,12 +2487,9 @@ combine_stack_adjustments_for_block (bb)
break;
if (pending_delete)
- flow_delete_insn (pending_delete);
+ delete_insn (pending_delete);
}
if (pending_delete)
- {
- bb->end = PREV_INSN (pending_delete);
- flow_delete_insn (pending_delete);
- }
+ delete_insn (pending_delete);
}
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 11010e2..1636337 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -7744,8 +7744,8 @@ delete_address_reloads (dead_insn, current_insn)
|| (INTVAL (XEXP (SET_SRC (set), 1))
!= -INTVAL (XEXP (SET_SRC (set2), 1))))
return;
- delete_insn (prev);
- delete_insn (next);
+ delete_related_insns (prev);
+ delete_related_insns (next);
}
/* Subfunction of delete_address_reloads: process registers found in X. */
@@ -9519,7 +9519,7 @@ fixup_abnormal_edges ()
if (INSN_P (insn))
{
insert_insn_on_edge (PATTERN (insn), e);
- flow_delete_insn (insn);
+ delete_insn (insn);
}
insn = next;
}
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 2039945..986ef671 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -455,7 +455,7 @@ emit_delay_sequence (insn, list, length)
We will put the BARRIER back in later. */
if (NEXT_INSN (insn) && GET_CODE (NEXT_INSN (insn)) == BARRIER)
{
- delete_insn (NEXT_INSN (insn));
+ delete_related_insns (NEXT_INSN (insn));
last = get_last_insn ();
had_barrier = 1;
}
@@ -590,7 +590,7 @@ delete_from_delay_slot (insn)
list, and rebuild the delay list if non-empty. */
prev = PREV_INSN (seq_insn);
trial = XVECEXP (seq, 0, 0);
- delete_insn (seq_insn);
+ delete_related_insns (seq_insn);
add_insn_after (trial, prev);
if (GET_CODE (trial) == JUMP_INSN
@@ -651,14 +651,14 @@ delete_scheduled_jump (insn)
|| FIND_REG_INC_NOTE (trial, 0))
return;
if (PREV_INSN (NEXT_INSN (trial)) == trial)
- delete_insn (trial);
+ delete_related_insns (trial);
else
delete_from_delay_slot (trial);
}
}
#endif
- delete_insn (insn);
+ delete_related_insns (insn);
}
/* Counters for delay-slot filling. */
@@ -762,7 +762,7 @@ optimize_skip (insn)
delay_list = add_to_delay_list (trial, NULL_RTX);
next_trial = next_active_insn (trial);
update_block (trial, trial);
- delete_insn (trial);
+ delete_related_insns (trial);
/* Also, if we are targeting an unconditional
branch, thread our jump to the target of that branch. Don't
@@ -1510,7 +1510,7 @@ try_merge_delay_insns (insn, thread)
if (trial == thread)
thread = next_active_insn (thread);
- delete_insn (trial);
+ delete_related_insns (trial);
INSN_FROM_TARGET_P (next_to_match) = 0;
}
else
@@ -1603,7 +1603,7 @@ try_merge_delay_insns (insn, thread)
else
{
update_block (XEXP (merged_insns, 0), thread);
- delete_insn (XEXP (merged_insns, 0));
+ delete_related_insns (XEXP (merged_insns, 0));
}
}
@@ -2191,7 +2191,7 @@ fill_simple_delay_slots (non_jumps_p)
delay_list = gen_rtx_INSN_LIST (VOIDmode,
trial, delay_list);
update_block (trial, trial);
- delete_insn (trial);
+ delete_related_insns (trial);
if (slots_to_fill == ++slots_filled)
break;
continue;
@@ -2329,7 +2329,7 @@ fill_simple_delay_slots (non_jumps_p)
link_cc0_insns (trial);
#endif
- delete_insn (trial);
+ delete_related_insns (trial);
if (slots_to_fill == ++slots_filled)
break;
continue;
@@ -2488,7 +2488,7 @@ fill_simple_delay_slots (non_jumps_p)
current_function_epilogue_delay_list);
mark_end_of_function_resources (trial, 1);
update_block (trial, trial);
- delete_insn (trial);
+ delete_related_insns (trial);
/* Clear deleted bit so final.c will output the insn. */
INSN_DELETED_P (trial) = 0;
@@ -2636,7 +2636,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
new_thread = thread;
}
- delete_insn (trial);
+ delete_related_insns (trial);
}
else
{
@@ -2710,7 +2710,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
if (new_thread == trial)
new_thread = thread;
}
- delete_insn (trial);
+ delete_related_insns (trial);
}
else
new_thread = next_active_insn (trial);
@@ -2869,7 +2869,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
if (recog_memoized (ninsn) < 0
|| (extract_insn (ninsn), ! constrain_operands (1)))
{
- delete_insn (ninsn);
+ delete_related_insns (ninsn);
return 0;
}
@@ -2882,7 +2882,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
if (new_thread == trial)
new_thread = thread;
}
- delete_insn (trial);
+ delete_related_insns (trial);
}
else
new_thread = next_active_insn (trial);
@@ -3128,7 +3128,7 @@ relax_delay_slots (first)
if (invert_jump (insn, label, 1))
{
- delete_insn (next);
+ delete_related_insns (next);
next = insn;
}
@@ -3136,7 +3136,7 @@ relax_delay_slots (first)
--LABEL_NUSES (label);
if (--LABEL_NUSES (target_label) == 0)
- delete_insn (target_label);
+ delete_related_insns (target_label);
continue;
}
@@ -3212,7 +3212,7 @@ relax_delay_slots (first)
INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
trial = PREV_INSN (insn);
- delete_insn (insn);
+ delete_related_insns (insn);
emit_insn_after (pat, trial);
delete_scheduled_jump (delay_insn);
continue;
@@ -3325,7 +3325,7 @@ relax_delay_slots (first)
INSN_FROM_TARGET_P (XVECEXP (pat, 0, i)) = 0;
trial = PREV_INSN (insn);
- delete_insn (insn);
+ delete_related_insns (insn);
emit_insn_after (pat, trial);
delete_scheduled_jump (delay_insn);
continue;
@@ -3340,7 +3340,7 @@ relax_delay_slots (first)
&& XVECLEN (pat, 0) == 2
&& rtx_equal_p (PATTERN (next), PATTERN (XVECEXP (pat, 0, 1))))
{
- delete_insn (insn);
+ delete_related_insns (insn);
continue;
}
@@ -3384,12 +3384,12 @@ relax_delay_slots (first)
INSN_FROM_TARGET_P (slot) = ! INSN_FROM_TARGET_P (slot);
}
- delete_insn (next);
+ delete_related_insns (next);
next = insn;
}
if (old_label && --LABEL_NUSES (old_label) == 0)
- delete_insn (old_label);
+ delete_related_insns (old_label);
continue;
}
}
@@ -3508,7 +3508,7 @@ make_return_insns (first)
{
rtx prev = PREV_INSN (insn);
- delete_insn (insn);
+ delete_related_insns (insn);
for (i = 1; i < XVECLEN (pat, 0); i++)
prev = emit_insn_after (PATTERN (XVECEXP (pat, 0, i)), prev);
@@ -3527,7 +3527,7 @@ make_return_insns (first)
/* Now delete REAL_RETURN_LABEL if we never used it. Then try to fill any
new delay slots we have created. */
if (--LABEL_NUSES (real_return_label) == 0)
- delete_insn (real_return_label);
+ delete_related_insns (real_return_label);
fill_simple_delay_slots (1);
fill_simple_delay_slots (0);
@@ -3637,14 +3637,14 @@ dbr_schedule (first, file)
if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE
&& INSN_P (XEXP (PATTERN (insn), 0)))
- next = delete_insn (insn);
+ next = delete_related_insns (insn);
}
/* If we made an end of function label, indicate that it is now
safe to delete it by undoing our prior adjustment to LABEL_NUSES.
If it is now unused, delete it. */
if (end_of_function_label && --LABEL_NUSES (end_of_function_label) == 0)
- delete_insn (end_of_function_label);
+ delete_related_insns (end_of_function_label);
#ifdef HAVE_return
if (HAVE_return && end_of_function_label != 0)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 0ac125e..7deb964 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1288,7 +1288,7 @@ extern void cleanup_barriers PARAMS ((void));
/* In jump.c */
extern void squeeze_notes PARAMS ((rtx *, rtx *));
-extern rtx delete_insn PARAMS ((rtx));
+extern rtx delete_related_insns PARAMS ((rtx));
extern void delete_jump PARAMS ((rtx));
extern void delete_barrier PARAMS ((rtx));
extern rtx get_label_before PARAMS ((rtx));
@@ -1775,6 +1775,8 @@ int force_line_numbers PARAMS ((void));
void restore_line_number_status PARAMS ((int old_value));
extern void renumber_insns PARAMS ((FILE *));
extern void remove_unnecessary_notes PARAMS ((void));
+extern rtx delete_insn PARAMS ((rtx));
+extern void delete_insn_chain PARAMS ((rtx, rtx));
/* In combine.c */
extern int combine_instructions PARAMS ((rtx, unsigned int));
diff --git a/gcc/ssa-ccp.c b/gcc/ssa-ccp.c
index 3c64ff0..047b29d 100644
--- a/gcc/ssa-ccp.c
+++ b/gcc/ssa-ccp.c
@@ -1208,32 +1208,6 @@ ssa_fast_dce (df)
deleted. */
df_insn_delete (df, BLOCK_FOR_INSN (def), def);
- if (PHI_NODE_P (def))
- {
- if (def == BLOCK_FOR_INSN (def)->head
- && def == BLOCK_FOR_INSN (def)->end)
- {
- /* Delete it. */
- PUT_CODE (def, NOTE);
- NOTE_LINE_NUMBER (def) = NOTE_INSN_DELETED;
- }
- else if (def == BLOCK_FOR_INSN (def)->head)
- {
- BLOCK_FOR_INSN (def)->head = NEXT_INSN (def);
- flow_delete_insn (def);
- }
- else if (def == BLOCK_FOR_INSN (def)->end)
- {
- BLOCK_FOR_INSN (def)->end = PREV_INSN (def);
- flow_delete_insn (def);
- }
- else
- flow_delete_insn (def);
- }
- else
- {
- flow_delete_insn (def);
- }
VARRAY_RTX (ssa_definition, reg) = NULL;
}
}
diff --git a/gcc/ssa-dce.c b/gcc/ssa-dce.c
index 797a01c..62e59e8 100644
--- a/gcc/ssa-dce.c
+++ b/gcc/ssa-dce.c
@@ -468,7 +468,6 @@ static void
delete_insn_bb (insn)
rtx insn;
{
- basic_block bb;
if (!insn)
abort ();
@@ -480,20 +479,6 @@ delete_insn_bb (insn)
if (! INSN_P (insn))
return;
- bb = BLOCK_FOR_INSN (insn);
- if (!bb)
- abort ();
- if (bb->head == bb->end)
- {
- /* Delete the insn by converting it to a note. */
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- return;
- }
- else if (insn == bb->head)
- bb->head = NEXT_INSN (insn);
- else if (insn == bb->end)
- bb->end = PREV_INSN (insn);
delete_insn (insn);
}
diff --git a/gcc/ssa.c b/gcc/ssa.c
index 82be677..55aef89 100644
--- a/gcc/ssa.c
+++ b/gcc/ssa.c
@@ -2186,7 +2186,7 @@ convert_from_ssa()
{
if (insn == BLOCK_END (bb))
BLOCK_END (bb) = PREV_INSN (insn);
- insn = delete_insn (insn);
+ insn = delete_related_insns (insn);
}
/* Since all the phi nodes come at the beginning of the
block, if we find an ordinary insn, we can stop looking
diff --git a/gcc/unroll.c b/gcc/unroll.c
index bf0c607..f3f5656 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -355,7 +355,7 @@ unroll_loop (loop, insn_count, strength_reduce_p)
rtx ujump = ujump_to_loop_cont (loop->start, loop->cont);
if (ujump)
- delete_insn (ujump);
+ delete_related_insns (ujump);
/* If number of iterations is exactly 1, then eliminate the compare and
branch at the end of the loop since they will never be taken.
@@ -367,31 +367,31 @@ unroll_loop (loop, insn_count, strength_reduce_p)
if (GET_CODE (last_loop_insn) == BARRIER)
{
/* Delete the jump insn. This will delete the barrier also. */
- delete_insn (PREV_INSN (last_loop_insn));
+ delete_related_insns (PREV_INSN (last_loop_insn));
}
else if (GET_CODE (last_loop_insn) == JUMP_INSN)
{
#ifdef HAVE_cc0
rtx prev = PREV_INSN (last_loop_insn);
#endif
- delete_insn (last_loop_insn);
+ delete_related_insns (last_loop_insn);
#ifdef HAVE_cc0
/* The immediately preceding insn may be a compare which must be
deleted. */
if (only_sets_cc0_p (prev))
- delete_insn (prev);
+ delete_related_insns (prev);
#endif
}
/* Remove the loop notes since this is no longer a loop. */
if (loop->vtop)
- delete_insn (loop->vtop);
+ delete_related_insns (loop->vtop);
if (loop->cont)
- delete_insn (loop->cont);
+ delete_related_insns (loop->cont);
if (loop_start)
- delete_insn (loop_start);
+ delete_related_insns (loop_start);
if (loop_end)
- delete_insn (loop_end);
+ delete_related_insns (loop_end);
return;
}
@@ -1291,16 +1291,16 @@ unroll_loop (loop, insn_count, strength_reduce_p)
&& ! (GET_CODE (insn) == CODE_LABEL && LABEL_NAME (insn))
&& ! (GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))
- insn = delete_insn (insn);
+ insn = delete_related_insns (insn);
else
insn = NEXT_INSN (insn);
}
/* Can now delete the 'safety' label emitted to protect us from runaway
- delete_insn calls. */
+ delete_related_insns calls. */
if (INSN_DELETED_P (safety_label))
abort ();
- delete_insn (safety_label);
+ delete_related_insns (safety_label);
/* If exit_label exists, emit it after the loop. Doing the emit here
forces it to have a higher INSN_UID than any insn in the unrolled loop.
@@ -1315,13 +1315,13 @@ unroll_loop (loop, insn_count, strength_reduce_p)
{
/* Remove the loop notes since this is no longer a loop. */
if (loop->vtop)
- delete_insn (loop->vtop);
+ delete_related_insns (loop->vtop);
if (loop->cont)
- delete_insn (loop->cont);
+ delete_related_insns (loop->cont);
if (loop_start)
- delete_insn (loop_start);
+ delete_related_insns (loop_start);
if (loop_end)
- delete_insn (loop_end);
+ delete_related_insns (loop_end);
}
if (map->const_equiv_varray)
@@ -1562,7 +1562,7 @@ calculate_giv_inc (pattern, src_insn, regno)
/* The last insn emitted is not needed, so delete it to avoid confusing
the second cse pass. This insn sets the giv unnecessarily. */
- delete_insn (get_last_insn ());
+ delete_related_insns (get_last_insn ());
}
/* Verify that we have a constant as the second operand of the plus. */
@@ -1601,7 +1601,7 @@ calculate_giv_inc (pattern, src_insn, regno)
src_insn = PREV_INSN (src_insn);
increment = SET_SRC (PATTERN (src_insn));
/* Don't need the last insn anymore. */
- delete_insn (get_last_insn ());
+ delete_related_insns (get_last_insn ());
if (GET_CODE (second_part) != CONST_INT
|| GET_CODE (increment) != CONST_INT)
@@ -1620,7 +1620,7 @@ calculate_giv_inc (pattern, src_insn, regno)
/* The insn loading the constant into a register is no longer needed,
so delete it. */
- delete_insn (get_last_insn ());
+ delete_related_insns (get_last_insn ());
}
if (increment_total)
@@ -1644,7 +1644,7 @@ calculate_giv_inc (pattern, src_insn, regno)
src_insn = PREV_INSN (src_insn);
pattern = PATTERN (src_insn);
- delete_insn (get_last_insn ());
+ delete_related_insns (get_last_insn ());
goto retry;
}
@@ -2148,7 +2148,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
#ifdef HAVE_cc0
/* If the previous insn set cc0 for us, delete it. */
if (only_sets_cc0_p (PREV_INSN (copy)))
- delete_insn (PREV_INSN (copy));
+ delete_related_insns (PREV_INSN (copy));
#endif
/* If this is now a no-op, delete it. */
@@ -2159,7 +2159,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
instruction in the loop. */
if (JUMP_LABEL (copy))
LABEL_NUSES (JUMP_LABEL (copy))++;
- delete_insn (copy);
+ delete_related_insns (copy);
if (JUMP_LABEL (copy))
LABEL_NUSES (JUMP_LABEL (copy))--;
copy = 0;
@@ -2954,7 +2954,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
/* We can't use bl->initial_value to compute the initial
value, because the loop may have been preconditioned.
We must calculate it from NEW_REG. */
- delete_insn (PREV_INSN (loop->start));
+ delete_related_insns (PREV_INSN (loop->start));
start_sequence ();
ret = force_operand (v->new_reg, tem);