From patchwork Tue Aug 31 21:08:38 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 63318 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 4A70FB7109 for ; Wed, 1 Sep 2010 07:08:49 +1000 (EST) Received: (qmail 22868 invoked by alias); 31 Aug 2010 21:08:47 -0000 Received: (qmail 22855 invoked by uid 22791); 31 Aug 2010 21:08:45 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (212.99.106.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 31 Aug 2010 21:08:40 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 6E49DCB0291 for ; Tue, 31 Aug 2010 23:08:38 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HRW0jvwzm77A for ; Tue, 31 Aug 2010 23:08:38 +0200 (CEST) Received: from new-host-2.home (ADijon-552-1-118-151.w92-148.abo.wanadoo.fr [92.148.61.151]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id 42665CB023F for ; Tue, 31 Aug 2010 23:08:38 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: Fix wrong code with complex nested functions tree User-Agent: KMail/1.9.9 MIME-Version: 1.0 Date: Tue, 31 Aug 2010 23:08:38 +0200 Message-Id: <201008312308.38661.ebotcazou@adacore.com> 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 new iterative algorithm that computes the need for static chains in nested functions trees has a flaw: it only detects changes of static chain setting in the function it has just processed. So if a child function is nested in its parent and already requires a static chain, the parent is nested in the root function and doesn't, and the child function calls a sibling of its parent that does, the parent won't get the static chain it eventually needs because the setting is toggled from within the child function. Fixed by computing the sum of the static chains in each nest and iterating until after it doesn't change. Tested on x86-64-suse-linux, applied on the mainline and 4.5 branch as obvious. 2010-08-31 Eric Botcazou * tree-nested.c (convert_all_function_calls): Iterate until after the sum of static chains in the nest doesn't change. 2010-08-31 Eric Botcazou * gcc.dg/nested-func-8.c: New test. Index: tree-nested.c =================================================================== --- tree-nested.c (revision 163659) +++ tree-nested.c (working copy) @@ -2070,9 +2070,8 @@ convert_gimple_call (gimple_stmt_iterato static void convert_all_function_calls (struct nesting_info *root) { + unsigned int chain_count = 0, old_chain_count, iter_count; struct nesting_info *n; - int iter_count; - bool any_changed; /* First, optimistically clear static_chain for all decls that haven't used the static chain already for variable access. */ @@ -2088,6 +2087,7 @@ convert_all_function_calls (struct nesti } else DECL_STATIC_CHAIN (decl) = 1; + chain_count += DECL_STATIC_CHAIN (decl); } /* Walk the functions and perform transformations. Note that these @@ -2100,7 +2100,8 @@ convert_all_function_calls (struct nesti iter_count = 0; do { - any_changed = false; + old_chain_count = chain_count; + chain_count = 0; iter_count++; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2109,22 +2110,16 @@ convert_all_function_calls (struct nesti FOR_EACH_NEST_INFO (n, root) { tree decl = n->context; - bool old_static_chain = DECL_STATIC_CHAIN (decl); - walk_function (convert_tramp_reference_stmt, convert_tramp_reference_op, n); walk_function (convert_gimple_call, NULL, n); - - /* If a call to another function created the use of a chain - within this function, we'll have to continue iteration. */ - if (!old_static_chain && DECL_STATIC_CHAIN (decl)) - any_changed = true; + chain_count += DECL_STATIC_CHAIN (decl); } } - while (any_changed); + while (chain_count != old_chain_count); if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "convert_all_function_calls iterations: %d\n\n", + fprintf (dump_file, "convert_all_function_calls iterations: %u\n\n", iter_count); }