public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Martin Sebor <msebor@gmail.com>
To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com
Subject: Re: [07/23] Add a class that multiplexes two pointer types
Date: Fri, 27 Nov 2020 17:17:12 -0700	[thread overview]
Message-ID: <e77128da-b910-439e-37f6-8f98578c6751@gmail.com> (raw)
In-Reply-To: <mpty2iof3o3.fsf@arm.com>

On 11/26/20 10:06 AM, Richard Sandiford wrote:
> Martin Sebor <msebor@gmail.com> writes:
>> I do have one concern: the tendency to prioritize efficiency
>> over safety (this can be said about most GCC code). Specifically
>> in this class, the address bit twiddling makes me uneasy.  I don't
>> think the object model in either language (certainly not C but
>> I don't have the impression C++ either) makes it unequivocally
>> valid.  On the contrary, I'd say many of us interpret the current
>> rules as leaving it undefined.  There are efforts to sanction
>> this sort of thing under some conditions (e.g, the C object
>> model proposal) but they have not been adopted yet.  I think
>> we should try to avoid exploiting these dark corners in new
>> code.
> 
> I'd tried to stick to operations that I thought were well-defined.
> The primitives being used are really:
> 
> (1) convert a T1* or T2* to char*
> (2) increment an unincremented char*
> (3) decrement an incremented char*
> (4) convert a char* back to T1* or T2*
> (5) convert a char* to an intptr_t in order to test its low bit

All those are valid as long as the pointer points into the same
object, both before and after.

> I thought (1) and (4) were allowed.  At least, [basic.compound] says
> that void* must be able to hold any object pointer and that it must have
> the same representation as char*, so I thought the conversion in (1) was
> guaranteed to be representable.  And (4) only ever undoes (1): it only
> converts the result of (1) back to the original pointer type.
> 
> For (2) and (3), the incremented pointer will still be within the
> containing object, so I thought it would be well-defined.  Here too,
> (3) only ever undoes (2): it only decrements a pointer that had
> previously been incremented.
> 
> One thing I'd deliberately tried to avoid was converting integers
> “back” to pointers, because that seemed like a more dangerous thing.
> That's why:
> 
>>> +template<typename T1, typename T2>
>>> +inline T2 *
>>> +pointer_mux<T1, T2>::second_or_null () const
>>> +{
>>> +  // Micro optimization that's effective as of GCC 11: compute the value
>>> +  // of the second pointer as an integer and test that, so that the integer
>>> +  // result can be reused as the pointer and so that all computation can
>>> +  // happen before a branch on null.  This reduces the number of branches
>>> +  // needed for loops.
>>> +  return uintptr_t (m_ptr - 1) & 1 ? nullptr : known_second ();

This is only valid if m_ptr points to the second byte of an object.
If it points to the first byte of A then it's invalid.  This would
make the test valid but the result strictly unspecified (though in
practice I'd expect it to do what you expect):

   return (uintptr_t (m_ptr) - 1) & 1 ? nullptr : known_second ();

>>> +}
> 
> is written in a somewhat indirect way.
> 
> Are your concerns with the primitives above, or is the problem with
> something else?

My initial impression was that the code stored information in
the least significant bits of the pointer.  Now that I've looked
at it again I still think it does that, except not directly but
indirectly, by storing a pointer to either the first byte of one
object (A) or to the second byte of another (B).  Correct?  (If
so, I would recommend to expand the documentation to make this
clearer.)

It's clever (a little too clever for my taste) but other than
the m_ptr - 1 part above I can't think of anything undefined
about it.  My main concern also wasn't with the bit twiddling
as such but with hiding the identity of the objects by manipulating
the representation of the pointers via integer operations.  Since
(if) the code doesn't really do that, it may be less of a problem
than I thought.

Martin

  parent reply	other threads:[~2020-11-28  0:17 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-13  8:10 [00/23] Make fwprop use an on-the-side RTL SSA representation Richard Sandiford
2020-11-13  8:11 ` [01/23] vec: Silence clang warning Richard Sandiford
2020-11-25 19:58   ` Jeff Law
2020-11-13  8:12 ` [02/23] rtlanal: Remove noop_move_p REG_EQUAL condition Richard Sandiford
2020-11-25 20:00   ` Jeff Law
2020-11-13  8:12 ` [03/23] reginfo: Add a global_reg_set Richard Sandiford
2020-11-25 20:01   ` Jeff Law
2020-11-13  8:13 ` [04/23] Move iterator_range to a new iterator-utils.h file Richard Sandiford
2020-11-25 20:02   ` Jeff Law
2020-11-13  8:13 ` [05/23] Add more iterator utilities Richard Sandiford
2020-11-25 20:12   ` Jeff Law
2020-11-13  8:14 ` [06/23] Add an RAII class for managing obstacks Richard Sandiford
2020-11-25 20:15   ` Jeff Law
2020-11-13  8:14 ` [07/23] Add a class that multiplexes two pointer types Richard Sandiford
2020-11-25 20:23   ` Jeff Law
2020-11-26 16:15     ` Richard Sandiford
2020-11-30  1:28       ` Jeff Law
2020-11-25 23:33   ` Martin Sebor
2020-11-26 17:06     ` Richard Sandiford
2020-11-27 18:12       ` Richard Sandiford
2020-11-28  0:17       ` Martin Sebor [this message]
2020-12-17  0:17         ` Richard Sandiford
2020-12-17 14:21           ` Tom Tromey
2020-12-17 15:38             ` Richard Sandiford
2020-12-17 15:44               ` Nathan Sidwell
2021-01-04 15:32                 ` Jeff Law
2020-11-13  8:15 ` [08/23] Add an alternative splay tree implementation Richard Sandiford
2020-12-02 20:36   ` Jeff Law
2020-12-17  0:29     ` Richard Sandiford
2021-01-04 15:27       ` Jeff Law
2021-01-01  8:25   ` Andreas Schwab
2021-01-04 14:53     ` Richard Sandiford
2021-01-04 15:02       ` Andreas Schwab
2021-01-04 15:42         ` Richard Sandiford
2021-01-05 12:13           ` Richard Biener
2020-11-13  8:15 ` [09/23] Add a cut-down version of std::span (array_slice) Richard Sandiford
2020-11-30 19:56   ` Jeff Law
2022-08-03 15:13   ` Martin Jambor
2022-08-03 15:31     ` Richard Sandiford
2022-08-10 16:03   ` Martin Jambor
2022-08-11  6:58     ` Richard Biener
2022-08-16  7:59       ` Richard Sandiford
2020-11-13  8:16 ` [10/23] Tweak the way that is_a is implemented Richard Sandiford
2020-12-02  5:15   ` Jeff Law
2020-11-13  8:16 ` [11/23] Split update_cfg_for_uncondjump out of combine Richard Sandiford
2020-11-30  6:14   ` Jeff Law
2020-11-13  8:17 ` [12/23] Export print-rtl.c:print_insn_with_notes Richard Sandiford
2020-11-25 20:24   ` Jeff Law
2020-11-13  8:18 ` [13/23] recog: Split out a register_asm_p function Richard Sandiford
2020-11-25 20:24   ` Jeff Law
2020-11-13  8:18 ` [14/23] simplify-rtx: Put simplify routines into a class Richard Sandiford
2020-11-30 19:54   ` Jeff Law
2020-11-13  8:19 ` [15/23] recog: Add a validate_change_xveclen function Richard Sandiford
2020-11-30 20:03   ` Jeff Law
2020-11-13  8:19 ` [16/23] recog: Add a way of temporarily undoing changes Richard Sandiford
2020-11-25 20:27   ` Jeff Law
2020-12-17  0:22     ` Richard Sandiford
2020-11-13  8:20 ` [17/23] recog: Add a class for propagating into insns Richard Sandiford
2020-12-03 22:32   ` Jeff Law
2020-11-13  8:20 ` [18/23] recog: Add an RAII class for undoing insn changes Richard Sandiford
2020-11-25 20:27   ` Jeff Law
2020-11-13  8:20 ` [19/23] rtlanal: Add some new helper classes Richard Sandiford
2020-12-13 17:30   ` Jeff Law
2020-12-14 16:37     ` Richard Sandiford
2020-12-14 20:02       ` Jeff Law
2020-11-13  8:21 ` [20/23] rtlanal: Add simple_regno_set Richard Sandiford
2020-11-25 20:31   ` Jeff Law
2020-12-17  0:47     ` Richard Sandiford
2021-01-04 15:28       ` Jeff Law
2020-11-13  8:22 ` [21/23] doc: Add documentation for rtl-ssa Richard Sandiford
2020-11-30  6:26   ` Jeff Law
2020-11-13  8:23 ` [PATCH 22/23] Add rtl-ssa Richard Sandiford
2020-12-16  3:31   ` Jeff Law
2020-12-17  0:33     ` Richard Sandiford
2020-12-19 20:01       ` Jeff Law
2020-11-13  8:24 ` [PATCH 23/23] fwprop: Rewrite to use RTL SSA Richard Sandiford
2020-12-16  3:52   ` Jeff Law
2020-12-17  0:34     ` Richard Sandiford
2020-11-25 19:58 ` [00/23] Make fwprop use an on-the-side RTL SSA representation Jeff Law
2020-11-26 16:03   ` Richard Sandiford
2020-11-27 15:56     ` Michael Matz
2020-11-27 16:31       ` Richard Sandiford
2020-11-30 21:13         ` Jeff Law
2020-12-01  0:03           ` Michael Matz
2020-12-01 10:15             ` Richard Sandiford
2020-12-02  0:25             ` Jeff Law
2020-11-30  6:45     ` Jeff Law
2020-11-30 14:12       ` Richard Sandiford

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e77128da-b910-439e-37f6-8f98578c6751@gmail.com \
    --to=msebor@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=richard.sandiford@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).