From patchwork Mon Oct 3 04:32:09 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 117402 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 DE1DAB6F68 for ; Mon, 3 Oct 2011 15:32:28 +1100 (EST) Received: (qmail 32724 invoked by alias); 3 Oct 2011 04:32:26 -0000 Received: (qmail 32708 invoked by uid 22791); 3 Oct 2011 04:32:25 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 03 Oct 2011 04:32:11 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p934WAl1032473 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 3 Oct 2011 00:32:11 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p934WAKF004814 for ; Mon, 3 Oct 2011 00:32:10 -0400 Received: from [0.0.0.0] (ovpn-113-54.phx2.redhat.com [10.3.113.54]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p934W9Y4004991 for ; Mon, 3 Oct 2011 00:32:09 -0400 Message-ID: <4E893AC9.1020407@redhat.com> Date: Mon, 03 Oct 2011 00:32:09 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:6.0.2) Gecko/20110906 Thunderbird/6.0.2 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for variadic pack expansion memory use 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 Someone sent me a variadic templates testcase that was using an unreasonable amount of memory; -fmem-report showed that half of the garbage was from ARGUMENT_PACK_SELECT nodes. There's no reason why we should allocate a new node for each pack on each iteration of the expansion; we can just allocate them for the first node and then update the index as we go along. Tested x86_64-pc-linux-gnu, applying to trunk. commit 13dd4a100ef26121960b3fd1552c6c96c4309838 Author: Jason Merrill Date: Sun Oct 2 23:06:40 2011 -0400 * pt.c (tsubst_pack_expansion): Re-use ARGUMENT_PACK_SELECTs. Change unsubstituted_packs to bool. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 015ee37..051c89a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9102,7 +9102,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree pattern; - tree pack, packs = NULL_TREE, unsubstituted_packs = NULL_TREE; + tree pack, packs = NULL_TREE; + bool unsubstituted_packs = false; int i, len = -1; tree result; htab_t saved_local_specializations = NULL; @@ -9203,10 +9204,11 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, TREE_TYPE (packs) = orig_arg; } else - /* We can't substitute for this parameter pack. */ - unsubstituted_packs = tree_cons (TREE_PURPOSE (pack), - TREE_VALUE (pack), - unsubstituted_packs); + { + /* We can't substitute for this parameter pack. */ + unsubstituted_packs = true; + break; + } } /* We cannot expand this expansion expression, because we don't have @@ -9252,33 +9254,38 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, for (pack = packs; pack; pack = TREE_CHAIN (pack)) { tree parm = TREE_PURPOSE (pack); + tree arg; + /* Select the Ith argument from the pack. */ if (TREE_CODE (parm) == PARM_DECL) { - /* Select the Ith argument from the pack. */ - tree arg = make_node (ARGUMENT_PACK_SELECT); - ARGUMENT_PACK_SELECT_FROM_PACK (arg) = TREE_VALUE (pack); - ARGUMENT_PACK_SELECT_INDEX (arg) = i; - mark_used (parm); - register_local_specialization (arg, parm); + if (i == 0) + { + arg = make_node (ARGUMENT_PACK_SELECT); + ARGUMENT_PACK_SELECT_FROM_PACK (arg) = TREE_VALUE (pack); + mark_used (parm); + register_local_specialization (arg, parm); + } + else + arg = retrieve_local_specialization (parm); } else { - tree value = parm; int idx, level; template_parm_level_and_index (parm, &level, &idx); - - if (i < len) + + if (i == 0) { - /* Select the Ith argument from the pack. */ - value = make_node (ARGUMENT_PACK_SELECT); - ARGUMENT_PACK_SELECT_FROM_PACK (value) = TREE_VALUE (pack); - ARGUMENT_PACK_SELECT_INDEX (value) = i; + arg = make_node (ARGUMENT_PACK_SELECT); + ARGUMENT_PACK_SELECT_FROM_PACK (arg) = TREE_VALUE (pack); + /* Update the corresponding argument. */ + TMPL_ARG (args, level, idx) = arg; } - - /* Update the corresponding argument. */ - TMPL_ARG (args, level, idx) = value; + else + /* Re-use the ARGUMENT_PACK_SELECT. */ + arg = TMPL_ARG (args, level, idx); } + ARGUMENT_PACK_SELECT_INDEX (arg) = i; } /* Substitute into the PATTERN with the altered arguments. */