re PR bootstrap/51346 (LTO bootstrap failed with bootstrap-profiled)
[official-gcc.git] / gcc / tree-object-size.c
blob326b2e4c21b0645986622e17ca4954537adb0e0e
1 /* __builtin_object_size (ptr, object_size_type) computation
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Jakub Jelinek <jakub@redhat.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "diagnostic-core.h"
28 #include "tree-pretty-print.h"
29 #include "gimple-pretty-print.h"
30 #include "tree-flow.h"
31 #include "tree-pass.h"
32 #include "tree-ssa-propagate.h"
34 struct object_size_info
36 int object_size_type;
37 bitmap visited, reexamine;
38 int pass;
39 bool changed;
40 unsigned int *depths;
41 unsigned int *stack, *tos;
44 static unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
46 static tree compute_object_offset (const_tree, const_tree);
47 static unsigned HOST_WIDE_INT addr_object_size (struct object_size_info *,
48 const_tree, int);
49 static unsigned HOST_WIDE_INT alloc_object_size (const_gimple, int);
50 static tree pass_through_call (const_gimple);
51 static void collect_object_sizes_for (struct object_size_info *, tree);
52 static void expr_object_size (struct object_size_info *, tree, tree);
53 static bool merge_object_sizes (struct object_size_info *, tree, tree,
54 unsigned HOST_WIDE_INT);
55 static bool plus_stmt_object_size (struct object_size_info *, tree, gimple);
56 static bool cond_expr_object_size (struct object_size_info *, tree, gimple);
57 static unsigned int compute_object_sizes (void);
58 static void init_offset_limit (void);
59 static void check_for_plus_in_loops (struct object_size_info *, tree);
60 static void check_for_plus_in_loops_1 (struct object_size_info *, tree,
61 unsigned int);
63 /* object_sizes[0] is upper bound for number of bytes till the end of
64 the object.
65 object_sizes[1] is upper bound for number of bytes till the end of
66 the subobject (innermost array or field with address taken).
67 object_sizes[2] is lower bound for number of bytes till the end of
68 the object and object_sizes[3] lower bound for subobject. */
69 static unsigned HOST_WIDE_INT *object_sizes[4];
71 /* Bitmaps what object sizes have been computed already. */
72 static bitmap computed[4];
74 /* Maximum value of offset we consider to be addition. */
75 static unsigned HOST_WIDE_INT offset_limit;
78 /* Initialize OFFSET_LIMIT variable. */
79 static void
80 init_offset_limit (void)
82 if (host_integerp (TYPE_MAX_VALUE (sizetype), 1))
83 offset_limit = tree_low_cst (TYPE_MAX_VALUE (sizetype), 1);
84 else
85 offset_limit = -1;
86 offset_limit /= 2;
90 /* Compute offset of EXPR within VAR. Return error_mark_node
91 if unknown. */
93 static tree
94 compute_object_offset (const_tree expr, const_tree var)
96 enum tree_code code = PLUS_EXPR;
97 tree base, off, t;
99 if (expr == var)
100 return size_zero_node;
102 switch (TREE_CODE (expr))
104 case COMPONENT_REF:
105 base = compute_object_offset (TREE_OPERAND (expr, 0), var);
106 if (base == error_mark_node)
107 return base;
109 t = TREE_OPERAND (expr, 1);
110 off = size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (t),
111 size_int (tree_low_cst (DECL_FIELD_BIT_OFFSET (t), 1)
112 / BITS_PER_UNIT));
113 break;
115 case REALPART_EXPR:
116 CASE_CONVERT:
117 case VIEW_CONVERT_EXPR:
118 case NON_LVALUE_EXPR:
119 return compute_object_offset (TREE_OPERAND (expr, 0), var);
121 case IMAGPART_EXPR:
122 base = compute_object_offset (TREE_OPERAND (expr, 0), var);
123 if (base == error_mark_node)
124 return base;
126 off = TYPE_SIZE_UNIT (TREE_TYPE (expr));
127 break;
129 case ARRAY_REF:
130 base = compute_object_offset (TREE_OPERAND (expr, 0), var);
131 if (base == error_mark_node)
132 return base;
134 t = TREE_OPERAND (expr, 1);
135 if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) < 0)
137 code = MINUS_EXPR;
138 t = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
140 t = fold_convert (sizetype, t);
141 off = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (TREE_TYPE (expr)), t);
142 break;
144 case MEM_REF:
145 gcc_assert (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR);
146 return double_int_to_tree (sizetype, mem_ref_offset (expr));
148 default:
149 return error_mark_node;
152 return size_binop (code, base, off);
156 /* Compute __builtin_object_size for PTR, which is a ADDR_EXPR.
157 OBJECT_SIZE_TYPE is the second argument from __builtin_object_size.
158 If unknown, return unknown[object_size_type]. */
160 static unsigned HOST_WIDE_INT
161 addr_object_size (struct object_size_info *osi, const_tree ptr,
162 int object_size_type)
164 tree pt_var, pt_var_size = NULL_TREE, var_size, bytes;
166 gcc_assert (TREE_CODE (ptr) == ADDR_EXPR);
168 pt_var = TREE_OPERAND (ptr, 0);
169 while (handled_component_p (pt_var))
170 pt_var = TREE_OPERAND (pt_var, 0);
172 if (pt_var
173 && TREE_CODE (pt_var) == MEM_REF)
175 unsigned HOST_WIDE_INT sz;
177 if (!osi || (object_size_type & 1) != 0
178 || TREE_CODE (TREE_OPERAND (pt_var, 0)) != SSA_NAME)
180 sz = compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
181 object_size_type & ~1);
183 else
185 tree var = TREE_OPERAND (pt_var, 0);
186 if (osi->pass == 0)
187 collect_object_sizes_for (osi, var);
188 if (bitmap_bit_p (computed[object_size_type],
189 SSA_NAME_VERSION (var)))
190 sz = object_sizes[object_size_type][SSA_NAME_VERSION (var)];
191 else
192 sz = unknown[object_size_type];
194 if (sz != unknown[object_size_type])
196 double_int dsz = double_int_sub (uhwi_to_double_int (sz),
197 mem_ref_offset (pt_var));
198 if (double_int_negative_p (dsz))
199 sz = 0;
200 else if (double_int_fits_in_uhwi_p (dsz))
201 sz = double_int_to_uhwi (dsz);
202 else
203 sz = unknown[object_size_type];
206 if (sz != unknown[object_size_type] && sz < offset_limit)
207 pt_var_size = size_int (sz);
209 else if (pt_var
210 && DECL_P (pt_var)
211 && host_integerp (DECL_SIZE_UNIT (pt_var), 1)
212 && (unsigned HOST_WIDE_INT)
213 tree_low_cst (DECL_SIZE_UNIT (pt_var), 1) < offset_limit)
214 pt_var_size = DECL_SIZE_UNIT (pt_var);
215 else if (pt_var
216 && TREE_CODE (pt_var) == STRING_CST
217 && TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
218 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
219 && (unsigned HOST_WIDE_INT)
220 tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
221 < offset_limit)
222 pt_var_size = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
223 else
224 return unknown[object_size_type];
226 if (pt_var != TREE_OPERAND (ptr, 0))
228 tree var;
230 if (object_size_type & 1)
232 var = TREE_OPERAND (ptr, 0);
234 while (var != pt_var
235 && TREE_CODE (var) != BIT_FIELD_REF
236 && TREE_CODE (var) != COMPONENT_REF
237 && TREE_CODE (var) != ARRAY_REF
238 && TREE_CODE (var) != ARRAY_RANGE_REF
239 && TREE_CODE (var) != REALPART_EXPR
240 && TREE_CODE (var) != IMAGPART_EXPR)
241 var = TREE_OPERAND (var, 0);
242 if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
243 var = TREE_OPERAND (var, 0);
244 if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
245 || ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
246 || (pt_var_size
247 && tree_int_cst_lt (pt_var_size,
248 TYPE_SIZE_UNIT (TREE_TYPE (var)))))
249 var = pt_var;
250 else if (var != pt_var && TREE_CODE (pt_var) == MEM_REF)
252 tree v = var;
253 /* For &X->fld, compute object size only if fld isn't the last
254 field, as struct { int i; char c[1]; } is often used instead
255 of flexible array member. */
256 while (v && v != pt_var)
257 switch (TREE_CODE (v))
259 case ARRAY_REF:
260 if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (v, 0)))
261 && TREE_CODE (TREE_OPERAND (v, 1)) == INTEGER_CST)
263 tree domain
264 = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (v, 0)));
265 if (domain
266 && TYPE_MAX_VALUE (domain)
267 && TREE_CODE (TYPE_MAX_VALUE (domain))
268 == INTEGER_CST
269 && tree_int_cst_lt (TREE_OPERAND (v, 1),
270 TYPE_MAX_VALUE (domain)))
272 v = NULL_TREE;
273 break;
276 v = TREE_OPERAND (v, 0);
277 break;
278 case REALPART_EXPR:
279 case IMAGPART_EXPR:
280 v = NULL_TREE;
281 break;
282 case COMPONENT_REF:
283 if (TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
285 v = NULL_TREE;
286 break;
288 while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
289 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
290 != UNION_TYPE
291 && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
292 != QUAL_UNION_TYPE)
293 break;
294 else
295 v = TREE_OPERAND (v, 0);
296 if (TREE_CODE (v) == COMPONENT_REF
297 && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
298 == RECORD_TYPE)
300 tree fld_chain = DECL_CHAIN (TREE_OPERAND (v, 1));
301 for (; fld_chain; fld_chain = DECL_CHAIN (fld_chain))
302 if (TREE_CODE (fld_chain) == FIELD_DECL)
303 break;
305 if (fld_chain)
307 v = NULL_TREE;
308 break;
310 v = TREE_OPERAND (v, 0);
312 while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
313 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
314 != UNION_TYPE
315 && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
316 != QUAL_UNION_TYPE)
317 break;
318 else
319 v = TREE_OPERAND (v, 0);
320 if (v != pt_var)
321 v = NULL_TREE;
322 else
323 v = pt_var;
324 break;
325 default:
326 v = pt_var;
327 break;
329 if (v == pt_var)
330 var = pt_var;
333 else
334 var = pt_var;
336 if (var != pt_var)
337 var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
338 else if (!pt_var_size)
339 return unknown[object_size_type];
340 else
341 var_size = pt_var_size;
342 bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
343 if (bytes != error_mark_node)
345 if (TREE_CODE (bytes) == INTEGER_CST
346 && tree_int_cst_lt (var_size, bytes))
347 bytes = size_zero_node;
348 else
349 bytes = size_binop (MINUS_EXPR, var_size, bytes);
351 if (var != pt_var
352 && pt_var_size
353 && TREE_CODE (pt_var) == MEM_REF
354 && bytes != error_mark_node)
356 tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var);
357 if (bytes2 != error_mark_node)
359 if (TREE_CODE (bytes2) == INTEGER_CST
360 && tree_int_cst_lt (pt_var_size, bytes2))
361 bytes2 = size_zero_node;
362 else
363 bytes2 = size_binop (MINUS_EXPR, pt_var_size, bytes2);
364 bytes = size_binop (MIN_EXPR, bytes, bytes2);
368 else if (!pt_var_size)
369 return unknown[object_size_type];
370 else
371 bytes = pt_var_size;
373 if (host_integerp (bytes, 1))
374 return tree_low_cst (bytes, 1);
376 return unknown[object_size_type];
380 /* Compute __builtin_object_size for CALL, which is a GIMPLE_CALL.
381 Handles various allocation calls. OBJECT_SIZE_TYPE is the second
382 argument from __builtin_object_size. If unknown, return
383 unknown[object_size_type]. */
385 static unsigned HOST_WIDE_INT
386 alloc_object_size (const_gimple call, int object_size_type)
388 tree callee, bytes = NULL_TREE;
389 tree alloc_size;
390 int arg1 = -1, arg2 = -1;
392 gcc_assert (is_gimple_call (call));
394 callee = gimple_call_fndecl (call);
395 if (!callee)
396 return unknown[object_size_type];
398 alloc_size = lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (TREE_TYPE(callee)));
399 if (alloc_size && TREE_VALUE (alloc_size))
401 tree p = TREE_VALUE (alloc_size);
403 arg1 = TREE_INT_CST_LOW (TREE_VALUE (p))-1;
404 if (TREE_CHAIN (p))
405 arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
408 if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
409 switch (DECL_FUNCTION_CODE (callee))
411 case BUILT_IN_CALLOC:
412 arg2 = 1;
413 /* fall through */
414 case BUILT_IN_MALLOC:
415 case BUILT_IN_ALLOCA:
416 case BUILT_IN_ALLOCA_WITH_ALIGN:
417 arg1 = 0;
418 default:
419 break;
422 if (arg1 < 0 || arg1 >= (int)gimple_call_num_args (call)
423 || TREE_CODE (gimple_call_arg (call, arg1)) != INTEGER_CST
424 || (arg2 >= 0
425 && (arg2 >= (int)gimple_call_num_args (call)
426 || TREE_CODE (gimple_call_arg (call, arg2)) != INTEGER_CST)))
427 return unknown[object_size_type];
429 if (arg2 >= 0)
430 bytes = size_binop (MULT_EXPR,
431 fold_convert (sizetype, gimple_call_arg (call, arg1)),
432 fold_convert (sizetype, gimple_call_arg (call, arg2)));
433 else if (arg1 >= 0)
434 bytes = fold_convert (sizetype, gimple_call_arg (call, arg1));
436 if (bytes && host_integerp (bytes, 1))
437 return tree_low_cst (bytes, 1);
439 return unknown[object_size_type];
443 /* If object size is propagated from one of function's arguments directly
444 to its return value, return that argument for GIMPLE_CALL statement CALL.
445 Otherwise return NULL. */
447 static tree
448 pass_through_call (const_gimple call)
450 tree callee = gimple_call_fndecl (call);
452 if (callee
453 && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
454 switch (DECL_FUNCTION_CODE (callee))
456 case BUILT_IN_MEMCPY:
457 case BUILT_IN_MEMMOVE:
458 case BUILT_IN_MEMSET:
459 case BUILT_IN_STRCPY:
460 case BUILT_IN_STRNCPY:
461 case BUILT_IN_STRCAT:
462 case BUILT_IN_STRNCAT:
463 case BUILT_IN_MEMCPY_CHK:
464 case BUILT_IN_MEMMOVE_CHK:
465 case BUILT_IN_MEMSET_CHK:
466 case BUILT_IN_STRCPY_CHK:
467 case BUILT_IN_STRNCPY_CHK:
468 case BUILT_IN_STRCAT_CHK:
469 case BUILT_IN_STRNCAT_CHK:
470 case BUILT_IN_ASSUME_ALIGNED:
471 if (gimple_call_num_args (call) >= 1)
472 return gimple_call_arg (call, 0);
473 break;
474 default:
475 break;
478 return NULL_TREE;
482 /* Compute __builtin_object_size value for PTR. OBJECT_SIZE_TYPE is the
483 second argument from __builtin_object_size. */
485 unsigned HOST_WIDE_INT
486 compute_builtin_object_size (tree ptr, int object_size_type)
488 gcc_assert (object_size_type >= 0 && object_size_type <= 3);
490 if (! offset_limit)
491 init_offset_limit ();
493 if (TREE_CODE (ptr) == ADDR_EXPR)
494 return addr_object_size (NULL, ptr, object_size_type);
496 if (TREE_CODE (ptr) == SSA_NAME
497 && POINTER_TYPE_P (TREE_TYPE (ptr))
498 && object_sizes[object_size_type] != NULL)
500 if (!bitmap_bit_p (computed[object_size_type], SSA_NAME_VERSION (ptr)))
502 struct object_size_info osi;
503 bitmap_iterator bi;
504 unsigned int i;
506 if (dump_file)
508 fprintf (dump_file, "Computing %s %sobject size for ",
509 (object_size_type & 2) ? "minimum" : "maximum",
510 (object_size_type & 1) ? "sub" : "");
511 print_generic_expr (dump_file, ptr, dump_flags);
512 fprintf (dump_file, ":\n");
515 osi.visited = BITMAP_ALLOC (NULL);
516 osi.reexamine = BITMAP_ALLOC (NULL);
517 osi.object_size_type = object_size_type;
518 osi.depths = NULL;
519 osi.stack = NULL;
520 osi.tos = NULL;
522 /* First pass: walk UD chains, compute object sizes that
523 can be computed. osi.reexamine bitmap at the end will
524 contain what variables were found in dependency cycles
525 and therefore need to be reexamined. */
526 osi.pass = 0;
527 osi.changed = false;
528 collect_object_sizes_for (&osi, ptr);
530 /* Second pass: keep recomputing object sizes of variables
531 that need reexamination, until no object sizes are
532 increased or all object sizes are computed. */
533 if (! bitmap_empty_p (osi.reexamine))
535 bitmap reexamine = BITMAP_ALLOC (NULL);
537 /* If looking for minimum instead of maximum object size,
538 detect cases where a pointer is increased in a loop.
539 Although even without this detection pass 2 would eventually
540 terminate, it could take a long time. If a pointer is
541 increasing this way, we need to assume 0 object size.
542 E.g. p = &buf[0]; while (cond) p = p + 4; */
543 if (object_size_type & 2)
545 osi.depths = XCNEWVEC (unsigned int, num_ssa_names);
546 osi.stack = XNEWVEC (unsigned int, num_ssa_names);
547 osi.tos = osi.stack;
548 osi.pass = 1;
549 /* collect_object_sizes_for is changing
550 osi.reexamine bitmap, so iterate over a copy. */
551 bitmap_copy (reexamine, osi.reexamine);
552 EXECUTE_IF_SET_IN_BITMAP (reexamine, 0, i, bi)
553 if (bitmap_bit_p (osi.reexamine, i))
554 check_for_plus_in_loops (&osi, ssa_name (i));
556 free (osi.depths);
557 osi.depths = NULL;
558 free (osi.stack);
559 osi.stack = NULL;
560 osi.tos = NULL;
565 osi.pass = 2;
566 osi.changed = false;
567 /* collect_object_sizes_for is changing
568 osi.reexamine bitmap, so iterate over a copy. */
569 bitmap_copy (reexamine, osi.reexamine);
570 EXECUTE_IF_SET_IN_BITMAP (reexamine, 0, i, bi)
571 if (bitmap_bit_p (osi.reexamine, i))
573 collect_object_sizes_for (&osi, ssa_name (i));
574 if (dump_file && (dump_flags & TDF_DETAILS))
576 fprintf (dump_file, "Reexamining ");
577 print_generic_expr (dump_file, ssa_name (i),
578 dump_flags);
579 fprintf (dump_file, "\n");
583 while (osi.changed);
585 BITMAP_FREE (reexamine);
587 EXECUTE_IF_SET_IN_BITMAP (osi.reexamine, 0, i, bi)
588 bitmap_set_bit (computed[object_size_type], i);
590 /* Debugging dumps. */
591 if (dump_file)
593 EXECUTE_IF_SET_IN_BITMAP (osi.visited, 0, i, bi)
594 if (object_sizes[object_size_type][i]
595 != unknown[object_size_type])
597 print_generic_expr (dump_file, ssa_name (i),
598 dump_flags);
599 fprintf (dump_file,
600 ": %s %sobject size "
601 HOST_WIDE_INT_PRINT_UNSIGNED "\n",
602 (object_size_type & 2) ? "minimum" : "maximum",
603 (object_size_type & 1) ? "sub" : "",
604 object_sizes[object_size_type][i]);
608 BITMAP_FREE (osi.reexamine);
609 BITMAP_FREE (osi.visited);
612 return object_sizes[object_size_type][SSA_NAME_VERSION (ptr)];
615 return unknown[object_size_type];
618 /* Compute object_sizes for PTR, defined to VALUE, which is not an SSA_NAME. */
620 static void
621 expr_object_size (struct object_size_info *osi, tree ptr, tree value)
623 int object_size_type = osi->object_size_type;
624 unsigned int varno = SSA_NAME_VERSION (ptr);
625 unsigned HOST_WIDE_INT bytes;
627 gcc_assert (object_sizes[object_size_type][varno]
628 != unknown[object_size_type]);
629 gcc_assert (osi->pass == 0);
631 if (TREE_CODE (value) == WITH_SIZE_EXPR)
632 value = TREE_OPERAND (value, 0);
634 /* Pointer variables should have been handled by merge_object_sizes. */
635 gcc_assert (TREE_CODE (value) != SSA_NAME
636 || !POINTER_TYPE_P (TREE_TYPE (value)));
638 if (TREE_CODE (value) == ADDR_EXPR)
639 bytes = addr_object_size (osi, value, object_size_type);
640 else
641 bytes = unknown[object_size_type];
643 if ((object_size_type & 2) == 0)
645 if (object_sizes[object_size_type][varno] < bytes)
646 object_sizes[object_size_type][varno] = bytes;
648 else
650 if (object_sizes[object_size_type][varno] > bytes)
651 object_sizes[object_size_type][varno] = bytes;
656 /* Compute object_sizes for PTR, defined to the result of a call. */
658 static void
659 call_object_size (struct object_size_info *osi, tree ptr, gimple call)
661 int object_size_type = osi->object_size_type;
662 unsigned int varno = SSA_NAME_VERSION (ptr);
663 unsigned HOST_WIDE_INT bytes;
665 gcc_assert (is_gimple_call (call));
667 gcc_assert (object_sizes[object_size_type][varno]
668 != unknown[object_size_type]);
669 gcc_assert (osi->pass == 0);
671 bytes = alloc_object_size (call, object_size_type);
673 if ((object_size_type & 2) == 0)
675 if (object_sizes[object_size_type][varno] < bytes)
676 object_sizes[object_size_type][varno] = bytes;
678 else
680 if (object_sizes[object_size_type][varno] > bytes)
681 object_sizes[object_size_type][varno] = bytes;
686 /* Compute object_sizes for PTR, defined to an unknown value. */
688 static void
689 unknown_object_size (struct object_size_info *osi, tree ptr)
691 int object_size_type = osi->object_size_type;
692 unsigned int varno = SSA_NAME_VERSION (ptr);
693 unsigned HOST_WIDE_INT bytes;
695 gcc_assert (object_sizes[object_size_type][varno]
696 != unknown[object_size_type]);
697 gcc_assert (osi->pass == 0);
699 bytes = unknown[object_size_type];
701 if ((object_size_type & 2) == 0)
703 if (object_sizes[object_size_type][varno] < bytes)
704 object_sizes[object_size_type][varno] = bytes;
706 else
708 if (object_sizes[object_size_type][varno] > bytes)
709 object_sizes[object_size_type][varno] = bytes;
714 /* Merge object sizes of ORIG + OFFSET into DEST. Return true if
715 the object size might need reexamination later. */
717 static bool
718 merge_object_sizes (struct object_size_info *osi, tree dest, tree orig,
719 unsigned HOST_WIDE_INT offset)
721 int object_size_type = osi->object_size_type;
722 unsigned int varno = SSA_NAME_VERSION (dest);
723 unsigned HOST_WIDE_INT orig_bytes;
725 if (object_sizes[object_size_type][varno] == unknown[object_size_type])
726 return false;
727 if (offset >= offset_limit)
729 object_sizes[object_size_type][varno] = unknown[object_size_type];
730 return false;
733 if (osi->pass == 0)
734 collect_object_sizes_for (osi, orig);
736 orig_bytes = object_sizes[object_size_type][SSA_NAME_VERSION (orig)];
737 if (orig_bytes != unknown[object_size_type])
738 orig_bytes = (offset > orig_bytes)
739 ? (unsigned HOST_WIDE_INT) 0 : orig_bytes - offset;
741 if ((object_size_type & 2) == 0)
743 if (object_sizes[object_size_type][varno] < orig_bytes)
745 object_sizes[object_size_type][varno] = orig_bytes;
746 osi->changed = true;
749 else
751 if (object_sizes[object_size_type][varno] > orig_bytes)
753 object_sizes[object_size_type][varno] = orig_bytes;
754 osi->changed = true;
757 return bitmap_bit_p (osi->reexamine, SSA_NAME_VERSION (orig));
761 /* Compute object_sizes for VAR, defined to the result of an assignment
762 with operator POINTER_PLUS_EXPR. Return true if the object size might
763 need reexamination later. */
765 static bool
766 plus_stmt_object_size (struct object_size_info *osi, tree var, gimple stmt)
768 int object_size_type = osi->object_size_type;
769 unsigned int varno = SSA_NAME_VERSION (var);
770 unsigned HOST_WIDE_INT bytes;
771 tree op0, op1;
773 if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
775 op0 = gimple_assign_rhs1 (stmt);
776 op1 = gimple_assign_rhs2 (stmt);
778 else if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
780 tree rhs = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
781 gcc_assert (TREE_CODE (rhs) == MEM_REF);
782 op0 = TREE_OPERAND (rhs, 0);
783 op1 = TREE_OPERAND (rhs, 1);
785 else
786 gcc_unreachable ();
788 if (object_sizes[object_size_type][varno] == unknown[object_size_type])
789 return false;
791 /* Handle PTR + OFFSET here. */
792 if (TREE_CODE (op1) == INTEGER_CST
793 && (TREE_CODE (op0) == SSA_NAME
794 || TREE_CODE (op0) == ADDR_EXPR))
796 if (! host_integerp (op1, 1))
797 bytes = unknown[object_size_type];
798 else if (TREE_CODE (op0) == SSA_NAME)
799 return merge_object_sizes (osi, var, op0, tree_low_cst (op1, 1));
800 else
802 unsigned HOST_WIDE_INT off = tree_low_cst (op1, 1);
804 /* op0 will be ADDR_EXPR here. */
805 bytes = addr_object_size (osi, op0, object_size_type);
806 if (bytes == unknown[object_size_type])
808 else if (off > offset_limit)
809 bytes = unknown[object_size_type];
810 else if (off > bytes)
811 bytes = 0;
812 else
813 bytes -= off;
816 else
817 bytes = unknown[object_size_type];
819 if ((object_size_type & 2) == 0)
821 if (object_sizes[object_size_type][varno] < bytes)
822 object_sizes[object_size_type][varno] = bytes;
824 else
826 if (object_sizes[object_size_type][varno] > bytes)
827 object_sizes[object_size_type][varno] = bytes;
829 return false;
833 /* Compute object_sizes for VAR, defined at STMT, which is
834 a COND_EXPR. Return true if the object size might need reexamination
835 later. */
837 static bool
838 cond_expr_object_size (struct object_size_info *osi, tree var, gimple stmt)
840 tree then_, else_;
841 int object_size_type = osi->object_size_type;
842 unsigned int varno = SSA_NAME_VERSION (var);
843 bool reexamine = false;
845 gcc_assert (gimple_assign_rhs_code (stmt) == COND_EXPR);
847 if (object_sizes[object_size_type][varno] == unknown[object_size_type])
848 return false;
850 then_ = gimple_assign_rhs2 (stmt);
851 else_ = gimple_assign_rhs3 (stmt);
853 if (TREE_CODE (then_) == SSA_NAME)
854 reexamine |= merge_object_sizes (osi, var, then_, 0);
855 else
856 expr_object_size (osi, var, then_);
858 if (TREE_CODE (else_) == SSA_NAME)
859 reexamine |= merge_object_sizes (osi, var, else_, 0);
860 else
861 expr_object_size (osi, var, else_);
863 return reexamine;
866 /* Compute object sizes for VAR.
867 For ADDR_EXPR an object size is the number of remaining bytes
868 to the end of the object (where what is considered an object depends on
869 OSI->object_size_type).
870 For allocation GIMPLE_CALL like malloc or calloc object size is the size
871 of the allocation.
872 For POINTER_PLUS_EXPR where second operand is a constant integer,
873 object size is object size of the first operand minus the constant.
874 If the constant is bigger than the number of remaining bytes until the
875 end of the object, object size is 0, but if it is instead a pointer
876 subtraction, object size is unknown[object_size_type].
877 To differentiate addition from subtraction, ADDR_EXPR returns
878 unknown[object_size_type] for all objects bigger than half of the address
879 space, and constants less than half of the address space are considered
880 addition, while bigger constants subtraction.
881 For a memcpy like GIMPLE_CALL that always returns one of its arguments, the
882 object size is object size of that argument.
883 Otherwise, object size is the maximum of object sizes of variables
884 that it might be set to. */
886 static void
887 collect_object_sizes_for (struct object_size_info *osi, tree var)
889 int object_size_type = osi->object_size_type;
890 unsigned int varno = SSA_NAME_VERSION (var);
891 gimple stmt;
892 bool reexamine;
894 if (bitmap_bit_p (computed[object_size_type], varno))
895 return;
897 if (osi->pass == 0)
899 if (bitmap_set_bit (osi->visited, varno))
901 object_sizes[object_size_type][varno]
902 = (object_size_type & 2) ? -1 : 0;
904 else
906 /* Found a dependency loop. Mark the variable for later
907 re-examination. */
908 bitmap_set_bit (osi->reexamine, varno);
909 if (dump_file && (dump_flags & TDF_DETAILS))
911 fprintf (dump_file, "Found a dependency loop at ");
912 print_generic_expr (dump_file, var, dump_flags);
913 fprintf (dump_file, "\n");
915 return;
919 if (dump_file && (dump_flags & TDF_DETAILS))
921 fprintf (dump_file, "Visiting use-def links for ");
922 print_generic_expr (dump_file, var, dump_flags);
923 fprintf (dump_file, "\n");
926 stmt = SSA_NAME_DEF_STMT (var);
927 reexamine = false;
929 switch (gimple_code (stmt))
931 case GIMPLE_ASSIGN:
933 tree rhs = gimple_assign_rhs1 (stmt);
934 if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
935 || (gimple_assign_rhs_code (stmt) == ADDR_EXPR
936 && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF))
937 reexamine = plus_stmt_object_size (osi, var, stmt);
938 else if (gimple_assign_rhs_code (stmt) == COND_EXPR)
939 reexamine = cond_expr_object_size (osi, var, stmt);
940 else if (gimple_assign_single_p (stmt)
941 || gimple_assign_unary_nop_p (stmt))
943 if (TREE_CODE (rhs) == SSA_NAME
944 && POINTER_TYPE_P (TREE_TYPE (rhs)))
945 reexamine = merge_object_sizes (osi, var, rhs, 0);
946 else
947 expr_object_size (osi, var, rhs);
949 else
950 unknown_object_size (osi, var);
951 break;
954 case GIMPLE_CALL:
956 tree arg = pass_through_call (stmt);
957 if (arg)
959 if (TREE_CODE (arg) == SSA_NAME
960 && POINTER_TYPE_P (TREE_TYPE (arg)))
961 reexamine = merge_object_sizes (osi, var, arg, 0);
962 else
963 expr_object_size (osi, var, arg);
965 else
966 call_object_size (osi, var, stmt);
967 break;
970 case GIMPLE_ASM:
971 /* Pointers defined by __asm__ statements can point anywhere. */
972 object_sizes[object_size_type][varno] = unknown[object_size_type];
973 break;
975 case GIMPLE_NOP:
977 tree decl = SSA_NAME_VAR (var);
979 if (TREE_CODE (decl) != PARM_DECL && DECL_INITIAL (decl))
980 expr_object_size (osi, var, DECL_INITIAL (decl));
981 else
982 expr_object_size (osi, var, decl);
984 break;
986 case GIMPLE_PHI:
988 unsigned i;
990 for (i = 0; i < gimple_phi_num_args (stmt); i++)
992 tree rhs = gimple_phi_arg (stmt, i)->def;
994 if (object_sizes[object_size_type][varno]
995 == unknown[object_size_type])
996 break;
998 if (TREE_CODE (rhs) == SSA_NAME)
999 reexamine |= merge_object_sizes (osi, var, rhs, 0);
1000 else if (osi->pass == 0)
1001 expr_object_size (osi, var, rhs);
1003 break;
1006 default:
1007 gcc_unreachable ();
1010 if (! reexamine
1011 || object_sizes[object_size_type][varno] == unknown[object_size_type])
1013 bitmap_set_bit (computed[object_size_type], varno);
1014 bitmap_clear_bit (osi->reexamine, varno);
1016 else
1018 bitmap_set_bit (osi->reexamine, varno);
1019 if (dump_file && (dump_flags & TDF_DETAILS))
1021 fprintf (dump_file, "Need to reexamine ");
1022 print_generic_expr (dump_file, var, dump_flags);
1023 fprintf (dump_file, "\n");
1029 /* Helper function for check_for_plus_in_loops. Called recursively
1030 to detect loops. */
1032 static void
1033 check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
1034 unsigned int depth)
1036 gimple stmt = SSA_NAME_DEF_STMT (var);
1037 unsigned int varno = SSA_NAME_VERSION (var);
1039 if (osi->depths[varno])
1041 if (osi->depths[varno] != depth)
1043 unsigned int *sp;
1045 /* Found a loop involving pointer addition. */
1046 for (sp = osi->tos; sp > osi->stack; )
1048 --sp;
1049 bitmap_clear_bit (osi->reexamine, *sp);
1050 bitmap_set_bit (computed[osi->object_size_type], *sp);
1051 object_sizes[osi->object_size_type][*sp] = 0;
1052 if (*sp == varno)
1053 break;
1056 return;
1058 else if (! bitmap_bit_p (osi->reexamine, varno))
1059 return;
1061 osi->depths[varno] = depth;
1062 *osi->tos++ = varno;
1064 switch (gimple_code (stmt))
1067 case GIMPLE_ASSIGN:
1069 if ((gimple_assign_single_p (stmt)
1070 || gimple_assign_unary_nop_p (stmt))
1071 && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
1073 tree rhs = gimple_assign_rhs1 (stmt);
1075 check_for_plus_in_loops_1 (osi, rhs, depth);
1077 else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
1079 tree basevar = gimple_assign_rhs1 (stmt);
1080 tree cst = gimple_assign_rhs2 (stmt);
1082 gcc_assert (TREE_CODE (cst) == INTEGER_CST);
1084 check_for_plus_in_loops_1 (osi, basevar,
1085 depth + !integer_zerop (cst));
1087 else
1088 gcc_unreachable ();
1089 break;
1092 case GIMPLE_CALL:
1094 tree arg = pass_through_call (stmt);
1095 if (arg)
1097 if (TREE_CODE (arg) == SSA_NAME)
1098 check_for_plus_in_loops_1 (osi, arg, depth);
1099 else
1100 gcc_unreachable ();
1102 break;
1105 case GIMPLE_PHI:
1107 unsigned i;
1109 for (i = 0; i < gimple_phi_num_args (stmt); i++)
1111 tree rhs = gimple_phi_arg (stmt, i)->def;
1113 if (TREE_CODE (rhs) == SSA_NAME)
1114 check_for_plus_in_loops_1 (osi, rhs, depth);
1116 break;
1119 default:
1120 gcc_unreachable ();
1123 osi->depths[varno] = 0;
1124 osi->tos--;
1128 /* Check if some pointer we are computing object size of is being increased
1129 within a loop. If yes, assume all the SSA variables participating in
1130 that loop have minimum object sizes 0. */
1132 static void
1133 check_for_plus_in_loops (struct object_size_info *osi, tree var)
1135 gimple stmt = SSA_NAME_DEF_STMT (var);
1137 /* NOTE: In the pre-tuples code, we handled a CALL_EXPR here,
1138 and looked for a POINTER_PLUS_EXPR in the pass-through
1139 argument, if any. In GIMPLE, however, such an expression
1140 is not a valid call operand. */
1142 if (is_gimple_assign (stmt)
1143 && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
1145 tree basevar = gimple_assign_rhs1 (stmt);
1146 tree cst = gimple_assign_rhs2 (stmt);
1148 gcc_assert (TREE_CODE (cst) == INTEGER_CST);
1150 if (integer_zerop (cst))
1151 return;
1153 osi->depths[SSA_NAME_VERSION (basevar)] = 1;
1154 *osi->tos++ = SSA_NAME_VERSION (basevar);
1155 check_for_plus_in_loops_1 (osi, var, 2);
1156 osi->depths[SSA_NAME_VERSION (basevar)] = 0;
1157 osi->tos--;
1162 /* Initialize data structures for the object size computation. */
1164 void
1165 init_object_sizes (void)
1167 int object_size_type;
1169 if (object_sizes[0])
1170 return;
1172 for (object_size_type = 0; object_size_type <= 3; object_size_type++)
1174 object_sizes[object_size_type] = XNEWVEC (unsigned HOST_WIDE_INT, num_ssa_names);
1175 computed[object_size_type] = BITMAP_ALLOC (NULL);
1178 init_offset_limit ();
1182 /* Destroy data structures after the object size computation. */
1184 void
1185 fini_object_sizes (void)
1187 int object_size_type;
1189 for (object_size_type = 0; object_size_type <= 3; object_size_type++)
1191 free (object_sizes[object_size_type]);
1192 BITMAP_FREE (computed[object_size_type]);
1193 object_sizes[object_size_type] = NULL;
1198 /* Simple pass to optimize all __builtin_object_size () builtins. */
1200 static unsigned int
1201 compute_object_sizes (void)
1203 basic_block bb;
1204 FOR_EACH_BB (bb)
1206 gimple_stmt_iterator i;
1207 for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
1209 tree callee, result;
1210 gimple call = gsi_stmt (i);
1212 if (gimple_code (call) != GIMPLE_CALL)
1213 continue;
1215 callee = gimple_call_fndecl (call);
1216 if (!callee
1217 || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
1218 || DECL_FUNCTION_CODE (callee) != BUILT_IN_OBJECT_SIZE)
1219 continue;
1221 init_object_sizes ();
1222 result = fold_call_stmt (call, false);
1223 if (!result)
1225 if (gimple_call_num_args (call) == 2
1226 && POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0))))
1228 tree ost = gimple_call_arg (call, 1);
1230 if (host_integerp (ost, 1))
1232 unsigned HOST_WIDE_INT object_size_type
1233 = tree_low_cst (ost, 1);
1235 if (object_size_type < 2)
1236 result = fold_convert (size_type_node,
1237 integer_minus_one_node);
1238 else if (object_size_type < 4)
1239 result = build_zero_cst (size_type_node);
1243 if (!result)
1244 continue;
1247 if (dump_file && (dump_flags & TDF_DETAILS))
1249 fprintf (dump_file, "Simplified\n ");
1250 print_gimple_stmt (dump_file, call, 0, dump_flags);
1253 if (!update_call_from_tree (&i, result))
1254 gcc_unreachable ();
1256 if (dump_file && (dump_flags & TDF_DETAILS))
1258 fprintf (dump_file, "to\n ");
1259 print_gimple_stmt (dump_file, gsi_stmt (i), 0, dump_flags);
1260 fprintf (dump_file, "\n");
1265 fini_object_sizes ();
1266 return 0;
1269 struct gimple_opt_pass pass_object_sizes =
1272 GIMPLE_PASS,
1273 "objsz", /* name */
1274 NULL, /* gate */
1275 compute_object_sizes, /* execute */
1276 NULL, /* sub */
1277 NULL, /* next */
1278 0, /* static_pass_number */
1279 TV_NONE, /* tv_id */
1280 PROP_cfg | PROP_ssa, /* properties_required */
1281 0, /* properties_provided */
1282 0, /* properties_destroyed */
1283 0, /* todo_flags_start */
1284 TODO_verify_ssa /* todo_flags_finish */