diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/SCCPSolver.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SCCPSolver.cpp | 67 |
1 files changed, 45 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp index ce58e8e..101d605 100644 --- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp +++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp @@ -341,31 +341,45 @@ bool SCCPSolver::removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU, return true; } +static void inferAttribute(Function *F, unsigned AttrIndex, + const ValueLatticeElement &Val) { + // If there is a known constant range for the value, add range attribute. + if (Val.isConstantRange() && !Val.getConstantRange().isSingleElement()) { + // Do not add range attribute if the value may include undef. + if (Val.isConstantRangeIncludingUndef()) + return; + + // Take the intersection of the existing attribute and the inferred range. + Attribute OldAttr = F->getAttributeAtIndex(AttrIndex, Attribute::Range); + ConstantRange CR = Val.getConstantRange(); + if (OldAttr.isValid()) + CR = CR.intersectWith(OldAttr.getRange()); + F->addAttributeAtIndex( + AttrIndex, Attribute::get(F->getContext(), Attribute::Range, CR)); + return; + } + // Infer nonnull attribute. + if (Val.isNotConstant() && Val.getNotConstant()->getType()->isPointerTy() && + Val.getNotConstant()->isNullValue() && + !F->hasAttributeAtIndex(AttrIndex, Attribute::NonNull)) { + F->addAttributeAtIndex(AttrIndex, + Attribute::get(F->getContext(), Attribute::NonNull)); + } +} + void SCCPSolver::inferReturnAttributes() const { - for (const auto &[F, ReturnValue] : getTrackedRetVals()) { - - // If there is a known constant range for the return value, add range - // attribute to the return value. - if (ReturnValue.isConstantRange() && - !ReturnValue.getConstantRange().isSingleElement()) { - // Do not add range metadata if the return value may include undef. - if (ReturnValue.isConstantRangeIncludingUndef()) - continue; + for (const auto &[F, ReturnValue] : getTrackedRetVals()) + inferAttribute(F, AttributeList::ReturnIndex, ReturnValue); +} - // Take the intersection of the existing attribute and the inferred range. - ConstantRange CR = ReturnValue.getConstantRange(); - if (F->hasRetAttribute(Attribute::Range)) - CR = CR.intersectWith(F->getRetAttribute(Attribute::Range).getRange()); - F->addRangeRetAttr(CR); - continue; - } - // Infer nonnull return attribute. - if (F->getReturnType()->isPointerTy() && ReturnValue.isNotConstant() && - ReturnValue.getNotConstant()->isNullValue() && - !F->hasRetAttribute(Attribute::NonNull)) { - F->addRetAttr(Attribute::NonNull); +void SCCPSolver::inferArgAttributes() const { + for (Function *F : getArgumentTrackedFunctions()) { + if (!isBlockExecutable(&F->front())) continue; - } + for (Argument &A : F->args()) + if (!A.getType()->isStructTy()) + inferAttribute(F, AttributeList::FirstArgIndex + A.getArgNo(), + getLatticeValueFor(&A)); } } @@ -766,6 +780,10 @@ public: return TrackingIncomingArguments.count(F); } + const SmallPtrSetImpl<Function *> &getArgumentTrackedFunctions() const { + return TrackingIncomingArguments; + } + void solve(); bool resolvedUndef(Instruction &I); @@ -2140,6 +2158,11 @@ bool SCCPSolver::isArgumentTrackedFunction(Function *F) { return Visitor->isArgumentTrackedFunction(F); } +const SmallPtrSetImpl<Function *> & +SCCPSolver::getArgumentTrackedFunctions() const { + return Visitor->getArgumentTrackedFunctions(); +} + void SCCPSolver::solve() { Visitor->solve(); } bool SCCPSolver::resolvedUndefsIn(Function &F) { |