1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[TTI] Expose TTI::getGEPCost and use it in SLSR and NaryReassociate.

NFC.

llvm-svn: 274940
This commit is contained in:
Jingyue Wu 2016-07-08 21:48:05 +00:00
parent 22a07ca7fd
commit b8fbccd103
5 changed files with 28 additions and 80 deletions

View File

@ -102,8 +102,8 @@ public:
}
}
unsigned getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) {
int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) {
// In the basic model, we just assume that all-constant GEPs will be folded
// into their uses via addressing modes.
for (unsigned Idx = 0, Size = Operands.size(); Idx != Size; ++Idx)
@ -423,8 +423,8 @@ public:
using BaseT::getGEPCost;
unsigned getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) {
int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) {
const GlobalValue *BaseGV = nullptr;
if (Ptr != nullptr) {
// TODO: will remove this when pointers have an opaque type.

View File

@ -152,6 +152,11 @@ public:
return getTLI()->isTypeLegal(VT);
}
int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) {
return BaseT::getGEPCost(PointeeType, Ptr, Operands);
}
unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<const Value *> Arguments) {
return BaseT::getIntrinsicCost(IID, RetTy, Arguments);

View File

@ -71,6 +71,11 @@ unsigned TargetTransformInfo::getInliningThresholdMultiplier() const {
return TTIImpl->getInliningThresholdMultiplier();
}
int TargetTransformInfo::getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) const {
return TTIImpl->getGEPCost(PointeeType, Ptr, Operands);
}
int TargetTransformInfo::getIntrinsicCost(
Intrinsic::ID IID, Type *RetTy, ArrayRef<const Value *> Arguments) const {
int Cost = TTIImpl->getIntrinsicCost(IID, RetTy, Arguments);

View File

@ -299,49 +299,18 @@ Instruction *NaryReassociate::tryReassociate(Instruction *I) {
}
}
// FIXME: extract this method into TTI->getGEPCost.
static bool isGEPFoldable(GetElementPtrInst *GEP,
const TargetTransformInfo *TTI,
const DataLayout *DL) {
GlobalVariable *BaseGV = nullptr;
int64_t BaseOffset = 0;
bool HasBaseReg = false;
int64_t Scale = 0;
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getPointerOperand()))
BaseGV = GV;
else
HasBaseReg = true;
gep_type_iterator GTI = gep_type_begin(GEP);
for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I, ++GTI) {
if (isa<SequentialType>(*GTI)) {
int64_t ElementSize = DL->getTypeAllocSize(GTI.getIndexedType());
if (ConstantInt *ConstIdx = dyn_cast<ConstantInt>(*I)) {
BaseOffset += ConstIdx->getSExtValue() * ElementSize;
} else {
// Needs scale register.
if (Scale != 0) {
// No addressing mode takes two scale registers.
return false;
}
Scale = ElementSize;
}
} else {
StructType *STy = cast<StructType>(*GTI);
uint64_t Field = cast<ConstantInt>(*I)->getZExtValue();
BaseOffset += DL->getStructLayout(STy)->getElementOffset(Field);
}
}
unsigned AddrSpace = GEP->getPointerAddressSpace();
return TTI->isLegalAddressingMode(GEP->getResultElementType(), BaseGV,
BaseOffset, HasBaseReg, Scale, AddrSpace);
const TargetTransformInfo *TTI) {
SmallVector<const Value*, 4> Indices;
for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I)
Indices.push_back(*I);
return TTI->getGEPCost(GEP->getSourceElementType(), GEP->getPointerOperand(),
Indices) == TargetTransformInfo::TCC_Free;
}
Instruction *NaryReassociate::tryReassociateGEP(GetElementPtrInst *GEP) {
// Not worth reassociating GEP if it is foldable.
if (isGEPFoldable(GEP, TTI, DL))
if (isGEPFoldable(GEP, TTI))
return nullptr;
gep_type_iterator GTI = gep_type_begin(*GEP);

View File

@ -234,44 +234,13 @@ bool StraightLineStrengthReduce::isBasisFor(const Candidate &Basis,
Basis.CandidateKind == C.CandidateKind);
}
// TODO: use TTI->getGEPCost.
static bool isGEPFoldable(GetElementPtrInst *GEP,
const TargetTransformInfo *TTI,
const DataLayout *DL) {
GlobalVariable *BaseGV = nullptr;
int64_t BaseOffset = 0;
bool HasBaseReg = false;
int64_t Scale = 0;
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getPointerOperand()))
BaseGV = GV;
else
HasBaseReg = true;
gep_type_iterator GTI = gep_type_begin(GEP);
for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I, ++GTI) {
if (isa<SequentialType>(*GTI)) {
int64_t ElementSize = DL->getTypeAllocSize(GTI.getIndexedType());
if (ConstantInt *ConstIdx = dyn_cast<ConstantInt>(*I)) {
BaseOffset += ConstIdx->getSExtValue() * ElementSize;
} else {
// Needs scale register.
if (Scale != 0) {
// No addressing mode takes two scale registers.
return false;
}
Scale = ElementSize;
}
} else {
StructType *STy = cast<StructType>(*GTI);
uint64_t Field = cast<ConstantInt>(*I)->getZExtValue();
BaseOffset += DL->getStructLayout(STy)->getElementOffset(Field);
}
}
unsigned AddrSpace = GEP->getPointerAddressSpace();
return TTI->isLegalAddressingMode(GEP->getResultElementType(), BaseGV,
BaseOffset, HasBaseReg, Scale, AddrSpace);
const TargetTransformInfo *TTI) {
SmallVector<const Value*, 4> Indices;
for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I)
Indices.push_back(*I);
return TTI->getGEPCost(GEP->getSourceElementType(), GEP->getPointerOperand(),
Indices) == TargetTransformInfo::TCC_Free;
}
// Returns whether (Base + Index * Stride) can be folded to an addressing mode.
@ -287,7 +256,7 @@ bool StraightLineStrengthReduce::isFoldable(const Candidate &C,
if (C.CandidateKind == Candidate::Add)
return isAddFoldable(C.Base, C.Index, C.Stride, TTI);
if (C.CandidateKind == Candidate::GEP)
return isGEPFoldable(cast<GetElementPtrInst>(C.Ins), TTI, DL);
return isGEPFoldable(cast<GetElementPtrInst>(C.Ins), TTI);
return false;
}