summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2016-07-14 12:15:38 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2016-07-14 12:15:38 +0000
commit97f2a90b456288a59d1458941eb9d2f2747885a3 (patch)
treee63596b59c87415b491b0e9c85ffdeff0cdb6f3d
parent8e033d4ff5d8f4930a4e6296676a4748ecac6d74 (diff)
downloadgcc-97f2a90b456288a59d1458941eb9d2f2747885a3.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@238334 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71866.c40
-rw-r--r--gcc/tree-ssa-pre.c117
-rw-r--r--gcc/tree-ssa-sccvn.c31
-rw-r--r--gcc/tree-ssa-sccvn.h1
6 files changed, 109 insertions, 99 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a1cf7424d9d..24b929812b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+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>
PR target/71733
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c5a737926a1..6c85d55bcad 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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>
* gcc.target/arm/pr42574.c: Add missing target keyword for the dg-do
diff --git a/gcc/testsuite/gcc.dg/torture/pr71866.c b/gcc/testsuite/gcc.dg/torture/pr71866.c
new file mode 100644
index 00000000000..e1b36cb8b7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr71866.c
@@ -0,0 +1,40 @@
+/* { 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));
+}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index a5f3f712da1..518346aa8f2 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -1164,29 +1164,6 @@ get_or_alloc_expr_for_constant (tree constant)
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.
Currently only supports constants and SSA_NAMES. */
static pre_expr
@@ -1236,76 +1213,16 @@ fully_constant_expression (pre_expr e)
case NARY:
{
vn_nary_op_t nary = PRE_EXPR_NARY (e);
- switch (TREE_CODE_CLASS (nary->opcode))
- {
- case tcc_binary:
- case tcc_comparison:
- {
- /* We have to go from trees to pre exprs to value ids to
- constants. */
- tree naryop0 = nary->op[0];
- tree naryop1 = nary->op[1];
- tree result;
- 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;
- }
+ tree res = vn_nary_simplify (nary);
+ if (!res)
+ return e;
+ if (is_gimple_min_invariant (res))
+ return get_or_alloc_expr_for_constant (res);
+ /* 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 REFERENCE:
{
@@ -3618,10 +3535,18 @@ do_hoist_insertion (basic_block block)
gimple_seq stmts = NULL;
tree res = create_expression_by_pieces (block, expr, &stmts,
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
- 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
failed but also make sure to insert any stmts produced as they
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 9427bfc6062..bd752a5eccd 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -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
- 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
-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;
/* We will be creating a value number for
@@ -1658,7 +1660,7 @@ vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops)
else
{
tree val = vn_lookup_simplify_result (rcode, type, ops);
- if (!val)
+ if (!val && insert)
{
gimple_seq stmts = NULL;
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)
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
from the statement defining VUSE and if not successful tries to
translate *REFP and VR_ through an aggregate copy at the definition
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index 069590a0b01..92c255d93d2 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -234,6 +234,7 @@ unsigned int get_constant_value_id (tree);
unsigned int get_or_alloc_constant_value_id (tree);
bool value_id_constant_p (unsigned int);
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. */