From patchwork Fri Nov 26 23:42:36 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 73249 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 1CC8EB70EC for ; Sat, 27 Nov 2010 10:44:14 +1100 (EST) Received: (qmail 28099 invoked by alias); 26 Nov 2010 23:44:11 -0000 Received: (qmail 28081 invoked by uid 22791); 26 Nov 2010 23:44:09 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 26 Nov 2010 23:44:03 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id E22DDCB0237 for ; Sat, 27 Nov 2010 00:44:00 +0100 (CET) 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 Cutl30VhfPbJ for ; Sat, 27 Nov 2010 00:44:00 +0100 (CET) Received: from [192.168.1.2] (bon31-9-83-155-120-49.fbx.proxad.net [83.155.120.49]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id 20AE8CB0236 for ; Sat, 27 Nov 2010 00:43:59 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Enable Ada bootstrap with LTO Date: Sat, 27 Nov 2010 00:42:36 +0100 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Message-Id: <201011270042.36210.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 Hi, this finally enables Ada bootstrap with LTO. It successfully completed with only the gnatvsn.adb patchlet until yesterday but, after resyncing the tree this morning, it started crashing during stage #2 LTRANS for gnat1. The failure mode is as follows: during the LGEN phase, a VAR_DECL with VLA type is gimplified, i.e. replaced with a pointer VAR_DECL in the code, and DECL_VALUE_EXPR for it is set to the dereference of the pointer. Then this pointer VAR_DECL is put into the FRAME structure by the nested functions lowering pass and the reference to it present in the above DECL_VALUE_EXPR is replaced with a debug variable, which itself has DECL_VALUE_EXPR pointing to the rewritten access. During the LTRANS phase, the VAR_DECL is correctly read in with DECL_VALUE_EXPR pointing to the dereference of the debug pointer variable. Then lto_materialize_function triggers a GC for an unrelated function which sweeps the debug pointer variable and, consequently, removes its slot from the DECL_VALUE_EXPR table. So the original VAR_DECL has its DECL_VALUE_EXPR pointing to the dereference of a dangling debug variable with DECL_HAS_VALUE_EXPR_P set but no entry in the DECL_VALUE_EXPR table and this crashes during debug info generation. The patch addresses this issue in the nested functions lowering pass by replacing references to VAR_DECLs put into the FRAME structure present in DECL_VALUE_EXPRs by the rewritten access, instead of the debug variable. Bootstrapped/regtested on x86_64-suse-linux, OK for the mainline? 2010-11-26 Eric Botcazou * bootstrap-lto.mk (BOOT_ADAFLAGS): Delete. 2010-11-26 Eric Botcazou * tree-nested.c (remap_vla_decls): Fully expand value expressions of VLA variables. 2010-11-26 Eric Botcazou * gnatvsn.adb (Version_String): Change type to C-like array of chars. (Gnat_Version_String): Adjust to above change. Index: gcc/ada/gnatvsn.adb =================================================================== --- gcc/ada/gnatvsn.adb (revision 167175) +++ gcc/ada/gnatvsn.adb (working copy) @@ -53,9 +53,10 @@ package body Gnatvsn is " FOR A PARTICULAR PURPOSE."; end Gnat_Free_Software; - Version_String : String (1 .. Ver_Len_Max); + type char_array is array (Natural range <>) of aliased Character; + Version_String : char_array (0 .. Ver_Len_Max - 1); -- Import the C string defined in the (language-independent) source file - -- version.c. + -- version.c using the zero-based convention of the C language. -- The size is not the real one, which does not matter since we will -- check for the nul character in Gnat_Version_String. pragma Import (C, Version_String, "version_string"); @@ -65,15 +66,17 @@ package body Gnatvsn is ------------------------- function Gnat_Version_String return String is - NUL_Pos : Positive := 1; + S : String (1 .. Ver_Len_Max); + Pos : Natural := 0; begin loop - exit when Version_String (NUL_Pos) = ASCII.NUL; + exit when Version_String (Pos) = ASCII.NUL; - NUL_Pos := NUL_Pos + 1; + S (Pos + 1) := Version_String (Pos); + Pos := Pos + 1; end loop; - return Version_String (1 .. NUL_Pos - 1); + return S (1 .. Pos); end Gnat_Version_String; end Gnatvsn; Index: gcc/tree-nested.c =================================================================== --- gcc/tree-nested.c (revision 167175) +++ gcc/tree-nested.c (working copy) @@ -2192,18 +2192,21 @@ remap_vla_decls (tree block, struct nest remap_vla_decls (subblock, root); for (var = BLOCK_VARS (block); var; var = DECL_CHAIN (var)) - { - if (TREE_CODE (var) == VAR_DECL - && variably_modified_type_p (TREE_TYPE (var), NULL) - && DECL_HAS_VALUE_EXPR_P (var)) - { - type = TREE_TYPE (var); - val = DECL_VALUE_EXPR (var); - if (walk_tree (&type, contains_remapped_vars, root, NULL) != NULL - || walk_tree (&val, contains_remapped_vars, root, NULL) != NULL) - break; - } - } + if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var)) + { + val = DECL_VALUE_EXPR (var); + type = TREE_TYPE (var); + + if (!(TREE_CODE (val) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL + && variably_modified_type_p (type, NULL))) + continue; + + if (pointer_map_contains (root->var_map, TREE_OPERAND (val, 0)) + || walk_tree (&type, contains_remapped_vars, root, NULL)) + break; + } + if (var == NULL_TREE) return; @@ -2213,17 +2216,22 @@ remap_vla_decls (tree block, struct nest id.root = root; for (; var; var = DECL_CHAIN (var)) - if (TREE_CODE (var) == VAR_DECL - && variably_modified_type_p (TREE_TYPE (var), NULL) - && DECL_HAS_VALUE_EXPR_P (var)) + if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var)) { struct nesting_info *i; - tree newt, t, context; + tree newt, context; + void **slot; - t = type = TREE_TYPE (var); val = DECL_VALUE_EXPR (var); - if (walk_tree (&type, contains_remapped_vars, root, NULL) == NULL - && walk_tree (&val, contains_remapped_vars, root, NULL) == NULL) + type = TREE_TYPE (var); + + if (!(TREE_CODE (val) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL + && variably_modified_type_p (type, NULL))) + continue; + + slot = pointer_map_contains (root->var_map, TREE_OPERAND (val, 0)); + if (!slot && !walk_tree (&type, contains_remapped_vars, root, NULL)) continue; context = decl_function_context (var); @@ -2234,6 +2242,15 @@ remap_vla_decls (tree block, struct nest if (i == NULL) continue; + /* Fully expand value expressions. This avoids having debug variables + only referenced from them and that can be swept during GC. */ + if (slot) + { + tree t = (tree) *slot; + gcc_assert (DECL_P (t) && DECL_HAS_VALUE_EXPR_P (t)); + val = build1 (INDIRECT_REF, TREE_TYPE (val), DECL_VALUE_EXPR (t)); + } + id.cb.src_fn = i->context; id.cb.dst_fn = i->context; id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context); @@ -2242,13 +2259,13 @@ remap_vla_decls (tree block, struct nest while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt)) { newt = TREE_TYPE (newt); - t = TREE_TYPE (t); + type = TREE_TYPE (type); } if (TYPE_NAME (newt) && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL && DECL_ORIGINAL_TYPE (TYPE_NAME (newt)) - && newt != t - && TYPE_NAME (newt) == TYPE_NAME (t)) + && newt != type + && TYPE_NAME (newt) == TYPE_NAME (type)) TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb); walk_tree (&val, copy_tree_body_r, &id.cb, NULL); Index: config/bootstrap-lto.mk =================================================================== --- config/bootstrap-lto.mk (revision 167172) +++ config/bootstrap-lto.mk (working copy) @@ -3,6 +3,3 @@ STAGE2_CFLAGS += -flto=jobserver -fuse-linker-plugin -frandom-seed=1 STAGE3_CFLAGS += -flto=jobserver -fuse-linker-plugin -frandom-seed=1 - -# Ada fails to build with LTO, turn it off for now. -BOOT_ADAFLAGS += -fno-lto