From patchwork Tue Jul 30 17:13:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 263449 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 5C6D52C00AB for ; Wed, 31 Jul 2013 03:13:56 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; q=dns; s=default; b=xlyZlNyeXyrMU4M9L 54NWq6gBlQHk39Vs3b3F0S/4oLgmQbdOPHse/f8mSnapvbH+a9a6SowtNCFVK4PF +3lkRa9bFzZMiBBSgtq0hu1UPesXwf8c/4eD2I6qNUt4/TsfIbocChdPjcPGFuT5 d55Meio9RAIshdN9PVLxLzjas8= 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 :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; s=default; bh=O3Jk3kTHEEP9RAluNrV9Rzp 27fc=; b=PZ7CrDjSCf3YOy94iPIsUNftJqDFEbBWEGlppC52Ip5hZ+yaLVDZWKV Q7JLoUxpuYI9f2zDOPyT5HODcRkc6QZUQ6StHkETC1PXLLR6HbRXRyaoNle4+u7p iczGgQctuDn2KoxItdRaj13kajHIJ7A9NwX1cUpIbNkQWGBHW31k= Received: (qmail 26963 invoked by alias); 30 Jul 2013 17:13:49 -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 26932 invoked by uid 89); 30 Jul 2013 17:13:48 -0000 X-Spam-SWARE-Status: No, score=-5.0 required=5.0 tests=AWL, BAYES_50, KHOP_THREADED, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RDNS_NONE, SPF_HELO_PASS, SPF_PASS autolearn=no version=3.3.1 Received: from Unknown (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Tue, 30 Jul 2013 17:13:47 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r6UHDdn6009245 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 30 Jul 2013 13:13:39 -0400 Received: from [10.10.61.198] (vpn-61-198.rdu2.redhat.com [10.10.61.198]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r6UHDcj7025462 for ; Tue, 30 Jul 2013 13:13:38 -0400 Message-ID: <51F7F442.8050202@redhat.com> Date: Tue, 30 Jul 2013 13:13:38 -0400 From: Andrew MacLeod User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130514 Thunderbird/17.0.6 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/5] Atomic type qualifier - Add atomic type to tree node References: <51F2AEB1.60408@redhat.com> <51F7EE86.20805@redhat.com> In-Reply-To: <51F7EE86.20805@redhat.com> X-Virus-Found: No This patch adds an atomic qualifier to the type node. it sets up atomic{QHSDT}I_type_node types upon startup and used the alignment target hook to override alignment if need be. Whenever new atomic types are created, they will inherit this alignment setting if they would otherwise be aligned to a lower boundry. The middle end is also taught to treat decls that are atomic much the way we handle volatile... ie, "don't really try to optimize this thing". Adnrew * tree.h (struct tree_base): Add atomic_flag field. (TYPE_ATOMIC): New accessor macro. (enum cv_qualifier): Add TYPE_QUAL_ATOMIC. (TYPE_QUALS, TYPE_QUALS_NO_ADDR_SPACE): Add TYPE_QUAL_ATOMIC. (TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC): New macro. (enum tree_index): Add TI_ATOMIC{QHSDT}I_TYPE. (atomic{QHSDT}I_type_node): Add new type nodes. * emit-rtl.c (set_mem_attributes_minus_bitpos): Atomics are volatile. * function.c (assign_stack_temp_for_type): Atomics are volatile. * print-tree.c (print_node): Print atomic qualifier. * tree-pretty-print.c (dump_generic_node): Print atomic type attribute. * tree.c (set_type_quals): Set TYPE_ATOMIC. (find_atomic_core_type): New. Function to get atomic type from size. (build_qualified_type): Tweak for atomic qualifier overrides. (build_atomic_variant): New. Build atomic variant node. (build_common_tree_nodes): Build atomic{QHSDT}I_type_node, allowing for override with target hook. * alias.c (objects_must_conflict_p): Treat atomics as volatile. * calls.c (expand_call): Treat atomics as volatile. Index: gcc/tree.h =================================================================== *** gcc/tree.h (revision 201248) --- gcc/tree.h (working copy) *************** struct GTY(()) tree_base { *** 457,463 **** unsigned packed_flag : 1; unsigned user_align : 1; unsigned nameless_flag : 1; ! unsigned spare0 : 4; unsigned spare1 : 8; --- 457,464 ---- unsigned packed_flag : 1; unsigned user_align : 1; unsigned nameless_flag : 1; ! unsigned atomic_flag : 1; ! unsigned spare0 : 3; unsigned spare1 : 8; *************** extern enum machine_mode vector_type_mod *** 2205,2210 **** --- 2206,2214 ---- /* Nonzero in a type considered volatile as a whole. */ #define TYPE_VOLATILE(NODE) (TYPE_CHECK (NODE)->base.volatile_flag) + /* Nonzero in a type considered atomic as a whole. */ + #define TYPE_ATOMIC(NODE) (TYPE_CHECK (NODE)->base.u.bits.atomic_flag) + /* Means this type is const-qualified. */ #define TYPE_READONLY(NODE) (TYPE_CHECK (NODE)->base.readonly_flag) *************** enum cv_qualifier *** 2226,2232 **** TYPE_UNQUALIFIED = 0x0, TYPE_QUAL_CONST = 0x1, TYPE_QUAL_VOLATILE = 0x2, ! TYPE_QUAL_RESTRICT = 0x4 }; /* Encode/decode the named memory support as part of the qualifier. If more --- 2230,2237 ---- TYPE_UNQUALIFIED = 0x0, TYPE_QUAL_CONST = 0x1, TYPE_QUAL_VOLATILE = 0x2, ! TYPE_QUAL_RESTRICT = 0x4, ! TYPE_QUAL_ATOMIC = 0x8 }; /* Encode/decode the named memory support as part of the qualifier. If more *************** enum cv_qualifier *** 2245,2250 **** --- 2250,2256 ---- #define TYPE_QUALS(NODE) \ ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \ | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \ + | (TYPE_ATOMIC (NODE) * TYPE_QUAL_ATOMIC) \ | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT) \ | (ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (NODE))))) *************** enum cv_qualifier *** 2252,2259 **** --- 2258,2273 ---- #define TYPE_QUALS_NO_ADDR_SPACE(NODE) \ ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \ | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \ + | (TYPE_ATOMIC (NODE) * TYPE_QUAL_ATOMIC) \ + | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT))) + /* The same as TYPE_QUALS without the address space and atomic + qualifications. */ + #define TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC(NODE) \ + ((int) ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \ + | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \ | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT))) + /* These flags are available for each language front end to use internally. */ #define TYPE_LANG_FLAG_0(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_0) #define TYPE_LANG_FLAG_1(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_1) *************** enum tree_index *** 4178,4183 **** --- 4192,4203 ---- TI_UINTDI_TYPE, TI_UINTTI_TYPE, + TI_ATOMICQI_TYPE, + TI_ATOMICHI_TYPE, + TI_ATOMICSI_TYPE, + TI_ATOMICDI_TYPE, + TI_ATOMICTI_TYPE, + TI_UINT16_TYPE, TI_UINT32_TYPE, TI_UINT64_TYPE, *************** extern GTY(()) tree global_trees[TI_MAX] *** 4334,4339 **** --- 4354,4365 ---- #define unsigned_intDI_type_node global_trees[TI_UINTDI_TYPE] #define unsigned_intTI_type_node global_trees[TI_UINTTI_TYPE] + #define atomicQI_type_node global_trees[TI_ATOMICQI_TYPE] + #define atomicHI_type_node global_trees[TI_ATOMICHI_TYPE] + #define atomicSI_type_node global_trees[TI_ATOMICSI_TYPE] + #define atomicDI_type_node global_trees[TI_ATOMICDI_TYPE] + #define atomicTI_type_node global_trees[TI_ATOMICTI_TYPE] + #define uint16_type_node global_trees[TI_UINT16_TYPE] #define uint32_type_node global_trees[TI_UINT32_TYPE] #define uint64_type_node global_trees[TI_UINT64_TYPE] Index: gcc/emit-rtl.c =================================================================== *** gcc/emit-rtl.c (revision 201248) --- gcc/emit-rtl.c (working copy) *************** set_mem_attributes_minus_bitpos (rtx ref *** 1607,1613 **** front-end routine) and use it. */ attrs.alias = get_alias_set (t); ! MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type); MEM_POINTER (ref) = POINTER_TYPE_P (type); /* Default values from pre-existing memory attributes if present. */ --- 1607,1613 ---- front-end routine) and use it. */ attrs.alias = get_alias_set (t); ! MEM_VOLATILE_P (ref) |= (TYPE_VOLATILE (type) || TYPE_ATOMIC (type)); MEM_POINTER (ref) = POINTER_TYPE_P (type); /* Default values from pre-existing memory attributes if present. */ Index: gcc/function.c =================================================================== *** gcc/function.c (revision 201248) --- gcc/function.c (working copy) *************** assign_stack_temp_for_type (enum machine *** 901,907 **** /* If a type is specified, set the relevant flags. */ if (type != 0) ! MEM_VOLATILE_P (slot) = TYPE_VOLATILE (type); MEM_NOTRAP_P (slot) = 1; return slot; --- 901,907 ---- /* If a type is specified, set the relevant flags. */ if (type != 0) ! MEM_VOLATILE_P (slot) = (TYPE_VOLATILE (type) || TYPE_ATOMIC (type)); MEM_NOTRAP_P (slot) = 1; return slot; Index: gcc/print-tree.c =================================================================== *** gcc/print-tree.c (revision 201248) --- gcc/print-tree.c (working copy) *************** print_node (FILE *file, const char *pref *** 304,309 **** --- 304,311 ---- if (TYPE_P (node) ? TYPE_READONLY (node) : TREE_READONLY (node)) fputs (" readonly", file); + if (TYPE_P (node) ? TYPE_ATOMIC (node) : TYPE_ATOMIC (node)) + fputs (" atomic", file); if (!TYPE_P (node) && TREE_CONSTANT (node)) fputs (" constant", file); else if (TYPE_P (node) && TYPE_SIZES_GIMPLIFIED (node)) Index: gcc/tree-pretty-print.c =================================================================== *** gcc/tree-pretty-print.c (revision 201248) --- gcc/tree-pretty-print.c (working copy) *************** dump_generic_node (pretty_printer *buffe *** 679,684 **** --- 679,686 ---- unsigned int quals = TYPE_QUALS (node); enum tree_code_class tclass; + if (quals & TYPE_QUAL_ATOMIC) + pp_string (buffer, "atomic "); if (quals & TYPE_QUAL_CONST) pp_string (buffer, "const "); else if (quals & TYPE_QUAL_VOLATILE) *************** dump_generic_node (pretty_printer *buffe *** 980,985 **** --- 982,989 ---- { unsigned int quals = TYPE_QUALS (node); + if (quals & TYPE_QUAL_ATOMIC) + pp_string (buffer, "atomic "); if (quals & TYPE_QUAL_CONST) pp_string (buffer, "const "); if (quals & TYPE_QUAL_VOLATILE) Index: gcc/tree.c =================================================================== *** gcc/tree.c (revision 201248) --- gcc/tree.c (working copy) *************** set_type_quals (tree type, int type_qual *** 5937,5942 **** --- 5937,5943 ---- TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0; TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0; TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0; + TYPE_ATOMIC (type) = (type_quals & TYPE_QUAL_ATOMIC) != 0; TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals); } *************** check_aligned_type (const_tree cand, con *** 5970,5975 **** --- 5971,6018 ---- TYPE_ATTRIBUTES (base))); } + /* This function checks to see if TYPE matches the size one of the built-in + atomic types, and returns that core atomic type. */ + + tree + find_atomic_core_type (tree type) + { + tree base_atomic_type; + + /* Only handle complete types. */ + if (TYPE_SIZE (type) == NULL_TREE) + return NULL_TREE; + + HOST_WIDE_INT type_size = tree_low_cst (TYPE_SIZE (type), 1); + switch (type_size) + { + case 8: + base_atomic_type = atomicQI_type_node; + break; + + case 16: + base_atomic_type = atomicHI_type_node; + break; + + case 32: + base_atomic_type = atomicSI_type_node; + break; + + case 64: + base_atomic_type = atomicDI_type_node; + break; + + case 128: + base_atomic_type = atomicTI_type_node; + break; + + default: + base_atomic_type = NULL_TREE; + } + + return base_atomic_type; + } + /* Return a version of the TYPE, qualified as indicated by the TYPE_QUALS, if one exists. If no qualified version exists yet, return NULL_TREE. */ *************** build_qualified_type (tree type, int typ *** 6009,6014 **** --- 6052,6070 ---- t = build_variant_type_copy (type); set_type_quals (t, type_quals); + if (((type_quals & TYPE_QUAL_ATOMIC) == TYPE_QUAL_ATOMIC)) + { + /* See if this object can map to a basic atomic type. */ + tree atomic_type = find_atomic_core_type (type); + if (atomic_type) + { + /* Ensure the alignment of this type is compatible with + the required alignment of the atomic type. */ + if (TYPE_ALIGN (atomic_type) > TYPE_ALIGN (t)) + TYPE_ALIGN (t) = TYPE_ALIGN (atomic_type); + } + } + if (TYPE_STRUCTURAL_EQUALITY_P (type)) /* Propagate structural equality. */ SET_TYPE_STRUCTURAL_EQUALITY (t); *************** make_or_reuse_accum_type (unsigned size, *** 9521,9526 **** --- 9577,9607 ---- return make_accum_type (size, unsignedp, satp); } + + /* Create an atomic variant node for TYPE. This routine is called during + initialization of data types to create the 5 basic atomic types. The generic + build_variant_type function requires these to already be set up in order to + function properly, so cannot be called from there. + if ALIGN is non-zero, then ensure alignment is overridden to this value. */ + + static tree + build_atomic_variant (tree type, unsigned int align) + { + tree t; + + /* Make sure its not already registered. */ + if ((t = get_qualified_type (type, TYPE_QUAL_ATOMIC))) + return t; + + t = build_variant_type_copy (type); + set_type_quals (t, TYPE_QUAL_ATOMIC); + + if (align) + TYPE_ALIGN (t) = align; + + return t; + } + /* Create nodes for all integer types (and error_mark_node) using the sizes of C datatypes. SIGNED_CHAR specifies whether char is signed, SHORT_DOUBLE specifies whether double should be of the same precision *************** build_common_tree_nodes (bool signed_cha *** 9603,9608 **** --- 9684,9704 ---- unsigned_intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 1); unsigned_intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 1); + /* Dont call build_qualified type for atomics. That routine does special + processing for atomics, and until they are initialized its better not + to make that call. + + Check to see if there is a target override for atomic types. */ + + #define SET_ATOMIC_TYPE_NODE(TYPE, MODE, DEFAULT) \ + (TYPE) = build_atomic_variant (DEFAULT, targetm.atomic_align_for_mode (MODE)); + + SET_ATOMIC_TYPE_NODE (atomicQI_type_node, QImode, unsigned_intQI_type_node); + SET_ATOMIC_TYPE_NODE (atomicHI_type_node, HImode, unsigned_intHI_type_node); + SET_ATOMIC_TYPE_NODE (atomicSI_type_node, SImode, unsigned_intSI_type_node); + SET_ATOMIC_TYPE_NODE (atomicDI_type_node, DImode, unsigned_intDI_type_node); + SET_ATOMIC_TYPE_NODE (atomicTI_type_node, TImode, unsigned_intTI_type_node); + access_public_node = get_identifier ("public"); access_protected_node = get_identifier ("protected"); access_private_node = get_identifier ("private"); Index: gcc/alias.c =================================================================== *** gcc/alias.c (revision 201248) --- gcc/alias.c (working copy) *************** objects_must_conflict_p (tree t1, tree t *** 486,493 **** /* If they are the same type, they must conflict. */ if (t1 == t2 ! /* Likewise if both are volatile. */ ! || (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2))) return 1; set1 = t1 ? get_alias_set (t1) : 0; --- 486,494 ---- /* If they are the same type, they must conflict. */ if (t1 == t2 ! /* Likewise if both are volatile or atomic. */ ! || (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2)) ! || (t1 != 0 && TYPE_ATOMIC (t1) && t2 != 0 && TYPE_ATOMIC (t2))) return 1; set1 = t1 ? get_alias_set (t1) : 0; Index: gcc/calls.c =================================================================== *** gcc/calls.c (revision 201248) --- gcc/calls.c (working copy) *************** expand_call (tree exp, rtx target, int i *** 2592,2597 **** --- 2592,2598 ---- optimized. */ || (flags & (ECF_RETURNS_TWICE | ECF_NORETURN)) || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr))) + || TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (addr))) /* If the called function is nested in the current one, it might access some of the caller's arguments, but could clobber them beforehand if the argument areas are shared. */