Commit 730832cd by Martin Sebor Committed by Jeff Law

gimple-fold.c (get_range_strlen): Update prototype.

	* gimple-fold.c (get_range_strlen): Update prototype.
	(get_range_strlen_tree): Update prototype.  Drop minlen/maxlen
	local variables.  Use pdata to return information to caller.
	Update calls to get_range_strlen.  Update pdata->maxbound.
	(get_range_strlen -- static version): Similarly.
	(get_range_strlen -- extern version): Update for internal
	get_range_strlen API change.  Convert to external data format.
	(get_maxval_strlen): Similarly.

Co-Authored-By: Jeff Law <law@redhat.com>

From-SVN: r267498
parent 976cbbe1
2019-01-01 Martin Sebor <msebor@redhat.com>
Jeff Law <law@redhat.com>
* gimple-fold.c (get_range_strlen): Update prototype.
(get_range_strlen_tree): Update prototype. Drop minlen/maxlen
local variables. Use pdata to return information to caller.
Update calls to get_range_strlen. Update pdata->maxbound.
(get_range_strlen -- static version): Similarly.
(get_range_strlen -- extern version): Update for internal
get_range_strlen API change. Convert to external data format.
(get_maxval_strlen): Similarly.
2019-01-01 Jan Hubicka <hubicka@ucw.cz> 2019-01-01 Jan Hubicka <hubicka@ucw.cz>
* coverage.c (get_coverage_counts): Use current_function_decl. * coverage.c (get_coverage_counts): Use current_function_decl.
......
...@@ -83,8 +83,8 @@ enum strlen_range_kind { ...@@ -83,8 +83,8 @@ enum strlen_range_kind {
SRK_INT_VALUE SRK_INT_VALUE
}; };
static bool get_range_strlen (tree, tree[2], bitmap *, strlen_range_kind, static bool get_range_strlen (tree, bitmap *, strlen_range_kind,
bool *, unsigned, tree *); c_strlen_data *, bool *, unsigned);
/* Return true when DECL can be referenced from current unit. /* Return true when DECL can be referenced from current unit.
FROM_DECL (if non-null) specify constructor of variable DECL was taken from. FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
...@@ -1281,16 +1281,13 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len) ...@@ -1281,16 +1281,13 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
/* Helper of get_range_strlen for ARG that is not an SSA_NAME. */ /* Helper of get_range_strlen for ARG that is not an SSA_NAME. */
static bool static bool
get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, get_range_strlen_tree (tree arg, bitmap *visited,
strlen_range_kind rkind, strlen_range_kind rkind,
bool *flexp, unsigned eltsize, tree *nonstr) c_strlen_data *pdata,
bool *flexp, unsigned eltsize)
{ {
gcc_assert (TREE_CODE (arg) != SSA_NAME); gcc_assert (TREE_CODE (arg) != SSA_NAME);
/* The minimum and maximum length. */
tree *const minlen = length;
tree *const maxlen = length + 1;
/* The length computed by this invocation of the function. */ /* The length computed by this invocation of the function. */
tree val = NULL_TREE; tree val = NULL_TREE;
...@@ -1304,9 +1301,8 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, ...@@ -1304,9 +1301,8 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
tree aop0 = TREE_OPERAND (op, 0); tree aop0 = TREE_OPERAND (op, 0);
if (TREE_CODE (aop0) == INDIRECT_REF if (TREE_CODE (aop0) == INDIRECT_REF
&& TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME) && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME)
return get_range_strlen (TREE_OPERAND (aop0, 0), length, return get_range_strlen (TREE_OPERAND (aop0, 0), visited,
visited, rkind, flexp, rkind, pdata, flexp, eltsize);
eltsize, nonstr);
} }
else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF
&& (rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2)) && (rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2))
...@@ -1344,9 +1340,9 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, ...@@ -1344,9 +1340,9 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
bubble that information up to the caller. */ bubble that information up to the caller. */
if (!val && lendata.decl) if (!val && lendata.decl)
{ {
*nonstr = lendata.decl; pdata->decl = lendata.decl;
*minlen = lendata.minlen; pdata->minlen = lendata.minlen;
*maxlen = lendata.minlen; pdata->maxlen = lendata.minlen;
return rkind == SRK_STRLEN ? false : true; return rkind == SRK_STRLEN ? false : true;
} }
} }
...@@ -1354,9 +1350,8 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, ...@@ -1354,9 +1350,8 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
if (!val && (rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2)) if (!val && (rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2))
{ {
if (TREE_CODE (arg) == ADDR_EXPR) if (TREE_CODE (arg) == ADDR_EXPR)
return get_range_strlen (TREE_OPERAND (arg, 0), length, return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind,
visited, rkind, flexp, pdata, flexp, eltsize);
eltsize, nonstr);
if (TREE_CODE (arg) == ARRAY_REF) if (TREE_CODE (arg) == ARRAY_REF)
{ {
...@@ -1383,7 +1378,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, ...@@ -1383,7 +1378,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
/* Set the minimum size to zero since the string in /* Set the minimum size to zero since the string in
the array could have zero length. */ the array could have zero length. */
*minlen = ssize_int (0); pdata->minlen = ssize_int (0);
if (TREE_CODE (TREE_OPERAND (arg, 0)) == COMPONENT_REF if (TREE_CODE (TREE_OPERAND (arg, 0)) == COMPONENT_REF
&& optype == TREE_TYPE (TREE_OPERAND (arg, 0)) && optype == TREE_TYPE (TREE_OPERAND (arg, 0))
...@@ -1423,7 +1418,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, ...@@ -1423,7 +1418,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
/* Set the minimum size to zero since the string in /* Set the minimum size to zero since the string in
the array could have zero length. */ the array could have zero length. */
*minlen = ssize_int (0); pdata->minlen = ssize_int (0);
} }
if (VAR_P (arg)) if (VAR_P (arg))
...@@ -1444,7 +1439,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, ...@@ -1444,7 +1439,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
/* Set the minimum size to zero since the string in /* Set the minimum size to zero since the string in
the array could have zero length. */ the array could have zero length. */
*minlen = ssize_int (0); pdata->minlen = ssize_int (0);
} }
} }
} }
...@@ -1453,28 +1448,49 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, ...@@ -1453,28 +1448,49 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
return false; return false;
/* Adjust the lower bound on the string length as necessary. */ /* Adjust the lower bound on the string length as necessary. */
if (!*minlen if (!pdata->minlen
|| (rkind != SRK_STRLEN || (rkind != SRK_STRLEN
&& TREE_CODE (*minlen) == INTEGER_CST && TREE_CODE (pdata->minlen) == INTEGER_CST
&& TREE_CODE (val) == INTEGER_CST && TREE_CODE (val) == INTEGER_CST
&& tree_int_cst_lt (val, *minlen))) && tree_int_cst_lt (val, pdata->minlen)))
*minlen = val; pdata->minlen = val;
if (*maxlen) if (pdata->maxbound)
{
/* Adjust the tighter (more optimistic) string length bound
if necessary and proceed to adjust the more conservative
bound. */
if (TREE_CODE (val) == INTEGER_CST)
{
if (TREE_CODE (pdata->maxbound) == INTEGER_CST)
{
if (tree_int_cst_lt (pdata->maxbound, val))
pdata->maxbound = val;
}
else
pdata->maxbound = build_all_ones_cst (size_type_node);
}
else
pdata->maxbound = val;
}
else
pdata->maxbound = val;
if (pdata->maxlen)
{ {
/* Adjust the more conservative bound if possible/necessary /* Adjust the more conservative bound if possible/necessary
and fail otherwise. */ and fail otherwise. */
if (rkind != SRK_STRLEN) if (rkind != SRK_STRLEN)
{ {
if (TREE_CODE (*maxlen) != INTEGER_CST if (TREE_CODE (pdata->maxlen) != INTEGER_CST
|| TREE_CODE (val) != INTEGER_CST) || TREE_CODE (val) != INTEGER_CST)
return false; return false;
if (tree_int_cst_lt (*maxlen, val)) if (tree_int_cst_lt (pdata->maxlen, val))
*maxlen = val; pdata->maxlen = val;
return true; return true;
} }
else if (simple_cst_equal (val, *maxlen) != 1) else if (simple_cst_equal (val, pdata->maxlen) != 1)
{ {
/* Fail if the length of this ARG is different from that /* Fail if the length of this ARG is different from that
previously determined from another ARG. */ previously determined from another ARG. */
...@@ -1482,7 +1498,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, ...@@ -1482,7 +1498,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
} }
} }
*maxlen = val; pdata->maxlen = val;
return true; return true;
} }
...@@ -1500,14 +1516,13 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited, ...@@ -1500,14 +1516,13 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
Return true if *PDATA was successfully populated and false otherwise. */ Return true if *PDATA was successfully populated and false otherwise. */
static bool static bool
get_range_strlen (tree arg, tree length[2], bitmap *visited, get_range_strlen (tree arg, bitmap *visited,
strlen_range_kind rkind, strlen_range_kind rkind,
bool *flexp, unsigned eltsize, tree *nonstr) c_strlen_data *pdata, bool *flexp, unsigned eltsize)
{ {
if (TREE_CODE (arg) != SSA_NAME) if (TREE_CODE (arg) != SSA_NAME)
return get_range_strlen_tree (arg, length, visited, rkind, flexp, return get_range_strlen_tree (arg, visited, rkind, pdata, flexp, eltsize);
eltsize, nonstr);
/* If ARG is registered for SSA update we cannot look at its defining /* If ARG is registered for SSA update we cannot look at its defining
statement. */ statement. */
...@@ -1523,9 +1538,6 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, ...@@ -1523,9 +1538,6 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
tree var = arg; tree var = arg;
gimple *def_stmt = SSA_NAME_DEF_STMT (var); gimple *def_stmt = SSA_NAME_DEF_STMT (var);
/* The minimum and maximum length. */
tree *const maxlen = length + 1;
switch (gimple_code (def_stmt)) switch (gimple_code (def_stmt))
{ {
case GIMPLE_ASSIGN: case GIMPLE_ASSIGN:
...@@ -1536,8 +1548,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, ...@@ -1536,8 +1548,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
|| gimple_assign_unary_nop_p (def_stmt)) || gimple_assign_unary_nop_p (def_stmt))
{ {
tree rhs = gimple_assign_rhs1 (def_stmt); tree rhs = gimple_assign_rhs1 (def_stmt);
return get_range_strlen (rhs, length, visited, rkind, flexp, return get_range_strlen (rhs, visited, rkind, pdata, flexp, eltsize);
eltsize, nonstr);
} }
else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR) else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR)
{ {
...@@ -1545,8 +1556,8 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, ...@@ -1545,8 +1556,8 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
gimple_assign_rhs3 (def_stmt) }; gimple_assign_rhs3 (def_stmt) };
for (unsigned int i = 0; i < 2; i++) for (unsigned int i = 0; i < 2; i++)
if (!get_range_strlen (ops[i], length, visited, rkind, if (!get_range_strlen (ops[i], visited, rkind, pdata,
flexp, eltsize, nonstr)) flexp, eltsize))
{ {
if (rkind != SRK_LENRANGE_2) if (rkind != SRK_LENRANGE_2)
return false; return false;
...@@ -1558,7 +1569,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, ...@@ -1558,7 +1569,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
in fact zero can be determined from MAXLEN being in fact zero can be determined from MAXLEN being
unbounded but the discovered minimum is used for unbounded but the discovered minimum is used for
diagnostics. */ diagnostics. */
*maxlen = build_all_ones_cst (size_type_node); pdata->maxlen = build_all_ones_cst (size_type_node);
} }
return true; return true;
} }
...@@ -1580,8 +1591,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, ...@@ -1580,8 +1591,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
if (arg == gimple_phi_result (def_stmt)) if (arg == gimple_phi_result (def_stmt))
continue; continue;
if (!get_range_strlen (arg, length, visited, rkind, flexp, if (!get_range_strlen (arg, visited, rkind, pdata, flexp, eltsize))
eltsize, nonstr))
{ {
if (rkind != SRK_LENRANGE_2) if (rkind != SRK_LENRANGE_2)
return false; return false;
...@@ -1593,7 +1603,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, ...@@ -1593,7 +1603,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
in fact zero can be determined from MAXLEN being in fact zero can be determined from MAXLEN being
unbounded but the discovered minimum is used for unbounded but the discovered minimum is used for
diagnostics. */ diagnostics. */
*maxlen = build_all_ones_cst (size_type_node); pdata->maxlen = build_all_ones_cst (size_type_node);
} }
} }
return true; return true;
...@@ -1642,14 +1652,21 @@ get_range_strlen (tree arg, tree minmaxlen[2], unsigned eltsize, ...@@ -1642,14 +1652,21 @@ get_range_strlen (tree arg, tree minmaxlen[2], unsigned eltsize,
*nonstr = NULL_TREE; *nonstr = NULL_TREE;
bool flexarray = false; bool flexarray = false;
if (!get_range_strlen (arg, minmaxlen, &visited, c_strlen_data lendata = { };
if (!get_range_strlen (arg, &visited,
strict ? SRK_LENRANGE : SRK_LENRANGE_2, strict ? SRK_LENRANGE : SRK_LENRANGE_2,
&flexarray, eltsize, nonstr)) &lendata, &flexarray, eltsize))
{ {
minmaxlen[0] = NULL_TREE; minmaxlen[0] = NULL_TREE;
minmaxlen[1] = NULL_TREE; minmaxlen[1] = NULL_TREE;
} }
else
{
minmaxlen[0] = lendata.minlen;
minmaxlen[1] = lendata.maxlen;
}
*nonstr = lendata.decl;
if (visited) if (visited)
BITMAP_FREE (visited); BITMAP_FREE (visited);
...@@ -1674,13 +1691,11 @@ get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL) ...@@ -1674,13 +1691,11 @@ get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL)
gcc_assert (rkind != SRK_INT_VALUE || INTEGRAL_TYPE_P (TREE_TYPE (arg))); gcc_assert (rkind != SRK_INT_VALUE || INTEGRAL_TYPE_P (TREE_TYPE (arg)));
bitmap visited = NULL; bitmap visited = NULL;
tree len[2] = { NULL_TREE, NULL_TREE };
bool dummy; bool dummy;
/* Set to non-null if ARG refers to an untermianted array. */ c_strlen_data lendata = { };
tree mynonstr = NULL_TREE; if (!get_range_strlen (arg, &visited, rkind, &lendata, &dummy, 1))
if (!get_range_strlen (arg, len, &visited, rkind, &dummy, 1, &mynonstr)) lendata.maxlen = NULL_TREE;
len[1] = NULL_TREE;
if (visited) if (visited)
BITMAP_FREE (visited); BITMAP_FREE (visited);
...@@ -1689,12 +1704,12 @@ get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL) ...@@ -1689,12 +1704,12 @@ get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL)
/* For callers prepared to handle unterminated arrays set /* For callers prepared to handle unterminated arrays set
*NONSTR to point to the declaration of the array and return *NONSTR to point to the declaration of the array and return
the maximum length/size. */ the maximum length/size. */
*nonstr = mynonstr; *nonstr = lendata.decl;
return len[1]; return lendata.maxlen;
} }
/* Fail if the constant array isn't nul-terminated. */ /* Fail if the constant array isn't nul-terminated. */
return mynonstr ? NULL_TREE : len[1]; return lendata.decl ? NULL_TREE : lendata.maxlen;
} }
......
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