[PATCH] [InstCombine] Attempt to eliminate redundant loads whose addresses are dependent on the result of a select instruction.
Chad Rosier
mcrosier at codeaurora.org
Fri Sep 19 10:32:30 PDT 2014
Lastly, do you think we could extend this work to handle something like
the following:
while (i < e) {
if (agg[i+1]->field < agg[i]->field)
++i;
if (agg[i]->field > agg[j]->field)
break;
...
...
}
These two expressions seem equivalent:
agg[i+1]->field // 1st if statement
and
++i
agg[i]->field // 2nd if statement
However, I'm seeing a redundant load for agg[i]->field in the 2nd if
statement.
(Honestly, I feel like this patch is what would resolve this issue, but
I'm not 100%.)
Here is what I saw on AArch64 a while ago (~2 months):
ldr x16, [x8, w14, sxtw #3] x16 = &agg[i]
ldr x17, [x8, w15, sxtw #3] x17 = &agg[i+1]
ldr s0, [x16, #4] s0 = agg[i]->field
ldr s1, [x17, #4] s1 = agg[i+1]->field
fcmp s1, s0
csel w14, w15, w14, lt
ldr x16, [x8, w14, sxtw #3] <==== load is redundant (and I believe your
patch would address this)
ldr s0, [x16, #4] <==== load is redundant (but not this)
ldr s1, [x12, #4] s1 = agg[j]->field
fcmp s0, s1
b.gt .LBB8_7 // while exit
And I think we could generate something like this:
fcmp s1, s0
csel w14, w15, w14, lt
csel x16, x17, x16, lt <==== reuse value in x17/x16
fcsel s0, s1, s0, lt <==== reuse value in s1/s0
Hopefully, this makes sense. If not, I'm happy to clarify.
Chad
> Tilmann,
> Would you consider filing a bug with an outline of the proposed solution?
> I'd hate for this work to stall in your low priority queue for too long;
> happens to me all the time. Perhaps, someone else might consider picking
> up the work?
>
> Also, is there a specific benchmark you're targeting? We're doing a lot
> of AArch64 tuning on my end and I'm trying to track which changes are
> effecting which benchmarks. If there's a big enough win, I might be able
> to redirect my work and address this on your behalf (assuming you don't
> mind). Please let me know.
>
> Chad
>
>> Hi Chad,
>>
>> thanks for the review!
>>
>> I discussed this earlier this week with David on IRC and he pointed me
>> to
>> the PHITransAddr class, suggesting to implement something similar for
>> selects. That way GVN doesn't need to know much about selects and
>> everything
>> will just go through MemDep.
>>
>> I think this is a much better solution but I haven't actually started
>> working on it (and most likely won't be able to for the next couple of
>> weeks).
>>
>> Regards,
>>
>> Tilmann
>>
>> -----Original Message-----
>> From: Chad Rosier [mailto:mcrosier at codeaurora.org]
>> Sent: Thursday, September 18, 2014 4:46 AM
>> To: Tilmann Scheller
>> Cc: 'David Majnemer'; llvm-commits at cs.uiuc.edu
>> Subject: RE: [PATCH] [InstCombine] Attempt to eliminate redundant loads
>> whose addresses are dependent on the result of a select instruction.
>>
>> Tilmann,
>> GVN is certainly not my area, but hopefully my comments will be helpful.
>> Overall, the patch LGTM, but perhaps David or others have additional
>> comments (i.e., I'm not the right person to approve this patch :).
>>
>> +// Helper function for OptimizeLoadGEPSelect().
>> +static bool IsMatchingLoadGEP(Value *Inst, GetElementPtrInst *BaseGEP,
>> + Value *&SecondIdx) {
>>
>> Hoist isa load logic out and add an assert(isa<LoadInst>(Inst) &&
>> "Expected
>> Load");
>>
>> + bool FoundTrue = false;
>> + bool FoundFalse = false;
>>
>> These two booleans, FoundTrue and FoundFalse, seem redundant with
>> LoadTrue
>> and LoadFalse, respectively.
>>
>> + Value *LoadTrue = nullptr;
>> + Value *LoadFalse = nullptr;
>>
>> + while (ScanFrom != ScanBB->begin() &&
>> + !(FoundTrue && FoundFalse)) {
>>
>> How about reusing LoadTrue and LoadFalse?
>>
>> !(LoadTrue && LoadFalse)
>>
>> + Instruction *Inst = --ScanFrom;
>> +
>> + // Just give up if memory is potentially modified.
>> + if (Inst->mayWriteToMemory()) {
>> + return nullptr;
>> + }
>>
>> Curly braces not necessary:
>>
>> if (Inst->mayWriteToMemory())
>> return nullptr;
>>
>>
>> + Value *SecondIdx = nullptr;
>> + if (IsMatchingLoadGEP(Inst, GEPI, SecondIdx)) {
>>
>> Hoist the isa load check out of the help function?
>>
>> if (isa<LoadInst>(Inst) && IsMatchingLoadGEP(Inst, GEPI, SecondIdx)
>>
>> + // All preconditions fulfilled, apply the transformation:
>> + if (FoundTrue && FoundFalse)
>>
>> How about?
>>
>> if (LoadTrue && LoadFalse)
>>
>> I would like to see this go in as I've seen this issue in the past.
>>
>> Chad
>>
>>> Hi David,
>>>
>>> attached is a new patch which is now doing the transformation in GVN.
>>>
>>> The bulk of the patch is still the same, I didn't find much logic
>>> within GVN which I could reuse, if there's any obvious way to simplify
>>> the patch please let me know :)
>>>
>>> Nonetheless, the optimization is now in close distance to the other
>>> redundant load optimizations.
>>>
>>> Regards,
>>>
>>> Tilmann
>>>
>>> -----Original Message-----
>>> From: Tilmann Scheller [mailto:t.scheller at samsung.com]
>>> Sent: Thursday, September 04, 2014 8:23 AM
>>> To: 'David Majnemer'
>>> Cc: 'llvm-commits at cs.uiuc.edu'
>>> Subject: RE: [PATCH] [InstCombine] Attempt to eliminate redundant
>>> loads whose addresses are dependent on the result of a select
>>> instruction.
>>>
>>> Hi David,
>>>
>>> fair enough, I'll try to figure out how to implement this in GVN then
>>> :)
>>>
>>> Regards,
>>>
>>> Tilmann
>>>
>>> From: David Majnemer [mailto:david.majnemer at gmail.com]
>>> Sent: Thursday, September 04, 2014 12:15 AM
>>> To: Tilmann Scheller
>>> Cc: llvm-commits at cs.uiuc.edu
>>> Subject: Re: [PATCH] [InstCombine] Attempt to eliminate redundant
>>> loads whose addresses are dependent on the result of a select
>>> instruction.
>>>
>>> Hi Tilmann,
>>>
>>> I don't think this a natural place to do this, I'm of the opinion that
>>> we should try to get GVN to do this sort of thing.
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>
>>
>>
>>
>
>
>
More information about the llvm-commits
mailing list