aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJun Bum Lim <junbuml@codeaurora.org>2017-09-29 14:50:16 +0000
committerJun Bum Lim <junbuml@codeaurora.org>2017-09-29 14:50:16 +0000
commitfd8d5dac8491859e0860b5195013540c455aeb02 (patch)
treedaaa784008f535aa2059c22cc67df138d4ace590 /include
parente2ff20cbface83819e447eef1345ddaa9bfec441 (diff)
Use the basic cost if a GEP is not used as addressing mode
Summary: Currently, getGEPCost() returns TCC_FREE whenever a GEP is a legal addressing mode in the target. However, since it doesn't check its actual users, it will return FREE even in cases where the GEP cannot be folded away as a part of actual addressing mode. For example, if an user of the GEP is a call instruction taking the GEP as a parameter, then the GEP may not be folded in isel. Reviewers: hfinkel, efriedma, mcrosier, jingyue, haicheng Reviewed By: hfinkel Subscribers: javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D38085 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314517 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h19
-rw-r--r--include/llvm/Analysis/TargetTransformInfoImpl.h36
-rw-r--r--include/llvm/CodeGen/BasicTTIImpl.h4
-rw-r--r--include/llvm/IR/Operator.h2
4 files changed, 53 insertions, 8 deletions
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index afc16e89da6..10ecf64a39c 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -193,6 +193,13 @@ public:
int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) const;
+ /// \brief Estimate the cost of a GEP operation when lowered.
+ ///
+ /// This user-based overload adds the ability to check if the GEP can be
+ /// folded into its users.
+ int getGEPCost(const GEPOperator *GEP,
+ ArrayRef<const Value *> Operands) const;
+
/// \brief Estimate the cost of a EXT operation when lowered.
///
/// The contract for this function is the same as \c getOperationCost except
@@ -251,9 +258,9 @@ public:
/// \brief Estimate the cost of a given IR user when lowered.
///
/// This can estimate the cost of either a ConstantExpr or Instruction when
- /// lowered. It has two primary advantages over the \c getOperationCost and
- /// \c getGEPCost above, and one significant disadvantage: it can only be
- /// used when the IR construct has already been formed.
+ /// lowered. It has two primary advantages over the \c getOperationCost above,
+ /// and one significant disadvantage: it can only be used when the IR
+ /// construct has already been formed.
///
/// The advantages are that it can inspect the SSA use graph to reason more
/// accurately about the cost. For example, all-constant-GEPs can often be
@@ -932,6 +939,8 @@ public:
virtual int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0;
virtual int getGEPCost(Type *PointeeType, const Value *Ptr,
ArrayRef<const Value *> Operands) = 0;
+ virtual int getGEPCost(const GEPOperator *GEP,
+ ArrayRef<const Value *> Operands) = 0;
virtual int getExtCost(const Instruction *I, const Value *Src) = 0;
virtual int getCallCost(FunctionType *FTy, int NumArgs) = 0;
virtual int getCallCost(const Function *F, int NumArgs) = 0;
@@ -1113,6 +1122,10 @@ public:
ArrayRef<const Value *> Operands) override {
return Impl.getGEPCost(PointeeType, Ptr, Operands);
}
+ int getGEPCost(const GEPOperator *GEP,
+ ArrayRef<const Value *> Operands) override {
+ return Impl.getGEPCost(GEP, Operands);
+ }
int getExtCost(const Instruction *I, const Value *Src) override {
return Impl.getExtCost(I, Src);
}
diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h
index b3b3e07b4dc..70651805b19 100644
--- a/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -726,6 +726,35 @@ public:
return TTI::TCC_Basic;
}
+ int getGEPCost(const GEPOperator *GEP, ArrayRef<const Value *> Operands) {
+ Type *PointeeType = GEP->getSourceElementType();
+ const Value *Ptr = GEP->getPointerOperand();
+
+ if (getGEPCost(PointeeType, Ptr, Operands) == TTI::TCC_Free) {
+ // Should check if the GEP is actually used in load / store instructions.
+ // For simplicity, we check only direct users of the GEP.
+ //
+ // FIXME: GEPs could also be folded away as a part of addressing mode in
+ // load/store instructions together with other instructions (e.g., other
+ // GEPs). Handling all such cases must be expensive to be performed
+ // in this function, so we stay conservative for now.
+ for (const User *U : GEP->users()) {
+ const Operator *UOP = cast<Operator>(U);
+ const Value *PointerOperand = nullptr;
+ if (auto *LI = dyn_cast<LoadInst>(UOP))
+ PointerOperand = LI->getPointerOperand();
+ else if (auto *SI = dyn_cast<StoreInst>(UOP))
+ PointerOperand = SI->getPointerOperand();
+
+ if ((!PointerOperand || PointerOperand != GEP) &&
+ !GEP->hasAllZeroIndices())
+ return TTI::TCC_Basic;
+ }
+ return TTI::TCC_Free;
+ }
+ return TTI::TCC_Basic;
+ }
+
using BaseT::getIntrinsicCost;
unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
@@ -749,11 +778,8 @@ public:
if (A->isStaticAlloca())
return TTI::TCC_Free;
- if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
- return static_cast<T *>(this)->getGEPCost(GEP->getSourceElementType(),
- GEP->getPointerOperand(),
- Operands.drop_front());
- }
+ if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U))
+ return static_cast<T *>(this)->getGEPCost(GEP, Operands.drop_front());
if (auto CS = ImmutableCallSite(U)) {
const Function *F = CS.getCalledFunction();
diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h
index 14dfc088627..0738b4dd824 100644
--- a/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/include/llvm/CodeGen/BasicTTIImpl.h
@@ -151,6 +151,10 @@ public:
return BaseT::getGEPCost(PointeeType, Ptr, Operands);
}
+ int getGEPCost(const GEPOperator *GEP, ArrayRef<const Value *> Operands) {
+ return BaseT::getGEPCost(GEP, Operands);
+ }
+
int getExtCost(const Instruction *I, const Value *Src) {
if (getTLI()->isExtFree(I))
return TargetTransformInfo::TCC_Free;
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
index 54e1165a111..84ab4f36444 100644
--- a/include/llvm/IR/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -456,6 +456,8 @@ public:
if (ConstantInt *C = dyn_cast<ConstantInt>(I))
if (C->isZero())
continue;
+ if (isa<ConstantAggregateZero>(I))
+ continue;
return false;
}
return true;