diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-25 16:38:26 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-25 16:38:26 +0000 |
commit | 12d9baf99f5dc0a2bf75047322487521fa6684be (patch) | |
tree | c5579d7a1f5560c1a63423337a418a4054fce3bd /gcc/tree-ssa-structalias.c | |
parent | 37f094265d742296bceaa819821d95269f5c6cf6 (diff) | |
download | gcc-12d9baf99f5dc0a2bf75047322487521fa6684be.tar.gz |
2011-01-25 Richard Guenther <rguenther@suse.de>
PR tree-optimization/47426
* tree-ssa-structalias.c (ipa_pta_execute): Make externally
visible functions results escape.
* gcc.dg/torture/pr47426-1.c: New testcase.
* gcc.dg/torture/pr47426-2.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169241 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-structalias.c')
-rw-r--r-- | gcc/tree-ssa-structalias.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index a49f14bba13..cf1e817f377 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4435,12 +4435,14 @@ find_func_aliases (gimple origt) do_structure_copy (lhsop, rhsop); else { + enum tree_code code = gimple_assign_rhs_code (t); + get_constraint_for (lhsop, &lhsc); - if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR) + if (code == POINTER_PLUS_EXPR) get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), gimple_assign_rhs2 (t), &rhsc); - else if (gimple_assign_rhs_code (t) == BIT_AND_EXPR + else if (code == BIT_AND_EXPR && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST) { /* Aligning a pointer via a BIT_AND_EXPR is offsetting @@ -4448,11 +4450,15 @@ find_func_aliases (gimple origt) get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), NULL_TREE, &rhsc); } - else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t)) + else if ((CONVERT_EXPR_CODE_P (code) && !(POINTER_TYPE_P (gimple_expr_type (t)) && !POINTER_TYPE_P (TREE_TYPE (rhsop)))) || gimple_assign_single_p (t)) get_constraint_for_rhs (rhsop, &rhsc); + else if (truth_value_p (code)) + /* Truth value results are not pointer (parts). Or at least + very very unreasonable obfuscation of a part. */ + ; else { /* All other operations are merges. */ @@ -6827,11 +6833,34 @@ ipa_pta_execute (void) push_cfun (func); current_function_decl = node->decl; - /* For externally visible functions use local constraints for - their arguments. For local functions we see all callers - and thus do not need initial constraints for parameters. */ if (node->local.externally_visible) - intra_create_variable_infos (); + { + /* For externally visible functions use local constraints for + their arguments. For local functions we see all callers + and thus do not need initial constraints for parameters. */ + intra_create_variable_infos (); + + /* We also need to make function return values escape. Nothing + escapes by returning from main though. */ + if (!MAIN_NAME_P (DECL_NAME (node->decl))) + { + varinfo_t fi, rvi; + fi = lookup_vi_for_tree (node->decl); + rvi = first_vi_for_offset (fi, fi_result); + if (rvi && rvi->offset == fi_result) + { + struct constraint_expr includes; + struct constraint_expr var; + includes.var = escaped_id; + includes.offset = 0; + includes.type = SCALAR; + var.var = rvi->id; + var.offset = 0; + var.type = SCALAR; + process_constraint (new_constraint (includes, var)); + } + } + } /* Build constriants for the function body. */ FOR_EACH_BB_FN (bb, func) |