Commit fb471a13 by Martin Sebor Committed by Jeff Law

gimple-fold.c (get_range_strlen_tree): Factored out of get_range_strlen.

	* gimple-fold.c (get_range_strlen_tree): Factored out of
	get_range_strlen.  Minor comment updates/additions.  Assert
	argument is not a simple SSA_NAME.
	(get_range_strlen): Call get_range_strlen_tree as appropriate.
	Minor comment updates/additions.

From-SVN: r267412
parent c1dd347c
2018-12-24 Martin Sebor <msebor@redhat.com>
* gimple-fold.c (get_range_strlen_tree): Factored out of
get_range_strlen. Minor comment updates/additions. Assert
argument is not a simple SSA_NAME.
(get_range_strlen): Call get_range_strlen_tree as appropriate.
Minor comment updates/additions.
2018-12-24 Jan Hubicka <hubicka@ucw.cz>
* ipa-devirt.c (dump_targets): Cap number of targets printed.
......@@ -66,6 +66,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree-vector-builder.h"
#include "tree-ssa-strlen.h"
static bool get_range_strlen (tree, tree[2], bitmap *, int,
int, bool *, unsigned, tree *);
/* Return true when DECL can be referenced from current unit.
FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
We can get declarations that are not possible to reference for various
......@@ -1258,42 +1261,21 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
return true;
}
/* Obtain the minimum and maximum string length or minimum and maximum
value of ARG in LENGTH[0] and LENGTH[1], respectively.
If ARG is an SSA name variable, follow its use-def chains. When
TYPE == 0, if LENGTH[1] is not equal to the length we determine or
if we are unable to determine the length or value, return false.
VISITED is a bitmap of visited variables.
TYPE is 0 if string length should be obtained, 1 for maximum string
length and 2 for maximum value ARG can have.
When FUZZY is non-zero and the length of a string cannot be determined,
the function instead considers as the maximum possible length the
size of a character array it may refer to. If FUZZY is 2, it will handle
PHIs and COND_EXPRs optimistically, if we can determine string length
minimum and maximum, it will use the minimum from the ones where it
can be determined.
Set *FLEXP to true if the range of the string lengths has been
obtained from the upper bound of an array at the end of a struct.
Such an array may hold a string that's longer than its upper bound
due to it being used as a poor-man's flexible array member.
Pass NONSTR through to children.
ELTSIZE is 1 for normal single byte character strings, and 2 or
4 for wide characer strings. ELTSIZE is by default 1. */
/* Helper of get_range_strlen for ARG that is not an SSA_NAME. */
static bool
get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, int type,
int fuzzy, bool *flexp, unsigned eltsize, tree *nonstr)
{
tree var, val = NULL_TREE;
gimple *def_stmt;
gcc_assert (TREE_CODE (arg) != SSA_NAME);
/* The minimum and maximum length. */
tree *const minlen = length;
tree *const maxlen = length + 1;
if (TREE_CODE (arg) != SSA_NAME)
{
/* The length computed by this invocation of the function. */
tree val = NULL_TREE;
/* We can end up with &(*iftmp_1)[0] here as well, so handle it. */
if (TREE_CODE (arg) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF)
......@@ -1328,6 +1310,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
if (type == 2)
{
/* We are computing the maximum value (not string length). */
val = arg;
if (TREE_CODE (val) != INTEGER_CST
|| tree_int_cst_sgn (val) < 0)
......@@ -1378,6 +1361,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
integer_one_node);
/* Set the minimum size to zero since the string in
the array could have zero length. */
*minlen = ssize_int (0);
......@@ -1417,6 +1401,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
return false;
val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
integer_one_node);
/* Set the minimum size to zero since the string in
the array could have zero length. */
*minlen = ssize_int (0);
......@@ -1437,6 +1422,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
return false;
val = wide_int_to_tree (TREE_TYPE (val),
wi::sub (wi::to_wide (val), 1));
/* Set the minimum size to zero since the string in
the array could have zero length. */
*minlen = ssize_int (0);
......@@ -1447,6 +1433,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
if (!val)
return false;
/* Adjust the lower bound on the string length as necessary. */
if (!*minlen
|| (type > 0
&& TREE_CODE (*minlen) == INTEGER_CST
......@@ -1456,6 +1443,8 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
if (*maxlen)
{
/* Adjust the more conservative bound if possible/necessary
and fail otherwise. */
if (type > 0)
{
if (TREE_CODE (*maxlen) != INTEGER_CST
......@@ -1467,12 +1456,47 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
return true;
}
else if (simple_cst_equal (val, *maxlen) != 1)
{
/* Fail if the length of this ARG is different from that
previously determined from another ARG. */
return false;
}
}
*maxlen = val;
return true;
}
}
/* Obtain the minimum and maximum string length or minimum and maximum
value of ARG in LENGTH[0] and LENGTH[1], respectively.
If ARG is an SSA name variable, follow its use-def chains. When
TYPE == 0, if LENGTH[1] is not equal to the length we determine or
if we are unable to determine the length or value, return false.
VISITED is a bitmap of visited variables.
TYPE is 0 if string length should be obtained, 1 for maximum string
length and 2 for maximum value ARG can have.
When FUZZY is non-zero and the length of a string cannot be determined,
the function instead considers as the maximum possible length the
size of a character array it may refer to. If FUZZY is 2, it will handle
PHIs and COND_EXPRs optimistically, if we can determine string length
minimum and maximum, it will use the minimum from the ones where it
can be determined.
Set *FLEXP to true if the range of the string lengths has been
obtained from the upper bound of an array at the end of a struct.
Such an array may hold a string that's longer than its upper bound
due to it being used as a poor-man's flexible array member.
Pass NONSTR through to children.
ELTSIZE is 1 for normal single byte character strings, and 2 or
4 for wide characer strings. ELTSIZE is by default 1. */
static bool
get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
int fuzzy, bool *flexp, unsigned eltsize, tree *nonstr)
{
if (TREE_CODE (arg) != SSA_NAME)
return get_range_strlen_tree (arg, length, visited, type, fuzzy, flexp,
eltsize, nonstr);
/* If ARG is registered for SSA update we cannot look at its defining
statement. */
......@@ -1485,8 +1509,11 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (arg)))
return true;
var = arg;
def_stmt = SSA_NAME_DEF_STMT (var);
tree var = arg;
gimple *def_stmt = SSA_NAME_DEF_STMT (var);
/* The minimum and maximum length. */
tree *const maxlen = length + 1;
switch (gimple_code (def_stmt))
{
......@@ -1550,7 +1577,6 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
return false;
}
}
/* Determine the minimum and maximum value or string length that ARG
refers to and store each in the first two elements of MINMAXLEN.
For expressions that point to strings of unknown lengths that are
......
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