Eliminate false DV warnings for predicated calls to noreturn functions.
* calls.c (emit_call_1): Add REG_NORETURN note to call if ECF_NORETURN. * combine.c (distribute_notes): Handle REG_NORETURN. * rtl.c (reg_note_name): Add REG_NORETURN. * rtl.h (enum reg_note): Likewise. * config/ia64/ia64-protos.h (emit_safe_across_calls): Renamed from ia64_file_start. * config/ia64/ia64.c (emit_safe_across_calls): Likewise. (rtx_needs_barrier): Handle unspec_volatile 8 and 9. (emit_predicate_relation_info): Handle conditional calls with REG_NORETURN. * config/ia64/ia64.h (ASM_FILE_START): Call emit_safe_across_calls instead of ia64_file_start. * config/ia64/sysv4.h (ASM_FILE_START): Likewise. * config/ia64/ia64.md (safe_across_calls_all, save_across_calls_normal): New patterns. From-SVN: r36107
This commit is contained in:
parent
3c786c6945
commit
ca3920adb2
@ -24,6 +24,23 @@
|
||||
|
||||
2000-09-01 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* calls.c (emit_call_1): Add REG_NORETURN note to call if ECF_NORETURN.
|
||||
* combine.c (distribute_notes): Handle REG_NORETURN.
|
||||
* rtl.c (reg_note_name): Add REG_NORETURN.
|
||||
* rtl.h (enum reg_note): Likewise.
|
||||
|
||||
* config/ia64/ia64-protos.h (emit_safe_across_calls): Renamed from
|
||||
ia64_file_start.
|
||||
* config/ia64/ia64.c (emit_safe_across_calls): Likewise.
|
||||
(rtx_needs_barrier): Handle unspec_volatile 8 and 9.
|
||||
(emit_predicate_relation_info): Handle conditional calls with
|
||||
REG_NORETURN.
|
||||
* config/ia64/ia64.h (ASM_FILE_START): Call emit_safe_across_calls
|
||||
instead of ia64_file_start.
|
||||
* config/ia64/sysv4.h (ASM_FILE_START): Likewise.
|
||||
* config/ia64/ia64.md (safe_across_calls_all,
|
||||
save_across_calls_normal): New patterns.
|
||||
|
||||
* loop.c (check_final_value): Check for biv use before checking for
|
||||
giv use. Check for both biv and giv uses. Always set last_giv_use
|
||||
if there is a giv use.
|
||||
|
@ -605,6 +605,10 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
|
||||
REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, const0_rtx,
|
||||
REG_NOTES (call_insn));
|
||||
|
||||
if (ecf_flags & ECF_NORETURN)
|
||||
REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_NORETURN, const0_rtx,
|
||||
REG_NOTES (call_insn));
|
||||
|
||||
SIBLING_CALL_P (call_insn) = ((ecf_flags & ECF_SIBCALL) != 0);
|
||||
|
||||
/* Restore this now, so that we do defer pops for this call's args
|
||||
|
@ -12036,6 +12036,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
|
||||
|
||||
case REG_EH_REGION:
|
||||
case REG_EH_RETHROW:
|
||||
case REG_NORETURN:
|
||||
/* These notes must remain with the call. It should not be
|
||||
possible for both I2 and I3 to be a call. */
|
||||
if (GET_CODE (i3) == CALL_INSN)
|
||||
|
@ -118,7 +118,7 @@ extern void ia64_encode_section_info PARAMS((tree));
|
||||
|
||||
extern int ia64_register_move_cost PARAMS((enum reg_class, enum reg_class));
|
||||
extern int ia64_epilogue_uses PARAMS((int));
|
||||
extern void ia64_file_start PARAMS((FILE *));
|
||||
extern void emit_safe_across_calls PARAMS((FILE *));
|
||||
extern void ia64_output_end_prologue PARAMS((FILE *));
|
||||
extern void ia64_init_builtins PARAMS((void));
|
||||
extern void ia64_override_options PARAMS((void));
|
||||
|
@ -984,7 +984,7 @@ spill_tfmode_operand (in, force)
|
||||
/* Begin the assembly file. */
|
||||
|
||||
void
|
||||
ia64_file_start (f)
|
||||
emit_safe_across_calls (f)
|
||||
FILE *f;
|
||||
{
|
||||
unsigned int rs, re;
|
||||
@ -4003,6 +4003,8 @@ rtx_needs_barrier (x, flags, pred)
|
||||
break;
|
||||
|
||||
case 7: /* pred.rel.mutex */
|
||||
case 8: /* safe_across_calls all */
|
||||
case 9: /* safe_across_calls normal */
|
||||
return 0;
|
||||
|
||||
default:
|
||||
@ -4249,6 +4251,35 @@ emit_predicate_relation_info (insns)
|
||||
head = n;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for conditional calls that do not return, and protect predicate
|
||||
relations around them. Otherwise the assembler will assume the call
|
||||
returns, and complain about uses of call-clobbered predicates after
|
||||
the call. */
|
||||
for (i = n_basic_blocks - 1; i >= 0; --i)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
rtx insn = bb->head;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (GET_CODE (insn) == CALL_INSN
|
||||
&& GET_CODE (PATTERN (insn)) == COND_EXEC
|
||||
&& find_reg_note (insn, REG_NORETURN, NULL_RTX))
|
||||
{
|
||||
rtx b = emit_insn_before (gen_safe_across_calls_all (), insn);
|
||||
rtx a = emit_insn_after (gen_safe_across_calls_normal (), insn);
|
||||
if (bb->head == insn)
|
||||
bb->head = b;
|
||||
if (bb->end == insn)
|
||||
bb->end = a;
|
||||
}
|
||||
|
||||
if (insn == bb->end)
|
||||
break;
|
||||
insn = NEXT_INSN (insn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform machine dependent operations on the rtl chain INSNS. */
|
||||
|
@ -1479,7 +1479,7 @@ do { \
|
||||
/* Output at beginning of assembler file. */
|
||||
|
||||
#define ASM_FILE_START(FILE) \
|
||||
ia64_file_start (FILE)
|
||||
emit_safe_across_calls (FILE)
|
||||
|
||||
/* A C compound statement that outputs the assembler code for a thunk function,
|
||||
used to implement C++ virtual function calls with multiple inheritance. */
|
||||
|
@ -70,6 +70,8 @@
|
||||
;; 2 insn_group_barrier
|
||||
;; 5 set_bsp
|
||||
;; 7 pred.rel.mutex
|
||||
;; 8 pred.safe_across_calls all
|
||||
;; 9 pred.safe_across_calls normal
|
||||
|
||||
;; ::::::::::::::::::::
|
||||
;; ::
|
||||
@ -3953,3 +3955,22 @@
|
||||
".pred.rel.mutex %0, %I0"
|
||||
[(set_attr "type" "unknown")
|
||||
(set_attr "predicable" "no")])
|
||||
|
||||
(define_insn "safe_across_calls_all"
|
||||
[(unspec_volatile [(const_int 0)] 8)]
|
||||
""
|
||||
".pred.safe_across_calls p1-p63"
|
||||
[(set_attr "type" "unknown")
|
||||
(set_attr "predicable" "no")])
|
||||
|
||||
(define_insn "safe_across_calls_normal"
|
||||
[(unspec_volatile [(const_int 0)] 9)]
|
||||
""
|
||||
"*
|
||||
{
|
||||
emit_safe_across_calls (asm_out_file);
|
||||
return \"\";
|
||||
}"
|
||||
[(set_attr "type" "unknown")
|
||||
(set_attr "predicable" "no")])
|
||||
|
||||
|
@ -178,7 +178,7 @@ do { \
|
||||
#define ASM_FILE_START(STREAM) \
|
||||
do { \
|
||||
output_file_directive (STREAM, main_input_filename); \
|
||||
ia64_file_start(STREAM); \
|
||||
emit_safe_across_calls (STREAM); \
|
||||
} while (0)
|
||||
|
||||
/* Case label alignment is handled by ADDR_VEC_ALIGN now. */
|
||||
|
@ -277,7 +277,7 @@ const char * const reg_note_name[] =
|
||||
"REG_LABEL", "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
|
||||
"REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED",
|
||||
"REG_FRAME_RELATED_EXPR", "REG_EH_CONTEXT", "REG_EH_REGION",
|
||||
"REG_EH_RETHROW", "REG_SAVE_NOTE", "REG_MAYBE_DEAD"
|
||||
"REG_EH_RETHROW", "REG_SAVE_NOTE", "REG_MAYBE_DEAD", "REG_NORETURN"
|
||||
};
|
||||
|
||||
static void fatal_with_file_and_line PARAMS ((FILE *, const char *, ...))
|
||||
|
@ -543,7 +543,10 @@ enum reg_note
|
||||
a value which might not be used later, and if so it's OK to delete
|
||||
the insn. Normally, deleting any insn in the prologue is an error.
|
||||
At present the parameter is unused and set to (const_int 0). */
|
||||
REG_MAYBE_DEAD
|
||||
REG_MAYBE_DEAD,
|
||||
|
||||
/* Indicates that a call does not return. */
|
||||
REG_NORETURN
|
||||
};
|
||||
|
||||
/* The base value for branch probability notes. */
|
||||
|
Loading…
Reference in New Issue
Block a user