Commit 351168fe by Richard Biener Committed by Richard Biener

re PR tree-optimization/71866 (gcc locks up after fix for PR70159)

2016-07-14  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/71866
	* tree-ssa-pre.c (get_constant_for_value_id): Remove.
	(do_hoist_insertion): Avoid endless recursion when we
	didn't insert anything because we managed to simplify
	things down to a constant or SSA name.
	(fully_constant_expression): Re-write in terms of ...
	* tree-ssa-sccvn.h (vn_nary_simplify): ... this.  Declare.
	* tree-ssa-sccvn.c (vn_nary_simplify): New wrapper around
	vn_nary_build_or_lookup_1.
	(vn_nary_build_or_lookup_1): Added flag and renamed from ...
	(vn_nary_build_or_lookup): ... this which now wraps it.

	* gcc.dg/torture/pr71866.c: New testcase.

From-SVN: r238334
parent 8234d02a
2016-07-14 Richard Biener <rguenther@suse.de>
PR tree-optimization/71866
* tree-ssa-pre.c (get_constant_for_value_id): Remove.
(do_hoist_insertion): Avoid endless recursion when we
didn't insert anything because we managed to simplify
things down to a constant or SSA name.
(fully_constant_expression): Re-write in terms of ...
* tree-ssa-sccvn.h (vn_nary_simplify): ... this. Declare.
* tree-ssa-sccvn.c (vn_nary_simplify): New wrapper around
vn_nary_build_or_lookup_1.
(vn_nary_build_or_lookup_1): Added flag and renamed from ...
(vn_nary_build_or_lookup): ... this which now wraps it.
2016-07-14 Alan Modra <amodra@gmail.com> 2016-07-14 Alan Modra <amodra@gmail.com>
PR target/71733 PR target/71733
......
2016-07-14 Richard Biener <rguenther@suse.de>
PR tree-optimization/71866
* gcc.dg/torture/pr71866.c: New testcase.
2016-07-14 Thomas Preud'homme <thomas.preudhomme@arm.com> 2016-07-14 Thomas Preud'homme <thomas.preudhomme@arm.com>
* gcc.target/arm/pr42574.c: Add missing target keyword for the dg-do * gcc.target/arm/pr42574.c: Add missing target keyword for the dg-do
......
/* { dg-do compile } */
/* { dg-additional-options "-ftree-pre -fcode-hoisting" } */
typedef unsigned char u8;
extern unsigned long pci_io_base;
u8 in_8 (const volatile void *);
int eeh_enabled ();
void eeh_check_failure ();
static inline
u8 eeh_readb(const volatile void *addr)
{
u8 val = in_8(addr);
if (((val) == (u8)~0 && eeh_enabled())) eeh_check_failure();
return val;
}
extern struct ppc_pci_io {
void (*outb) (u8 val, unsigned long port);
}
ppc_pci_io;
static inline
u8 readb (const volatile void * addr)
{
return eeh_readb((addr));
}
static inline
u8 inb (unsigned long port)
{
return readb((volatile void *)pci_io_base + port);
}
static inline
void outb (u8 val, unsigned long port)
{
if (ppc_pci_io.outb != ((void *)0)) ppc_pci_io.outb (val, port);
};
void frob_econtrol(unsigned long base_hi, unsigned char m, unsigned char v)
{
unsigned char ectr = 0;
if (m != 0xff) ectr = inb((base_hi + 0x2));
outb((ectr & ~m) ^ v, (base_hi + 0x2));
}
...@@ -1164,29 +1164,6 @@ get_or_alloc_expr_for_constant (tree constant) ...@@ -1164,29 +1164,6 @@ get_or_alloc_expr_for_constant (tree constant)
return newexpr; return newexpr;
} }
/* Given a value id V, find the actual tree representing the constant
value if there is one, and return it. Return NULL if we can't find
a constant. */
static tree
get_constant_for_value_id (unsigned int v)
{
if (value_id_constant_p (v))
{
unsigned int i;
bitmap_iterator bi;
bitmap exprset = value_expressions[v];
EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi)
{
pre_expr expr = expression_for_id (i);
if (expr->kind == CONSTANT)
return PRE_EXPR_CONSTANT (expr);
}
}
return NULL;
}
/* Get or allocate a pre_expr for a piece of GIMPLE, and return it. /* Get or allocate a pre_expr for a piece of GIMPLE, and return it.
Currently only supports constants and SSA_NAMES. */ Currently only supports constants and SSA_NAMES. */
static pre_expr static pre_expr
...@@ -1236,76 +1213,16 @@ fully_constant_expression (pre_expr e) ...@@ -1236,76 +1213,16 @@ fully_constant_expression (pre_expr e)
case NARY: case NARY:
{ {
vn_nary_op_t nary = PRE_EXPR_NARY (e); vn_nary_op_t nary = PRE_EXPR_NARY (e);
switch (TREE_CODE_CLASS (nary->opcode)) tree res = vn_nary_simplify (nary);
{ if (!res)
case tcc_binary: return e;
case tcc_comparison: if (is_gimple_min_invariant (res))
{ return get_or_alloc_expr_for_constant (res);
/* We have to go from trees to pre exprs to value ids to /* We might have simplified the expression to a
constants. */ SSA_NAME for example from x_1 * 1. But we cannot
tree naryop0 = nary->op[0]; insert a PHI for x_1 unconditionally as x_1 might
tree naryop1 = nary->op[1]; not be available readily. */
tree result; return e;
if (!is_gimple_min_invariant (naryop0))
{
pre_expr rep0 = get_or_alloc_expr_for (naryop0);
unsigned int vrep0 = get_expr_value_id (rep0);
tree const0 = get_constant_for_value_id (vrep0);
if (const0)
naryop0 = fold_convert (TREE_TYPE (naryop0), const0);
}
if (!is_gimple_min_invariant (naryop1))
{
pre_expr rep1 = get_or_alloc_expr_for (naryop1);
unsigned int vrep1 = get_expr_value_id (rep1);
tree const1 = get_constant_for_value_id (vrep1);
if (const1)
naryop1 = fold_convert (TREE_TYPE (naryop1), const1);
}
result = fold_binary (nary->opcode, nary->type,
naryop0, naryop1);
if (result && is_gimple_min_invariant (result))
return get_or_alloc_expr_for_constant (result);
/* We might have simplified the expression to a
SSA_NAME for example from x_1 * 1. But we cannot
insert a PHI for x_1 unconditionally as x_1 might
not be available readily. */
return e;
}
case tcc_reference:
if (nary->opcode != REALPART_EXPR
&& nary->opcode != IMAGPART_EXPR
&& nary->opcode != VIEW_CONVERT_EXPR)
return e;
/* Fallthrough. */
case tcc_unary:
{
/* We have to go from trees to pre exprs to value ids to
constants. */
tree naryop0 = nary->op[0];
tree const0, result;
if (is_gimple_min_invariant (naryop0))
const0 = naryop0;
else
{
pre_expr rep0 = get_or_alloc_expr_for (naryop0);
unsigned int vrep0 = get_expr_value_id (rep0);
const0 = get_constant_for_value_id (vrep0);
}
result = NULL;
if (const0)
{
tree type1 = TREE_TYPE (nary->op[0]);
const0 = fold_convert (type1, const0);
result = fold_unary (nary->opcode, nary->type, const0);
}
if (result && is_gimple_min_invariant (result))
return get_or_alloc_expr_for_constant (result);
return e;
}
default:
return e;
}
} }
case REFERENCE: case REFERENCE:
{ {
...@@ -3618,10 +3535,18 @@ do_hoist_insertion (basic_block block) ...@@ -3618,10 +3535,18 @@ do_hoist_insertion (basic_block block)
gimple_seq stmts = NULL; gimple_seq stmts = NULL;
tree res = create_expression_by_pieces (block, expr, &stmts, tree res = create_expression_by_pieces (block, expr, &stmts,
get_expr_type (expr)); get_expr_type (expr));
if (gsi_end_p (last) || is_ctrl_stmt (gsi_stmt (last)))
gsi_insert_seq_before (&last, stmts, GSI_SAME_STMT); /* Do not return true if expression creation ultimately
did not insert any statements. */
if (gimple_seq_empty_p (stmts))
res = NULL_TREE;
else else
gsi_insert_seq_after (&last, stmts, GSI_NEW_STMT); {
if (gsi_end_p (last) || is_ctrl_stmt (gsi_stmt (last)))
gsi_insert_seq_before (&last, stmts, GSI_SAME_STMT);
else
gsi_insert_seq_after (&last, stmts, GSI_NEW_STMT);
}
/* Make sure to not return true if expression creation ultimately /* Make sure to not return true if expression creation ultimately
failed but also make sure to insert any stmts produced as they failed but also make sure to insert any stmts produced as they
......
...@@ -1625,10 +1625,12 @@ vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops) ...@@ -1625,10 +1625,12 @@ vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops)
} }
/* Return a value-number for RCODE OPS... either by looking up an existing /* Return a value-number for RCODE OPS... either by looking up an existing
value-number for the simplified result or by inserting the operation. */ value-number for the simplified result or by inserting the operation if
INSERT is true. */
static tree static tree
vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops) vn_nary_build_or_lookup_1 (code_helper rcode, tree type, tree *ops,
bool insert)
{ {
tree result = NULL_TREE; tree result = NULL_TREE;
/* We will be creating a value number for /* We will be creating a value number for
...@@ -1658,7 +1660,7 @@ vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops) ...@@ -1658,7 +1660,7 @@ vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops)
else else
{ {
tree val = vn_lookup_simplify_result (rcode, type, ops); tree val = vn_lookup_simplify_result (rcode, type, ops);
if (!val) if (!val && insert)
{ {
gimple_seq stmts = NULL; gimple_seq stmts = NULL;
result = maybe_push_res_to_seq (rcode, type, ops, &stmts); result = maybe_push_res_to_seq (rcode, type, ops, &stmts);
...@@ -1719,6 +1721,29 @@ vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops) ...@@ -1719,6 +1721,29 @@ vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops)
return result; return result;
} }
/* Return a value-number for RCODE OPS... either by looking up an existing
value-number for the simplified result or by inserting the operation. */
static tree
vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops)
{
return vn_nary_build_or_lookup_1 (rcode, type, ops, true);
}
/* Try to simplify the expression RCODE OPS... of type TYPE and return
its value if present. */
tree
vn_nary_simplify (vn_nary_op_t nary)
{
if (nary->length > 3)
return NULL_TREE;
tree ops[3];
memcpy (ops, nary->op, sizeof (tree) * nary->length);
return vn_nary_build_or_lookup_1 (nary->opcode, nary->type, ops, false);
}
/* Callback for walk_non_aliased_vuses. Tries to perform a lookup /* Callback for walk_non_aliased_vuses. Tries to perform a lookup
from the statement defining VUSE and if not successful tries to from the statement defining VUSE and if not successful tries to
translate *REFP and VR_ through an aggregate copy at the definition translate *REFP and VR_ through an aggregate copy at the definition
......
...@@ -234,6 +234,7 @@ unsigned int get_constant_value_id (tree); ...@@ -234,6 +234,7 @@ unsigned int get_constant_value_id (tree);
unsigned int get_or_alloc_constant_value_id (tree); unsigned int get_or_alloc_constant_value_id (tree);
bool value_id_constant_p (unsigned int); bool value_id_constant_p (unsigned int);
tree fully_constant_vn_reference_p (vn_reference_t); tree fully_constant_vn_reference_p (vn_reference_t);
tree vn_nary_simplify (vn_nary_op_t);
/* Valueize NAME if it is an SSA name, otherwise just return it. */ /* Valueize NAME if it is an SSA name, otherwise just return it. */
......
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