On Thu, Jul 04, 2019 at 01:00:18PM +0200, Richard Biener wrote:
> On Wed, Jul 3, 2019 at 6:33 PM Paul E. McKenney <paul...@linux.ibm.com> wrote:
> >
> > On Wed, Jul 03, 2019 at 05:47:56PM +0200, Richard Biener wrote:
> > > On July 3, 2019 5:14:58 PM GMT+02:00, "Paul E. McKenney" 
> > > <paul...@linux.ibm.com> wrote:
> > > >On Wed, Jul 03, 2019 at 12:39:41AM +0530, Akshat Garg wrote:
> > > >> On Tue, Jul 2, 2019 at 8:40 PM Paul E. McKenney
> > > ><paul...@linux.ibm.com>
> > > >> wrote:
> > > >>
> > > >> > On Tue, Jul 02, 2019 at 02:15:55PM +0100, Ramana Radhakrishnan
> > > >wrote:
> > > >> > > On Tue, Jul 2, 2019 at 1:38 PM Paul E. McKenney
> > > ><paul...@linux.ibm.com>
> > > >> > wrote:
> > > >> > >
> > > >> > > >
> > > >> > > > Once a user-created non-dependent pointer is assigned to, it is
> > > >OK to
> > > >> > > > break the dependency.
> > > >> > >
> > > >> > > Ok, that's good.
> > > >> > > >
> > > >> > > > Or am I missing the point here?
> > > >> > >
> > > >> > > I was just trying to make sure we were on the same page. I wonder
> > > >if
> > > >> > > marking this volatile would be sufficient for prototyping. I
> > > >suspect
> > > >> > > we would need another flag somewhere which someone with gimple
> > > >> > > knowledge might be able to help us with.
> > > >> >
> > > >> > I expect that marking it as volatile would do the trick.  ;-)
> > > >> >
> > > >> >                                                         Thanx, Paul
> > > >> >
> > > >> So, marking this pointer as volatile will not allow the compiler to
> > > >> modify/optimize the statements, the pointer is appearing in. And we
> > > >don't
> > > >> need to push any other code inside any of the passes. Due to this, we
> > > >want
> > > >> to automatically say those dependent pointers are volatile and
> > > >introduce a
> > > >> new flag for this. Am I getting you guys correctly? Kindly, let me
> > > >know?
> > > >
> > > >While I suspect that this might work, it would suppress way more
> > > >optimizations than would be good.  For but one example, consider:
> > > >
> > > >     _Dependent_ptr int *p;
> > > >
> > > >     p = atomic_load_explicit(gp, memory_order_consume);
> > > >     a = p->a;
> > > >     b = p->b;
> > > >
> > > >If "p" is volatile, then the compiler will be prevented from keeping
> > > >it in a register, which would not make people coding fastpaths at
> > > >all happy.  ;-)
> > > >
> > > >Still, use of volatile might be a good technique for prototyping and
> > > >analysis of _Dependent_ptr.
> > >
> > > With this example can you quickly summarize what kind of guarantees 
> > > _Dependent_ptr gives and how a compiler
> > > Could possibly break those?
> >
> > First I suppose I should fix the bug in the above code.  Or one of the
> > bugs, at least.  :-/
> >
> >         struct foo {
> >                 int a;
> >                 int b;
> >         };
> >
> >         _Dependent_ptr struct foo *p;
> >
> >         p = atomic_load_explicit(gp, memory_order_consume);
> >         a = p->a;
> >         b = p->b;
> >
> > And then let me tweak the example a bit.  For the first tweak:
> >
> >         struct foo {
> >                 int a;
> >                 int b;
> >         };
> >
> >         struct foo default_foo = { .a = 42, .b = 43 };
> >         int *gp = &default_foo;
> >
> >         ...
> >
> >         _Dependent_ptr int *p;
> >
> >         p = atomic_load_explicit(gp, memory_order_consume);
> >         a = p->a;
> >         b = p->b;
> >
> > Suppose that the compiler used feedback-driven optimization, and noticed
> > that the value of gp was almost always &default_foo.  The compiler might
> > decide to transform the last three lines as follows:
> >
> >         p = atomic_load_explicit(gp, memory_order_consume);
> >         if (p == &default_foo) {
> >                 a = default_foo.a;
> >                 b = default_foo.b;
> >         } else {
> >                 a = p->a;
> >                 b = p->b;
> >         }
> >
> > Now, as long as the value of gp had remained &default_foo for the full
> > duration of execution, no harm done.  But suppose the following code
> > was executing concurrently with the above transformed code:
> >
> >         struct foo *q;
> >
> >         q = malloc(sizeof(*q));
> >         assert(q);
> >         q->a = 1729;
> >         q->b = 1730;
> >         atomic_store_explicit(gp, q, memory_order_release);
> >         do_something();
> >         default_foo.a = 1;
> >         default_foo.b = 2;
> >         atomic_store_explicit(gp, &default_foo, memory_order_release);
> >
> > In this case, if the memory_order_consume() came just after the pointer
> > was reset to &default_foo, it is possible that the transformed code
> > would set "a" to 42 and "b" to 43, which might not be what the guy
> > writing the code wanted to happen.
> >
> > One of the purposes of _Dependent_ptr is to prevent this transformation.
> >
> > This transformation can also happen if the developer's code contained a
> > comparison to &default_foo -- an ARM or PowerPC compiler backend, upon
> > seeing two pointers containing the same bits, would likely consider the
> > two pointers as being interchangeable, and thus might do the dereferences
> > using the copy that was not tagged with the hardware dependencies.
> >
> > There are quite a few other examples.  The C++ standards committee
> > working papers shown below go through a number of them, in case the
> > above example is not convincing.  Or you could tell me what you would
> > like to see, and I would attempt to find/create a suitable example.
> >
> > Does that help, or am I missing your point?
> 
> Browsed through that resources, so yes.  So the important thing
> is that data dependences in the source are not to be removed or
> replaced by control dependences because that enables out-of-order
> execution on the CPU (or by the compiler).  This is only needed
> for data typed with the _Dependent_ptr qualifier.
> 
> I think fully guaranteeing this is hard (besides when you use
> volatile), we have the very same issue when dealing with
> pointer provenance rules, known for years and not fixed
> (and I don't see a good way to fix these issues without
> sacrifying performance everywhere).
> 
> Good luck ;)

Thank you, we will need it!  ;-)

> Maybe performance isn't so much of an issue for _Dependent_ptr
> (compared to when all pointers are affected).

Here is hoping!

                                                        Thanx, Paul

> Richard.
> 
> >
> >                                                         Thanx, Paul
> >
> > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0098r0.pdf
> > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf
> > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0462r1.pdf
> >
> > > Richard.
> > >
> > > >
> > > >                                                     Thanx, Paul
> > > >
> > > >> Akshat
> > > >>
> > > >> >
> > > >> > > regards
> > > >> > > Ramana
> > > >> > >
> > > >> > > >
> > > >> > > >                                                         Thanx,
> > > >Paul
> > > >> > > >
> > > >> > > > > Ramana
> > > >> > > > > >>
> > > >> > > > > >>
> > > >> > > > > >> > Does this sounds like a workable plan for ? Let me know
> > > >your
> > > >> > thoughts. If this sounds good then, we can do this for all the
> > > >> > optimizations that may kill the dependencies at somepoint.
> > > >> > > > > >> >
> > > >> > > > > >> > -Akshat
> > > >> > > > >
> > > >> > > >
> > > >> > >
> > > >> >
> > > >> >
> > >
> >

Reply via email to