tree-optimization/106378 - DSE of LEN_STORE and MASK_STORE
The following enhances DSE to handle LEN_STORE (optimally) and MASK_STORE (conservatively). PR tree-optimization/106378 * tree-ssa-dse.cc (initialize_ao_ref_for_dse): Handle LEN_STORE, add mode to initialize a may-def and handle MASK_STORE that way. (dse_optimize_stmt): Query may-defs. Handle internal functions LEN_STORE and MASK_STORE similar to how we handle memory builtins but without byte tracking.
This commit is contained in:
parent
bd9837bc3c
commit
dc477ffb4a
@ -93,7 +93,9 @@ static bitmap need_eh_cleanup;
|
||||
static bitmap need_ab_cleanup;
|
||||
|
||||
/* STMT is a statement that may write into memory. Analyze it and
|
||||
initialize WRITE to describe how STMT affects memory.
|
||||
initialize WRITE to describe how STMT affects memory. When
|
||||
MAY_DEF_OK is true then the function initializes WRITE to what
|
||||
the stmt may define.
|
||||
|
||||
Return TRUE if the statement was analyzed, FALSE otherwise.
|
||||
|
||||
@ -101,7 +103,7 @@ static bitmap need_ab_cleanup;
|
||||
can be achieved by analyzing more statements. */
|
||||
|
||||
static bool
|
||||
initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write)
|
||||
initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write, bool may_def_ok = false)
|
||||
{
|
||||
/* It's advantageous to handle certain mem* functions. */
|
||||
if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
|
||||
@ -146,6 +148,32 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (is_gimple_call (stmt)
|
||||
&& gimple_call_internal_p (stmt))
|
||||
{
|
||||
switch (gimple_call_internal_fn (stmt))
|
||||
{
|
||||
case IFN_LEN_STORE:
|
||||
ao_ref_init_from_ptr_and_size
|
||||
(write, gimple_call_arg (stmt, 0),
|
||||
int_const_binop (MINUS_EXPR,
|
||||
gimple_call_arg (stmt, 2),
|
||||
gimple_call_arg (stmt, 4)));
|
||||
return true;
|
||||
case IFN_MASK_STORE:
|
||||
/* We cannot initialize a must-def ao_ref (in all cases) but we
|
||||
can provide a may-def variant. */
|
||||
if (may_def_ok)
|
||||
{
|
||||
ao_ref_init_from_ptr_and_size
|
||||
(write, gimple_call_arg (stmt, 0),
|
||||
TYPE_SIZE_UNIT (TREE_TYPE (gimple_call_arg (stmt, 2))));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
else if (tree lhs = gimple_get_lhs (stmt))
|
||||
{
|
||||
if (TREE_CODE (lhs) != SSA_NAME)
|
||||
@ -1328,8 +1356,10 @@ dse_optimize_stmt (function *fun, gimple_stmt_iterator *gsi, sbitmap live_bytes)
|
||||
|
||||
ao_ref ref;
|
||||
/* If this is not a store we can still remove dead call using
|
||||
modref summary. */
|
||||
if (!initialize_ao_ref_for_dse (stmt, &ref))
|
||||
modref summary. Note we specifically allow ref to be initialized
|
||||
to a conservative may-def since we are looking for followup stores
|
||||
to kill all of it. */
|
||||
if (!initialize_ao_ref_for_dse (stmt, &ref, true))
|
||||
{
|
||||
dse_optimize_call (gsi, live_bytes);
|
||||
return;
|
||||
@ -1398,6 +1428,23 @@ dse_optimize_stmt (function *fun, gimple_stmt_iterator *gsi, sbitmap live_bytes)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (is_gimple_call (stmt)
|
||||
&& gimple_call_internal_p (stmt))
|
||||
{
|
||||
switch (gimple_call_internal_fn (stmt))
|
||||
{
|
||||
case IFN_LEN_STORE:
|
||||
case IFN_MASK_STORE:
|
||||
{
|
||||
enum dse_store_status store_status;
|
||||
store_status = dse_classify_store (&ref, stmt, false, live_bytes);
|
||||
if (store_status == DSE_STORE_DEAD)
|
||||
delete_dead_or_redundant_call (gsi, "dead");
|
||||
return;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
bool by_clobber_p = false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user