Commit e45f84a5 by Eric Botcazou Committed by Eric Botcazou

repinfo.ads: Document new treatment of dynamic values.

	* 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) <Dynamic_Val>: New case.
	(Rep_Value)  <Dynamic_Val>: Likewise.
	* repinfo.h (Dynamic_Val): New macro.
	* gcc-interface/decl.c (annotate_value): Tidy up and cache result for
	DECL_P nodes too.
	<INTEGER_CST>: Set TCODE instead of recursing.
	<COMPONENT_REF>: Set TCODE instead of calling Create_Node manually.
	<VAR_DECL>: New case.
	<MULT_EXPR, PLUS_EXPR>: Fold conversions into inner operations.
	<BIT_AND_EXPR>: Adjust.
	<CALL_EXPR>: Do not fall through.

From-SVN: r251698
parent 6a9db54c
2017-09-05 Eric Botcazou <ebotcazou@adacore.com> 2017-09-05 Eric Botcazou <ebotcazou@adacore.com>
* 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) <Dynamic_Val>: New case.
(Rep_Value) <Dynamic_Val>: Likewise.
* repinfo.h (Dynamic_Val): New macro.
* gcc-interface/decl.c (annotate_value): Tidy up and cache result for
DECL_P nodes too.
<INTEGER_CST>: Set TCODE instead of recursing.
<COMPONENT_REF>: Set TCODE instead of calling Create_Node manually.
<VAR_DECL>: New case.
<MULT_EXPR, PLUS_EXPR>: Fold conversions into inner operations.
<BIT_AND_EXPR>: Adjust.
<CALL_EXPR>: Do not fall through.
2017-09-05 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (Call_to_gnu): If this is a function call and * gcc-interface/trans.c (Call_to_gnu): If this is a function call and
there is no target, do not create a temporary for the return value for there is no target, do not create a temporary for the return value for
an allocator either. an allocator either.
......
...@@ -8047,13 +8047,13 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type, ...@@ -8047,13 +8047,13 @@ components_to_record (Node_Id gnat_component_list, Entity_Id gnat_record_type,
static Uint static Uint
annotate_value (tree gnu_size) annotate_value (tree gnu_size)
{ {
static int var_count = 0;
TCode tcode; 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; struct tree_int_map in;
int i;
/* See if we've already saved the value for this node. */ /* 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; struct tree_int_map *e;
...@@ -8067,9 +8067,7 @@ annotate_value (tree gnu_size) ...@@ -8067,9 +8067,7 @@ annotate_value (tree gnu_size)
in.base.from = NULL_TREE; in.base.from = NULL_TREE;
/* If we do not return inside this switch, TCODE will be set to the /* 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 code to be used in a call to Create_Node. */
the number of recursive calls for us to make. */
switch (TREE_CODE (gnu_size)) switch (TREE_CODE (gnu_size))
{ {
case INTEGER_CST: case INTEGER_CST:
...@@ -8078,38 +8076,51 @@ annotate_value (tree gnu_size) ...@@ -8078,38 +8076,51 @@ annotate_value (tree gnu_size)
if (tree_int_cst_sgn (gnu_size) < 0) if (tree_int_cst_sgn (gnu_size) < 0)
{ {
tree t = wide_int_to_tree (sizetype, wi::neg (gnu_size)); 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);
} }
else
return TREE_OVERFLOW (gnu_size) ? No_Uint : UI_From_gnu (gnu_size); return TREE_OVERFLOW (gnu_size) ? No_Uint : UI_From_gnu (gnu_size);
break;
case COMPONENT_REF: case COMPONENT_REF:
/* The only case we handle here is a simple discriminant reference. */ /* The only case we handle here is a simple discriminant reference. */
if (DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1))) 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. */ /* Climb up the chain of successive extensions, if any. */
while (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == COMPONENT_REF while (TREE_CODE (TREE_OPERAND (ref, 0)) == COMPONENT_REF
&& DECL_NAME (TREE_OPERAND (TREE_OPERAND (gnu_size, 0), 1)) && DECL_NAME (TREE_OPERAND (TREE_OPERAND (ref, 0), 1))
== parent_name_id) == 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) if (TREE_CODE (TREE_OPERAND (ref, 0)) == PLACEHOLDER_EXPR)
return {
Create_Node (Discrim_Val, annotate_value (n), No_Uint, No_Uint); /* 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)); return annotate_value (TREE_OPERAND (gnu_size, 0));
/* Now just list the operations we handle. */ /* Now just list the operations we handle. */
case COND_EXPR: tcode = Cond_Expr; break; case COND_EXPR: tcode = Cond_Expr; break;
case PLUS_EXPR: tcode = Plus_Expr; break;
case MINUS_EXPR: tcode = Minus_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 TRUNC_DIV_EXPR: tcode = Trunc_Div_Expr; break;
case CEIL_DIV_EXPR: tcode = Ceil_Div_Expr; break; case CEIL_DIV_EXPR: tcode = Ceil_Div_Expr; break;
case FLOOR_DIV_EXPR: tcode = Floor_Div_Expr; break; case FLOOR_DIV_EXPR: tcode = Floor_Div_Expr; break;
...@@ -8134,6 +8145,30 @@ annotate_value (tree gnu_size) ...@@ -8134,6 +8145,30 @@ annotate_value (tree gnu_size)
case EQ_EXPR: tcode = Eq_Expr; break; case EQ_EXPR: tcode = Eq_Expr; break;
case NE_EXPR: tcode = Ne_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: case BIT_AND_EXPR:
tcode = Bit_And_Expr; tcode = Bit_And_Expr;
/* For negative values in sizetype, build NEGATE_EXPR of the opposite. /* For negative values in sizetype, build NEGATE_EXPR of the opposite.
...@@ -8146,7 +8181,7 @@ annotate_value (tree gnu_size) ...@@ -8146,7 +8181,7 @@ annotate_value (tree gnu_size)
if (wi::neg_p (signed_op1)) if (wi::neg_p (signed_op1))
{ {
op1 = wide_int_to_tree (sizetype, wi::neg (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; break;
...@@ -8158,34 +8193,26 @@ annotate_value (tree gnu_size) ...@@ -8158,34 +8193,26 @@ annotate_value (tree gnu_size)
if (List_Representation_Info == 3 || type_annotate_only) if (List_Representation_Info == 3 || type_annotate_only)
{ {
tree t = maybe_inline_call_in_expr (gnu_size); tree t = maybe_inline_call_in_expr (gnu_size);
if (t) return t ? annotate_value (t) : No_Uint;
return annotate_value (t);
} }
else else
return Uint_Minus_1; return Uint_Minus_1;
/* Fall through... */
default: default:
return No_Uint; return No_Uint;
} }
/* Now get each of the operands that's relevant for this code. If any /* 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. */ cannot be expressed as a repinfo node, say we can't. */
for (i = 0; i < 3; i++) for (int i = 0; i < TREE_CODE_LENGTH (TREE_CODE (gnu_size)); i++)
ops[i] = No_Uint; if (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
ops[i] = annotate_value (TREE_OPERAND (gnu_size, i)); ops[i] = annotate_value (TREE_OPERAND (gnu_size, i));
if (ops[i] == No_Uint) if (ops[i] == No_Uint)
return 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. */ /* Save the result in the cache. */
if (in.base.from) if (in.base.from)
...@@ -8198,7 +8225,7 @@ annotate_value (tree gnu_size) ...@@ -8198,7 +8225,7 @@ annotate_value (tree gnu_size)
h = annotate_value_cache->find_slot (&in, INSERT); h = annotate_value_cache->find_slot (&in, INSERT);
gcc_assert (!*h); gcc_assert (!*h);
*h = ggc_alloc<tree_int_map> (); *h = ggc_alloc<tree_int_map> ();
(*h)->base.from = gnu_size; (*h)->base.from = in.base.from;
(*h)->to = ret; (*h)->to = ret;
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- 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 -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -59,11 +59,11 @@ package body Repinfo is ...@@ -59,11 +59,11 @@ package body Repinfo is
-- value is assumed to be 8 for the implementation of the DDA. -- 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 -- 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 -- 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 -- annotated expressions. This table is written out by -gnatt and read
...@@ -643,6 +643,10 @@ package body Repinfo is ...@@ -643,6 +643,10 @@ package body Repinfo is
when Discrim_Val => when Discrim_Val =>
Write_Char ('#'); Write_Char ('#');
UI_Write (Node.Op1); UI_Write (Node.Op1);
when Dynamic_Val =>
Write_Str ("Var");
UI_Write (Node.Op1);
end case; end case;
end; end;
end if; end if;
...@@ -1448,6 +1452,9 @@ package body Repinfo is ...@@ -1448,6 +1452,9 @@ package body Repinfo is
pragma Assert (Sub in D'Range); pragma Assert (Sub in D'Range);
return D (Sub); return D (Sub);
end; end;
when Dynamic_Val =>
return No_Uint;
end case; end case;
end; end;
end if; end if;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- 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 -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -83,7 +83,7 @@ package Repinfo is ...@@ -83,7 +83,7 @@ package Repinfo is
-- For E_Array_Type entities, the Component_Size field -- For E_Array_Type entities, the Component_Size field
-- For all record and array types and subtypes, the Esize 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 the type or subtype.
-- For E_Component and E_Discriminant entities, the Esize (size -- For E_Component and E_Discriminant entities, the Esize (size
...@@ -96,19 +96,19 @@ package Repinfo is ...@@ -96,19 +96,19 @@ package Repinfo is
-- by simply storing the non-negative universal integer value in -- by simply storing the non-negative universal integer value in
-- the appropriate field corresponding to this constant size. -- the appropriate field corresponding to this constant size.
-- 2. The value depends on variables other than discriminants of the -- 2. The value depends on the discriminant values for the current
-- 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
-- record. In this case, gigi back annotates the field with a -- record. In this case, gigi back annotates the field with a
-- representation of the expression for computing the value in -- representation of the expression for computing the value in
-- terms of the discriminants. A negative Uint value is used to -- terms of the discriminants. A negative Uint value is used to
-- represent the value of such an expression, as explained in -- represent the value of such an expression, as explained in
-- the following section. -- 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 -- for -gnatR3 output, and for proper operation of the ASIS DDA. Since it
-- can be expensive to do this back annotation (for discriminated records -- can be expensive to do this back annotation (for discriminated records
-- with many variable length arrays), we only do the full back annotation -- with many variable length arrays), we only do the full back annotation
...@@ -136,7 +136,7 @@ package Repinfo is ...@@ -136,7 +136,7 @@ package Repinfo is
-- Subtype used for values that can either be a Node_Ref (negative) -- Subtype used for values that can either be a Node_Ref (negative)
-- or a value (non-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 -- Type used on Ada side to represent DEFTREECODE values defined in
-- tree.def. Only a subset of these tree codes can actually appear. -- tree.def. Only a subset of these tree codes can actually appear.
-- The names are the names from tree.def in Ada casing. -- The names are the names from tree.def in Ada casing.
...@@ -174,10 +174,17 @@ package Repinfo is ...@@ -174,10 +174,17 @@ package Repinfo is
-- The following entry is used to represent a discriminant value in -- The following entry is used to represent a discriminant value in
-- the tree. It has a special tree code that does not correspond -- 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 -- directly to a GCC node. The single operand is the index number
-- discriminant in the record (1 = first discriminant). -- 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 -- -- The gigi Interface --
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* * * *
* C Header File * * 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 * * 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- * * terms of the GNU General Public License as published by the Free Soft- *
...@@ -71,6 +71,7 @@ typedef char TCode; ...@@ -71,6 +71,7 @@ typedef char TCode;
#define Eq_Expr 26 #define Eq_Expr 26
#define Ne_Expr 27 #define Ne_Expr 27
#define Bit_And_Expr 28 #define Bit_And_Expr 28
#define Dynamic_Val 29
/* Creates a node using the tree code defined by Expr and from 1-3 /* 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 operands as required (unused operands set as shown to No_Uint) Note
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment