[llvm] [Object] Extract format-agnostic BBAddrMap decoder (PR #188435)
Haohai Wen via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 19:15:28 PDT 2026
================
@@ -0,0 +1,220 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements shared utilities for basic-block address maps.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/BBAddrMap.h"
+#include "llvm/Object/Error.h"
+
+using namespace llvm;
+using namespace object;
+
+namespace {
+
+// Helper to extract and decode the next ULEB128 value as unsigned int.
+// Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the unsigned
+// int limit.
+// Also returns zero if ULEBSizeErr is already in an error state.
+// ULEBSizeErr is an out variable if an error occurs.
+template <typename IntTy, std::enable_if_t<std::is_unsigned_v<IntTy>, int> = 0>
+static IntTy readULEB128As(DataExtractor &Data, DataExtractor::Cursor &Cur,
+ Error &ULEBSizeErr) {
+ // Bail out and do not extract data if ULEBSizeErr is already set.
+ if (ULEBSizeErr)
+ return 0;
+ uint64_t Offset = Cur.tell();
+ uint64_t Value = Data.getULEB128(Cur);
+ if (Value > std::numeric_limits<IntTy>::max()) {
+ ULEBSizeErr = createError("ULEB128 value at offset 0x" +
+ Twine::utohexstr(Offset) + " exceeds UINT" +
+ Twine(std::numeric_limits<IntTy>::digits) +
+ "_MAX (0x" + Twine::utohexstr(Value) + ")");
+ return 0;
+ }
+ return static_cast<IntTy>(Value);
+}
+} // end anonymous namespace
+
+Expected<std::vector<BBAddrMap>>
+llvm::object::decodeBBAddrMapPayload(AddressExtractor &Extractor,
+ std::vector<PGOAnalysisMap> *PGOAnalyses) {
+ DataExtractor &Data = Extractor.getDataExtractor();
+ std::vector<BBAddrMap> FunctionEntries;
+
+ DataExtractor::Cursor Cur(0);
+ Error ULEBSizeErr = Error::success();
+ Error MetadataDecodeErr = Error::success();
+
+ uint8_t Version = 0;
+ uint16_t Feature = 0;
+ BBAddrMap::Features FeatEnable{};
+ while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&
+ Cur.tell() < Data.getData().size()) {
+ Version = Data.getU8(Cur);
+ if (!Cur)
+ break;
+ if (Version < 2 || Version > 5)
+ return createError("unsupported BB address map version: " +
+ Twine(static_cast<int>(Version)));
+ Feature = Version < 5 ? Data.getU8(Cur) : Data.getU16(Cur);
+ if (!Cur)
+ break;
+ auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);
+ if (!FeatEnableOrErr)
+ return FeatEnableOrErr.takeError();
+ FeatEnable = *FeatEnableOrErr;
+ if (FeatEnable.CallsiteEndOffsets && Version < 3)
+ return createError("version should be >= 3 for BB address map when "
+ "callsite offsets feature is enabled: version = " +
+ Twine(static_cast<int>(Version)) +
+ " feature = " + Twine(static_cast<int>(Feature)));
+ if (FeatEnable.BBHash && Version < 4)
+ return createError("version should be >= 4 for BB address map when "
+ "basic block hash feature is enabled: version = " +
+ Twine(static_cast<int>(Version)) +
+ " feature = " + Twine(static_cast<int>(Feature)));
+ if (FeatEnable.PostLinkCfg && Version < 5)
+ return createError("version should be >= 5 for BB address map when "
+ "post link cfg feature is enabled: version = " +
+ Twine(static_cast<int>(Version)) +
+ " feature = " + Twine(static_cast<int>(Feature)));
+ uint32_t NumBlocksInBBRange = 0;
+ uint32_t NumBBRanges = 1;
+ uint64_t RangeBaseAddress = 0;
+ if (FeatEnable.MultiBBRange) {
+ NumBBRanges = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
+ if (!Cur || ULEBSizeErr)
+ break;
+ if (!NumBBRanges) {
+ std::string SecDesc = Extractor.getSectionDescription();
+ return createError("invalid zero number of BB ranges at offset " +
+ Twine::utohexstr(Cur.tell()) +
+ (SecDesc.empty() ? "" : " in " + SecDesc));
----------------
HaohaiWen wrote:
Done.
https://github.com/llvm/llvm-project/pull/188435
More information about the llvm-commits
mailing list