#include "llvm/Transforms/Scalar.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Instructions.h"
-#include "llvm/LLVMContext.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/Dominators.h"
/// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated
/// byte store (e.g. i16 0x1234), return null.
static Value *isBytewiseValue(Value *V) {
- LLVMContext &Context = V->getContext();
-
// All byte-wide stores are splatable, even of arbitrary variables.
if (V->getType()->isIntegerTy(8)) return V;
// corresponding integer value is "byteable". An important case is 0.0.
if (ConstantFP *CFP = dyn_cast<ConstantFP>(V)) {
if (CFP->getType()->isFloatTy())
- V = ConstantExpr::getBitCast(CFP, Type::getInt32Ty(Context));
+ V = ConstantExpr::getBitCast(CFP, Type::getInt32Ty(V->getContext()));
if (CFP->getType()->isDoubleTy())
- V = ConstantExpr::getBitCast(CFP, Type::getInt64Ty(Context));
+ V = ConstantExpr::getBitCast(CFP, Type::getInt64Ty(V->getContext()));
// Don't handle long double formats, which have strange constraints.
}
if (Val != Val2)
return 0;
}
- return ConstantInt::get(Context, Val);
+ return ConstantInt::get(V->getContext(), Val);
}
}
return false;
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+
+ // Verify that the copied-from memory doesn't change in between the two
+ // transfers. For example, in:
+ // memcpy(a <- b)
+ // *b = 42;
+ // memcpy(c <- a)
+ // It would be invalid to transform the second memcpy into memcpy(c <- b).
+ //
+ // TODO: If the code between M and MDep is transparent to the destination "c",
+ // then we could still perform the xform by moving M up to the first memcpy.
+ //
+ // NOTE: This is conservative, it will stop on any read from the source loc,
+ // not just the defining memcpy.
+ MemDepResult SourceDep =
+ MD->getPointerDependencyFrom(AA.getLocationForSource(MDep),
+ false, M, M->getParent());
+ if (!SourceDep.isClobber() || SourceDep.getInst() != MDep)
+ return false;
// If the dest of the second might alias the source of the first, then the
// source and dest might overlap. We still want to eliminate the intermediate
ConstantInt::get(Type::getInt32Ty(MemCpyFun->getContext()), Align),
M->getVolatileCst()
};
- CallInst *C = CallInst::Create(MemCpyFun, Args, Args+5, "", M);
-
-
- // Verify that the copied-from memory doesn't change in between the two
- // transfers. For example, in:
- // memcpy(a <- b)
- // *b = 42;
- // memcpy(c <- a)
- // It would be invalid to transform the second memcpy into memcpy(c <- b).
- //
- // TODO: If the code between M and MDep is transparent to the destination "c",
- // then we could still perform the xform by moving M up to the first memcpy.
- MemDepResult NewDep = MD->getDependency(C);
- if (!NewDep.isClobber() || NewDep.getInst() != MDep) {
- MD->removeInstruction(C);
- C->eraseFromParent();
- return false;
- }
+ CallInst::Create(MemCpyFun, Args, Args+5, "", M);
- // Otherwise we're good! Nuke the instruction we're replacing.
+ // Remove the instruction we're replacing.
MD->removeInstruction(M);
M->eraseFromParent();
++NumMemCpyInstr;
TargetData *TD = getAnalysisIfAvailable<TargetData>();
if (!TD) return false;
+ // Find out what feeds this byval argument.
Value *ByValArg = CS.getArgument(ArgNo);
-
- // MemDep doesn't have a way to do a local query with a memory location.
- // Instead, just insert a load and ask for its dependences.
- LoadInst *TmpLoad = new LoadInst(ByValArg, "", CS.getInstruction());
- MemDepResult DepInfo = MD->getDependency(TmpLoad);
-
- MD->removeInstruction(TmpLoad);
- TmpLoad->eraseFromParent();
-
+ const Type *ByValTy =cast<PointerType>(ByValArg->getType())->getElementType();
+ uint64_t ByValSize = TD->getTypeAllocSize(ByValTy);
+ MemDepResult DepInfo =
+ MD->getPointerDependencyFrom(AliasAnalysis::Location(ByValArg, ByValSize),
+ true, CS.getInstruction(),
+ CS.getInstruction()->getParent());
if (!DepInfo.isClobber())
return false;
return false;
// The length of the memcpy must be larger or equal to the size of the byval.
- // must be larger than the following one.
ConstantInt *C1 = dyn_cast<ConstantInt>(MDep->getLength());
- if (C1 == 0 ||
- C1->getValue().getZExtValue() < TD->getTypeAllocSize(ByValArg->getType()))
+ if (C1 == 0 || C1->getValue().getZExtValue() < ByValSize)
return false;
// Get the alignment of the byval. If it is greater than the memcpy, then we
// *b = 42;
// foo(*a)
// It would be invalid to transform the second memcpy into foo(*b).
+ //
+ // NOTE: This is conservative, it will stop on any read from the source loc,
+ // not just the defining memcpy.
+ MemDepResult SourceDep =
+ MD->getPointerDependencyFrom(AliasAnalysis::getLocationForSource(MDep),
+ false, CS.getInstruction(), MDep->getParent());
+ if (!SourceDep.isClobber() || SourceDep.getInst() != MDep)
+ return false;
+
Value *TmpCast = MDep->getSource();
if (MDep->getSource()->getType() != ByValArg->getType())
TmpCast = new BitCastInst(MDep->getSource(), ByValArg->getType(),
"tmpcast", CS.getInstruction());
- Value *TmpVal =
- UndefValue::get(cast<PointerType>(TmpCast->getType())->getElementType());
- Instruction *TmpStore = new StoreInst(TmpVal, TmpCast, false,
- CS.getInstruction());
- DepInfo = MD->getDependency(TmpStore);
- bool isUnsafe = !DepInfo.isClobber() || DepInfo.getInst() != MDep;
- MD->removeInstruction(TmpStore);
- TmpStore->eraseFromParent();
-
- if (isUnsafe) {
- // Clean up the inserted cast instruction.
- if (TmpCast != MDep->getSource())
- cast<Instruction>(TmpCast)->eraseFromParent();
- return false;
- }
-
+
DEBUG(dbgs() << "MemCpyOpt: Forwarding memcpy to byval:\n"
<< " " << *MDep << "\n"
<< " " << *CS.getInstruction() << "\n");