From 35b9e48cfd315d3c7010f985a694d81c7c2ae5d0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 12 Oct 2004 04:52:52 +0000 Subject: [PATCH] Transform memmove -> memcpy when the source is obviously constant memory. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16932 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 763ffe1d019..2155b78b5d9 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -35,10 +35,8 @@ #define DEBUG_TYPE "instcombine" #include "llvm/Transforms/Scalar.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" -#include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" #include "llvm/Target/TargetData.h" @@ -3094,23 +3092,42 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { // CallInst simplification // Instruction *InstCombiner::visitCallInst(CallInst &CI) { + // Intrinsics cannot occur in an invoke, so handle them here instead of in // visitCallSite. - if (Function *F = CI.getCalledFunction()) - switch (F->getIntrinsicID()) { - case Intrinsic::memmove: - case Intrinsic::memcpy: - case Intrinsic::memset: - // memmove/cpy/set of zero bytes is a noop. - if (Constant *NumBytes = dyn_cast(CI.getOperand(3))) { - if (NumBytes->isNullValue()) - return EraseInstFromFunction(CI); - } - break; - default: - break; + if (MemIntrinsic *MI = dyn_cast(&CI)) { + bool Changed = false; + + // memmove/cpy/set of zero bytes is a noop. + if (Constant *NumBytes = dyn_cast(MI->getLength())) { + if (NumBytes->isNullValue()) return EraseInstFromFunction(CI); + + // FIXME: Increase alignment here. + + if (ConstantInt *CI = dyn_cast(NumBytes)) + if (CI->getRawValue() == 1) { + // Replace the instruction with just byte operations. We would + // transform other cases to loads/stores, but we don't know if + // alignment is sufficient. + } } + // If we have a memmove and the source operation is a constant global, + // then the source and dest pointers can't alias, so we can change this + // into a call to memcpy. + if (MemMoveInst *MMI = dyn_cast(MI)) + if (GlobalVariable *GVSrc = dyn_cast(MMI->getSource())) + if (GVSrc->isConstant()) { + Module *M = CI.getParent()->getParent()->getParent(); + Function *MemCpy = M->getOrInsertFunction("llvm.memcpy", + CI.getCalledFunction()->getFunctionType()); + CI.setOperand(0, MemCpy); + Changed = true; + } + + if (Changed) return &CI; + } + return visitCallSite(&CI); } -- 2.34.1