From f0eddb90199eac4df644329c8cd0089b110062f1 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 16 Mar 2011 11:36:30 +0000 Subject: [PATCH] gimple-fold.c (maybe_fold_reference): Open-code relevant constant folding. 2011-03-16 Richard Guenther * gimple-fold.c (maybe_fold_reference): Open-code relevant constant folding. Move MEM_REF canonicalization first. Rely on fold_const_aggregate_ref for initializer folding. * tree-ssa-ccp.c (ccp_fold): Handle constant vector extracts. * gcc.dg/tree-ssa/pr14814.c: Adjust. * gcc.dg/tree-ssa/ssa-ccp-19.c: Likewise. From-SVN: r171043 --- gcc/ChangeLog | 7 ++ gcc/gimple-fold.c | 87 ++++++++++------------ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/tree-ssa/pr14814.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-19.c | 2 +- gcc/tree-ssa-ccp.c | 11 +++ 6 files changed, 66 insertions(+), 48 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5f4c4ed497..f42547c88fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-03-16 Richard Guenther + + * gimple-fold.c (maybe_fold_reference): Open-code relevant + constant folding. Move MEM_REF canonicalization first. + Rely on fold_const_aggregate_ref for initializer folding. + * tree-ssa-ccp.c (ccp_fold): Handle constant vector extracts. + 2011-03-16 Jakub Jelinek PR middle-end/48136 diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index abc2273adf8..158cb05802d 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -560,23 +560,50 @@ maybe_fold_reference (tree expr, bool is_lhs) tree *t = &expr; tree result; - if (!is_lhs - && (result = fold_const_aggregate_ref (expr)) - && is_gimple_min_invariant (result)) - return result; + if ((TREE_CODE (expr) == VIEW_CONVERT_EXPR + || TREE_CODE (expr) == REALPART_EXPR + || TREE_CODE (expr) == IMAGPART_EXPR) + && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0))) + return fold_unary_loc (EXPR_LOCATION (expr), + TREE_CODE (expr), + TREE_TYPE (expr), + TREE_OPERAND (expr, 0)); + else if (TREE_CODE (expr) == BIT_FIELD_REF + && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0))) + return fold_ternary_loc (EXPR_LOCATION (expr), + TREE_CODE (expr), + TREE_TYPE (expr), + TREE_OPERAND (expr, 0), + TREE_OPERAND (expr, 1), + TREE_OPERAND (expr, 2)); + + while (handled_component_p (*t)) + t = &TREE_OPERAND (*t, 0); - /* ??? We might want to open-code the relevant remaining cases - to avoid using the generic fold. */ - if (handled_component_p (*t) - && CONSTANT_CLASS_P (TREE_OPERAND (*t, 0))) + /* Canonicalize MEM_REFs invariant address operand. Do this first + to avoid feeding non-canonical MEM_REFs elsewhere. */ + if (TREE_CODE (*t) == MEM_REF + && !is_gimple_mem_ref_addr (TREE_OPERAND (*t, 0))) { - tree tem = fold (*t); - if (tem != *t) - return tem; + bool volatile_p = TREE_THIS_VOLATILE (*t); + tree tem = fold_binary (MEM_REF, TREE_TYPE (*t), + TREE_OPERAND (*t, 0), + TREE_OPERAND (*t, 1)); + if (tem) + { + TREE_THIS_VOLATILE (tem) = volatile_p; + *t = tem; + tem = maybe_fold_reference (expr, is_lhs); + if (tem) + return tem; + return expr; + } } - while (handled_component_p (*t)) - t = &TREE_OPERAND (*t, 0); + if (!is_lhs + && (result = fold_const_aggregate_ref (expr)) + && is_gimple_min_invariant (result)) + return result; /* Fold back MEM_REFs to reference trees. */ if (TREE_CODE (*t) == MEM_REF @@ -593,7 +620,7 @@ maybe_fold_reference (tree expr, bool is_lhs) compatibility. */ && types_compatible_p (TREE_TYPE (*t), TREE_TYPE (TREE_OPERAND - (TREE_OPERAND (*t, 0), 0)))) + (TREE_OPERAND (*t, 0), 0)))) { tree tem; *t = TREE_OPERAND (TREE_OPERAND (*t, 0), 0); @@ -602,24 +629,6 @@ maybe_fold_reference (tree expr, bool is_lhs) return tem; return expr; } - /* Canonicalize MEM_REFs invariant address operand. */ - else if (TREE_CODE (*t) == MEM_REF - && !is_gimple_mem_ref_addr (TREE_OPERAND (*t, 0))) - { - bool volatile_p = TREE_THIS_VOLATILE (*t); - tree tem = fold_binary (MEM_REF, TREE_TYPE (*t), - TREE_OPERAND (*t, 0), - TREE_OPERAND (*t, 1)); - if (tem) - { - TREE_THIS_VOLATILE (tem) = volatile_p; - *t = tem; - tem = maybe_fold_reference (expr, is_lhs); - if (tem) - return tem; - return expr; - } - } else if (TREE_CODE (*t) == TARGET_MEM_REF) { tree tem = maybe_fold_tmr (*t); @@ -632,20 +641,6 @@ maybe_fold_reference (tree expr, bool is_lhs) return expr; } } - else if (!is_lhs - && DECL_P (*t)) - { - tree tem = get_symbol_constant_value (*t); - if (tem - && useless_type_conversion_p (TREE_TYPE (*t), TREE_TYPE (tem))) - { - *t = unshare_expr (tem); - tem = maybe_fold_reference (expr, is_lhs); - if (tem) - return tem; - return expr; - } - } return NULL_TREE; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7e952dca4e5..b3d5f8193fd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-03-16 Richard Guenther + + * gcc.dg/tree-ssa/pr14814.c: Adjust. + * gcc.dg/tree-ssa/ssa-ccp-19.c: Likewise. + 2011-03-16 Jakub Jelinek PR middle-end/48136 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr14814.c b/gcc/testsuite/gcc.dg/tree-ssa/pr14814.c index eb360551561..20608156f3c 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr14814.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr14814.c @@ -18,5 +18,5 @@ int foo(const struct XX* r) { return 1; } -/* { dg-final { scan-tree-dump-times "&" 0 "forwprop2" } } */ +/* { dg-final { scan-tree-dump-times "= &" 0 "forwprop2" } } */ /* { dg-final { cleanup-tree-dump "forwprop2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-19.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-19.c index ab4182246a3..c67373f017e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-19.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-19.c @@ -12,5 +12,5 @@ int g() return *i; /* This should be turned into a.i */ } -/* { dg-final { scan-tree-dump "= a.i;" "ccp1" } } */ +/* { dg-final { scan-tree-dump "= MEM\\\[\\\(int \\\*\\\)&a\\\];" "ccp1" } } */ /* { dg-final { cleanup-tree-dump "ccp1" } } */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 8b8d996f508..4fc4316bb1c 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1182,6 +1182,17 @@ ccp_fold (gimple stmt) TREE_CODE (rhs), TREE_TYPE (rhs), val); } + else if (TREE_CODE (rhs) == BIT_FIELD_REF + && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME) + { + tree val = get_constant_value (TREE_OPERAND (rhs, 0)); + if (val) + return fold_ternary_loc (EXPR_LOCATION (rhs), + TREE_CODE (rhs), + TREE_TYPE (rhs), val, + TREE_OPERAND (rhs, 1), + TREE_OPERAND (rhs, 2)); + } else if (TREE_CODE (rhs) == MEM_REF && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME) { -- 2.30.2