From 8ab78162c0dfc65aef769516ba77560566577113 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 27 Oct 2015 20:16:04 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 20 ++++++++++++++++++-- gcc/gimple.c | 3 ++- gcc/gimple.h | 15 +++++++++++++++ gcc/internal-fn.c | 24 ++++++++++++++++++++++++ gcc/internal-fn.def | 7 +++++++ gcc/internal-fn.h | 5 +++++ gcc/target-insns.def | 1 + gcc/tracer.c | 21 ++++++++++++++------- gcc/tree-cfg.c | 6 +++++- gcc/tree-ssa-threadedge.c | 7 +++++++ 10 files changed, 98 insertions(+), 11 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 369a5821fd1..19a6809e8d4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2015-10-27 Nathan Sidwell + + * 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 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 diff --git a/gcc/gimple.c b/gcc/gimple.c index 5312d6e055d..d7ce18749d2 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 (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 02d0db59752..781801b7c4a 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 (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 f12d3aff96a..ff5a90dc502 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 305cf1b858c..e181bccf52d 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 2ff3347241f..521e4af2647 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 00e00273cd0..d79fdf21db8 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 11d5f94ec67..074a96a3972 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 40d5eb89ed7..970207d04d2 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 38f80ba14fc..68fd4ef17ec 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 (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++; -- 2.30.2