From 165240fe38b4199adab40e57b61e848cc169a83e Mon Sep 17 00:00:00 2001 From: Dawid Jurczak Date: Tue, 12 Jul 2022 15:00:27 +0200 Subject: [PATCH] [NFC] Fix compile time regression seen on some benchmarks after a630ea3003 commit The goal of this change is fixing most of compile time slowdown seen after a630ea3003 commit on lencod and sqlite3 benchmarks. There are 3 improvements included in this patch: 1. In getNumOperands when possible get value directly from SmallNumOps. 2. Inline getLargePtr by moving its definition to header. 3. In TBAAStructTypeNode::getField get all operands once instead taking operands in loop one after one. Differential Revision: https://reviews.llvm.org/D129468 --- llvm/include/llvm/IR/Metadata.h | 16 +++++++-- llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp | 34 +++++++++++--------- llvm/lib/IR/Metadata.cpp | 7 ---- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h index 293eba9e9f0a9..ec769ce95160f 100644 --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -999,7 +999,13 @@ class MDNode : public Metadata { 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() { @@ -1032,6 +1038,12 @@ class MDNode : public Metadata { return makeArrayRef(reinterpret_cast(this) - SmallSize, SmallNumOps); } + + unsigned getNumOperands() const { + if (!IsLarge) + return SmallNumOps; + return getLarge().size(); + } }; Header &getHeader() { return *(reinterpret_cast
(this) - 1); } @@ -1283,7 +1295,7 @@ class MDNode : public Metadata { } /// 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 index 9bcbe4a4cc1e8..560f46d39d0dc 100644 --- a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -303,24 +303,27 @@ class TBAAStructTypeNode { /// 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 @@ class TBAAStructTypeNode { 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 @@ class TBAAStructTypeNode { } // 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 index ae2401026ebf0..2a1a514922fdc 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -592,13 +592,6 @@ MDNode::Header::~Header() { (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");