[PATCH] PR60092, basic support for posix_malloc

Richard Biener rguenther@suse.de
Thu Feb 6 13:21:00 GMT 2014


This adds posix_malloc as builtin and support for it in the
alias machinery.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?

Thanks,
Richard.

2014-02-06  Richard Biener  <rguenther@suse.de>

	PR middle-end/60092
	* builtin-types.def (BT_FN_INT_PTRPTR_SIZE_SIZE): Add.
	* builtins.def (BUILT_IN_POSIX_MEMALIGN): Likewise.
	* tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
	Handle BUILT_IN_POSIX_MEMALIGN.
	(find_func_clobbers): Likewise.
	* tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Likewise.
	(call_may_clobber_ref_p_1): Likewise.

	* gcc.dg/tree-ssa/alias-30.c: New testcase.
	* gcc.dg/tree-ssa/alias-31.c: Likewise.

Index: gcc/builtin-types.def
===================================================================
*** gcc/builtin-types.def	(revision 207532)
--- gcc/builtin-types.def	(working copy)
*************** DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I2_
*** 429,434 ****
--- 429,435 ----
  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I4_INT, BT_VOID, BT_VOLATILE_PTR, BT_I4, BT_INT)
  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I8_INT, BT_VOID, BT_VOLATILE_PTR, BT_I8, BT_INT)
  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR, BT_I16, BT_INT)
+ DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTRPTR_SIZE_SIZE, BT_INT, BT_PTR_PTR, BT_SIZE, BT_SIZE)
  
  DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
  		     BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
Index: gcc/builtins.def
===================================================================
*** gcc/builtins.def	(revision 207532)
--- gcc/builtins.def	(working copy)
*************** DEF_GCC_BUILTIN        (BUILT_IN_POPCOUN
*** 755,760 ****
--- 755,761 ----
  DEF_GCC_BUILTIN        (BUILT_IN_POPCOUNTIMAX, "popcountimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
+ DEF_EXT_LIB_BUILTIN    (BUILT_IN_POSIX_MEMALIGN, "posix_memalign", BT_FN_INT_PTRPTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
  DEF_GCC_BUILTIN        (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST)
  DEF_LIB_BUILTIN        (BUILT_IN_REALLOC, "realloc", BT_FN_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c	(revision 207532)
--- gcc/tree-ssa-structalias.c	(working copy)
*************** find_func_aliases_for_builtin_call (gimp
*** 4231,4236 ****
--- 4231,4256 ----
  	  lhsc.release ();
  	  return true;
  	}
+       case BUILT_IN_POSIX_MEMALIGN:
+         {
+ 	  tree ptrptr = gimple_call_arg (t, 0);
+ 	  get_constraint_for (ptrptr, &lhsc);
+ 	  do_deref (&lhsc);
+ 	  varinfo_t vi = make_heapvar ("HEAP");
+ 	  /* We marking allocated storage local, we deal with it becoming
+ 	     global by escaping and setting of vars_contains_escaped_heap.  */
+ 	  DECL_EXTERNAL (vi->decl) = 0;
+ 	  vi->is_global_var = 0;
+ 	  struct constraint_expr tmpc;
+ 	  tmpc.var = vi->id;
+ 	  tmpc.offset = 0;
+ 	  tmpc.type = ADDRESSOF;
+ 	  rhsc.safe_push (tmpc);
+ 	  process_all_all_constraints (lhsc, rhsc);
+ 	  lhsc.release ();
+ 	  rhsc.release ();
+ 	  return true;
+ 	}
        case BUILT_IN_ASSUME_ALIGNED:
  	{
  	  tree res = gimple_call_lhs (t);
*************** find_func_clobbers (gimple origt)
*** 4960,4965 ****
--- 4980,4986 ----
  	     its argument.  */
  	  case BUILT_IN_MEMSET:
  	  case BUILT_IN_MEMSET_CHK:
+ 	  case BUILT_IN_POSIX_MEMALIGN:
  	    {
  	      tree dest = gimple_call_arg (t, 0);
  	      unsigned i;
Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c	(revision 207532)
--- gcc/tree-ssa-alias.c	(working copy)
*************** ref_maybe_used_by_call_p_1 (gimple call,
*** 1515,1520 ****
--- 1515,1521 ----
  	/* The following builtins do not read from memory.  */
  	case BUILT_IN_FREE:
  	case BUILT_IN_MALLOC:
+ 	case BUILT_IN_POSIX_MEMALIGN:
  	case BUILT_IN_CALLOC:
  	case BUILT_IN_ALLOCA:
  	case BUILT_IN_ALLOCA_WITH_ALIGN:
*************** call_may_clobber_ref_p_1 (gimple call, a
*** 1838,1843 ****
--- 1839,1854 ----
  	case BUILT_IN_ALLOCA_WITH_ALIGN:
  	case BUILT_IN_ASSUME_ALIGNED:
  	  return false;
+ 	/* But posix_memalign stores a pointer into the memory pointed to
+ 	   by its first argument.  */
+ 	case BUILT_IN_POSIX_MEMALIGN:
+ 	  {
+ 	    tree ptrptr = gimple_call_arg (call, 0);
+ 	    ao_ref dref;
+ 	    ao_ref_init_from_ptr_and_size (&dref, ptrptr,
+ 					   TYPE_SIZE_UNIT (ptr_type_node));
+ 	    return refs_may_alias_p_1 (&dref, ref, false);
+ 	  }
  	/* Freeing memory kills the pointed-to memory.  More importantly
  	   the call has to serve as a barrier for moving loads and stores
  	   across it.  */
Index: gcc/testsuite/gcc.dg/tree-ssa/alias-30.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/alias-30.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/alias-30.c	(working copy)
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-fre-details" } */
+ 
+ extern int posix_memalign(void **memptr,
+ 			  __SIZE_TYPE__ alignment, __SIZE_TYPE__ size);
+ 
+ int foo (int *p)
+ {
+   int res = *p;
+   int *q;
+   posix_memalign ((void **)&q, 128, 128 * sizeof (int));
+   *q = 1;
+   return res + *p;
+ }
+ 
+ /* We should be able to CSE the load from *p in the return stmt.  */
+ 
+ /* { dg-final { scan-tree-dump "Replaced \\\*p" "fre1" } } */
+ /* { dg-final { cleanup-tree-dump "fre1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/alias-31.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/alias-31.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/alias-31.c	(working copy)
***************
*** 0 ****
--- 1,22 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-cddce1" } */
+ 
+ extern int posix_memalign(void **memptr,
+ 			  __SIZE_TYPE__ alignment, __SIZE_TYPE__ size);
+ 
+ int foo (int *p)
+ {
+   int res = *p;
+   struct { int *q1; int *q2; } q;
+   posix_memalign ((void **)&q.q1, 128, 128 * sizeof (int));
+   posix_memalign ((void **)&q.q2, 128, 128 * sizeof (int));
+   *q.q1 = 1;
+   *q.q2 = 2;
+   return res + *p + *q.q1 + *q.q2;
+ }
+ 
+ /* 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" } } */



More information about the Gcc-patches mailing list