From patchwork Sun Sep 25 20:37:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 116326 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 12210B6EE8 for ; Mon, 26 Sep 2011 07:41:18 +1000 (EST) Received: (qmail 30287 invoked by alias); 25 Sep 2011 20:41:16 -0000 Received: (qmail 30276 invoked by uid 22791); 25 Sep 2011 20:41:15 -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) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 25 Sep 2011 20:41:01 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 075AFCB0231 for ; Sun, 25 Sep 2011 22:41:02 +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 xKsyrrPv+8NT for ; Sun, 25 Sep 2011 22:40:51 +0200 (CEST) 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 EFA47CB0222 for ; Sun, 25 Sep 2011 22:40:24 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [Ada] Expand use of TREE_THIS_NOTRAP to unconstrained arrays Date: Sun, 25 Sep 2011 22:37:33 +0200 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Message-Id: <201109252237.33885.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 This expands the use of the TREE_THIS_NOTRAP flag to the dereference expression built for some unconstrained arrays. It will be propagated onto the regular INDIRECT_REF expression ultimately passed to the middle-end. Tested on i586-suse-linux, applied on the mainline. 2011-09-25 Eric Botcazou * gcc-interface/ada-tree.h (TREE_THIS_NOTRAP): Redefine. * gcc-interface/trans.c (Identifier_to_gnu): Factor out common code in the by-ref case. Do not set TREE_READONLY on a renamed object. Set TREE_THIS_NOTRAP on UNCONSTRAINED_ARRAY_REF nodes. (Attribute_to_gnu) : Expand the use of the parameter cache to the indirect case. * gcc-interface/utils.c (convert) : Preserve the TREE_THIS_NOTRAP flag. Index: gcc-interface/utils.c =================================================================== --- gcc-interface/utils.c (revision 179163) +++ gcc-interface/utils.c (working copy) @@ -3947,17 +3947,21 @@ convert (tree type, tree expr) break; case UNCONSTRAINED_ARRAY_REF: - /* Convert this to the type of the inner array by getting the address of - the array from the template. */ - expr = TREE_OPERAND (expr, 0); - expr = build_unary_op (INDIRECT_REF, NULL_TREE, - build_component_ref (expr, NULL_TREE, - TYPE_FIELDS - (TREE_TYPE (expr)), - false)); - etype = TREE_TYPE (expr); - ecode = TREE_CODE (etype); - break; + { + /* Convert this to the type of the inner array by getting the address + of the array from the template. */ + const bool no_trap = TREE_THIS_NOTRAP (expr); + expr = TREE_OPERAND (expr, 0); + expr = build_unary_op (INDIRECT_REF, NULL_TREE, + build_component_ref (expr, NULL_TREE, + TYPE_FIELDS + (TREE_TYPE (expr)), + false)); + TREE_THIS_NOTRAP (expr) = no_trap; + etype = TREE_TYPE (expr); + ecode = TREE_CODE (etype); + break; + } case VIEW_CONVERT_EXPR: { @@ -3992,8 +3996,9 @@ convert (tree type, tree expr) && !TYPE_IS_FAT_POINTER_P (etype)) return convert (type, op0); } + + break; } - break; default: break; Index: gcc-interface/trans.c =================================================================== --- gcc-interface/trans.c (revision 179169) +++ gcc-interface/trans.c (working copy) @@ -989,8 +989,8 @@ Identifier_to_gnu (Node_Id gnat_node, tr && DECL_BY_COMPONENT_PTR_P (gnu_result)))) { const bool read_only = DECL_POINTS_TO_READONLY_P (gnu_result); - tree renamed_obj; + /* First do the first dereference if needed. */ if (TREE_CODE (gnu_result) == PARM_DECL && DECL_BY_DOUBLE_REF_P (gnu_result)) { @@ -999,42 +999,37 @@ Identifier_to_gnu (Node_Id gnat_node, tr TREE_THIS_NOTRAP (gnu_result) = 1; } + /* If it's a PARM_DECL to foreign convention subprogram, convert it. */ if (TREE_CODE (gnu_result) == PARM_DECL && DECL_BY_COMPONENT_PTR_P (gnu_result)) - { - gnu_result - = build_unary_op (INDIRECT_REF, NULL_TREE, - convert (build_pointer_type (gnu_result_type), - gnu_result)); - if (TREE_CODE (gnu_result) == INDIRECT_REF) - TREE_THIS_NOTRAP (gnu_result) = 1; - } + gnu_result + = convert (build_pointer_type (gnu_result_type), gnu_result); + + /* If it's a CONST_DECL, return the underlying constant like below. */ + else if (TREE_CODE (gnu_result) == CONST_DECL) + gnu_result = DECL_INITIAL (gnu_result); /* If it's a renaming pointer and we are at the right binding level, we can reference the renamed object directly, since the renamed expression has been protected against multiple evaluations. */ - else if (TREE_CODE (gnu_result) == VAR_DECL - && (renamed_obj = DECL_RENAMED_OBJECT (gnu_result)) - && (!DECL_RENAMING_GLOBAL_P (gnu_result) - || global_bindings_p ())) - gnu_result = renamed_obj; - - /* Return the underlying CST for a CONST_DECL like a few lines below, - after dereferencing in this case. */ - else if (TREE_CODE (gnu_result) == CONST_DECL) - gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, - DECL_INITIAL (gnu_result)); + if (TREE_CODE (gnu_result) == VAR_DECL + && DECL_RENAMED_OBJECT (gnu_result) + && (!DECL_RENAMING_GLOBAL_P (gnu_result) || global_bindings_p ())) + gnu_result = DECL_RENAMED_OBJECT (gnu_result); + /* Otherwise, do the final dereference. */ else { gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result); - if (TREE_CODE (gnu_result) == INDIRECT_REF + + if ((TREE_CODE (gnu_result) == INDIRECT_REF + || TREE_CODE (gnu_result) == UNCONSTRAINED_ARRAY_REF) && No (Address_Clause (gnat_temp))) TREE_THIS_NOTRAP (gnu_result) = 1; - } - if (read_only) - TREE_READONLY (gnu_result) = 1; + if (read_only) + TREE_READONLY (gnu_result) = 1; + } } /* The GNAT tree has the type of a function as the type of its result. Also @@ -1597,11 +1592,26 @@ Attribute_to_gnu (Node_Id gnat_node, tre /* Make sure any implicit dereference gets done. */ gnu_prefix = maybe_implicit_deref (gnu_prefix); gnu_prefix = maybe_unconstrained_array (gnu_prefix); + /* We treat unconstrained array In parameters specially. */ - if (Nkind (Prefix (gnat_node)) == N_Identifier - && !Is_Constrained (Etype (Prefix (gnat_node))) - && Ekind (Entity (Prefix (gnat_node))) == E_In_Parameter) - gnat_param = Entity (Prefix (gnat_node)); + if (!Is_Constrained (Etype (Prefix (gnat_node)))) + { + Node_Id gnat_prefix = Prefix (gnat_node); + + /* This is the direct case. */ + if (Nkind (gnat_prefix) == N_Identifier + && Ekind (Entity (gnat_prefix)) == E_In_Parameter) + gnat_param = Entity (gnat_prefix); + + /* This is the indirect case. Note that we need to be sure that + the access value cannot be null as we'll hoist the load. */ + if (Nkind (gnat_prefix) == N_Explicit_Dereference + && Nkind (Prefix (gnat_prefix)) == N_Identifier + && Ekind (Entity (Prefix (gnat_prefix))) == E_In_Parameter + && Can_Never_Be_Null (Entity (Prefix (gnat_prefix)))) + gnat_param = Entity (Prefix (gnat_prefix)); + } + gnu_type = TREE_TYPE (gnu_prefix); prefix_unused = true; gnu_result_type = get_unpadded_type (Etype (gnat_node)); Index: gcc-interface/ada-tree.h =================================================================== --- gcc-interface/ada-tree.h (revision 179163) +++ gcc-interface/ada-tree.h (working copy) @@ -426,6 +426,15 @@ do { \ SET_DECL_LANG_SPECIFIC (PARM_DECL_CHECK (NODE), X) +/* Flags added to ref nodes. */ + +/* Nonzero means this node will not trap. */ +#undef TREE_THIS_NOTRAP +#define TREE_THIS_NOTRAP(NODE) \ + (TREE_CHECK4 (NODE, INDIRECT_REF, ARRAY_REF, UNCONSTRAINED_ARRAY_REF, \ + ARRAY_RANGE_REF)->base.nothrow_flag) + + /* Fields and macros for statements. */ #define IS_ADA_STMT(NODE) \ (STATEMENT_CLASS_P (NODE) && TREE_CODE (NODE) >= STMT_STMT)