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.
	(if_convert): Remove recompute_dominance parameter.  Change all
	callers.

From-SVN: r129729
This commit is contained in:
Ian Lance Taylor 2007-10-29 20:41:17 +00:00 committed by Ian Lance Taylor
parent 04d053492e
commit 0ba227b5a4
2 changed files with 78 additions and 18 deletions

View File

@ -1,3 +1,10 @@
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.
(if_convert): Remove recompute_dominance parameter. Change all
callers.
2007-10-29 Richard Guenther <rguenther@suse.de>
* tree-flow-inline.h (get_subvar_at): Use binary search.

View File

@ -2139,6 +2139,46 @@ noce_mem_write_may_trap_or_fault_p (const_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, const_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-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
it without using conditional execution. Return TRUE if we were successful
at converting the block. */
@ -2292,17 +2332,31 @@ noce_process_if_block (struct noce_if_info *if_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;
@ -3957,7 +4011,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
/* Main entry point for all if-conversion. */
static void
if_convert (bool recompute_dominance)
if_convert (void)
{
basic_block bb;
int pass;
@ -3977,9 +4031,8 @@ if_convert (bool recompute_dominance)
loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
/* Compute postdominators if we think we'll use them. */
if (HAVE_conditional_execution || recompute_dominance)
calculate_dominance_info (CDI_POST_DOMINATORS);
/* Compute postdominators. */
calculate_dominance_info (CDI_POST_DOMINATORS);
df_set_flags (DF_LR_RUN_DCE);
@ -4068,7 +4121,7 @@ rest_of_handle_if_conversion (void)
if (dump_file)
dump_flow_info (dump_file, dump_flags);
cleanup_cfg (CLEANUP_EXPENSIVE);
if_convert (false);
if_convert ();
}
cleanup_cfg (0);
@ -4105,7 +4158,7 @@ gate_handle_if_after_combine (void)
static unsigned int
rest_of_handle_if_after_combine (void)
{
if_convert (true);
if_convert ();
return 0;
}
@ -4138,7 +4191,7 @@ gate_handle_if_after_reload (void)
static unsigned int
rest_of_handle_if_after_reload (void)
{
if_convert (true);
if_convert ();
return 0;
}