@@ -1871,16 +1871,29 @@ propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j
unsigned precision = TYPE_PRECISION (parm_type);
signop sgn = TYPE_SIGN (parm_type);
- if (jfunc->type == IPA_JF_PASS_THROUGH)
+ if (jfunc->type == IPA_JF_PASS_THROUGH
+ || jfunc->type == IPA_JF_ANCESTOR)
{
struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
- enum tree_code code = ipa_get_jf_pass_through_operation (jfunc);
tree operand = NULL_TREE;
+ enum tree_code code;
+ unsigned src_idx;
- if (code != NOP_EXPR)
- operand = ipa_get_jf_pass_through_operand (jfunc);
+ if (jfunc->type == IPA_JF_PASS_THROUGH)
+ {
+ code = ipa_get_jf_pass_through_operation (jfunc);
+ src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
+ if (code != NOP_EXPR)
+ operand = ipa_get_jf_pass_through_operand (jfunc);
+ }
+ else
+ {
+ code = POINTER_PLUS_EXPR;
+ src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
+ unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
+ operand = build_int_cstu (size_type_node, offset);
+ }
- int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
struct ipcp_param_lattices *src_lats
= ipa_get_parm_lattices (caller_info, src_idx);
@@ -2258,8 +2271,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
&dest_plats->itself);
ret |= propagate_context_accross_jump_function (cs, jump_func, i,
&dest_plats->ctxlat);
- ret |= propagate_alignment_accross_jump_function (cs, jump_func,
- &dest_plats->alignment);
+// ret |= propagate_alignment_accross_jump_function (cs, jump_func,
+// &dest_plats->alignment);
ret |= propagate_bits_accross_jump_function (cs, i, jump_func,
&dest_plats->bits_lattice);
ret |= propagate_aggs_accross_jump_function (cs, jump_func,
@@ -1701,6 +1701,16 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
jfunc->bits.mask = 0;
}
}
+ else if (POINTER_TYPE_P (TREE_TYPE (arg)))
+ {
+ unsigned HOST_WIDE_INT bitpos;
+ unsigned align;
+
+ jfunc->bits.known = true;
+ get_pointer_alignment_1 (arg, &align, &bitpos);
+ jfunc->bits.mask = wi::mask<widest_int>(TYPE_PRECISION (TREE_TYPE (arg)), false).and_not (align / BITS_PER_UNIT - 1);
+ jfunc->bits.value = bitpos / BITS_PER_UNIT;
+ }
else
gcc_assert (!jfunc->bits.known);
@@ -5534,7 +5544,7 @@ ipcp_update_bits (struct cgraph_node *node)
next_parm = DECL_CHAIN (parm);
if (!bits[i].known
- || !INTEGRAL_TYPE_P (TREE_TYPE (parm))
+ || !(INTEGRAL_TYPE_P (TREE_TYPE (parm)) || POINTER_TYPE_P (TREE_TYPE (parm)))
|| !is_gimple_reg (parm))
continue;
@@ -5549,12 +5559,41 @@ ipcp_update_bits (struct cgraph_node *node)
fprintf (dump_file, "\n");
}
- unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
- signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
+ if (INTEGRAL_TYPE_P (TREE_TYPE (ddef)))
+ {
+ unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef));
+ signop sgn = TYPE_SIGN (TREE_TYPE (ddef));
+
+ wide_int nonzero_bits = wide_int::from (bits[i].mask, prec, UNSIGNED)
+ | wide_int::from (bits[i].value, prec, sgn);
+ set_nonzero_bits (ddef, nonzero_bits);
+ }
+ else
+ {
+ unsigned tem = bits[i].mask.to_uhwi ();
+ unsigned HOST_WIDE_INT bitpos = bits[i].value.to_uhwi ();
+ unsigned align = tem & -tem;
+ unsigned misalign = bitpos & (align - 1);
- wide_int nonzero_bits = wide_int::from (bits[i].mask, prec, UNSIGNED)
- | wide_int::from (bits[i].value, prec, sgn);
- set_nonzero_bits (ddef, nonzero_bits);
+ if (align > 1)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Adjusting align: %u, misalign: %u\n", align, misalign);
+
+ unsigned old_align, old_misalign;
+ struct ptr_info_def *pi = get_ptr_info (ddef);
+ bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign);
+
+ if (old_known
+ && old_align > align)
+ {
+ if (dump_file)
+ fprintf (dump_file, "But alignment was already %u.\n", old_align);
+ continue;
+ }
+ set_ptr_info_alignment (pi, align, misalign);
+ }
+ }
}
}
@@ -27,5 +27,5 @@ bar (void)
}
-/* { dg-final { scan-ipa-dump "Adjusting alignment of param" "cp" } } */
+/* { dg-final { scan-ipa-dump "Adjusting align" "cp" } } */
/* { dg-final { scan-tree-dump-not "fail_the_test" "optimized" } } */
@@ -53,5 +53,5 @@ bar2 (void)
through (c.buf);
}
-/* { dg-final { scan-ipa-dump "Adjusting alignment of param" "cp" } } */
+/* { dg-final { scan-ipa-dump "Adjusting align" "cp" } } */
/* { dg-final { scan-tree-dump-not "fail_the_test" "optimized" } } */
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fno-ipa-cp-alignment -fno-early-inlining -fdump-ipa-cp -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fno-ipa-bit-cp -fno-early-inlining -fdump-ipa-cp -fdump-tree-optimized" } */
/* { dg-skip-if "No alignment restrictions" { { ! natural_alignment_32 } && { ! natural_alignment_64 } } } */
#include <stdint.h>
@@ -53,5 +53,5 @@ bar2 (void)
through (c.buf);
}
-/* { dg-final { scan-ipa-dump-not "Adjusting alignment of param" "cp" } } */
+/* { dg-final { scan-ipa-dump-not "align:" "cp" } } */
/* { dg-final { scan-tree-dump "fail_the_test" "optimized" } } */
@@ -20,4 +20,4 @@ main()
test (&aa[3]);
return 0;
}
-/* { dg-final { scan-ipa-dump "Alignment 8, misalignment 4" "cp" } } */
+/* { dg-final { scan-ipa-dump "align: 8, misalign: 4" "cp" } } */
@@ -20,4 +20,4 @@ main()
test (&bb);
return 0;
}
-/* { dg-final { scan-ipa-dump "Alignment 2" "cp" } } */
+/* { dg-final { scan-ipa-dump "align: 2" "cp" } } */