From patchwork Thu Jun 24 09:38:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 56773 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 80328B6EDF for ; Thu, 24 Jun 2010 19:38:25 +1000 (EST) Received: (qmail 9545 invoked by alias); 24 Jun 2010 09:38:24 -0000 Received: (qmail 9536 invoked by uid 22791); 24 Jun 2010 09:38:22 -0000 X-SWARE-Spam-Status: No, hits=-5.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor.suse.de (HELO mx1.suse.de) (195.135.220.2) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 24 Jun 2010 09:38:17 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id BD9DC93EE3 for ; Thu, 24 Jun 2010 11:38:14 +0200 (CEST) Date: Thu, 24 Jun 2010 11:38:14 +0200 (CEST) From: Richard Guenther To: gcc-patches@gcc.gnu.org Subject: [PATCH][mem-ref2] Delete dead code, some cleanups Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2010-06-24 Richard Guenther * tree-ssa-ccp.c (ccp_fold): Do not bother about volatile qualifiers of pointers. * tree.def (MEM_REF): Clarify. * gimple-fold.c (maybe_fold_stmt_indirect): Remove. (maybe_fold_reference): Remove INDIRECT_REF handling. Constrain folding back to non-MEM_REF properly. * gcc.dg/tree-ssa/ssa-ccp-25.c: Adjust. * gcc.dg/tree-ssa/ssa-ccp-26.c: Likewise. Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-25.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-25.c (revision 161081) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-25.c (working copy) *************** int foo(int i) *** 9,14 **** } /* { dg-final { scan-tree-dump "&a\\\[\[iD\]\\\." "ccp1" } } */ ! /* { dg-final { scan-tree-dump "= a\\\[\[iD\]\\\." "forwprop1" } } */ /* { dg-final { cleanup-tree-dump "ccp1" } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ --- 9,14 ---- } /* { dg-final { scan-tree-dump "&a\\\[\[iD\]\\\." "ccp1" } } */ ! /* { dg-final { scan-tree-dump "= .*&a\\\]\\\[\[iD\]\\\." "forwprop1" } } */ /* { dg-final { cleanup-tree-dump "ccp1" } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-26.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-26.c (revision 161081) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-26.c (working copy) *************** int foo(int i) *** 7,11 **** return (a + 1)[i]; } ! /* { dg-final { scan-tree-dump "= a\\\[D\\\." "forwprop1" } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ --- 7,11 ---- return (a + 1)[i]; } ! /* { dg-final { scan-tree-dump "=.*&a\\\]\\\[D\\\." "forwprop1" } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ Index: gcc/tree-ssa-ccp.c =================================================================== --- gcc/tree-ssa-ccp.c (revision 161081) +++ gcc/tree-ssa-ccp.c (working copy) @@ -984,16 +984,10 @@ ccp_fold (gimple stmt) allowed places. */ if (CONVERT_EXPR_CODE_P (subcode) && POINTER_TYPE_P (TREE_TYPE (lhs)) - && POINTER_TYPE_P (TREE_TYPE (op0)) - /* Do not allow differences in volatile qualification - as this might get us confused as to whether a - propagation destination statement is volatile - or not. See PR36988. */ - && (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (lhs))) - == TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (op0))))) + && POINTER_TYPE_P (TREE_TYPE (op0))) { tree tem; - /* Still try to generate a constant of correct type. */ + /* Try to re-construct array references on-the-fly. */ if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (op0)) && ((tem = maybe_fold_offset_to_address Index: gcc/tree.def =================================================================== --- gcc/tree.def (revision 161081) +++ gcc/tree.def (working copy) @@ -972,9 +972,10 @@ DEFTREECODE (TARGET_MEM_REF, "target_mem /* Memory addressing. Operands are a pointer and a tree constant integer byte offset of the pointer type that when dereferenced yields the - type of the base object the pointer points to and which is used for + type of the base object the pointer points into and which is used for TBAA purposes. - The type of the MEM_REF is the type of the value load from memory. + The type of the MEM_REF is the type the bytes at the memory location + are interpreted as. MEM_REF is equivalent to ((typeof(c))p)->x... where x... is a chain of component references offsetting p by c. */ DEFTREECODE (MEM_REF, "mem_ref", tcc_reference, 2) Index: gcc/gimple-fold.c =================================================================== --- gcc/gimple-fold.c (revision 161182) +++ gcc/gimple-fold.c (working copy) @@ -290,109 +290,6 @@ maybe_fold_offset_to_address (location_t return ret; } -/* A subroutine of fold_stmt. Attempt to simplify *(BASE+OFFSET). - Return the simplified expression, or NULL if nothing could be done. */ - -static tree -maybe_fold_stmt_indirect (tree expr, tree base, tree offset) -{ - tree t; - bool volatile_p = TREE_THIS_VOLATILE (expr); - location_t loc = EXPR_LOCATION (expr); - - /* We may well have constructed a double-nested PLUS_EXPR via multiple - substitutions. Fold that down to one. Remove NON_LVALUE_EXPRs that - are sometimes added. */ - base = fold (base); - STRIP_TYPE_NOPS (base); - TREE_OPERAND (expr, 0) = base; - - /* One possibility is that the address reduces to a string constant. */ - t = fold_read_from_constant_string (expr); - if (t) - return t; - - /* Add in any offset from a POINTER_PLUS_EXPR. */ - if (TREE_CODE (base) == POINTER_PLUS_EXPR) - { - tree offset2; - - offset2 = TREE_OPERAND (base, 1); - if (TREE_CODE (offset2) != INTEGER_CST) - return NULL_TREE; - base = TREE_OPERAND (base, 0); - - offset = fold_convert (sizetype, - int_const_binop (PLUS_EXPR, offset, offset2, 1)); - } - - if (TREE_CODE (base) == ADDR_EXPR) - { - tree base_addr = base; - - /* Strip the ADDR_EXPR. */ - base = TREE_OPERAND (base, 0); - - /* Fold away CONST_DECL to its value, if the type is scalar. */ - if (TREE_CODE (base) == CONST_DECL - && is_gimple_min_invariant (DECL_INITIAL (base))) - return DECL_INITIAL (base); - - /* If there is no offset involved simply return the folded base. */ - if (integer_zerop (offset)) - return base; - - /* Try folding *(&B+O) to B[X]. */ - t = maybe_fold_offset_to_reference (loc, base_addr, offset, - TREE_TYPE (expr)); - if (t) - { - /* Preserve volatileness of the original expression. - We can end up with a plain decl here which is shared - and we shouldn't mess with its flags. */ - if (!SSA_VAR_P (t)) - TREE_THIS_VOLATILE (t) = volatile_p; - return t; - } - } - else - { - /* We can get here for out-of-range string constant accesses, - such as "_"[3]. Bail out of the entire substitution search - and arrange for the entire statement to be replaced by a - call to __builtin_trap. In all likelihood this will all be - constant-folded away, but in the meantime we can't leave with - something that get_expr_operands can't understand. */ - - t = base; - STRIP_NOPS (t); - if (TREE_CODE (t) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST) - { - /* FIXME: Except that this causes problems elsewhere with dead - code not being deleted, and we die in the rtl expanders - because we failed to remove some ssa_name. In the meantime, - just return zero. */ - /* FIXME2: This condition should be signaled by - fold_read_from_constant_string directly, rather than - re-checking for it here. */ - return integer_zero_node; - } - - /* Try folding *(B+O) to (*B)[X]. Still an improvement. */ - if (POINTER_TYPE_P (TREE_TYPE (base))) - { - t = maybe_fold_offset_to_reference (loc, base, offset, - TREE_TYPE (expr)); - if (t) - return t; - } - } - - /* Otherwise we had an offset that we could not simplify. */ - return NULL_TREE; -} - /* A quaint feature extant in our address arithmetic is that there can be hidden type changes here. The type of the result need @@ -589,42 +486,22 @@ maybe_fold_reference (tree expr, bool is while (handled_component_p (*t)) t = &TREE_OPERAND (*t, 0); - if (TREE_CODE (*t) == INDIRECT_REF) - { - tree tem = maybe_fold_stmt_indirect (*t, TREE_OPERAND (*t, 0), - integer_zero_node); - /* Avoid folding *"abc" = 5 into 'a' = 5. */ - if (is_lhs && tem && CONSTANT_CLASS_P (tem)) - tem = NULL_TREE; - if (!tem - && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR) - /* If we had a good reason for propagating the address here, - make sure we end up with valid gimple. See PR34989. */ - tem = TREE_OPERAND (TREE_OPERAND (*t, 0), 0); - - if (tem) - { - *t = tem; - tem = maybe_fold_reference (expr, is_lhs); - if (tem) - return tem; - return expr; - } - } /* Fold back MEM_REFs to reference trees. */ - else if (TREE_CODE (*t) == MEM_REF - && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR - && integer_zerop (TREE_OPERAND (*t, 1)) - && (TREE_THIS_VOLATILE (*t) - == TREE_THIS_VOLATILE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))) - && (get_alias_set (*t) - == get_alias_set (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))) - /* We have to look out here to not drop a required conversion - from the rhs to the lhs if is_lhs, but we don't have the - rhs here to verify that. Thus require strict type - compatibility. */ - && types_compatible_p (TREE_TYPE (*t), - TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0)))) + if (TREE_CODE (*t) == MEM_REF + && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR + && integer_zerop (TREE_OPERAND (*t, 1)) + && (TREE_THIS_VOLATILE (*t) + == TREE_THIS_VOLATILE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))) + && !TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (*t, 1))) + && (TYPE_MAIN_VARIANT (TREE_TYPE (*t)) + == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (*t, 1))))) + /* We have to look out here to not drop a required conversion + from the rhs to the lhs if is_lhs, but we don't have the + rhs here to verify that. Thus require strict type + compatibility. */ + && types_compatible_p (TREE_TYPE (*t), + TREE_TYPE (TREE_OPERAND + (TREE_OPERAND (*t, 0), 0)))) { tree tem; *t = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);