diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -997,7 +997,13 @@ alignTo(getAllocSize(), alignof(uint64_t)); } - void *getLargePtr() const; + void *getLargePtr() const { + static_assert(alignof(LargeStorageVector) <= alignof(Header), + "LargeStorageVector too strongly aligned"); + return reinterpret_cast(const_cast
(this)) - + sizeof(LargeStorageVector); + } + void *getSmallPtr(); LargeStorageVector &getLarge() { @@ -1030,6 +1036,12 @@ return makeArrayRef(reinterpret_cast(this) - SmallSize, SmallNumOps); } + + unsigned getNumOperands() const { + if (!IsLarge) + return SmallNumOps; + return getLarge().size(); + } }; Header &getHeader() { return *(reinterpret_cast
(this) - 1); } @@ -1281,7 +1293,7 @@ } /// Return number of MDNode operands. - unsigned getNumOperands() const { return getHeader().operands().size(); } + unsigned getNumOperands() const { return getHeader().getNumOperands(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Metadata *MD) { diff --git a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp --- a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -303,24 +303,27 @@ /// given offset. Update the offset to be relative to the field type. TBAAStructTypeNode getField(uint64_t &Offset) const { bool NewFormat = isNewFormat(); + const ArrayRef Operands(Node->op_begin(), Node->op_end()); + const unsigned NumOperands = Operands.size(); + if (NewFormat) { // New-format root and scalar type nodes have no fields. - if (Node->getNumOperands() < 6) + if (NumOperands < 6) return TBAAStructTypeNode(); } else { // Parent can be omitted for the root node. - if (Node->getNumOperands() < 2) + if (NumOperands < 2) return TBAAStructTypeNode(); // Fast path for a scalar type node and a struct type node with a single // field. - if (Node->getNumOperands() <= 3) { - uint64_t Cur = Node->getNumOperands() == 2 - ? 0 - : mdconst::extract(Node->getOperand(2)) - ->getZExtValue(); + if (NumOperands <= 3) { + uint64_t Cur = + NumOperands == 2 + ? 0 + : mdconst::extract(Operands[2])->getZExtValue(); Offset -= Cur; - MDNode *P = dyn_cast_or_null(Node->getOperand(1)); + MDNode *P = dyn_cast_or_null(Operands[1]); if (!P) return TBAAStructTypeNode(); return TBAAStructTypeNode(P); @@ -332,10 +335,11 @@ unsigned FirstFieldOpNo = NewFormat ? 3 : 1; unsigned NumOpsPerField = NewFormat ? 3 : 2; unsigned TheIdx = 0; - for (unsigned Idx = FirstFieldOpNo; Idx < Node->getNumOperands(); + + for (unsigned Idx = FirstFieldOpNo; Idx < NumOperands; Idx += NumOpsPerField) { - uint64_t Cur = mdconst::extract(Node->getOperand(Idx + 1)) - ->getZExtValue(); + uint64_t Cur = + mdconst::extract(Operands[Idx + 1])->getZExtValue(); if (Cur > Offset) { assert(Idx >= FirstFieldOpNo + NumOpsPerField && "TBAAStructTypeNode::getField should have an offset match!"); @@ -345,11 +349,11 @@ } // Move along the last field. if (TheIdx == 0) - TheIdx = Node->getNumOperands() - NumOpsPerField; - uint64_t Cur = mdconst::extract(Node->getOperand(TheIdx + 1)) - ->getZExtValue(); + TheIdx = NumOperands - NumOpsPerField; + uint64_t Cur = + mdconst::extract(Operands[TheIdx + 1])->getZExtValue(); Offset -= Cur; - MDNode *P = dyn_cast_or_null(Node->getOperand(TheIdx)); + MDNode *P = dyn_cast_or_null(Operands[TheIdx]); if (!P) return TBAAStructTypeNode(); return TBAAStructTypeNode(P); diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -592,13 +592,6 @@ (void)(O - 1)->~MDOperand(); } -void *MDNode::Header::getLargePtr() const { - static_assert(alignof(LargeStorageVector) <= alignof(Header), - "LargeStorageVector too strongly aligned"); - return reinterpret_cast(const_cast
(this)) - - sizeof(LargeStorageVector); -} - void *MDNode::Header::getSmallPtr() { static_assert(alignof(MDOperand) <= alignof(Header), "MDOperand too strongly aligned");