From: Akshat Garg <xkspr7@gmail.com>
To: Richard Biener <richard.guenther@gmail.com>
Cc: gcc mailing list <gcc@gcc.gnu.org>,
"Paul E. McKenney" <paulmck@linux.ibm.com>,
Ramana Radhakrishnan <ramana.gcc@googlemail.com>,
Jason Merrill <jason@redhat.com>,
Jakub Jelinek <jakub@redhat.com>
Subject: Re: Doubts regarding the _Dependent_ptr keyword
Date: Mon, 22 Jul 2019 08:54:00 -0000 [thread overview]
Message-ID: <CAMEQ7Yzg0-b=gA+Zy4vKtP8XURn5RP_0AD0_Fb-cZwZ1bLDc+Q@mail.gmail.com> (raw)
In-Reply-To: <CAFiYyc31q0Av-Yephv+Y6vGqBpZTmrhLpKa75Eg1JNU9S9JDFA@mail.gmail.com>
On Mon, Jul 22, 2019 at 2:11 PM Richard Biener <richard.guenther@gmail.com>
wrote:
> On Mon, Jul 22, 2019 at 2:27 AM Akshat Garg <xkspr7@gmail.com> wrote:
>
>> Hi all,
>> Consider part of an example(figure 20) from doc P0190R4(
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf)
>> shown below:
>>
>> 1. void thread1 (void)
>> 2. {
>> 3. int * volatile p;
>> 4. p = rcu_dereference(gip);
>> 5. if (p)
>> 6. assert(*(p+p[0]) == 42);
>> 7. }
>> The .gimple code produced is :
>>
>> 1. thread1 ()
>> 2. {
>> 3. atomic int * D.1992;
>> 4. int * volatile p;
>> 5. {
>> 6. atomic int * * __atomic_load_ptr;
>> 7. atomic int * __atomic_load_tmp;
>> 8. try
>> 9. {
>> 10. __atomic_load_ptr = &gip;
>> 11. _1 = __atomic_load_8 (__atomic_load_ptr, 1);
>> 12. _2 = (atomic int *) _1;
>> 13. __atomic_load_tmp = _2;
>> 14. D.1992 = __atomic_load_tmp;
>> 15. }
>> 16. finally
>> 17. {
>> 18. __atomic_load_tmp = {CLOBBER};
>> 19. }
>> 20. }
>> 21. p = D.1992;
>> 22. p.2_3 = p;
>> 23. if (p.2_3 != 0B) goto <D.1994>; else goto <D.1995>;
>> 24. <D.1994>:
>> 25. p.3_4 = p;
>> 26. p.4_5 = p;
>> 27. _6 = *p.4_5;
>> 28. _7 = (long unsigned int) _6;
>> 29. _8 = _7 * 4;
>> 30. _9 = p.3_4 + _8;
>> 31. _10 = *_9;
>> 32. _11 = _10 == 42;
>> 33. _12 = (int) _11;
>> 34. assert (_12);
>> 35. <D.1995>:
>> 36. }
>>
>> assert at line 34 in .gimple code still breaks the dependency given by
>> the user. I believe, there should be some ssa defined variable of p or p
>> itself in assert. This is happening when I am considering pointer as
>> volatile qualified. If I consider it as _Dependent_ptr qualified then it
>> surely produces the broken dependency code. Let me know, if I wrong
>> somewhere.
>>
>>
> p appears as memory here which we load its value to p.3_4 which we then
> offset by _8 and load from the
> computed address into _10 which then appears in the assert condition. I
> think that's as good as it can
> get ...
>
> Richard.
>
Thank you for your reply. For, the same example above, consider this (
https://github.com/AKG001/rtl_opt/blob/master/p0190r4_fig20.c.239r.cse1#L402)
instruction at rtl level changed form this (
https://github.com/AKG001/rtl_opt/blob/master/p0190r4_fig20.c.239r.cse1#L231)
during the cse pass. The variable p.2_3 gets replaced by a temporary _1 but
_1 is not any dependent pointer where, p.2_3 was. Is this also not breaking
any dependencies?
-Akshat
>>
>>
>>
>>
>> On Wed, Jul 17, 2019 at 4:23 PM Akshat Garg <xkspr7@gmail.com> wrote:
>>
>>> On Tue, Jul 2, 2019 at 9:06 PM Jason Merrill <jason@redhat.com> wrote:
>>>
>>>> On Mon, Jul 1, 2019 at 8:59 PM Paul E. McKenney <paulmck@linux.ibm.com>
>>>> wrote:
>>>> >
>>>> > On Tue, Jul 02, 2019 at 05:58:48AM +0530, Akshat Garg wrote:
>>>> > > On Tue, Jun 25, 2019 at 9:49 PM Akshat Garg <xkspr7@gmail.com>
>>>> wrote:
>>>> > >
>>>> > > > On Tue, Jun 25, 2019 at 4:04 PM Ramana Radhakrishnan <
>>>> > > > ramana.gcc@googlemail.com> wrote:
>>>> > > >
>>>> > > >> On Tue, Jun 25, 2019 at 11:03 AM Akshat Garg <xkspr7@gmail.com>
>>>> wrote:
>>>> > > >> >
>>>> > > >> > As we have some working front-end code for _Dependent_ptr,
>>>> What should
>>>> > > >> we do next? What I understand, we can start adding the library
>>>> for
>>>> > > >> dependent_ptr and its functions for C corresponding to the ones
>>>> we created
>>>> > > >> as C++ template library. Then, after that, we can move on to
>>>> generating the
>>>> > > >> assembly code part.
>>>> > > >> >
>>>> > > >>
>>>> > > >>
>>>> > > >> I think the next step is figuring out how to model the Dependent
>>>> > > >> pointer information in the IR and figuring out what
>>>> optimizations to
>>>> > > >> allow or not with that information. At this point , I suspect we
>>>> need
>>>> > > >> a plan on record and have the conversation upstream on the lists.
>>>> > > >>
>>>> > > >> I think we need to put down a plan on record.
>>>> > > >>
>>>> > > >> Ramana
>>>> > > >
>>>> > > > [CCing gcc mailing list]
>>>> > > >
>>>> > > > So, shall I start looking over the pointer optimizations only and
>>>> see what
>>>> > > > information we may be needed on the same examples in the IR
>>>> itself?
>>>> > > >
>>>> > > > - Akshat
>>>> > > >
>>>> > > I have coded an example where equality comparison kills dependency
>>>> from the
>>>> > > document P0190R4 as shown below :
>>>> > >
>>>> > > 1. struct rcutest rt = {1, 2, 3};
>>>> > > 2. void thread0 ()
>>>> > > 3. {
>>>> > > 4. rt.a = -42;
>>>> > > 5. rt.b = -43;
>>>> > > 6. rt.c = -44;
>>>> > > 7. rcu_assign_pointer(gp, &rt);
>>>> > > 8. }
>>>> > > 9.
>>>> > > 10. void thread1 ()
>>>> > > 11. {
>>>> > > 12. int i = -1;
>>>> > > 13. int j = -1;
>>>> > > 14. _Dependent_ptr struct rcutest *p;
>>>> > > 15.
>>>> > > 16. p = rcu_dereference(gp);
>>>> > > 17. j = p->a;
>>>> > > 18. if (p == &rt)
>>>> > > 19. i = p->b; /*Dependency breaking point*/
>>>> > > 20. else if(p)
>>>> > > 21. i = p->c;
>>>> > > 22. assert(i<0);
>>>> > > 23. assert(j<0);
>>>> > > 24. }
>>>> > > The gimple unoptimized code produced for lines 17-24 is shown below
>>>> > >
>>>> > > 1. if (p_16 == &rt)
>>>> > > 2. goto <bb 3>; [INV]
>>>> > > 3. else
>>>> > > 4. goto <bb 4>; [INV]
>>>> > > 5.
>>>> > > 6. <bb 3> :
>>>> > > 7. i_19 = p_16->b;
>>>> > > 8. goto <bb 6>; [INV]
>>>> > > 9.
>>>> > > 10. <bb 4> :
>>>> > > 11. if (p_16 != 0B)
>>>> > > 12. goto <bb 5>; [INV]
>>>> > > 13. else
>>>> > > 14. goto <bb 6>; [INV]
>>>> > > 15.
>>>> > > 16. <bb 5> :
>>>> > > 17. i_18 = p_16->c;
>>>> > > 18.
>>>> > > 19. <bb 6> :
>>>> > > 20. # i_7 = PHI <i_19(3), i_8(4), i_18(5)>
>>>> > > 21. _3 = i_7 < 0;
>>>> > > 22. _4 = (int) _3;
>>>> > > 23. assert (_4);
>>>> > > 24. _5 = j_17 < 0;
>>>> > > 25. _6 = (int) _5;
>>>> > > 26. assert (_6);
>>>> > > 27. return;
>>>> > >
>>>> > > The optimized code after -O1 is applied for the same lines is hown
>>>> below :
>>>> > >
>>>> > > 1. if (_2 == &rt)
>>>> > > 2. goto <bb 3>; [30.00%]
>>>> > > 3. else
>>>> > > 4. goto <bb 4>; [70.00%]
>>>> > > 5.
>>>> > > 6. <bb 3> [local count: 322122547]:
>>>> > > 7. i_12 = rt.b;
>>>> > > 8. goto <bb 6>; [100.00%]
>>>> > > 9.
>>>> > > 10. <bb 4> [local count: 751619277]:
>>>> > > 11. if (_1 != 0)
>>>> > > 12. goto <bb 5>; [50.00%]
>>>> > > 13. else
>>>> > > 14. goto <bb 6>; [50.00%]
>>>> > > 15.
>>>> > > 16. <bb 5> [local count: 375809638]:
>>>> > > 17. i_11 = MEM[(dependent_ptr struct rcutest *)_2].c;
>>>> > > 18.
>>>> > > 19. <bb 6> [local count: 1073741824]:
>>>> > > 20. # i_7 = PHI <i_12(3), i_11(5), -1(4)>
>>>> > > 21. _3 = i_7 < 0;
>>>> > > 22. _4 = (int) _3;
>>>> > > 23. assert (_4);
>>>> > > 24. _5 = j_10 < 0;
>>>> > > 25. _6 = (int) _5;
>>>> > > 26. assert (_6);
>>>> > > 27. return;
>>>> >
>>>> > Good show on tracing this through!
>>>> >
>>>> > > Statement 19 in the program gets converted from i_19 = p_16->b; in
>>>> line 7
>>>> > > in unoptimized code to i_12 = rt.b; in line 7 in optimized code
>>>> which
>>>> > > breaks the dependency chain. We need to figure out the pass that
>>>> does that
>>>> > > and put some handling code in there for the _dependent_ptr qualified
>>>> > > pointers. Passing simply -fipa-pure-const,
>>>> -fguess-branch-probability or
>>>> > > any other option alone does not produce the optimized code that
>>>> breaks the
>>>> > > dependency. But applying -O1, i.e., allowing all the optimizations
>>>> does so.
>>>> > > As passes are applied in a certain order, we need to figure out up
>>>> to what
>>>> > > passes, the code remains same and after what pass the dependency
>>>> does not
>>>> > > holds. So, we need to check the translated code after every pass.
>>>> > >
>>>> > > 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.
>>>> >
>>>> > I don't know of a better plan.
>>>> >
>>>> > My usual question... Is there some way to script the checking of the
>>>> > translated code at the end of each pass?
>>>>
>>>> The usual way to check the output of an optimization pass is by
>>>> dumping the intermediate code at that point and matching the dump
>>>> against a regexp, as in the tree-ssa directories in the testsuite.
>>>> -fdump-tree-all will dump after all the gimple optimization passes,
>>>> and you can look through them until you find the breakage.
>>>>
>>>> Jason
>>>>
>>> Thanks Jason for the advice, I followed it.
>>>
>>> I coded an example shown in figure 26 from here (
>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0190r4.pdf).
>>> The example:
>>> https://github.com/AKG001/test/blob/master/dependency_breaking.c
>>> The .objsz1 code:
>>> https://github.com/AKG001/test/blob/master/dependency_breaking.c.027t.objsz1
>>> The .ccp1 code:
>>> https://github.com/AKG001/test/blob/master/dependency_breaking.c.028t.ccp1
>>> The .sra code:
>>> https://github.com/AKG001/test/blob/master/dependency_breaking.c.114t.sra
>>> The .dom2 code:
>>> https://github.com/AKG001/test/blob/master/dependency_breaking.c.116t.dom2
>>>
>>> Comparing the .objsz1 and .ccp1 file, the "struct p" gets removed after
>>> constant copy propagation (ccp) pass(
>>> https://github.com/gcc-mirror/gcc/blob/master/gcc/passes.def#L77). In
>>> .objsz1 file at line 53, the dependencies start with
>>> p_16 = _14;
>>> .......
>>> i_19 = p_16->b;
>>> ......
>>> as user specified and after that all the references are made through
>>> struct p or its variants. But in .ccp1 file at line 41, the "struct p" is
>>> replaced with variable _2, now, variable _2 starts the dependencies as we
>>> can see.
>>> _2 = (atomic struct rcutest *) _1;
>>> ...........
>>> i_19 = MEM[(struct rcutest *)_2].b;
>>> ..........
>>> I don't know whether it is okay to say at this point, the dependencies
>>> are still maintained or not. Or we have to pass the dependent pointer
>>> qualification to new variables that replaces them. Hoping someone could
>>> clarify.
>>>
>>> Also, In .sra file at line 43 in thread1(), the statement is:
>>> i_12 = MEM[(struct rcutest *)_2].b;
>>> In .dom2 file at line 61, the above statement gets converted to:
>>> i_12 = rt.b;
>>> So, I believe that sure does breaks the dependency specified by the
>>> user. For this, we need to do some modifications in tree-ssa-dom.c file.
>>> Hope this makes sense.
>>>
>>> Thanks,
>>> Akshat
>>>
>>
next prev parent reply other threads:[~2019-07-22 8:54 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CAMEQ7Yw5mV+zoDV-kmOnWoy4+_CiDeUyJmipkkrTGhxninp3Hw@mail.gmail.com>
[not found] ` <20190617023256.GJ26519@linux.ibm.com>
[not found] ` <CAMEQ7Yxp-o+4dPd_o=eaPYqpV1n7KfqMS_Un1U1n9-ut_HK_uw@mail.gmail.com>
[not found] ` <20190618211927.GY26519@linux.ibm.com>
[not found] ` <CAJA7tRYJPaFuvR+bC40kGdKOLVTHEFnD1SkBqF6oUcpv-bLMbw@mail.gmail.com>
[not found] ` <CAMEQ7YyN72aMAEsuKW4GQua_Vyi8Wd6F6BKcTo8dS_JcLm2TvQ@mail.gmail.com>
[not found] ` <CAMEQ7YxT4mwNvgr_iqxKAJE=yeuOmhcNkHL1ET-84hwv9uMwdQ@mail.gmail.com>
[not found] ` <CAJA7tRZVhVtabJLgWJ3BK3HhR2pf+X0fiG+sF=y2Y=PkWg8eTQ@mail.gmail.com>
[not found] ` <CAMEQ7YyLp0YymRiYD4O_1A=YswbbDBh0gQz9kGtw4t8mfvU4Jg@mail.gmail.com>
[not found] ` <20190619164145.GJ26519@linux.ibm.com>
[not found] ` <20190620140600.GA15142@linux.ibm.com>
[not found] ` <CAMEQ7Yx=dg0TWcXKA8eZk=RCN+az116Y9whKGQSB3fRVZwbvQw@mail.gmail.com>
[not found] ` <CAJA7tRbj6eoOj_fr+Nnm1rS=kdc0jPxkb77AoPCFrJEaaPsCSA@mail.gmail.com>
2019-06-25 16:20 ` Akshat Garg
2019-07-02 0:29 ` Akshat Garg
2019-07-02 0:59 ` Paul E. McKenney
2019-07-02 1:42 ` nick
2019-07-02 15:36 ` Jason Merrill
2019-07-02 17:53 ` Richard Biener
2019-07-03 15:09 ` Paul E. McKenney
2019-07-02 19:37 ` Akshat Garg
2019-07-17 10:54 ` Akshat Garg
2019-07-22 0:27 ` Akshat Garg
2019-07-22 8:41 ` Richard Biener
2019-07-22 8:54 ` Akshat Garg [this message]
2019-07-22 9:46 ` Richard Biener
2019-07-23 20:11 ` Akshat Garg
2019-07-23 20:50 ` Akshat Garg
2019-07-02 10:22 ` Ramana Radhakrishnan
2019-07-02 10:39 ` Akshat Garg
2019-07-02 11:01 ` Ramana Radhakrishnan
2019-07-02 12:38 ` Paul E. McKenney
2019-07-02 13:16 ` Ramana Radhakrishnan
2019-07-02 15:09 ` Paul E. McKenney
2019-07-02 19:09 ` Akshat Garg
2019-07-03 15:16 ` Paul E. McKenney
2019-07-03 15:48 ` Richard Biener
2019-07-03 16:34 ` Paul E. McKenney
2019-07-04 11:00 ` Richard Biener
2019-07-04 17:40 ` Paul E. McKenney
2019-07-04 18:09 ` Jakub Jelinek
2019-07-04 23:08 ` Akshat Garg
2019-07-05 11:20 ` Richard Biener
2019-07-05 15:38 ` Akshat Garg
[not found] ` <20190705014806.GM26519@linux.ibm.com>
[not found] ` <CAMEQ7YyrjkGVhnLUCXMrbyicPkRZkpZvH_3KQ56cNh_6+Tr4iQ@mail.gmail.com>
[not found] ` <CAMEQ7YzOqU68kQN99g_zhwJUkNaJa9q_Dv9pue+4NFK4rYubFg@mail.gmail.com>
[not found] ` <20190707141928.GE26519@linux.ibm.com>
[not found] ` <CAMEQ7YyuzvN_OzU4oMJGaFMBpnQwkCt4=ZTo-AmSmvsr2dBOMw@mail.gmail.com>
2019-07-07 21:44 ` Akshat Garg
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='CAMEQ7Yzg0-b=gA+Zy4vKtP8XURn5RP_0AD0_Fb-cZwZ1bLDc+Q@mail.gmail.com' \
--to=xkspr7@gmail.com \
--cc=gcc@gcc.gnu.org \
--cc=jakub@redhat.com \
--cc=jason@redhat.com \
--cc=paulmck@linux.ibm.com \
--cc=ramana.gcc@googlemail.com \
--cc=richard.guenther@gmail.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).