aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-object-size.c
diff options
context:
space:
mode:
authorRichard Biener <rguenth@gcc.gnu.org>2008-07-28 14:33:56 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-07-28 14:33:56 +0000
commit726a989a8b74bf238a96029860bcf7ba14eff317 (patch)
tree2926705dd533a8904679724ab1cec40dfee45094 /gcc/tree-object-size.c
parent0d48657d7378a4b1cb25ed181bca8020eae520f1 (diff)
downloadgcc-726a989a8b74bf238a96029860bcf7ba14eff317.zip
gcc-726a989a8b74bf238a96029860bcf7ba14eff317.tar.gz
gcc-726a989a8b74bf238a96029860bcf7ba14eff317.tar.bz2
backport: ChangeLog.tuples: ChangeLog from gimple-tuples-branch.
2008-07-28 Richard Guenther <rguenther@suse.de> Merge from gimple-tuples-branch. * ChangeLog.tuples: ChangeLog from gimple-tuples-branch. * gimple.def: New file. * gsstruct.def: Likewise. * gimple-iterator.c: Likewise. * gimple-pretty-print.c: Likewise. * tree-gimple.c: Removed. Merged into ... * gimple.c: ... here. New file. * tree-gimple.h: Removed. Merged into ... * gimple.h: ... here. New file. * Makefile.in: Add dependencies on GIMPLE_H and tree-iterator.h. * configure.ac: Added support for ENABLE_GIMPLE_CHECKING and the --enable-checking=gimple flag. * config.in: Likewise. * configure: Regenerated. * tree-ssa-operands.h: Tuplified. * tree-vrp.c: Likewise. * tree-loop-linear.c: Likewise. * tree-into-ssa.c: Likewise. * tree-ssa-loop-im.c: Likewise. * tree-dump.c: Likewise. * tree-complex.c: Likewise. * cgraphbuild.c: Likewise. * tree-ssa-threadupdate.c: Likewise. * tree-ssa-loop-niter.c: Likewise. * tree-pretty-print.c: Likewise. * tracer.c: Likewise. * gengtype.c: Likewise. * tree-loop-distribution.c: Likewise. * tree-ssa-loop-unswitch.c: Likewise. * cgraph.c: Likewise. * cgraph.h: Likewise. * tree-ssa-loop-manip.c: Likewise. * value-prof.c: Likewise. * tree-ssa-loop-ch.c: Likewise. * tree-tailcall.c: Likewise. * value-prof.h: Likewise. * tree.c: Likewise. * tree.h: Likewise. * tree-pass.h: Likewise. * ipa-cp.c: Likewise. * tree-scalar-evolution.c: Likewise. * tree-scalar-evolution.h: Likewise. * target.h: Likewise. * lambda-mat.c: Likewise. * tree-phinodes.c: Likewise. * diagnostic.h: Likewise. * builtins.c: Likewise. * tree-ssa-alias-warnings.c: Likewise. * cfghooks.c: Likewise. * fold-const.c: Likewise. * cfghooks.h: Likewise. * omp-low.c: Likewise. * tree-ssa-dse.c: Likewise. * ipa-reference.c: Likewise. * tree-ssa-uncprop.c: Likewise. * toplev.c: Likewise. * tree-gimple.c: Likewise. * tree-gimple.h: Likewise. * tree-chrec.c: Likewise. * tree-chrec.h: Likewise. * tree-ssa-sccvn.c: Likewise. * tree-ssa-sccvn.h: Likewise. * cgraphunit.c: Likewise. * tree-ssa-copyrename.c: Likewise. * tree-ssa-ccp.c: Likewise. * tree-ssa-loop-ivopts.c: Likewise. * tree-nomudflap.c: Likewise. * tree-call-cdce.c: Likewise. * ipa-pure-const.c: Likewise. * c-format.c: Likewise. * tree-stdarg.c: Likewise. * tree-ssa-math-opts.c: Likewise. * tree-ssa-dom.c: Likewise. * tree-nrv.c: Likewise. * tree-ssa-propagate.c: Likewise. * ipa-utils.c: Likewise. * tree-ssa-propagate.h: Likewise. * tree-ssa-alias.c: Likewise. * gimple-low.c: Likewise. * tree-ssa-sink.c: Likewise. * ipa-inline.c: Likewise. * c-semantics.c: Likewise. * dwarf2out.c: Likewise. * expr.c: Likewise. * tree-ssa-loop-ivcanon.c: Likewise. * predict.c: Likewise. * tree-ssa-loop.c: Likewise. * tree-parloops.c: Likewise. * tree-ssa-address.c: Likewise. * tree-ssa-ifcombine.c: Likewise. * matrix-reorg.c: Likewise. * c-decl.c: Likewise. * tree-eh.c: Likewise. * c-pretty-print.c: Likewise. * lambda-trans.c: Likewise. * function.c: Likewise. * langhooks.c: Likewise. * ebitmap.h: Likewise. * tree-vectorizer.c: Likewise. * function.h: Likewise. * langhooks.h: Likewise. * tree-vectorizer.h: Likewise. * ipa-type-escape.c: Likewise. * ipa-type-escape.h: Likewise. * domwalk.c: Likewise. * tree-if-conv.c: Likewise. * profile.c: Likewise. * domwalk.h: Likewise. * tree-data-ref.c: Likewise. * tree-data-ref.h: Likewise. * tree-flow-inline.h: Likewise. * tree-affine.c: Likewise. * tree-vect-analyze.c: Likewise. * c-typeck.c: Likewise. * gimplify.c: Likewise. * coretypes.h: Likewise. * tree-ssa-phiopt.c: Likewise. * calls.c: Likewise. * tree-ssa-coalesce.c: Likewise. * tree.def: Likewise. * tree-dfa.c: Likewise. * except.c: Likewise. * except.h: Likewise. * cfgexpand.c: Likewise. * tree-cfgcleanup.c: Likewise. * tree-ssa-pre.c: Likewise. * tree-ssa-live.c: Likewise. * tree-sra.c: Likewise. * tree-ssa-live.h: Likewise. * tree-predcom.c: Likewise. * lambda.h: Likewise. * tree-mudflap.c: Likewise. * ipa-prop.c: Likewise. * print-tree.c: Likewise. * tree-ssa-copy.c: Likewise. * ipa-prop.h: Likewise. * tree-ssa-forwprop.c: Likewise. * ggc-page.c: Likewise. * c-omp.c: Likewise. * tree-ssa-dce.c: Likewise. * tree-vect-patterns.c: Likewise. * tree-ssa-ter.c: Likewise. * tree-nested.c: Likewise. * tree-ssa.c: Likewise. * lambda-code.c: Likewise. * tree-ssa-loop-prefetch.c: Likewise. * tree-inline.c: Likewise. * tree-inline.h: Likewise. * tree-iterator.c: Likewise. * tree-optimize.c: Likewise. * tree-ssa-phiprop.c: Likewise. * tree-vect-transform.c: Likewise. * tree-object-size.c: Likewise. * tree-outof-ssa.c: Likewise. * cfgloop.c: Likewise. * system.h: Likewise. * tree-profile.c: Likewise. * cfgloop.h: Likewise. * c-gimplify.c: Likewise. * c-common.c: Likewise. * tree-vect-generic.c: Likewise. * tree-flow.h: Likewise. * c-common.h: Likewise. * basic-block.h: Likewise. * tree-ssa-structalias.c: Likewise. * tree-switch-conversion.c: Likewise. * tree-ssa-structalias.h: Likewise. * tree-cfg.c: Likewise. * passes.c: Likewise. * ipa-struct-reorg.c: Likewise. * ipa-struct-reorg.h: Likewise. * tree-ssa-reassoc.c: Likewise. * cfgrtl.c: Likewise. * varpool.c: Likewise. * stmt.c: Likewise. * tree-ssanames.c: Likewise. * tree-ssa-threadedge.c: Likewise. * langhooks-def.h: Likewise. * tree-ssa-operands.c: Likewise. * config/alpha/alpha.c: Likewise. * config/frv/frv.c: Likewise. * config/s390/s390.c: Likewise. * config/m32c/m32c.c: Likewise. * config/m32c/m32c-protos.h: Likewise. * config/spu/spu.c: Likewise. * config/sparc/sparc.c: Likewise. * config/i386/i386.c: Likewise. * config/sh/sh.c: Likewise. * config/xtensa/xtensa.c: Likewise. * config/stormy16/stormy16.c: Likewise. * config/ia64/ia64.c: Likewise. * config/rs6000/rs6000.c: Likewise. * config/pa/pa.c: Likewise. * config/mips/mips.c: Likewise. From-SVN: r138207
Diffstat (limited to 'gcc/tree-object-size.c')
-rw-r--r--gcc/tree-object-size.c391
1 files changed, 215 insertions, 176 deletions
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index c1b3b5f..22c4951 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -43,13 +43,13 @@ static unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
static tree compute_object_offset (const_tree, const_tree);
static unsigned HOST_WIDE_INT addr_object_size (const_tree, int);
-static unsigned HOST_WIDE_INT alloc_object_size (const_tree, int);
-static tree pass_through_call (const_tree);
+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_expr_object_size (struct object_size_info *, tree, tree);
+static bool plus_stmt_object_size (struct object_size_info *, tree, gimple);
static bool cond_expr_object_size (struct object_size_info *, tree, tree);
static unsigned int compute_object_sizes (void);
static void init_offset_limit (void);
@@ -219,21 +219,21 @@ addr_object_size (const_tree ptr, int object_size_type)
}
-/* Compute __builtin_object_size for CALL, which is a CALL_EXPR.
+/* 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]. */
static unsigned HOST_WIDE_INT
-alloc_object_size (const_tree call, int object_size_type)
+alloc_object_size (const_gimple call, int object_size_type)
{
tree callee, bytes = NULL_TREE;
tree alloc_size;
int arg1 = -1, arg2 = -1;
- gcc_assert (TREE_CODE (call) == CALL_EXPR);
+ gcc_assert (is_gimple_call (call));
- callee = get_callee_fndecl (call);
+ callee = gimple_call_fndecl (call);
if (!callee)
return unknown[object_size_type];
@@ -244,7 +244,7 @@ alloc_object_size (const_tree call, int object_size_type)
arg1 = TREE_INT_CST_LOW (TREE_VALUE (p))-1;
if (TREE_CHAIN (p))
- arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
+ arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
}
if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
@@ -260,19 +260,19 @@ alloc_object_size (const_tree call, int object_size_type)
break;
}
- if (arg1 < 0 || arg1 >= call_expr_nargs (call)
- || TREE_CODE (CALL_EXPR_ARG (call, arg1)) != INTEGER_CST
+ if (arg1 < 0 || arg1 >= (int)gimple_call_num_args (call)
+ || TREE_CODE (gimple_call_arg (call, arg1)) != INTEGER_CST
|| (arg2 >= 0
- && (arg2 >= call_expr_nargs (call)
- || TREE_CODE (CALL_EXPR_ARG (call, arg2)) != INTEGER_CST)))
+ && (arg2 >= (int)gimple_call_num_args (call)
+ || TREE_CODE (gimple_call_arg (call, arg2)) != INTEGER_CST)))
return unknown[object_size_type];
if (arg2 >= 0)
bytes = size_binop (MULT_EXPR,
- fold_convert (sizetype, CALL_EXPR_ARG (call, arg1)),
- fold_convert (sizetype, CALL_EXPR_ARG (call, arg2)));
+ fold_convert (sizetype, gimple_call_arg (call, arg1)),
+ fold_convert (sizetype, gimple_call_arg (call, arg2)));
else if (arg1 >= 0)
- bytes = fold_convert (sizetype, CALL_EXPR_ARG (call, arg1));
+ bytes = fold_convert (sizetype, gimple_call_arg (call, arg1));
if (bytes && host_integerp (bytes, 1))
return tree_low_cst (bytes, 1);
@@ -282,13 +282,13 @@ alloc_object_size (const_tree call, int object_size_type)
/* If object size is propagated from one of function's arguments directly
- to its return value, return that argument for CALL_EXPR CALL.
+ to its return value, return that argument for GIMPLE_CALL statement CALL.
Otherwise return NULL. */
static tree
-pass_through_call (const_tree call)
+pass_through_call (const_gimple call)
{
- tree callee = get_callee_fndecl (call);
+ tree callee = gimple_call_fndecl (call);
if (callee
&& DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
@@ -308,8 +308,8 @@ pass_through_call (const_tree call)
case BUILT_IN_STRNCPY_CHK:
case BUILT_IN_STRCAT_CHK:
case BUILT_IN_STRNCAT_CHK:
- if (call_expr_nargs (call) >= 1)
- return CALL_EXPR_ARG (call, 0);
+ if (gimple_call_num_args (call) >= 1)
+ return gimple_call_arg (call, 0);
break;
default:
break;
@@ -332,16 +332,8 @@ compute_builtin_object_size (tree ptr, int object_size_type)
if (TREE_CODE (ptr) == ADDR_EXPR)
return addr_object_size (ptr, object_size_type);
- else if (TREE_CODE (ptr) == CALL_EXPR)
- {
- tree arg = pass_through_call (ptr);
- if (arg)
- return compute_builtin_object_size (arg, object_size_type);
- else
- return alloc_object_size (ptr, object_size_type);
- }
- else if (TREE_CODE (ptr) == SSA_NAME
+ if (TREE_CODE (ptr) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (ptr))
&& object_sizes[object_size_type] != NULL)
{
@@ -463,9 +455,7 @@ compute_builtin_object_size (tree ptr, int object_size_type)
return unknown[object_size_type];
}
-
-/* Compute object_sizes for PTR, defined to VALUE, which is not
- a SSA_NAME. */
+/* Compute object_sizes for PTR, defined to VALUE, which is not an SSA_NAME. */
static void
expr_object_size (struct object_size_info *osi, tree ptr, tree value)
@@ -487,8 +477,6 @@ expr_object_size (struct object_size_info *osi, tree ptr, tree value)
if (TREE_CODE (value) == ADDR_EXPR)
bytes = addr_object_size (value, object_size_type);
- else if (TREE_CODE (value) == CALL_EXPR)
- bytes = alloc_object_size (value, object_size_type);
else
bytes = unknown[object_size_type];
@@ -505,6 +493,64 @@ expr_object_size (struct object_size_info *osi, tree ptr, tree value)
}
+/* Compute object_sizes for PTR, defined to the result of a call. */
+
+static void
+call_object_size (struct object_size_info *osi, tree ptr, gimple call)
+{
+ int object_size_type = osi->object_size_type;
+ unsigned int varno = SSA_NAME_VERSION (ptr);
+ unsigned HOST_WIDE_INT bytes;
+
+ gcc_assert (is_gimple_call (call));
+
+ gcc_assert (object_sizes[object_size_type][varno]
+ != unknown[object_size_type]);
+ gcc_assert (osi->pass == 0);
+
+ bytes = alloc_object_size (call, object_size_type);
+
+ if ((object_size_type & 2) == 0)
+ {
+ if (object_sizes[object_size_type][varno] < bytes)
+ object_sizes[object_size_type][varno] = bytes;
+ }
+ else
+ {
+ if (object_sizes[object_size_type][varno] > bytes)
+ object_sizes[object_size_type][varno] = bytes;
+ }
+}
+
+
+/* Compute object_sizes for PTR, defined to an unknown value. */
+
+static void
+unknown_object_size (struct object_size_info *osi, tree ptr)
+{
+ int object_size_type = osi->object_size_type;
+ unsigned int varno = SSA_NAME_VERSION (ptr);
+ unsigned HOST_WIDE_INT bytes;
+
+ gcc_assert (object_sizes[object_size_type][varno]
+ != unknown[object_size_type]);
+ gcc_assert (osi->pass == 0);
+
+ bytes = unknown[object_size_type];
+
+ if ((object_size_type & 2) == 0)
+ {
+ if (object_sizes[object_size_type][varno] < bytes)
+ object_sizes[object_size_type][varno] = bytes;
+ }
+ else
+ {
+ if (object_sizes[object_size_type][varno] > bytes)
+ object_sizes[object_size_type][varno] = bytes;
+ }
+}
+
+
/* Merge object sizes of ORIG + OFFSET into DEST. Return true if
the object size might need reexamination later. */
@@ -552,20 +598,22 @@ merge_object_sizes (struct object_size_info *osi, tree dest, tree orig,
}
-/* Compute object_sizes for PTR, defined to VALUE, which is
- a POINTER_PLUS_EXPR. Return true if the object size might need reexamination
- later. */
+/* 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. */
static bool
-plus_expr_object_size (struct object_size_info *osi, tree var, tree value)
+plus_stmt_object_size (struct object_size_info *osi, tree var, gimple stmt)
{
- tree op0 = TREE_OPERAND (value, 0);
- tree op1 = TREE_OPERAND (value, 1);
int object_size_type = osi->object_size_type;
unsigned int varno = SSA_NAME_VERSION (var);
unsigned HOST_WIDE_INT bytes;
+ tree op0, op1;
+
+ gcc_assert (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR);
- gcc_assert (TREE_CODE (value) == POINTER_PLUS_EXPR);
+ op0 = gimple_assign_rhs1 (stmt);
+ op1 = gimple_assign_rhs2 (stmt);
if (object_sizes[object_size_type][varno] == unknown[object_size_type])
return false;
@@ -583,6 +631,7 @@ plus_expr_object_size (struct object_size_info *osi, tree var, tree value)
{
unsigned HOST_WIDE_INT off = tree_low_cst (op1, 1);
+ /* op0 will be ADDR_EXPR here. */
bytes = compute_builtin_object_size (op0, object_size_type);
if (bytes == unknown[object_size_type])
;
@@ -611,7 +660,7 @@ plus_expr_object_size (struct object_size_info *osi, tree var, tree value)
}
-/* Compute object_sizes for PTR, defined to VALUE, which is
+/* Compute object_sizes for VAR, defined to VALUE, which is
a COND_EXPR. Return true if the object size might need reexamination
later. */
@@ -644,12 +693,11 @@ cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
return reexamine;
}
-
/* 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 CALL_EXPR like malloc or calloc object size is the size
+ 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.
@@ -660,7 +708,7 @@ cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
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 CALL_EXPR that always returns one of its arguments, the
+ 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. */
@@ -670,7 +718,7 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
{
int object_size_type = osi->object_size_type;
unsigned int varno = SSA_NAME_VERSION (var);
- tree stmt;
+ gimple stmt;
bool reexamine;
if (bitmap_bit_p (computed[object_size_type], varno))
@@ -709,51 +757,57 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
stmt = SSA_NAME_DEF_STMT (var);
reexamine = false;
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case RETURN_EXPR:
- gcc_assert (TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT);
- stmt = TREE_OPERAND (stmt, 0);
- /* FALLTHRU */
-
- case GIMPLE_MODIFY_STMT:
+ case GIMPLE_ASSIGN:
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), arg;
- STRIP_NOPS (rhs);
-
- if (TREE_CODE (rhs) == CALL_EXPR)
- {
- arg = pass_through_call (rhs);
- if (arg)
- rhs = arg;
- }
-
- if (TREE_CODE (rhs) == SSA_NAME
- && POINTER_TYPE_P (TREE_TYPE (rhs)))
- reexamine = merge_object_sizes (osi, var, rhs, 0);
-
- else if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
- reexamine = plus_expr_object_size (osi, var, rhs);
-
- else if (TREE_CODE (rhs) == COND_EXPR)
- reexamine = cond_expr_object_size (osi, var, rhs);
+ if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
+ reexamine = plus_stmt_object_size (osi, var, stmt);
+ else if (gimple_assign_single_p (stmt)
+ || gimple_assign_unary_nop_p (stmt))
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ if (TREE_CODE (rhs) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (rhs)))
+ reexamine = merge_object_sizes (osi, var, rhs, 0);
+ else if (TREE_CODE (rhs) == COND_EXPR)
+ reexamine = cond_expr_object_size (osi, var, rhs);
+ else
+ expr_object_size (osi, var, rhs);
+ }
+ else
+ unknown_object_size (osi, var);
+ break;
+ }
- else
- expr_object_size (osi, var, rhs);
+ case GIMPLE_CALL:
+ {
+ tree arg = pass_through_call (stmt);
+ if (arg)
+ {
+ if (TREE_CODE (arg) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (arg)))
+ reexamine = merge_object_sizes (osi, var, arg, 0);
+ else if (TREE_CODE (arg) == COND_EXPR)
+ reexamine = cond_expr_object_size (osi, var, arg);
+ else
+ expr_object_size (osi, var, arg);
+ }
+ else
+ call_object_size (osi, var, stmt);
break;
}
- case ASM_EXPR:
+ case GIMPLE_ASM:
/* Pointers defined by __asm__ statements can point anywhere. */
object_sizes[object_size_type][varno] = unknown[object_size_type];
break;
- case NOP_EXPR:
+ case GIMPLE_NOP:
{
tree decl = SSA_NAME_VAR (var);
- gcc_assert (IS_EMPTY_STMT (stmt));
-
if (TREE_CODE (decl) != PARM_DECL && DECL_INITIAL (decl))
expr_object_size (osi, var, DECL_INITIAL (decl));
else
@@ -761,13 +815,13 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
}
break;
- case PHI_NODE:
+ case GIMPLE_PHI:
{
- int i;
+ unsigned i;
- for (i = 0; i < PHI_NUM_ARGS (stmt); i++)
+ for (i = 0; i < gimple_phi_num_args (stmt); i++)
{
- tree rhs = PHI_ARG_DEF (stmt, i);
+ tree rhs = gimple_phi_arg (stmt, i)->def;
if (object_sizes[object_size_type][varno]
== unknown[object_size_type])
@@ -780,6 +834,7 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
}
break;
}
+
default:
gcc_unreachable ();
}
@@ -810,7 +865,7 @@ static void
check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
unsigned int depth)
{
- tree stmt = SSA_NAME_DEF_STMT (var);
+ gimple stmt = SSA_NAME_DEF_STMT (var);
unsigned int varno = SSA_NAME_VERSION (var);
if (osi->depths[varno])
@@ -838,57 +893,61 @@ check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
osi->depths[varno] = depth;
*osi->tos++ = varno;
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case RETURN_EXPR:
- gcc_assert (TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT);
- stmt = TREE_OPERAND (stmt, 0);
- /* FALLTHRU */
- case GIMPLE_MODIFY_STMT:
+ case GIMPLE_ASSIGN:
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), arg;
- STRIP_NOPS (rhs);
-
- if (TREE_CODE (rhs) == CALL_EXPR)
- {
- arg = pass_through_call (rhs);
- if (arg)
- rhs = arg;
- }
-
- if (TREE_CODE (rhs) == SSA_NAME)
- check_for_plus_in_loops_1 (osi, rhs, depth);
- else if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
- {
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
- tree cst, basevar;
-
- basevar = op0;
- cst = op1;
- gcc_assert (TREE_CODE (cst) == INTEGER_CST);
+ if ((gimple_assign_single_p (stmt)
+ || gimple_assign_unary_nop_p (stmt))
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ check_for_plus_in_loops_1 (osi, rhs, depth);
+ }
+ else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
+ {
+ tree basevar = gimple_assign_rhs1 (stmt);
+ tree cst = gimple_assign_rhs2 (stmt);
+
+ gcc_assert (TREE_CODE (cst) == INTEGER_CST);
+
+ check_for_plus_in_loops_1 (osi, basevar,
+ depth + !integer_zerop (cst));
+ }
+ else
+ gcc_unreachable ();
+ break;
+ }
- check_for_plus_in_loops_1 (osi, basevar,
- depth + !integer_zerop (cst));
- }
- else
- gcc_unreachable ();
- break;
+ case GIMPLE_CALL:
+ {
+ tree arg = pass_through_call (stmt);
+ if (arg)
+ {
+ if (TREE_CODE (arg) == SSA_NAME)
+ check_for_plus_in_loops_1 (osi, arg, depth);
+ else
+ gcc_unreachable ();
+ }
+ break;
}
- case PHI_NODE:
+
+ case GIMPLE_PHI:
{
- int i;
+ unsigned i;
- for (i = 0; i < PHI_NUM_ARGS (stmt); i++)
+ for (i = 0; i < gimple_phi_num_args (stmt); i++)
{
- tree rhs = PHI_ARG_DEF (stmt, i);
+ tree rhs = gimple_phi_arg (stmt, i)->def;
if (TREE_CODE (rhs) == SSA_NAME)
check_for_plus_in_loops_1 (osi, rhs, depth);
}
break;
}
+
default:
gcc_unreachable ();
}
@@ -905,50 +964,29 @@ check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
static void
check_for_plus_in_loops (struct object_size_info *osi, tree var)
{
- tree stmt = SSA_NAME_DEF_STMT (var);
+ gimple stmt = SSA_NAME_DEF_STMT (var);
- switch (TREE_CODE (stmt))
- {
- case RETURN_EXPR:
- gcc_assert (TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT);
- stmt = TREE_OPERAND (stmt, 0);
- /* FALLTHRU */
-
- case GIMPLE_MODIFY_STMT:
- {
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), arg;
- STRIP_NOPS (rhs);
-
- if (TREE_CODE (rhs) == CALL_EXPR)
- {
- arg = pass_through_call (rhs);
- if (arg)
- rhs = arg;
- }
+ /* 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. */
- if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
- {
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
- tree cst, basevar;
-
- basevar = op0;
- cst = op1;
- gcc_assert (TREE_CODE (cst) == INTEGER_CST);
-
- if (integer_zerop (cst))
- break;
-
- osi->depths[SSA_NAME_VERSION (basevar)] = 1;
- *osi->tos++ = SSA_NAME_VERSION (basevar);
- check_for_plus_in_loops_1 (osi, var, 2);
- osi->depths[SSA_NAME_VERSION (basevar)] = 0;
- osi->tos--;
- }
- break;
- }
- default:
- break;
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
+ {
+ tree basevar = gimple_assign_rhs1 (stmt);
+ tree cst = gimple_assign_rhs2 (stmt);
+
+ gcc_assert (TREE_CODE (cst) == INTEGER_CST);
+
+ if (integer_zerop (cst))
+ return;
+
+ osi->depths[SSA_NAME_VERSION (basevar)] = 1;
+ *osi->tos++ = SSA_NAME_VERSION (basevar);
+ check_for_plus_in_loops_1 (osi, var, 2);
+ osi->depths[SSA_NAME_VERSION (basevar)] = 0;
+ osi->tos--;
}
}
@@ -997,30 +1035,29 @@ compute_object_sizes (void)
basic_block bb;
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ gimple_stmt_iterator i;
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree *stmtp = bsi_stmt_ptr (i);
- tree call = get_rhs (*stmtp);
tree callee, result;
+ gimple call = gsi_stmt (i);
- if (!call || TREE_CODE (call) != CALL_EXPR)
+ if (gimple_code (call) != GIMPLE_CALL)
continue;
- callee = get_callee_fndecl (call);
+ callee = gimple_call_fndecl (call);
if (!callee
|| DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
|| DECL_FUNCTION_CODE (callee) != BUILT_IN_OBJECT_SIZE)
continue;
init_object_sizes ();
- result = fold_call_expr (call, false);
+ result = fold_call_stmt (call, false);
if (!result)
{
- if (call_expr_nargs (call) == 2
- && POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (call, 0))))
+ if (gimple_call_num_args (call) == 2
+ && POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0))))
{
- tree ost = CALL_EXPR_ARG (call, 1);
+ tree ost = gimple_call_arg (call, 1);
if (host_integerp (ost, 1))
{
@@ -1042,17 +1079,19 @@ compute_object_sizes (void)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Simplified\n ");
- print_generic_stmt (dump_file, *stmtp, dump_flags);
+ print_gimple_stmt (dump_file, call, 0, dump_flags);
}
- if (!set_rhs (stmtp, result))
+ if (!update_call_from_tree (&i, result))
gcc_unreachable ();
- update_stmt (*stmtp);
+
+ /* NOTE: In the pre-tuples code, we called update_stmt here. This is
+ now handled by gsi_replace, called from update_call_from_tree. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "to\n ");
- print_generic_stmt (dump_file, *stmtp, dump_flags);
+ print_gimple_stmt (dump_file, call, 0, dump_flags);
fprintf (dump_file, "\n");
}
}