From 77d33a842d42d8de1dcfa142f8202ea60b4403ac Mon Sep 17 00:00:00 2001 From: Andrew Macleod Date: Mon, 16 Mar 1998 12:51:39 +0000 Subject: except.c (insn_eh_region, [...]): New static variables. * except.c (insn_eh_region, maximum_uid): New static variables. (set_insn_eh_region): New static function to set region numbers. (free_insn_eh_region): New function to free EH region table. (init_insn_eh_region): New function to initialize EH region table. (in_same_eh_region): New function used to determine if two rtl instructions are in the same exception region or not. From-SVN: r18624 --- gcc/except.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'gcc/except.c') diff --git a/gcc/except.c b/gcc/except.c index f8a17874c63..4a0c2491b5c 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -2168,3 +2168,109 @@ expand_builtin_set_eh_regs (handler, offset) emit_insn (gen_rtx_USE (VOIDmode, reg1)); emit_insn (gen_rtx_USE (VOIDmode, reg2)); } + + + +/* This contains the code required to verify whether arbitrary instructions + are in the same exception region. */ + +static int *insn_eh_region = (int *)0; +static int maximum_uid; + +static void set_insn_eh_region (first, region_num) + rtx *first; + int region_num; +{ + rtx insn; + int rnum; + + for (insn = *first; insn; insn = NEXT_INSN (insn)) + { + if ((GET_CODE (insn) == NOTE) && + (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)) + { + rnum = NOTE_BLOCK_NUMBER (insn); + insn_eh_region[INSN_UID (insn)] = rnum; + insn = NEXT_INSN (insn); + set_insn_eh_region (&insn, rnum); + /* Upon return, insn points to the EH_REGION_END of nested region */ + continue; + } + insn_eh_region[INSN_UID (insn)] = region_num; + if ((GET_CODE (insn) == NOTE) && + (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) + break; + } + *first = insn; +} + +/* Free the insn table, an make sure it cannot be used again. */ + +void free_insn_eh_region () +{ + if (!doing_eh (0)) + return; + + if (insn_eh_region) + { + free (insn_eh_region); + insn_eh_region = (int *)0; + } +} + +/* Initialize the table. max_uid must be calculated and handed into + this routine. If it is unavailable, passing a value of 0 will + cause this routine to calculate it as well. */ + +void init_insn_eh_region (first, max_uid) + rtx first; + int max_uid; +{ + rtx insn; + + if (!doing_eh (0)) + return; + + if (insn_eh_region) + free_insn_eh_region(); + + if (max_uid == 0) + for (insn = first; insn; insn = NEXT_INSN (insn)) + if (INSN_UID (insn) > max_uid) /* find largest UID */ + max_uid = INSN_UID (insn); + + maximum_uid = max_uid; + insn_eh_region = (int *) malloc ((max_uid + 1) * sizeof (int)); + insn = first; + set_insn_eh_region (&insn, 0); +} + + +/* Check whether 2 instructions are within the same region. */ + +int in_same_eh_region(insn1, insn2) + rtx insn1,insn2; +{ + int ret, uid1, uid2; + + /* If no exceptions, instructions are always in same region. */ + if (!doing_eh (0)) + return 1; + + /* If the table isn't allocated, assume the worst. */ + if (!insn_eh_region) + return 0; + + uid1 = INSN_UID (insn1); + uid2 = INSN_UID (insn2); + + /* if instructions have been allocated beyond the end, either + the table is out of date, or this is a late addition, or + something... Assume the worst. */ + if (uid1 > maximum_uid || uid2 > maximum_uid) + return 0; + + ret = (insn_eh_region[uid1] == insn_eh_region[uid2]); + return ret; +} + -- cgit v1.2.1