From patchwork Mon Oct 26 22:32:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 536332 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 872071412FD for ; Tue, 27 Oct 2015 09:32:59 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=O1DIBzG/; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=rS4DHFe7oscLIAYgi j3bZEqc1AtxX+lMRxtPUUvrkRz+Z9XoJl6SHc+KnhZugTEGklV/ru/GyfS5KMvCY gs7QWlUw8vXk1btYxnYv7n3UmSpwPyPnByM7kSSxlbvU072DtfTlK9ZucZD9emkl v794XNQghW+vaOKlBb4NiFl14w= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=v0uZ9l2p3N7DY3BVkGv7xSg +LV8=; b=O1DIBzG/Rep97lrlhyL7PrV0jpnuGKgDJZ60aIDXTk7TYTdwrQDBMqm FqQz7CDMHdzRJXjoNwkLCtspefQcqNI28EC4oAyu8LdjuEnX7vOmePdWAM4SDKce lHvqtKd7UdjnhvDHJhQppBH5x7DMgBON9EsXij/dVjKr401fZxIU= Received: (qmail 19578 invoked by alias); 26 Oct 2015 22:32:52 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 19567 invoked by uid 89); 26 Oct 2015 22:32:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.9 required=5.0 tests=BAYES_50, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 X-HELO: mail-pa0-f45.google.com Received: from mail-pa0-f45.google.com (HELO mail-pa0-f45.google.com) (209.85.220.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Mon, 26 Oct 2015 22:32:49 +0000 Received: by pasz6 with SMTP id z6so200415002pas.2 for ; Mon, 26 Oct 2015 15:32:47 -0700 (PDT) X-Received: by 10.68.94.69 with SMTP id da5mr24736706pbb.63.1445898767802; Mon, 26 Oct 2015 15:32:47 -0700 (PDT) Received: from ?IPv6:2600:1012:b115:101e:a2a8:cdff:fe3e:b48? ([2600:1012:b115:101e:a2a8:cdff:fe3e:b48]) by smtp.googlemail.com with ESMTPSA id zn9sm36030373pac.48.2015.10.26.15.32.46 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 26 Oct 2015 15:32:47 -0700 (PDT) Subject: Re: [OpenACC 1/11] UNIQUE internal function To: Jakub Jelinek References: <5627DD78.9040302@acm.org> <5627E0DF.9050507@acm.org> <20151022080444.GC478@tucnak.redhat.com> <5628EC53.9090006@acm.org> <562925BE.805@acm.org> <20151023082545.GA478@tucnak.redhat.com> <562A2EAD.2020802@acm.org> <20151023130313.GG478@tucnak.redhat.com> <562CE4C1.3090705@acm.org> Cc: Richard Biener , GCC Patches , Bernd Schmidt , Jason Merrill , "Joseph S. Myers" From: Nathan Sidwell Message-ID: <562EAA0D.4040203@acm.org> Date: Mon, 26 Oct 2015 15:32:45 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <562CE4C1.3090705@acm.org> Richard, Jakub, this updates patch 1 to use the target-insns.def mechanism of detecting conditionally-implemented instructions. Otherwise it's the same as yesterday's patch. To recap: 1) Moved the subcodes to an enumeration in internal-fn.h 2) Remove ECF_LEAF 3) Added check in initialize_ctrl_altering 4) tracer code now (continues) to only look in last stmt of block I looked at fnsplit and do not believe I need changes there. That's changing things like: if (cheap test) do cheap thing else do complex thing to break out the else part into a separate function. That's fine -- it'll copy the whole CFG of interest. ok? nathan 2015-10-26 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. Index: gcc/target-insns.def =================================================================== --- gcc/target-insns.def (revision 229276) +++ gcc/target-insns.def (working copy) @@ -89,5 +93,6 @@ DEF_TARGET_INSN (stack_protect_test, (rt 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)) Index: gcc/gimple.c =================================================================== --- gcc/gimple.c (revision 229276) +++ gcc/gimple.c (working copy) @@ -1346,7 +1346,8 @@ gimple_call_same_target_p (const gimple { 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) Index: gcc/gimple.h =================================================================== --- gcc/gimple.h (revision 229276) +++ gcc/gimple.h (working copy) @@ -2895,6 +2895,21 @@ gimple_call_internal_fn (const gimple *g 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. */ Index: gcc/internal-fn.c =================================================================== --- gcc/internal-fn.c (revision 229276) +++ gcc/internal-fn.c (working copy) @@ -1958,6 +1958,30 @@ expand_VA_ARG (gcall *stmt ATTRIBUTE_UNU 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: Index: gcc/internal-fn.h =================================================================== --- gcc/internal-fn.h (revision 229276) +++ gcc/internal-fn.h (working copy) @@ -20,6 +20,11 @@ along with GCC; see the file COPYING3. #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 (); Index: gcc/internal-fn.def =================================================================== --- gcc/internal-fn.def (revision 229276) +++ gcc/internal-fn.def (working copy) @@ -65,3 +65,10 @@ DEF_INTERNAL_FN (SUB_OVERFLOW, ECF_CONST 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) Index: gcc/tracer.c =================================================================== --- gcc/tracer.c (revision 229276) +++ gcc/tracer.c (working copy) @@ -93,18 +93,24 @@ 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; } Index: gcc/tree-ssa-threadedge.c =================================================================== --- gcc/tree-ssa-threadedge.c (revision 229276) +++ gcc/tree-ssa-threadedge.c (working copy) @@ -283,6 +283,13 @@ record_temporary_equivalences_from_stmts && 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++; Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (revision 229276) +++ gcc/tree-cfg.c (working copy) @@ -487,7 +487,11 @@ gimple_call_initialize_ctrl_altering (gi || ((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);