aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-object-size.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-object-size.c')
-rw-r--r--gcc/tree-object-size.c63
1 files changed, 49 insertions, 14 deletions
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 4b2c267..828a3d0 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -1268,25 +1268,60 @@ pass_object_sizes::execute (function *fun)
continue;
init_object_sizes ();
+
+ /* In the first pass instance, only attempt to fold
+ __builtin_object_size (x, 1) and __builtin_object_size (x, 3),
+ and rather than folding the builtin to the constant if any,
+ create a MIN_EXPR or MAX_EXPR of the __builtin_object_size
+ call result and the computed constant. */
+ if (first_pass_instance)
+ {
+ tree ost = gimple_call_arg (call, 1);
+ if (tree_fits_uhwi_p (ost))
+ {
+ unsigned HOST_WIDE_INT object_size_type = tree_to_uhwi (ost);
+ tree ptr = gimple_call_arg (call, 0);
+ tree lhs = gimple_call_lhs (call);
+ if ((object_size_type == 1 || object_size_type == 3)
+ && (TREE_CODE (ptr) == ADDR_EXPR
+ || TREE_CODE (ptr) == SSA_NAME)
+ && lhs)
+ {
+ tree type = TREE_TYPE (lhs);
+ unsigned HOST_WIDE_INT bytes
+ = compute_builtin_object_size (ptr, object_size_type);
+ if (bytes != (unsigned HOST_WIDE_INT) (object_size_type == 1
+ ? -1 : 0)
+ && wi::fits_to_tree_p (bytes, type))
+ {
+ tree tem = make_ssa_name (type);
+ gimple_call_set_lhs (call, tem);
+ enum tree_code code
+ = object_size_type == 1 ? MIN_EXPR : MAX_EXPR;
+ tree cst = build_int_cstu (type, bytes);
+ gimple g = gimple_build_assign (lhs, code, tem, cst);
+ gsi_insert_after (&i, g, GSI_NEW_STMT);
+ update_stmt (call);
+ }
+ }
+ }
+ continue;
+ }
+
result = fold_call_stmt (as_a <gcall *> (call), false);
if (!result)
{
- if (gimple_call_num_args (call) == 2
- && POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0))))
+ tree ost = gimple_call_arg (call, 1);
+
+ if (tree_fits_uhwi_p (ost))
{
- tree ost = gimple_call_arg (call, 1);
+ unsigned HOST_WIDE_INT object_size_type = tree_to_uhwi (ost);
- if (tree_fits_uhwi_p (ost))
- {
- unsigned HOST_WIDE_INT object_size_type
- = tree_to_uhwi (ost);
-
- if (object_size_type < 2)
- result = fold_convert (size_type_node,
- integer_minus_one_node);
- else if (object_size_type < 4)
- result = build_zero_cst (size_type_node);
- }
+ if (object_size_type < 2)
+ result = fold_convert (size_type_node,
+ integer_minus_one_node);
+ else if (object_size_type < 4)
+ result = build_zero_cst (size_type_node);
}
if (!result)