diff options
author | Richard Biener <rguenth@gcc.gnu.org> | 2008-07-28 14:33:56 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-07-28 14:33:56 +0000 |
commit | 726a989a8b74bf238a96029860bcf7ba14eff317 (patch) | |
tree | 2926705dd533a8904679724ab1cec40dfee45094 /gcc/tree-object-size.c | |
parent | 0d48657d7378a4b1cb25ed181bca8020eae520f1 (diff) | |
download | gcc-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.c | 391 |
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"); } } |