-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[NFC] Reduce copies created of ConstantRange when getting ConstantRangeAttributes. #90335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-function-specialization @llvm/pr-subscribers-llvm-ir Author: Andreas Jonson (andjo403) ChangesThink that it can be good to reduce the number of copies created when working with ConstantRangeAttributes. Full diff: https://github.com/llvm/llvm-project/pull/90335.diff 14 Files Affected:
diff --git a/llvm/include/llvm/IR/Argument.h b/llvm/include/llvm/IR/Argument.h
index 3349f1306970eb..dd47800bd5c040 100644
--- a/llvm/include/llvm/IR/Argument.h
+++ b/llvm/include/llvm/IR/Argument.h
@@ -71,8 +71,8 @@ class Argument final : public Value {
FPClassTest getNoFPClass() const;
/// If this argument has a range attribute, return the value range of the
- /// argument. Otherwise, std::nullopt is returned.
- std::optional<ConstantRange> getRange() const;
+ /// argument. Otherwise, nullptr is returned.
+ const ConstantRange *getRange() const;
/// Return true if this argument has the byval attribute.
bool hasByValAttr() const;
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index 5e3ba1f32e6ab0..dd11955714895e 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -224,7 +224,7 @@ class Attribute {
/// Return the attribute's value as a ConstantRange. This requires the
/// attribute to be a ConstantRange attribute.
- ConstantRange getValueAsConstantRange() const;
+ const ConstantRange &getValueAsConstantRange() const;
/// Returns the alignment field of an attribute as a byte alignment
/// value.
@@ -265,7 +265,7 @@ class Attribute {
FPClassTest getNoFPClass() const;
/// Returns the value of the range attribute.
- ConstantRange getRange() const;
+ const ConstantRange &getRange() const;
/// The Attribute is converted to a string of equivalent mnemonic. This
/// is, presumably, for writing out the mnemonics for the assembly writer.
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index b9af3a6ca42c06..b0d94b18d82404 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -2199,8 +2199,8 @@ class CallBase : public Instruction {
FPClassTest getParamNoFPClass(unsigned i) const;
/// If this return value has a range attribute, return the value range of the
- /// argument. Otherwise, std::nullopt is returned.
- std::optional<ConstantRange> getRange() const;
+ /// argument. Otherwise, nullptr is returned.
+ const ConstantRange *getRange() const;
/// Return true if the return value is known to be not null.
/// This may be because it has the nonnull attribute, or because at least
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index c06984c0d49436..9b1eec42b2954d 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3726,10 +3726,13 @@ static std::optional<ConstantRange> getRange(Value *V,
if (MDNode *MD = IIQ.getMetadata(I, LLVMContext::MD_range))
return getConstantRangeFromMetadata(*MD);
- if (const Argument *A = dyn_cast<Argument>(V))
- return A->getRange();
- else if (const CallBase *CB = dyn_cast<CallBase>(V))
- return CB->getRange();
+ if (const Argument *A = dyn_cast<Argument>(V)) {
+ if (const ConstantRange *Range = A->getRange())
+ return *Range;
+ } else if (const CallBase *CB = dyn_cast<CallBase>(V)) {
+ if (const ConstantRange *Range = CB->getRange())
+ return *Range;
+ }
return std::nullopt;
}
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 6cded828c25f4a..b6cb87a2d46d66 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -592,7 +592,7 @@ static ValueLatticeElement getFromRangeMetadata(Instruction *BBI) {
break;
case Instruction::Call:
case Instruction::Invoke:
- if (std::optional<ConstantRange> Range = cast<CallBase>(BBI)->getRange())
+ if (const ConstantRange *Range = cast<CallBase>(BBI)->getRange())
return ValueLatticeElement::getRange(*Range);
[[fallthrough]];
case Instruction::Load:
@@ -713,7 +713,7 @@ LazyValueInfoImpl::solveBlockValueNonLocal(Value *Val, BasicBlock *BB) {
// If this is the entry block, we must be asking about an argument.
if (BB->isEntryBlock()) {
assert(isa<Argument>(Val) && "Unknown live-in to the entry block");
- if (std::optional<ConstantRange> Range = cast<Argument>(Val)->getRange())
+ if (const ConstantRange *Range = cast<Argument>(Val)->getRange())
return ValueLatticeElement::getRange(*Range);
return ValueLatticeElement::getOverdefined();
}
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 93f885c5d5ad8b..139c1b06383279 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6386,12 +6386,12 @@ static std::optional<ConstantRange> GetRangeFromMetadata(Value *V) {
if (MDNode *MD = I->getMetadata(LLVMContext::MD_range))
return getConstantRangeFromMetadata(*MD);
if (const auto *CB = dyn_cast<CallBase>(V))
- if (std::optional<ConstantRange> Range = CB->getRange())
- return Range;
+ if (const ConstantRange *Range = CB->getRange())
+ return *Range;
}
if (auto *A = dyn_cast<Argument>(V))
- if (std::optional<ConstantRange> Range = A->getRange())
- return Range;
+ if (const ConstantRange *Range = A->getRange())
+ return *Range;
return std::nullopt;
}
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index de38eddaa98fef..9c7d69d420aa9e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1516,7 +1516,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
const auto *CB = cast<CallBase>(I);
- if (std::optional<ConstantRange> Range = CB->getRange())
+ if (const ConstantRange *Range = CB->getRange())
Known = Known.unionWith(Range->toKnownBits());
if (const Value *RV = CB->getReturnedArgOperand()) {
@@ -1971,7 +1971,7 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
assert(!isa<ConstantData>(V) && "Unhandled constant data!");
if (const auto *A = dyn_cast<Argument>(V))
- if (std::optional<ConstantRange> Range = A->getRange())
+ if (const ConstantRange *Range = A->getRange())
Known = Range->toKnownBits();
// All recursive calls that increase depth must come after this.
@@ -2896,7 +2896,7 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
} else {
if (MDNode *Ranges = Q.IIQ.getMetadata(Call, LLVMContext::MD_range))
return rangeMetadataExcludesValue(Ranges, APInt::getZero(BitWidth));
- if (std::optional<ConstantRange> Range = Call->getRange()) {
+ if (const ConstantRange *Range = Call->getRange()) {
const APInt ZeroValue(Range->getBitWidth(), 0);
if (!Range->contains(ZeroValue))
return true;
@@ -3070,7 +3070,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
}
if (const auto *A = dyn_cast<Argument>(V))
- if (std::optional<ConstantRange> Range = A->getRange()) {
+ if (const ConstantRange *Range = A->getRange()) {
const APInt ZeroValue(Range->getBitWidth(), 0);
if (!Range->contains(ZeroValue))
return true;
@@ -9390,7 +9390,7 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
setLimitForFPToI(cast<Instruction>(V), Lower, Upper);
CR = ConstantRange::getNonEmpty(Lower, Upper);
} else if (const auto *A = dyn_cast<Argument>(V))
- if (std::optional<ConstantRange> Range = A->getRange())
+ if (const ConstantRange *Range = A->getRange())
CR = *Range;
if (auto *I = dyn_cast<Instruction>(V)) {
@@ -9398,7 +9398,7 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
CR = CR.intersectWith(getConstantRangeFromMetadata(*Range));
if (const auto *CB = dyn_cast<CallBase>(V))
- if (std::optional<ConstantRange> Range = CB->getRange())
+ if (const ConstantRange *Range = CB->getRange())
CR = CR.intersectWith(*Range);
}
diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h
index 9a6427bbc3d557..a71a36da0aa05b 100644
--- a/llvm/lib/IR/AttributeImpl.h
+++ b/llvm/lib/IR/AttributeImpl.h
@@ -77,7 +77,7 @@ class AttributeImpl : public FoldingSetNode {
Type *getValueAsType() const;
- ConstantRange getValueAsConstantRange() const;
+ const ConstantRange &getValueAsConstantRange() const;
/// Used when sorting the attributes.
bool operator<(const AttributeImpl &AI) const;
@@ -219,7 +219,7 @@ class ConstantRangeAttributeImpl : public EnumAttributeImpl {
ConstantRangeAttributeImpl(Attribute::AttrKind Kind, const ConstantRange &CR)
: EnumAttributeImpl(ConstantRangeAttrEntry, Kind), CR(CR) {}
- ConstantRange getConstantRangeValue() const { return CR; }
+ const ConstantRange &getConstantRangeValue() const { return CR; }
};
class AttributeBitSet {
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 9c48a481de1ff6..7a04b618d60808 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -360,7 +360,7 @@ Type *Attribute::getValueAsType() const {
return pImpl->getValueAsType();
}
-ConstantRange Attribute::getValueAsConstantRange() const {
+const ConstantRange &Attribute::getValueAsConstantRange() const {
assert(isConstantRangeAttribute() &&
"Invalid attribute type to get the value as a ConstantRange!");
return pImpl->getValueAsConstantRange();
@@ -444,7 +444,7 @@ FPClassTest Attribute::getNoFPClass() const {
return static_cast<FPClassTest>(pImpl->getValueAsInt());
}
-ConstantRange Attribute::getRange() const {
+const ConstantRange &Attribute::getRange() const {
assert(hasAttribute(Attribute::Range) &&
"Trying to get range args from non-range attribute");
return pImpl->getValueAsConstantRange();
@@ -607,7 +607,7 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
if (hasAttribute(Attribute::Range)) {
std::string Result;
raw_string_ostream OS(Result);
- ConstantRange CR = getValueAsConstantRange();
+ const ConstantRange &CR = getValueAsConstantRange();
OS << "range(";
OS << "i" << CR.getBitWidth() << " ";
OS << CR.getLower() << ", " << CR.getUpper();
@@ -735,7 +735,7 @@ Type *AttributeImpl::getValueAsType() const {
return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
}
-ConstantRange AttributeImpl::getValueAsConstantRange() const {
+const ConstantRange &AttributeImpl::getValueAsConstantRange() const {
assert(isConstantRangeAttribute());
return static_cast<const ConstantRangeAttributeImpl *>(this)
->getConstantRangeValue();
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 545940dd86f90f..eeeec1d8930e85 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -263,11 +263,11 @@ FPClassTest Argument::getNoFPClass() const {
return getParent()->getParamNoFPClass(getArgNo());
}
-std::optional<ConstantRange> Argument::getRange() const {
+const ConstantRange *Argument::getRange() const {
const Attribute RangeAttr = getAttribute(llvm::Attribute::Range);
if (RangeAttr.isValid())
- return RangeAttr.getRange();
- return std::nullopt;
+ return &RangeAttr.getRange();
+ return nullptr;
}
bool Argument::hasNestAttr() const {
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index d2babc748731ac..4a7a62161a1520 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -396,11 +396,11 @@ FPClassTest CallBase::getParamNoFPClass(unsigned i) const {
return Mask;
}
-std::optional<ConstantRange> CallBase::getRange() const {
+const ConstantRange *CallBase::getRange() const {
const Attribute RangeAttr = getRetAttr(llvm::Attribute::Range);
if (RangeAttr.isValid())
- return RangeAttr.getRange();
- return std::nullopt;
+ return &RangeAttr.getRange();
+ return nullptr;
}
bool CallBase::isReturnNonNull() const {
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index e42cc7e260ef10..a0f6c72e78046c 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2065,7 +2065,8 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
"Invalid value for 'nofpclass' test mask", V);
}
if (Attrs.hasAttribute(Attribute::Range)) {
- auto CR = Attrs.getAttribute(Attribute::Range).getValueAsConstantRange();
+ const ConstantRange &CR =
+ Attrs.getAttribute(Attribute::Range).getValueAsConstantRange();
Check(Ty->isIntOrIntVectorTy(CR.getBitWidth()),
"Range bit width must match type bit width!", V);
}
diff --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
index 67aeba7048f860..d95248c84b8602 100644
--- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp
+++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
@@ -148,8 +148,8 @@ int FunctionComparator::cmpAttrs(const AttributeList L,
if (LA.getKindAsEnum() != RA.getKindAsEnum())
return cmpNumbers(LA.getKindAsEnum(), RA.getKindAsEnum());
- ConstantRange LCR = LA.getRange();
- ConstantRange RCR = RA.getRange();
+ const ConstantRange &LCR = LA.getRange();
+ const ConstantRange &RCR = RA.getRange();
if (int Res = cmpAPInts(LCR.getLower(), RCR.getLower()))
return Res;
if (int Res = cmpAPInts(LCR.getUpper(), RCR.getUpper()))
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index c6029b428ed398..f7d2696f7ebaa7 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -818,7 +818,7 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
void trackValueOfArgument(Argument *A) {
if (A->getType()->isIntegerTy()) {
- if (std::optional<ConstantRange> Range = A->getRange()) {
+ if (const ConstantRange *Range = A->getRange()) {
markConstantRange(ValueState[A], A, *Range);
return;
}
@@ -1635,7 +1635,7 @@ static ValueLatticeElement getValueFromMetadata(const Instruction *I) {
getConstantRangeFromMetadata(*Ranges));
if (const auto *CB = dyn_cast<CallBase>(I))
- if (std::optional<ConstantRange> Range = CB->getRange())
+ if (const ConstantRange *Range = CB->getRange())
return ValueLatticeElement::getRange(*Range);
}
if (I->hasMetadata(LLVMContext::MD_nonnull))
|
@llvm/pr-subscribers-llvm-analysis Author: Andreas Jonson (andjo403) ChangesThink that it can be good to reduce the number of copies created when working with ConstantRangeAttributes. Full diff: https://github.com/llvm/llvm-project/pull/90335.diff 14 Files Affected:
diff --git a/llvm/include/llvm/IR/Argument.h b/llvm/include/llvm/IR/Argument.h
index 3349f1306970eb..dd47800bd5c040 100644
--- a/llvm/include/llvm/IR/Argument.h
+++ b/llvm/include/llvm/IR/Argument.h
@@ -71,8 +71,8 @@ class Argument final : public Value {
FPClassTest getNoFPClass() const;
/// If this argument has a range attribute, return the value range of the
- /// argument. Otherwise, std::nullopt is returned.
- std::optional<ConstantRange> getRange() const;
+ /// argument. Otherwise, nullptr is returned.
+ const ConstantRange *getRange() const;
/// Return true if this argument has the byval attribute.
bool hasByValAttr() const;
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index 5e3ba1f32e6ab0..dd11955714895e 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -224,7 +224,7 @@ class Attribute {
/// Return the attribute's value as a ConstantRange. This requires the
/// attribute to be a ConstantRange attribute.
- ConstantRange getValueAsConstantRange() const;
+ const ConstantRange &getValueAsConstantRange() const;
/// Returns the alignment field of an attribute as a byte alignment
/// value.
@@ -265,7 +265,7 @@ class Attribute {
FPClassTest getNoFPClass() const;
/// Returns the value of the range attribute.
- ConstantRange getRange() const;
+ const ConstantRange &getRange() const;
/// The Attribute is converted to a string of equivalent mnemonic. This
/// is, presumably, for writing out the mnemonics for the assembly writer.
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index b9af3a6ca42c06..b0d94b18d82404 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -2199,8 +2199,8 @@ class CallBase : public Instruction {
FPClassTest getParamNoFPClass(unsigned i) const;
/// If this return value has a range attribute, return the value range of the
- /// argument. Otherwise, std::nullopt is returned.
- std::optional<ConstantRange> getRange() const;
+ /// argument. Otherwise, nullptr is returned.
+ const ConstantRange *getRange() const;
/// Return true if the return value is known to be not null.
/// This may be because it has the nonnull attribute, or because at least
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index c06984c0d49436..9b1eec42b2954d 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3726,10 +3726,13 @@ static std::optional<ConstantRange> getRange(Value *V,
if (MDNode *MD = IIQ.getMetadata(I, LLVMContext::MD_range))
return getConstantRangeFromMetadata(*MD);
- if (const Argument *A = dyn_cast<Argument>(V))
- return A->getRange();
- else if (const CallBase *CB = dyn_cast<CallBase>(V))
- return CB->getRange();
+ if (const Argument *A = dyn_cast<Argument>(V)) {
+ if (const ConstantRange *Range = A->getRange())
+ return *Range;
+ } else if (const CallBase *CB = dyn_cast<CallBase>(V)) {
+ if (const ConstantRange *Range = CB->getRange())
+ return *Range;
+ }
return std::nullopt;
}
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 6cded828c25f4a..b6cb87a2d46d66 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -592,7 +592,7 @@ static ValueLatticeElement getFromRangeMetadata(Instruction *BBI) {
break;
case Instruction::Call:
case Instruction::Invoke:
- if (std::optional<ConstantRange> Range = cast<CallBase>(BBI)->getRange())
+ if (const ConstantRange *Range = cast<CallBase>(BBI)->getRange())
return ValueLatticeElement::getRange(*Range);
[[fallthrough]];
case Instruction::Load:
@@ -713,7 +713,7 @@ LazyValueInfoImpl::solveBlockValueNonLocal(Value *Val, BasicBlock *BB) {
// If this is the entry block, we must be asking about an argument.
if (BB->isEntryBlock()) {
assert(isa<Argument>(Val) && "Unknown live-in to the entry block");
- if (std::optional<ConstantRange> Range = cast<Argument>(Val)->getRange())
+ if (const ConstantRange *Range = cast<Argument>(Val)->getRange())
return ValueLatticeElement::getRange(*Range);
return ValueLatticeElement::getOverdefined();
}
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 93f885c5d5ad8b..139c1b06383279 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6386,12 +6386,12 @@ static std::optional<ConstantRange> GetRangeFromMetadata(Value *V) {
if (MDNode *MD = I->getMetadata(LLVMContext::MD_range))
return getConstantRangeFromMetadata(*MD);
if (const auto *CB = dyn_cast<CallBase>(V))
- if (std::optional<ConstantRange> Range = CB->getRange())
- return Range;
+ if (const ConstantRange *Range = CB->getRange())
+ return *Range;
}
if (auto *A = dyn_cast<Argument>(V))
- if (std::optional<ConstantRange> Range = A->getRange())
- return Range;
+ if (const ConstantRange *Range = A->getRange())
+ return *Range;
return std::nullopt;
}
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index de38eddaa98fef..9c7d69d420aa9e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1516,7 +1516,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
const auto *CB = cast<CallBase>(I);
- if (std::optional<ConstantRange> Range = CB->getRange())
+ if (const ConstantRange *Range = CB->getRange())
Known = Known.unionWith(Range->toKnownBits());
if (const Value *RV = CB->getReturnedArgOperand()) {
@@ -1971,7 +1971,7 @@ void computeKnownBits(const Value *V, const APInt &DemandedElts,
assert(!isa<ConstantData>(V) && "Unhandled constant data!");
if (const auto *A = dyn_cast<Argument>(V))
- if (std::optional<ConstantRange> Range = A->getRange())
+ if (const ConstantRange *Range = A->getRange())
Known = Range->toKnownBits();
// All recursive calls that increase depth must come after this.
@@ -2896,7 +2896,7 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
} else {
if (MDNode *Ranges = Q.IIQ.getMetadata(Call, LLVMContext::MD_range))
return rangeMetadataExcludesValue(Ranges, APInt::getZero(BitWidth));
- if (std::optional<ConstantRange> Range = Call->getRange()) {
+ if (const ConstantRange *Range = Call->getRange()) {
const APInt ZeroValue(Range->getBitWidth(), 0);
if (!Range->contains(ZeroValue))
return true;
@@ -3070,7 +3070,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
}
if (const auto *A = dyn_cast<Argument>(V))
- if (std::optional<ConstantRange> Range = A->getRange()) {
+ if (const ConstantRange *Range = A->getRange()) {
const APInt ZeroValue(Range->getBitWidth(), 0);
if (!Range->contains(ZeroValue))
return true;
@@ -9390,7 +9390,7 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
setLimitForFPToI(cast<Instruction>(V), Lower, Upper);
CR = ConstantRange::getNonEmpty(Lower, Upper);
} else if (const auto *A = dyn_cast<Argument>(V))
- if (std::optional<ConstantRange> Range = A->getRange())
+ if (const ConstantRange *Range = A->getRange())
CR = *Range;
if (auto *I = dyn_cast<Instruction>(V)) {
@@ -9398,7 +9398,7 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
CR = CR.intersectWith(getConstantRangeFromMetadata(*Range));
if (const auto *CB = dyn_cast<CallBase>(V))
- if (std::optional<ConstantRange> Range = CB->getRange())
+ if (const ConstantRange *Range = CB->getRange())
CR = CR.intersectWith(*Range);
}
diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h
index 9a6427bbc3d557..a71a36da0aa05b 100644
--- a/llvm/lib/IR/AttributeImpl.h
+++ b/llvm/lib/IR/AttributeImpl.h
@@ -77,7 +77,7 @@ class AttributeImpl : public FoldingSetNode {
Type *getValueAsType() const;
- ConstantRange getValueAsConstantRange() const;
+ const ConstantRange &getValueAsConstantRange() const;
/// Used when sorting the attributes.
bool operator<(const AttributeImpl &AI) const;
@@ -219,7 +219,7 @@ class ConstantRangeAttributeImpl : public EnumAttributeImpl {
ConstantRangeAttributeImpl(Attribute::AttrKind Kind, const ConstantRange &CR)
: EnumAttributeImpl(ConstantRangeAttrEntry, Kind), CR(CR) {}
- ConstantRange getConstantRangeValue() const { return CR; }
+ const ConstantRange &getConstantRangeValue() const { return CR; }
};
class AttributeBitSet {
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 9c48a481de1ff6..7a04b618d60808 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -360,7 +360,7 @@ Type *Attribute::getValueAsType() const {
return pImpl->getValueAsType();
}
-ConstantRange Attribute::getValueAsConstantRange() const {
+const ConstantRange &Attribute::getValueAsConstantRange() const {
assert(isConstantRangeAttribute() &&
"Invalid attribute type to get the value as a ConstantRange!");
return pImpl->getValueAsConstantRange();
@@ -444,7 +444,7 @@ FPClassTest Attribute::getNoFPClass() const {
return static_cast<FPClassTest>(pImpl->getValueAsInt());
}
-ConstantRange Attribute::getRange() const {
+const ConstantRange &Attribute::getRange() const {
assert(hasAttribute(Attribute::Range) &&
"Trying to get range args from non-range attribute");
return pImpl->getValueAsConstantRange();
@@ -607,7 +607,7 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
if (hasAttribute(Attribute::Range)) {
std::string Result;
raw_string_ostream OS(Result);
- ConstantRange CR = getValueAsConstantRange();
+ const ConstantRange &CR = getValueAsConstantRange();
OS << "range(";
OS << "i" << CR.getBitWidth() << " ";
OS << CR.getLower() << ", " << CR.getUpper();
@@ -735,7 +735,7 @@ Type *AttributeImpl::getValueAsType() const {
return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
}
-ConstantRange AttributeImpl::getValueAsConstantRange() const {
+const ConstantRange &AttributeImpl::getValueAsConstantRange() const {
assert(isConstantRangeAttribute());
return static_cast<const ConstantRangeAttributeImpl *>(this)
->getConstantRangeValue();
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 545940dd86f90f..eeeec1d8930e85 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -263,11 +263,11 @@ FPClassTest Argument::getNoFPClass() const {
return getParent()->getParamNoFPClass(getArgNo());
}
-std::optional<ConstantRange> Argument::getRange() const {
+const ConstantRange *Argument::getRange() const {
const Attribute RangeAttr = getAttribute(llvm::Attribute::Range);
if (RangeAttr.isValid())
- return RangeAttr.getRange();
- return std::nullopt;
+ return &RangeAttr.getRange();
+ return nullptr;
}
bool Argument::hasNestAttr() const {
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index d2babc748731ac..4a7a62161a1520 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -396,11 +396,11 @@ FPClassTest CallBase::getParamNoFPClass(unsigned i) const {
return Mask;
}
-std::optional<ConstantRange> CallBase::getRange() const {
+const ConstantRange *CallBase::getRange() const {
const Attribute RangeAttr = getRetAttr(llvm::Attribute::Range);
if (RangeAttr.isValid())
- return RangeAttr.getRange();
- return std::nullopt;
+ return &RangeAttr.getRange();
+ return nullptr;
}
bool CallBase::isReturnNonNull() const {
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index e42cc7e260ef10..a0f6c72e78046c 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2065,7 +2065,8 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
"Invalid value for 'nofpclass' test mask", V);
}
if (Attrs.hasAttribute(Attribute::Range)) {
- auto CR = Attrs.getAttribute(Attribute::Range).getValueAsConstantRange();
+ const ConstantRange &CR =
+ Attrs.getAttribute(Attribute::Range).getValueAsConstantRange();
Check(Ty->isIntOrIntVectorTy(CR.getBitWidth()),
"Range bit width must match type bit width!", V);
}
diff --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
index 67aeba7048f860..d95248c84b8602 100644
--- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp
+++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
@@ -148,8 +148,8 @@ int FunctionComparator::cmpAttrs(const AttributeList L,
if (LA.getKindAsEnum() != RA.getKindAsEnum())
return cmpNumbers(LA.getKindAsEnum(), RA.getKindAsEnum());
- ConstantRange LCR = LA.getRange();
- ConstantRange RCR = RA.getRange();
+ const ConstantRange &LCR = LA.getRange();
+ const ConstantRange &RCR = RA.getRange();
if (int Res = cmpAPInts(LCR.getLower(), RCR.getLower()))
return Res;
if (int Res = cmpAPInts(LCR.getUpper(), RCR.getUpper()))
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index c6029b428ed398..f7d2696f7ebaa7 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -818,7 +818,7 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
void trackValueOfArgument(Argument *A) {
if (A->getType()->isIntegerTy()) {
- if (std::optional<ConstantRange> Range = A->getRange()) {
+ if (const ConstantRange *Range = A->getRange()) {
markConstantRange(ValueState[A], A, *Range);
return;
}
@@ -1635,7 +1635,7 @@ static ValueLatticeElement getValueFromMetadata(const Instruction *I) {
getConstantRangeFromMetadata(*Ranges));
if (const auto *CB = dyn_cast<CallBase>(I))
- if (std::optional<ConstantRange> Range = CB->getRange())
+ if (const ConstantRange *Range = CB->getRange())
return ValueLatticeElement::getRange(*Range);
}
if (I->hasMetadata(LLVMContext::MD_nonnull))
|
hmm maybe this is not the solution that we want. have today been looking at how to handle the ConstantRangeAttributes in the c api and have not found any good solution for how to set and get the range and the allocation of the ConstantRange is the hardest thing. my initial ide was to have something like
but I can not find any place to allocate the ConstantRange in LLVMCreateConstantRange. Started to think that we maybe only shall have a pointer to the ConstantRange in the attribute same as the type attributes and have a ConstantRange allocator in the context instead of a ConstantRangeAttributeImpl that we have now. But do not know if that helps either as we maybe want to have some way to get the lower and upper from the ConstantRange also eg. |
llvm/include/llvm/IR/InstrTypes.h
Outdated
/// argument. Otherwise, std::nullopt is returned. | ||
std::optional<ConstantRange> getRange() const; | ||
/// argument. Otherwise, nullptr is returned. | ||
const ConstantRange *getRange() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this one -- e.g. if we wanted to intersect the range on the call and the declaration, we'd no longer be able to do it with this API...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that I understand this comment, the intersect methods seems to works on const ConstantRange*
as it is e.g.
ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type = Smallest) const;
or was there something else that you was thinking about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You would not be able to return the result of the intersection in a const ConstantRange * type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok you was thinking that the intersection was done in the body of this function. But is it interesting to return the intersection shall not only the smallest of the ranges be returned feels like some thing is wrong if the the call do not contain the same range or a subrange of the declaration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm or after #90134 it maybe is not possible to say that the call is a subrange of the declaration anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted this part
@andjo403 I think the C API would have to do the same as other places that take an APInt, e.g.:
In this case we'd accept the words for both lower and upper. I'm not sure whether we have any C APIs that return APInt values. |
@nikic this it ready for review again |
llvm/include/llvm/IR/Argument.h
Outdated
/// argument. Otherwise, std::nullopt is returned. | ||
std::optional<ConstantRange> getRange() const; | ||
/// argument. Otherwise, nullptr is returned. | ||
const ConstantRange *getRange() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to leave this alone as well, to keep the APIs consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes agree was thinking about it when I hade the two ifs after each other but was to deep in save copies mode to stop and reflect. Pushed a new commit as there was so mush removed so a fix commit did not make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Think that it can be good to reduce the number of copies created when working with ConstantRangeAttributes.
CC @nikic