From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31780 invoked by alias); 15 Mar 2008 18:20:46 -0000 Received: (qmail 31770 invoked by uid 22791); 15 Mar 2008 18:20:45 -0000 X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 15 Mar 2008 18:20:26 +0000 Received: from Relay1.suse.de (relay-ext.suse.de [195.135.221.8]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 804FE3BD85 for ; Sat, 15 Mar 2008 19:20:23 +0100 (CET) Date: Sat, 15 Mar 2008 20:34:00 -0000 From: Richard Guenther To: gcc-patches@gcc.gnu.org Subject: [PATCH] Make non-store CCP stronger Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2008-03/txt/msg00953.txt.bz2 I wondered why early CCP does not recognize static const int x; int foo(void) { return "hello"[x]; } but in fact it does notice that "hello"[x] is likely constant. It just fails to try folding constant aggregate refs in ccp_fold which then returns not NULL as advertised, but the original tree. So we do not fall back to the !simplified case, but simply fail. Duh. This part of evaluate_stmt was "interesting" everytime I looked at it, so I just simplified it and moved the foldings that should be done for likely constant values into ccp_fold itself. Of course it had some shortcomings which were thus fixed. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2008-03-15 Richard Guenther * tree-ssa-ccp.c (ccp_fold): Also read from constant values and fold constant aggregate refs. (fold_const_aggregate_ref): Handle string constants and constructors in ARRAY_REFs. Handle INDIRECT_REF. (evaluate_stmt): Simplify now that ccp_fold folds constant aggregate refs. * gcc.dg/tree-ssa/ssa-ccp-16.c: New testcase. Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c =================================================================== *** /dev/null 1970-01-01 00:00:00.000000000 +0000 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c 2008-03-15 16:46:24.000000000 +0100 *************** *** 0 **** --- 1,22 ---- + /* { dg-do compile } */ + /* { dg-options "-O -fdump-tree-ccp1" } */ + + static const int x; + + int test1 (void) + { + char *p = "hello"; + int i = x; + i = i + 5; + return p[i]; + } + + int test2 (void) + { + int i = x; + i = i + 5; + return "hello"[i]; + } + + /* { dg-final { scan-tree-dump-times "return 0;" 2 "ccp1" } } */ + /* { dg-final { cleanup-tree-dump "ccp1" } } */ Index: trunk/gcc/tree-ssa-ccp.c =================================================================== *** trunk.orig/gcc/tree-ssa-ccp.c 2008-03-15 15:35:15.000000000 +0100 --- trunk/gcc/tree-ssa-ccp.c 2008-03-15 16:39:52.000000000 +0100 *************** ccp_fold (tree stmt) *** 984,989 **** --- 984,995 ---- return fold_binary (code, TREE_TYPE (rhs), op0, op1); } + else if (kind == tcc_declaration) + return get_symbol_constant_value (rhs); + + else if (kind == tcc_reference) + return fold_const_aggregate_ref (rhs); + /* We may be able to fold away calls to builtin functions if their arguments are constants. */ else if (code == CALL_EXPR *************** fold_const_aggregate_ref (tree t) *** 1062,1067 **** --- 1068,1078 ---- ctor = fold_const_aggregate_ref (base); break; + case STRING_CST: + case CONSTRUCTOR: + ctor = base; + break; + default: return NULL_TREE; } *************** fold_const_aggregate_ref (tree t) *** 1162,1168 **** return fold_build1 (TREE_CODE (t), TREE_TYPE (t), c); break; } ! default: break; } --- 1173,1190 ---- return fold_build1 (TREE_CODE (t), TREE_TYPE (t), c); break; } ! ! case INDIRECT_REF: ! { ! tree base = TREE_OPERAND (t, 0); ! if (TREE_CODE (base) == SSA_NAME ! && (value = get_value (base)) ! && value->lattice_val == CONSTANT ! && TREE_CODE (value->value) == ADDR_EXPR) ! return fold_const_aggregate_ref (TREE_OPERAND (value->value, 0)); ! break; ! } ! default: break; } *************** evaluate_stmt (tree stmt) *** 1190,1204 **** simplified = ccp_fold (stmt); /* If the statement is likely to have a VARYING result, then do not bother folding the statement. */ ! if (likelyvalue == VARYING) simplified = get_rhs (stmt); - /* If the statement is an ARRAY_REF or COMPONENT_REF into constant - aggregates, extract the referenced constant. Otherwise the - statement is likely to have an UNDEFINED value, and there will be - nothing to do. Note that fold_const_aggregate_ref returns - NULL_TREE if the first case does not match. */ - else if (!simplified) - simplified = fold_const_aggregate_ref (get_rhs (stmt)); is_constant = simplified && is_gimple_min_invariant (simplified); --- 1212,1219 ---- simplified = ccp_fold (stmt); /* If the statement is likely to have a VARYING result, then do not bother folding the statement. */ ! else if (likelyvalue == VARYING) simplified = get_rhs (stmt); is_constant = simplified && is_gimple_min_invariant (simplified); *************** visit_assignment (tree stmt, tree *outpu *** 1265,1271 **** } else /* Evaluate the statement. */ ! val = evaluate_stmt (stmt); /* If the original LHS was a VIEW_CONVERT_EXPR, modify the constant value to be a VIEW_CONVERT_EXPR of the old constant value. --- 1280,1286 ---- } else /* Evaluate the statement. */ ! val = evaluate_stmt (stmt); /* If the original LHS was a VIEW_CONVERT_EXPR, modify the constant value to be a VIEW_CONVERT_EXPR of the old constant value.