GCC Middle and Back End API Reference
tree-object-size.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "diagnostic-core.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "tree-ssanames.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
Include dependency graph for tree-object-size.c:

Data Structures

struct  object_size_info

Functions

static tree compute_object_offset (const_tree, const_tree)
static unsigned HOST_WIDE_INT addr_object_size (struct object_size_info *, const_tree, int)
static unsigned HOST_WIDE_INT alloc_object_size (const_gimple, int)
static tree pass_through_call (const_gimple)
static void collect_object_sizes_for (struct object_size_info *, tree)
static void expr_object_size (struct object_size_info *, tree, tree)
static bool merge_object_sizes (struct object_size_info *, tree, tree, unsigned HOST_WIDE_INT)
static bool plus_stmt_object_size (struct object_size_info *, tree, gimple)
static bool cond_expr_object_size (struct object_size_info *, tree, gimple)
static unsigned int compute_object_sizes (void)
static void init_offset_limit (void)
static void check_for_plus_in_loops (struct object_size_info *, tree)
static void check_for_plus_in_loops_1 (struct object_size_info *, tree, unsigned int)
static tree compute_object_offset ()
static unsigned HOST_WIDE_INT alloc_object_size ()
static tree pass_through_call ()
unsigned HOST_WIDE_INT compute_builtin_object_size ()
static void expr_object_size ()
static void call_object_size ()
static void unknown_object_size ()
static bool plus_stmt_object_size ()
static bool cond_expr_object_size ()
static void collect_object_sizes_for ()
static void check_for_plus_in_loops ()
void init_object_sizes ()
void fini_object_sizes ()
gimple_opt_passmake_pass_object_sizes ()

Variables

static const unsigned HOST_WIDE_INT unknown [4] = { -1, -1, 0, 0 }
static unsigned HOST_WIDE_INTobject_sizes [4]
static bitmap computed [4]
static unsigned HOST_WIDE_INT offset_limit

Function Documentation

static unsigned HOST_WIDE_INT addr_object_size ( struct object_size_info osi,
const_tree  ptr,
int  object_size_type 
)
static

Compute __builtin_object_size for PTR, which is a ADDR_EXPR. OBJECT_SIZE_TYPE is the second argument from __builtin_object_size. If unknown, return unknown[object_size_type].

For &X->fld, compute object size only if fld isn't the last field, as struct { int i; char c[1]; } is often used instead of flexible array member.

Referenced by plus_stmt_object_size().

static unsigned HOST_WIDE_INT alloc_object_size ( const_gimple  ,
int   
)
static
static unsigned HOST_WIDE_INT alloc_object_size ( )
static

Compute __builtin_object_size for CALL, which is a GIMPLE_CALL. Handles various allocation calls. OBJECT_SIZE_TYPE is the second argument from __builtin_object_size. If unknown, return unknown[object_size_type].

fall through

static void call_object_size ( )
static

Compute object_sizes for PTR, defined to the result of a call.

static void check_for_plus_in_loops ( struct object_size_info ,
tree   
)
static
static void check_for_plus_in_loops ( )
static

Check if some pointer we are computing object size of is being increased within a loop. If yes, assume all the SSA variables participating in that loop have minimum object sizes 0.

NOTE: In the pre-tuples code, we handled a CALL_EXPR here, and looked for a POINTER_PLUS_EXPR in the pass-through argument, if any. In GIMPLE, however, such an expression is not a valid call operand.

References BITMAP_ALLOC, NULL, num_ssa_names, object_size_info::object_size_type, and object_sizes.

static void check_for_plus_in_loops_1 ( struct object_size_info osi,
tree  var,
unsigned int  depth 
)
static

Helper function for check_for_plus_in_loops. Called recursively to detect loops.

Found a loop involving pointer addition.

References gcc_assert, gcc_unreachable, gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_single_p(), gimple_assign_unary_nop_p(), gimple_phi_arg(), gimple_phi_num_args(), integer_zerop(), pass_through_call(), and TREE_CODE.

static void collect_object_sizes_for ( struct object_size_info ,
tree   
)
static
static void collect_object_sizes_for ( )
static

Compute object sizes for VAR. For ADDR_EXPR an object size is the number of remaining bytes to the end of the object (where what is considered an object depends on OSI->object_size_type). For allocation GIMPLE_CALL like malloc or calloc object size is the size of the allocation. For POINTER_PLUS_EXPR where second operand is a constant integer, object size is object size of the first operand minus the constant. If the constant is bigger than the number of remaining bytes until the end of the object, object size is 0, but if it is instead a pointer subtraction, object size is unknown[object_size_type]. To differentiate addition from subtraction, ADDR_EXPR returns unknown[object_size_type] for all objects bigger than half of the address space, and constants less than half of the address space are considered addition, while bigger constants subtraction. For a memcpy like GIMPLE_CALL that always returns one of its arguments, the object size is object size of that argument. Otherwise, object size is the maximum of object sizes of variables that it might be set to.

Found a dependency loop.  Mark the variable for later
re-examination.   
     Pointers defined by <strong>asm</strong> statements can point anywhere.   


       Uninitialized SSA names point nowhere.   
unsigned HOST_WIDE_INT compute_builtin_object_size ( )

