[PATCH] PR60092 - lower posix_memalign to make align-info accessible
Richard Biener
rguenther@suse.de
Thu Feb 6 14:28:00 GMT 2014
This re-writes posix_memalign calls to
posix_memalign (ptr, align, size);
tem = *ptr;
tem = __builtin_assume_aligned (align);
*ptr = tem;
during CF lowering (yeah, ok ...) to make alignment info accessible
to SSA based analysis.
I have to adjust the added alias-31.c testcase again because with
the above we end up with
<bb 2>:
res_3 = *p_2(D);
posix_memalign (&q.q1, 128, 512);
_5 = MEM[(void *)&q];
_6 = __builtin_assume_aligned (_5, 128);
MEM[(void *)&q] = _6;
posix_memalign (&q.q2, 128, 512);
_17 = res_3 + res_3;
_20 = _17 + 1;
_23 = _20 + 2;
q ={v} {CLOBBER};
return _23;
after early DCE. This is because DCE only has "baby" DSE built-in
and the store to MEM[(void *)&q] which it doesn't remove keeps
the rest live. DSE removes the store and the DCE following it
the rest.
Not sure if more sophisticated lowering is wanted here. Special-casing
&... operands to posix_memalign as stated in the PR, generating
for posix_memalign (&ptr, 128, 512);
posix_memalign (&tem, 128, 512);
reg = tem;
reg = __builtin_assume_aligned (reg, 128);
ptr = reg;
instead would be possible (hoping for ptr to become non-address-taken).
Bootstrap / regtest on x86_64-unknown-linux-gnu pending.
Thanks,
Richard.
2014-02-06 Richard Biener <rguenther@suse.de>
PR middle-end/60092
* gimple-low.c (lower_builtin_posix_memalign): New function.
(lower_stmt): Call it to lower posix_memalign in a way
to make alignment info accessible.
* gcc.dg/tree-ssa/alias-31.c: Adjust.
* gcc.dg/vect/pr60092-2.c: New testcase.
Index: trunk/gcc/gimple-low.c
===================================================================
*** trunk.orig/gcc/gimple-low.c 2014-02-06 15:06:39.013419315 +0100
--- trunk/gcc/gimple-low.c 2014-02-06 15:12:39.116394523 +0100
*************** static void lower_gimple_bind (gimple_st
*** 83,88 ****
--- 83,89 ----
static void lower_try_catch (gimple_stmt_iterator *, struct lower_data *);
static void lower_gimple_return (gimple_stmt_iterator *, struct lower_data *);
static void lower_builtin_setjmp (gimple_stmt_iterator *);
+ static void lower_builtin_posix_memalign (gimple_stmt_iterator *);
/* Lower the body of current_function_decl from High GIMPLE into Low
*************** lower_stmt (gimple_stmt_iterator *gsi, s
*** 327,338 ****
}
if (decl
! && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
! && DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
{
! lower_builtin_setjmp (gsi);
! data->cannot_fallthru = false;
! return;
}
if (decl && (flags_from_decl_or_type (decl) & ECF_NORETURN))
--- 328,346 ----
}
if (decl
! && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
{
! if (DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
! {
! lower_builtin_setjmp (gsi);
! data->cannot_fallthru = false;
! return;
! }
! else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_POSIX_MEMALIGN)
! {
! lower_builtin_posix_memalign (gsi);
! return;
! }
}
if (decl && (flags_from_decl_or_type (decl) & ECF_NORETURN))
*************** lower_builtin_setjmp (gimple_stmt_iterat
*** 771,776 ****
--- 779,812 ----
/* Remove the call to __builtin_setjmp. */
gsi_remove (gsi, false);
}
+
+ /* Lower calls to posix_memalign to
+ posix_memalign (ptr, align, size);
+ tem = *ptr;
+ tem = __builtin_assume_aligned (align);
+ *ptr = tem;
+ so we can get at the alignment of *ptr in CCP. */
+
+ static void
+ lower_builtin_posix_memalign (gimple_stmt_iterator *gsi)
+ {
+ gimple stmt = gsi_stmt (*gsi);
+ tree pptr = gimple_call_arg (stmt, 0);
+ tree align = gimple_call_arg (stmt, 1);
+ tree ptr = create_tmp_var (ptr_type_node, NULL);
+ stmt = gimple_build_assign (ptr,
+ fold_build2 (MEM_REF, ptr_type_node, pptr,
+ build_int_cst (ptr_type_node, 0)));
+ gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+ stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_ASSUME_ALIGNED),
+ 2, ptr, align);
+ gimple_call_set_lhs (stmt, ptr);
+ gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+ stmt = gimple_build_assign (fold_build2 (MEM_REF, ptr_type_node, pptr,
+ build_int_cst (ptr_type_node, 0)),
+ ptr);
+ gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+ }
/* Record the variables in VARS into function FN. */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/alias-31.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/alias-31.c 2014-02-06 15:11:55.881397499 +0100
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/alias-31.c 2014-02-06 15:12:39.117394523 +0100
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-cddce1" } */
extern int posix_memalign(void **memptr,
__SIZE_TYPE__ alignment, __SIZE_TYPE__ size);
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dce2" } */
extern int posix_memalign(void **memptr,
__SIZE_TYPE__ alignment, __SIZE_TYPE__ size);
*************** int foo (int *p)
*** 20,24 ****
/* There should be only one load from *p left. All stores and all
other loads should be removed. */
! /* { dg-final { scan-tree-dump-times "\\\*\[^ \]" 1 "cddce1" } } */
! /* { dg-final { cleanup-tree-dump "cddce1" } } */
--- 20,24 ----
/* There should be only one load from *p left. All stores and all
other loads should be removed. */
! /* { dg-final { scan-tree-dump-times "\\\*\[^ \]" 1 "dce2" } } */
! /* { dg-final { cleanup-tree-dump "dce2" } } */
Index: trunk/gcc/testsuite/gcc.dg/vect/pr60092-2.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.dg/vect/pr60092-2.c 2014-02-06 15:15:10.167384123 +0100
***************
*** 0 ****
--- 1,25 ----
+ /* { dg-do compile } */
+ /* { dg-require-effective-target vect_int } */
+
+ int *foo (int n)
+ {
+ int *p;
+ int *q;
+ void *tem;
+ if (posix_memalign (&tem, 256, n * sizeof (int)) != 0)
+ return (void *)0;
+ p = (int *)tem;
+ if (posix_memalign (&tem, 256, n * sizeof (int)) != 0)
+ return (void *)0;
+ q = (int *)tem;
+ bar (q);
+ int i;
+ for (i = 0; i < n; ++i)
+ p[i] = q[i] + q[i];
+ return p;
+ }
+
+ /* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+ /* { dg-final { scan-tree-dump-not "Peeling for alignment will be applied" "vect" } } */
+ /* { dg-final { scan-tree-dump-not "Vectorizing an unaligned access" "vect" } } */
+ /* { dg-final { cleanup-tree-dump "vect" } } */
More information about the Gcc-patches
mailing list