Commit f45f9664 by Eric Botcazou Committed by Eric Botcazou

decl.c (cannot_be_superflat_p): New predicate.

	* gcc-interface/decl.c (cannot_be_superflat_p): New predicate.
	(gnat_to_gnu_entity) <E_Array_Subtype>: Use it to build the expression
	of the upper bound of the index types.

From-SVN: r148966
parent bcade395
2009-06-26 Eric Botcazou <ebotcazou@adacore.com> 2009-06-26 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (cannot_be_superflat_p): New predicate.
(gnat_to_gnu_entity) <E_Array_Subtype>: Use it to build the expression
of the upper bound of the index types.
2009-06-26 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Factor * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Factor
out common predicate. Use the maximum to compute the upper bound of out common predicate. Use the maximum to compute the upper bound of
the index type only when it is not wider than sizetype. Perform the the index type only when it is not wider than sizetype. Perform the
......
...@@ -136,6 +136,7 @@ static tree gnat_to_gnu_param (Entity_Id, Mechanism_Type, Entity_Id, bool, ...@@ -136,6 +136,7 @@ static tree gnat_to_gnu_param (Entity_Id, Mechanism_Type, Entity_Id, bool,
static bool same_discriminant_p (Entity_Id, Entity_Id); static bool same_discriminant_p (Entity_Id, Entity_Id);
static bool array_type_has_nonaliased_component (Entity_Id, tree); static bool array_type_has_nonaliased_component (Entity_Id, tree);
static bool compile_time_known_address_p (Node_Id); static bool compile_time_known_address_p (Node_Id);
static bool cannot_be_superflat_p (Node_Id);
static void components_to_record (tree, Node_Id, tree, int, bool, tree *, static void components_to_record (tree, Node_Id, tree, int, bool, tree *,
bool, bool, bool, bool); bool, bool, bool, bool);
static Uint annotate_value (tree); static Uint annotate_value (tree);
...@@ -2202,22 +2203,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) ...@@ -2202,22 +2203,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_high = gnu_max; gnu_high = gnu_max;
} }
/* Compute the size of this dimension in the general case. We
need to provide GCC with an upper bound to use but have to
deal with the "superflat" case. There are three ways to do
this. If we can prove that the array can never be superflat,
we can just use the high bound of the index type. */
else if (Nkind (gnat_index) == N_Range
&& cannot_be_superflat_p (gnat_index))
gnu_high = gnu_max;
/* Otherwise, if we can prove that the low bound minus one and
the high bound cannot overflow, we can just use the expression
MAX (hb, lb - 1). Otherwise, we have to use the most general
expression (hb >= lb) ? hb : lb - 1. Note that the comparison
must be done in the original index type, to avoid any overflow
during the conversion. */
else else
{ {
/* Now compute the size of this bound. We need to provide
GCC with an upper bound to use but have to deal with the
"superflat" case. There are three ways to do this. If
we can prove that the array can never be superflat, we
can just use the high bound of the index subtype. If we
can prove that the low bound minus one and the high bound
can't overflow, we can do this as MAX (hb, lb - 1). But,
otherwise, we have to use (hb >= lb) ? hb : lb - 1. Note
that the comparison must be done in the original index
type, to avoid any overflow during the conversion. */
gnu_high = size_binop (MINUS_EXPR, gnu_min, size_one_node); gnu_high = size_binop (MINUS_EXPR, gnu_min, size_one_node);
/* If gnu_high is a constant that has overflowed, the array /* If gnu_high is a constant that has overflowed, the bound
cannot be superflat. */ is the smallest integer so cannot be the maximum. */
if (TREE_CODE (gnu_high) == INTEGER_CST if (TREE_CODE (gnu_high) == INTEGER_CST
&& TREE_OVERFLOW (gnu_high)) && TREE_OVERFLOW (gnu_high))
gnu_high = gnu_max; gnu_high = gnu_max;
...@@ -5304,6 +5310,44 @@ compile_time_known_address_p (Node_Id gnat_address) ...@@ -5304,6 +5310,44 @@ compile_time_known_address_p (Node_Id gnat_address)
return Compile_Time_Known_Value (gnat_address); return Compile_Time_Known_Value (gnat_address);
} }
/* Return true if GNAT_RANGE, a N_Range node, cannot be superflat, i.e.
cannot verify HB < LB-1 when LB and HB are the low and high bounds. */
static bool
cannot_be_superflat_p (Node_Id gnat_range)
{
Node_Id gnat_lb = Low_Bound (gnat_range), gnat_hb = High_Bound (gnat_range);
tree gnu_lb, gnu_hb;
/* If the low bound is not constant, try to find an upper bound. */
while (Nkind (gnat_lb) != N_Integer_Literal
&& (Ekind (Etype (gnat_lb)) == E_Signed_Integer_Subtype
|| Ekind (Etype (gnat_lb)) == E_Modular_Integer_Subtype)
&& Nkind (Scalar_Range (Etype (gnat_lb))) == N_Range)
gnat_lb = High_Bound (Scalar_Range (Etype (gnat_lb)));
/* If the high bound is not constant, try to find a lower bound. */
while (Nkind (gnat_hb) != N_Integer_Literal
&& (Ekind (Etype (gnat_hb)) == E_Signed_Integer_Subtype
|| Ekind (Etype (gnat_hb)) == E_Modular_Integer_Subtype)
&& Nkind (Scalar_Range (Etype (gnat_hb))) == N_Range)
gnat_hb = Low_Bound (Scalar_Range (Etype (gnat_hb)));
if (!(Nkind (gnat_lb) == N_Integer_Literal
&& Nkind (gnat_hb) == N_Integer_Literal))
return false;
gnu_lb = UI_To_gnu (Intval (gnat_lb), bitsizetype);
gnu_hb = UI_To_gnu (Intval (gnat_hb), bitsizetype);
/* If the low bound is the smallest integer, nothing can be smaller. */
gnu_lb = size_binop (MINUS_EXPR, gnu_lb, bitsize_one_node);
if (TREE_OVERFLOW (gnu_lb))
return true;
return (tree_int_cst_lt (gnu_hb, gnu_lb) == 0);
}
/* Given GNAT_ENTITY, elaborate all expressions that are required to /* Given GNAT_ENTITY, elaborate all expressions that are required to
be elaborated at the point of its definition, but do nothing else. */ be elaborated at the point of its definition, but do nothing else. */
......
2009-06-26 Eric Botcazou <ebotcazou@adacore.com> 2009-06-26 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/array7.ad[sb]: New test.
2009-06-26 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/array6.adb: New test. * gnat.dg/array6.adb: New test.
2009-06-25 Ian Lance Taylor <iant@google.com> 2009-06-25 Ian Lance Taylor <iant@google.com>
......
-- { dg-do compile }
-- { dg-options "-O -gnatp -fdump-tree-optimized" }
package body Array7 is
function Get_Arr (Nbr : My_Range) return Arr_Acc is
begin
return new Arr (1 .. Nbr);
end;
end Array7;
-- { dg-final { scan-tree-dump-not "MAX_EXPR" "optimized" } }
package Array7 is
type Arr is array (Positive range <>) of Integer;
type Arr_Acc is access Arr;
subtype My_Range is Integer range 1 .. 25;
function Get_Arr (Nbr : My_Range) return Arr_Acc;
end Array7;
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