From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 127435 invoked by alias); 25 Oct 2017 21:31:40 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 127419 invoked by uid 89); 25 Oct 2017 21:31:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=implications, primitive X-HELO: mail-wm0-f47.google.com Received: from mail-wm0-f47.google.com (HELO mail-wm0-f47.google.com) (74.125.82.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 25 Oct 2017 21:31:38 +0000 Received: by mail-wm0-f47.google.com with SMTP id b9so4527640wmh.0 for ; Wed, 25 Oct 2017 14:31:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:cc:subject:references :date:in-reply-to:message-id:user-agent:mime-version; bh=sjYw4M2e14Xda9grXRVZ/Zi9tWivx4wT0piz66V2eYo=; b=oTUjmsmbP62jEmIXtxgRNxMAXFwSagavkLWFG4zDxjgnW2T9oirmuwHdUFQOOXhSxq YTtI0poHsA3IHwgLWtNnNmi6WvLiSvNcSV7uGwkieyeIrAXvQjhNuv/+0QMu2p/gXVZm +BnZV5FOV0E6ZVmoRQ6K5hhVe6r6i3QuevsClfKpoCbMPoBUKQZFRr49q2lnF/qXZnkq 2Ya+lcnxlVsgG77nFygQDm32SmPodUsvga7timrdxaiacLOc4uuq+ee0OrZUEyTwmVUy UlZCQgIjwCpdyKlHMwENXG/Ds+WWK8fgYxspG3tYxbgZ6JDSI14RBAr8cqkl0DxaTFY8 4DcA== X-Gm-Message-State: AMCzsaUOLLc5y94TIc4x0Ctxxv2F6QSIXdGZax6f/nF3oOEC8K2rFm8o hW2yP/2QEZoFusNJm4JcdGTrywi0awg= X-Google-Smtp-Source: ABhQp+TK7rk6K81P/eomYw0ZjngD0jmeaPP9sjqH9ga99fdFPuCcl7kwRQYV/c4s/V66Rb1kVqpv1A== X-Received: by 10.28.140.13 with SMTP id o13mr3158355wmd.150.1508967096344; Wed, 25 Oct 2017 14:31:36 -0700 (PDT) Received: from localhost ([2.26.27.199]) by smtp.gmail.com with ESMTPSA id p28sm7740650wmf.2.2017.10.25.14.31.34 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 25 Oct 2017 14:31:35 -0700 (PDT) From: Richard Sandiford To: Martin Sebor Mail-Followup-To: Martin Sebor ,gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Cc: gcc-patches@gcc.gnu.org Subject: Re: [006/nnn] poly_int: tree constants References: <871sltvm7r.fsf@linaro.org> <878tg1u7cl.fsf@linaro.org> Date: Wed, 25 Oct 2017 21:35:00 -0000 In-Reply-To: (Martin Sebor's message of "Wed, 25 Oct 2017 10:59:54 -0600") Message-ID: <877evi3oeh.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2017-10/txt/msg01852.txt.bz2 Martin Sebor writes: > On 10/23/2017 11:00 AM, Richard Sandiford wrote: >> +#if NUM_POLY_INT_COEFFS == 1 >> +extern inline __attribute__ ((__gnu_inline__)) poly_int64 >> +tree_to_poly_int64 (const_tree t) > > I'm curious about the extern inline and __gnu_inline__ here and > not in poly_int_tree_p below. Am I correct in assuming that > the combination is a holdover from the days when GCC was compiled > using a C compiler, and that the way to write the same definition > in C++ 98 is simply: > > inline poly_int64 > tree_to_poly_int64 (const_tree t) > >> +{ >> + gcc_assert (tree_fits_poly_int64_p (t)); >> + return TREE_INT_CST_LOW (t); >> +} > > If yes, I would suggest to use the C++ form (and at some point, > changing the existing uses of the GCC/C idiom to the C++ form > as well). > > Otherwise, if something requires the use of the C form I would > suggest to add a brief comment explaining it. You probably saw that this is based on tree_to_[su]hwi. AIUI the differences from plain C++ inline are that: a) with __gnu_inline__, an out-of-line definition must still exist. That fits this use case well, because the inline is conditional on the #ifdef and tree.c has an out-of-line definition either way. If we used normal inline, we'd need to add extra #ifs to tree.c as well, to avoid multiple definitions. b) __gnu_inline__ has the strength of __always_inline__, but without the correctness implications if inlining is impossible for any reason. I did try normal inline first, but it wasn't strong enough. The compiler ended up measurably faster if I copied the tree_to_[su]hwi approach. > ... >> + >> +inline bool >> +poly_int_tree_p (const_tree t, poly_int64_pod *value) >> +{ > ... [This one is unconditionally inline.] >> /* The tree and const_tree overload templates. */ >> namespace wi >> { >> + class unextended_tree >> + { >> + private: >> + const_tree m_t; >> + >> + public: >> + unextended_tree () {} > > Defining no-op ctors is quite dangerous and error-prone. I suggest > to instead default initialize the member(s): > > unextended_tree (): m_t () {} > > Ditto everywhere else, such as in: This is really performance-senesitive code though, so I don't think we want to add any unnecessary initialisation. Primitive types are uninitalised by default too, and the point of this class is to provide an integer-like interface. In your other message you used the example of explicit default initialisation, such as: class foo { foo () : x () {} unextended_tree x; }; But I think we should strongly discourage that kind of thing. If someone wants to initialise x to a particular value, like integer_zero_node, then it would be better to do it explicitly. If they don't care what the initial value is, then for these integer-mimicing classes, uninitialised is as good as anything else. :-) Note that for this class NULL_TREE is not a safe default value. The same goes for the wide-int.h classes, where a length or precision of 0 is undefined and isn't necessarily going to be handled gracefully or predictably. >> template >> class extended_tree >> { >> @@ -5139,11 +5225,13 @@ extern bool anon_aggrname_p (const_tree) >> const_tree m_t; >> >> public: >> + extended_tree () {} >> extended_tree (const_tree); > ... >> Index: gcc/tree.c >> =================================================================== > ... >> + >> +/* Return true if T holds a polynomial pointer difference, storing it in >> + *VALUE if so. A true return means that T's precision is no greater >> + than 64 bits, which is the largest address space we support, so *VALUE >> + never loses precision. However, the signedness of the result is >> + somewhat arbitrary, since if B lives near the end of a 64-bit address >> + range and A lives near the beginning, B - A is a large positive value >> + outside the range of int64_t. A - B is likewise a large negative value >> + outside the range of int64_t. All the pointer difference really >> + gives is a raw pointer-sized bitstring that can be added to the first >> + pointer value to get the second. */ > > I'm not sure I understand the comment about the sign correctly, but > if I do, I don't think it's correct. > > Because their difference wouldn't representable in any basic integer > type (i.,e., in ptrdiff_t) the pointers described above could never > point to the same object (or array), and so their difference is not > meaningful. C/C++ only define the semantics of a difference between > pointers to the same object. That restricts the size of the largest > possible object typically to SIZE_MAX / 2, or at most SIZE_MAX on > the handful of targets where ptrdiff_t has greater precision than > size_t. But even on those targets, the difference between any two > pointers to the same object must be representable in ptrdiff_t, > including the sign. But does that apply even when no pointer difference of that size occurs in the original source? I.e., is: char *x = malloc (0x80000001) undefined in itself on 32-bit targets? Does it become undefined after: for (unsigned int i = 0; i < 0x80000001; ++i) x[i++] = 0; where no large pointer difference is calculated? But I realise gcc's support for this kind of thing is limited, and that we do try to emit a diagnostic for obvious instances... In the (two) places that need this -- both conversions from cst_and_fits_in_hwi -- the immediate problem is that the sign of the type doesn't necessarily match the logical sign of the difference. E.g. a negative offset can be represented as a large unsigned value of sizetype. Thanks, Richard