Index: include/llvm/Analysis/ValueLattice.h =================================================================== --- include/llvm/Analysis/ValueLattice.h +++ include/llvm/Analysis/ValueLattice.h @@ -87,13 +87,8 @@ ConstantRange Range; }; -public: - // Const and Range are initialized on-demand. - ValueLatticeElement() : Tag(unknown) {} - - /// Custom destructor to ensure Range is properly destroyed, when the object - /// is deallocated. - ~ValueLatticeElement() { + /// Destroy contents of lattice value, without destructing the object. + void destroy() { switch (Tag) { case overdefined: case unknown: @@ -108,27 +103,17 @@ }; } - /// Custom copy constructor, to ensure Range gets initialized when - /// copying a constant range lattice element. - ValueLatticeElement(const ValueLatticeElement &Other) : Tag(unknown) { - *this = Other; - } +public: + // Const and Range are initialized on-demand. + ValueLatticeElement() : Tag(unknown) {} - /// Custom assignment operator, to ensure Range gets initialized when - /// assigning a constant range lattice element. - ValueLatticeElement &operator=(const ValueLatticeElement &Other) { - // If we change the state of this from constant range to non constant range, - // destroy Range. - if (isConstantRange() && !Other.isConstantRange()) - Range.~ConstantRange(); + ~ValueLatticeElement() { destroy(); } + ValueLatticeElement(const ValueLatticeElement &Other) : Tag(Other.Tag) { switch (Other.Tag) { case constantrange: case constantrange_including_undef: - if (!isConstantRange()) - new (&Range) ConstantRange(Other.Range); - else - Range = Other.Range; + new (&Range) ConstantRange(Other.Range); NumRangeExtensions = Other.NumRangeExtensions; break; case constant: @@ -140,7 +125,36 @@ case undef: break; } - Tag = Other.Tag; + } + + ValueLatticeElement(ValueLatticeElement &&Other) : Tag(Other.Tag) { + switch (Other.Tag) { + case constantrange: + case constantrange_including_undef: + new (&Range) ConstantRange(std::move(Other.Range)); + NumRangeExtensions = Other.NumRangeExtensions; + break; + case constant: + case notconstant: + ConstVal = Other.ConstVal; + break; + case overdefined: + case unknown: + case undef: + break; + } + Other.Tag = unknown; + } + + ValueLatticeElement &operator=(const ValueLatticeElement &Other) { + destroy(); + new (this) ValueLatticeElement(Other); + return *this; + } + + ValueLatticeElement &operator=(ValueLatticeElement &&Other) { + destroy(); + new (this) ValueLatticeElement(std::move(Other)); return *this; } @@ -223,8 +237,7 @@ bool markOverdefined() { if (isOverdefined()) return false; - if (isConstantRange()) - Range.~ConstantRange(); + destroy(); Tag = overdefined; return true; }