[LLVMdev] [PATCH] PR2218
Jakub Staszak
kuba at gcc.gnu.org
Wed Sep 2 14:04:05 PDT 2009
On Sep 2, 2009, at 3:15 PM, Chris Lattner wrote:
> Please merge the three testcases into one file. We added a new
> FileCheck tool which allows you to check for the exact sequence of
> instructions expected, which also allows the tests to be merged into
> one file.
>
> +/// MemCpyOpt::pointerIsParameter - returns true iff pointer is a
> parameter of
> +/// C call instruction.
> +bool MemCpyOpt::pointerIsParameter(Value *pointer, CallInst *C,
> unsigned &argI)
> +{
> + CallSite CS = CallSite::get(C);
> + for (argI = 0; argI < CS.arg_size(); ++argI)
>
> Please make this a static function, it doesn't need "this". Also,
> please do something like this in the for loop:
>
> + for (argI = 0, CS.arg_size(); argI != argE; ++argI)
>
>
> pointerIsParameter returning a bool and the argument # byref is
> somewhat awkward. I think it would be better if it returned an int,
> which was -1 if not found.
The problem is that CS.arg_size() is "unsigned int". Of course, I can
cast int -> unsigned int but it wouldn't look good I think.
>
> + MemoryDependenceAnalysis& MD =
> getAnalysis<MemoryDependenceAnalysis>();
>
> You can sink this link to right before the call to MD.getDependency.
>
>
>
> + // Require pointer to have local dependency.
> + if (!dep.getInst() || dep.isNonLocal())
> + return false;
>
> Random thought: after this patch goes in, it would be interesting to
> see how many queries get rejected because they are non-local:
> handling non-local would be pretty easy. Please add a TODO that
> mentions this.
>
> In any case, the check for dep.isNonLocal() can be removed.
> Nonlocal queries have a null instruction.
OK, i'll work on it.
>
> + } else if (StoreInst *S = dyn_cast<StoreInst>(dep.getInst())) {
> ...
> + uint64_t ptrSize = AA.getTypeStoreSize(pointer->getType());
> ...
> + uint64_t memSize = AA.getTypeStoreSize(memPtr->getType());
> ...
> + if (AA.alias(pointer, ptrSize, memPtr, memSize) !=
> AliasAnalysis::MustAlias)
>
> This is passing in the size of the pointer, not the pointee.
> However, since you only care about must alias, you don't care about
> the size of the object, you can just pass in 1 for both sizes.
Ahh, last time you said I had to check sizes. You said:
"Knowing that the loaded and stored pointer must alias is important,
but you also need to check that the loaded and stored sizes equal each
other." :-)
> Please put a comment above the call to AA.alias explaining why you
> require mustalias here.
>
>
>
> + // Look for a replacement for our pointer. If more than one
> found, exit.
> + if (!L->hasOneUse())
> + return false;
> + StoreInst *StoreOfLoad = dyn_cast<StoreInst>(L->use_back());
> + if (!StoreOfLoad)
> + return false;
>
> Please do these check before the MemDep query, they are very cheap
> and will make the optimization run faster (by avoiding queries).
>
>
>
> I'm pretty sure that there is still a legality check missing here.
> Your code will transform this:
>
> %temporary = alloca i8
> call void @initialize(i8* noalias sret %temporary)
> %tmp = load i8* %temporary
> store i8 42, i8* %result
> store i8 %tmp, i8* %result
>
> to:
>
> %temporary = alloca i8
> call void @initialize(i8* noalias sret %result)
> store i8 42, i8* %result
>
> which is a miscompilation. To fix this, I'd do a memdep query of
> "result" from StoreOfLoad and from L. If they both have the same
> dependence, then the transform is ok.
See PR2218-dont.ll test.
-Jakub
More information about the llvm-dev
mailing list