diff options
author | Nathan Sidwell <nathan@gcc.gnu.org> | 2015-10-27 20:16:04 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2015-10-27 20:16:04 +0000 |
commit | 8ab78162c0dfc65aef769516ba77560566577113 (patch) | |
tree | bd71d653036a68ca09bc7d09522690d5e4988df5 /gcc | |
parent | a271b387e6375d5612a2bd8669e0da1ac731e9c3 (diff) | |
download | gcc-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/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/gimple.c | 3 | ||||
-rw-r--r-- | gcc/gimple.h | 15 | ||||
-rw-r--r-- | gcc/internal-fn.c | 24 | ||||
-rw-r--r-- | gcc/internal-fn.def | 7 | ||||
-rw-r--r-- | gcc/internal-fn.h | 5 | ||||
-rw-r--r-- | gcc/target-insns.def | 1 | ||||
-rw-r--r-- | gcc/tracer.c | 21 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 6 | ||||
-rw-r--r-- | gcc/tree-ssa-threadedge.c | 7 |
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++; |