diff options
author | Jun Bum Lim <junbuml@codeaurora.org> | 2017-09-29 14:50:16 +0000 |
---|---|---|
committer | Jun Bum Lim <junbuml@codeaurora.org> | 2017-09-29 14:50:16 +0000 |
commit | fd8d5dac8491859e0860b5195013540c455aeb02 (patch) | |
tree | daaa784008f535aa2059c22cc67df138d4ace590 /include | |
parent | e2ff20cbface83819e447eef1345ddaa9bfec441 (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.h | 19 | ||||
-rw-r--r-- | include/llvm/Analysis/TargetTransformInfoImpl.h | 36 | ||||
-rw-r--r-- | include/llvm/CodeGen/BasicTTIImpl.h | 4 | ||||
-rw-r--r-- | include/llvm/IR/Operator.h | 2 |
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; |