From patchwork Thu Nov 18 14:18:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 72096 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 3AE5BB71A7 for ; Fri, 19 Nov 2010 01:18:55 +1100 (EST) Received: (qmail 25527 invoked by alias); 18 Nov 2010 14:18:52 -0000 Received: (qmail 25515 invoked by uid 22791); 18 Nov 2010 14:18:52 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_CP, T_RP_MATCHES_RCVD 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; Thu, 18 Nov 2010 14:18:43 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oAIEIfkx010749 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 18 Nov 2010 09:18:41 -0500 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id oAIEIet8004967 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 18 Nov 2010 09:18:41 -0500 Received: from tyan-ft48-01.lab.bos.redhat.com (localhost.localdomain [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id oAIEIe1c029567; Thu, 18 Nov 2010 15:18:40 +0100 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id oAIEIehl029565; Thu, 18 Nov 2010 15:18:40 +0100 Date: Thu, 18 Nov 2010 15:18:40 +0100 From: Jakub Jelinek To: Richard Guenther Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Fix ICE on printf optimization with very large format string (PR middle-end/46534) Message-ID: <20101118141839.GX29412@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek References: <20101118110655.GV29412@tyan-ft48-01.lab.bos.redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) 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 On Thu, Nov 18, 2010 at 01:09:25PM +0100, Richard Guenther wrote: > On Thu, Nov 18, 2010 at 12:06 PM, Jakub Jelinek wrote: > > Hi! > > > > For the printf ("...\n") -> puts ("...") optimization we use alloca > > to copy the string and change it before passing it to build_string_literal. > > This doesn't work very well if the string is so long that we hit > > RLIMIT_STACK. > > > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for > > trunk? > > As stated in the PR we can avoid the copying completely if by > adjusting tree.c:build_string to do this modification itself. No need > to copy things twice. So something like this? Duplicating both build_string and build_string_literal for this special case would be ugly. 2010-11-18 Jakub Jelinek PR middle-end/46534 * builtins.c (fold_builtin_printf): Don't copy and modify string before build_string_literal, instead modify what build_string_literal returned. * gcc.c-torture/compile/pr46534.c: New test. Jakub --- gcc/builtins.c.jj 2010-11-18 10:00:20.040373470 +0100 +++ gcc/builtins.c 2010-11-18 14:48:06.826405229 +0100 @@ -12892,15 +12892,28 @@ fold_builtin_printf (location_t loc, tre { /* If the string was "string\n", call puts("string"). */ size_t len = strlen (str); - if ((unsigned char)str[len - 1] == target_newline) + if ((unsigned char)str[len - 1] == target_newline + && (size_t) (int) len == len + && (int) len > 0) { + char *newstr; + tree offset_node, string_cst; + /* Create a NUL-terminated string that's one char shorter than the original, stripping off the trailing '\n'. */ - char *newstr = XALLOCAVEC (char, len); - memcpy (newstr, str, len - 1); - newstr[len - 1] = 0; - - newarg = build_string_literal (len, newstr); + newarg = build_string_literal (len, str); + string_cst = string_constant (newarg, &offset_node); + gcc_checking_assert (string_cst + && (TREE_STRING_LENGTH (string_cst) + == (int) len) + && integer_zerop (offset_node) + && (unsigned char) + TREE_STRING_POINTER (string_cst)[len - 1] + == target_newline); + /* build_string_literal creates a new STRING_CST, + modify it in place to avoid double copying. */ + newstr = CONST_CAST (char *, TREE_STRING_POINTER (string_cst)); + newstr[len - 1] = '\0'; if (fn_puts) call = build_call_expr_loc (loc, fn_puts, 1, newarg); } --- gcc/testsuite/gcc.c-torture/compile/pr46534.c.jj 2010-11-18 10:07:00.695450656 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr46534.c 2010-11-18 10:07:00.695450656 +0100 @@ -0,0 +1,17 @@ +/* PR middle-end/46534 */ + +extern int printf (const char *, ...); + +#define S1 " " +#define S2 S1 S1 S1 S1 S1 S1 S1 S1 S1 S1 +#define S3 S2 S2 S2 S2 S2 S2 S2 S2 S2 S2 +#define S4 S3 S3 S3 S3 S3 S3 S3 S3 S3 S3 +#define S5 S4 S4 S4 S4 S4 S4 S4 S4 S4 S4 +#define S6 S5 S5 S5 S5 S5 S5 S5 S5 S5 S5 +#define S7 S6 S6 S6 S6 S6 S6 S6 S6 S6 S6 + +void +foo (void) +{ + printf (S7 "\n"); +}