aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-lower-bitint.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimple-lower-bitint.cc')
-rw-r--r--gcc/gimple-lower-bitint.cc57
1 files changed, 49 insertions, 8 deletions
diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index cf30d8e..6fefc83 100644
--- a/gcc/gimple-lower-bitint.cc
+++ b/gcc/gimple-lower-bitint.cc
@@ -1547,14 +1547,15 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
}
else
{
- if (tree_to_uhwi (idx) < low)
+ unsigned tidx = tree_to_uhwi (idx);
+ if (tidx < low)
{
t = handle_operand (rhs1, idx);
if (m_first)
m_data[save_data_cnt + 2]
= build_int_cst (NULL_TREE, m_data_cnt);
}
- else if (tree_to_uhwi (idx) < high)
+ else if (tidx < high)
{
t = handle_operand (rhs1, size_int (low));
if (m_first)
@@ -1587,7 +1588,9 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx)
m_data_cnt = tree_to_uhwi (m_data[save_data_cnt + 2]);
if (TYPE_UNSIGNED (rhs_type))
t = build_zero_cst (m_limb_type);
- else if (m_bb && m_data[save_data_cnt])
+ else if (m_bb
+ && m_data[save_data_cnt]
+ && ((tidx & 1) == 0 || tidx != low + 1))
t = m_data[save_data_cnt];
else
t = m_data[save_data_cnt + 1];
@@ -5916,7 +5919,8 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track *live,
ssa_conflicts *graph, bitmap names,
void (*def) (live_track *, tree,
ssa_conflicts *),
- void (*use) (live_track *, tree))
+ void (*use) (live_track *, tree),
+ void (*clear) (live_track *, tree))
{
bool muldiv_p = false;
tree lhs = NULL_TREE;
@@ -5933,6 +5937,25 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track *live,
{
if (!bitmap_bit_p (names, SSA_NAME_VERSION (lhs)))
return;
+
+ /* A copy between 2 partitions does not introduce an interference
+ by itself. If they did, you would never be able to coalesce
+ two things which are copied. If the two variables really do
+ conflict, they will conflict elsewhere in the program.
+
+ This is handled by simply removing the SRC of the copy from
+ the live list, and processing the stmt normally.
+
+ Don't do this if lhs is not in names though, in such cases
+ it is actually used at some point later in the basic
+ block. */
+ if (gimple_assign_copy_p (stmt))
+ {
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ if (TREE_CODE (rhs1) == SSA_NAME)
+ clear (live, rhs1);
+ }
+
switch (gimple_assign_rhs_code (stmt))
{
case MULT_EXPR:
@@ -6624,10 +6647,28 @@ gimple_lower_bitint (void)
bitmap_set_bit (large_huge.m_names, SSA_NAME_VERSION (s));
if (has_single_use (s))
{
- if (!large_huge.m_single_use_names)
- large_huge.m_single_use_names = BITMAP_ALLOC (NULL);
- bitmap_set_bit (large_huge.m_single_use_names,
- SSA_NAME_VERSION (s));
+ tree s2 = s;
+ /* The coalescing hook special cases SSA_NAME copies.
+ Make sure not to mark in m_single_use_names single
+ use SSA_NAMEs copied from non-single use SSA_NAMEs. */
+ while (gimple_assign_copy_p (SSA_NAME_DEF_STMT (s2)))
+ {
+ s2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (s2));
+ if (TREE_CODE (s2) != SSA_NAME)
+ break;
+ if (!has_single_use (s2))
+ {
+ s2 = NULL_TREE;
+ break;
+ }
+ }
+ if (s2)
+ {
+ if (!large_huge.m_single_use_names)
+ large_huge.m_single_use_names = BITMAP_ALLOC (NULL);
+ bitmap_set_bit (large_huge.m_single_use_names,
+ SSA_NAME_VERSION (s));
+ }
}
if (SSA_NAME_VAR (s)
&& ((TREE_CODE (SSA_NAME_VAR (s)) == PARM_DECL