Commit 586388fd by Eric Botcazou Committed by Eric Botcazou

uintp.adb (UI_From_Dint): Remove useless code.

	* uintp.adb (UI_From_Dint): Remove useless code.
	(UI_From_Int): Likewise.
	* uintp.h: Reorder declarations.
	(UI_From_gnu): Declare.
	(UI_Base): Likewise.
	(Vector_Template): Likewise.
	(Vector_To_Uint): Likewise.
	(Uint_0): Remove.
	(Uint_1): Likewise.
	* gcc-interface/gigi.h: Tweak comments.
	* gcc-interface/cuintp.c (UI_From_gnu): New global function.
	* gcc-interface/decl.c (maybe_pad_type): Do not warn if either size
	overflows.
	(annotate_value) <INTEGER_CST>: Call UI_From_gnu.
	* gcc-interface/trans.c (post_error_ne_num): Call post_error_ne.
	(post_error_ne_tree): Call UI_From_gnu and post_error_ne.
	* gcc-interface/utils.c (max_size) <tcc_binary>: Do not special-case
	TYPE_MAX_VALUE.

From-SVN: r158408
parent f0c6475a
2010-04-16 Eric Botcazou <ebotcazou@adacore.com> 2010-04-16 Eric Botcazou <ebotcazou@adacore.com>
* uintp.adb (UI_From_Dint): Remove useless code.
(UI_From_Int): Likewise.
* uintp.h: Reorder declarations.
(UI_From_gnu): Declare.
(UI_Base): Likewise.
(Vector_Template): Likewise.
(Vector_To_Uint): Likewise.
(Uint_0): Remove.
(Uint_1): Likewise.
* gcc-interface/gigi.h: Tweak comments.
* gcc-interface/cuintp.c (UI_From_gnu): New global function.
* gcc-interface/decl.c (maybe_pad_type): Do not warn if either size
overflows.
(annotate_value) <INTEGER_CST>: Call UI_From_gnu.
* gcc-interface/trans.c (post_error_ne_num): Call post_error_ne.
(post_error_ne_tree): Call UI_From_gnu and post_error_ne.
* gcc-interface/utils.c (max_size) <tcc_binary>: Do not special-case
TYPE_MAX_VALUE.
2010-04-16 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (make_type_from_size) <INTEGER_TYPE>: Just copy * gcc-interface/decl.c (make_type_from_size) <INTEGER_TYPE>: Just copy
TYPE_NAME. TYPE_NAME.
* gcc-interface/trans.c (smaller_packable_type_p): Rename into... * gcc-interface/trans.c (smaller_packable_type_p): Rename into...
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* * * *
* C Implementation File * * C Implementation File *
* * * *
* Copyright (C) 1992-2009, Free Software Foundation, Inc. * * Copyright (C) 1992-2010, 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- *
...@@ -142,3 +142,61 @@ UI_To_gnu (Uint Input, tree type) ...@@ -142,3 +142,61 @@ UI_To_gnu (Uint Input, tree type)
return gnu_ret; return gnu_ret;
} }
/* Similar to UI_From_Int, but take a GCC INTEGER_CST. We use UI_From_Int
when possible, i.e. for a 32-bit signed value, to take advantage of its
built-in caching mechanism. For values of larger magnitude, we compute
digits into a vector and call Vector_To_Uint. */
Uint
UI_From_gnu (tree Input)
{
tree gnu_type = TREE_TYPE (Input), gnu_base, gnu_temp;
/* UI_Base is defined so that 5 Uint digits is sufficient to hold the
largest possible signed 64-bit value. */
const int Max_For_Dint = 5;
int v[Max_For_Dint], i;
Vector_Template temp;
Int_Vector vec;
#if HOST_BITS_PER_WIDE_INT == 64
/* On 64-bit hosts, host_integerp tells whether the input fits in a
signed 64-bit integer. Then a truncation tells whether it fits
in a signed 32-bit integer. */
if (host_integerp (Input, 0))
{
HOST_WIDE_INT hw_input = TREE_INT_CST_LOW (Input);
if (hw_input == (int) hw_input)
return UI_From_Int (hw_input);
}
else
return No_Uint;
#else
/* On 32-bit hosts, host_integerp tells whether the input fits in a
signed 32-bit integer. Then a sign test tells whether it fits
in a signed 64-bit integer. */
if (host_integerp (Input, 0))
return UI_From_Int (TREE_INT_CST_LOW (Input));
else if (TREE_INT_CST_HIGH (Input) < 0
&& TYPE_UNSIGNED (gnu_type)
&& !(TREE_CODE (gnu_type) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (gnu_type)))
return No_Uint;
#endif
gnu_base = build_int_cst (gnu_type, UI_Base);
gnu_temp = Input;
for (i = Max_For_Dint - 1; i >= 0; i--)
{
v[i] = tree_low_cst (fold_build1 (ABS_EXPR, gnu_type,
fold_build2 (TRUNC_MOD_EXPR, gnu_type,
gnu_temp, gnu_base)),
0);
gnu_temp = fold_build2 (TRUNC_DIV_EXPR, gnu_type, gnu_temp, gnu_base);
}
temp.Low_Bound = 1, temp.High_Bound = Max_For_Dint;
vec.Array = v, vec.Bounds = &temp;
return Vector_To_Uint (vec, tree_int_cst_sgn (Input) < 0);
}
...@@ -6281,7 +6281,9 @@ maybe_pad_type (tree type, tree size, unsigned int align, ...@@ -6281,7 +6281,9 @@ maybe_pad_type (tree type, tree size, unsigned int align,
&& !operand_equal_p (size, orig_size, 0) && !operand_equal_p (size, orig_size, 0)
&& !(TREE_CODE (size) == INTEGER_CST && !(TREE_CODE (size) == INTEGER_CST
&& TREE_CODE (orig_size) == INTEGER_CST && TREE_CODE (orig_size) == INTEGER_CST
&& tree_int_cst_lt (size, orig_size))) && (TREE_OVERFLOW (size)
|| TREE_OVERFLOW (orig_size)
|| tree_int_cst_lt (size, orig_size))))
{ {
Node_Id gnat_error_node = Empty; Node_Id gnat_error_node = Empty;
...@@ -7087,7 +7089,7 @@ annotate_value (tree gnu_size) ...@@ -7087,7 +7089,7 @@ annotate_value (tree gnu_size)
TCode tcode; TCode tcode;
Node_Ref_Or_Val ops[3], ret; Node_Ref_Or_Val ops[3], ret;
struct tree_int_map **h = NULL; struct tree_int_map **h = NULL;
int size, i; 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))
...@@ -7143,17 +7145,7 @@ annotate_value (tree gnu_size) ...@@ -7143,17 +7145,7 @@ annotate_value (tree gnu_size)
return annotate_value (temp); return annotate_value (temp);
} }
if (!host_integerp (gnu_size, 1)) return UI_From_gnu (gnu_size);
return No_Uint;
size = tree_low_cst (gnu_size, 1);
/* This peculiar test is to make sure that the size fits in an int
on machines where HOST_WIDE_INT is not "int". */
if (tree_low_cst (gnu_size, 1) == size)
return UI_From_Int (size);
else
return No_Uint;
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. */
......
...@@ -232,28 +232,25 @@ extern bool Sloc_to_locus (Source_Ptr Sloc, location_t *locus); ...@@ -232,28 +232,25 @@ extern bool Sloc_to_locus (Source_Ptr Sloc, location_t *locus);
/* Post an error message. MSG is the error message, properly annotated. /* Post an error message. MSG is the error message, properly annotated.
NODE is the node at which to post the error and the node to use for the NODE is the node at which to post the error and the node to use for the
"&" substitution. */ '&' substitution. */
extern void post_error (const char *msg, Node_Id node); extern void post_error (const char *msg, Node_Id node);
/* Similar, but NODE is the node at which to post the error and ENT /* Similar to post_error, but NODE is the node at which to post the error and
is the node to use for the "&" substitution. */ ENT is the node to use for the '&' substitution. */
extern void post_error_ne (const char *msg, Node_Id node, Entity_Id ent); extern void post_error_ne (const char *msg, Node_Id node, Entity_Id ent);
/* Similar, but NODE is the node at which to post the error, ENT is the node /* Similar to post_error_ne, but NUM is the number to use for the '^'. */
to use for the "&" substitution, and NUM is the number to use for ^. */
extern void post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent, extern void post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent,
int num); int num);
/* Similar to post_error_ne_num, but T is a GCC tree representing the number /* Similar to post_error_ne, but T is a GCC tree representing the number to
to write. If the tree represents a constant that fits within a write. If T represents a constant, the text inside curly brackets in
host integer, the text inside curly brackets in MSG will be output MSG will be output (presumably including a '^'). Otherwise it will not
(presumably including a '^'). Otherwise that text will not be output be output and the text inside square brackets will be output instead. */
and the text inside square brackets will be output instead. */
extern void post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, extern void post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent,
tree t); tree t);
/* Similar to post_error_ne_tree, except that NUM is a second integer to write /* Similar to post_error_ne_tree, but NUM is a second integer to write. */
in the message. */
extern void post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent, extern void post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent,
tree t, int num); tree t, int num);
......
...@@ -7404,7 +7404,7 @@ decode_name (const char *name) ...@@ -7404,7 +7404,7 @@ decode_name (const char *name)
/* Post an error message. MSG is the error message, properly annotated. /* Post an error message. MSG is the error message, properly annotated.
NODE is the node at which to post the error and the node to use for the NODE is the node at which to post the error and the node to use for the
"&" substitution. */ '&' substitution. */
void void
post_error (const char *msg, Node_Id node) post_error (const char *msg, Node_Id node)
...@@ -7418,8 +7418,8 @@ post_error (const char *msg, Node_Id node) ...@@ -7418,8 +7418,8 @@ post_error (const char *msg, Node_Id node)
Error_Msg_N (fp, node); Error_Msg_N (fp, node);
} }
/* Similar, but NODE is the node at which to post the error and ENT /* Similar to post_error, but NODE is the node at which to post the error and
is the node to use for the "&" substitution. */ ENT is the node to use for the '&' substitution. */
void void
post_error_ne (const char *msg, Node_Id node, Entity_Id ent) post_error_ne (const char *msg, Node_Id node, Entity_Id ent)
...@@ -7433,56 +7433,37 @@ post_error_ne (const char *msg, Node_Id node, Entity_Id ent) ...@@ -7433,56 +7433,37 @@ post_error_ne (const char *msg, Node_Id node, Entity_Id ent)
Error_Msg_NE (fp, node, ent); Error_Msg_NE (fp, node, ent);
} }
/* Similar, but NODE is the node at which to post the error, ENT is the node /* Similar to post_error_ne, but NUM is the number to use for the '^'. */
to use for the "&" substitution, and NUM is the number to use for ^. */
void void
post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent, int num) post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent, int num)
{ {
String_Template temp;
Fat_Pointer fp;
temp.Low_Bound = 1, temp.High_Bound = strlen (msg);
fp.Array = msg, fp.Bounds = &temp;
Error_Msg_Uint_1 = UI_From_Int (num); Error_Msg_Uint_1 = UI_From_Int (num);
post_error_ne (msg, node, ent);
if (Present (node))
Error_Msg_NE (fp, node, ent);
} }
/* Similar to post_error_ne_num, but T is a GCC tree representing the /* Similar to post_error_ne, but T is a GCC tree representing the number to
number to write. If the tree represents a constant that fits within write. If T represents a constant, the text inside curly brackets in
a host integer, the text inside curly brackets in MSG will be output MSG will be output (presumably including a '^'). Otherwise it will not
(presumably including a '^'). Otherwise that text will not be output be output and the text inside square brackets will be output instead. */
and the text inside square brackets will be output instead. */
void void
post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t) post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t)
{ {
char *newmsg = XALLOCAVEC (char, strlen (msg) + 1); char *new_msg = XALLOCAVEC (char, strlen (msg) + 1);
String_Template temp = {1, 0};
Fat_Pointer fp;
char start_yes, end_yes, start_no, end_no; char start_yes, end_yes, start_no, end_no;
const char *p; const char *p;
char *q; char *q;
fp.Array = newmsg, fp.Bounds = &temp; if (TREE_CODE (t) == INTEGER_CST)
if (host_integerp (t, 1)
#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_INT
&&
compare_tree_int
(t, (((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_INT - 1)) - 1)) < 0
#endif
)
{ {
Error_Msg_Uint_1 = UI_From_Int (tree_low_cst (t, 1)); Error_Msg_Uint_1 = UI_From_gnu (t);
start_yes = '{', end_yes = '}', start_no = '[', end_no = ']'; start_yes = '{', end_yes = '}', start_no = '[', end_no = ']';
} }
else else
start_yes = '[', end_yes = ']', start_no = '{', end_no = '}'; start_yes = '[', end_yes = ']', start_no = '{', end_no = '}';
for (p = msg, q = newmsg; *p; p++) for (p = msg, q = new_msg; *p; p++)
{ {
if (*p == start_yes) if (*p == start_yes)
for (p++; *p != end_yes; p++) for (p++; *p != end_yes; p++)
...@@ -7496,13 +7477,10 @@ post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t) ...@@ -7496,13 +7477,10 @@ post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t)
*q = 0; *q = 0;
temp.High_Bound = strlen (newmsg); post_error_ne (new_msg, node, ent);
if (Present (node))
Error_Msg_NE (fp, node, ent);
} }
/* Similar to post_error_ne_tree, except that NUM is a second integer to write /* Similar to post_error_ne_tree, but NUM is a second integer to write. */
in the message. */
void void
post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent, tree t, post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent, tree t,
......
...@@ -2228,8 +2228,7 @@ max_size (tree exp, bool max_p) ...@@ -2228,8 +2228,7 @@ max_size (tree exp, bool max_p)
In that case, if one side overflows, return the other. In that case, if one side overflows, return the other.
sizetype is signed, but we know sizes are non-negative. sizetype is signed, but we know sizes are non-negative.
Likewise, handle a MINUS_EXPR or PLUS_EXPR with the LHS Likewise, handle a MINUS_EXPR or PLUS_EXPR with the LHS
overflowing or the maximum possible value and the RHS overflowing and the RHS a variable. */
a variable. */
if (max_p if (max_p
&& code == MIN_EXPR && code == MIN_EXPR
&& TREE_CODE (rhs) == INTEGER_CST && TREE_CODE (rhs) == INTEGER_CST
...@@ -2241,9 +2240,8 @@ max_size (tree exp, bool max_p) ...@@ -2241,9 +2240,8 @@ max_size (tree exp, bool max_p)
&& TREE_OVERFLOW (lhs)) && TREE_OVERFLOW (lhs))
return rhs; return rhs;
else if ((code == MINUS_EXPR || code == PLUS_EXPR) else if ((code == MINUS_EXPR || code == PLUS_EXPR)
&& ((TREE_CODE (lhs) == INTEGER_CST && TREE_CODE (lhs) == INTEGER_CST
&& TREE_OVERFLOW (lhs)) && TREE_OVERFLOW (lhs)
|| operand_equal_p (lhs, TYPE_MAX_VALUE (type), 0))
&& !TREE_CONSTANT (rhs)) && !TREE_CONSTANT (rhs))
return lhs; return lhs;
else else
......
...@@ -1703,15 +1703,9 @@ package body Uintp is ...@@ -1703,15 +1703,9 @@ package body Uintp is
V : UI_Vector (1 .. Max_For_Dint); V : UI_Vector (1 .. Max_For_Dint);
Temp_Integer : Dint; Temp_Integer : Dint := Input;
begin begin
for J in V'Range loop
V (J) := 0;
end loop;
Temp_Integer := Input;
for J in reverse V'Range loop for J in reverse V'Range loop
V (J) := Int (abs (Temp_Integer rem Dint (Base))); V (J) := Int (abs (Temp_Integer rem Dint (Base)));
Temp_Integer := Temp_Integer / Dint (Base); Temp_Integer := Temp_Integer / Dint (Base);
...@@ -1752,15 +1746,9 @@ package body Uintp is ...@@ -1752,15 +1746,9 @@ package body Uintp is
V : UI_Vector (1 .. Max_For_Int); V : UI_Vector (1 .. Max_For_Int);
Temp_Integer : Int; Temp_Integer : Int := Input;
begin begin
for J in V'Range loop
V (J) := 0;
end loop;
Temp_Integer := Input;
for J in reverse V'Range loop for J in reverse V'Range loop
V (J) := abs (Temp_Integer rem Base); V (J) := abs (Temp_Integer rem Base);
Temp_Integer := Temp_Integer / Base; Temp_Integer := Temp_Integer / Base;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* * * *
* C Header File * * C Header File *
* * * *
* Copyright (C) 1992-2007, Free Software Foundation, Inc. * * Copyright (C) 1992-2010, 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- *
...@@ -38,27 +38,42 @@ struct Uint_Entry ...@@ -38,27 +38,42 @@ struct Uint_Entry
#define UI_Is_In_Int_Range uintp__ui_is_in_int_range #define UI_Is_In_Int_Range uintp__ui_is_in_int_range
extern Boolean UI_Is_In_Int_Range (Uint); extern Boolean UI_Is_In_Int_Range (Uint);
/* Obtain Char_Code value from Uint input. Value must be in range. */ /* Obtain Char_Code value from Uint input. Value must be in range. */
#define UI_To_CC uintp__ui_to_cc #define UI_To_CC uintp__ui_to_cc
extern Char_Code UI_To_CC (Uint); extern Char_Code UI_To_CC (Uint);
/* Obtain Int value from Uint input. This will abort if the result is /* Convert a Char_Code into a Uint. */
out of range. */ #define UI_From_CC uintp__ui_from_cc
extern Uint UI_From_CC (Char_Code);
/* Obtain Int value from Uint input. Abort if the result is out of range. */
#define UI_To_Int uintp__ui_to_int #define UI_To_Int uintp__ui_to_int
extern Int UI_To_Int (Uint); extern Int UI_To_Int (Uint);
/* Similarly, but return a GCC INTEGER_CST. */
extern tree UI_To_gnu (Uint, tree);
/* Convert an Int into a Uint. */ /* Convert an Int into a Uint. */
#define UI_From_Int uintp__ui_from_int #define UI_From_Int uintp__ui_from_int
extern Uint UI_From_Int (int); extern Uint UI_From_Int (int);
/* Convert a Char_Code into a Uint. */ /* Similarly, but take a GCC INTEGER_CST. */
#define UI_From_CC uintp__ui_from_cc extern Uint UI_From_gnu (tree);
extern Uint UI_From_CC (Char_Code);
/* Similarly, but return a GCC INTEGER_CST. Overflow is tested by the /* Uint values are represented as multiple precision integers stored in a
constant-folding used to build the node. TYPE is the GCC type of the multi-digit format using UI_Base as the base. This value is chosen so
resulting node. */ that the product UI_Base*UI_Base is within the range of Int values. */
extern tree UI_To_gnu (Uint, tree); #define UI_Base uintp__base
extern const int UI_Base;
/* Types for the fat pointer of Int vectors and the template it points to. */
typedef struct {int Low_Bound, High_Bound; } Vector_Template;
typedef struct {const int *Array; Vector_Template *Bounds; }
__attribute ((aligned (sizeof (char *) * 2))) Int_Vector;
/* Create and return the Uint value from the Int vector. */
#define Vector_To_Uint uintp__vector_to_uint
extern Uint Vector_To_Uint (Int_Vector, Boolean);
/* Universal integers are represented by the Uint type which is an index into /* Universal integers are represented by the Uint type which is an index into
the Uints_Ptr table containing Uint_Entry values. A Uint_Entry contains an the Uints_Ptr table containing Uint_Entry values. A Uint_Entry contains an
...@@ -75,6 +90,3 @@ extern struct Uint_Entry *uintp__uints__table; ...@@ -75,6 +90,3 @@ extern struct Uint_Entry *uintp__uints__table;
#define Udigits_Ptr uintp__udigits__table #define Udigits_Ptr uintp__udigits__table
extern int *uintp__udigits__table; extern int *uintp__udigits__table;
#define Uint_0 (Uint_Direct_Bias + 0)
#define Uint_1 (Uint_Direct_Bias + 1)
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