Re: Question about gimple code during optimizing if-conversion
On Fri, Oct 13, 2023 at 10:16 PM Hanke Zhang via Gcc wrote: > > Hi, I'm working on optimizing if-conversion for my own business > recently. I got a problem here. > > I tried to optimize it in such a case, for example, when a conditional > statement block has only if statement and no else statement, the > source C code looks like this: > > int* foo; // assume this has been initialized > int c = rand(), t = rand(), size = 1000; > for (int i = 0; i < size; i++) { > if (foo[i] & (1 << c)) foo[i] ^= (1 << t); > } > > Part of its corresponding gimple is optimized like this before if-conversion: > > : > # i_71 = PHI > # ivtmp_9 = PHI > _5 = (long unsigned int) i_71; > _6 = _5 * 4; > _7 = foo_23 + _6; > _8 = *_7; > shifttmp_75 = _8 & shifttmp_76; > if (shifttmp_75 != 0) > goto ; [50.00%] > else > goto ; [50.00%] > >[local count: 531502205]: > goto ; [100.00%] > >[local count: 531502204]: > _12 = _8 ^ _11; > *_7 = _12; > >[local count: 1063004409]: > i_39 = i_71 + 1; > ivtmp_73 = ivtmp_9 - 1; > if (ivtmp_73 != 0) > goto ; [99.00%] > else > goto ; [1.00%] > > I want to add some statements to gimple to make it like adding an else > block to the source code. > > // What I expected: > int* foo; // assume this has been initialized > int c = rand(), t = rand(), size = 1000; > for (int i = 0; i < size; i++) { > if (foo[i] & (1 << c)) foo[i] ^= (1 << t); > + else foo[i] = foo[i]; // I want to add a statment here ! > } > > And of course I can't change the source code for real, so I can only > add a pass in front of if-conversion to modify the gimple. > > For the example above, I know that I have to add them in the block > '', but what confuses me is that I don't know what kind of > statement to add to be legal due to my poor experience. > > I try to add something like this below, but the compile error just > happened. So I'm here for help. What kind of statements should I add > here? > > [local count: 531502205]: > + *_7 = *_7 > goto ; [100.00%] > > Finally, The reason I did this was to avoid MASK_STORE generation, > because it might add an if branch in the final assembly which I don't > like it to be. And after such a modification, if-conversion should > have been changed it to the form of a ternary expression, which would > reduce the occurrence of branches after final vectorization and > produce more efficient code. > > Or there if is a better way to get rid of MASK_STORE, please tell me > about that. :) So there are 2 issues with this transformation which you need to take into account. 1) C11/C++11 threading model (-fallow-store-data-races is needed) 2) foo could be read only and cause a trap if written to. if the branch is never taken there would be no writes Thanks, Andrew Pinski > > Thanks > Hanke Zhang
Re: Question about gimple code during optimizing if-conversion
On 10/14/23 09:49, Andrew Pinski via Gcc wrote: On Fri, Oct 13, 2023 at 10:16 PM Hanke Zhang via Gcc wrote: Hi, I'm working on optimizing if-conversion for my own business recently. I got a problem here. I tried to optimize it in such a case, for example, when a conditional statement block has only if statement and no else statement, the source C code looks like this: int* foo; // assume this has been initialized int c = rand(), t = rand(), size = 1000; for (int i = 0; i < size; i++) { if (foo[i] & (1 << c)) foo[i] ^= (1 << t); } Part of its corresponding gimple is optimized like this before if-conversion: : # i_71 = PHI # ivtmp_9 = PHI _5 = (long unsigned int) i_71; _6 = _5 * 4; _7 = foo_23 + _6; _8 = *_7; shifttmp_75 = _8 & shifttmp_76; if (shifttmp_75 != 0) goto ; [50.00%] else goto ; [50.00%] [local count: 531502205]: goto ; [100.00%] [local count: 531502204]: _12 = _8 ^ _11; *_7 = _12; [local count: 1063004409]: i_39 = i_71 + 1; ivtmp_73 = ivtmp_9 - 1; if (ivtmp_73 != 0) goto ; [99.00%] else goto ; [1.00%] I want to add some statements to gimple to make it like adding an else block to the source code. // What I expected: int* foo; // assume this has been initialized int c = rand(), t = rand(), size = 1000; for (int i = 0; i < size; i++) { if (foo[i] & (1 << c)) foo[i] ^= (1 << t); + else foo[i] = foo[i]; // I want to add a statment here ! } And of course I can't change the source code for real, so I can only add a pass in front of if-conversion to modify the gimple. For the example above, I know that I have to add them in the block '', but what confuses me is that I don't know what kind of statement to add to be legal due to my poor experience. I try to add something like this below, but the compile error just happened. So I'm here for help. What kind of statements should I add here? [local count: 531502205]: + *_7 = *_7 goto ; [100.00%] Finally, The reason I did this was to avoid MASK_STORE generation, because it might add an if branch in the final assembly which I don't like it to be. And after such a modification, if-conversion should have been changed it to the form of a ternary expression, which would reduce the occurrence of branches after final vectorization and produce more efficient code. Or there if is a better way to get rid of MASK_STORE, please tell me about that. :) So there are 2 issues with this transformation which you need to take into account. 1) C11/C++11 threading model (-fallow-store-data-races is needed) 2) foo could be read only and cause a trap if written to. if the branch is never taken there would be no writes Right. See ifcvt_memrefs_wont_trap. That probably could be extended to capture additional cases. But I'm not sure that'll be sufficient for Hanke's problem. Jeff
gcc-13-20231014 is now available
Snapshot gcc-13-20231014 is now available on https://gcc.gnu.org/pub/gcc/snapshots/13-20231014/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 13 git branch with the following options: git://gcc.gnu.org/git/gcc.git branch releases/gcc-13 revision a9f39860efa645149ec88f0e9a7a31c3362b7e46 You'll find: gcc-13-20231014.tar.xz Complete GCC SHA256=40bf42e54cefefa4a8f35c48e0f290c9ef8118eee9a72800296a0e620dfb0240 SHA1=c7fa5bd8478bbc42556b25bc5e8b0c1c1dff1cdd Diffs from 13-20231007 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-13 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.