Skip to content

Commit

Permalink
[ARM] Implement TTI::getMemcpyCost
Browse files Browse the repository at this point in the history
This implements TargetTransformInfo method getMemcpyCost, which estimates the
number of instructions to which a memcpy instruction expands to.

Differential Revision: https://reviews.llvm.org/D59787

llvm-svn: 359547
  • Loading branch information
Sjoerd Meijer committed Apr 30, 2019
1 parent 9a7ccd0 commit ea31ddb
Show file tree
Hide file tree
Showing 4 changed files with 705 additions and 4 deletions.
6 changes: 6 additions & 0 deletions llvm/lib/Analysis/TargetTransformInfo.cpp
Expand Up @@ -584,6 +584,12 @@ int TargetTransformInfo::getAddressComputationCost(Type *Tp,
return Cost;
}

int TargetTransformInfo::getMemcpyCost(const Instruction *I) const {
int Cost = TTIImpl->getMemcpyCost(I);
assert(Cost >= 0 && "TTI should not produce negative costs!");
return Cost;
}

int TargetTransformInfo::getArithmeticReductionCost(unsigned Opcode, Type *Ty,
bool IsPairwiseForm) const {
int Cost = TTIImpl->getArithmeticReductionCost(Opcode, Ty, IsPairwiseForm);
Expand Down
35 changes: 35 additions & 0 deletions llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp
Expand Up @@ -21,6 +21,7 @@
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Type.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/Casting.h"
Expand Down Expand Up @@ -401,6 +402,40 @@ int ARMTTIImpl::getAddressComputationCost(Type *Ty, ScalarEvolution *SE,
return 1;
}

int ARMTTIImpl::getMemcpyCost(const Instruction *I) {
const MemCpyInst *MI = dyn_cast<MemCpyInst>(I);
assert(MI && "MemcpyInst expected");
ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength());

// To model the cost of a library call, we assume 1 for the call, and
// 3 for the argument setup.
const unsigned LibCallCost = 4;

// If 'size' is not a constant, a library call will be generated.
if (!C)
return LibCallCost;

const unsigned Size = C->getValue().getZExtValue();
const unsigned DstAlign = MI->getDestAlignment();
const unsigned SrcAlign = MI->getSourceAlignment();
const Function *F = I->getParent()->getParent();
const unsigned Limit = TLI->getMaxStoresPerMemmove(F->hasMinSize());
std::vector<EVT> MemOps;

// MemOps will be poplulated with a list of data types that needs to be
// loaded and stored. That's why we multiply the number of elements by 2 to
// get the cost for this memcpy.
if (getTLI()->findOptimalMemOpLowering(
MemOps, Limit, Size, DstAlign, SrcAlign, false /*IsMemset*/,
false /*ZeroMemset*/, false /*MemcpyStrSrc*/, false /*AllowOverlap*/,
MI->getDestAddressSpace(), MI->getSourceAddressSpace(),
F->getAttributes()))
return MemOps.size() * 2;

// If we can't find an optimal memop lowering, return the default cost
return LibCallCost;
}

int ARMTTIImpl::getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index,
Type *SubTp) {
if (Kind == TTI::SK_Broadcast) {
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/ARM/ARMTargetTransformInfo.h
Expand Up @@ -148,6 +148,8 @@ class ARMTTIImpl : public BasicTTIImplBase<ARMTTIImpl> {
return ST->getMaxInterleaveFactor();
}

int getMemcpyCost(const Instruction *I);

int getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index, Type *SubTp);

int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
Expand Down

0 comments on commit ea31ddb

Please sign in to comment.