mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 03:46:53 -05:00
ifcvt.c (noce_can_store_speculate_p): New static function.
* ifcvt.c (noce_can_store_speculate_p): New static function. (noce_process_if_block): Call it. (find_if_header): Only call find_if_case_1 and find_if_case_2 if life_data_ok is set. (if_convert): Always compute postdominators. From-SVN: r129763
This commit is contained in:
committed by
Ian Lance Taylor
parent
280ed215ff
commit
2e84c07f06
@@ -1,3 +1,11 @@
|
||||
2007-10-29 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* ifcvt.c (noce_can_store_speculate_p): New static function.
|
||||
(noce_process_if_block): Call it.
|
||||
(find_if_header): Only call find_if_case_1 and find_if_case_2 if
|
||||
life_data_ok is set.
|
||||
(if_convert): Always compute postdominators.
|
||||
|
||||
2007-10-29 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
* doc/invoke.texi (Option Summary, optimizations): Remove
|
||||
|
||||
84
gcc/ifcvt.c
84
gcc/ifcvt.c
@@ -2163,6 +2163,46 @@ noce_mem_write_may_trap_or_fault_p (rtx mem)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return whether we can use store speculation for MEM. TOP_BB is the
|
||||
basic block above the conditional block where we are considering
|
||||
doing the speculative store. We look for whether MEM is set
|
||||
unconditionally later in the function. */
|
||||
|
||||
static bool
|
||||
noce_can_store_speculate_p (basic_block top_bb, rtx mem)
|
||||
{
|
||||
basic_block dominator;
|
||||
|
||||
for (dominator = get_immediate_dominator (CDI_POST_DOMINATORS, top_bb);
|
||||
dominator != NULL;
|
||||
dominator = get_immediate_dominator (CDI_POST_DOMINATORS, dominator))
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
FOR_BB_INSNS (dominator, insn)
|
||||
{
|
||||
/* If we see something that might be a memory barrier, we
|
||||
have to stop looking. Even if the MEM is set later in
|
||||
the function, we still don't want to set it
|
||||
unconditionally before the barrier. */
|
||||
if (INSN_P (insn)
|
||||
&& (volatile_insn_p (PATTERN (insn))
|
||||
|| (CALL_P (insn)
|
||||
&& (!CONST_OR_PURE_CALL_P (insn)
|
||||
|| pure_call_p (insn)))))
|
||||
return false;
|
||||
|
||||
if (memory_modified_in_insn_p (mem, insn))
|
||||
return true;
|
||||
if (modified_in_p (XEXP (mem, 0), insn))
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
|
||||
without using conditional execution. Return TRUE if we were
|
||||
successful at converting the block. */
|
||||
@@ -2321,17 +2361,31 @@ noce_process_if_block (struct ce_if_block * ce_info)
|
||||
goto success;
|
||||
}
|
||||
|
||||
/* Disallow the "if (...) x = a;" form (with an implicit "else x = x;")
|
||||
for optimizations if writing to x may trap or fault, i.e. it's a memory
|
||||
other than a static var or a stack slot, is misaligned on strict
|
||||
aligned machines or is read-only.
|
||||
If x is a read-only memory, then the program is valid only if we
|
||||
avoid the store into it. If there are stores on both the THEN and
|
||||
ELSE arms, then we can go ahead with the conversion; either the
|
||||
program is broken, or the condition is always false such that the
|
||||
other memory is selected. */
|
||||
if (!set_b && MEM_P (orig_x) && noce_mem_write_may_trap_or_fault_p (orig_x))
|
||||
return FALSE;
|
||||
if (!set_b && MEM_P (orig_x))
|
||||
{
|
||||
/* Disallow the "if (...) x = a;" form (implicit "else x = x;")
|
||||
for optimizations if writing to x may trap or fault,
|
||||
i.e. it's a memory other than a static var or a stack slot,
|
||||
is misaligned on strict aligned machines or is read-only. If
|
||||
x is a read-only memory, then the program is valid only if we
|
||||
avoid the store into it. If there are stores on both the
|
||||
THEN and ELSE arms, then we can go ahead with the conversion;
|
||||
either the program is broken, or the condition is always
|
||||
false such that the other memory is selected. */
|
||||
if (noce_mem_write_may_trap_or_fault_p (orig_x))
|
||||
return FALSE;
|
||||
|
||||
/* Avoid store speculation: given "if (...) x = a" where x is a
|
||||
MEM, we only want to do the store if x is always set
|
||||
somewhere in the function. This avoids cases like
|
||||
if (pthread_mutex_trylock(mutex))
|
||||
++global_variable;
|
||||
where we only want global_variable to be changed if the mutex
|
||||
is held. FIXME: This should ideally be expressed directly in
|
||||
RTL somehow. */
|
||||
if (!noce_can_store_speculate_p (test_bb, orig_x))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (noce_try_move (&if_info))
|
||||
goto success;
|
||||
@@ -2847,7 +2901,8 @@ find_if_header (basic_block test_bb, int pass)
|
||||
&& find_cond_trap (test_bb, then_edge, else_edge))
|
||||
goto success;
|
||||
|
||||
if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY
|
||||
if (life_data_ok
|
||||
&& dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY
|
||||
&& (! HAVE_conditional_execution || reload_completed))
|
||||
{
|
||||
if (find_if_case_1 (test_bb, then_edge, else_edge))
|
||||
@@ -3862,9 +3917,8 @@ if_convert (int x_life_data_ok)
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
}
|
||||
|
||||
/* Compute postdominators if we think we'll use them. */
|
||||
if (HAVE_conditional_execution || life_data_ok)
|
||||
calculate_dominance_info (CDI_POST_DOMINATORS);
|
||||
/* Compute postdominators. */
|
||||
calculate_dominance_info (CDI_POST_DOMINATORS);
|
||||
|
||||
if (life_data_ok)
|
||||
clear_bb_flags ();
|
||||
|
||||
Reference in New Issue
Block a user