install EH code
From-SVN: r12549
This commit is contained in:
parent
3d1953912d
commit
6adb4e3a29
@ -127,6 +127,14 @@ struct function
|
|||||||
int emit_lineno;
|
int emit_lineno;
|
||||||
struct goto_fixup *goto_fixup_chain;
|
struct goto_fixup *goto_fixup_chain;
|
||||||
|
|
||||||
|
/* For exception handling information. */
|
||||||
|
struct eh_stack ehstack;
|
||||||
|
struct eh_queue ehqueue;
|
||||||
|
rtx catch_clauses;
|
||||||
|
struct label_node *false_label_stack;
|
||||||
|
struct label_node *caught_return_label_stack;
|
||||||
|
tree protect_list;
|
||||||
|
|
||||||
/* For expr.c. */
|
/* For expr.c. */
|
||||||
int pending_stack_adjust;
|
int pending_stack_adjust;
|
||||||
int inhibit_defer_pop;
|
int inhibit_defer_pop;
|
||||||
|
@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA. */
|
|||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "integrate.h"
|
#include "integrate.h"
|
||||||
#include "real.h"
|
#include "real.h"
|
||||||
|
#include "except.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "bytecode.h"
|
#include "bytecode.h"
|
||||||
|
|
||||||
@ -170,6 +171,19 @@ function_cannot_inline_p (fndecl)
|
|||||||
if (current_function_has_nonlocal_goto)
|
if (current_function_has_nonlocal_goto)
|
||||||
return "function with nonlocal goto cannot be inline";
|
return "function with nonlocal goto cannot be inline";
|
||||||
|
|
||||||
|
/* This is a hack, until the inliner is taught about eh regions at
|
||||||
|
the start of the function. */
|
||||||
|
for (insn = get_insns ();
|
||||||
|
insn &&
|
||||||
|
! (GET_CODE (insn) == NOTE
|
||||||
|
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG);
|
||||||
|
insn = NEXT_INSN (insn))
|
||||||
|
{
|
||||||
|
if (insn && GET_CODE (insn) == NOTE
|
||||||
|
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
|
||||||
|
return "function with complex parameters cannot be inline";
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +323,7 @@ initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, copy)
|
|||||||
the size of the incoming stack area for parameters,
|
the size of the incoming stack area for parameters,
|
||||||
the number of bytes popped on return,
|
the number of bytes popped on return,
|
||||||
the stack slot list,
|
the stack slot list,
|
||||||
|
the labels that are forced to exist,
|
||||||
some flags that are used to restore compiler globals,
|
some flags that are used to restore compiler globals,
|
||||||
the value of current_function_outgoing_args_size,
|
the value of current_function_outgoing_args_size,
|
||||||
the original argument vector,
|
the original argument vector,
|
||||||
@ -335,7 +350,7 @@ finish_inline (fndecl, head)
|
|||||||
tree fndecl;
|
tree fndecl;
|
||||||
rtx head;
|
rtx head;
|
||||||
{
|
{
|
||||||
NEXT_INSN (head) = get_first_nonparm_insn ();
|
FIRST_FUNCTION_INSN (head) = get_first_nonparm_insn ();
|
||||||
FIRST_PARM_INSN (head) = get_insns ();
|
FIRST_PARM_INSN (head) = get_insns ();
|
||||||
DECL_SAVED_INSNS (fndecl) = head;
|
DECL_SAVED_INSNS (fndecl) = head;
|
||||||
DECL_FRAME_SIZE (fndecl) = get_frame_size ();
|
DECL_FRAME_SIZE (fndecl) = get_frame_size ();
|
||||||
@ -565,6 +580,15 @@ save_for_inline_copying (fndecl)
|
|||||||
NOTE_SOURCE_FILE (insn) = (char *) copy;
|
NOTE_SOURCE_FILE (insn) = (char *) copy;
|
||||||
NOTE_SOURCE_FILE (copy) = 0;
|
NOTE_SOURCE_FILE (copy) = 0;
|
||||||
}
|
}
|
||||||
|
if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG
|
||||||
|
|| NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_END)
|
||||||
|
{
|
||||||
|
/* We have to forward these both to match the new exception
|
||||||
|
region. */
|
||||||
|
NOTE_BLOCK_NUMBER (copy)
|
||||||
|
= CODE_LABEL_NUMBER (label_map[NOTE_BLOCK_NUMBER (copy)]);
|
||||||
|
|
||||||
|
}
|
||||||
RTX_INTEGRATED_P (copy) = RTX_INTEGRATED_P (insn);
|
RTX_INTEGRATED_P (copy) = RTX_INTEGRATED_P (insn);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1872,7 +1896,18 @@ expand_inline_function (fndecl, parms, target, ignore, type,
|
|||||||
if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
|
if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
|
||||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
|
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
|
||||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
|
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
|
||||||
copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
|
{
|
||||||
|
copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
|
||||||
|
if (copy && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_BEG
|
||||||
|
|| NOTE_LINE_NUMBER (copy) == NOTE_INSN_EH_REGION_END))
|
||||||
|
{
|
||||||
|
rtx label = map->label_map[NOTE_BLOCK_NUMBER (copy)];
|
||||||
|
|
||||||
|
/* We have to forward these both to match the new exception
|
||||||
|
region. */
|
||||||
|
NOTE_BLOCK_NUMBER (copy) = CODE_LABEL_NUMBER (label);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
copy = 0;
|
copy = 0;
|
||||||
break;
|
break;
|
||||||
|
11
gcc/jump.c
11
gcc/jump.c
@ -60,6 +60,7 @@ Boston, MA 02111-1307, USA. */
|
|||||||
#include "insn-flags.h"
|
#include "insn-flags.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "real.h"
|
#include "real.h"
|
||||||
|
#include "except.h"
|
||||||
|
|
||||||
/* ??? Eventually must record somehow the labels used by jumps
|
/* ??? Eventually must record somehow the labels used by jumps
|
||||||
from nested functions. */
|
from nested functions. */
|
||||||
@ -234,6 +235,16 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
|
|||||||
for (insn = forced_labels; insn; insn = XEXP (insn, 1))
|
for (insn = forced_labels; insn; insn = XEXP (insn, 1))
|
||||||
LABEL_NUSES (XEXP (insn, 0))++;
|
LABEL_NUSES (XEXP (insn, 0))++;
|
||||||
|
|
||||||
|
check_exception_handler_labels ();
|
||||||
|
|
||||||
|
/* Keep track of labels used for marking handlers for exception
|
||||||
|
regions; they cannot usually be deleted. */
|
||||||
|
|
||||||
|
for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
|
||||||
|
LABEL_NUSES (XEXP (insn, 0))++;
|
||||||
|
|
||||||
|
exception_optimize ();
|
||||||
|
|
||||||
/* Delete all labels already not referenced.
|
/* Delete all labels already not referenced.
|
||||||
Also find the last insn. */
|
Also find the last insn. */
|
||||||
|
|
||||||
|
@ -2989,6 +2989,13 @@ int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
|
|||||||
#endif /* L_exit */
|
#endif /* L_exit */
|
||||||
|
|
||||||
#ifdef L_eh
|
#ifdef L_eh
|
||||||
|
|
||||||
|
#ifdef EH_TABLE_LOOKUP
|
||||||
|
|
||||||
|
EH_TABLE_LOOKUP
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *start;
|
void *start;
|
||||||
void *end;
|
void *end;
|
||||||
@ -3095,21 +3102,9 @@ void *pc;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("find_first_eh_table_match(): else: returning NULL!\n");
|
printf ("find_first_eh_table_match(): else: returning NULL!\n");
|
||||||
#endif
|
#endif
|
||||||
return (void*)0;
|
return (void *) 0;
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
__throw_type_match (void *catch_type, void *throw_type, void* obj)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
|
|
||||||
catch_type, throw_type);
|
|
||||||
#endif
|
|
||||||
if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
|
|
||||||
return obj;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3140,6 +3135,19 @@ __register_exceptions (exception_table *table)
|
|||||||
node->next = exception_table_list;
|
node->next = exception_table_list;
|
||||||
exception_table_list = node;
|
exception_table_list = node;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *
|
||||||
|
__throw_type_match (void *catch_type, void *throw_type, void *obj)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
|
||||||
|
catch_type, throw_type);
|
||||||
|
#endif
|
||||||
|
if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
|
||||||
|
return obj;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
__empty ()
|
__empty ()
|
||||||
|
14
gcc/loop.c
14
gcc/loop.c
@ -47,6 +47,7 @@ Boston, MA 02111-1307, USA. */
|
|||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
#include "real.h"
|
#include "real.h"
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
#include "except.h"
|
||||||
|
|
||||||
/* Vector mapping INSN_UIDs to luids.
|
/* Vector mapping INSN_UIDs to luids.
|
||||||
The luids are like uids but increase monotonically always.
|
The luids are like uids but increase monotonically always.
|
||||||
@ -2290,6 +2291,19 @@ find_and_verify_loops (f)
|
|||||||
loop_invalid[loop_num] = 1;
|
loop_invalid[loop_num] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Any loop containing a label used for an exception handler must be
|
||||||
|
invalidated, because it can be jumped into from anywhere. */
|
||||||
|
|
||||||
|
for (label = exception_handler_labels; label; label = XEXP (label, 1))
|
||||||
|
{
|
||||||
|
int loop_num;
|
||||||
|
|
||||||
|
for (loop_num = uid_loop_num[INSN_UID (XEXP (label, 0))];
|
||||||
|
loop_num != -1;
|
||||||
|
loop_num = loop_outer_loop[loop_num])
|
||||||
|
loop_invalid[loop_num] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now scan all insn's in the function. If any JUMP_INSN branches into a
|
/* Now scan all insn's in the function. If any JUMP_INSN branches into a
|
||||||
loop that it is not contained within, that loop is marked invalid.
|
loop that it is not contained within, that loop is marked invalid.
|
||||||
If any INSN or CALL_INSN uses a label's address, then the loop containing
|
If any INSN or CALL_INSN uses a label's address, then the loop containing
|
||||||
|
@ -118,6 +118,8 @@ rtx bcmp_libfunc;
|
|||||||
rtx memset_libfunc;
|
rtx memset_libfunc;
|
||||||
rtx bzero_libfunc;
|
rtx bzero_libfunc;
|
||||||
|
|
||||||
|
rtx throw_libfunc;
|
||||||
|
|
||||||
rtx eqhf2_libfunc;
|
rtx eqhf2_libfunc;
|
||||||
rtx nehf2_libfunc;
|
rtx nehf2_libfunc;
|
||||||
rtx gthf2_libfunc;
|
rtx gthf2_libfunc;
|
||||||
@ -4247,6 +4249,8 @@ init_optabs ()
|
|||||||
memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
|
memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
|
||||||
bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
|
bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
|
||||||
|
|
||||||
|
throw_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__throw");
|
||||||
|
|
||||||
eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
|
eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
|
||||||
nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
|
nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
|
||||||
gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
|
gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
|
||||||
|
@ -140,6 +140,9 @@ extern void named_section PROTO((tree, char *));
|
|||||||
/* Tell assembler to switch to the section for function DECL. */
|
/* Tell assembler to switch to the section for function DECL. */
|
||||||
extern void function_section PROTO((tree));
|
extern void function_section PROTO((tree));
|
||||||
|
|
||||||
|
/* Tell assembler to switch to the section for the exception table. */
|
||||||
|
extern void exception_section PROTO((void));
|
||||||
|
|
||||||
/* Create the rtl to represent a function, for a function definition.
|
/* Create the rtl to represent a function, for a function definition.
|
||||||
DECL is a FUNCTION_DECL node which describes which function.
|
DECL is a FUNCTION_DECL node which describes which function.
|
||||||
The rtl is stored into DECL. */
|
The rtl is stored into DECL. */
|
||||||
|
@ -108,6 +108,14 @@ print_rtx (in_rtx)
|
|||||||
{
|
{
|
||||||
case 'S':
|
case 'S':
|
||||||
case 's':
|
case 's':
|
||||||
|
if (i == 3 && GET_CODE (in_rtx) == NOTE
|
||||||
|
&& (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_BEG
|
||||||
|
|| NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_EH_REGION_END))
|
||||||
|
{
|
||||||
|
fprintf (outfile, " %d", NOTE_BLOCK_NUMBER (in_rtx));
|
||||||
|
sawclose = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (XSTR (in_rtx, i) == 0)
|
if (XSTR (in_rtx, i) == 0)
|
||||||
fprintf (outfile, " \"\"");
|
fprintf (outfile, " \"\"");
|
||||||
else
|
else
|
||||||
|
60
gcc/sched.c
60
gcc/sched.c
@ -111,9 +111,11 @@ Boston, MA 02111-1307, USA. */
|
|||||||
reg_n_calls_crossed, and reg_live_length. Also, basic_block_head,
|
reg_n_calls_crossed, and reg_live_length. Also, basic_block_head,
|
||||||
basic_block_end.
|
basic_block_end.
|
||||||
|
|
||||||
The information in the line number notes is carefully retained by this
|
The information in the line number notes is carefully retained by
|
||||||
pass. All other NOTE insns are grouped in their same relative order at
|
this pass. Notes that refer to the starting and ending of
|
||||||
the beginning of basic blocks that have been scheduled. */
|
exception regions are also carefully retained by this pass. All
|
||||||
|
other NOTE insns are grouped in their same relative order at the
|
||||||
|
beginning of basic blocks that have been scheduled. */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -2078,7 +2080,7 @@ sched_analyze_insn (x, insn, loop_notes)
|
|||||||
sched_analyze_2 (XEXP (link, 0), insn);
|
sched_analyze_2 (XEXP (link, 0), insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there is a LOOP_{BEG,END} note in the middle of a basic block, then
|
/* If there is a {LOOP,EHREGION}_{BEG,END} note in the middle of a basic block, then
|
||||||
we must be sure that no instructions are scheduled across it.
|
we must be sure that no instructions are scheduled across it.
|
||||||
Otherwise, the reg_n_refs info (which depends on loop_depth) would
|
Otherwise, the reg_n_refs info (which depends on loop_depth) would
|
||||||
become incorrect. */
|
become incorrect. */
|
||||||
@ -2240,8 +2242,13 @@ sched_analyze (head, tail)
|
|||||||
}
|
}
|
||||||
reg_pending_sets_all = 1;
|
reg_pending_sets_all = 1;
|
||||||
|
|
||||||
/* Add a fake REG_NOTE which we will later convert
|
/* Add a pair of fake REG_NOTEs which we will later
|
||||||
back into a NOTE_INSN_SETJMP note. */
|
convert back into a NOTE_INSN_SETJMP note. See
|
||||||
|
reemit_notes for why we use a pair of of NOTEs. */
|
||||||
|
|
||||||
|
REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD,
|
||||||
|
GEN_INT (0),
|
||||||
|
REG_NOTES (insn));
|
||||||
REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD,
|
REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD,
|
||||||
GEN_INT (NOTE_INSN_SETJMP),
|
GEN_INT (NOTE_INSN_SETJMP),
|
||||||
REG_NOTES (insn));
|
REG_NOTES (insn));
|
||||||
@ -2285,12 +2292,18 @@ sched_analyze (head, tail)
|
|||||||
last_function_call = insn;
|
last_function_call = insn;
|
||||||
n_insns += 1;
|
n_insns += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See comments on reemit_notes as to why we do this. */
|
||||||
else if (GET_CODE (insn) == NOTE
|
else if (GET_CODE (insn) == NOTE
|
||||||
&& (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
|
&& (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
|
||||||
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
|
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
|
||||||
|
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
|
||||||
|
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END
|
||||||
|| (NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP
|
|| (NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP
|
||||||
&& GET_CODE (PREV_INSN (insn)) != CALL_INSN)))
|
&& GET_CODE (PREV_INSN (insn)) != CALL_INSN)))
|
||||||
{
|
{
|
||||||
|
loop_notes = gen_rtx (EXPR_LIST, REG_DEAD,
|
||||||
|
GEN_INT (NOTE_BLOCK_NUMBER (insn)), loop_notes);
|
||||||
loop_notes = gen_rtx (EXPR_LIST, REG_DEAD,
|
loop_notes = gen_rtx (EXPR_LIST, REG_DEAD,
|
||||||
GEN_INT (NOTE_LINE_NUMBER (insn)), loop_notes);
|
GEN_INT (NOTE_LINE_NUMBER (insn)), loop_notes);
|
||||||
CONST_CALL_P (loop_notes) = CONST_CALL_P (insn);
|
CONST_CALL_P (loop_notes) = CONST_CALL_P (insn);
|
||||||
@ -3077,10 +3090,12 @@ unlink_notes (insn, tail)
|
|||||||
/* Don't save away NOTE_INSN_SETJMPs, because they must remain
|
/* Don't save away NOTE_INSN_SETJMPs, because they must remain
|
||||||
immediately after the call they follow. We use a fake
|
immediately after the call they follow. We use a fake
|
||||||
(REG_DEAD (const_int -1)) note to remember them.
|
(REG_DEAD (const_int -1)) note to remember them.
|
||||||
Likewise with NOTE_INSN_LOOP_BEG and NOTE_INSN_LOOP_END. */
|
Likewise with NOTE_INSN_{LOOP,EHREGION}_{BEG, END}. */
|
||||||
else if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_SETJMP
|
else if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_SETJMP
|
||||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG
|
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG
|
||||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_END)
|
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_END
|
||||||
|
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
|
||||||
|
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_END)
|
||||||
{
|
{
|
||||||
/* Insert the note at the end of the notes list. */
|
/* Insert the note at the end of the notes list. */
|
||||||
PREV_INSN (insn) = note_list;
|
PREV_INSN (insn) = note_list;
|
||||||
@ -3143,10 +3158,12 @@ finish_sometimes_live (regs_sometimes_live, sometimes_max)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search INSN for fake REG_DEAD notes for NOTE_INSN_SETJMP,
|
/* Search INSN for fake REG_DEAD note pairs for NOTE_INSN_SETJMP,
|
||||||
NOTE_INSN_LOOP_BEG, and NOTE_INSN_LOOP_END; and convert them back
|
NOTE_INSN_{LOOP,EHREGION}_{BEG,END}; and convert them back into
|
||||||
into NOTEs. LAST is the last instruction output by the instruction
|
NOTEs. The REG_DEAD note following first one is contains the saved
|
||||||
scheduler. Return the new value of LAST. */
|
value for NOTE_BLOCK_NUMBER which is useful for
|
||||||
|
NOTE_INSN_EH_REGION_{BEG,END} NOTEs. LAST is the last instruction
|
||||||
|
output by the instruction scheduler. Return the new value of LAST. */
|
||||||
|
|
||||||
static rtx
|
static rtx
|
||||||
reemit_notes (insn, last)
|
reemit_notes (insn, last)
|
||||||
@ -3161,10 +3178,19 @@ reemit_notes (insn, last)
|
|||||||
&& GET_CODE (XEXP (note, 0)) == CONST_INT)
|
&& GET_CODE (XEXP (note, 0)) == CONST_INT)
|
||||||
{
|
{
|
||||||
if (INTVAL (XEXP (note, 0)) == NOTE_INSN_SETJMP)
|
if (INTVAL (XEXP (note, 0)) == NOTE_INSN_SETJMP)
|
||||||
CONST_CALL_P (emit_note_after (INTVAL (XEXP (note, 0)), insn))
|
{
|
||||||
= CONST_CALL_P (note);
|
CONST_CALL_P (emit_note_after (INTVAL (XEXP (note, 0)), insn))
|
||||||
|
= CONST_CALL_P (note);
|
||||||
|
remove_note (insn, note);
|
||||||
|
note = XEXP (note, 1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
last = emit_note_before (INTVAL (XEXP (note, 0)), last);
|
{
|
||||||
|
last = emit_note_before (INTVAL (XEXP (note, 0)), last);
|
||||||
|
remove_note (insn, note);
|
||||||
|
note = XEXP (note, 1);
|
||||||
|
NOTE_BLOCK_NUMBER (last) = INTVAL (XEXP (note, 0));
|
||||||
|
}
|
||||||
remove_note (insn, note);
|
remove_note (insn, note);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3961,8 +3987,8 @@ schedule_block (b, file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put back NOTE_INSN_SETJMP, NOTE_INSN_LOOP_BEGIN, and
|
/* Put back NOTE_INSN_SETJMP,
|
||||||
NOTE_INSN_LOOP_END notes. */
|
NOTE_INSN_{LOOP,EHREGION}_{BEGIN,END} notes. */
|
||||||
|
|
||||||
/* To prime the loop. We need to handle INSN and all the insns in the
|
/* To prime the loop. We need to handle INSN and all the insns in the
|
||||||
sched group. */
|
sched group. */
|
||||||
|
15
gcc/stmt.c
15
gcc/stmt.c
@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA. */
|
|||||||
#include "rtl.h"
|
#include "rtl.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
#include "except.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "insn-flags.h"
|
#include "insn-flags.h"
|
||||||
#include "insn-config.h"
|
#include "insn-config.h"
|
||||||
@ -134,8 +135,6 @@ extern tree rtl_expr_chain;
|
|||||||
cleanup list whenever an empty list is required. */
|
cleanup list whenever an empty list is required. */
|
||||||
static tree empty_cleanup_list;
|
static tree empty_cleanup_list;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void (*interim_eh_hook) PROTO((tree));
|
|
||||||
|
|
||||||
/* Functions and data structures for expanding case statements. */
|
/* Functions and data structures for expanding case statements. */
|
||||||
|
|
||||||
@ -473,9 +472,7 @@ void
|
|||||||
init_stmt ()
|
init_stmt ()
|
||||||
{
|
{
|
||||||
gcc_obstack_init (&stmt_obstack);
|
gcc_obstack_init (&stmt_obstack);
|
||||||
#if 0
|
init_eh ();
|
||||||
empty_cleanup_list = build_tree_list (NULL_TREE, NULL_TREE);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -498,6 +495,8 @@ init_stmt_for_function ()
|
|||||||
/* We are not processing a ({...}) grouping. */
|
/* We are not processing a ({...}) grouping. */
|
||||||
expr_stmts_for_value = 0;
|
expr_stmts_for_value = 0;
|
||||||
last_expr_type = 0;
|
last_expr_type = 0;
|
||||||
|
|
||||||
|
init_eh_for_function ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -518,6 +517,7 @@ save_stmt_status (p)
|
|||||||
p->emit_filename = emit_filename;
|
p->emit_filename = emit_filename;
|
||||||
p->emit_lineno = emit_lineno;
|
p->emit_lineno = emit_lineno;
|
||||||
p->goto_fixup_chain = goto_fixup_chain;
|
p->goto_fixup_chain = goto_fixup_chain;
|
||||||
|
save_eh_status (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -538,6 +538,7 @@ restore_stmt_status (p)
|
|||||||
emit_filename = p->emit_filename;
|
emit_filename = p->emit_filename;
|
||||||
emit_lineno = p->emit_lineno;
|
emit_lineno = p->emit_lineno;
|
||||||
goto_fixup_chain = p->goto_fixup_chain;
|
goto_fixup_chain = p->goto_fixup_chain;
|
||||||
|
restore_eh_status (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emit a no-op instruction. */
|
/* Emit a no-op instruction. */
|
||||||
@ -3730,7 +3731,7 @@ expand_decl_cleanup (decl, cleanup)
|
|||||||
= temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
|
= temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
|
||||||
/* If this block has a cleanup, it belongs in stack_block_stack. */
|
/* If this block has a cleanup, it belongs in stack_block_stack. */
|
||||||
stack_block_stack = thisblock;
|
stack_block_stack = thisblock;
|
||||||
(*interim_eh_hook) (NULL_TREE);
|
expand_eh_region_start ();
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -3831,7 +3832,7 @@ expand_cleanups (list, dont_do, in_fixup, reachable)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (! in_fixup)
|
if (! in_fixup)
|
||||||
(*interim_eh_hook) (TREE_VALUE (tail));
|
expand_eh_region_end (TREE_VALUE (tail));
|
||||||
|
|
||||||
if (reachable)
|
if (reachable)
|
||||||
{
|
{
|
||||||
|
21
gcc/varasm.c
21
gcc/varasm.c
@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA. */
|
|||||||
#include "rtl.h"
|
#include "rtl.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
#include "except.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
@ -414,6 +415,26 @@ variable_section (decl, reloc)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tell assembler to switch to the section for the exception handling
|
||||||
|
table. */
|
||||||
|
|
||||||
|
void
|
||||||
|
exception_section ()
|
||||||
|
{
|
||||||
|
#ifdef ASM_OUTPUT_SECTION_NAME
|
||||||
|
named_section (NULL_TREE, ".gcc_except_table");
|
||||||
|
#else
|
||||||
|
if (flag_pic)
|
||||||
|
data_section ();
|
||||||
|
else
|
||||||
|
#if defined (EXCEPTION_SECTION)
|
||||||
|
EXCEPTION_SECTION ();
|
||||||
|
#else
|
||||||
|
readonly_data_section ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the rtl to represent a function, for a function definition.
|
/* Create the rtl to represent a function, for a function definition.
|
||||||
DECL is a FUNCTION_DECL node which describes which function.
|
DECL is a FUNCTION_DECL node which describes which function.
|
||||||
|
Loading…
Reference in New Issue
Block a user