Re: How to represent a fallthrough condtion (with no else) in "Match and Simplify"?
On Wed, Jun 12, 2024 at 8:57 AM Hanke Zhang via Gcc wrote: > > Hi, > > I'm trying to study "Match and Simplify" recently, and I had this sample code: > > int main() { > int n = 1000; > int *a = malloc (sizeof(int) * n); > int *b = malloc (sizeof(int) * n); > int *c = malloc (sizeof(int) * n); > for (int i = 0; i < n; i++) { > if (a[i] & b[i]) { > a[i] ^= c[i]; > } > } > } > > But this code cannot be vectorized very well. I hope it can become like this: > > int main() { > int n = 1000; > int *a = malloc (sizeof(int) * n); > int *b = malloc (sizeof(int) * n); > int *c = malloc (sizeof(int) * n); > for (int i = 0; i < n; i++) { > int cond = ((a[i] & b[i]) == 1); > unsigned int mask = cond ? -1 : 0; > a[i] ^= (c[i] & mask); > } > } > > > This can finally result in concise and efficient vectorized > instructions. But I want to know if this can be achieved through > "Match and Simplify"? Because when I tried to write the pattern, I > found that the condtional statement here seemed not to be matched > well, as there is not an else block. > > Or is this not possible with "Match and Simplify"? Is it possible to > implement it in if-conversion? It's not possible to perform this transform in match-and-simplify, if-conversion does this but it considers 'a' to be possibly not writable and thus the conditional store has to be preserved. It should use a .MASK_STORE here and I verified it does with -mavx2. Note your testcase is optimized away as it's full of dead code. int foo (int n, int *a, int *b, int *c) { for (int i = 0; i < n; i++) { if (a[i] & b[i]) { a[i] ^= c[i]; } } } is what I tried. I suppose other compilers do not consider read-only memory mappings? Note there's also store data races to be considered (but -Ofast might help with that). In my testcase the c[i] access could also trap, requiring .MASK_LOAD (I'm quite sure we can't analyze allocated array bounds when the allocation stmt is seen as in your case). Richard. > Thanks > Hanke Zhang
Re: Question about optimizing function pointers for direct function calls
Richard Biener 于2024年5月24日周五 14:39写道: > > On Fri, May 24, 2024 at 5:53 AM Hanke Zhang via Gcc wrote: > > > > Hi, > > I got a question about optimizing function pointers for direct > > function calls in C. > > > > Consider the following scenario: one of the fields of a structure is a > > function pointer, and all its assignments come from the same function. > > Can all its uses be replaced by direct calls to this function? So the > > later passes can do more optimizations. > > > > Here is the example: > > > > int add(int a, int b) { return a + b; } > > int sub(int a, int b) { return a - b; } > > > > struct Foo { > > int (*add)(int, int); > > }; > > int main() > > { > > struct Foo foo[5] = malloc(sizeof(struct Foo) * 5); > > > > for (int i = 0; i < 5; i++) { > > foo[i].add = add; > > } > > > > int sum = 0; > > for (int i = 0; i < 5; i++) { > > sum += foo[i].add(1, 2); > > } > > > > return 0; > > } > > > > Can I replace the code above to the code below? > > > > int add(int a, int b) { return a + b; } > > int sub(int a, int b) { return a - b; } > > > > struct Foo { > > int (*add)(int, int); > > }; > > int main() > > { > > struct Foo foo[5] = malloc(sizeof(struct Foo) * 5); > > > > for (int i = 0; i < 5; i++) { > > foo[i].add = add; > > } > > > > int sum = 0; > > for (int i = 0; i < 5; i++) { > > sum += add(1,2); > > } > > > > return 0; > > } > > > > My idea is to determine whether the assignment of the field is the > > same function, and if so, perform the replacement. > > If it's as simple as above then sure, even CSE should do it. If you > can prove otherwise the memory location with the function pointer > always has the same value you are obviously fine. If you just > do not see any other store via 'add's FIELD_DECL then no, that > isn't good enough. Every void * store you do not know where it > goes might go to that slot. > > > Of course this is not a reasonable optimization, I just want to know > > if there are security issues in doing so, and if I want to do it in > > the IPA stage, is it possible? > > For the more general case you can do what we do for speculative > devirtualization - replace the code with > > sum += foo[i].add == add ? add (1,2) : foo[i].add(1,2); Hi Richard, I'm trying to do what you suggested. (sum += foo[i].add == add ? add (1,2) : foo[i].add(1,2);) I created a new IPA-Pass before IPA-INLINE and I made the changes on the GIMPLE in the "function_transform" stage. But my newly created "foo[i].add(1,2)" seems to fail to be inlined. And it was optimized out in the subsequent FRE. I would like to ask if there is any way to mark my newly created cgraph_edge as "inline" in the "function_transform" stage. Here is part of the code creating the call_stmt in true basic_block in my IPA-PASS: // ... // part of the code have been omitted auto_vec params; for (int i = 0; i < gimple_call_num_args (call_stmt); i++) { params.safe_push (gimple_call_arg (call_stmt, i)); } gimple* tbb_call = gimple_build_call_vec (fndecl, params); /// = fn() tree tbb_ssa; if (ret_val_flag) { tbb_ssa = make_ssa_name (TREE_TYPE (gimple_call_lhs(call_stmt)), NULL); gimple_call_set_lhs (tbb_call, tbb_ssa); /// _2 = fn() } gsi = gsi_start_bb (tbb); gsi_insert_before (&gsi, tbb_call, GSI_SAME_STMT); cgraph_edge* tbb_callee = node->create_edge (cgraph_node::get_create (fndecl), (gcall*)tbb_call, tbb_call->bb->count, true); // what should I do to this cgraph_edge to mark it to be inlined // ... Or should I not do these things in the function_transform stage? Thanks Hanke Zhang > > that way we can inline the direct call and hopefully the branch will be > well predicted. > > In some SPEC there is IIRC the situation where such speculative > devirtualization candidates can be found solely based on function > signature. With LTO/IPA you'd basically collect candidate targets > for each indirect call (possibly address-taken function definitions > with correct signature) and if there's just a single one you can > choose that as speculative devirt target. > > Speculative devirt as we have now of course works with profile > data to identify the most probable candidate. > > Richard. > > > > > Thanks > > Hanke Zhang
Re: Question about optimizing function pointers for direct function calls
On Wed, Jun 12, 2024 at 11:57 AM Hanke Zhang wrote: > > Richard Biener 于2024年5月24日周五 14:39写道: > > > > On Fri, May 24, 2024 at 5:53 AM Hanke Zhang via Gcc wrote: > > > > > > Hi, > > > I got a question about optimizing function pointers for direct > > > function calls in C. > > > > > > Consider the following scenario: one of the fields of a structure is a > > > function pointer, and all its assignments come from the same function. > > > Can all its uses be replaced by direct calls to this function? So the > > > later passes can do more optimizations. > > > > > > Here is the example: > > > > > > int add(int a, int b) { return a + b; } > > > int sub(int a, int b) { return a - b; } > > > > > > struct Foo { > > > int (*add)(int, int); > > > }; > > > int main() > > > { > > > struct Foo foo[5] = malloc(sizeof(struct Foo) * 5); > > > > > > for (int i = 0; i < 5; i++) { > > > foo[i].add = add; > > > } > > > > > > int sum = 0; > > > for (int i = 0; i < 5; i++) { > > > sum += foo[i].add(1, 2); > > > } > > > > > > return 0; > > > } > > > > > > Can I replace the code above to the code below? > > > > > > int add(int a, int b) { return a + b; } > > > int sub(int a, int b) { return a - b; } > > > > > > struct Foo { > > > int (*add)(int, int); > > > }; > > > int main() > > > { > > > struct Foo foo[5] = malloc(sizeof(struct Foo) * 5); > > > > > > for (int i = 0; i < 5; i++) { > > > foo[i].add = add; > > > } > > > > > > int sum = 0; > > > for (int i = 0; i < 5; i++) { > > > sum += add(1,2); > > > } > > > > > > return 0; > > > } > > > > > > My idea is to determine whether the assignment of the field is the > > > same function, and if so, perform the replacement. > > > > If it's as simple as above then sure, even CSE should do it. If you > > can prove otherwise the memory location with the function pointer > > always has the same value you are obviously fine. If you just > > do not see any other store via 'add's FIELD_DECL then no, that > > isn't good enough. Every void * store you do not know where it > > goes might go to that slot. > > > > > Of course this is not a reasonable optimization, I just want to know > > > if there are security issues in doing so, and if I want to do it in > > > the IPA stage, is it possible? > > > > For the more general case you can do what we do for speculative > > devirtualization - replace the code with > > > > sum += foo[i].add == add ? add (1,2) : foo[i].add(1,2); > > Hi Richard, > > I'm trying to do what you suggested. (sum += foo[i].add == add ? add > (1,2) : foo[i].add(1,2);) > > I created a new IPA-Pass before IPA-INLINE and I made the changes on > the GIMPLE in the "function_transform" stage. But my newly created > "foo[i].add(1,2)" seems to fail to be inlined. And it was optimized > out in the subsequent FRE. I would like to ask if there is any way to > mark my newly created cgraph_edge as "inline" in the > "function_transform" stage. > > Here is part of the code creating the call_stmt in true basic_block in > my IPA-PASS: > > // ... > // part of the code have been omitted > auto_vec params; > for (int i = 0; i < gimple_call_num_args (call_stmt); i++) { > params.safe_push (gimple_call_arg (call_stmt, i)); > } > gimple* tbb_call = gimple_build_call_vec (fndecl, params); /// = fn() > tree tbb_ssa; > if (ret_val_flag) { > tbb_ssa = make_ssa_name (TREE_TYPE (gimple_call_lhs(call_stmt)), NULL); > gimple_call_set_lhs (tbb_call, tbb_ssa); /// _2 = fn() > } > gsi = gsi_start_bb (tbb); > gsi_insert_before (&gsi, tbb_call, GSI_SAME_STMT); > cgraph_edge* tbb_callee = node->create_edge (cgraph_node::get_create > (fndecl), (gcall*)tbb_call, tbb_call->bb->count, true); > // what should I do to this cgraph_edge to mark it to be inlined > // ... > > Or should I not do these things in the function_transform stage? That's indeed too late. You have to create speculative call edges, I would suggest to look how IPA devirtualization handles this case and possibly simply amend it. I'm CCing Honza who should know more about this, I do not know the details. Richard. > Thanks > Hanke Zhang > > > > > > that way we can inline the direct call and hopefully the branch will be > > well predicted. > > > > In some SPEC there is IIRC the situation where such speculative > > devirtualization candidates can be found solely based on function > > signature. With LTO/IPA you'd basically collect candidate targets > > for each indirect call (possibly address-taken function definitions > > with correct signature) and if there's just a single one you can > > choose that as speculative devirt target. > > > > Speculative devirt as we have now of course works with profile > > data to identify the most probable candidate. > > > > Richard. > > > > > > > > Thanks > > > Hanke Zhang
gcc git locked out for hours second day in a row
Hi! Yesterday the gcc git repository was locked for 3 hours locked by user mikael at 2024-06-11 13:27:44.301067 (pid = 974167) 78:06 python hooks/update.py refs/users/mikael/tags/fortran-dev_merges/r10-1545 c2f9fe1d8111b9671bf0aa8362446516fd942f1d process until overseers killed it but today we have the same situation for 3 ours and counting again: locked by user mikael at 2024-06-12 08:35:48.137564 (pid = 2219652) 78:06 python hooks/update.py refs/users/mikael/tags/toto cca005166dba2cefeb51afac3ea629b3972acea3 It is possible we have some bug in the git hook scripts, but it would be helpful trying to understand what exactly you're trying to commit and why nobody else (at least to my knowledge) has similarly stuck commits. The effect is that nobody can push anything else to gcc git repo for hours. Jakub
Re: gcc git locked out for hours second day in a row
Hi, On Wed, 2024-06-12 at 13:48 +0200, Jakub Jelinek via Gcc wrote: > Yesterday the gcc git repository was locked for 3 hours > locked by user mikael at 2024-06-11 13:27:44.301067 (pid = 974167) > 78:06 python hooks/update.py > refs/users/mikael/tags/fortran-dev_merges/r10-1545 > > c2f9fe1d8111b9671bf0aa8362446516fd942f1d > process until overseers killed it but today we have the same > situation for 3 ours and counting again: > locked by user mikael at 2024-06-12 08:35:48.137564 (pid = 2219652) > 78:06 python hooks/update.py refs/users/mikael/tags/toto > > cca005166dba2cefeb51afac3ea629b3972acea3 Just for the record, I kill the process and removed the git- hooks::update.token.lock file. Sorry that killed mikael's push, but hopefully that makes it possible for others to push again. Cheers, Mark
Re: gcc git locked out for hours second day in a row
Le 12/06/2024 à 13:48, Jakub Jelinek a écrit : Hi! Yesterday the gcc git repository was locked for 3 hours locked by user mikael at 2024-06-11 13:27:44.301067 (pid = 974167) 78:06 python hooks/update.py refs/users/mikael/tags/fortran-dev_merges/r10-1545 c2f9fe1d8111b9671bf0aa8362446516fd942f1d process until overseers killed it but today we have the same situation for 3 ours and counting again: locked by user mikael at 2024-06-12 08:35:48.137564 (pid = 2219652) 78:06 python hooks/update.py refs/users/mikael/tags/toto cca005166dba2cefeb51afac3ea629b3972acea3 It is possible we have some bug in the git hook scripts, but it would be helpful trying to understand what exactly you're trying to commit and why nobody else (at least to my knowledge) has similarly stuck commits. The effect is that nobody can push anything else to gcc git repo for hours. Jakub Yes, sorry for the inconvenience. I tried pushing a series of tags labeling merge points between the fortran-dev branch and recent years master. The number of merge points is a bit high (329) but I expected it to be a manageable number. I tried again today with just the most recent merge point, but it got stuck again. I should try with the oldest one, but I'm afraid locking the repository again. I waited for the push to finish for say one hour before killing it yesterday, and no more than 15 minutes today. Unfortunately, killing the process doesn't seem to unlock things on the server side. It may be a misconfiguration on my side, but I have never had this problem before. Sorry again.
Re: gcc git locked out for hours second day in a row
Le 12/06/2024 à 14:14, Mark Wielaard a écrit : Hi, On Wed, 2024-06-12 at 13:48 +0200, Jakub Jelinek via Gcc wrote: Yesterday the gcc git repository was locked for 3 hours locked by user mikael at 2024-06-11 13:27:44.301067 (pid = 974167) 78:06 python hooks/update.py refs/users/mikael/tags/fortran-dev_merges/r10-1545 c2f9fe1d8111b9671bf0aa8362446516fd942f1d process until overseers killed it but today we have the same situation for 3 ours and counting again: locked by user mikael at 2024-06-12 08:35:48.137564 (pid = 2219652) 78:06 python hooks/update.py refs/users/mikael/tags/toto cca005166dba2cefeb51afac3ea629b3972acea3 Just for the record, I kill the process and removed the git- hooks::update.token.lock file. Sorry that killed mikael's push, but hopefully that makes it possible for others to push again. No problem, I had interrupted the push long before on my side.
Re: gcc git locked out for hours second day in a row
On Wed, 12 Jun 2024 at 13:57, Mikael Morin via Gcc wrote: > > Le 12/06/2024 à 13:48, Jakub Jelinek a écrit : > > Hi! > > > > Yesterday the gcc git repository was locked for 3 hours > > locked by user mikael at 2024-06-11 13:27:44.301067 (pid = 974167) > > 78:06 python hooks/update.py > > refs/users/mikael/tags/fortran-dev_merges/r10-1545 > > > > c2f9fe1d8111b9671bf0aa8362446516fd942f1d > > process until overseers killed it but today we have the same > > situation for 3 ours and counting again: > > locked by user mikael at 2024-06-12 08:35:48.137564 (pid = 2219652) > > 78:06 python hooks/update.py refs/users/mikael/tags/toto > > > > cca005166dba2cefeb51afac3ea629b3972acea3 > > > > It is possible we have some bug in the git hook scripts, but it would > > be helpful trying to understand what exactly you're trying to commit > > and why nobody else (at least to my knowledge) has similarly stuck commits. > > > > The effect is that nobody can push anything else to gcc git repo > > for hours. > > > > Jakub > > > Yes, sorry for the inconvenience. > I tried pushing a series of tags labeling merge points between the > fortran-dev branch and recent years master. Just pushing tags should not cause a problem, assuming all the commits being tagged already exist. What exactly are you pushing? > The number of merge points is a bit high (329) but I expected it to be a > manageable number. I tried again today with just the most recent merge > point, but it got stuck again. I should try with the oldest one, but > I'm afraid locking the repository again. > > I waited for the push to finish for say one hour before killing it > yesterday, and no more than 15 minutes today. Unfortunately, killing > the process doesn't seem to unlock things on the server side. > > It may be a misconfiguration on my side, but I have never had this > problem before. > > Sorry again. > >
Re: gcc git locked out for hours second day in a row
Le 12/06/2024 à 14:58, Jonathan Wakely a écrit : On Wed, 12 Jun 2024 at 13:57, Mikael Morin via Gcc wrote: Le 12/06/2024 à 13:48, Jakub Jelinek a écrit : Hi! Yesterday the gcc git repository was locked for 3 hours locked by user mikael at 2024-06-11 13:27:44.301067 (pid = 974167) 78:06 python hooks/update.py refs/users/mikael/tags/fortran-dev_merges/r10-1545 c2f9fe1d8111b9671bf0aa8362446516fd942f1d process until overseers killed it but today we have the same situation for 3 ours and counting again: locked by user mikael at 2024-06-12 08:35:48.137564 (pid = 2219652) 78:06 python hooks/update.py refs/users/mikael/tags/toto cca005166dba2cefeb51afac3ea629b3972acea3 It is possible we have some bug in the git hook scripts, but it would be helpful trying to understand what exactly you're trying to commit and why nobody else (at least to my knowledge) has similarly stuck commits. The effect is that nobody can push anything else to gcc git repo for hours. Jakub Yes, sorry for the inconvenience. I tried pushing a series of tags labeling merge points between the fortran-dev branch and recent years master. Just pushing tags should not cause a problem, assuming all the commits being tagged already exist. What exactly are you pushing? Well, the individual commits to be merged do exist, but the merge points don't and they are what I'm trying to push. To be clear, the branch hasn't seen any update for years, and I'm trying to reapply what happened on trunk since, in a step-wise manner. With 300 merges I'm summing up 6 commits of history. The number of merge points is a bit high (329) but I expected it to be a manageable number. I tried again today with just the most recent merge point, but it got stuck again. I should try with the oldest one, but I'm afraid locking the repository again. I waited for the push to finish for say one hour before killing it yesterday, and no more than 15 minutes today. Unfortunately, killing the process doesn't seem to unlock things on the server side. It may be a misconfiguration on my side, but I have never had this problem before. Sorry again.
Re: gcc git locked out for hours second day in a row
On 12/06/2024 14:23, Mikael Morin via Gcc wrote: > Le 12/06/2024 à 14:58, Jonathan Wakely a écrit : >> On Wed, 12 Jun 2024 at 13:57, Mikael Morin via Gcc wrote: >>> >>> Le 12/06/2024 à 13:48, Jakub Jelinek a écrit : Hi! Yesterday the gcc git repository was locked for 3 hours locked by user mikael at 2024-06-11 13:27:44.301067 (pid = 974167) 78:06 python hooks/update.py refs/users/mikael/tags/fortran-dev_merges/r10-1545 c2f9fe1d8111b9671bf0aa8362446516fd942f1d process until overseers killed it but today we have the same situation for 3 ours and counting again: locked by user mikael at 2024-06-12 08:35:48.137564 (pid = 2219652) 78:06 python hooks/update.py refs/users/mikael/tags/toto cca005166dba2cefeb51afac3ea629b3972acea3 It is possible we have some bug in the git hook scripts, but it would be helpful trying to understand what exactly you're trying to commit and why nobody else (at least to my knowledge) has similarly stuck commits. The effect is that nobody can push anything else to gcc git repo for hours. Jakub >>> Yes, sorry for the inconvenience. >>> I tried pushing a series of tags labeling merge points between the >>> fortran-dev branch and recent years master. >> >> Just pushing tags should not cause a problem, assuming all the commits >> being tagged already exist. What exactly are you pushing? >> > Well, the individual commits to be merged do exist, but the merge points > don't and they are what I'm trying to push. > > To be clear, the branch hasn't seen any update for years, and I'm trying to > reapply what happened on trunk since, in a step-wise manner. With 300 merges > I'm summing up 6 commits of history. > >> >>> The number of merge points is a bit high (329) but I expected it to be a >>> manageable number. I tried again today with just the most recent merge >>> point, but it got stuck again. I should try with the oldest one, but >>> I'm afraid locking the repository again. >>> >>> I waited for the push to finish for say one hour before killing it >>> yesterday, and no more than 15 minutes today. Unfortunately, killing >>> the process doesn't seem to unlock things on the server side. >>> >>> It may be a misconfiguration on my side, but I have never had this >>> problem before. >>> >>> Sorry again. >>> >>> > Perhaps you could create a mirror version of the repo and do some experiments locally on that to identify where the bottle-neck is coming from? R.
Re: gcc git locked out for hours second day in a row
Le 12/06/2024 à 16:34, Richard Earnshaw (lists) a écrit : On 12/06/2024 14:23, Mikael Morin via Gcc wrote: Le 12/06/2024 à 14:58, Jonathan Wakely a écrit : On Wed, 12 Jun 2024 at 13:57, Mikael Morin via Gcc wrote: Le 12/06/2024 à 13:48, Jakub Jelinek a écrit : Hi! Yesterday the gcc git repository was locked for 3 hours locked by user mikael at 2024-06-11 13:27:44.301067 (pid = 974167) 78:06 python hooks/update.py refs/users/mikael/tags/fortran-dev_merges/r10-1545 c2f9fe1d8111b9671bf0aa8362446516fd942f1d process until overseers killed it but today we have the same situation for 3 ours and counting again: locked by user mikael at 2024-06-12 08:35:48.137564 (pid = 2219652) 78:06 python hooks/update.py refs/users/mikael/tags/toto cca005166dba2cefeb51afac3ea629b3972acea3 It is possible we have some bug in the git hook scripts, but it would be helpful trying to understand what exactly you're trying to commit and why nobody else (at least to my knowledge) has similarly stuck commits. The effect is that nobody can push anything else to gcc git repo for hours. Jakub Yes, sorry for the inconvenience. I tried pushing a series of tags labeling merge points between the fortran-dev branch and recent years master. Just pushing tags should not cause a problem, assuming all the commits being tagged already exist. What exactly are you pushing? Well, the individual commits to be merged do exist, but the merge points don't and they are what I'm trying to push. To be clear, the branch hasn't seen any update for years, and I'm trying to reapply what happened on trunk since, in a step-wise manner. With 300 merges I'm summing up 6 commits of history. The number of merge points is a bit high (329) but I expected it to be a manageable number. I tried again today with just the most recent merge point, but it got stuck again. I should try with the oldest one, but I'm afraid locking the repository again. I waited for the push to finish for say one hour before killing it yesterday, and no more than 15 minutes today. Unfortunately, killing the process doesn't seem to unlock things on the server side. It may be a misconfiguration on my side, but I have never had this problem before. Sorry again. Perhaps you could create a mirror version of the repo and do some experiments locally on that to identify where the bottle-neck is coming from? Not sure where to start for that.Are the hooks published somewhere?
Re: gcc git locked out for hours second day in a row
On Wed, Jun 12, 2024 at 04:53:38PM +0200, Mikael Morin wrote: > > Perhaps you could create a mirror version of the repo and do some > > experiments locally on that to identify where the bottle-neck is coming > > from? > > > Not sure where to start for that.Are the hooks published somewhere? Yes: https://github.com/AdaCore/git-hooks/tree/master Note, we use some tweaks on top of that, but that is mostly for the release branches and trunk, so it would be interesting to just try to reproduce that with the stock AdaCore git hooks. Jakub
Re: Question about optimizing function pointers for direct function calls
Hi Richard, Thanks for your reply. I'm looking forward to hearing from Honza! But I still have a small question about the IPA passes. If I want to make such a conversion (sum += foo[i].add == add ? add (1,2) : foo[i].add (1,2);), I definitely need to change the function's body. But the article "Using summary information in IPA passes"(https://gcc.gnu.org/onlinedocs/gccint/link-time-optimization/using-summary- Information-in-ipa-passes.html) mentioned that if IPA-Pass needs to change the function body, it needs to be done in the transform stage, but the execution stage of IPA-inline has ended before the transform stage. So we still can’t mark the newly created function calls/cgraph_edge as inlineable. Is that correct? Or did I understand something wrong? Thanks Hanke Zhang Richard Biener 于2024年6月12日周三 18:49写道: > > On Wed, Jun 12, 2024 at 11:57 AM Hanke Zhang wrote: > > > > Richard Biener 于2024年5月24日周五 14:39写道: > > > > > > On Fri, May 24, 2024 at 5:53 AM Hanke Zhang via Gcc > > > wrote: > > > > > > > > Hi, > > > > I got a question about optimizing function pointers for direct > > > > function calls in C. > > > > > > > > Consider the following scenario: one of the fields of a structure is a > > > > function pointer, and all its assignments come from the same function. > > > > Can all its uses be replaced by direct calls to this function? So the > > > > later passes can do more optimizations. > > > > > > > > Here is the example: > > > > > > > > int add(int a, int b) { return a + b; } > > > > int sub(int a, int b) { return a - b; } > > > > > > > > struct Foo { > > > > int (*add)(int, int); > > > > }; > > > > int main() > > > > { > > > > struct Foo foo[5] = malloc(sizeof(struct Foo) * 5); > > > > > > > > for (int i = 0; i < 5; i++) { > > > > foo[i].add = add; > > > > } > > > > > > > > int sum = 0; > > > > for (int i = 0; i < 5; i++) { > > > > sum += foo[i].add(1, 2); > > > > } > > > > > > > > return 0; > > > > } > > > > > > > > Can I replace the code above to the code below? > > > > > > > > int add(int a, int b) { return a + b; } > > > > int sub(int a, int b) { return a - b; } > > > > > > > > struct Foo { > > > > int (*add)(int, int); > > > > }; > > > > int main() > > > > { > > > > struct Foo foo[5] = malloc(sizeof(struct Foo) * 5); > > > > > > > > for (int i = 0; i < 5; i++) { > > > > foo[i].add = add; > > > > } > > > > > > > > int sum = 0; > > > > for (int i = 0; i < 5; i++) { > > > > sum += add(1,2); > > > > } > > > > > > > > return 0; > > > > } > > > > > > > > My idea is to determine whether the assignment of the field is the > > > > same function, and if so, perform the replacement. > > > > > > If it's as simple as above then sure, even CSE should do it. If you > > > can prove otherwise the memory location with the function pointer > > > always has the same value you are obviously fine. If you just > > > do not see any other store via 'add's FIELD_DECL then no, that > > > isn't good enough. Every void * store you do not know where it > > > goes might go to that slot. > > > > > > > Of course this is not a reasonable optimization, I just want to know > > > > if there are security issues in doing so, and if I want to do it in > > > > the IPA stage, is it possible? > > > > > > For the more general case you can do what we do for speculative > > > devirtualization - replace the code with > > > > > > sum += foo[i].add == add ? add (1,2) : foo[i].add(1,2); > > > > Hi Richard, > > > > I'm trying to do what you suggested. (sum += foo[i].add == add ? add > > (1,2) : foo[i].add(1,2);) > > > > I created a new IPA-Pass before IPA-INLINE and I made the changes on > > the GIMPLE in the "function_transform" stage. But my newly created > > "foo[i].add(1,2)" seems to fail to be inlined. And it was optimized > > out in the subsequent FRE. I would like to ask if there is any way to > > mark my newly created cgraph_edge as "inline" in the > > "function_transform" stage. > > > > Here is part of the code creating the call_stmt in true basic_block in > > my IPA-PASS: > > > > // ... > > // part of the code have been omitted > > auto_vec params; > > for (int i = 0; i < gimple_call_num_args (call_stmt); i++) { > > params.safe_push (gimple_call_arg (call_stmt, i)); > > } > > gimple* tbb_call = gimple_build_call_vec (fndecl, params); /// = fn() > > tree tbb_ssa; > > if (ret_val_flag) { > > tbb_ssa = make_ssa_name (TREE_TYPE (gimple_call_lhs(call_stmt)), NULL); > > gimple_call_set_lhs (tbb_call, tbb_ssa); /// _2 = fn() > > } > > gsi = gsi_start_bb (tbb); > > gsi_insert_before (&gsi, tbb_call, GSI_SAME_STMT); > > cgraph_edge* tbb_callee = node->create_edge (cgraph_node::get_create > > (fndecl), (gcall*)tbb_call, tbb_call->bb->count, true); > > // what should I do to this cgraph_edge to mark it to be inlined > > // ... > > > > Or should I not do these things in the function_transform stage? > > That's indeed too late. Y
Re: gcc git locked out for hours second day in a row
On Wed, 12 Jun 2024 at 14:23, Mikael Morin wrote: > > Le 12/06/2024 à 14:58, Jonathan Wakely a écrit : > > On Wed, 12 Jun 2024 at 13:57, Mikael Morin via Gcc wrote: > >> > >> Le 12/06/2024 à 13:48, Jakub Jelinek a écrit : > >>> Hi! > >>> > >>> Yesterday the gcc git repository was locked for 3 hours > >>> locked by user mikael at 2024-06-11 13:27:44.301067 (pid = 974167) > >>> 78:06 python hooks/update.py > >>> refs/users/mikael/tags/fortran-dev_merges/r10-1545 > >>> > >>> c2f9fe1d8111b9671bf0aa8362446516fd942f1d > >>> process until overseers killed it but today we have the same > >>> situation for 3 ours and counting again: > >>> locked by user mikael at 2024-06-12 08:35:48.137564 (pid = 2219652) > >>> 78:06 python hooks/update.py refs/users/mikael/tags/toto > >>> > >>> cca005166dba2cefeb51afac3ea629b3972acea3 > >>> > >>> It is possible we have some bug in the git hook scripts, but it would > >>> be helpful trying to understand what exactly you're trying to commit > >>> and why nobody else (at least to my knowledge) has similarly stuck > >>> commits. > >>> > >>> The effect is that nobody can push anything else to gcc git repo > >>> for hours. > >>> > >>>Jakub > >>> > >> Yes, sorry for the inconvenience. > >> I tried pushing a series of tags labeling merge points between the > >> fortran-dev branch and recent years master. > > > > Just pushing tags should not cause a problem, assuming all the commits > > being tagged already exist. What exactly are you pushing? > > > Well, the individual commits to be merged do exist, but the merge points > don't and they are what I'm trying to push. I see. Merge commits are still commits, so they get processed by the hooks. We don't even allow merge commits on trunk or the release branches, so I don't know how the hooks handle them. > To be clear, the branch hasn't seen any update for years, and I'm trying > to reapply what happened on trunk since, in a step-wise manner. With > 300 merges I'm summing up 6 commits of history. Yes, that's going to give the hooks a ton of work to do. So it's probably just the number of commits being pushed to the branch, not the fact they're merge commits (and certainly not the tags referring to any of those commits, which should be very cheap). If it was my branch, I'd be tempted to rebase the fortran_dev branch on trunk, instead of merging years and years of trunk commits into the ancient branch. Or create a new branch, say "fortran_dev_2", from trunk, then merge the fortran_dev branch into that, and push the new branch. That would presumably be a much smaller set of "new" commits relative to trunk, so much less work for the hooks.
Sourceware Open Office, Friday 16:00 UTC
Friday June 14, 16:00 UTC, irc.libera.chat #overseers To get the right time in your local timezone: $ date -d "Fri May 10 16:00:00 UTC 2024" - Discussion topic: https://sourceware.org/sourceware-security-vision.html The Sourceware infrastructure security vision explains what Sourceware is, the mission, how the organization works, the secure Sourceware project goals and plans. This includes not just infrastructure services updates, but also the secure software development framework projects use and secure supply chain issues. But feel free to drop in with any question or suggestion you have related to Sourceware infrastructure.
gcc-11-20240612 is now available
Snapshot gcc-11-20240612 is now available on https://gcc.gnu.org/pub/gcc/snapshots/11-20240612/ and on various mirrors, see https://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 11 git branch with the following options: git://gcc.gnu.org/git/gcc.git branch releases/gcc-11 revision e8d2679c0163f190984c6e5c20f17fe0ceec77fd You'll find: gcc-11-20240612.tar.xz Complete GCC SHA256=7aea7bd6460fb6e7d57a130ac7ce687dd390592a4d7372f9e3c3d4a930219451 SHA1=e25ba50d179a54b4ce1b3055e1c78db738799724 Diffs from 11-20240605 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-11 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
“ira_may_move_out_cost” vs “ira_register_move_cost”
Hi Vladimir, With my patch for PR111673 (scale the spill/restore cost of callee-save register with the frequency of the entry bb in the routine assign_hard_reg() : https://gcc.gnu.org/pipermail/gcc-patches/2023-October/631849.html), the following Linaro aarch64 test failed due to an extra 'mov' instruction: __SVBool_t __attribute__((noipa)) callee_pred (__SVBool_t p0, __SVBool_t p1, __SVBool_t p2, __SVBool_t p3, __SVBool_t mem0, __SVBool_t mem1) { p0 = svbrkpa_z (p0, p1, p2); p0 = svbrkpb_z (p0, p3, mem0); return svbrka_z (p0, mem1); } With trunk: addvl sp, sp, #-1 str p14, [sp] str p15, [sp, #1, mul vl] ldr p14, [x0] ldr p15, [x1] brkpa p0.b, p0/z, p1.b, p2.b brkpb p0.b, p0/z, p3.b, p14.b brkap0.b, p0/z, p15.b ldr p14, [sp] ldr p15, [sp, #1, mul vl] addvl sp, sp, #1 ret With patch: addvl sp, sp, #-1 str p14, [sp] str p15, [sp, #1, mul vl] mov p14.b, p3.b // extra mov insn ldr p15, [x0] ldr p3, [x1] brkpa p0.b, p0/z, p1.b, p2.b brkpb p0.b, p0/z, p14.b, p15.b brkap0.b, p0/z, p3.b ldr p14, [sp] ldr p15, [sp, #1, mul vl] addvl sp, sp, #1 ret p0-p15 are predicate registers on aarch64 where p0-p3 are caller-save while p4-p15 are callee-save. The input RTL for ira pass: 1: set r112, r68#p0 2: set r113, r69#p1 3: set r114, r70#p2 4: set r115, r71#p3 5: set r116, x0 #mem0, the 5th parameter 6: set r108, mem(r116) 7: set r117, x1 #mem1, the 6th parameter 8: set r110, mem(r117) 9: set r100, unspec_brkpa(r112, r113, r114) 10: set r101, unspec_brkpb(r100, r115, r108) 11: set r68, unspec_brka(r101, r110) 12: ret r68 Here, r68-r71 represent predicate hard regs p0-p3. With my patch, r113 and r114 are being assigned memory by ira but with trunk they are assigned registers. This in turn leads to a difference in decisions taken by LRA ultimately leading to the extra mov instruction. Register assignment w/ patch: Popping a5(r112,l0) -- assign reg p0 Popping a2(r100,l0) -- assign reg p0 Popping a0(r101,l0) -- assign reg p0 Popping a1(r110,l0) -- assign reg p3 Popping a3(r115,l0) -- assign reg p2 Popping a4(r108,l0) -- assign reg p1 Popping a6(r113,l0) -- (memory is more profitable 8000 vs 9000) spill! Popping a7(r114,l0) -- (memory is more profitable 8000 vs 9000) spill! Popping a8(r117,l0) -- assign reg 1 Popping a9(r116,l0) -- assign reg 0 With patch, cost of memory is 8000 and it is lesser than the cost of callee-save register (9000) and hence memory is assigned to r113 and r114. It is interesting to see that all the callee-save registers are free but none is chosen. The two instructions in which r113 is referenced are: 2: set r113, r69 #p1 9: set r100, unspec_brkpa(r112, r113, r114) IRA computes the memory cost of an allocno in find_costs_and_classes(). In this routine IRA scans each insn and computes memory cost and cost of register classes for each operand in the insn. So for insn 2, memory cost of r113 is set to 4000 because this is the cost of storing r69 to memory if r113 is assigned to memory. The possible register classes of r113 are ALL_REGS, PR_REGS, PR_HI_REGS and PR_LO_REGS. The cost of moving r69 to r113 if r113 is assigned a register from each of the possible register classes is computed. If r113 is assigned a reg in ALL_REGS, then the cost of the move is 18000, while if r113 is assigned a register from any of the predicate register classes, then the cost of the move is 2000. This cost is obtained from the array “ira_register_move_cost”. After scanning insn 9, memory cost of r113 is increased to 8000 because if r113 is assigned memory, we need a load to read the value before using it in the unspec_brkpa. But the register class cost is unchanged. Later in setup_allocno_class_and_costs(), the ALLOCNO_CLASS of r113 is set to PR_REGS. The ALLOCNO_MEMORY_COST of r113 is set to 8000. The ALLOCNO_HARD_REG_COSTS of each register in PR_REGS is set to 2000. During coloring, when r113 has to be assigned a register, the cost of callee-save registers in PR_REGS is increased by the spill/restore cost. So the cost of callee-save registers increases from 2000 to 9000. All the caller-save registers have been assigned to other allocnos, so for r113 memory is assigned as memory is cheaper than callee-save registers. However, for r108, the cost is 0 for register classes PR_REGS, PR_HI_REGS and PR_LO_REGS. References of r108: 6: set r108, mem(r116) 10: set r101, unspec_brkpb(r100, r115, r108) It was surprising that while for r113, the cost of the predicate register classes was 2000, for r10