[LLVMdev] [PATCH] PR2218

Chris Lattner clattner at apple.com
Wed Jul 22 17:51:33 PDT 2009


On Jul 22, 2009, at 1:37 PM, Jakub Staszak wrote:

> Hello,
>
> This patch fixes PR2218.

Very nice.  Are you sure this fixes PR2218?  The example there doesn't  
have any loads in it.

>  However, I'm not pretty sure that this optimization should be in  
> MemCpyOpt. I think that GVN is good place as well.

Yes, you're right.  My long term goal is to merge the relevant pieces  
of memcpyopt into GVN/DSE at some point.  To do that, some more major  
surgery needs to be done to memdep to make it work both backward (to  
support GVN) and forward (to support DSE).  In the meantime, enhancing  
memcpyopt is fine, so long as there are good testcases (and your patch  
has them!).

Nit picky stuff about the patch:

+    for(unsigned argI = 0; argI < CS.arg_size(); ++argI) {
+      if(CS.getArgument(argI)->stripPointerCasts() == pointer)

Please put spaces after if/for.  You get this right in some places,  
but wrong in others.

+  Value* pointer = L->getPointerOperand();

Please use "Value *pointer" style throughout.  It looks like MemCpyOpt  
is already really inconsistent about this :-/ but please don't make it  
worse :).

+    /* Pointer must be a parameter (case 1) */

please use C++ style // comments.



Some other points:
1. I don't see a check that the load isn't volatile, please don't hack  
volatile loads.

2. The dependency check is relatively expensive, so please reorder it  
to be checked after the check for alloca:

+  Value* pointer = L->getPointerOperand();
+  MemDepResult dep = MD.getDependency(L);
+
+  // Require pointer to have local dependency.
+  if(!dep.getInst() || dep.isNonLocal())
+    return false;
+
+  // Require pointer to be an alloca.
+  if(!isa<AllocaInst>(pointer))
+    return false;


3. In this code, does the argument also need to be sret, or is any  
argument ok?

+  if(CallInst *C = dyn_cast<CallInst>(dep.getInst())) {
+    CallSite CS = CallSite::get(C);
+
+    /* Pointer must be a parameter (case 1) */
+    if(!CS.hasArgument(pointer))
+      return false;

4. Here, please do an alias check if the store's pointer operand is  
not the same as the load's (allowing the xform if they are must- 
alias).  This helps in some cases where there are GEP's that are the  
same but not actually CSE'd:

+    /* Store cannot be volatile (case 2) */
+    if(S->getPointerOperand() != pointer || S->isVolatile())
+      return false;


5. In the logic for your xform, I don't see any check to see if the  
alloca itself has uses other than the load/store.  In this example,  
won't it miscompile the code by eliminating the store into temporary?

    %temporary = alloca i8
    call void @initialize(i8* noalias sret %temporary)
    %tmp = load i8* %temporary
    store i8 %tmp, i8* %result
    %tmp2 = load i8* %temporary
       ...

6.  In the xform part of the code, you strip pointer casts, but you  
don't do that in the argument checking part, why?

+    for(unsigned argI = 0; argI < CS.arg_size(); ++argI) {
+      if(CS.getArgument(argI)->stripPointerCasts() == pointer)

Thanks for working on this area, I'm glad to see it getting attention!

-Chris



More information about the llvm-dev mailing list