This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patches] Re: spec20000 eon fix
> On Fri, Aug 03, 2001 at 11:51:18PM +0200, Jan Hubicka wrote:
> > Perhaps "fixup_abnormal_edges"?
>
> Better.
>
> > I would need then to also update the frequencies and counts manually.
> > Inserting on the edges looked more clear to me.
>
> Hum. I guess it's ok then.
I am just testing following. Looks OK now?
So srp 4 01:16:45 CEST 2001 Jan Hubicka <jh@suse.cz>
* reload1.c (fixup_abnormal_edges): New static function.
(reload): Use it.
*** /p1/jumpr/egcs/gcc/reload1.c Thu Jul 12 18:03:44 2001
--- reload1.c Sat Aug 4 01:10:07 2001
*************** static void failed_reload PARAMS ((rtx,
*** 461,466 ****
--- 461,467 ----
static int set_reload_reg PARAMS ((int, int));
static void reload_cse_delete_noop_set PARAMS ((rtx, rtx));
static void reload_cse_simplify PARAMS ((rtx));
+ static void fixup_abnormal_edges PARAMS ((void));
extern void dump_needs PARAMS ((struct insn_chain *));
/* Initialize the reload pass once per compilation. */
*************** reload (first, global)
*** 1269,1274 ****
--- 1270,1276 ----
/* Free all the insn_chain structures at once. */
obstack_free (&reload_obstack, reload_startobj);
unused_insn_chains = 0;
+ fixup_abnormal_edges ();
return failure;
}
*************** copy_eh_notes (insn, x)
*** 9458,9460 ****
--- 9472,9527 ----
}
}
+ /* 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. */
+ static void
+ fixup_abnormal_edges ()
+ {
+ 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 ();
+ }