From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11772 invoked by alias); 13 May 2003 19:35:24 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 11675 invoked from network); 13 May 2003 19:35:23 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sources.redhat.com with SMTP; 13 May 2003 19:35:23 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h4DJZNH20889; Tue, 13 May 2003 15:35:23 -0400 Received: from speedy.slc.redhat.com (vpn50-12.rdu.redhat.com [172.16.50.12]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h4DJZKI16590; Tue, 13 May 2003 15:35:20 -0400 Received: from redhat.com (law@localhost) by speedy.slc.redhat.com (8.12.8/8.12.8/Submit) with ESMTP id h4DJZ5kI013484; Tue, 13 May 2003 13:35:06 -0600 Message-Id: <200305131935.h4DJZ5kI013484@speedy.slc.redhat.com> X-Authentication-Warning: speedy.slc.redhat.com: law owned process doing -bs To: gcc-patches@gcc.gnu.org cc: Diego Novillo cc: Zack Weinberg , Michael Matz , "gcc@gcc.gnu.org" Reply-To: law@redhat.com Subject: [tree-ssa] Improve eliminate_useless_stmts_and_vars [Was Re: Dead-code elimination can't remove string copy insns? ] In-Reply-To: Your message of "Tue, 13 May 2003 13:07:22 EDT." <20030513170722.GA7112@tornado.toronto.redhat.com> From: law@redhat.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Tue, 13 May 2003 19:35:00 -0000 X-SW-Source: 2003-05/txt/msg01347.txt.bz2 In message <20030513170722.GA7112@tornado.toronto.redhat.com>, Diego Novillo wr ites: >On Tue, May 13, 2003 at 09:40:33AM -0700, Zack Weinberg wrote: > >> gcc.dg/const-elim-1.c. On an x86, compile it with -march=i386 -O2; >> rs6000-ibm-aix5 and arm-elf also show the problem. >> >Yup, tree-ssa handles it. The original program in GIMPLE form is >on the left. The optimized version is on the right (we still >don't linearize GOTO_EXPRs). Here's the patch to allow us to eliminate the unnecessary GOTOs in const-elim-1.c. * tree-cfg.c (cleanup_tree_cfg): Update comments. Set repeat anytime we remove a control structure. Index: tree-cfg.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v retrieving revision 1.1.4.88 diff -c -3 -p -r1.1.4.88 tree-cfg.c *** tree-cfg.c 13 May 2003 02:16:38 -0000 1.1.4.88 --- tree-cfg.c 13 May 2003 18:36:20 -0000 *************** cleanup_tree_cfg () *** 1382,1395 **** * Empty statement nodes are removed * Some unnecessary BIND_EXPRs are removed Clearly more work could be done. The trick is doing the analysis and removal fast enough to be a net improvement in compile times. Note that when we remove a control structure such as a COND_EXPR ! or BIND_EXPR, we will need to repeat this optimization pass to ! ensure we eliminate all the useless code. */ int remove_useless_stmts_and_vars (first_p) --- 1382,1399 ---- * Empty statement nodes are removed + * Unnecessary TRY_FINALLY and TRY_CATCH blocks are removed + + * Unnecessary COND_EXPRs are removed + * Some unnecessary BIND_EXPRs are removed Clearly more work could be done. The trick is doing the analysis and removal fast enough to be a net improvement in compile times. Note that when we remove a control structure such as a COND_EXPR ! BIND_EXPR, or TRY block, we will need to repeat this optimization pass ! to ensure we eliminate all the useless code. */ int remove_useless_stmts_and_vars (first_p) *************** remove_useless_stmts_and_vars (first_p) *** 1436,1451 **** label in one arm. If the label has since become unreachable then we may be able to zap the entire conditional here. ! If this causes us to replace the COND_EXPR with an ! empty statement, then we will need to repeat this pass. */ if (integer_nonzerop (cond) && IS_EMPTY_STMT (else_clause)) ! *stmt_p = then_clause; if (integer_zerop (cond) && IS_EMPTY_STMT (then_clause)) ! *stmt_p = else_clause; ! ! /* This can happen if both arms were ultimately empty. */ ! if (IS_EMPTY_STMT (*stmt_p)) ! repeat = 1; } else if (code == SWITCH_EXPR) repeat |= remove_useless_stmts_and_vars (&SWITCH_BODY (*stmt_p)); --- 1440,1457 ---- label in one arm. If the label has since become unreachable then we may be able to zap the entire conditional here. ! If so, replace the COND_EXPR and set up to repeat this ! optimization pass. */ if (integer_nonzerop (cond) && IS_EMPTY_STMT (else_clause)) ! { ! *stmt_p = then_clause; ! repeat = 1; ! } if (integer_zerop (cond) && IS_EMPTY_STMT (then_clause)) ! { ! *stmt_p = else_clause; ! repeat = 1; ! } } else if (code == SWITCH_EXPR) repeat |= remove_useless_stmts_and_vars (&SWITCH_BODY (*stmt_p)); *************** remove_useless_stmts_and_vars (first_p) *** 1463,1479 **** If the body of a TRY_CATCH is empty and the handler is empty (it had no reachable code either), then we can ! emit an empty statement without the enclosing TRY_CATCH. */ if (IS_EMPTY_STMT (TREE_OPERAND (*stmt_p, 0))) { if (code == TRY_FINALLY_EXPR || IS_EMPTY_STMT (TREE_OPERAND (*stmt_p, 1))) ! *stmt_p = TREE_OPERAND (*stmt_p, 1); ! ! /* If we replaced this statement with an empty statement, ! then we'll need to repeat this optimization. */ ! if (IS_EMPTY_STMT (*stmt_p)) ! repeat = 1; } } else if (code == BIND_EXPR) --- 1469,1486 ---- If the body of a TRY_CATCH is empty and the handler is empty (it had no reachable code either), then we can ! emit an empty statement without the enclosing TRY_CATCH. ! ! In both cases we want to apply this optimization pass ! again. */ if (IS_EMPTY_STMT (TREE_OPERAND (*stmt_p, 0))) { if (code == TRY_FINALLY_EXPR || IS_EMPTY_STMT (TREE_OPERAND (*stmt_p, 1))) ! { ! *stmt_p = TREE_OPERAND (*stmt_p, 1); ! repeat = 1; ! } } } else if (code == BIND_EXPR) *************** remove_useless_stmts_and_vars (first_p) *** 1485,1491 **** /* If the BIND_EXPR has no variables, then we can pull everything up one level and remove the BIND_EXPR, unless this is the toplevel BIND_EXPR for the current function or an inlined ! function. */ block = BIND_EXPR_BLOCK (*stmt_p); if (BIND_EXPR_VARS (*stmt_p) == NULL_TREE && *stmt_p != DECL_SAVED_TREE (current_function_decl) --- 1492,1501 ---- /* If the BIND_EXPR has no variables, then we can pull everything up one level and remove the BIND_EXPR, unless this is the toplevel BIND_EXPR for the current function or an inlined ! function. ! ! When this situation occurs we will want to apply this ! optimization again. */ block = BIND_EXPR_BLOCK (*stmt_p); if (BIND_EXPR_VARS (*stmt_p) == NULL_TREE && *stmt_p != DECL_SAVED_TREE (current_function_decl) *************** remove_useless_stmts_and_vars (first_p) *** 1493,1505 **** || ! BLOCK_ABSTRACT_ORIGIN (block) || (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) != FUNCTION_DECL))) ! *stmt_p = BIND_EXPR_BODY (*stmt_p); ! ! /* If we removed the BIND_EXPR completely and were left with ! an empty statement, then we'll need to repeat this ! optimization. */ ! if (IS_EMPTY_STMT (*stmt_p)) ! repeat = 1; } else if (code == GOTO_EXPR) { --- 1503,1512 ---- || ! BLOCK_ABSTRACT_ORIGIN (block) || (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) != FUNCTION_DECL))) ! { ! *stmt_p = BIND_EXPR_BODY (*stmt_p); ! repeat = 1; ! } } else if (code == GOTO_EXPR) {