[llvm-commits] PR12385 PATCH: Missed constant propagation in loops

Stepan Dyatkovskiy stpworld at narod.ru
Thu Apr 19 00:42:56 PDT 2012


Hi all. I solved PR12385 issue: Missed constant propagation in loops.
LLVM and clang can't optimize next case:
int i;
void bar();
int main(){
   i = 0;
   int j;
   for(j = 0; j < 10000; ++j) {
     if (i)
       bar();
     i = 0;
   }
   return 0;
}

Ideally it should be folded to "int main() { return 0; }"

I improved Instruction Combining pass, so now it is possible to combine 
store + load instructions from different basic blocks.

The concept is next.
We need to scan BB graph. And if we found "X = load Addr" instruction 
predecessed with the same "store C, Addr" instructions in all its 
predecessors, we can replace the "load" with the stored value ("C").

[store C, Addr]   [store C, Addr]   [store C, Addr]
        \                 |                 /
         -------          |         -------
                 \        |       /
                   [X = load Addr] ==> X := C


There are some restrictions:
1. Store/Load address should be non-volatile and it should be constant.
2. The parent of "load" may be predecessed with some BB's that are still 
was not scanned (loops and BB's that marked as non-executable). In that 
case we should mark this load's as waiting until all predecessors will 
resolved; and after all executable edges and requested loops will 
scanned we can determine possibility of replacement.
3. If some predecessor chain doesn't contains any "store" or it contains 
"store" with the same address and different value, the "load" inst could 
NOT be converted to constant then:

       [store A, Addr]        [store C, Addr]
              \                     /
               -------       -------
                      \     /
                   [X = load Addr] ==> could NOT be replaced with a 
constant.

Data structure:
For tracking we will use TrackedStoreInsts map, that has format:
map<BB, StoreInstsInfo>
where
StoreInstsInfo is struct {
   set<BB> PendingBB;
   map<Address, StoreInst> Stores;
}

Algorithm:

Go over all executable edges, collect stores info and propogate it 
through the graph:

1. Go over executable edges
and for each BB do the next:
2. If BB contains predecessors that was not scanned before, we can't 
determine possibility of replacement "load" with "constant" in current 
BB, since we need to scan all predecessors before. So, add this 
predecessor to the TrackedStoreInsts[BB].PendingBB set.
3. Scan the BB instructions.
3.1. If we found "store" instruction and it uses constant non-volatile 
address, and it stores constant value, save it in 
TrackedStoreInsts[BB].Stores.
3.2. If we found "X = load Addr".
3.2.1. If TrackedStoreInsts[BB].Stores doesn't contains "store C, Addr" 
ignore it.
3.2.2. If TrackedStoreInsts[BB].PendingBBs is not empty(), scan each 
PendingBB, and if it was already tracked - remove it
from PendingBBs.
3.2.3. If TrackedStoreInsts[BB].Stores contains "store Addr, C"
3.2.3.1. If TrackedStoreInsts[BB].PendingBBs is empty, then replace 
"load" with "C".
3.2.3.2. If rackedStoreInsts[BB].PendingBBs is not empty, mark load as 
still unresolved.
4. If we reached TerminatorInst, propogate stores info for each its 
successor then:
4.1. Add all TrackedStoreInsts[BB].PendingBBs to the 
TrackedStoreInsts[Successor].PendingBBs.
4.2. Perform set intersection of TrackedStoreInsts[BB].Stores and 
TrackedStoreInsts[Successor].Stores and save it in the last one.
5. After all executable edges was scanned, resolve all remained "load"s:
get load's BB, and if we found corresponent "store" in 
TrackedStoreInsts[BB].Stores, then it is possible to replace load with 
constant, otherwise zap it.

P.S.: By now whis optimization is integrated into SCCP. But may be it is 
better to make separated pass. What do you think?


-Stepan
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr12385-5.patch
Type: text/x-patch
Size: 13566 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20120419/5a2d0f18/attachment.bin>


More information about the llvm-commits mailing list