Index: include/llvm/Support/KnownBits.h =================================================================== --- include/llvm/Support/KnownBits.h +++ include/llvm/Support/KnownBits.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file contains a class for reprsenting known zeros and ones used by +// This file contains a class for representing known zeros and ones used by // computeKnownBits. // //===----------------------------------------------------------------------===// @@ -19,7 +19,7 @@ namespace llvm { -// For now this is a simple wrapper around two APInts. +// Struct for managing the known zeros and ones of a value. struct KnownBits { APInt Zero; APInt One; @@ -36,6 +36,56 @@ "Zero and One should have the same width!"); return Zero.getBitWidth(); } + + /// Returns true if there is conflicting information. + bool hasConflict() const { return Zero.intersects(One); } + + /// Returns true if there is no conflicting information. + bool isValid() const { + assert(Zero.getBitWidth() == One.getBitWidth() && + "Zero and One should have the same width!"); + return !hasConflict(); + } + + /// Returns true if we know the value of all bits. + bool isComplete() const { + assert(isValid() && "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 &getValue() const { + assert(isComplete() && "Can only get value when all bits are known"); + return One; + } + + /// Returns true if this value is known to be negative. + bool isNegative() const { return One.isSignBitSet(); } + + /// Returns true if this value is known to be non-negative. + bool isNonNegative() const { return Zero.isSignBitSet(); } + + /// Truncate the underlying known Zero and One bits. This is equivalent + /// to truncating the value we're tracking. + void trunc(unsigned BitWidth) { + Zero = Zero.trunc(BitWidth); + One = One.trunc(BitWidth); + } + + /// Zero extends the underlying known Zero and One bits. This is equivalent + /// to zero extending the value we're tracking. + void zext(unsigned BitWidth) { + Zero = Zero.zext(BitWidth); + One = One.zext(BitWidth); + } + + /// Sign extends the underlying known Zero and One bits. This is equivalent + /// to sign extending the value we're tracking. + void sext(unsigned BitWidth) { + Zero = Zero.sext(BitWidth); + One = One.sext(BitWidth); + } }; } // end namespace llvm