[llvm-commits] [PATCH] Make EarlyCSE understand commutativity

Evan Cheng evan.cheng at apple.com
Mon Sep 24 12:55:16 PDT 2012


On Sep 24, 2012, at 9:46 AM, Michael Ilseman <milseman at apple.com> wrote:

> 
> On Sep 22, 2012, at 3:01 AM, Duncan Sands <baldrick at free.fr> wrote:
> 
>> Hi Michael,
>> 
>>>> The attached patch and tests alter EarlyCSE to also check for commuted values. This allows EarlyCSE to replace:
>>>> 
>>>> t1 = fadd a, b
>>>> t2 = fadd b, a
>>>> 
>>>> with:
>>>> t1 = fadd a, b
>> 
>> -ENOTESTCASE.
>> 
> 
> Tests cases were in the commute.ll file that was attached along with the patch.
> 
>>> @@ -397,8 +398,30 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
>>> 
>>>    // If this is a simple instruction that we can value number, process it.
>>>    if (SimpleValue::canHandle(Inst)) {
>>> +
>>>      // See if the instruction has an available value.  If so, use it.
>>> -      if (Value *V = AvailableValues->lookup(Inst)) {
>>> +      Value *V = AvailableValues->lookup(Inst);
>>> +
>>> +      // If this is a commutative op, also see if its commuted value is
>>> +      // available.
>>> +      if (!V) {
>>> +        if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Inst)) {
>>> +          if (BinOp->isCommutative()) {
>>> +            BinaryOperator *Commuted = cast<BinaryOperator>(BinOp->clone());
>>> +            Commuted->swapOperands();
>>> +            V = AvailableValues->lookup(Commuted);
>>> +            ilist_node_traits<Instruction>::deleteNode(Commuted);
>> 
>> urgh, I really don't like creating an instruction just to look it up, then
>> deleting it again.  Can you make the lookup logic more flexible instead?
>> By the way, how GVN takes care of commutativity is: when computing the value
>> number for an instruction, it sorts the operands of commutative instructions
>> (its sorts the operands according to their value number) before calculating
>> a value number from them, ensuring that if two commutative instructions are
>> the same except for a different operand order then they get the same value
>> number.  I don't know how EarlyCSE works, but maybe something along these lines
>> would also be possible?
>> 
> 
> Thanks for the feedback!
> 
> I also don't like making a new instruction, but considered it the lesser of evils. Essentially, EarlyCSE uses a DenseMap over the instructions, but overloading hash to hash the instruction itself rather than its address. It also overloads isEqual to call Instruction::isIdenticalTo.
> 
> As far as changing the lookup mechanism, that would involve both sorting operand hashes on getHashValue, and extending Instruction::isIdenticalToWhenDefined to also calculate equality modulo commutativity (or, essentially inlining its body into the overloaded isEqual function rather than making the call). I don't know what is more desirable, but the original patch to EarlyCSE at least kept it very localized and would only trigger when a commutative op was encountered.
> 
> Another option is to restructure EarlyCSE to do expression numbering similarly to GVN, as you mentioned. Again, I don't know if this is more desirable over a localized call to clone(), as this would require a re-encapsulation of Instruction's data that would affect all of EarlyCSE.

I would strong advise against the new instruction approach. That's considered a definite no-no in LLVM. Do you have a good sense how much effort it is to implement expression numbering?

Evan

> 
> 
> 
>> Ciao, Duncan.
>> 
>>> +          }
>>> +        } else if (CmpInst *CI = dyn_cast<CmpInst>(Inst)) {
>>> +          // For CmpInst, swapping will also correct the predicate
>>> +          CmpInst *Commuted = cast<CmpInst>(CI->clone());
>>> +          Commuted->swapOperands();
>>> +          V = AvailableValues->lookup(Commuted);
>>> +          ilist_node_traits<Instruction>::deleteNode(Commuted);
>>> +        }
>>> +      }
>>> +
>>> +      if (V) {
>>>        DEBUG(dbgs() << "EarlyCSE CSE: " << *Inst << "  to: " << *V << '\n');
>>>        Inst->replaceAllUsesWith(V);
>>>        Inst->eraseFromParent();
>> 
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 
> _______________________________________________
> 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