diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 5ff7bed..d251223 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -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, diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 1629781..5cee27b 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -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(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); + } + } } } diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-1.c b/gcc/testsuite/gcc.dg/ipa/propalign-1.c index f34552c..1491de8 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-1.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-2.c b/gcc/testsuite/gcc.dg/ipa/propalign-2.c index 67b149a..51799c7 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-2.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-2.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-3.c b/gcc/testsuite/gcc.dg/ipa/propalign-3.c index d3bc2c4..4f5df4a 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-3.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-3.c @@ -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 @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-4.c b/gcc/testsuite/gcc.dg/ipa/propalign-4.c index b680813..bd32bf0 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-4.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-4.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-5.c b/gcc/testsuite/gcc.dg/ipa/propalign-5.c index f2cf600..68e57da 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-5.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-5.c @@ -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" } } */