On July 2, 2019 5:36:08 PM GMT+02:00, Jason Merrill <ja...@redhat.com> wrote: >On Mon, Jul 1, 2019 at 8:59 PM Paul E. McKenney <paul...@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 <xks...@gmail.com> >wrote: >> > >> > > On Tue, Jun 25, 2019 at 4:04 PM Ramana Radhakrishnan < >> > > ramana....@googlemail.com> wrote: >> > > >> > >> On Tue, Jun 25, 2019 at 11:03 AM Akshat Garg <xks...@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.
Wtf should this be for? A type qualifier is certainly not going to work. Richard. 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