From patchwork Sun May 27 00:39:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Matz X-Patchwork-Id: 161513 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 ED88FB6F9F for ; Sun, 27 May 2012 10:39:49 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1338683990; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Subject:Message-ID:MIME-Version:Content-Type: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=Zw3k4E3Eg+L00iQhEXH3 Hjc9kaw=; b=OTj0M9zuz6yeJEEf/Dbp/C6khu2Zvakb+y9rgYHOxjtLasVaiz6O ZvnmCXV+qDhVd/d2yVR6CiubIU/B1D5s9ywiIlPX1ypeStCe1UCD6yc6K7gNbmfW /3XSS0orLArNF8gpNeNEQ7BtPBWTD+BsUaM6QJaHUdq2jOENE4PPlwQ= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Date:From:To:Subject:Message-ID:MIME-Version:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=pirgK1zOBYemUZk2cIZf1vVugPXtoZpgO2JGtqHe0nkvVx6y9TUtuXUKermqy5 k8vOX3Y2JCaV79luM5H5SvvCizhm4O0Jaykk66ttW8E6D/epWHT3kexZ73zlNISw O/MBw609swgTWqlL4jG+G0VVlbW73uMdvl8c+0j0qNIqI=; Received: (qmail 26986 invoked by alias); 27 May 2012 00:39:44 -0000 Received: (qmail 26976 invoked by uid 22791); 27 May 2012 00:39:42 -0000 X-SWARE-Spam-Status: No, hits=-5.2 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 27 May 2012 00:39:22 +0000 Received: from relay1.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id D05309604E for ; Sun, 27 May 2012 02:39:20 +0200 (CEST) Date: Sun, 27 May 2012 02:39:20 +0200 (CEST) From: Michael Matz To: gcc-patches@gcc.gnu.org Subject: RFA: temp slot TLC [1/3] Message-ID: MIME-Version: 1.0 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 Hi, I still had some cleanups for age-old code lying around, and thought to bring it up to date. The whole dealing of slots for temporary stack space in function.c was never really updated to the way we're meanwhile expanding statements. It has facilities that aren't useful anymore. In the old days it worked like this: after a statement was expanded temporary slots that were allocated during that expansion would be freed. The problem was that statements could be arbitrarily complex, including calls as call arguments or statement expressions. So there had to be a way that some of these slots could be marked as to be kept until the next scope would be popped (the 'keep' flag to assign_temp), or at least that the slot might be used in the containing expression even after a free_temp_slots (the addr_taken flag for a slot). Meanwhile the situation is like so: 1) There are only three places that still allocate a 'kept' slot (i.e. keep==1 in a call to assign_temp, assign_stack_temp and assign_stack_temp_for_type): a) expand_expr_real_1, when expanding a reference from a constant object, which must be in memory but isn't; this is meanwhile useless, the so allocated temporary will not be freed until the full statement is done, at which point the expanded reference will either be consumed into the real objects, or will be ignored; it's not necessary to artificially mark it kept b) expand_asm_operands, for handling mem inputs on non-lvalues; this is dead code, we rewrite all such asms at gimple level already. c) in expand_decl; this routine I'm going to remove (with removal of the reference from Ada it's all dead code) 2) The single place that still sometimes marks temp slots as addr_taken is in expand_call. It does so when the callee returns an aggregate and no target is given (or no return slot optimization should happen). The temp slot will not go away until the next free_temp_slots at which point it must already be copied out into the real LHS of the (gimple) call statement or it'll be ignored, so marking it to be kept isn't necessary. expand_decl is dead code because it only does things for CONST_DECLs (for Ada, but I'm removing that use) and automatic vars. But automatic vars are (supposed to be) allocated since quite some time in cfgexpand. One call to expand_decl that still did something is for expansion of COMPOUND_LITERAL_EXPR, which we can have only in global ctors (usual problem of not gimplifying those). That's easy to deal with, though, as in the patch. The other expand_decl call that does something is for generating RTL for the nonlocal_goto_save_area in case it doesn't have RTL yet. The latter shouldn't (and after the patch doesn't) happen: the underlying variable is supposed to be in local_decls and hence should have gotten RTL during cfgexpand. This is only not true when it was unused, removed from local_decls, but the reference from cfun remains. In that case we'd expand (unused) stack space. Instead I simply remove the reference from cfun when the variable is removed. As the data flow regarding temporaries in the old RTL code is a bit complicated I reassured myself regarding the above points with various gcc_unreachable and commenting code. That is this first patch. The second and third patch contain the more or less obvious cleanup followups. I'm asking for approval for all three patches, but I have bootstrapped the first separately, so if approved I'm going to commit them as separate revisions so that in case I got something wrong with this touchy area it's easy to play with adjusting just parts of the patch, without always having to redo all the cleanup adjustments. So, regstrapped on x86_64-linux all languages (+Ada,+obj-c++), this patch alone and in connection with [2/3] and [3/3]. Okay for trunk (I have approval for the Ada part already). Ciao, Michael. ----------------------- * expr.c (expand_expr_real_1 ): Don't allocate a kept temp. (expand_expr_real_1 ): Make unreachable. * gimple-fold.c (canonicalize_constructor_val): Canonicalize COMPOUND_LITERAL_EXPR. * function.c (expand_function_start): Don't call expand_decl, instead assert that we have RTL assigned. * tree-ssa-live.c (remove_unused_locals): Clear nonlocal_goto_save_area if its backing variable is removed. * stmt.c (expand_asm_operands): Remove handling of non-lvalues as mem inputs. (expand_decl): Assert that this does nothing. * calls.c (expand_call): Don't call mark_temp_addr_taken. * c-tree.h (c_expand_decl): Remove prototype. c-family/ * c-common.h (c_expand_decl): Remove prototype. ada/ * gcc-interface/utils.c (create_var_decl_1): Don't call expand_decl. Index: expr.c =================================================================== --- expr.c.orig 2012-05-25 17:03:54.000000000 +0200 +++ expr.c 2012-05-26 16:37:09.000000000 +0200 @@ -9922,7 +9922,7 @@ expand_expr_real_1 (tree exp, rtx target tree nt = build_qualified_type (TREE_TYPE (tem), (TYPE_QUALS (TREE_TYPE (tem)) | TYPE_QUAL_CONST)); - memloc = assign_temp (nt, 1, 1, 1); + memloc = assign_temp (nt, 0, 1, 1); emit_move_insn (memloc, op0); op0 = memloc; mem_attrs_from_type = true; @@ -10425,6 +10425,7 @@ expand_expr_real_1 (tree exp, rtx target case POSTDECREMENT_EXPR: case LOOP_EXPR: case EXIT_EXPR: + case COMPOUND_LITERAL_EXPR: /* Lowered by gimplify.c. */ gcc_unreachable (); @@ -10439,7 +10440,7 @@ expand_expr_real_1 (tree exp, rtx target return expand_expr_real (treeop0, original_target, tmode, modifier, alt_rtl); - case COMPOUND_LITERAL_EXPR: +#if 0 { /* Initialize the anonymous variable declared in the compound literal, then return the variable. */ @@ -10459,6 +10460,7 @@ expand_expr_real_1 (tree exp, rtx target return expand_expr_real (decl, original_target, tmode, modifier, alt_rtl); } +#endif default: return expand_expr_real_2 (&ops, target, tmode, modifier); Index: function.c =================================================================== --- function.c.orig 2012-05-25 17:03:13.000000000 +0200 +++ function.c 2012-05-26 16:37:08.000000000 +0200 @@ -4788,11 +4788,8 @@ expand_function_start (tree subr) tree t_save; rtx r_save; - /* ??? We need to do this save early. Unfortunately here is - before the frame variable gets declared. Help out... */ tree var = TREE_OPERAND (cfun->nonlocal_goto_save_area, 0); - if (!DECL_RTL_SET_P (var)) - expand_decl (var); + gcc_assert (DECL_RTL_SET_P (var)); t_save = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (cfun->nonlocal_goto_save_area)), Index: gimple-fold.c =================================================================== --- gimple-fold.c.orig 2012-05-25 17:03:54.000000000 +0200 +++ gimple-fold.c 2012-05-25 17:20:54.000000000 +0200 @@ -154,6 +154,12 @@ canonicalize_constructor_val (tree cval, if (TREE_CODE (cval) == ADDR_EXPR) { tree base = get_base_address (TREE_OPERAND (cval, 0)); + if (!base && TREE_CODE (TREE_OPERAND (cval, 0)) == COMPOUND_LITERAL_EXPR) + { + base = COMPOUND_LITERAL_EXPR_DECL (TREE_OPERAND (cval, 0)); + if (base) + TREE_OPERAND (cval, 0) = base; + } if (!base) return NULL_TREE; Index: tree-ssa-live.c =================================================================== --- tree-ssa-live.c.orig 2012-05-25 17:03:54.000000000 +0200 +++ tree-ssa-live.c 2012-05-26 18:24:14.000000000 +0200 @@ -835,6 +835,9 @@ remove_unused_locals (void) { if (var_ann (var)) remove_referenced_var (var); + if (cfun->nonlocal_goto_save_area + && TREE_OPERAND (cfun->nonlocal_goto_save_area, 0) == var) + cfun->nonlocal_goto_save_area = NULL; continue; } } Index: stmt.c =================================================================== --- stmt.c.orig 2012-05-25 17:03:13.000000000 +0200 +++ stmt.c 2012-05-26 16:37:09.000000000 +0200 @@ -910,6 +910,8 @@ expand_asm_operands (tree string, tree o at this point. Ignore it: clearly this *is* a memory. */ } else + gcc_unreachable (); +#if 0 { warning (0, "use of memory input without lvalue in " "asm operand %d is deprecated", i + noutputs); @@ -935,6 +937,7 @@ expand_asm_operands (tree string, tree o op = memloc; } } +#endif } generating_concat_p = old_generating_concat_p; @@ -1703,6 +1706,7 @@ expand_decl (tree decl) type in case this node is used in a reference. */ if (TREE_CODE (decl) == CONST_DECL) { + gcc_unreachable (); DECL_MODE (decl) = TYPE_MODE (type); DECL_ALIGN (decl) = TYPE_ALIGN (type); DECL_SIZE (decl) = TYPE_SIZE (type); @@ -1720,6 +1724,7 @@ expand_decl (tree decl) if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) return; + gcc_unreachable (); /* Create the RTL representation for the variable. */ if (type == error_mark_node) Index: c-family/c-common.h =================================================================== --- c-family/c-common.h.orig 2012-05-25 17:03:13.000000000 +0200 +++ c-family/c-common.h 2012-05-25 17:20:54.000000000 +0200 @@ -544,8 +544,6 @@ extern tree build_modify_expr (location_ location_t, tree, tree); extern tree build_indirect_ref (location_t, tree, ref_operator); -extern int c_expand_decl (tree); - extern int field_decl_cmp (const void *, const void *); extern void resort_sorted_fields (void *, void *, gt_pointer_operator, void *); Index: c-tree.h =================================================================== --- c-tree.h.orig 2012-05-25 17:03:13.000000000 +0200 +++ c-tree.h 2012-05-25 17:20:54.000000000 +0200 @@ -535,7 +535,6 @@ extern void store_parm_decls (void); extern void store_parm_decls_from (struct c_arg_info *); extern tree xref_tag (enum tree_code, tree); extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree); -extern int c_expand_decl (tree); extern struct c_parm *build_c_parm (struct c_declspecs *, tree, struct c_declarator *); extern struct c_declarator *build_attrs_declarator (tree, Index: calls.c =================================================================== --- calls.c.orig 2012-05-25 17:03:13.000000000 +0200 +++ calls.c 2012-05-26 16:37:09.000000000 +0200 @@ -2405,8 +2405,6 @@ expand_call (tree exp, rtx target, int i specified. If we were to allocate space on the stack here, we would have no way of knowing when to free it. */ rtx d = assign_temp (rettype, 0, 1, 1); - - mark_temp_addr_taken (d); structure_value_addr = XEXP (d, 0); target = 0; } Index: ada/gcc-interface/utils.c =================================================================== --- ada/gcc-interface/utils.c.orig 2012-05-25 17:03:13.000000000 +0200 +++ ada/gcc-interface/utils.c 2012-05-25 17:20:54.000000000 +0200 @@ -2227,8 +2227,6 @@ create_var_decl_1 (tree var_name, tree a if (global_bindings_p ()) rest_of_decl_compilation (var_decl, true, 0); } - else - expand_decl (var_decl); return var_decl; }