gimple-ssa-store-merging.c (struct store_immediate_info): Add bit_not_p field.
* gimple-ssa-store-merging.c (struct store_immediate_info): Add bit_not_p field. (store_immediate_info::store_immediate_info): Add bitnotp argument, set bit_not_p to it. (imm_store_chain_info::coalesce_immediate_stores): Break group if bit_not_p is different. (count_multiple_uses, split_group, imm_store_chain_info::output_merged_store): Handle info->bit_not_p. (handled_load): Avoid multiple chained BIT_NOT_EXPRs. (pass_store_merging::process_store): Handle BIT_{AND,IOR,XOR}_EXPR result inverted using BIT_NOT_EXPR, compute bit_not_p, pass it to store_immediate_info ctor. From-SVN: r254606
This commit is contained in:
parent
6e307219b9
commit
d60edaba4f
2 changed files with 66 additions and 6 deletions
|
@ -1,3 +1,18 @@
|
|||
2017-11-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gimple-ssa-store-merging.c (struct store_immediate_info): Add
|
||||
bit_not_p field.
|
||||
(store_immediate_info::store_immediate_info): Add bitnotp argument,
|
||||
set bit_not_p to it.
|
||||
(imm_store_chain_info::coalesce_immediate_stores): Break group
|
||||
if bit_not_p is different.
|
||||
(count_multiple_uses, split_group,
|
||||
imm_store_chain_info::output_merged_store): Handle info->bit_not_p.
|
||||
(handled_load): Avoid multiple chained BIT_NOT_EXPRs.
|
||||
(pass_store_merging::process_store): Handle BIT_{AND,IOR,XOR}_EXPR
|
||||
result inverted using BIT_NOT_EXPR, compute bit_not_p, pass it
|
||||
to store_immediate_info ctor.
|
||||
|
||||
2017-11-09 Jim Wilson <jimw@sifive.com>
|
||||
|
||||
* collect2.c (OBJECT_FORMAT_COFF): Remove EXTENDED_COFF support.
|
||||
|
|
|
@ -209,12 +209,13 @@ struct store_immediate_info
|
|||
/* INTEGER_CST for constant stores, MEM_REF for memory copy or
|
||||
BIT_*_EXPR for logical bitwise operation. */
|
||||
enum tree_code rhs_code;
|
||||
bool bit_not_p;
|
||||
/* Operands. For BIT_*_EXPR rhs_code both operands are used, otherwise
|
||||
just the first one. */
|
||||
store_operand_info ops[2];
|
||||
store_immediate_info (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
|
||||
gimple *, unsigned int, enum tree_code,
|
||||
gimple *, unsigned int, enum tree_code, bool,
|
||||
const store_operand_info &,
|
||||
const store_operand_info &);
|
||||
};
|
||||
|
@ -226,10 +227,11 @@ store_immediate_info::store_immediate_info (unsigned HOST_WIDE_INT bs,
|
|||
gimple *st,
|
||||
unsigned int ord,
|
||||
enum tree_code rhscode,
|
||||
bool bitnotp,
|
||||
const store_operand_info &op0r,
|
||||
const store_operand_info &op1r)
|
||||
: bitsize (bs), bitpos (bp), bitregion_start (brs), bitregion_end (bre),
|
||||
stmt (st), order (ord), rhs_code (rhscode)
|
||||
stmt (st), order (ord), rhs_code (rhscode), bit_not_p (bitnotp)
|
||||
#if __cplusplus >= 201103L
|
||||
, ops { op0r, op1r }
|
||||
{
|
||||
|
@ -1169,7 +1171,8 @@ imm_store_chain_info::coalesce_immediate_stores ()
|
|||
Merge it into the current store group. There can be gaps in between
|
||||
the stores, but there can't be gaps in between bitregions. */
|
||||
else if (info->bitregion_start <= merged_store->bitregion_end
|
||||
&& info->rhs_code == merged_store->stores[0]->rhs_code)
|
||||
&& info->rhs_code == merged_store->stores[0]->rhs_code
|
||||
&& info->bit_not_p == merged_store->stores[0]->bit_not_p)
|
||||
{
|
||||
store_immediate_info *infof = merged_store->stores[0];
|
||||
|
||||
|
@ -1386,6 +1389,17 @@ count_multiple_uses (store_immediate_info *info)
|
|||
case BIT_AND_EXPR:
|
||||
case BIT_IOR_EXPR:
|
||||
case BIT_XOR_EXPR:
|
||||
if (info->bit_not_p)
|
||||
{
|
||||
if (!has_single_use (gimple_assign_rhs1 (stmt)))
|
||||
ret = 1; /* Fall through below to return
|
||||
the BIT_NOT_EXPR stmt and then
|
||||
BIT_{AND,IOR,XOR}_EXPR and anything it
|
||||
uses. */
|
||||
else
|
||||
/* stmt is after this the BIT_NOT_EXPR. */
|
||||
stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
|
||||
}
|
||||
if (!has_single_use (gimple_assign_rhs1 (stmt)))
|
||||
{
|
||||
ret += 1 + info->ops[0].bit_not_p;
|
||||
|
@ -1479,6 +1493,8 @@ split_group (merged_store_group *group, bool allow_unaligned_store,
|
|||
case BIT_AND_EXPR:
|
||||
case BIT_IOR_EXPR:
|
||||
case BIT_XOR_EXPR:
|
||||
if (info->bit_not_p)
|
||||
total_orig[0]++; /* The orig BIT_NOT_EXPR stmt. */
|
||||
total_orig[0]++; /* The orig BIT_*_EXPR stmt. */
|
||||
break;
|
||||
default:
|
||||
|
@ -1649,6 +1665,8 @@ split_group (merged_store_group *group, bool allow_unaligned_store,
|
|||
case BIT_AND_EXPR:
|
||||
case BIT_IOR_EXPR:
|
||||
case BIT_XOR_EXPR:
|
||||
if (info->bit_not_p)
|
||||
total_new[0] += ret; /* The new BIT_NOT_EXPR stmt. */
|
||||
total_new[0] += ret; /* The new BIT_*_EXPR stmt. */
|
||||
break;
|
||||
default:
|
||||
|
@ -1918,6 +1936,17 @@ imm_store_chain_info::output_merged_store (merged_store_group *group)
|
|||
else
|
||||
gimple_seq_add_stmt_without_update (&seq, stmt);
|
||||
src = gimple_assign_lhs (stmt);
|
||||
if (split_store->orig_stores[0]->bit_not_p)
|
||||
{
|
||||
stmt = gimple_build_assign (make_ssa_name (int_type),
|
||||
BIT_NOT_EXPR, src);
|
||||
gimple_set_location (stmt, bit_loc);
|
||||
if (load_addr[1] == NULL_TREE && gsi_bb (load_gsi[0]))
|
||||
gimple_seq_add_stmt_without_update (&load_seq[0], stmt);
|
||||
else
|
||||
gimple_seq_add_stmt_without_update (&seq, stmt);
|
||||
src = gimple_assign_lhs (stmt);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
src = ops[0];
|
||||
|
@ -2232,6 +2261,11 @@ handled_load (gimple *stmt, store_operand_info *op,
|
|||
&& handled_load (SSA_NAME_DEF_STMT (rhs1), op, bitsize, bitpos,
|
||||
bitregion_start, bitregion_end))
|
||||
{
|
||||
/* Don't allow _1 = load; _2 = ~1; _3 = ~_2; which should have
|
||||
been optimized earlier, but if allowed here, would confuse the
|
||||
multiple uses counting. */
|
||||
if (op->bit_not_p)
|
||||
return false;
|
||||
op->bit_not_p = !op->bit_not_p;
|
||||
return true;
|
||||
}
|
||||
|
@ -2283,6 +2317,7 @@ pass_store_merging::process_store (gimple *stmt)
|
|||
|| ((bitsize > MAX_BITSIZE_MODE_ANY_INT)
|
||||
&& (TREE_CODE (rhs) != INTEGER_CST)));
|
||||
enum tree_code rhs_code = ERROR_MARK;
|
||||
bool bit_not_p = false;
|
||||
store_operand_info ops[2];
|
||||
if (invalid)
|
||||
;
|
||||
|
@ -2301,7 +2336,17 @@ pass_store_merging::process_store (gimple *stmt)
|
|||
else if (handled_load (def_stmt, &ops[0], bitsize, bitpos,
|
||||
bitregion_start, bitregion_end))
|
||||
rhs_code = MEM_REF;
|
||||
else
|
||||
else if (gimple_assign_rhs_code (def_stmt) == BIT_NOT_EXPR)
|
||||
{
|
||||
tree rhs1 = gimple_assign_rhs1 (def_stmt);
|
||||
if (TREE_CODE (rhs1) == SSA_NAME
|
||||
&& is_gimple_assign (SSA_NAME_DEF_STMT (rhs1)))
|
||||
{
|
||||
bit_not_p = true;
|
||||
def_stmt = SSA_NAME_DEF_STMT (rhs1);
|
||||
}
|
||||
}
|
||||
if (rhs_code == ERROR_MARK && !invalid)
|
||||
switch ((rhs_code = gimple_assign_rhs_code (def_stmt)))
|
||||
{
|
||||
case BIT_AND_EXPR:
|
||||
|
@ -2355,7 +2400,7 @@ pass_store_merging::process_store (gimple *stmt)
|
|||
unsigned int ord = (*chain_info)->m_store_info.length ();
|
||||
info = new store_immediate_info (bitsize, bitpos, bitregion_start,
|
||||
bitregion_end, stmt, ord, rhs_code,
|
||||
ops[0], ops[1]);
|
||||
bit_not_p, ops[0], ops[1]);
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "Recording immediate store from stmt:\n");
|
||||
|
@ -2383,7 +2428,7 @@ pass_store_merging::process_store (gimple *stmt)
|
|||
= new imm_store_chain_info (m_stores_head, base_addr);
|
||||
info = new store_immediate_info (bitsize, bitpos, bitregion_start,
|
||||
bitregion_end, stmt, 0, rhs_code,
|
||||
ops[0], ops[1]);
|
||||
bit_not_p, ops[0], ops[1]);
|
||||
new_chain->m_store_info.safe_push (info);
|
||||
m_stores.put (base_addr, new_chain);
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
|
|
Loading…
Add table
Reference in a new issue