From 4ac6a9321a3eda64e6c0b88851ce2cd5dde44c7e Mon Sep 17 00:00:00 2001 From: Rahul Joshi Date: Fri, 8 Aug 2025 07:49:29 -0700 Subject: [PATCH] [NFCI[TableGen] Minor improvements to `Intrinsic::getAttributes` --- .../utils/TableGen/Basic/IntrinsicEmitter.cpp | 108 +++++++++--------- 1 file changed, 51 insertions(+), 57 deletions(-) diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp index 293e64e97cc33..04707084a4166 100644 --- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp +++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp @@ -455,15 +455,9 @@ struct FnAttributeComparator { struct AttributeComparator { bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const { - // Order all intrinsics with no functiona attributes before all intrinsics - // with function attributes. - bool HasFnAttrLHS = hasFnAttributes(*L); - bool HasFnAttrRHS = hasFnAttributes(*R); - - // Order by argument attributes if function `hasFnAttributes` is equal. - // This is reliable because each side is already sorted internally. - return std::tie(HasFnAttrLHS, L->ArgumentAttributes) < - std::tie(HasFnAttrRHS, R->ArgumentAttributes); + // This comparator is used to unique just the argument attributes of an + // intrinsic without considering any function attributes. + return L->ArgumentAttributes < R->ArgumentAttributes; } }; } // End anonymous namespace @@ -659,7 +653,7 @@ static constexpr uint16_t IntrinsicsToAttributesMap[] = {)"; // // getIntrinsicArgAttributeSet(C, ArgAttrID, FT->getContainedType(ArgNo)); // - // Create a table that records, for each argument attributes, the set of + // Create a table that records, for each argument attributes, the list of // pairs that are needed to construct its argument // attributes. These tables for all intrinsics will be concatenated into one // large table and then for each intrinsic, we remember the Staring index and @@ -667,79 +661,77 @@ static constexpr uint16_t IntrinsicsToAttributesMap[] = {)"; // non-empty attributes), so that we can build the attribute list for an // intrinsic without using a switch-case. - // Find the max number of attributes to create the local array and create - // a concatenated list of pairs. - struct ArgNoAttrIDPair { - uint16_t ArgNo, ArgAttrID; - ArgNoAttrIDPair(uint16_t ArgNo, uint16_t ArgAttrID) - : ArgNo(ArgNo), ArgAttrID(ArgAttrID) {} - }; + using ArgNoAttrIDPair = std::pair; - // For each unique ID in UniqAttributes, reacord the starting index in the - // flattened ArgNoAttrIDPair table, and the number of non-empty arg - // attributes. - struct ArgAttributesInfo { - uint16_t StartIndex; - uint16_t NumAttrs; - ArgAttributesInfo(uint16_t StartIndex, uint16_t NumAttrs) - : StartIndex(StartIndex), NumAttrs(NumAttrs) {} - }; - SmallVector ArgAttrIdTable; - SmallVector ArgAttributesInfoTable(UniqAttributes.size(), - {0, 0}); + // Emit the table of concatenated using SequenceToOffsetTable + // so that entries can be reused if possible. Individual sequences in this + // table do not have any terminator. + using ArgAttrIDSubTable = SmallVector; + SequenceToOffsetTable ArgAttrIdSequenceTable(std::nullopt); + SmallVector ArgAttrIdSubTables( + UniqAttributes.size()); // Indexed by UniqueID. + // Find the max number of attributes to create the local array. unsigned MaxNumAttrs = 0; for (const auto [IntPtr, UniqueID] : UniqAttributes) { const CodeGenIntrinsic &Int = *IntPtr; - unsigned NumAttrs = 0; - unsigned StartIndex = ArgAttrIdTable.size(); + ArgAttrIDSubTable SubTable; for (const auto &[ArgNo, Attrs] : enumerate(Int.ArgumentAttributes)) { if (Attrs.empty()) continue; uint16_t ArgAttrID = UniqArgAttributes.find(Attrs)->second; - ArgAttrIdTable.emplace_back((uint16_t)ArgNo, ArgAttrID); - ++NumAttrs; + SubTable.emplace_back((uint16_t)ArgNo, ArgAttrID); } - - // Record the start index and size of the list for this unique ID. - if (NumAttrs) - ArgAttributesInfoTable[UniqueID] = - ArgAttributesInfo(StartIndex, NumAttrs); - - NumAttrs += hasFnAttributes(Int); + ArgAttrIdSubTables[UniqueID] = SubTable; + if (!SubTable.empty()) + ArgAttrIdSequenceTable.add(SubTable); + unsigned NumAttrs = SubTable.size() + hasFnAttributes(Int); MaxNumAttrs = std::max(MaxNumAttrs, NumAttrs); } - if (ArgAttrIdTable.size() >= std::numeric_limits::max()) + ArgAttrIdSequenceTable.layout(); + + if (ArgAttrIdSequenceTable.size() >= std::numeric_limits::max()) PrintFatalError("Size of ArgAttrIdTable exceeds supported limit"); - // Emit the 2 tables (flattened ArgNo, ArgAttrID) and ArgAttrIdTableIndex - OS << R"( -namespace { -struct ArgNoAttrIDPair { + // Emit the 2 tables (flattened ArgNo, ArgAttrID) and ArgAttributesInfoTable. + OS << formatv(R"( +namespace {{ +struct ArgNoAttrIDPair {{ uint16_t ArgNo, ArgAttrID; }; } // namespace -static constexpr ArgNoAttrIDPair ArgAttrIdTable[] = { -)"; - for (const auto &[ArgNo, ArgAttrID] : ArgAttrIdTable) - OS << formatv(" {{{}, {}},\n", ArgNo, ArgAttrID); - OS << R"(}; // ArgAttrIdTable +// Number of entries: {} +static constexpr ArgNoAttrIDPair ArgAttrIdTable[] = {{ +)", + ArgAttrIdSequenceTable.size()); -namespace { -struct ArgAttributesInfo { + ArgAttrIdSequenceTable.emit(OS, [](raw_ostream &OS, ArgNoAttrIDPair Elem) { + OS << formatv("{{{}, {}}", Elem.first, Elem.second); + }); + + OS << formatv(R"(}; // ArgAttrIdTable + +namespace {{ +struct ArgAttributesInfo {{ uint16_t StartIndex; uint16_t NumAttrs; }; } // namespace - -static constexpr ArgAttributesInfo ArgAttributesInfoTable[] = { -)"; - for (const auto &[StartIndex, NumAttrs] : ArgAttributesInfoTable) + +// Number of entries: {} +static constexpr ArgAttributesInfo ArgAttributesInfoTable[] = {{ +)", + ArgAttrIdSubTables.size()); + + for (const auto &SubTable : ArgAttrIdSubTables) { + unsigned NumAttrs = SubTable.size(); + unsigned StartIndex = NumAttrs ? ArgAttrIdSequenceTable.get(SubTable) : 0; OS << formatv(" {{{}, {}},\n", StartIndex, NumAttrs); + } OS << "}; // ArgAttributesInfoTable\n"; // Now emit the Intrinsic::getAttributes function. This will first map @@ -756,7 +748,9 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id, uint16_t PackedID = IntrinsicsToAttributesMap[id - 1]; uint8_t FnAttrID = PackedID >> 8; uint8_t ArgAttrID = PackedID & 0xFF; - std::pair AS[{}]; + using PairTy = std::pair; + alignas(PairTy) char ASStorage[sizeof(PairTy) * {}]; + PairTy *AS = reinterpret_cast(ASStorage); // Construct an ArrayRef for easier range checking. ArrayRef ArgAttributesInfoTableAR(ArgAttributesInfoTable);