From patchwork Sun Oct 25 14:18:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 535583 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 432D5140D7F for ; Mon, 26 Oct 2015 01:18:55 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=vhuzBQ3L; 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=vGOQRBmMRSTp1M9dB MX4HOoJtkqlqmMWnWyB3J7XVZEjVNXqPA+G4ahTUmj1dYxmI4/VyYzaC2qhD5id7 METrJZ6TwXQOz1yo67xB+zUBLUtGa4g0MAcXKYI8uKMEsX/6T4LEvud5bxfDCFfY a/ILMKo0KVIK1129v2oQ5jUc8E= 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=UEB5fKcDfe+qjT2rrg56QSN 4ifI=; b=vhuzBQ3LOYRf3XW//iLxuRgK5x9GBzy8EsweZnexoZxawirruQUUMUi YSpaf4pY7VvaBrtbam8iB/tyueHKchS78K4eAHKQapMTQV4K4ODO+igjEIAfW9uq vLIK4P23R1DqGqxh6esNOq/UMK+hMArKTZ/BjJeeqMY5gHxmz5Ac= Received: (qmail 5102 invoked by alias); 25 Oct 2015 14:18:48 -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 5089 invoked by uid 89); 25 Oct 2015 14:18:47 -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-yk0-f176.google.com Received: from mail-yk0-f176.google.com (HELO mail-yk0-f176.google.com) (209.85.160.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sun, 25 Oct 2015 14:18:45 +0000 Received: by ykdr3 with SMTP id r3so161476770ykd.1 for ; Sun, 25 Oct 2015 07:18:43 -0700 (PDT) X-Received: by 10.129.104.195 with SMTP id d186mr14345430ywc.13.1445782723509; Sun, 25 Oct 2015 07:18:43 -0700 (PDT) Received: from ?IPv6:2600:1000:b00c:599b:a2a8:cdff:fe3e:b48? ([2600:1000:b00c:599b:a2a8:cdff:fe3e:b48]) by smtp.googlemail.com with ESMTPSA id c71sm12167365ywb.42.2015.10.25.07.18.42 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 25 Oct 2015 07:18:43 -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> Cc: Richard Biener , GCC Patches , Bernd Schmidt , Jason Merrill , "Joseph S. Myers" From: Nathan Sidwell Message-ID: <562CE4C1.3090705@acm.org> Date: Sun, 25 Oct 2015 10:18:41 -0400 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: <20151023130313.GG478@tucnak.redhat.com> Richard, Jakub, here is an updated patch. Changes from previous version 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. I'll be posting an updated 7/11 patch shortly. comments? nathan 2015-10-25 Nathan Sidwell * internal-fn.c (expand_UNIQUE): New. * internal-fn.h (enum ifn_unique_kind): New. * internal-fn.def (IFN_UNIQUE): New. * 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/tree-ssa-threadedge.c =================================================================== --- gcc/tree-ssa-threadedge.c (revision 229276) +++ gcc/tree-ssa-threadedge.c (working copy) @@ -283,6 +283,17 @@ 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) + { + gcall *call = as_a (stmt); + + if (gimple_call_internal_p (call) + && gimple_call_internal_unique_p (call)) + 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/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/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; + int code = TREE_INT_CST_LOW (gimple_call_arg (stmt, 0)); + + switch (code) + { + default: + gcc_unreachable (); + + case IFN_UNIQUE_UNSPEC: +#ifdef HAVE_unique + pattern = gen_unique (); +#endif + 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/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-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);