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