diff options
author | Dan Gohman <gohman@apple.com> | 2009-09-04 12:08:11 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-09-04 12:08:11 +0000 |
commit | 859fff476dfe8d83abdf4621b1d20062c0daa85c (patch) | |
tree | 15f6b66f5538046096a0f13f5ff878227987faef /include/llvm/Operator.h | |
parent | 70327dabb4cbe7a95b65ea787716170508ac3068 (diff) |
Include optional subclass flags, such as inbounds, nsw, etc., in the
Constant uniquing tables. This allows distinct ConstantExpr objects
with the same operation and different flags.
Even though a ConstantExpr "a + b" is either always overflowing or
never overflowing (due to being a ConstantExpr), it's still necessary
to be able to represent it both with and without overflow flags at
the same time within the IR, because the safety of the flag may
depend on the context of the use. If the constant really does overflow,
it wouldn't ever be safe to use with the flag set, however the use
may be in code that is never actually executed.
This also makes it possible to merge all the flags tests into a single test.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80998 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/Operator.h')
-rw-r--r-- | include/llvm/Operator.h | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index 48ac09d54f..06eb243418 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -21,6 +21,8 @@ namespace llvm { class GetElementPtrInst; +class BinaryOperator; +class ConstantExpr; /// Operator - This is a utility class that provides an abstraction for the /// common functionality between Instructions and ConstantExprs. @@ -67,24 +69,37 @@ public: /// despite that operator having the potential for overflow. /// class OverflowingBinaryOperator : public Operator { +public: + enum { + NoUnsignedWrap = (1 << 0), + NoSignedWrap = (1 << 1) + }; + +private: ~OverflowingBinaryOperator(); // do not implement + + friend class BinaryOperator; + friend class ConstantExpr; + void setHasNoUnsignedWrap(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap); + } + void setHasNoSignedWrap(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap); + } + public: /// hasNoUnsignedWrap - Test whether this operation is known to never /// undergo unsigned overflow, aka the nuw property. bool hasNoUnsignedWrap() const { - return SubclassOptionalData & (1 << 0); - } - void setHasNoUnsignedWrap(bool B) { - SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0); + return SubclassOptionalData & NoUnsignedWrap; } /// hasNoSignedWrap - Test whether this operation is known to never /// undergo signed overflow, aka the nsw property. bool hasNoSignedWrap() const { - return SubclassOptionalData & (1 << 1); - } - void setHasNoSignedWrap(bool B) { - SubclassOptionalData = (SubclassOptionalData & ~(1 << 1)) | (B << 1); + return SubclassOptionalData & NoSignedWrap; } static inline bool classof(const OverflowingBinaryOperator *) { return true; } @@ -161,15 +176,25 @@ public: /// SDivOperator - An Operator with opcode Instruction::SDiv. /// class SDivOperator : public Operator { +public: + enum { + IsExact = (1 << 0) + }; + +private: ~SDivOperator(); // do not implement + + friend class BinaryOperator; + friend class ConstantExpr; + void setIsExact(bool B) { + SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); + } + public: /// isExact - Test whether this division is known to be exact, with /// zero remainder. bool isExact() const { - return SubclassOptionalData & (1 << 0); - } - void setIsExact(bool B) { - SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0); + return SubclassOptionalData & IsExact; } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -187,15 +212,24 @@ public: }; class GEPOperator : public Operator { + enum { + IsInBounds = (1 << 0) + }; + ~GEPOperator(); // do not implement + + friend class GetElementPtrInst; + friend class ConstantExpr; + void setIsInBounds(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds); + } + public: /// isInBounds - Test whether this is an inbounds GEP, as defined /// by LangRef.html. bool isInBounds() const { - return SubclassOptionalData & (1 << 0); - } - void setIsInBounds(bool B) { - SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0); + return SubclassOptionalData & IsInBounds; } inline op_iterator idx_begin() { return op_begin()+1; } |