[llvm] Don't rely on undefined behavior to store how a `User` object's allocation is laid out (PR #105714)
Daniel Paoliello via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 9 17:22:22 PDT 2024
https://github.com/dpaoliello updated https://github.com/llvm/llvm-project/pull/105714
>From a856c9ea0b6d688aa7403d4879da7e37f97ec74e Mon Sep 17 00:00:00 2001
From: Daniel Paoliello <danpao at microsoft.com>
Date: Mon, 9 Sep 2024 13:25:26 -0700
Subject: [PATCH] Don't rely on undefined behavior to store how a User object's
allocation is laid out
---
llvm/include/llvm/Analysis/MemorySSA.h | 28 +--
llvm/include/llvm/IR/Constant.h | 4 +-
llvm/include/llvm/IR/Constants.h | 35 ++--
llvm/include/llvm/IR/DerivedUser.h | 4 +-
llvm/include/llvm/IR/Function.h | 7 +-
llvm/include/llvm/IR/GlobalAlias.h | 4 +-
llvm/include/llvm/IR/GlobalIFunc.h | 4 +-
llvm/include/llvm/IR/GlobalObject.h | 7 +-
llvm/include/llvm/IR/GlobalValue.h | 6 +-
llvm/include/llvm/IR/GlobalVariable.h | 31 +--
llvm/include/llvm/IR/InstrTypes.h | 22 ++-
llvm/include/llvm/IR/Instruction.h | 2 +-
llvm/include/llvm/IR/Instructions.h | 262 +++++++++++++++----------
llvm/include/llvm/IR/User.h | 105 +++++++---
llvm/lib/IR/Constants.cpp | 36 ++--
llvm/lib/IR/ConstantsContext.h | 44 +++--
llvm/lib/IR/Function.cpp | 5 +-
llvm/lib/IR/Globals.cpp | 11 +-
llvm/lib/IR/Instruction.cpp | 4 +-
llvm/lib/IR/Instructions.cpp | 235 +++++++++++-----------
llvm/lib/IR/User.cpp | 20 +-
21 files changed, 508 insertions(+), 368 deletions(-)
diff --git a/llvm/include/llvm/Analysis/MemorySSA.h b/llvm/include/llvm/Analysis/MemorySSA.h
index c5eff151ca4180..09fc34af60dc3c 100644
--- a/llvm/include/llvm/Analysis/MemorySSA.h
+++ b/llvm/include/llvm/Analysis/MemorySSA.h
@@ -218,8 +218,8 @@ class MemoryAccess
inline unsigned getID() const;
MemoryAccess(LLVMContext &C, unsigned Vty, DeleteValueTy DeleteValue,
- BasicBlock *BB, unsigned NumOperands)
- : DerivedUser(Type::getVoidTy(C), Vty, nullptr, NumOperands, DeleteValue),
+ BasicBlock *BB, AllocInfo AllocInfo)
+ : DerivedUser(Type::getVoidTy(C), Vty, AllocInfo, DeleteValue),
Block(BB) {}
// Use deleteValue() to delete a generic MemoryAccess.
@@ -280,8 +280,8 @@ class MemoryUseOrDef : public MemoryAccess {
MemoryUseOrDef(LLVMContext &C, MemoryAccess *DMA, unsigned Vty,
DeleteValueTy DeleteValue, Instruction *MI, BasicBlock *BB,
- unsigned NumOperands)
- : MemoryAccess(C, Vty, DeleteValue, BB, NumOperands),
+ AllocInfo AllocInfo)
+ : MemoryAccess(C, Vty, DeleteValue, BB, AllocInfo),
MemoryInstruction(MI) {
setDefiningAccess(DMA);
}
@@ -307,15 +307,16 @@ class MemoryUseOrDef : public MemoryAccess {
/// MemoryUse's is exactly the set of Instructions for which
/// AliasAnalysis::getModRefInfo returns "Ref".
class MemoryUse final : public MemoryUseOrDef {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
+
public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
MemoryUse(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB)
- : MemoryUseOrDef(C, DMA, MemoryUseVal, deleteMe, MI, BB,
- /*NumOperands=*/1) {}
+ : MemoryUseOrDef(C, DMA, MemoryUseVal, deleteMe, MI, BB, AllocMarker) {}
// allocate space for exactly one operand
- void *operator new(size_t S) { return User::operator new(S, 1); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
static bool classof(const Value *MA) {
@@ -367,6 +368,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryUse, MemoryAccess)
/// associated with them. This use points to the nearest reaching
/// MemoryDef/MemoryPhi.
class MemoryDef final : public MemoryUseOrDef {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
public:
friend class MemorySSA;
@@ -374,12 +377,11 @@ class MemoryDef final : public MemoryUseOrDef {
MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB,
unsigned Ver)
- : MemoryUseOrDef(C, DMA, MemoryDefVal, deleteMe, MI, BB,
- /*NumOperands=*/2),
+ : MemoryUseOrDef(C, DMA, MemoryDefVal, deleteMe, MI, BB, AllocMarker),
ID(Ver) {}
// allocate space for exactly two operands
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
static bool classof(const Value *MA) {
@@ -474,8 +476,10 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryUseOrDef, MemoryAccess)
/// Because MemoryUse's do not generate new definitions, they do not have this
/// issue.
class MemoryPhi final : public MemoryAccess {
+ constexpr static HungOffOperandsAllocMarker AllocMarker{};
+
// allocate space for exactly zero operands
- void *operator new(size_t S) { return User::operator new(S); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
public:
void operator delete(void *Ptr) { User::operator delete(Ptr); }
@@ -484,7 +488,7 @@ class MemoryPhi final : public MemoryAccess {
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
MemoryPhi(LLVMContext &C, BasicBlock *BB, unsigned Ver, unsigned NumPreds = 0)
- : MemoryAccess(C, MemoryPhiVal, deleteMe, BB, 0), ID(Ver),
+ : MemoryAccess(C, MemoryPhiVal, deleteMe, BB, AllocMarker), ID(Ver),
ReservedSpace(NumPreds) {
allocHungoffUses(ReservedSpace);
}
diff --git a/llvm/include/llvm/IR/Constant.h b/llvm/include/llvm/IR/Constant.h
index a82e37b7e2df23..0aefb5ecf6b7f2 100644
--- a/llvm/include/llvm/IR/Constant.h
+++ b/llvm/include/llvm/IR/Constant.h
@@ -41,8 +41,8 @@ class APInt;
/// LLVM Constant Representation
class Constant : public User {
protected:
- Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
- : User(ty, vty, Ops, NumOps) {}
+ Constant(Type *ty, ValueTy vty, AllocInfo AllocInfo)
+ : User(ty, vty, AllocInfo) {}
~Constant() = default;
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index 62ccde96e5397b..3b16aa039a5087 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -51,6 +51,8 @@ template <class ConstantClass> struct ConstantAggrKeyType;
/// Since they can be in use by unrelated modules (and are never based on
/// GlobalValues), it never makes sense to RAUW them.
class ConstantData : public Constant {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{0};
+
friend class Constant;
Value *handleOperandChangeImpl(Value *From, Value *To) {
@@ -58,9 +60,9 @@ class ConstantData : public Constant {
}
protected:
- explicit ConstantData(Type *Ty, ValueTy VT) : Constant(Ty, VT, nullptr, 0) {}
+ explicit ConstantData(Type *Ty, ValueTy VT) : Constant(Ty, VT, AllocMarker) {}
- void *operator new(size_t S) { return User::operator new(S, 0); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
public:
void operator delete(void *Ptr) { User::operator delete(Ptr); }
@@ -399,7 +401,8 @@ class ConstantAggregateZero final : public ConstantData {
/// use operands.
class ConstantAggregate : public Constant {
protected:
- ConstantAggregate(Type *T, ValueTy VT, ArrayRef<Constant *> V);
+ ConstantAggregate(Type *T, ValueTy VT, ArrayRef<Constant *> V,
+ AllocInfo AllocInfo);
public:
/// Transparently provide more efficient getOperand methods.
@@ -425,7 +428,7 @@ class ConstantArray final : public ConstantAggregate {
friend struct ConstantAggrKeyType<ConstantArray>;
friend class Constant;
- ConstantArray(ArrayType *T, ArrayRef<Constant *> Val);
+ ConstantArray(ArrayType *T, ArrayRef<Constant *> Val, AllocInfo AllocInfo);
void destroyConstantImpl();
Value *handleOperandChangeImpl(Value *From, Value *To);
@@ -457,7 +460,7 @@ class ConstantStruct final : public ConstantAggregate {
friend struct ConstantAggrKeyType<ConstantStruct>;
friend class Constant;
- ConstantStruct(StructType *T, ArrayRef<Constant *> Val);
+ ConstantStruct(StructType *T, ArrayRef<Constant *> Val, AllocInfo AllocInfo);
void destroyConstantImpl();
Value *handleOperandChangeImpl(Value *From, Value *To);
@@ -509,7 +512,7 @@ class ConstantVector final : public ConstantAggregate {
friend struct ConstantAggrKeyType<ConstantVector>;
friend class Constant;
- ConstantVector(VectorType *T, ArrayRef<Constant *> Val);
+ ConstantVector(VectorType *T, ArrayRef<Constant *> Val, AllocInfo AllocInfo);
void destroyConstantImpl();
Value *handleOperandChangeImpl(Value *From, Value *To);
@@ -890,9 +893,11 @@ class ConstantTargetNone final : public ConstantData {
class BlockAddress final : public Constant {
friend class Constant;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
BlockAddress(Function *F, BasicBlock *BB);
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void destroyConstantImpl();
Value *handleOperandChangeImpl(Value *From, Value *To);
@@ -936,9 +941,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BlockAddress, Value)
class DSOLocalEquivalent final : public Constant {
friend class Constant;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
+
DSOLocalEquivalent(GlobalValue *GV);
- void *operator new(size_t S) { return User::operator new(S, 1); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void destroyConstantImpl();
Value *handleOperandChangeImpl(Value *From, Value *To);
@@ -973,9 +980,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(DSOLocalEquivalent, Value)
class NoCFIValue final : public Constant {
friend class Constant;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
+
NoCFIValue(GlobalValue *GV);
- void *operator new(size_t S) { return User::operator new(S, 1); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void destroyConstantImpl();
Value *handleOperandChangeImpl(Value *From, Value *To);
@@ -1013,10 +1022,12 @@ class ConstantPtrAuth final : public Constant {
friend struct ConstantPtrAuthKeyType;
friend class Constant;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{4};
+
ConstantPtrAuth(Constant *Ptr, ConstantInt *Key, ConstantInt *Disc,
Constant *AddrDisc);
- void *operator new(size_t s) { return User::operator new(s, 4); }
+ void *operator new(size_t s) { return User::operator new(s, AllocMarker); }
void destroyConstantImpl();
Value *handleOperandChangeImpl(Value *From, Value *To);
@@ -1102,8 +1113,8 @@ class ConstantExpr : public Constant {
Value *handleOperandChangeImpl(Value *From, Value *To);
protected:
- ConstantExpr(Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps)
- : Constant(ty, ConstantExprVal, Ops, NumOps) {
+ ConstantExpr(Type *ty, unsigned Opcode, AllocInfo AllocInfo)
+ : Constant(ty, ConstantExprVal, AllocInfo) {
// Operation type (an Instruction opcode) is stored as the SubclassData.
setValueSubclassData(Opcode);
}
diff --git a/llvm/include/llvm/IR/DerivedUser.h b/llvm/include/llvm/IR/DerivedUser.h
index a25d316c2d60bc..a307315864b425 100644
--- a/llvm/include/llvm/IR/DerivedUser.h
+++ b/llvm/include/llvm/IR/DerivedUser.h
@@ -34,9 +34,9 @@ class DerivedUser : public User {
DeleteValueTy DeleteValue;
public:
- DerivedUser(Type *Ty, unsigned VK, Use *U, unsigned NumOps,
+ DerivedUser(Type *Ty, unsigned VK, AllocInfo AllocInfo,
DeleteValueTy DeleteValue)
- : User(Ty, VK, U, NumOps), DeleteValue(DeleteValue) {}
+ : User(Ty, VK, AllocInfo), DeleteValue(DeleteValue) {}
};
} // end namespace llvm
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index f7e4e976ae4c44..866c68d15e4011 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -72,6 +72,8 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
using const_arg_iterator = const Argument *;
private:
+ constexpr static HungOffOperandsAllocMarker AllocMarker{};
+
// Important things that make up a function!
BasicBlockListType BasicBlocks; ///< The basic blocks
@@ -171,13 +173,14 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
unsigned AddrSpace, const Twine &N = "",
Module *M = nullptr) {
- return new Function(Ty, Linkage, AddrSpace, N, M);
+ return new (AllocMarker) Function(Ty, Linkage, AddrSpace, N, M);
}
// TODO: remove this once all users have been updated to pass an AddrSpace
static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
const Twine &N = "", Module *M = nullptr) {
- return new Function(Ty, Linkage, static_cast<unsigned>(-1), N, M);
+ return new (AllocMarker)
+ Function(Ty, Linkage, static_cast<unsigned>(-1), N, M);
}
/// Creates a new function and attaches it to a module.
diff --git a/llvm/include/llvm/IR/GlobalAlias.h b/llvm/include/llvm/IR/GlobalAlias.h
index 583d66e28155d7..3db6984c4a30c3 100644
--- a/llvm/include/llvm/IR/GlobalAlias.h
+++ b/llvm/include/llvm/IR/GlobalAlias.h
@@ -28,6 +28,8 @@ template <typename ValueSubClass, typename... Args> class SymbolTableListTraits;
class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
friend class SymbolTableListTraits<GlobalAlias>;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
+
GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage,
const Twine &Name, Constant *Aliasee, Module *Parent);
@@ -59,7 +61,7 @@ class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee);
// allocate space for exactly one operand
- void *operator new(size_t S) { return User::operator new(S, 1); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Provide fast operand accessors
diff --git a/llvm/include/llvm/IR/GlobalIFunc.h b/llvm/include/llvm/IR/GlobalIFunc.h
index 8935284f32d759..0d2f152cef403e 100644
--- a/llvm/include/llvm/IR/GlobalIFunc.h
+++ b/llvm/include/llvm/IR/GlobalIFunc.h
@@ -34,6 +34,8 @@ template <typename ValueSubClass, typename... Args> class SymbolTableListTraits;
class GlobalIFunc final : public GlobalObject, public ilist_node<GlobalIFunc> {
friend class SymbolTableListTraits<GlobalIFunc>;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
+
GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage,
const Twine &Name, Constant *Resolver, Module *Parent);
@@ -48,7 +50,7 @@ class GlobalIFunc final : public GlobalObject, public ilist_node<GlobalIFunc> {
Constant *Resolver, Module *Parent);
// allocate space for exactly one operand
- void *operator new(size_t S) { return User::operator new(S, 1); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Provide fast operand accessors
diff --git a/llvm/include/llvm/IR/GlobalObject.h b/llvm/include/llvm/IR/GlobalObject.h
index b6a974d8bb9f08..08edc13d81f880 100644
--- a/llvm/include/llvm/IR/GlobalObject.h
+++ b/llvm/include/llvm/IR/GlobalObject.h
@@ -40,10 +40,9 @@ class GlobalObject : public GlobalValue {
};
protected:
- GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
- LinkageTypes Linkage, const Twine &Name,
- unsigned AddressSpace = 0)
- : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace) {
+ GlobalObject(Type *Ty, ValueTy VTy, AllocInfo AllocInfo, LinkageTypes Linkage,
+ const Twine &Name, unsigned AddressSpace = 0)
+ : GlobalValue(Ty, VTy, AllocInfo, Linkage, Name, AddressSpace) {
setGlobalValueSubClassData(0);
}
~GlobalObject();
diff --git a/llvm/include/llvm/IR/GlobalValue.h b/llvm/include/llvm/IR/GlobalValue.h
index 53eddebdd6ae68..d9104d7af5f972 100644
--- a/llvm/include/llvm/IR/GlobalValue.h
+++ b/llvm/include/llvm/IR/GlobalValue.h
@@ -77,9 +77,9 @@ class GlobalValue : public Constant {
};
protected:
- GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
- LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace)
- : Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps),
+ GlobalValue(Type *Ty, ValueTy VTy, AllocInfo AllocInfo, LinkageTypes Linkage,
+ const Twine &Name, unsigned AddressSpace)
+ : Constant(PointerType::get(Ty, AddressSpace), VTy, AllocInfo),
ValueType(Ty), Visibility(DefaultVisibility),
UnnamedAddrVal(unsigned(UnnamedAddr::None)),
DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal),
diff --git a/llvm/include/llvm/IR/GlobalVariable.h b/llvm/include/llvm/IR/GlobalVariable.h
index 0736c300de72f5..83e484816d7d4c 100644
--- a/llvm/include/llvm/IR/GlobalVariable.h
+++ b/llvm/include/llvm/IR/GlobalVariable.h
@@ -39,6 +39,8 @@ class DIGlobalVariableExpression;
class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
friend class SymbolTableListTraits<GlobalVariable>;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
+
AttributeSet Attrs;
// Is this a global constant?
@@ -70,24 +72,31 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
GlobalVariable(const GlobalVariable &) = delete;
GlobalVariable &operator=(const GlobalVariable &) = delete;
+private:
+ /// Set the number of operands on a GlobalVariable.
+ ///
+ /// GlobalVariable always allocates space for a single operands, but
+ /// doesn't always use it.
+ void setGlobalVariableNumOperands(unsigned NumOps) {
+ assert(NumOps <= 1 && "GlobalVariable can only have 0 or 1 operands");
+ NumUserOperands = NumOps;
+ }
+
+public:
~GlobalVariable() {
dropAllReferences();
+
+ // Number of operands can be set to 0 after construction and initialization.
+ // Make sure that number of operands is reset to 1, as this is needed in
+ // User::operator delete
+ setGlobalVariableNumOperands(1);
}
// allocate space for exactly one operand
- void *operator new(size_t s) {
- return User::operator new(s, 1);
- }
+ void *operator new(size_t s) { return User::operator new(s, AllocMarker); }
// delete space for exactly one operand as created in the corresponding new operator
- void operator delete(void *ptr){
- assert(ptr != nullptr && "must not be nullptr");
- User *Obj = static_cast<User *>(ptr);
- // Number of operands can be set to 0 after construction and initialization. Make sure
- // that number of operands is reset to 1, as this is needed in User::operator delete
- Obj->setGlobalVariableNumOperands(1);
- User::operator delete(Obj);
- }
+ void operator delete(void *ptr) { User::operator delete(ptr); }
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index 6fddedd86e97b8..82dd9cf7e296e9 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -55,24 +55,26 @@ typedef unsigned ID;
//===----------------------------------------------------------------------===//
class UnaryInstruction : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
+
protected:
UnaryInstruction(Type *Ty, unsigned iType, Value *V, BasicBlock::iterator IB)
- : Instruction(Ty, iType, &Op<0>(), 1, IB) {
+ : Instruction(Ty, iType, AllocMarker, IB) {
Op<0>() = V;
}
UnaryInstruction(Type *Ty, unsigned iType, Value *V,
Instruction *IB = nullptr)
- : Instruction(Ty, iType, &Op<0>(), 1, IB) {
+ : Instruction(Ty, iType, AllocMarker, IB) {
Op<0>() = V;
}
UnaryInstruction(Type *Ty, unsigned iType, Value *V, BasicBlock *IAE)
- : Instruction(Ty, iType, &Op<0>(), 1, IAE) {
+ : Instruction(Ty, iType, AllocMarker, IAE) {
Op<0>() = V;
}
public:
// allocate space for exactly one operand
- void *operator new(size_t S) { return User::operator new(S, 1); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Transparently provide more efficient getOperand methods.
@@ -186,6 +188,8 @@ class UnaryOperator : public UnaryInstruction {
//===----------------------------------------------------------------------===//
class BinaryOperator : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
void AssertOK();
protected:
@@ -199,7 +203,7 @@ class BinaryOperator : public Instruction {
public:
// allocate space for exactly two operands
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Transparently provide more efficient getOperand methods.
@@ -745,6 +749,8 @@ class PossiblyNonNegInst : public CastInst {
/// This class is the base class for the comparison instructions.
/// Abstract base class of comparison instructions.
class CmpInst : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
public:
/// This enumeration lists the possible predicates for CmpInst subclasses.
/// Values in the range 0-31 are reserved for FCmpInst, while values in the
@@ -814,7 +820,7 @@ class CmpInst : public Instruction {
public:
// allocate space for exactly two operands
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Construct a compare instruction, given the opcode, the predicate and
@@ -2416,10 +2422,10 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CallBase, Value)
//===----------------------------------------------------------------------===//
class FuncletPadInst : public Instruction {
private:
- FuncletPadInst(const FuncletPadInst &CPI);
+ FuncletPadInst(const FuncletPadInst &CPI, AllocInfo AllocInfo);
explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
- ArrayRef<Value *> Args, unsigned Values,
+ ArrayRef<Value *> Args, AllocInfo AllocInfo,
const Twine &NameStr, InsertPosition InsertBefore);
void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr);
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index c27572300d5063..a12d5d9d8fe945 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -1030,7 +1030,7 @@ class Instruction : public User,
setValueSubclassData(Storage);
}
- Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
+ Instruction(Type *Ty, unsigned iType, AllocInfo AllocInfo,
InsertPosition InsertBefore = nullptr);
private:
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index ab3321ee755717..e89739a5552662 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -297,6 +297,8 @@ class StoreInst : public Instruction {
void AssertOK();
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -314,7 +316,7 @@ class StoreInst : public Instruction {
InsertPosition InsertBefore = nullptr);
// allocate space for exactly two operands
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Return true if this is a store to a volatile memory location.
@@ -420,6 +422,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
class FenceInst : public Instruction {
using OrderingField = AtomicOrderingBitfieldElementT<0>;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{0};
+
void Init(AtomicOrdering Ordering, SyncScope::ID SSID);
protected:
@@ -436,7 +440,7 @@ class FenceInst : public Instruction {
InsertPosition InsertBefore = nullptr);
// allocate space for exactly zero operands
- void *operator new(size_t S) { return User::operator new(S, 0); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Returns the ordering constraint of this fence instruction.
@@ -502,6 +506,8 @@ class AtomicCmpXchgInst : public Instruction {
typename Bitfield::Element<AtomicOrdering, Offset, 3,
AtomicOrdering::LAST>;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{3};
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -515,7 +521,7 @@ class AtomicCmpXchgInst : public Instruction {
InsertPosition InsertBefore = nullptr);
// allocate space for exactly three operands
- void *operator new(size_t S) { return User::operator new(S, 3); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
using VolatileField = BoolBitfieldElementT<0>;
@@ -774,13 +780,15 @@ class AtomicRMWInst : public Instruction {
using BinOpBitfieldElement =
typename Bitfield::Element<BinOp, Offset, 5, BinOp::LAST_BINOP>;
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
public:
AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val, Align Alignment,
AtomicOrdering Ordering, SyncScope::ID SSID,
InsertPosition InsertBefore = nullptr);
// allocate space for exactly two operands
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
using VolatileField = BoolBitfieldElementT<0>;
@@ -924,14 +932,14 @@ class GetElementPtrInst : public Instruction {
Type *SourceElementType;
Type *ResultElementType;
- GetElementPtrInst(const GetElementPtrInst &GEPI);
+ GetElementPtrInst(const GetElementPtrInst &GEPI, AllocInfo AllocInfo);
/// Constructors - Create a getelementptr instruction with a base pointer an
/// list of indices. The first and second ctor can optionally insert before an
/// existing instruction, the third appends the new instruction to the
/// specified BasicBlock.
inline GetElementPtrInst(Type *PointeeType, Value *Ptr,
- ArrayRef<Value *> IdxList, unsigned Values,
+ ArrayRef<Value *> IdxList, AllocInfo AllocInfo,
const Twine &NameStr, InsertPosition InsertBefore);
void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
@@ -949,8 +957,9 @@ class GetElementPtrInst : public Instruction {
InsertPosition InsertBefore = nullptr) {
unsigned Values = 1 + unsigned(IdxList.size());
assert(PointeeType && "Must specify element type");
- return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
- NameStr, InsertBefore);
+ IntrusiveOperandsAllocMarker AllocMarker{Values};
+ return new (AllocMarker) GetElementPtrInst(
+ PointeeType, Ptr, IdxList, AllocMarker, NameStr, InsertBefore);
}
static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
@@ -1124,12 +1133,11 @@ struct OperandTraits<GetElementPtrInst>
: public VariadicOperandTraits<GetElementPtrInst> {};
GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
- ArrayRef<Value *> IdxList, unsigned Values,
- const Twine &NameStr,
+ ArrayRef<Value *> IdxList,
+ AllocInfo AllocInfo, const Twine &NameStr,
InsertPosition InsertBefore)
- : Instruction(getGEPReturnType(Ptr, IdxList), GetElementPtr,
- OperandTraits<GetElementPtrInst>::op_end(this) - Values,
- Values, InsertBefore),
+ : Instruction(getGEPReturnType(Ptr, IdxList), GetElementPtr, AllocInfo,
+ InsertBefore),
SourceElementType(PointeeType),
ResultElementType(getIndexedType(PointeeType, IdxList)) {
init(Ptr, IdxList, NameStr);
@@ -1403,26 +1411,29 @@ class FCmpInst: public CmpInst {
/// hold the calling convention of the call.
///
class CallInst : public CallBase {
- CallInst(const CallInst &CI);
+ CallInst(const CallInst &CI, AllocInfo AllocInfo);
/// Construct a CallInst from a range of arguments
inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
- InsertPosition InsertBefore);
+ AllocInfo AllocInfo, InsertPosition InsertBefore);
inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
- const Twine &NameStr, InsertPosition InsertBefore)
- : CallInst(Ty, Func, Args, std::nullopt, NameStr, InsertBefore) {}
+ const Twine &NameStr, AllocInfo AllocInfo,
+ InsertPosition InsertBefore)
+ : CallInst(Ty, Func, Args, std::nullopt, NameStr, AllocInfo,
+ InsertBefore) {}
explicit CallInst(FunctionType *Ty, Value *F, const Twine &NameStr,
- InsertPosition InsertBefore);
+ AllocInfo AllocInfo, InsertPosition InsertBefore);
void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
void init(FunctionType *FTy, Value *Func, const Twine &NameStr);
/// Compute the number of operands to allocate.
- static int ComputeNumOperands(int NumArgs, int NumBundleInputs = 0) {
+ static unsigned ComputeNumOperands(unsigned NumArgs,
+ unsigned NumBundleInputs = 0) {
// We need one operand for the called function, plus the input operand
// counts provided.
return 1 + NumArgs + NumBundleInputs;
@@ -1437,26 +1448,29 @@ class CallInst : public CallBase {
public:
static CallInst *Create(FunctionType *Ty, Value *F, const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr) {
- return new (ComputeNumOperands(0)) CallInst(Ty, F, NameStr, InsertBefore);
+ IntrusiveOperandsAllocMarker AllocMarker{ComputeNumOperands(0)};
+ return new (AllocMarker)
+ CallInst(Ty, F, NameStr, AllocMarker, InsertBefore);
}
static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr,
InsertPosition InsertBefore = nullptr) {
- return new (ComputeNumOperands(Args.size()))
- CallInst(Ty, Func, Args, std::nullopt, NameStr, InsertBefore);
+ IntrusiveOperandsAllocMarker AllocMarker{ComputeNumOperands(Args.size())};
+ return new (AllocMarker) CallInst(Ty, Func, Args, std::nullopt, NameStr,
+ AllocMarker, InsertBefore);
}
static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles = std::nullopt,
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr) {
- const int NumOperands =
- ComputeNumOperands(Args.size(), CountBundleInputs(Bundles));
- const unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo);
+ IntrusiveOperandsAndDescriptorAllocMarker AllocMarker{
+ ComputeNumOperands(unsigned(Args.size()), CountBundleInputs(Bundles)),
+ unsigned(Bundles.size() * sizeof(BundleOpInfo))};
- return new (NumOperands, DescriptorBytes)
- CallInst(Ty, Func, Args, Bundles, NameStr, InsertBefore);
+ return new (AllocMarker)
+ CallInst(Ty, Func, Args, Bundles, NameStr, AllocMarker, InsertBefore);
}
static CallInst *Create(FunctionCallee Func, const Twine &NameStr = "",
@@ -1561,12 +1575,11 @@ class CallInst : public CallBase {
CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
- InsertPosition InsertBefore)
- : CallBase(Ty->getReturnType(), Instruction::Call,
- OperandTraits<CallBase>::op_end(this) -
- (Args.size() + CountBundleInputs(Bundles) + 1),
- unsigned(Args.size() + CountBundleInputs(Bundles) + 1),
+ AllocInfo AllocInfo, InsertPosition InsertBefore)
+ : CallBase(Ty->getReturnType(), Instruction::Call, AllocInfo,
InsertBefore) {
+ assert(AllocInfo.NumOps ==
+ unsigned(Args.size() + CountBundleInputs(Bundles) + 1));
init(Ty, Func, Args, Bundles, NameStr);
}
@@ -1577,10 +1590,11 @@ CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
/// This class represents the LLVM 'select' instruction.
///
class SelectInst : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{3};
SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr,
InsertPosition InsertBefore)
- : Instruction(S1->getType(), Instruction::Select, &Op<0>(), 3,
+ : Instruction(S1->getType(), Instruction::Select, AllocMarker,
InsertBefore) {
init(C, S1, S2);
setName(NameStr);
@@ -1604,7 +1618,8 @@ class SelectInst : public Instruction {
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr,
Instruction *MDFrom = nullptr) {
- SelectInst *Sel = new(3) SelectInst(C, S1, S2, NameStr, InsertBefore);
+ SelectInst *Sel =
+ new (AllocMarker) SelectInst(C, S1, S2, NameStr, InsertBefore);
if (MDFrom)
Sel->copyMetadata(*MDFrom);
return Sel;
@@ -1693,6 +1708,8 @@ class VAArgInst : public UnaryInstruction {
/// element from a VectorType value
///
class ExtractElementInst : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr);
@@ -1706,7 +1723,8 @@ class ExtractElementInst : public Instruction {
static ExtractElementInst *Create(Value *Vec, Value *Idx,
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr) {
- return new(2) ExtractElementInst(Vec, Idx, NameStr, InsertBefore);
+ return new (AllocMarker)
+ ExtractElementInst(Vec, Idx, NameStr, InsertBefore);
}
/// Return true if an extractelement instruction can be
@@ -1749,6 +1767,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementInst, Value)
/// element into a VectorType value
///
class InsertElementInst : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{3};
+
InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr);
@@ -1763,7 +1783,8 @@ class InsertElementInst : public Instruction {
static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx,
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr) {
- return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertBefore);
+ return new (AllocMarker)
+ InsertElementInst(Vec, NewElt, Idx, NameStr, InsertBefore);
}
/// Return true if an insertelement instruction can be
@@ -1813,6 +1834,8 @@ constexpr int PoisonMaskElem = -1;
/// For scalable vectors, all the elements of the mask must be 0 or -1. This
/// requirement may be relaxed in the future.
class ShuffleVectorInst : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
SmallVector<int, 4> ShuffleMask;
Constant *ShuffleMaskForBitcode;
@@ -1834,7 +1857,7 @@ class ShuffleVectorInst : public Instruction {
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr);
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { return User::operator delete(Ptr); }
/// Swap the operands and adjust the mask to preserve the semantics
@@ -2395,6 +2418,8 @@ ExtractValueInst::ExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
/// value into an aggregate value.
///
class InsertValueInst : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
SmallVector<unsigned, 4> Indices;
InsertValueInst(const InsertValueInst &IVI);
@@ -2423,7 +2448,7 @@ class InsertValueInst : public Instruction {
public:
// allocate space for exactly two operands
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
static InsertValueInst *Create(Value *Agg, Value *Val,
@@ -2493,9 +2518,7 @@ struct OperandTraits<InsertValueInst> :
InsertValueInst::InsertValueInst(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs, const Twine &NameStr,
InsertPosition InsertBefore)
- : Instruction(Agg->getType(), InsertValue,
- OperandTraits<InsertValueInst>::op_begin(this), 2,
- InsertBefore) {
+ : Instruction(Agg->getType(), InsertValue, AllocMarker, InsertBefore) {
init(Agg, Val, Idxs, NameStr);
}
@@ -2510,6 +2533,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
// scientist's overactive imagination.
//
class PHINode : public Instruction {
+ constexpr static HungOffOperandsAllocMarker AllocMarker{};
+
/// The number of operands actually allocated. NumOperands is
/// the number actually in use.
unsigned ReservedSpace;
@@ -2519,7 +2544,7 @@ class PHINode : public Instruction {
explicit PHINode(Type *Ty, unsigned NumReservedValues,
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr)
- : Instruction(Ty, Instruction::PHI, nullptr, 0, InsertBefore),
+ : Instruction(Ty, Instruction::PHI, AllocMarker, InsertBefore),
ReservedSpace(NumReservedValues) {
assert(!Ty->isTokenTy() && "PHI nodes cannot have token type!");
setName(NameStr);
@@ -2545,7 +2570,8 @@ class PHINode : public Instruction {
static PHINode *Create(Type *Ty, unsigned NumReservedValues,
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr) {
- return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore);
+ return new (AllocMarker)
+ PHINode(Ty, NumReservedValues, NameStr, InsertBefore);
}
/// Provide fast operand accessors
@@ -2749,6 +2775,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value)
class LandingPadInst : public Instruction {
using CleanupField = BoolBitfieldElementT<0>;
+ constexpr static HungOffOperandsAllocMarker AllocMarker{};
+
/// The number of operands actually allocated. NumOperands is
/// the number actually in use.
unsigned ReservedSpace;
@@ -2763,7 +2791,7 @@ class LandingPadInst : public Instruction {
const Twine &NameStr, InsertPosition InsertBefore);
// Allocate space for exactly zero operands.
- void *operator new(size_t S) { return User::operator new(S); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void growOperands(unsigned Size);
void init(unsigned NumReservedValues, const Twine &NameStr);
@@ -2843,7 +2871,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value)
/// does not continue in this function any longer.
///
class ReturnInst : public Instruction {
- ReturnInst(const ReturnInst &RI);
+ ReturnInst(const ReturnInst &RI, AllocInfo AllocInfo);
private:
// ReturnInst constructors:
@@ -2859,8 +2887,8 @@ class ReturnInst : public Instruction {
//
// NOTE: If the Value* passed is of type void then the constructor behaves as
// if it was passed NULL.
- explicit ReturnInst(LLVMContext &C, Value *retVal = nullptr,
- InsertPosition InsertBefore = nullptr);
+ explicit ReturnInst(LLVMContext &C, Value *retVal, AllocInfo AllocInfo,
+ InsertPosition InsertBefore);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
@@ -2871,11 +2899,13 @@ class ReturnInst : public Instruction {
public:
static ReturnInst *Create(LLVMContext &C, Value *retVal = nullptr,
InsertPosition InsertBefore = nullptr) {
- return new(!!retVal) ReturnInst(C, retVal, InsertBefore);
+ IntrusiveOperandsAllocMarker AllocMarker{retVal ? 1U : 0U};
+ return new (AllocMarker) ReturnInst(C, retVal, AllocMarker, InsertBefore);
}
static ReturnInst *Create(LLVMContext &C, BasicBlock *InsertAtEnd) {
- return new (0) ReturnInst(C, nullptr, InsertAtEnd);
+ IntrusiveOperandsAllocMarker AllocMarker{0};
+ return new (AllocMarker) ReturnInst(C, nullptr, AllocMarker, InsertAtEnd);
}
/// Provide fast operand accessors
@@ -2923,7 +2953,7 @@ class BranchInst : public Instruction {
/// [Cond, FalseDest,] TrueDest. This makes some accessors faster because
/// they don't have to check for cond/uncond branchness. These are mostly
/// accessed relative from op_end().
- BranchInst(const BranchInst &BI);
+ BranchInst(const BranchInst &BI, AllocInfo AllocInfo);
// BranchInst constructors (where {B, T, F} are blocks, and C is a condition):
// BranchInst(BB *B) - 'br B'
// BranchInst(BB* T, BB *F, Value *C) - 'br C, T, F'
@@ -2933,10 +2963,10 @@ class BranchInst : public Instruction {
// BranchInst(BB* T, BB *F, Value *C, Inst *I) - 'br C, T, F', insert before I
// BranchInst(BB* B, BB *I) - 'br B' insert at end
// BranchInst(BB* T, BB *F, Value *C, BB *I) - 'br C, T, F', insert at end
- explicit BranchInst(BasicBlock *IfTrue,
- InsertPosition InsertBefore = nullptr);
+ explicit BranchInst(BasicBlock *IfTrue, AllocInfo AllocInfo,
+ InsertPosition InsertBefore);
BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
- InsertPosition InsertBefore = nullptr);
+ AllocInfo AllocInfo, InsertPosition InsertBefore);
void AssertOK();
@@ -2976,13 +3006,16 @@ class BranchInst : public Instruction {
static BranchInst *Create(BasicBlock *IfTrue,
InsertPosition InsertBefore = nullptr) {
- return new(1) BranchInst(IfTrue, InsertBefore);
+ IntrusiveOperandsAllocMarker AllocMarker{1};
+ return new (AllocMarker) BranchInst(IfTrue, AllocMarker, InsertBefore);
}
static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
Value *Cond,
InsertPosition InsertBefore = nullptr) {
- return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertBefore);
+ IntrusiveOperandsAllocMarker AllocMarker{3};
+ return new (AllocMarker)
+ BranchInst(IfTrue, IfFalse, Cond, AllocMarker, InsertBefore);
}
/// Transparently provide more efficient getOperand methods.
@@ -3054,6 +3087,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value)
/// Multiway switch
///
class SwitchInst : public Instruction {
+ constexpr static HungOffOperandsAllocMarker AllocMarker{};
+
unsigned ReservedSpace;
// Operand[0] = Value to switch on
@@ -3070,7 +3105,7 @@ class SwitchInst : public Instruction {
InsertPosition InsertBefore);
// allocate space for exactly zero operands
- void *operator new(size_t S) { return User::operator new(S); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
void growOperands();
@@ -3442,6 +3477,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value)
/// Indirect Branch Instruction.
///
class IndirectBrInst : public Instruction {
+ constexpr static HungOffOperandsAllocMarker AllocMarker{};
+
unsigned ReservedSpace;
// Operand[0] = Address to jump to
@@ -3456,7 +3493,7 @@ class IndirectBrInst : public Instruction {
InsertPosition InsertBefore);
// allocate space for exactly zero operands
- void *operator new(size_t S) { return User::operator new(S); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void init(Value *Address, unsigned NumDests);
void growOperands();
@@ -3576,14 +3613,14 @@ class InvokeInst : public CallBase {
/// The index from the end of the operand array to the unwind destination.
static constexpr int UnwindDestOpEndIdx = -2;
- InvokeInst(const InvokeInst &BI);
+ InvokeInst(const InvokeInst &BI, AllocInfo AllocInfo);
/// Construct an InvokeInst given a range of arguments.
///
/// Construct an InvokeInst from a range of arguments
inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles, int NumOperands,
+ ArrayRef<OperandBundleDef> Bundles, AllocInfo AllocInfo,
const Twine &NameStr, InsertPosition InsertBefore);
void init(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
@@ -3591,10 +3628,11 @@ class InvokeInst : public CallBase {
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
/// Compute the number of operands to allocate.
- static int ComputeNumOperands(int NumArgs, int NumBundleInputs = 0) {
+ static unsigned ComputeNumOperands(unsigned NumArgs,
+ size_t NumBundleInputs = 0) {
// We need one operand for the called function, plus our extra operands and
// the input operand counts provided.
- return 1 + NumExtraOperands + NumArgs + NumBundleInputs;
+ return 1 + NumExtraOperands + NumArgs + unsigned(NumBundleInputs);
}
protected:
@@ -3608,10 +3646,11 @@ class InvokeInst : public CallBase {
BasicBlock *IfException, ArrayRef<Value *> Args,
const Twine &NameStr,
InsertPosition InsertBefore = nullptr) {
- int NumOperands = ComputeNumOperands(Args.size());
- return new (NumOperands)
+ IntrusiveOperandsAllocMarker AllocMarker{
+ ComputeNumOperands(unsigned(Args.size()))};
+ return new (AllocMarker)
InvokeInst(Ty, Func, IfNormal, IfException, Args, std::nullopt,
- NumOperands, NameStr, InsertBefore);
+ AllocMarker, NameStr, InsertBefore);
}
static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
@@ -3619,12 +3658,12 @@ class InvokeInst : public CallBase {
ArrayRef<OperandBundleDef> Bundles = std::nullopt,
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr) {
- int NumOperands =
- ComputeNumOperands(Args.size(), CountBundleInputs(Bundles));
- unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo);
+ IntrusiveOperandsAndDescriptorAllocMarker AllocMarker{
+ ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)),
+ unsigned(Bundles.size() * sizeof(BundleOpInfo))};
- return new (NumOperands, DescriptorBytes)
- InvokeInst(Ty, Func, IfNormal, IfException, Args, Bundles, NumOperands,
+ return new (AllocMarker)
+ InvokeInst(Ty, Func, IfNormal, IfException, Args, Bundles, AllocMarker,
NameStr, InsertBefore);
}
@@ -3709,10 +3748,9 @@ class InvokeInst : public CallBase {
InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles, int NumOperands,
+ ArrayRef<OperandBundleDef> Bundles, AllocInfo AllocInfo,
const Twine &NameStr, InsertPosition InsertBefore)
- : CallBase(Ty->getReturnType(), Instruction::Invoke,
- OperandTraits<CallBase>::op_end(this) - NumOperands, NumOperands,
+ : CallBase(Ty->getReturnType(), Instruction::Invoke, AllocInfo,
InsertBefore) {
init(Ty, Func, IfNormal, IfException, Args, Bundles, NameStr);
}
@@ -3729,7 +3767,7 @@ class CallBrInst : public CallBase {
unsigned NumIndirectDests;
- CallBrInst(const CallBrInst &BI);
+ CallBrInst(const CallBrInst &BI, AllocInfo AllocInfo);
/// Construct a CallBrInst given a range of arguments.
///
@@ -3737,7 +3775,7 @@ class CallBrInst : public CallBase {
inline CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest,
ArrayRef<BasicBlock *> IndirectDests,
ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles,
- int NumOperands, const Twine &NameStr,
+ AllocInfo AllocInfo, const Twine &NameStr,
InsertPosition InsertBefore);
void init(FunctionType *FTy, Value *Func, BasicBlock *DefaultDest,
@@ -3745,11 +3783,11 @@ class CallBrInst : public CallBase {
ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
/// Compute the number of operands to allocate.
- static int ComputeNumOperands(int NumArgs, int NumIndirectDests,
- int NumBundleInputs = 0) {
+ static unsigned ComputeNumOperands(int NumArgs, int NumIndirectDests,
+ int NumBundleInputs = 0) {
// We need one operand for the called function, plus our extra operands and
// the input operand counts provided.
- return 2 + NumIndirectDests + NumArgs + NumBundleInputs;
+ return unsigned(2 + NumIndirectDests + NumArgs + NumBundleInputs);
}
protected:
@@ -3764,10 +3802,11 @@ class CallBrInst : public CallBase {
ArrayRef<BasicBlock *> IndirectDests,
ArrayRef<Value *> Args, const Twine &NameStr,
InsertPosition InsertBefore = nullptr) {
- int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size());
- return new (NumOperands)
+ IntrusiveOperandsAllocMarker AllocMarker{
+ ComputeNumOperands(Args.size(), IndirectDests.size())};
+ return new (AllocMarker)
CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, std::nullopt,
- NumOperands, NameStr, InsertBefore);
+ AllocMarker, NameStr, InsertBefore);
}
static CallBrInst *
@@ -3775,13 +3814,14 @@ class CallBrInst : public CallBase {
ArrayRef<BasicBlock *> IndirectDests, ArrayRef<Value *> Args,
ArrayRef<OperandBundleDef> Bundles = std::nullopt,
const Twine &NameStr = "", InsertPosition InsertBefore = nullptr) {
- int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size(),
- CountBundleInputs(Bundles));
- unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo);
+ IntrusiveOperandsAndDescriptorAllocMarker AllocMarker{
+ ComputeNumOperands(Args.size(), IndirectDests.size(),
+ CountBundleInputs(Bundles)),
+ unsigned(Bundles.size() * sizeof(BundleOpInfo))};
- return new (NumOperands, DescriptorBytes)
+ return new (AllocMarker)
CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, Bundles,
- NumOperands, NameStr, InsertBefore);
+ AllocMarker, NameStr, InsertBefore);
}
static CallBrInst *Create(FunctionCallee Func, BasicBlock *DefaultDest,
@@ -3881,10 +3921,9 @@ class CallBrInst : public CallBase {
CallBrInst::CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest,
ArrayRef<BasicBlock *> IndirectDests,
ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles, int NumOperands,
+ ArrayRef<OperandBundleDef> Bundles, AllocInfo AllocInfo,
const Twine &NameStr, InsertPosition InsertBefore)
- : CallBase(Ty->getReturnType(), Instruction::CallBr,
- OperandTraits<CallBase>::op_end(this) - NumOperands, NumOperands,
+ : CallBase(Ty->getReturnType(), Instruction::CallBr, AllocInfo,
InsertBefore) {
init(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, NameStr);
}
@@ -3897,6 +3936,8 @@ CallBrInst::CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest,
/// Resume the propagation of an exception.
///
class ResumeInst : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
+
ResumeInst(const ResumeInst &RI);
explicit ResumeInst(Value *Exn, InsertPosition InsertBefore = nullptr);
@@ -3909,7 +3950,7 @@ class ResumeInst : public Instruction {
public:
static ResumeInst *Create(Value *Exn, InsertPosition InsertBefore = nullptr) {
- return new(1) ResumeInst(Exn, InsertBefore);
+ return new (AllocMarker) ResumeInst(Exn, InsertBefore);
}
/// Provide fast operand accessors
@@ -3951,6 +3992,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
class CatchSwitchInst : public Instruction {
using UnwindDestField = BoolBitfieldElementT<0>;
+ constexpr static HungOffOperandsAllocMarker AllocMarker{};
+
/// The number of operands actually allocated. NumOperands is
/// the number actually in use.
unsigned ReservedSpace;
@@ -3969,7 +4012,7 @@ class CatchSwitchInst : public Instruction {
InsertPosition InsertBefore);
// allocate space for exactly zero operands
- void *operator new(size_t S) { return User::operator new(S); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void init(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReserved);
void growOperands(unsigned Size);
@@ -4114,9 +4157,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchSwitchInst, Value)
class CleanupPadInst : public FuncletPadInst {
private:
explicit CleanupPadInst(Value *ParentPad, ArrayRef<Value *> Args,
- unsigned Values, const Twine &NameStr,
+ AllocInfo AllocInfo, const Twine &NameStr,
InsertPosition InsertBefore)
- : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values,
+ : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, AllocInfo,
NameStr, InsertBefore) {}
public:
@@ -4124,9 +4167,9 @@ class CleanupPadInst : public FuncletPadInst {
ArrayRef<Value *> Args = std::nullopt,
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr) {
- unsigned Values = 1 + Args.size();
- return new (Values)
- CleanupPadInst(ParentPad, Args, Values, NameStr, InsertBefore);
+ IntrusiveOperandsAllocMarker AllocMarker{unsigned(1 + Args.size())};
+ return new (AllocMarker)
+ CleanupPadInst(ParentPad, Args, AllocMarker, NameStr, InsertBefore);
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -4144,18 +4187,18 @@ class CleanupPadInst : public FuncletPadInst {
class CatchPadInst : public FuncletPadInst {
private:
explicit CatchPadInst(Value *CatchSwitch, ArrayRef<Value *> Args,
- unsigned Values, const Twine &NameStr,
+ AllocInfo AllocInfo, const Twine &NameStr,
InsertPosition InsertBefore)
- : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values,
+ : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, AllocInfo,
NameStr, InsertBefore) {}
public:
static CatchPadInst *Create(Value *CatchSwitch, ArrayRef<Value *> Args,
const Twine &NameStr = "",
InsertPosition InsertBefore = nullptr) {
- unsigned Values = 1 + Args.size();
- return new (Values)
- CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertBefore);
+ IntrusiveOperandsAllocMarker AllocMarker{unsigned(1 + Args.size())};
+ return new (AllocMarker)
+ CatchPadInst(CatchSwitch, Args, AllocMarker, NameStr, InsertBefore);
}
/// Convenience accessors
@@ -4181,6 +4224,8 @@ class CatchPadInst : public FuncletPadInst {
//===----------------------------------------------------------------------===//
class CatchReturnInst : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
CatchReturnInst(const CatchReturnInst &RI);
CatchReturnInst(Value *CatchPad, BasicBlock *BB, InsertPosition InsertBefore);
@@ -4197,7 +4242,7 @@ class CatchReturnInst : public Instruction {
InsertPosition InsertBefore = nullptr) {
assert(CatchPad);
assert(BB);
- return new (2) CatchReturnInst(CatchPad, BB, InsertBefore);
+ return new (AllocMarker) CatchReturnInst(CatchPad, BB, InsertBefore);
}
/// Provide fast operand accessors
@@ -4257,9 +4302,9 @@ class CleanupReturnInst : public Instruction {
using UnwindDestField = BoolBitfieldElementT<0>;
private:
- CleanupReturnInst(const CleanupReturnInst &RI);
- CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values,
- InsertPosition InsertBefore = nullptr);
+ CleanupReturnInst(const CleanupReturnInst &RI, AllocInfo AllocInfo);
+ CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB,
+ AllocInfo AllocInfo, InsertPosition InsertBefore = nullptr);
void init(Value *CleanupPad, BasicBlock *UnwindBB);
@@ -4277,8 +4322,9 @@ class CleanupReturnInst : public Instruction {
unsigned Values = 1;
if (UnwindBB)
++Values;
- return new (Values)
- CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore);
+ IntrusiveOperandsAllocMarker AllocMarker{Values};
+ return new (AllocMarker)
+ CleanupReturnInst(CleanupPad, UnwindBB, AllocMarker, InsertBefore);
}
/// Provide fast operand accessors
@@ -4350,6 +4396,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
/// end of the block cannot be reached.
///
class UnreachableInst : public Instruction {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{0};
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -4361,7 +4409,7 @@ class UnreachableInst : public Instruction {
InsertPosition InsertBefore = nullptr);
// allocate space for exactly zero operands
- void *operator new(size_t S) { return User::operator new(S, 0); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
unsigned getNumSuccessors() const { return 0; }
diff --git a/llvm/include/llvm/IR/User.h b/llvm/include/llvm/IR/User.h
index 910815f236abea..39e1314bd8130b 100644
--- a/llvm/include/llvm/IR/User.h
+++ b/llvm/include/llvm/IR/User.h
@@ -43,39 +43,86 @@ struct OperandTraits;
class User : public Value {
friend struct HungoffOperandTraits;
+ template <class ConstantClass> friend struct ConstantAggrKeyType;
LLVM_ATTRIBUTE_ALWAYS_INLINE static void *
allocateFixedOperandUser(size_t, unsigned, unsigned);
protected:
+ // Disable the default operator new, as all subclasses must use one of the
+ // custom operators below depending on how they store their operands.
+ void *operator new(size_t Size) = delete;
+
+ /// Indicates this User has operands "hung off" in another allocation.
+ struct HungOffOperandsAllocMarker {};
+
+ /// Indicates this User has operands co-allocated.
+ struct IntrusiveOperandsAllocMarker {
+ /// The number of operands for this User.
+ const unsigned NumOps;
+ };
+
+ /// Indicates this User has operands and a descriptor co-allocated .
+ struct IntrusiveOperandsAndDescriptorAllocMarker {
+ /// The number of operands for this User.
+ const unsigned NumOps;
+ /// The number of bytes to allocate for the descriptor. Must be divisible by
+ /// `sizeof(void *)`.
+ const unsigned DescBytes;
+ };
+
+ /// Information about how a User object was allocated, to be passed into the
+ /// User constructor.
+ ///
+ /// DO NOT USE DIRECTLY. Use one of the `AllocMarker` structs instead, they
+ /// call all be implicitly converted to `AllocInfo`.
+ struct AllocInfo {
+ public:
+ const unsigned NumOps : NumUserOperandsBits;
+ const bool HasHungOffUses : 1;
+ const bool HasDescriptor : 1;
+
+ AllocInfo() = delete;
+
+ constexpr AllocInfo(const HungOffOperandsAllocMarker)
+ : NumOps(0), HasHungOffUses(true), HasDescriptor(false) {}
+
+ constexpr AllocInfo(const IntrusiveOperandsAllocMarker Alloc)
+ : NumOps(Alloc.NumOps), HasHungOffUses(false), HasDescriptor(false) {}
+
+ constexpr AllocInfo(const IntrusiveOperandsAndDescriptorAllocMarker Alloc)
+ : NumOps(Alloc.NumOps), HasHungOffUses(false),
+ HasDescriptor(Alloc.DescBytes != 0) {}
+ };
+
/// Allocate a User with an operand pointer co-allocated.
///
/// This is used for subclasses which need to allocate a variable number
/// of operands, ie, 'hung off uses'.
- void *operator new(size_t Size);
+ void *operator new(size_t Size, HungOffOperandsAllocMarker);
/// Allocate a User with the operands co-allocated.
///
/// This is used for subclasses which have a fixed number of operands.
- void *operator new(size_t Size, unsigned Us);
+ void *operator new(size_t Size, IntrusiveOperandsAllocMarker allocTrait);
/// Allocate a User with the operands co-allocated. If DescBytes is non-zero
/// then allocate an additional DescBytes bytes before the operands. These
/// bytes can be accessed by calling getDescriptor.
- ///
- /// DescBytes needs to be divisible by sizeof(void *). The allocated
- /// descriptor, if any, is aligned to sizeof(void *) bytes.
- ///
- /// This is used for subclasses which have a fixed number of operands.
- void *operator new(size_t Size, unsigned Us, unsigned DescBytes);
-
- User(Type *ty, unsigned vty, Use *, unsigned NumOps)
- : Value(ty, vty) {
- assert(NumOps < (1u << NumUserOperandsBits) && "Too many operands");
- NumUserOperands = NumOps;
+ void *operator new(size_t Size,
+ IntrusiveOperandsAndDescriptorAllocMarker allocTrait);
+
+ User(Type *ty, unsigned vty, AllocInfo AllocInfo) : Value(ty, vty) {
+ assert(AllocInfo.NumOps < (1u << NumUserOperandsBits) &&
+ "Too many operands");
+ NumUserOperands = AllocInfo.NumOps;
+ assert((!AllocInfo.HasDescriptor || !AllocInfo.HasHungOffUses) &&
+ "Cannot have both hung off uses and a descriptor");
+ HasHungOffUses = AllocInfo.HasHungOffUses;
+ HasDescriptor = AllocInfo.HasDescriptor;
// If we have hung off uses, then the operand list should initially be
// null.
- assert((!HasHungOffUses || !getOperandList()) &&
+ assert((!AllocInfo.HasHungOffUses || !getOperandList()) &&
"Error in initializing hung off uses for User");
}
@@ -98,7 +145,20 @@ class User : public Value {
/// Free memory allocated for User and Use objects.
void operator delete(void *Usr);
/// Placement delete - required by std, called if the ctor throws.
- void operator delete(void *Usr, unsigned) {
+ void operator delete(void *Usr, HungOffOperandsAllocMarker) {
+ // Note: If a subclass manipulates the information which is required to
+ // calculate the Usr memory pointer, e.g. NumUserOperands, the operator
+ // delete of that subclass has to restore the changed information to the
+ // original value, since the dtor of that class is not called if the ctor
+ // fails.
+ User::operator delete(Usr);
+
+#ifndef LLVM_ENABLE_EXCEPTIONS
+ llvm_unreachable("Constructor throws?");
+#endif
+ }
+ /// Placement delete - required by std, called if the ctor throws.
+ void operator delete(void *Usr, IntrusiveOperandsAllocMarker) {
// Note: If a subclass manipulates the information which is required to calculate the
// Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has
// to restore the changed information to the original value, since the dtor of that class
@@ -110,7 +170,7 @@ class User : public Value {
#endif
}
/// Placement delete - required by std, called if the ctor throws.
- void operator delete(void *Usr, unsigned, unsigned) {
+ void operator delete(void *Usr, IntrusiveOperandsAndDescriptorAllocMarker) {
// Note: If a subclass manipulates the information which is required to calculate the
// Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has
// to restore the changed information to the original value, since the dtor of that class
@@ -195,19 +255,6 @@ class User : public Value {
/// Returns the descriptor co-allocated with this User instance.
MutableArrayRef<uint8_t> getDescriptor();
- /// Set the number of operands on a GlobalVariable.
- ///
- /// GlobalVariable always allocates space for a single operands, but
- /// doesn't always use it.
- ///
- /// FIXME: As that the number of operands is used to find the start of
- /// the allocated memory in operator delete, we need to always think we have
- /// 1 operand before delete.
- void setGlobalVariableNumOperands(unsigned NumOps) {
- assert(NumOps <= 1 && "GlobalVariable can only have 0 or 1 operands");
- NumUserOperands = NumOps;
- }
-
/// Subclasses with hung off uses need to manage the operand count
/// themselves. In these instances, the operand count isn't used to find the
/// OperandList, so there's no issue in having the operand count change.
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index e32a54fa346a9a..6d035d53732957 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -1267,9 +1267,9 @@ static Constant *getSequenceIfElementsMatch(Constant *C,
}
ConstantAggregate::ConstantAggregate(Type *T, ValueTy VT,
- ArrayRef<Constant *> V)
- : Constant(T, VT, OperandTraits<ConstantAggregate>::op_end(this) - V.size(),
- V.size()) {
+ ArrayRef<Constant *> V,
+ AllocInfo AllocInfo)
+ : Constant(T, VT, AllocInfo) {
llvm::copy(V, op_begin());
// Check that types match, unless this is an opaque struct.
@@ -1282,8 +1282,9 @@ ConstantAggregate::ConstantAggregate(Type *T, ValueTy VT,
}
}
-ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
- : ConstantAggregate(T, ConstantArrayVal, V) {
+ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V,
+ AllocInfo AllocInfo)
+ : ConstantAggregate(T, ConstantArrayVal, V, AllocInfo) {
assert(V.size() == T->getNumElements() &&
"Invalid initializer for constant array");
}
@@ -1346,8 +1347,9 @@ StructType *ConstantStruct::getTypeForElements(ArrayRef<Constant*> V,
return getTypeForElements(V[0]->getContext(), V, Packed);
}
-ConstantStruct::ConstantStruct(StructType *T, ArrayRef<Constant *> V)
- : ConstantAggregate(T, ConstantStructVal, V) {
+ConstantStruct::ConstantStruct(StructType *T, ArrayRef<Constant *> V,
+ AllocInfo AllocInfo)
+ : ConstantAggregate(T, ConstantStructVal, V, AllocInfo) {
assert((T->isOpaque() || V.size() == T->getNumElements()) &&
"Invalid initializer for constant struct");
}
@@ -1388,8 +1390,9 @@ Constant *ConstantStruct::get(StructType *ST, ArrayRef<Constant*> V) {
return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V);
}
-ConstantVector::ConstantVector(VectorType *T, ArrayRef<Constant *> V)
- : ConstantAggregate(T, ConstantVectorVal, V) {
+ConstantVector::ConstantVector(VectorType *T, ArrayRef<Constant *> V,
+ AllocInfo AllocInfo)
+ : ConstantAggregate(T, ConstantVectorVal, V, AllocInfo) {
assert(V.size() == cast<FixedVectorType>(T)->getNumElements() &&
"Invalid initializer for constant vector");
}
@@ -1879,7 +1882,7 @@ BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
BlockAddress::BlockAddress(Function *F, BasicBlock *BB)
: Constant(PointerType::get(F->getContext(), F->getAddressSpace()),
- Value::BlockAddressVal, &Op<0>(), 2) {
+ Value::BlockAddressVal, AllocMarker) {
setOperand(0, F);
setOperand(1, BB);
BB->AdjustBlockAddressRefCount(1);
@@ -1951,7 +1954,7 @@ DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {
}
DSOLocalEquivalent::DSOLocalEquivalent(GlobalValue *GV)
- : Constant(GV->getType(), Value::DSOLocalEquivalentVal, &Op<0>(), 1) {
+ : Constant(GV->getType(), Value::DSOLocalEquivalentVal, AllocMarker) {
setOperand(0, GV);
}
@@ -2009,7 +2012,7 @@ NoCFIValue *NoCFIValue::get(GlobalValue *GV) {
}
NoCFIValue::NoCFIValue(GlobalValue *GV)
- : Constant(GV->getType(), Value::NoCFIValueVal, &Op<0>(), 1) {
+ : Constant(GV->getType(), Value::NoCFIValueVal, AllocMarker) {
setOperand(0, GV);
}
@@ -2056,7 +2059,7 @@ ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const {
ConstantPtrAuth::ConstantPtrAuth(Constant *Ptr, ConstantInt *Key,
ConstantInt *Disc, Constant *AddrDisc)
- : Constant(Ptr->getType(), Value::ConstantPtrAuthVal, &Op<0>(), 4) {
+ : Constant(Ptr->getType(), Value::ConstantPtrAuthVal, AllocMarker) {
assert(Ptr->getType()->isPointerTy());
assert(Key->getBitWidth() == 32);
assert(Disc->getBitWidth() == 64);
@@ -2758,11 +2761,8 @@ const char *ConstantExpr::getOpcodeName() const {
GetElementPtrConstantExpr::GetElementPtrConstantExpr(
Type *SrcElementTy, Constant *C, ArrayRef<Constant *> IdxList, Type *DestTy,
- std::optional<ConstantRange> InRange)
- : ConstantExpr(DestTy, Instruction::GetElementPtr,
- OperandTraits<GetElementPtrConstantExpr>::op_end(this) -
- (IdxList.size() + 1),
- IdxList.size() + 1),
+ std::optional<ConstantRange> InRange, AllocInfo AllocInfo)
+ : ConstantExpr(DestTy, Instruction::GetElementPtr, AllocInfo),
SrcElementTy(SrcElementTy),
ResElementTy(GetElementPtrInst::getIndexedType(SrcElementTy, IdxList)),
InRange(std::move(InRange)) {
diff --git a/llvm/lib/IR/ConstantsContext.h b/llvm/lib/IR/ConstantsContext.h
index bd19ec6b9dcac0..6afc86ffc73abc 100644
--- a/llvm/lib/IR/ConstantsContext.h
+++ b/llvm/lib/IR/ConstantsContext.h
@@ -44,14 +44,16 @@ namespace llvm {
/// CastConstantExpr - This class is private to Constants.cpp, and is used
/// behind the scenes to implement cast constant exprs.
class CastConstantExpr final : public ConstantExpr {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
+
public:
CastConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
- : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
+ : ConstantExpr(Ty, Opcode, AllocMarker) {
Op<0>() = C;
}
// allocate space for exactly one operand
- void *operator new(size_t S) { return User::operator new(S, 1); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -67,17 +69,19 @@ class CastConstantExpr final : public ConstantExpr {
/// BinaryConstantExpr - This class is private to Constants.cpp, and is used
/// behind the scenes to implement binary constant exprs.
class BinaryConstantExpr final : public ConstantExpr {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
public:
BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
unsigned Flags)
- : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
+ : ConstantExpr(C1->getType(), Opcode, AllocMarker) {
Op<0>() = C1;
Op<1>() = C2;
SubclassOptionalData = Flags;
}
// allocate space for exactly two operands
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Transparently provide more efficient getOperand methods.
@@ -95,16 +99,18 @@ class BinaryConstantExpr final : public ConstantExpr {
/// Constants.cpp, and is used behind the scenes to implement
/// extractelement constant exprs.
class ExtractElementConstantExpr final : public ConstantExpr {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
public:
ExtractElementConstantExpr(Constant *C1, Constant *C2)
- : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
- Instruction::ExtractElement, &Op<0>(), 2) {
+ : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
+ Instruction::ExtractElement, AllocMarker) {
Op<0>() = C1;
Op<1>() = C2;
}
// allocate space for exactly two operands
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Transparently provide more efficient getOperand methods.
@@ -122,17 +128,18 @@ class ExtractElementConstantExpr final : public ConstantExpr {
/// Constants.cpp, and is used behind the scenes to implement
/// insertelement constant exprs.
class InsertElementConstantExpr final : public ConstantExpr {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{3};
+
public:
InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
- : ConstantExpr(C1->getType(), Instruction::InsertElement,
- &Op<0>(), 3) {
+ : ConstantExpr(C1->getType(), Instruction::InsertElement, AllocMarker) {
Op<0>() = C1;
Op<1>() = C2;
Op<2>() = C3;
}
// allocate space for exactly three operands
- void *operator new(size_t S) { return User::operator new(S, 3); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Transparently provide more efficient getOperand methods.
@@ -150,12 +157,14 @@ class InsertElementConstantExpr final : public ConstantExpr {
/// Constants.cpp, and is used behind the scenes to implement
/// shufflevector constant exprs.
class ShuffleVectorConstantExpr final : public ConstantExpr {
+ constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
+
public:
ShuffleVectorConstantExpr(Constant *C1, Constant *C2, ArrayRef<int> Mask)
: ConstantExpr(VectorType::get(
cast<VectorType>(C1->getType())->getElementType(),
Mask.size(), isa<ScalableVectorType>(C1->getType())),
- Instruction::ShuffleVector, &Op<0>(), 2) {
+ Instruction::ShuffleVector, AllocMarker) {
assert(ShuffleVectorInst::isValidOperands(C1, C2, Mask) &&
"Invalid shuffle vector instruction operands!");
Op<0>() = C1;
@@ -168,7 +177,7 @@ class ShuffleVectorConstantExpr final : public ConstantExpr {
SmallVector<int, 4> ShuffleMask;
Constant *ShuffleMaskForBitcode;
- void *operator new(size_t S) { return User::operator new(S, 2); }
+ void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
void operator delete(void *Ptr) { return User::operator delete(Ptr); }
/// Transparently provide more efficient getOperand methods.
@@ -191,15 +200,17 @@ class GetElementPtrConstantExpr : public ConstantExpr {
GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C,
ArrayRef<Constant *> IdxList, Type *DestTy,
- std::optional<ConstantRange> InRange);
+ std::optional<ConstantRange> InRange,
+ AllocInfo AllocInfo);
public:
static GetElementPtrConstantExpr *
Create(Type *SrcElementTy, Constant *C, ArrayRef<Constant *> IdxList,
Type *DestTy, unsigned Flags, std::optional<ConstantRange> InRange) {
- GetElementPtrConstantExpr *Result = new (IdxList.size() + 1)
+ IntrusiveOperandsAllocMarker AllocMarker{unsigned(IdxList.size() + 1)};
+ GetElementPtrConstantExpr *Result = new (AllocMarker)
GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy,
- std::move(InRange));
+ std::move(InRange), AllocMarker);
Result->SubclassOptionalData = Flags;
return Result;
}
@@ -318,7 +329,8 @@ template <class ConstantClass> struct ConstantAggrKeyType {
using TypeClass = typename ConstantInfo<ConstantClass>::TypeClass;
ConstantClass *create(TypeClass *Ty) const {
- return new (Operands.size()) ConstantClass(Ty, Operands);
+ User::IntrusiveOperandsAllocMarker AllocMarker{unsigned(Operands.size())};
+ return new (AllocMarker) ConstantClass(Ty, Operands, AllocMarker);
}
};
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index afef8930669e84..82ff4e1bc7f5c5 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -402,7 +402,7 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty,
LinkageTypes Linkage,
unsigned AddrSpace, const Twine &N,
Module *M) {
- auto *F = new Function(Ty, Linkage, AddrSpace, N, M);
+ auto *F = new (AllocMarker) Function(Ty, Linkage, AddrSpace, N, M);
AttrBuilder B(F->getContext());
UWTableKind UWTable = M->getUwtable();
if (UWTable != UWTableKind::None)
@@ -501,8 +501,7 @@ static unsigned computeAddrSpace(unsigned AddrSpace, Module *M) {
Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace,
const Twine &name, Module *ParentModule)
- : GlobalObject(Ty, Value::FunctionVal,
- OperandTraits<Function>::op_begin(this), 0, Linkage, name,
+ : GlobalObject(Ty, Value::FunctionVal, AllocMarker, Linkage, name,
computeAddrSpace(AddrSpace, ParentModule)),
NumArgs(Ty->getNumParams()), IsNewDbgInfoFormat(UseNewDbgInfoFormat) {
assert(FunctionType::isValidReturnType(getReturnType()) &&
diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp
index 2bc69cdb712b0a..99f4fa50e9c433 100644
--- a/llvm/lib/IR/Globals.cpp
+++ b/llvm/lib/IR/Globals.cpp
@@ -442,9 +442,8 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
Constant *InitVal, const Twine &Name,
ThreadLocalMode TLMode, unsigned AddressSpace,
bool isExternallyInitialized)
- : GlobalObject(Ty, Value::GlobalVariableVal,
- OperandTraits<GlobalVariable>::op_begin(this),
- InitVal != nullptr, Link, Name, AddressSpace),
+ : GlobalObject(Ty, Value::GlobalVariableVal, AllocMarker, Link, Name,
+ AddressSpace),
isConstantGlobal(constant),
isExternallyInitializedConstant(isExternallyInitialized) {
assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) &&
@@ -454,6 +453,8 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
assert(InitVal->getType() == Ty &&
"Initializer should be the same type as the GlobalVariable!");
Op<0>() = InitVal;
+ } else {
+ setGlobalVariableNumOperands(0);
}
}
@@ -540,7 +541,7 @@ void GlobalVariable::setCodeModel(CodeModel::Model CM) {
GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
const Twine &Name, Constant *Aliasee,
Module *ParentModule)
- : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name,
+ : GlobalValue(Ty, Value::GlobalAliasVal, AllocMarker, Link, Name,
AddressSpace) {
setAliasee(Aliasee);
if (ParentModule)
@@ -597,7 +598,7 @@ const GlobalObject *GlobalAlias::getAliaseeObject() const {
GlobalIFunc::GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
const Twine &Name, Constant *Resolver,
Module *ParentModule)
- : GlobalObject(Ty, Value::GlobalIFuncVal, &Op<0>(), 1, Link, Name,
+ : GlobalObject(Ty, Value::GlobalIFuncVal, AllocMarker, Link, Name,
AddressSpace) {
setResolver(Resolver);
if (ParentModule)
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 62d88ce21657b2..b1c2b0200c8269 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -32,9 +32,9 @@ InsertPosition::InsertPosition(Instruction *InsertBefore)
InsertPosition::InsertPosition(BasicBlock *InsertAtEnd)
: InsertAt(InsertAtEnd ? InsertAtEnd->end() : InstListType::iterator()) {}
-Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
+Instruction::Instruction(Type *ty, unsigned it, AllocInfo AllocInfo,
InsertPosition InsertBefore)
- : User(ty, Value::InstructionVal + it, Ops, NumOps) {
+ : User(ty, Value::InstructionVal + it, AllocInfo) {
// When called with an iterator, there must be a block to insert into.
if (InstListType::iterator InsertIt = InsertBefore; InsertIt.isValid()) {
BasicBlock *BB = InsertIt.getNodeParent();
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 19da1f60d424d2..e95b98a6404432 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -121,8 +121,9 @@ const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
//===----------------------------------------------------------------------===//
PHINode::PHINode(const PHINode &PN)
- : Instruction(PN.getType(), Instruction::PHI, nullptr, PN.getNumOperands()),
+ : Instruction(PN.getType(), Instruction::PHI, AllocMarker),
ReservedSpace(PN.getNumOperands()) {
+ NumUserOperands = PN.getNumOperands();
allocHungoffUses(PN.getNumOperands());
std::copy(PN.op_begin(), PN.op_end(), op_begin());
copyIncomingBlocks(make_range(PN.block_begin(), PN.block_end()));
@@ -243,14 +244,14 @@ bool PHINode::hasConstantOrUndefValue() const {
LandingPadInst::LandingPadInst(Type *RetTy, unsigned NumReservedValues,
const Twine &NameStr,
InsertPosition InsertBefore)
- : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertBefore) {
+ : Instruction(RetTy, Instruction::LandingPad, AllocMarker, InsertBefore) {
init(NumReservedValues, NameStr);
}
LandingPadInst::LandingPadInst(const LandingPadInst &LP)
- : Instruction(LP.getType(), Instruction::LandingPad, nullptr,
- LP.getNumOperands()),
+ : Instruction(LP.getType(), Instruction::LandingPad, AllocMarker),
ReservedSpace(LP.getNumOperands()) {
+ NumUserOperands = LP.getNumOperands();
allocHungoffUses(LP.getNumOperands());
Use *OL = getOperandList();
const Use *InOL = LP.getOperandList();
@@ -716,16 +717,16 @@ void CallInst::init(FunctionType *FTy, Value *Func, const Twine &NameStr) {
}
CallInst::CallInst(FunctionType *Ty, Value *Func, const Twine &Name,
- InsertPosition InsertBefore)
- : CallBase(Ty->getReturnType(), Instruction::Call,
- OperandTraits<CallBase>::op_end(this) - 1, 1, InsertBefore) {
+ AllocInfo AllocInfo, InsertPosition InsertBefore)
+ : CallBase(Ty->getReturnType(), Instruction::Call, AllocInfo,
+ InsertBefore) {
init(Ty, Func, Name);
}
-CallInst::CallInst(const CallInst &CI)
- : CallBase(CI.Attrs, CI.FTy, CI.getType(), Instruction::Call,
- OperandTraits<CallBase>::op_end(this) - CI.getNumOperands(),
- CI.getNumOperands()) {
+CallInst::CallInst(const CallInst &CI, AllocInfo AllocInfo)
+ : CallBase(CI.Attrs, CI.FTy, CI.getType(), Instruction::Call, AllocInfo) {
+ assert(getNumOperands() == CI.getNumOperands() &&
+ "Wrong number of operands allocated");
setTailCallKind(CI.getTailCallKind());
setCallingConv(CI.getCallingConv());
@@ -774,7 +775,7 @@ void InvokeInst::init(FunctionType *FTy, Value *Fn, BasicBlock *IfNormal,
const Twine &NameStr) {
this->FTy = FTy;
- assert((int)getNumOperands() ==
+ assert(getNumOperands() ==
ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)) &&
"NumOperands not set up?");
@@ -803,10 +804,10 @@ void InvokeInst::init(FunctionType *FTy, Value *Fn, BasicBlock *IfNormal,
setName(NameStr);
}
-InvokeInst::InvokeInst(const InvokeInst &II)
- : CallBase(II.Attrs, II.FTy, II.getType(), Instruction::Invoke,
- OperandTraits<CallBase>::op_end(this) - II.getNumOperands(),
- II.getNumOperands()) {
+InvokeInst::InvokeInst(const InvokeInst &II, AllocInfo AllocInfo)
+ : CallBase(II.Attrs, II.FTy, II.getType(), Instruction::Invoke, AllocInfo) {
+ assert(getNumOperands() == II.getNumOperands() &&
+ "Wrong number of operands allocated");
setCallingConv(II.getCallingConv());
std::copy(II.op_begin(), II.op_end(), op_begin());
std::copy(II.bundle_op_info_begin(), II.bundle_op_info_end(),
@@ -855,9 +856,9 @@ void CallBrInst::init(FunctionType *FTy, Value *Fn, BasicBlock *Fallthrough,
const Twine &NameStr) {
this->FTy = FTy;
- assert((int)getNumOperands() ==
- ComputeNumOperands(Args.size(), IndirectDests.size(),
- CountBundleInputs(Bundles)) &&
+ assert(getNumOperands() == ComputeNumOperands(Args.size(),
+ IndirectDests.size(),
+ CountBundleInputs(Bundles)) &&
"NumOperands not set up?");
#ifndef NDEBUG
@@ -887,10 +888,11 @@ void CallBrInst::init(FunctionType *FTy, Value *Fn, BasicBlock *Fallthrough,
setName(NameStr);
}
-CallBrInst::CallBrInst(const CallBrInst &CBI)
+CallBrInst::CallBrInst(const CallBrInst &CBI, AllocInfo AllocInfo)
: CallBase(CBI.Attrs, CBI.FTy, CBI.getType(), Instruction::CallBr,
- OperandTraits<CallBase>::op_end(this) - CBI.getNumOperands(),
- CBI.getNumOperands()) {
+ AllocInfo) {
+ assert(getNumOperands() == CBI.getNumOperands() &&
+ "Wrong number of operands allocated");
setCallingConv(CBI.getCallingConv());
std::copy(CBI.op_begin(), CBI.op_end(), op_begin());
std::copy(CBI.bundle_op_info_begin(), CBI.bundle_op_info_end(),
@@ -918,19 +920,19 @@ CallBrInst *CallBrInst::Create(CallBrInst *CBI, ArrayRef<OperandBundleDef> OpB,
// ReturnInst Implementation
//===----------------------------------------------------------------------===//
-ReturnInst::ReturnInst(const ReturnInst &RI)
+ReturnInst::ReturnInst(const ReturnInst &RI, AllocInfo AllocInfo)
: Instruction(Type::getVoidTy(RI.getContext()), Instruction::Ret,
- OperandTraits<ReturnInst>::op_end(this) - RI.getNumOperands(),
- RI.getNumOperands()) {
+ AllocInfo) {
+ assert(getNumOperands() == RI.getNumOperands() &&
+ "Wrong number of operands allocated");
if (RI.getNumOperands())
Op<0>() = RI.Op<0>();
SubclassOptionalData = RI.SubclassOptionalData;
}
-ReturnInst::ReturnInst(LLVMContext &C, Value *retVal,
+ReturnInst::ReturnInst(LLVMContext &C, Value *retVal, AllocInfo AllocInfo,
InsertPosition InsertBefore)
- : Instruction(Type::getVoidTy(C), Instruction::Ret,
- OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
+ : Instruction(Type::getVoidTy(C), Instruction::Ret, AllocInfo,
InsertBefore) {
if (retVal)
Op<0>() = retVal;
@@ -942,13 +944,13 @@ ReturnInst::ReturnInst(LLVMContext &C, Value *retVal,
ResumeInst::ResumeInst(const ResumeInst &RI)
: Instruction(Type::getVoidTy(RI.getContext()), Instruction::Resume,
- OperandTraits<ResumeInst>::op_begin(this), 1) {
+ AllocMarker) {
Op<0>() = RI.Op<0>();
}
ResumeInst::ResumeInst(Value *Exn, InsertPosition InsertBefore)
: Instruction(Type::getVoidTy(Exn->getContext()), Instruction::Resume,
- OperandTraits<ResumeInst>::op_begin(this), 1, InsertBefore) {
+ AllocMarker, InsertBefore) {
Op<0>() = Exn;
}
@@ -956,11 +958,11 @@ ResumeInst::ResumeInst(Value *Exn, InsertPosition InsertBefore)
// CleanupReturnInst Implementation
//===----------------------------------------------------------------------===//
-CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI)
- : Instruction(CRI.getType(), Instruction::CleanupRet,
- OperandTraits<CleanupReturnInst>::op_end(this) -
- CRI.getNumOperands(),
- CRI.getNumOperands()) {
+CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI,
+ AllocInfo AllocInfo)
+ : Instruction(CRI.getType(), Instruction::CleanupRet, AllocInfo) {
+ assert(getNumOperands() == CRI.getNumOperands() &&
+ "Wrong number of operands allocated");
setSubclassData<Instruction::OpaqueField>(
CRI.getSubclassData<Instruction::OpaqueField>());
Op<0>() = CRI.Op<0>();
@@ -978,12 +980,10 @@ void CleanupReturnInst::init(Value *CleanupPad, BasicBlock *UnwindBB) {
}
CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB,
- unsigned Values,
+ AllocInfo AllocInfo,
InsertPosition InsertBefore)
: Instruction(Type::getVoidTy(CleanupPad->getContext()),
- Instruction::CleanupRet,
- OperandTraits<CleanupReturnInst>::op_end(this) - Values,
- Values, InsertBefore) {
+ Instruction::CleanupRet, AllocInfo, InsertBefore) {
init(CleanupPad, UnwindBB);
}
@@ -997,7 +997,7 @@ void CatchReturnInst::init(Value *CatchPad, BasicBlock *BB) {
CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI)
: Instruction(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet,
- OperandTraits<CatchReturnInst>::op_begin(this), 2) {
+ AllocMarker) {
Op<0>() = CRI.Op<0>();
Op<1>() = CRI.Op<1>();
}
@@ -1005,8 +1005,7 @@ CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI)
CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB,
InsertPosition InsertBefore)
: Instruction(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
- OperandTraits<CatchReturnInst>::op_begin(this), 2,
- InsertBefore) {
+ AllocMarker, InsertBefore) {
init(CatchPad, BB);
}
@@ -1018,7 +1017,7 @@ CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest,
unsigned NumReservedValues,
const Twine &NameStr,
InsertPosition InsertBefore)
- : Instruction(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0,
+ : Instruction(ParentPad->getType(), Instruction::CatchSwitch, AllocMarker,
InsertBefore) {
if (UnwindDest)
++NumReservedValues;
@@ -1027,8 +1026,8 @@ CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest,
}
CatchSwitchInst::CatchSwitchInst(const CatchSwitchInst &CSI)
- : Instruction(CSI.getType(), Instruction::CatchSwitch, nullptr,
- CSI.getNumOperands()) {
+ : Instruction(CSI.getType(), Instruction::CatchSwitch, AllocMarker) {
+ NumUserOperands = CSI.NumUserOperands;
init(CSI.getParentPad(), CSI.getUnwindDest(), CSI.getNumOperands());
setNumHungOffUseOperands(ReservedSpace);
Use *OL = getOperandList();
@@ -1093,22 +1092,19 @@ void FuncletPadInst::init(Value *ParentPad, ArrayRef<Value *> Args,
setName(NameStr);
}
-FuncletPadInst::FuncletPadInst(const FuncletPadInst &FPI)
- : Instruction(FPI.getType(), FPI.getOpcode(),
- OperandTraits<FuncletPadInst>::op_end(this) -
- FPI.getNumOperands(),
- FPI.getNumOperands()) {
+FuncletPadInst::FuncletPadInst(const FuncletPadInst &FPI, AllocInfo AllocInfo)
+ : Instruction(FPI.getType(), FPI.getOpcode(), AllocInfo) {
+ assert(getNumOperands() == FPI.getNumOperands() &&
+ "Wrong number of operands allocated");
std::copy(FPI.op_begin(), FPI.op_end(), op_begin());
setParentPad(FPI.getParentPad());
}
FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
- ArrayRef<Value *> Args, unsigned Values,
+ ArrayRef<Value *> Args, AllocInfo AllocInfo,
const Twine &NameStr,
InsertPosition InsertBefore)
- : Instruction(ParentPad->getType(), Op,
- OperandTraits<FuncletPadInst>::op_end(this) - Values, Values,
- InsertBefore) {
+ : Instruction(ParentPad->getType(), Op, AllocInfo, InsertBefore) {
init(ParentPad, Args, NameStr);
}
@@ -1118,8 +1114,8 @@ FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
UnreachableInst::UnreachableInst(LLVMContext &Context,
InsertPosition InsertBefore)
- : Instruction(Type::getVoidTy(Context), Instruction::Unreachable, nullptr,
- 0, InsertBefore) {}
+ : Instruction(Type::getVoidTy(Context), Instruction::Unreachable,
+ AllocMarker, InsertBefore) {}
//===----------------------------------------------------------------------===//
// BranchInst Implementation
@@ -1131,19 +1127,18 @@ void BranchInst::AssertOK() {
"May only branch on boolean predicates!");
}
-BranchInst::BranchInst(BasicBlock *IfTrue, InsertPosition InsertBefore)
+BranchInst::BranchInst(BasicBlock *IfTrue, AllocInfo AllocInfo,
+ InsertPosition InsertBefore)
: Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br,
- OperandTraits<BranchInst>::op_end(this) - 1, 1,
- InsertBefore) {
+ AllocInfo, InsertBefore) {
assert(IfTrue && "Branch destination may not be null!");
Op<-1>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
- InsertPosition InsertBefore)
+ AllocInfo AllocInfo, InsertPosition InsertBefore)
: Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br,
- OperandTraits<BranchInst>::op_end(this) - 3, 3,
- InsertBefore) {
+ AllocInfo, InsertBefore) {
// Assign in order of operand index to make use-list order predictable.
Op<-3>() = Cond;
Op<-2>() = IfFalse;
@@ -1153,10 +1148,11 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
#endif
}
-BranchInst::BranchInst(const BranchInst &BI)
+BranchInst::BranchInst(const BranchInst &BI, AllocInfo AllocInfo)
: Instruction(Type::getVoidTy(BI.getContext()), Instruction::Br,
- OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(),
- BI.getNumOperands()) {
+ AllocInfo) {
+ assert(getNumOperands() == BI.getNumOperands() &&
+ "Wrong number of operands allocated");
// Assign in order of operand index to make use-list order predictable.
if (BI.getNumOperands() != 1) {
assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!");
@@ -1313,9 +1309,8 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Align Align,
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Align Align,
AtomicOrdering Order, SyncScope::ID SSID,
InsertPosition InsertBefore)
- : Instruction(Type::getVoidTy(val->getContext()), Store,
- OperandTraits<StoreInst>::op_begin(this),
- OperandTraits<StoreInst>::operands(this), InsertBefore) {
+ : Instruction(Type::getVoidTy(val->getContext()), Store, AllocMarker,
+ InsertBefore) {
Op<0>() = val;
Op<1>() = addr;
setVolatile(isVolatile);
@@ -1356,8 +1351,7 @@ AtomicCmpXchgInst::AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
InsertPosition InsertBefore)
: Instruction(
StructType::get(Cmp->getType(), Type::getInt1Ty(Cmp->getContext())),
- AtomicCmpXchg, OperandTraits<AtomicCmpXchgInst>::op_begin(this),
- OperandTraits<AtomicCmpXchgInst>::operands(this), InsertBefore) {
+ AtomicCmpXchg, AllocMarker, InsertBefore) {
Init(Ptr, Cmp, NewVal, Alignment, SuccessOrdering, FailureOrdering, SSID);
}
@@ -1389,9 +1383,7 @@ void AtomicRMWInst::Init(BinOp Operation, Value *Ptr, Value *Val,
AtomicRMWInst::AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
Align Alignment, AtomicOrdering Ordering,
SyncScope::ID SSID, InsertPosition InsertBefore)
- : Instruction(Val->getType(), AtomicRMW,
- OperandTraits<AtomicRMWInst>::op_begin(this),
- OperandTraits<AtomicRMWInst>::operands(this), InsertBefore) {
+ : Instruction(Val->getType(), AtomicRMW, AllocMarker, InsertBefore) {
Init(Operation, Ptr, Val, Alignment, Ordering, SSID);
}
@@ -1448,7 +1440,7 @@ StringRef AtomicRMWInst::getOperationName(BinOp Op) {
FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering,
SyncScope::ID SSID, InsertPosition InsertBefore)
- : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertBefore) {
+ : Instruction(Type::getVoidTy(C), Fence, AllocMarker, InsertBefore) {
setOrdering(Ordering);
setSyncScopeID(SSID);
}
@@ -1466,13 +1458,13 @@ void GetElementPtrInst::init(Value *Ptr, ArrayRef<Value *> IdxList,
setName(Name);
}
-GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI)
- : Instruction(GEPI.getType(), GetElementPtr,
- OperandTraits<GetElementPtrInst>::op_end(this) -
- GEPI.getNumOperands(),
- GEPI.getNumOperands()),
+GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI,
+ AllocInfo AllocInfo)
+ : Instruction(GEPI.getType(), GetElementPtr, AllocInfo),
SourceElementType(GEPI.SourceElementType),
ResultElementType(GEPI.ResultElementType) {
+ assert(getNumOperands() == GEPI.getNumOperands() &&
+ "Wrong number of operands allocated");
std::copy(GEPI.op_begin(), GEPI.op_end(), op_begin());
SubclassOptionalData = GEPI.SubclassOptionalData;
}
@@ -1606,9 +1598,8 @@ bool GetElementPtrInst::collectOffset(
ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
const Twine &Name,
InsertPosition InsertBef)
- : Instruction(
- cast<VectorType>(Val->getType())->getElementType(), ExtractElement,
- OperandTraits<ExtractElementInst>::op_begin(this), 2, InsertBef) {
+ : Instruction(cast<VectorType>(Val->getType())->getElementType(),
+ ExtractElement, AllocMarker, InsertBef) {
assert(isValidOperands(Val, Index) &&
"Invalid extractelement instruction operands!");
Op<0>() = Val;
@@ -1629,9 +1620,7 @@ bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) {
InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
const Twine &Name,
InsertPosition InsertBef)
- : Instruction(Vec->getType(), InsertElement,
- OperandTraits<InsertElementInst>::op_begin(this), 3,
- InsertBef) {
+ : Instruction(Vec->getType(), InsertElement, AllocMarker, InsertBef) {
assert(isValidOperands(Vec, Elt, Index) &&
"Invalid insertelement instruction operands!");
Op<0>() = Vec;
@@ -1679,8 +1668,7 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
: Instruction(
VectorType::get(cast<VectorType>(V1->getType())->getElementType(),
cast<VectorType>(Mask->getType())->getElementCount()),
- ShuffleVector, OperandTraits<ShuffleVectorInst>::op_begin(this),
- OperandTraits<ShuffleVectorInst>::operands(this), InsertBefore) {
+ ShuffleVector, AllocMarker, InsertBefore) {
assert(isValidOperands(V1, V2, Mask) &&
"Invalid shuffle vector instruction operands!");
@@ -1698,8 +1686,7 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, ArrayRef<int> Mask,
: Instruction(
VectorType::get(cast<VectorType>(V1->getType())->getElementType(),
Mask.size(), isa<ScalableVectorType>(V1->getType())),
- ShuffleVector, OperandTraits<ShuffleVectorInst>::op_begin(this),
- OperandTraits<ShuffleVectorInst>::operands(this), InsertBefore) {
+ ShuffleVector, AllocMarker, InsertBefore) {
assert(isValidOperands(V1, V2, Mask) &&
"Invalid shuffle vector instruction operands!");
Op<0>() = V1;
@@ -2464,9 +2451,8 @@ void InsertValueInst::init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
}
InsertValueInst::InsertValueInst(const InsertValueInst &IVI)
- : Instruction(IVI.getType(), InsertValue,
- OperandTraits<InsertValueInst>::op_begin(this), 2),
- Indices(IVI.Indices) {
+ : Instruction(IVI.getType(), InsertValue, AllocMarker),
+ Indices(IVI.Indices) {
Op<0>() = IVI.getOperand(0);
Op<1>() = IVI.getOperand(1);
SubclassOptionalData = IVI.SubclassOptionalData;
@@ -2565,8 +2551,7 @@ void UnaryOperator::AssertOK() {
BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
const Twine &Name, InsertPosition InsertBefore)
- : Instruction(Ty, iType, OperandTraits<BinaryOperator>::op_begin(this),
- OperandTraits<BinaryOperator>::operands(this), InsertBefore) {
+ : Instruction(Ty, iType, AllocMarker, InsertBefore) {
Op<0>() = S1;
Op<1>() = S2;
setName(Name);
@@ -3427,8 +3412,7 @@ AddrSpaceCastInst::AddrSpaceCastInst(Value *S, Type *Ty, const Twine &Name,
CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS,
Value *RHS, const Twine &Name, InsertPosition InsertBefore,
Instruction *FlagsSource)
- : Instruction(ty, op, OperandTraits<CmpInst>::op_begin(this),
- OperandTraits<CmpInst>::operands(this), InsertBefore) {
+ : Instruction(ty, op, AllocMarker, InsertBefore) {
Op<0>() = LHS;
Op<1>() = RHS;
setPredicate((Predicate)predicate);
@@ -3918,12 +3902,12 @@ void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumReserved) {
SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
InsertPosition InsertBefore)
: Instruction(Type::getVoidTy(Value->getContext()), Instruction::Switch,
- nullptr, 0, InsertBefore) {
+ AllocMarker, InsertBefore) {
init(Value, Default, 2+NumCases*2);
}
SwitchInst::SwitchInst(const SwitchInst &SI)
- : Instruction(SI.getType(), Instruction::Switch, nullptr, 0) {
+ : Instruction(SI.getType(), Instruction::Switch, AllocMarker) {
init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands());
setNumHungOffUseOperands(SI.getNumOperands());
Use *OL = getOperandList();
@@ -4125,13 +4109,14 @@ void IndirectBrInst::growOperands() {
IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases,
InsertPosition InsertBefore)
: Instruction(Type::getVoidTy(Address->getContext()),
- Instruction::IndirectBr, nullptr, 0, InsertBefore) {
+ Instruction::IndirectBr, AllocMarker, InsertBefore) {
init(Address, NumCases);
}
IndirectBrInst::IndirectBrInst(const IndirectBrInst &IBI)
: Instruction(Type::getVoidTy(IBI.getContext()), Instruction::IndirectBr,
- nullptr, IBI.getNumOperands()) {
+ AllocMarker) {
+ NumUserOperands = IBI.NumUserOperands;
allocHungoffUses(IBI.getNumOperands());
Use *OL = getOperandList();
const Use *InOL = IBI.getOperandList();
@@ -4185,7 +4170,8 @@ FreezeInst::FreezeInst(Value *S, const Twine &Name, InsertPosition InsertBefore)
// unit that uses these classes.
GetElementPtrInst *GetElementPtrInst::cloneImpl() const {
- return new (getNumOperands()) GetElementPtrInst(*this);
+ IntrusiveOperandsAllocMarker AllocMarker{getNumOperands()};
+ return new (AllocMarker) GetElementPtrInst(*this, AllocMarker);
}
UnaryOperator *UnaryOperator::cloneImpl() const {
@@ -4305,10 +4291,13 @@ AddrSpaceCastInst *AddrSpaceCastInst::cloneImpl() const {
CallInst *CallInst::cloneImpl() const {
if (hasOperandBundles()) {
- unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo);
- return new(getNumOperands(), DescriptorBytes) CallInst(*this);
+ IntrusiveOperandsAndDescriptorAllocMarker AllocMarker{
+ getNumOperands(),
+ getNumOperandBundles() * unsigned(sizeof(BundleOpInfo))};
+ return new (AllocMarker) CallInst(*this, AllocMarker);
}
- return new(getNumOperands()) CallInst(*this);
+ IntrusiveOperandsAllocMarker AllocMarker{getNumOperands()};
+ return new (AllocMarker) CallInst(*this, AllocMarker);
}
SelectInst *SelectInst::cloneImpl() const {
@@ -4331,18 +4320,20 @@ ShuffleVectorInst *ShuffleVectorInst::cloneImpl() const {
return new ShuffleVectorInst(getOperand(0), getOperand(1), getShuffleMask());
}
-PHINode *PHINode::cloneImpl() const { return new PHINode(*this); }
+PHINode *PHINode::cloneImpl() const { return new (AllocMarker) PHINode(*this); }
LandingPadInst *LandingPadInst::cloneImpl() const {
return new LandingPadInst(*this);
}
ReturnInst *ReturnInst::cloneImpl() const {
- return new(getNumOperands()) ReturnInst(*this);
+ IntrusiveOperandsAllocMarker AllocMarker{getNumOperands()};
+ return new (AllocMarker) ReturnInst(*this, AllocMarker);
}
BranchInst *BranchInst::cloneImpl() const {
- return new(getNumOperands()) BranchInst(*this);
+ IntrusiveOperandsAllocMarker AllocMarker{getNumOperands()};
+ return new (AllocMarker) BranchInst(*this, AllocMarker);
}
SwitchInst *SwitchInst::cloneImpl() const { return new SwitchInst(*this); }
@@ -4353,28 +4344,37 @@ IndirectBrInst *IndirectBrInst::cloneImpl() const {
InvokeInst *InvokeInst::cloneImpl() const {
if (hasOperandBundles()) {
- unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo);
- return new(getNumOperands(), DescriptorBytes) InvokeInst(*this);
+ IntrusiveOperandsAndDescriptorAllocMarker AllocMarker{
+ getNumOperands(),
+ getNumOperandBundles() * unsigned(sizeof(BundleOpInfo))};
+ return new (AllocMarker) InvokeInst(*this, AllocMarker);
}
- return new(getNumOperands()) InvokeInst(*this);
+ IntrusiveOperandsAllocMarker AllocMarker{getNumOperands()};
+ return new (AllocMarker) InvokeInst(*this, AllocMarker);
}
CallBrInst *CallBrInst::cloneImpl() const {
if (hasOperandBundles()) {
- unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo);
- return new (getNumOperands(), DescriptorBytes) CallBrInst(*this);
+ IntrusiveOperandsAndDescriptorAllocMarker AllocMarker{
+ getNumOperands(),
+ getNumOperandBundles() * unsigned(sizeof(BundleOpInfo))};
+ return new (AllocMarker) CallBrInst(*this, AllocMarker);
}
- return new (getNumOperands()) CallBrInst(*this);
+ IntrusiveOperandsAllocMarker AllocMarker{getNumOperands()};
+ return new (AllocMarker) CallBrInst(*this, AllocMarker);
}
-ResumeInst *ResumeInst::cloneImpl() const { return new (1) ResumeInst(*this); }
+ResumeInst *ResumeInst::cloneImpl() const {
+ return new (AllocMarker) ResumeInst(*this);
+}
CleanupReturnInst *CleanupReturnInst::cloneImpl() const {
- return new (getNumOperands()) CleanupReturnInst(*this);
+ IntrusiveOperandsAllocMarker AllocMarker{getNumOperands()};
+ return new (AllocMarker) CleanupReturnInst(*this, AllocMarker);
}
CatchReturnInst *CatchReturnInst::cloneImpl() const {
- return new (getNumOperands()) CatchReturnInst(*this);
+ return new (AllocMarker) CatchReturnInst(*this);
}
CatchSwitchInst *CatchSwitchInst::cloneImpl() const {
@@ -4382,7 +4382,8 @@ CatchSwitchInst *CatchSwitchInst::cloneImpl() const {
}
FuncletPadInst *FuncletPadInst::cloneImpl() const {
- return new (getNumOperands()) FuncletPadInst(*this);
+ IntrusiveOperandsAllocMarker AllocMarker{getNumOperands()};
+ return new (AllocMarker) FuncletPadInst(*this, AllocMarker);
}
UnreachableInst *UnreachableInst::cloneImpl() const {
diff --git a/llvm/lib/IR/User.cpp b/llvm/lib/IR/User.cpp
index 637af7aaa24530..d8034f922016f3 100644
--- a/llvm/lib/IR/User.cpp
+++ b/llvm/lib/IR/User.cpp
@@ -135,10 +135,7 @@ void *User::allocateFixedOperandUser(size_t Size, unsigned Us,
::operator new(Size + sizeof(Use) * Us + DescBytesToAllocate));
Use *Start = reinterpret_cast<Use *>(Storage + DescBytesToAllocate);
Use *End = Start + Us;
- User *Obj = reinterpret_cast<User*>(End);
- Obj->NumUserOperands = Us;
- Obj->HasHungOffUses = false;
- Obj->HasDescriptor = DescBytes != 0;
+ User *Obj = reinterpret_cast<User *>(End);
for (; Start != End; Start++)
new (Start) Use(Obj);
@@ -150,22 +147,21 @@ void *User::allocateFixedOperandUser(size_t Size, unsigned Us,
return Obj;
}
-void *User::operator new(size_t Size, unsigned Us) {
- return allocateFixedOperandUser(Size, Us, 0);
+void *User::operator new(size_t Size, IntrusiveOperandsAllocMarker allocTrait) {
+ return allocateFixedOperandUser(Size, allocTrait.NumOps, 0);
}
-void *User::operator new(size_t Size, unsigned Us, unsigned DescBytes) {
- return allocateFixedOperandUser(Size, Us, DescBytes);
+void *User::operator new(size_t Size,
+ IntrusiveOperandsAndDescriptorAllocMarker allocTrait) {
+ return allocateFixedOperandUser(Size, allocTrait.NumOps,
+ allocTrait.DescBytes);
}
-void *User::operator new(size_t Size) {
+void *User::operator new(size_t Size, HungOffOperandsAllocMarker) {
// Allocate space for a single Use*
void *Storage = ::operator new(Size + sizeof(Use *));
Use **HungOffOperandList = static_cast<Use **>(Storage);
User *Obj = reinterpret_cast<User *>(HungOffOperandList + 1);
- Obj->NumUserOperands = 0;
- Obj->HasHungOffUses = true;
- Obj->HasDescriptor = false;
*HungOffOperandList = nullptr;
return Obj;
}
More information about the llvm-commits
mailing list