X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FScalar%2FGVN.cpp;h=481956f6b4ce039dbb5307cc558372ce9e4c5d06;hb=61d30a821f372ca4185fc518023f857fbcb9c0f5;hp=26f7cb1630a36aafbc52a7f85327c646285f5b1b;hpb=9cffa9a6ed754a480dc73db0e8a5b0d846ba2dde;p=oota-llvm.git diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 26f7cb1630a..481956f6b4c 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1083,6 +1083,8 @@ static bool isReturnSlotOptznProfitable(Value* dest, MemCpyInst* cpy) { /// rather than using memcpy bool GVN::performReturnSlotOptzn(MemCpyInst* cpy, CallInst* C, SmallVector& toErase) { + // Deliberately get the source and destination with bitcasts stripped away, + // because we'll need to do type comparisons based on the underlying type. Value* cpyDest = cpy->getDest(); Value* cpySrc = cpy->getSource(); CallSite CS = CallSite::get(C); @@ -1097,23 +1099,25 @@ bool GVN::performReturnSlotOptzn(MemCpyInst* cpy, CallInst* C, !CS.paramHasAttr(1, ParamAttr::NoAlias | ParamAttr::StructRet)) return false; - // We only perform the transformation if it will be profitable. - if (!isReturnSlotOptznProfitable(cpyDest, cpy)) - return false; - // Check that something sneaky is not happening involving casting // return slot types around. if (CS.getArgument(0)->getType() != cpyDest->getType()) return false; + // sret --> pointer + const PointerType* PT = cast(cpyDest->getType()); // We can only perform the transformation if the size of the memcpy // is constant and equal to the size of the structure. - if (!isa(cpy->getLength())) + ConstantInt* cpyLength = dyn_cast(cpy->getLength()); + if (!cpyLength) return false; - ConstantInt* cpyLength = cast(cpy->getLength()); TargetData& TD = getAnalysis(); - if (TD.getTypeStoreSize(cpyDest->getType()) == cpyLength->getZExtValue()) + if (TD.getTypeStoreSize(PT->getElementType()) != cpyLength->getZExtValue()) + return false; + + // We only perform the transformation if it will be profitable. + if (!isReturnSlotOptznProfitable(cpyDest, cpy)) return false; // In addition to knowing that the call does not access the return slot @@ -1135,6 +1139,7 @@ bool GVN::performReturnSlotOptzn(MemCpyInst* cpy, CallInst* C, MD.dropInstruction(C); // Remove the memcpy + MD.removeInstruction(cpy); toErase.push_back(cpy); return true; @@ -1220,13 +1225,11 @@ bool GVN::processInstruction(Instruction* I, if (dep == MemoryDependenceAnalysis::None || dep == MemoryDependenceAnalysis::NonLocal) return false; - else if (CallInst* C = dyn_cast(dep)) { - if (!isa(C)) - return performReturnSlotOptzn(M, C, toErase); - } else if (!isa(dep)) - return false; - - return processMemCpy(M, cast(dep), toErase); + if (MemCpyInst *MemCpy = dyn_cast(dep)) + return processMemCpy(M, MemCpy, toErase); + if (CallInst* C = dyn_cast(dep)) + return performReturnSlotOptzn(M, C, toErase); + return false; } unsigned num = VN.lookup_or_add(I);