spec20000 eon fix
Jan Hubicka
jh@suse.cz
Fri Aug 3 14:26:00 GMT 2001
> On Fri, Aug 03, 2001 at 10:34:38PM +0200, Jan Hubicka wrote:
> > OK, I can take a look for the edges - what flag they get?
>
> EDGE_EH | EDGE_ABNORMAL
>
> > How can I recognize instructions that throws?
>
> can_throw_internal
I am just testing the attached patch. Does it look OK now?
Pá srp 3 21:12:55 CEST 2001 Jan Hubicka <jh@suse.cz>
* flow.c (verify_flow_info): Verify that abnormal call edge are
going from calls.
(fixup_abnormal_calls): New function.
* rtl.h (fixup_abnormal_calls): Declare.
* toplev.c (rest_of_compilation): Use it.
*** flow.c.older Fri Aug 3 19:52:41 2001
--- flow.c Fri Aug 3 19:57:46 2001
*** toplev.c1 Mon Jun 18 19:12:26 2001
--- toplev.c Fri Aug 3 19:53:30 2001
*************** rest_of_compilation (decl)
*** 3482,3487 ****
--- 3423,3429 ----
build_insn_chain (insns);
failure = reload (insns, 0);
}
+ fixup_abnormal_calls ();
timevar_pop (TV_GLOBAL_ALLOC);
*** rtl.h.old Fri Aug 3 21:12:23 2001
--- rtl.h Fri Aug 3 21:12:41 2001
*************** extern void recompute_reg_usage PARAMS
*** 1844,1849 ****
--- 1844,1850 ----
extern void print_rtl_with_bb PARAMS ((FILE *, rtx));
extern void dump_flow_info PARAMS ((FILE *));
#endif
+ extern void fixup_abnormal_calls PARAMS ((void));
/* In expmed.c */
extern void init_expmed PARAMS ((void));
*** flow.c.older Fri Aug 3 19:52:41 2001
--- flow.c Sat Aug 4 00:26:25 2001
*************** verify_flow_info ()
*** 8328,8333 ****
--- 8328,8339 ----
}
last_visited [e->dest->index + 2] = bb;
+ if (e->flags & EDGE_ABNORMAL_CALL && GET_CODE (bb->end) != CALL_INSN)
+ {
+ error ("verify_flow_info: Abnormal call edge outgoing from BB %i not ending by CALL_INSN",
+ bb->index);
+ err = 1;
+ }
if (e->flags & EDGE_FALLTHRU)
has_fallthru = 1;
*************** purge_all_dead_edges ()
*** 10220,10223 ****
--- 10226,10283 ----
int i;
for (i = 0; i < n_basic_blocks; i++)
purge_dead_edges (BASIC_BLOCK (i));
+ }
+
+ /* This is used by reload pass, that does emit some instructions after
+ abnormal calls moving basic block end, but in fact it wants to emit
+ them on the edge. Looks for abnormal call edges, find backward the
+ proper call and fix the damage.
+
+ Similar handle instructions throwing exceptions internally. */
+ void
+ fixup_abnormal_calls ()
+ {
+ int i;
+ bool inserted = false;
+
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ edge e;
+
+ /* Look for cases we are interested in - an calls or instructions causing
+ exceptions. */
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (e->flags & EDGE_ABNORMAL_CALL)
+ break;
+ if ((e->flags & (EDGE_ABNORMAL | EDGE_EH))
+ == (EDGE_ABNORMAL | EDGE_EH))
+ break;
+ }
+ if (e && GET_CODE (bb->end) != CALL_INSN && !can_throw_internal (bb->end))
+ {
+ rtx insn = bb->end;
+ rtx next;
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+ while (GET_CODE (insn) == INSN && !can_throw_internal (insn))
+ insn = PREV_INSN (insn);
+ if (GET_CODE (insn) != CALL_INSN && !can_throw_internal (insn))
+ abort ();
+ bb->end = insn;
+ inserted = true;
+ insn = NEXT_INSN (insn);
+ while (insn && GET_CODE (insn) == INSN)
+ {
+ next = NEXT_INSN (insn);
+ insert_insn_on_edge (PATTERN (insn), e);
+ flow_delete_insn (insn);
+ insn = next;
+ }
+ }
+ }
+ if (inserted)
+ commit_edge_insertions ();
}
More information about the Gcc-patches
mailing list