diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 5c6806c1d0d..5e216f0c0cf 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -2248,7 +2248,7 @@ protected: // allocHungoffUses - this is more complicated than the generic // User::allocHungoffUses, because we have to allocate Uses for the incoming // values and pointers to the incoming blocks, all in one allocation. - Use *allocHungoffUses(unsigned N) const { + Use *allocHungoffUses(unsigned N) { return User::allocHungoffUses(N, /* IsPhi */ true); } diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index 1dacc3f303e..df6034d0b48 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -57,7 +57,7 @@ protected: /// (with bottom bit set) to the User. /// \param IsPhi identifies callers which are phi nodes and which need /// N BasicBlock* allocated along with N - Use *allocHungoffUses(unsigned N, bool IsPhi = false) const; + Use *allocHungoffUses(unsigned N, bool IsPhi = false); void dropHungoffUses() { Use::zap(OperandList, OperandList + NumOperands, true); OperandList = nullptr; diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 19a1d6cd91d..83df4cddd7f 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -100,10 +100,11 @@ protected: /// This is stored here to save space in User on 64-bit hosts. Since most /// instances of Value have operands, 32-bit hosts aren't significantly /// affected. - unsigned NumOperands : 30; + unsigned NumOperands : 29; bool IsUsedByMD : 1; bool HasName : 1; + bool HasHungOffUses : 1; private: template // UseT == 'Use' or 'const Use' diff --git a/lib/IR/User.cpp b/lib/IR/User.cpp index 4dae071185f..e5450946006 100644 --- a/lib/IR/User.cpp +++ b/lib/IR/User.cpp @@ -40,7 +40,7 @@ void User::replaceUsesOfWith(Value *From, Value *To) { // User allocHungoffUses Implementation //===----------------------------------------------------------------------===// -Use *User::allocHungoffUses(unsigned N, bool IsPhi) const { +Use *User::allocHungoffUses(unsigned N, bool IsPhi) { // Allocate the array of Uses, followed by a pointer (with bottom bit set) to // the User. size_t size = N * sizeof(Use) + sizeof(Use::UserRef); @@ -49,7 +49,11 @@ Use *User::allocHungoffUses(unsigned N, bool IsPhi) const { Use *Begin = static_cast(::operator new(size)); Use *End = Begin + N; (void) new(End) Use::UserRef(const_cast(this), 1); - return Use::initTags(Begin, End); + Use *Uses = Use::initTags(Begin, End); + OperandList = Uses; + // Tag this operand list as being a hung off. + HasHungOffUses = true; + return Uses; } //===----------------------------------------------------------------------===// @@ -62,6 +66,7 @@ void *User::operator new(size_t s, unsigned Us) { Use *End = Start + Us; User *Obj = reinterpret_cast(End); Obj->OperandList = Start; + Obj->HasHungOffUses = false; Obj->NumOperands = Us; Use::initTags(Start, End); return Obj;