From patchwork Tue Sep 5 08:40:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 809998 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-461458-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="MaullrBh"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xmgCV5CRVz9sNq for ; Tue, 5 Sep 2017 18:40:37 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=qd+vhpbnonJwIa/x WMGNidOtDMIKfY4wOg2mOgnkRgLk3RfefFu9q8Cc+HRCpkeynqa8oqmgs/QeyDzv tqEoHLM7rcXGEsdKrEXeQeMgkZmu9fhkH3w2zthOq2HzPr/zHYy5xZ/5iDiWQJyW 6+DHMcr32RcQLluWTzpAK19xkUA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=iSb3H6Fl968WcXGx83Jcw3 E4CMg=; b=MaullrBhUmImlEvgVtsK/jEibutdDZ8wFur70gNiOmE5hlS9mPGKN9 b46Jv+1avxK+fo3sPUaJrL5hw3ipfSZN6/6nUDJcR60Yku6SJmkxiASUigWJgRB+ enGthbQe9b38T3YWe5cG/qaG35ZBMiHiONA9IGmU8Xt7UpXBrJwoM= Received: (qmail 111557 invoked by alias); 5 Sep 2017 08:40:22 -0000 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 Received: (qmail 111538 invoked by uid 89); 5 Sep 2017 08:40:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-14.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=qn, 1-3, successive, dda X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 05 Sep 2017 08:40:16 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 24680822CA for ; Tue, 5 Sep 2017 10:40:14 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7f1JS5cVFOip for ; Tue, 5 Sep 2017 10:40:14 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id D5603814C6 for ; Tue, 5 Sep 2017 10:40:13 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [Ada] Enhance -gnatR3 output for simple dynamic record types Date: Tue, 05 Sep 2017 10:40:13 +0200 Message-ID: <4618254.OjInZ6m1JO@polaris> User-Agent: KMail/4.14.10 (Linux/3.16.7-53-desktop; KDE/4.14.9; x86_64; ; ) MIME-Version: 1.0 This changes the terse -gnatR3 output for simple dynamic record types like: package Q is type My_Index is range 1 .. 1024 * 1024; type Arr is array (My_Index range <>) of Short_Integer; function N return My_Index; end Q; with Q; use Q; package P is type R is record I1 : Integer; S1 : Short_Integer; A1 : Arr (1 .. Q.N); end record; end P; from: Representation information for unit P (spec) -------------------------------------------- for R'Size use ??; for R'Alignment use 4; for R use record I1 at 0 range 0 .. 31; S1 at 4 range 0 .. 15; A1 at 6 range 0 .. ??; end record; to: Representation information for unit P (spec) -------------------------------------------- for R'Object_Size use ((((Var1 + 3) * 16) + 31) & -32) ; for R'Value_Size use ((Var1 + 3) * 16) ; for R'Alignment use 4; for R use record I1 at 0 range 0 .. 31; S1 at 4 range 0 .. 15; A1 at 6 range 0 .. ((Var1 * 16)) - 1; end record; where Var1 is a symbolic representation of the dynamic value. 2017-09-05 Eric Botcazou * repinfo.ads: Document new treatment of dynamic values. (TCode): Bump upper bound to 29. (Dynamic_Val): New constant set to 29. * repinfo.adb (Print_Expr) : New case. (Rep_Value) : Likewise. * repinfo.h (Dynamic_Val): New macro. * gcc-interface/decl.c (annotate_value): Tidy up and cache result for DECL_P nodes too. : Set TCODE instead of recursing. : Set TCODE instead of calling Create_Node manually. : New case. : Fold conversions into inner operations. : Adjust. : Do not fall through. Index: gcc-interface/decl.c =================================================================== --- gcc-interface/decl.c (revision 251553) +++ gcc-interface/decl.c (working copy) @@ -8047,13 +8047,13 @@ components_to_record (Node_Id gnat_compo static Uint annotate_value (tree gnu_size) { + static int var_count = 0; TCode tcode; - Node_Ref_Or_Val ops[3], ret, pre_op1 = No_Uint; + Node_Ref_Or_Val ops[3] = { No_Uint, No_Uint, No_Uint }; struct tree_int_map in; - int i; /* See if we've already saved the value for this node. */ - if (EXPR_P (gnu_size)) + if (EXPR_P (gnu_size) || DECL_P (gnu_size)) { struct tree_int_map *e; @@ -8067,9 +8067,7 @@ annotate_value (tree gnu_size) in.base.from = NULL_TREE; /* If we do not return inside this switch, TCODE will be set to the - code to use for a Create_Node operand and LEN (set above) will be - the number of recursive calls for us to make. */ - + code to be used in a call to Create_Node. */ switch (TREE_CODE (gnu_size)) { case INTEGER_CST: @@ -8078,38 +8076,51 @@ annotate_value (tree gnu_size) if (tree_int_cst_sgn (gnu_size) < 0) { tree t = wide_int_to_tree (sizetype, wi::neg (gnu_size)); - return annotate_value (build1 (NEGATE_EXPR, sizetype, t)); + tcode = Negate_Expr; + ops[0] = UI_From_gnu (t); } - - return TREE_OVERFLOW (gnu_size) ? No_Uint : UI_From_gnu (gnu_size); + else + return TREE_OVERFLOW (gnu_size) ? No_Uint : UI_From_gnu (gnu_size); + break; case COMPONENT_REF: /* The only case we handle here is a simple discriminant reference. */ if (DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1))) { - tree n = DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1)); + tree ref = gnu_size; + gnu_size = TREE_OPERAND (ref, 1); /* Climb up the chain of successive extensions, if any. */ - while (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == COMPONENT_REF - && DECL_NAME (TREE_OPERAND (TREE_OPERAND (gnu_size, 0), 1)) + while (TREE_CODE (TREE_OPERAND (ref, 0)) == COMPONENT_REF + && DECL_NAME (TREE_OPERAND (TREE_OPERAND (ref, 0), 1)) == parent_name_id) - gnu_size = TREE_OPERAND (gnu_size, 0); + ref = TREE_OPERAND (ref, 0); - if (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == PLACEHOLDER_EXPR) - return - Create_Node (Discrim_Val, annotate_value (n), No_Uint, No_Uint); + if (TREE_CODE (TREE_OPERAND (ref, 0)) == PLACEHOLDER_EXPR) + { + /* Fall through to common processing as a FIELD_DECL. */ + tcode = Discrim_Val; + ops[0] = UI_From_gnu (DECL_DISCRIMINANT_NUMBER (gnu_size)); + } + else + return No_Uint; } + else + return No_Uint; + break; - return No_Uint; + case VAR_DECL: + tcode = Dynamic_Val; + ops[0] = UI_From_Int (++var_count); + break; - CASE_CONVERT: case NON_LVALUE_EXPR: + CASE_CONVERT: + case NON_LVALUE_EXPR: return annotate_value (TREE_OPERAND (gnu_size, 0)); /* Now just list the operations we handle. */ case COND_EXPR: tcode = Cond_Expr; break; - case PLUS_EXPR: tcode = Plus_Expr; break; case MINUS_EXPR: tcode = Minus_Expr; break; - case MULT_EXPR: tcode = Mult_Expr; break; case TRUNC_DIV_EXPR: tcode = Trunc_Div_Expr; break; case CEIL_DIV_EXPR: tcode = Ceil_Div_Expr; break; case FLOOR_DIV_EXPR: tcode = Floor_Div_Expr; break; @@ -8134,6 +8145,30 @@ annotate_value (tree gnu_size) case EQ_EXPR: tcode = Eq_Expr; break; case NE_EXPR: tcode = Ne_Expr; break; + case MULT_EXPR: + case PLUS_EXPR: + tcode = (TREE_CODE (gnu_size) == MULT_EXPR ? Mult_Expr : Plus_Expr); + /* Fold conversions from bytes to bits into inner operations. */ + if (TREE_CODE (TREE_OPERAND (gnu_size, 1)) == INTEGER_CST + && CONVERT_EXPR_P (TREE_OPERAND (gnu_size, 0))) + { + tree inner_op = TREE_OPERAND (TREE_OPERAND (gnu_size, 0), 0); + if (TREE_CODE (inner_op) == TREE_CODE (gnu_size) + && TREE_CODE (TREE_OPERAND (inner_op, 1)) == INTEGER_CST) + { + tree inner_op_op1 = TREE_OPERAND (inner_op, 1); + tree gnu_size_op1 = TREE_OPERAND (gnu_size, 1); + wide_int op1; + if (TREE_CODE (gnu_size) == MULT_EXPR) + op1 = wi::mul (inner_op_op1, gnu_size_op1); + else + op1 = wi::add (inner_op_op1, gnu_size_op1); + ops[1] = UI_From_gnu (wide_int_to_tree (sizetype, op1)); + ops[0] = annotate_value (TREE_OPERAND (inner_op, 0)); + } + } + break; + case BIT_AND_EXPR: tcode = Bit_And_Expr; /* For negative values in sizetype, build NEGATE_EXPR of the opposite. @@ -8146,7 +8181,7 @@ annotate_value (tree gnu_size) if (wi::neg_p (signed_op1)) { op1 = wide_int_to_tree (sizetype, wi::neg (signed_op1)); - pre_op1 = annotate_value (build1 (NEGATE_EXPR, sizetype, op1)); + ops[1] = annotate_value (build1 (NEGATE_EXPR, sizetype, op1)); } } break; @@ -8158,34 +8193,26 @@ annotate_value (tree gnu_size) if (List_Representation_Info == 3 || type_annotate_only) { tree t = maybe_inline_call_in_expr (gnu_size); - if (t) - return annotate_value (t); + return t ? annotate_value (t) : No_Uint; } else return Uint_Minus_1; - /* Fall through... */ - default: return No_Uint; } /* Now get each of the operands that's relevant for this code. If any cannot be expressed as a repinfo node, say we can't. */ - for (i = 0; i < 3; i++) - ops[i] = No_Uint; - - for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (gnu_size)); i++) - { - if (i == 1 && pre_op1 != No_Uint) - ops[i] = pre_op1; - else + for (int i = 0; i < TREE_CODE_LENGTH (TREE_CODE (gnu_size)); i++) + if (ops[i] == No_Uint) + { ops[i] = annotate_value (TREE_OPERAND (gnu_size, i)); - if (ops[i] == No_Uint) - return No_Uint; - } + if (ops[i] == No_Uint) + return No_Uint; + } - ret = Create_Node (tcode, ops[0], ops[1], ops[2]); + Node_Ref_Or_Val ret = Create_Node (tcode, ops[0], ops[1], ops[2]); /* Save the result in the cache. */ if (in.base.from) @@ -8198,7 +8225,7 @@ annotate_value (tree gnu_size) h = annotate_value_cache->find_slot (&in, INSERT); gcc_assert (!*h); *h = ggc_alloc (); - (*h)->base.from = gnu_size; + (*h)->base.from = in.base.from; (*h)->to = ret; } Index: repinfo.adb =================================================================== --- repinfo.adb (revision 251553) +++ repinfo.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1999-2016, Free Software Foundation, Inc. -- +-- Copyright (C) 1999-2017, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -59,11 +59,11 @@ package body Repinfo is -- value is assumed to be 8 for the implementation of the DDA. --------------------------------------- - -- Representation of gcc Expressions -- + -- Representation of GCC Expressions -- --------------------------------------- -- This table is used only if Frontend_Layout_On_Target is False, so gigi - -- lays out dynamic size/offset fields using encoded gcc expressions. + -- lays out dynamic size/offset fields using encoded GCC expressions. -- A table internal to this unit is used to hold the values of back -- annotated expressions. This table is written out by -gnatt and read @@ -643,6 +643,10 @@ package body Repinfo is when Discrim_Val => Write_Char ('#'); UI_Write (Node.Op1); + + when Dynamic_Val => + Write_Str ("Var"); + UI_Write (Node.Op1); end case; end; end if; @@ -1448,6 +1452,9 @@ package body Repinfo is pragma Assert (Sub in D'Range); return D (Sub); end; + + when Dynamic_Val => + return No_Uint; end case; end; end if; Index: repinfo.ads =================================================================== --- repinfo.ads (revision 251553) +++ repinfo.ads (working copy) @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1999-2014, Free Software Foundation, Inc. -- +-- Copyright (C) 1999-2017, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -83,7 +83,7 @@ package Repinfo is -- For E_Array_Type entities, the Component_Size field -- For all record and array types and subtypes, the Esize field, - -- which contains the Size (more accurately the Object_SIze) value + -- which contains the Size (more accurately the Object_Size) value -- for the type or subtype. -- For E_Component and E_Discriminant entities, the Esize (size @@ -96,19 +96,19 @@ package Repinfo is -- by simply storing the non-negative universal integer value in -- the appropriate field corresponding to this constant size. - -- 2. The value depends on variables other than discriminants of the - -- current record. In this case, the value is not known, even if - -- the complete data of the record is available, and gigi marks - -- this situation by storing the special value No_Uint. - - -- 3. The value depends on the discriminant values for the current + -- 2. The value depends on the discriminant values for the current -- record. In this case, gigi back annotates the field with a -- representation of the expression for computing the value in -- terms of the discriminants. A negative Uint value is used to -- represent the value of such an expression, as explained in -- the following section. - -- Note: the extended back-annotation for the dynamic case is needed only + -- 3. The value depends on variables other than discriminants of the + -- current record. In this case, gigi also back annotates the field + -- with a representation of the expression for computing the value + -- in terms of the variables represented symbolically. + + -- Note: the extended back annotation for the dynamic case is needed only -- for -gnatR3 output, and for proper operation of the ASIS DDA. Since it -- can be expensive to do this back annotation (for discriminated records -- with many variable length arrays), we only do the full back annotation @@ -136,7 +136,7 @@ package Repinfo is -- Subtype used for values that can either be a Node_Ref (negative) -- or a value (non-negative) - type TCode is range 0 .. 28; + type TCode is range 0 .. 29; -- Type used on Ada side to represent DEFTREECODE values defined in -- tree.def. Only a subset of these tree codes can actually appear. -- The names are the names from tree.def in Ada casing. @@ -174,10 +174,17 @@ package Repinfo is -- The following entry is used to represent a discriminant value in -- the tree. It has a special tree code that does not correspond - -- directly to a gcc node. The single operand is the number of the - -- discriminant in the record (1 = first discriminant). + -- directly to a GCC node. The single operand is the index number + -- of the discriminant in the record (1 = first discriminant). + + Discrim_Val : constant TCode := 0; -- discriminant value 1 + + -- The following entry is used to represent a value not known at + -- compile time in the tree, other than a discriminant value. It + -- has a special tree code that does not correspond directly to + -- a GCC node. The single operand is an arbitrary index number. - Discrim_Val : constant TCode := 0; -- discriminant value 1 + Dynamic_Val : constant TCode := 29; -- dynamic value 1 ------------------------ -- The gigi Interface -- Index: repinfo.h =================================================================== --- repinfo.h (revision 251553) +++ repinfo.h (working copy) @@ -6,7 +6,7 @@ * * * C Header File * * * - * Copyright (C) 1999-2011, Free Software Foundation, Inc. * + * Copyright (C) 1999-2017, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -71,6 +71,7 @@ typedef char TCode; #define Eq_Expr 26 #define Ne_Expr 27 #define Bit_And_Expr 28 +#define Dynamic_Val 29 /* Creates a node using the tree code defined by Expr and from 1-3 operands as required (unused operands set as shown to No_Uint) Note