GCC Middle and Back End API 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"
Data Structures | |
struct | object_size_info |
Variables | |
static const unsigned HOST_WIDE_INT | unknown [4] = { -1, -1, 0, 0 } |
static unsigned HOST_WIDE_INT * | object_sizes [4] |
static bitmap | computed [4] |
static unsigned HOST_WIDE_INT | offset_limit |
|
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 |
|
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 |
Compute object_sizes for PTR, defined to the result of a call.
|
static |
Referenced by compute_builtin_object_size().
|
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 |
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 |
Referenced by compute_builtin_object_size().
|
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 |
Referenced by compute_object_offset().
|
static |
Compute offset of EXPR within VAR. Return error_mark_node if unknown.
References BITS_PER_UNIT, CASE_CONVERT, compute_object_offset(), DECL_FIELD_BIT_OFFSET, DECL_FIELD_OFFSET, double_int_to_tree(), error_mark_node, fold_build1, fold_convert, gcc_assert, mem_ref_offset(), size_binop, size_int, sizetype, TREE_CODE, tree_int_cst_sgn(), tree_low_cst(), TREE_OPERAND, TREE_TYPE, and TYPE_SIZE_UNIT.
|
static |
Simple pass to optimize all __builtin_object_size () builtins.
|
static |
|
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 |
|
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 |
Initialize OFFSET_LIMIT variable.
gimple_opt_pass* make_pass_object_sizes | ( | ) |
|
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 |
Referenced by check_for_plus_in_loops_1().
|
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 |
|
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 |
Compute object_sizes for PTR, defined to an unknown value.
|
static |
Bitmaps what object sizes have been computed already.
|
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().
|
static |
Maximum value of offset we consider to be addition.
Referenced by plus_stmt_object_size().
|
static |
Referenced by compute_builtin_object_size(), make_length_attrs(), and plus_stmt_object_size().