aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@gcc.gnu.org>2015-10-27 20:16:04 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2015-10-27 20:16:04 +0000
commit8ab78162c0dfc65aef769516ba77560566577113 (patch)
treebd71d653036a68ca09bc7d09522690d5e4988df5 /gcc
parenta271b387e6375d5612a2bd8669e0da1ac731e9c3 (diff)
downloadgcc-8ab78162c0dfc65aef769516ba77560566577113.zip
gcc-8ab78162c0dfc65aef769516ba77560566577113.tar.gz
gcc-8ab78162c0dfc65aef769516ba77560566577113.tar.bz2
internal-fn.c (expand_UNIQUE): New.
* internal-fn.c (expand_UNIQUE): New. * internal-fn.h (enum ifn_unique_kind): New. * internal-fn.def (IFN_UNIQUE): New. * target-insns.def (unique): Define. * gimple.h (gimple_call_internal_unique_p): New. * gimple.c (gimple_call_same_target_p): Check internal fn uniqueness. * tracer.c (ignore_bb_p): Check for IFN_UNIQUE call. * tree-ssa-threadedge.c (record_temporary_equivalences_from_stmts): Likewise. * tree-cfg.c (gmple_call_initialize_ctrl_altering): Likewise. From-SVN: r229459
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/gimple.c3
-rw-r--r--gcc/gimple.h15
-rw-r--r--gcc/internal-fn.c24
-rw-r--r--gcc/internal-fn.def7
-rw-r--r--gcc/internal-fn.h5
-rw-r--r--gcc/target-insns.def1
-rw-r--r--gcc/tracer.c21
-rw-r--r--gcc/tree-cfg.c6
-rw-r--r--gcc/tree-ssa-threadedge.c7
10 files changed, 98 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 369a582..19a6809 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2015-10-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * internal-fn.c (expand_UNIQUE): New.
+ * internal-fn.h (enum ifn_unique_kind): New.
+ * internal-fn.def (IFN_UNIQUE): New.
+ * target-insns.def (unique): Define.
+ * gimple.h (gimple_call_internal_unique_p): New.
+ * gimple.c (gimple_call_same_target_p): Check internal fn
+ uniqueness.
+ * tracer.c (ignore_bb_p): Check for IFN_UNIQUE call.
+ * tree-ssa-threadedge.c
+ (record_temporary_equivalences_from_stmts): Likewise.
+ * tree-cfg.c (gmple_call_initialize_ctrl_altering): Likewise.
+
2015-10-27 Richard Henderson <rth@redhat.com>
PR rtl-opt/67609
@@ -29,8 +43,10 @@
* graphite-optimize-isl.c (get_schedule_for_node_st): New callback
function to schedule based on isl_schedule_node.
- (get_schedule_map_st): New schedule optimizer based on isl_schedule_node.
- (scop_get_domains): New. Return the isl_union_set containing the domains of all the pbbs.
+ (get_schedule_map_st): New schedule optimizer based on
+ isl_schedule_node.
+ (scop_get_domains): New. Return the isl_union_set containing the
+ domains of all the pbbs.
(optimize_isl): Call the new function get_schedule_map_st for isl-0.15
2015-10-27 H.J. Lu <hongjiu.lu@intel.com>
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 5312d6e..d7ce187 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1346,7 +1346,8 @@ gimple_call_same_target_p (const gimple *c1, const gimple *c2)
{
if (gimple_call_internal_p (c1))
return (gimple_call_internal_p (c2)
- && gimple_call_internal_fn (c1) == gimple_call_internal_fn (c2));
+ && gimple_call_internal_fn (c1) == gimple_call_internal_fn (c2)
+ && !gimple_call_internal_unique_p (as_a <const gcall *> (c1)));
else
return (gimple_call_fn (c1) == gimple_call_fn (c2)
|| (gimple_call_fndecl (c1)
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 02d0db5..781801b 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -2895,6 +2895,21 @@ gimple_call_internal_fn (const gimple *gs)
return gimple_call_internal_fn (gc);
}
+/* Return true, if this internal gimple call is unique. */
+
+static inline bool
+gimple_call_internal_unique_p (const gcall *gs)
+{
+ return gimple_call_internal_fn (gs) == IFN_UNIQUE;
+}
+
+static inline bool
+gimple_call_internal_unique_p (const gimple *gs)
+{
+ const gcall *gc = GIMPLE_CHECK2<const gcall *> (gs);
+ return gimple_call_internal_unique_p (gc);
+}
+
/* If CTRL_ALTERING_P is true, mark GIMPLE_CALL S to be a stmt
that could alter control flow. */
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index f12d3af..ff5a90d 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -1958,6 +1958,30 @@ expand_VA_ARG (gcall *stmt ATTRIBUTE_UNUSED)
gcc_unreachable ();
}
+/* Expand the IFN_UNIQUE function according to its first argument. */
+
+static void
+expand_UNIQUE (gcall *stmt)
+{
+ rtx pattern = NULL_RTX;
+ enum ifn_unique_kind kind
+ = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (stmt, 0));
+
+ switch (kind)
+ {
+ default:
+ gcc_unreachable ();
+
+ case IFN_UNIQUE_UNSPEC:
+ if (targetm.have_unique ())
+ pattern = targetm.gen_unique ();
+ break;
+ }
+
+ if (pattern)
+ emit_insn (pattern);
+}
+
/* Routines to expand each internal function, indexed by function number.
Each routine has the prototype:
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 305cf1b..e181bcc 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -65,3 +65,10 @@ DEF_INTERNAL_FN (SUB_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (MUL_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (TSAN_FUNC_EXIT, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (VA_ARG, ECF_NOTHROW | ECF_LEAF, NULL)
+
+/* An unduplicable, uncombinable function. Generally used to preserve
+ a CFG property in the face of jump threading, tail merging or
+ other such optimizations. The first argument distinguishes
+ between uses. See internal-fn.h for usage. */
+DEF_INTERNAL_FN (UNIQUE, ECF_NOTHROW, NULL)
+
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index 2ff3347..521e4af 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -20,6 +20,11 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_INTERNAL_FN_H
#define GCC_INTERNAL_FN_H
+/* INTEGER_CST values for IFN_UNIQUE function arg-0. */
+enum ifn_unique_kind {
+ IFN_UNIQUE_UNSPEC /* Undifferentiated UNIQUE. */
+};
+
/* Initialize internal function tables. */
extern void init_internal_fns ();
diff --git a/gcc/target-insns.def b/gcc/target-insns.def
index 00e0027..d79fdf2 100644
--- a/gcc/target-insns.def
+++ b/gcc/target-insns.def
@@ -89,5 +89,6 @@ DEF_TARGET_INSN (stack_protect_test, (rtx x0, rtx x1, rtx x2))
DEF_TARGET_INSN (store_multiple, (rtx x0, rtx x1, rtx x2))
DEF_TARGET_INSN (tablejump, (rtx x0, rtx x1))
DEF_TARGET_INSN (trap, (void))
+DEF_TARGET_INSN (unique, (void))
DEF_TARGET_INSN (untyped_call, (rtx x0, rtx x1, rtx x2))
DEF_TARGET_INSN (untyped_return, (rtx x0, rtx x1))
diff --git a/gcc/tracer.c b/gcc/tracer.c
index 11d5f94..074a96a 100644
--- a/gcc/tracer.c
+++ b/gcc/tracer.c
@@ -93,18 +93,25 @@ bb_seen_p (basic_block bb)
static bool
ignore_bb_p (const_basic_block bb)
{
- gimple *g;
-
if (bb->index < NUM_FIXED_BLOCKS)
return true;
if (optimize_bb_for_size_p (bb))
return true;
- /* A transaction is a single entry multiple exit region. It must be
- duplicated in its entirety or not at all. */
- g = last_stmt (CONST_CAST_BB (bb));
- if (g && gimple_code (g) == GIMPLE_TRANSACTION)
- return true;
+ if (gimple *g = last_stmt (CONST_CAST_BB (bb)))
+ {
+ /* A transaction is a single entry multiple exit region. It
+ must be duplicated in its entirety or not at all. */
+ if (gimple_code (g) == GIMPLE_TRANSACTION)
+ return true;
+
+ /* An IFN_UNIQUE call must be duplicated as part of its group,
+ or not at all. */
+ if (is_gimple_call (g)
+ && gimple_call_internal_p (g)
+ && gimple_call_internal_unique_p (g))
+ return true;
+ }
return false;
}
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 40d5eb8..970207d 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -487,7 +487,11 @@ gimple_call_initialize_ctrl_altering (gimple *stmt)
|| ((flags & ECF_TM_BUILTIN)
&& is_tm_ending_fndecl (gimple_call_fndecl (stmt)))
/* BUILT_IN_RETURN call is same as return statement. */
- || gimple_call_builtin_p (stmt, BUILT_IN_RETURN))
+ || gimple_call_builtin_p (stmt, BUILT_IN_RETURN)
+ /* IFN_UNIQUE should be the last insn, to make checking for it
+ as cheap as possible. */
+ || (gimple_call_internal_p (stmt)
+ && gimple_call_internal_unique_p (stmt)))
gimple_call_set_ctrl_altering (stmt, true);
else
gimple_call_set_ctrl_altering (stmt, false);
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 38f80ba..68fd4ef 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -247,6 +247,13 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
&& gimple_asm_volatile_p (as_a <gasm *> (stmt)))
return NULL;
+ /* If the statement is a unique builtin, we can not thread
+ through here. */
+ if (gimple_code (stmt) == GIMPLE_CALL
+ && gimple_call_internal_p (stmt)
+ && gimple_call_internal_unique_p (stmt))
+ return NULL;
+
/* If duplicating this block is going to cause too much code
expansion, then do not thread through this block. */
stmt_count++;