This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix alignment propagation
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: Marek Polacek <polacek at redhat dot com>
- Cc: Jan Hubicka <hubicka at ucw dot cz>, gcc-patches at gcc dot gnu dot org, mjambor at suse dot cz
- Date: Fri, 20 Feb 2015 06:16:47 +0100
- Subject: Re: Fix alignment propagation
- Authentication-results: sourceware.org; auth=none
- References: <20150219233929 dot GA21632 at kam dot mff dot cuni dot cz> <20150219234421 dot GD23138 at redhat dot com>
> On Fri, Feb 20, 2015 at 12:39:29AM +0100, Jan Hubicka wrote:
> > Hi,
> > this patch fixes alignment propagation that causes wrong code on solex and firefox.
> > Patch is by Martin, I just added the obvous MINUS_EXPR fix (the offset would be wrong,
> > but I see no reason for MINUX_ExPR appearing there with constant parameter), went
> > ahead and commited the fix.
> >
> > Tested on x86_64-linux.
>
> Two nits:
>
> > Index: ChangeLog
> > ===================================================================
> > --- ChangeLog (revision 220825)
> > +++ ChangeLog (working copy)
> > @@ -1,3 +1,10 @@
> > +2015-02-19 Martin Jambor <mjmabor@suse.cz>
>
> Typo in the e-mail address.
>
>
> Two ;'s at the end of the line.
Oops, looks like celebrations of lunar new year was bit too devastating.
This is followup patch that also fixes ;; issue.
It makes the alignment propagation to do proper lattice operations instead
of requiring perfect match and dropping everything to bottom otherwise.
Martin, does it look OK?
* ipa-cp.c (ipcp_verify_propagated_values): Verify that there
are no bottoms in alignment.
(decrease_alignment, increase_alignment): New functions.
(propagate_alignment_accross_jump_function): Use proper lattice
operations
* ipa-cp-1.c: New testcase.
* ipa-cp-2.c: New testcase.
Index: ipa-cp.c
===================================================================
--- ipa-cp.c (revision 220826)
+++ ipa-cp.c (working copy)
@@ -1041,10 +1041,14 @@ ipcp_verify_propagated_values (void)
for (i = 0; i < count; i++)
{
ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
+ struct ipcp_param_lattices *plats;
+ plats = ipa_get_parm_lattices (info, i);
- if (!lat->bottom
- && !lat->contains_variable
- && lat->values_count == 0)
+ if ((!lat->bottom
+ && !lat->contains_variable
+ && lat->values_count == 0)
+ || (!plats->alignment.known
+ && opt_for_fn (node->decl, flag_ipa_cp_alignment)))
{
if (dump_file)
{
@@ -1409,6 +1413,60 @@ propagate_context_accross_jump_function
return ret;
}
+/* Decrease alignment info DEST to be at most CUR. */
+
+static bool
+decrease_alignment (ipa_alignment *dest, ipa_alignment cur)
+{
+ bool changed = false;
+
+ if (!cur.known)
+ return false;
+ if (!dest->known)
+ {
+ *dest = cur;
+ return true;
+ }
+ if (dest->align == cur.align
+ && dest->misalign == cur.misalign)
+ return false;
+
+ if (dest->align > cur.align)
+ {
+ dest->align = cur.align;
+ if (cur.align)
+ dest->misalign
+ = dest->misalign % cur.align;
+ changed = true;
+ }
+ if (dest->align && (dest->misalign != (cur.misalign % dest->align)))
+ {
+ int diff = abs (dest->misalign
+ - (cur.misalign % dest->align));
+ dest->align = MIN (dest->align, (unsigned)diff & - diff);
+ if (dest->align)
+ dest->misalign
+ = dest->misalign % dest->align;
+ changed = true;
+ }
+ return changed;
+}
+
+/* Increase alignment info DEST to be at least CUR. */
+
+static bool
+increase_alignment (ipa_alignment *dest, ipa_alignment cur)
+{
+ if (!dest->known)
+ return false;
+ if (!cur.known || dest->align < cur.align)
+ {
+ *dest = cur;
+ return true;
+ }
+ return false;
+}
+
/* Propagate alignments across jump function JFUNC that is associated with
edge CS and update DEST_LAT accordingly. */
@@ -1420,17 +1478,25 @@ propagate_alignment_accross_jump_functio
if (alignment_bottom_p (dest_lat))
return false;
- ipa_alignment cur;
- cur.known = false;
- if (jfunc->alignment.known)
- cur = jfunc->alignment;
- else if (jfunc->type == IPA_JF_PASS_THROUGH
- || jfunc->type == IPA_JF_ANCESTOR)
+ ipa_alignment cur = jfunc->alignment;
+
+ /* For some reason UNKNOWN jump function gets alignment to be TOP
+ instead of BOTTOM. */
+ if (!cur.known)
+ {
+ cur.known = true;
+ cur.align = 0;
+ }
+
+ if (jfunc->type == IPA_JF_PASS_THROUGH
+ || jfunc->type == IPA_JF_ANCESTOR)
{
struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
struct ipcp_param_lattices *src_lats;
HOST_WIDE_INT offset = 0;
int src_idx;
+ ipa_alignment incomming_cur;
+ bool ok = true;
if (jfunc->type == IPA_JF_PASS_THROUGH)
{
@@ -1439,44 +1505,34 @@ propagate_alignment_accross_jump_functio
{
if (op != POINTER_PLUS_EXPR
&& op != PLUS_EXPR)
- goto prop_fail;
+ ok = false;
tree operand = ipa_get_jf_pass_through_operand (jfunc);
if (!tree_fits_shwi_p (operand))
- goto prop_fail;
- offset = tree_to_shwi (operand);
+ ok = false;
+ else
+ offset = tree_to_shwi (operand);
}
src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
}
else
{
src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
- offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;;
+ offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
}
- src_lats = ipa_get_parm_lattices (caller_info, src_idx);
- if (!src_lats->alignment.known
- || alignment_bottom_p (src_lats))
- goto prop_fail;
-
- cur = src_lats->alignment;
- cur.misalign = (cur.misalign + offset) % cur.align;
- }
-
- if (cur.known)
- {
- if (!dest_lat->alignment.known)
+ if (ok)
{
- dest_lat->alignment = cur;
- return true;
+ src_lats = ipa_get_parm_lattices (caller_info, src_idx);
+
+ incomming_cur = src_lats->alignment;
+ if (incomming_cur.known && incomming_cur.align)
+ incomming_cur.misalign = (incomming_cur.misalign + offset)
+ % incomming_cur.align;
+ increase_alignment (&cur, incomming_cur);
}
- else if (dest_lat->alignment.align == cur.align
- && dest_lat->alignment.misalign == cur.misalign)
- return false;
}
- prop_fail:
- set_alignment_to_bottom (dest_lat);
- return true;
+ return decrease_alignment (&dest_lat->alignment, cur);
}
/* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
Index: testsuite/gcc.dg/ipa/ipa-cp-2.c
===================================================================
--- testsuite/gcc.dg/ipa/ipa-cp-2.c (revision 0)
+++ testsuite/gcc.dg/ipa/ipa-cp-2.c (revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-cp" } */
+int n;
+
+static void
+__attribute__ ((noinline))
+test(void *a)
+{
+ __builtin_memset (a,0,n);
+}
+
+static __attribute__ ((aligned(16))) int aa[10];
+
+int
+main()
+{
+ test (&aa[1]);
+ test (&aa[3]);
+ return 0;
+}
+/* { dg-final { scan-ipa-dump "Alignment 8, misalignment 4" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */
Index: testsuite/gcc.dg/ipa/ipa-cp-1.c
===================================================================
--- testsuite/gcc.dg/ipa/ipa-cp-1.c (revision 0)
+++ testsuite/gcc.dg/ipa/ipa-cp-1.c (revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-cp" } */
+int n;
+
+static void
+__attribute__ ((noinline))
+test(void *a)
+{
+ __builtin_memset (a,0,n);
+}
+
+int
+main()
+{
+ int aa;
+ short bb;
+ test (&aa);
+ test (&bb);
+ return 0;
+}
+/* { dg-final { scan-ipa-dump "Alignment 2" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */