On 6 February 2014 16:42:05 Jakub Jelinek <ja...@redhat.com> wrote:

Hi!

As discussed on IRC, this patch introduces two new attributes,
so that the C library (and other headers) have a way to
a) tell the compiler something about functions like aligned_alloc
   or memalign
b) tell the compiler the alignment of pointers returned say by malloc

Ok for trunk if bootstrap/regtest passes?

+/* Return the propagation value for functions with assume_aligned
+   or alloc_aligned attribute.  */
+
+static prop_value_t
+bit_value_alloc_assume_aligned_attribute (gimple stmt, tree attr,
+                                         prop_value_t ptrval,
+                                         bool alloc_aligned)
+{
+  tree lhs = gimple_call_lhs (stmt), align, misalign = NULL_TREE;
+  tree type = TREE_TYPE (lhs);
+  unsigned HOST_WIDE_INT aligni, misaligni = 0;
+  prop_value_t alignval;
+  double_int value, mask;
+  prop_value_t val;

Do we have an optimization that moves most of the above down..

+  if (ptrval.lattice_val == UNDEFINED)
+    return ptrval;
+  gcc_assert ((ptrval.lattice_val == CONSTANT
+              && TREE_CODE (ptrval.value) == INTEGER_CST)
+             || ptrval.mask.is_minus_one ());
+  if (TREE_VALUE (attr) == NULL_TREE)
+    return ptrval;
+  attr = TREE_VALUE (attr);
+  align = TREE_VALUE (attr);
+  if (!tree_fits_uhwi_p (align))
+    return ptrval;
+  aligni = tree_to_uhwi (align);
+  if (alloc_aligned)
+    {
+      if (aligni == 0 || aligni > gimple_call_num_args (stmt))
+       return ptrval;
+      align = gimple_call_arg (stmt, aligni - 1);
+      if (!tree_fits_uhwi_p (align))
+       return ptrval;
+      aligni = tree_to_uhwi (align);
+    }
+  if (aligni <= 1
+      || (aligni & (aligni - 1)) != 0)
+    return ptrval;
+  if (!alloc_aligned && TREE_CHAIN (attr) && TREE_VALUE (TREE_CHAIN (attr)))
+    {
+      misalign = TREE_VALUE (TREE_CHAIN (attr));
+      if (!tree_fits_uhwi_p (misalign))
+       return ptrval;
+      misaligni = tree_to_uhwi (misalign);
+      if (misaligni >= aligni)
+       return ptrval;
+    }

.. here, btw? Or would one have to do that manually?
Just curious.
Thanks,

+  align = build_int_cst_type (type, -aligni);
+  alignval = get_value_for_expr (align, true);
+  bit_value_binop_1 (BIT_AND_EXPR, type, &value, &mask,
+                    type, value_to_double_int (ptrval), ptrval.mask,
+                    type, value_to_double_int (alignval), alignval.mask);
+  if (!mask.is_minus_one ())
+    {
+      val.lattice_val = CONSTANT;
+      val.mask = mask;
+      gcc_assert ((mask.low & (aligni - 1)) == 0);
+      gcc_assert ((value.low & (aligni - 1)) == 0);
+      value.low |= misaligni;
+      /* ???  Delay building trees here.  */
+      val.value = double_int_to_tree (type, value);
+    }
+  else
+    {
+      val.lattice_val = VARYING;
+      val.value = NULL_TREE;
+      val.mask = double_int_minus_one;
+    }
+  return val;
+}
+
 /* Evaluate statement STMT.
    Valid only for assignments, calls, conditionals, and switches. */



Sent with AquaMail for Android
http://www.aqua-mail.com


Reply via email to