From d1088df8f6ca5b9cf5307ec9410432a7121664d3 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Wed, 15 Oct 2014 20:39:05 +0000 Subject: [PATCH] IR: Move NumOperands from User to Value, NFC Store `User::NumOperands` (and `MDNode::NumOperands`) in `Value`. On 64-bit host architectures, this reduces `sizeof(User)` and all subclasses by 8, and has no effect on `sizeof(Value)` (or, incidentally, on `sizeof(MDNode)`). On 32-bit host architectures, this increases `sizeof(Value)` by 4. However, it has no effect on `sizeof(User)` and `sizeof(MDNode)`, so the only concrete subclasses of `Value` that actually see the increase are `BasicBlock`, `Argument`, `InlineAsm`, and `MDString`. Moreover, I'll be shocked and confused if this causes a tangible memory regression. This has no functionality change (other than memory footprint). llvm-svn: 219845 --- include/llvm/IR/Metadata.h | 3 --- include/llvm/IR/User.h | 7 +++---- include/llvm/IR/Value.h | 13 +++++++++++++ lib/IR/Value.cpp | 3 ++- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index 8b33d7022c7..be0f54974fd 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -126,9 +126,6 @@ class MDNode : public Value, public FoldingSetNode { /// \brief If the MDNode is uniqued cache the hash to speed up lookup. unsigned Hash; - /// \brief Number of co-allocated 'MDNodeOperand' items. - unsigned NumOperands; - /// \brief Subclass data enums. enum { /// FunctionLocalBit - This bit is set if this MDNode is function local. diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index fb5abe0c0e4..f578227d6ca 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -39,9 +39,6 @@ class User : public Value { friend struct HungoffOperandTraits; virtual void anchor(); protected: - /// \brief The number of values used by this User. - unsigned NumOperands; - /// \brief This is a pointer to the array of Uses for this User. /// /// For nodes of fixed arity (e.g. a binary operator) this array will live @@ -52,7 +49,9 @@ protected: void *operator new(size_t s, unsigned Us); User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps) - : Value(ty, vty), NumOperands(NumOps), OperandList(OpList) {} + : Value(ty, vty), OperandList(OpList) { + NumOperands = NumOps; + } Use *allocHungoffUses(unsigned) const; void dropHungoffUses() { Use::zap(OperandList, OperandList + NumOperands, true); diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 02630d8c666..efe0cca7bb4 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -92,6 +92,19 @@ private: /// field is initialized to zero by the ctor. unsigned short SubclassData; +protected: + /// \brief The number of operands in the subclass. + /// + /// This member is defined by this class, but not used for anything. + /// Subclasses can use it to store their number of operands, if they have + /// any. + /// + /// This is stored here to save space in User on 64-bit hosts. Since most + /// instances of Value have operands, 32-bit hosts aren't significantly + /// affected. + unsigned NumOperands; + +private: template // UseT == 'Use' or 'const Use' class use_iterator_impl : public std::iterator { diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp index b5af72b858e..862f08c8966 100644 --- a/lib/IR/Value.cpp +++ b/lib/IR/Value.cpp @@ -45,7 +45,8 @@ static inline Type *checkType(Type *Ty) { Value::Value(Type *ty, unsigned scid) : VTy(checkType(ty)), UseList(nullptr), Name(nullptr), SubclassID(scid), - HasValueHandle(0), SubclassOptionalData(0), SubclassData(0) { + HasValueHandle(0), SubclassOptionalData(0), SubclassData(0), + NumOperands(0) { // FIXME: Why isn't this in the subclass gunk?? // Note, we cannot call isa before the CallInst has been // constructed.