Compute __builtin_object_size value for PTR. OBJECT_SIZE_TYPE is the second argument from __builtin_object_size.

         First pass: walk UD chains, compute object sizes that
         can be computed.  osi.reexamine bitmap at the end will
         contain what variables were found in dependency cycles
         and therefore need to be reexamined.   
         Second pass: keep recomputing object sizes of variables
         that need reexamination, until no object sizes are
         increased or all object sizes are computed.   
             If looking for minimum instead of maximum object size,
             detect cases where a pointer is increased in a loop.
             Although even without this detection pass 2 would eventually
             terminate, it could take a long time.  If a pointer is
             increasing this way, we need to assume 0 object size.
             E.g. p = &buf[0]; while (cond) p = p + 4;   
                 collect_object_sizes_for is changing
                 osi.reexamine bitmap, so iterate over a copy.   
                 collect_object_sizes_for is changing
                 osi.reexamine bitmap, so iterate over a copy.   
         Debugging dumps.   

References BITMAP_ALLOC, bitmap_bit_p, bitmap_copy(), bitmap_empty_p(), BITMAP_FREE, bitmap_set_bit, object_size_info::changed, check_for_plus_in_loops(), collect_object_sizes_for(), object_size_info::depths, dump_file, dump_flags, EXECUTE_IF_SET_IN_BITMAP, HOST_WIDE_INT_PRINT_UNSIGNED, NULL, num_ssa_names, object_size_info::object_size_type, object_sizes, object_size_info::pass, print_generic_expr(), object_size_info::reexamine, ssa_name, SSA_NAME_VERSION, object_size_info::stack, TDF_DETAILS, object_size_info::tos, unknown, and object_size_info::visited.

Referenced by fold_builtin_strcspn().

static tree compute_object_offset ( const_tree  ,
const_tree   
)
static

Referenced by compute_object_offset().

static unsigned int compute_object_sizes ( )
static

Simple pass to optimize all __builtin_object_size () builtins.

static bool cond_expr_object_size ( struct object_size_info ,
tree  ,
gimple   
)
static
static bool cond_expr_object_size ( )
static

Compute object_sizes for VAR, defined at STMT, which is a COND_EXPR. Return true if the object size might need reexamination later.

References bitmap_bit_p, bitmap_set_bit, dump_file, dump_flags, object_size_info::object_size_type, object_sizes, object_size_info::pass, print_generic_expr(), object_size_info::reexamine, SSA_NAME_VERSION, TDF_DETAILS, and object_size_info::visited.

static void expr_object_size ( struct object_size_info ,
tree  ,
tree   
)
static
static void expr_object_size ( )
static

Compute object_sizes for PTR, defined to VALUE, which is not an SSA_NAME.

Pointer variables should have been handled by merge_object_sizes.

References object_size_info::object_size_type, and object_sizes.

void fini_object_sizes ( void  )

Destroy data structures after the object size computation.

void init_object_sizes ( void  )

Initialize data structures for the object size computation.

References BUILT_IN_NORMAL, DECL_BUILT_IN_CLASS, DECL_FUNCTION_CODE, FOR_EACH_BB, gimple_call_fndecl(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), and init_object_sizes().

Referenced by init_object_sizes().

static void init_offset_limit ( )
static

Initialize OFFSET_LIMIT variable.

gimple_opt_pass* make_pass_object_sizes ( )
static bool merge_object_sizes ( struct object_size_info osi,
tree  dest,
tree  orig,
unsigned HOST_WIDE_INT  offset 
)
static

Merge object sizes of ORIG + OFFSET into DEST. Return true if the object size might need reexamination later.

References object_size_info::changed, object_size_info::object_size_type, and object_sizes.

Referenced by plus_stmt_object_size().

static tree pass_through_call ( const_gimple  )
static
static tree pass_through_call ( )
static

If object size is propagated from one of function's arguments directly to its return value, return that argument for GIMPLE_CALL statement CALL. Otherwise return NULL.

static bool plus_stmt_object_size ( struct object_size_info ,
tree  ,
gimple   
)
static
static bool plus_stmt_object_size ( )
static

Compute object_sizes for VAR, defined to the result of an assignment with operator POINTER_PLUS_EXPR. Return true if the object size might need reexamination later.

Handle PTR + OFFSET here.

         op0 will be ADDR_EXPR here.   

References addr_object_size(), host_integerp(), merge_object_sizes(), object_size_info::object_size_type, offset_limit, TREE_CODE, tree_low_cst(), and unknown.

static void unknown_object_size ( )
static

Compute object_sizes for PTR, defined to an unknown value.


Variable Documentation

bitmap computed[4]
static

Bitmaps what object sizes have been computed already.

unsigned HOST_WIDE_INT* object_sizes[4]
static

object_sizes[0] is upper bound for number of bytes till the end of the object. object_sizes[1] is upper bound for number of bytes till the end of the subobject (innermost array or field with address taken). object_sizes[2] is lower bound for number of bytes till the end of the object and object_sizes[3] lower bound for subobject.

Referenced by check_for_plus_in_loops(), compute_builtin_object_size(), cond_expr_object_size(), expr_object_size(), and merge_object_sizes().

unsigned HOST_WIDE_INT offset_limit
static

Maximum value of offset we consider to be addition.

Referenced by plus_stmt_object_size().

const unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 }
static