diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-08 17:12:57 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-08 17:12:57 +0000 |
| commit | c46e6a5940c50058e00c0c5f9123fd82e338d29a (patch) | |
| tree | 89a719d723035c54a190b1f81d329834f1f93336 /include/llvm/Support/KnownBits.h | |
| parent | 148779df305667b6942fee7e758fdf81a6498f38 (diff) | |
Notes
Diffstat (limited to 'include/llvm/Support/KnownBits.h')
| -rw-r--r-- | include/llvm/Support/KnownBits.h | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/include/llvm/Support/KnownBits.h b/include/llvm/Support/KnownBits.h index 292ea9e4b7171..3d38cf8785389 100644 --- a/include/llvm/Support/KnownBits.h +++ b/include/llvm/Support/KnownBits.h @@ -24,6 +24,12 @@ struct KnownBits { APInt Zero; APInt One; +private: + // Internal constructor for creating a ConstantRange from two APInts. + KnownBits(APInt Zero, APInt One) + : Zero(std::move(Zero)), One(std::move(One)) {} + +public: // Default construct Zero and One. KnownBits() {} @@ -37,6 +43,55 @@ struct KnownBits { return Zero.getBitWidth(); } + /// Returns true if there is conflicting information. + bool hasConflict() const { return Zero.intersects(One); } + + /// Returns true if we know the value of all bits. + bool isConstant() const { + assert(!hasConflict() && "KnownBits conflict!"); + return Zero.countPopulation() + One.countPopulation() == getBitWidth(); + } + + /// Returns the value when all bits have a known value. This just returns One + /// with a protective assertion. + const APInt &getConstant() const { + assert(isConstant() && "Can only get value when all bits are known"); + return One; + } + + /// Returns true if we don't know any bits. + bool isUnknown() const { return Zero.isNullValue() && One.isNullValue(); } + + /// Resets the known state of all bits. + void resetAll() { + Zero.clearAllBits(); + One.clearAllBits(); + } + + /// Returns true if value is all zero. + bool isZero() const { + assert(!hasConflict() && "KnownBits conflict!"); + return Zero.isAllOnesValue(); + } + + /// Returns true if value is all one bits. + bool isAllOnes() const { + assert(!hasConflict() && "KnownBits conflict!"); + return One.isAllOnesValue(); + } + + /// Make all bits known to be zero and discard any previous information. + void setAllZero() { + Zero.setAllBits(); + One.clearAllBits(); + } + + /// Make all bits known to be one and discard any previous information. + void setAllOnes() { + Zero.clearAllBits(); + One.setAllBits(); + } + /// Returns true if this value is known to be negative. bool isNegative() const { return One.isSignBitSet(); } @@ -54,6 +109,30 @@ struct KnownBits { assert(!isNegative() && "Can't make a negative value non-negative"); Zero.setSignBit(); } + + /// Truncate the underlying known Zero and One bits. This is equivalent + /// to truncating the value we're tracking. + KnownBits trunc(unsigned BitWidth) { + return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth)); + } + + /// Zero extends the underlying known Zero and One bits. This is equivalent + /// to zero extending the value we're tracking. + KnownBits zext(unsigned BitWidth) { + return KnownBits(Zero.zext(BitWidth), One.zext(BitWidth)); + } + + /// Sign extends the underlying known Zero and One bits. This is equivalent + /// to sign extending the value we're tracking. + KnownBits sext(unsigned BitWidth) { + return KnownBits(Zero.sext(BitWidth), One.sext(BitWidth)); + } + + /// Zero extends or truncates the underlying known Zero and One bits. This is + /// equivalent to zero extending or truncating the value we're tracking. + KnownBits zextOrTrunc(unsigned BitWidth) { + return KnownBits(Zero.zextOrTrunc(BitWidth), One.zextOrTrunc(BitWidth)); + } }; } // end namespace llvm |
