From patchwork Sun Sep 5 02:12:16 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Froyd X-Patchwork-Id: 63818 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 60643B7126 for ; Sun, 5 Sep 2010 12:12:27 +1000 (EST) Received: (qmail 20657 invoked by alias); 5 Sep 2010 02:12:25 -0000 Received: (qmail 20648 invoked by uid 22791); 5 Sep 2010 02:12:23 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 05 Sep 2010 02:12:18 +0000 Received: (qmail 29233 invoked from network); 5 Sep 2010 02:12:17 -0000 Received: from unknown (HELO localhost) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 5 Sep 2010 02:12:17 -0000 Date: Sat, 4 Sep 2010 19:12:16 -0700 From: Nathan Froyd To: gcc-patches@gcc.gnu.org Subject: [PATCH, 4.4/4.5/4.6?] check for constant base addresses in is_gimple_invariant_address Message-ID: <20100905021216.GJ16898@codesourcery.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.17+20080114 (2008-01-14) X-IsSubscribed: yes 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 The functions in the following testcase (PPC-specific, but generalizable) do not compile to the same code: #define ASMSTR "stw%U0%X0 %1,%0" struct Foo { unsigned pad[10]; unsigned cs0_bnds; }; static inline void Out (unsigned *addr) { __asm__ __volatile__(ASMSTR : "=m" (*addr) : "r" (0x1f)); } void AsmFunction (void) { struct Foo *ddr = (struct Foo *)0xffe02000; Out (&ddr->cs0_bnds); Out (&ddr->pad[0]); } void AsmDirect (void) { struct Foo *ddr = (struct Foo *)0xffe02000; __asm__ __volatile__(ASMSTR : "=m" (ddr->cs0_bnds) : "r" (0x1f)); __asm__ __volatile__(ASMSTR : "=m" (ddr->pad[0]) : "r" (0x1f)); } The results are (cleaned up to remove #APP bits): AsmFunction: lis 9,0xffe0 li 0,31 ori 9,9,8232 stw 0,0(9) lis 9,0xffe0 ori 9,9,8192 stw 0,0(9) blr AsmDirect: lis 9,0xffe0 li 0,31 ori 9,9,8192 stw 0,40(9) li 0,28 stw 0,0(9) blr Notice that in AsmDirect, we've CSE'd the address of `ddr', and we haven't done so in AsmFunction. (We failed to move the lowpart of the address into the stores, but AFAICT that is a problem with the PPC backend and is not relevant here. Compiling the example above for MIPS demonstrates the same problem without the distraction of bad code.) We used to do this CSE'ing in 4.3. When faced with this code: D.2017_2 = &4292878336B->cs0_bnds; __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m" *D.2017_2 : "r" 31); in ccp, we'd propagate D.2017_2 into its use and wind up with identical trees between the two functions heading into expand. In 4.4 and 4.5, however, we don't, so we've never given an opportunity to CSE the address of `ddr'. This affects applications that are size-conscious; if you're doing several calls to 'Out' in the same function, your code size can increase quite a bit in 4.4 and 4.5. So far as I can tell, this is because is_gimple_invariant_address fails to consider that we might have an INTEGER_CST base address. The patch below fixes the testcase; with it applied, AsmFunction and AsmDirect compile to the same code. What I'm unsure of is: - Whether I should also check for decl_address_invariant_p, perhaps by: if (TREE_CODE (op) == INDIRECT_REF) op = TREE_OPERAND (op, 0); return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op); - Whether the same treatment should be applied to is_gimple_ip_invariant_address. My most recent powerpc compiler is somewhat old, but it is post-MEM_REF merge and it also does not do the desired propagation. It looks to me like the relevant case in handled in is_gimple_invariant_address, but something is not working; the result &4292878336B->FOO is marked VARYING. Anyway, the below patch is against 4.5 and I'm asking for approval to 4.4 and 4.5 and possibly mainline (with modifications, obviously) once I verify with an up-to-date compiler. Answers to the questions above would be helpful. -Nathan * gimple.c (is_gimple_invariant_address): Check for a constant operand of an INDIRECT_REF. Index: gcc/ChangeLog =================================================================== Index: gcc/gimple.c =================================================================== --- gcc/gimple.c (revision 163868) +++ gcc/gimple.c (working copy) @@ -2591,7 +2591,13 @@ is_gimple_invariant_address (const_tree op = strip_invariant_refs (TREE_OPERAND (t, 0)); - return op && (CONSTANT_CLASS_P (op) || decl_address_invariant_p (op)); + if (!op) + return false; + + if (TREE_CODE (op) == INDIRECT_REF) + return CONSTANT_CLASS_P (TREE_OPERAND (op, 0)); + + return (CONSTANT_CLASS_P (op) || decl_address_invariant_p (op)); } /* Return true if T is a gimple invariant address at IPA level