[llvm] [BitcodeReader] Lazily read and cache target triple (NFC) (PR #208175)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 13 07:00:22 PDT 2026


https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/208175

>From 2914fe136e4ba3073c5a6a86dda8dd6e43ca5d1a Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Wed, 8 Jul 2026 10:15:49 +0200
Subject: [PATCH 1/3] [BitcodeReader] Lazily read and cache target triple (NFC)

Lazily read and cache the target triple from the stream, currently
meant to be used only for upgrading AArch64 memory effects from old
bitcode.

Co-authored-by: Caroline Concatto <caroline.concatto at arm.com>
---
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 49 ++++++++++++-----------
 1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 264f68ccaf450..e022938595a33 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -581,7 +581,7 @@ class BitcodeConstant final : public Value,
 class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
   LLVMContext &Context;
   Module *TheModule = nullptr;
-  Triple BitcodeTargetTriple;
+  std::optional<Triple> TargetTriple;
   // Next offset to start scanning for lazy parsing of function bodies.
   uint64_t NextUnreadBit = 0;
   // Last function offset found in the VST.
@@ -705,8 +705,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
 
 public:
   BitcodeReader(BitstreamCursor Stream, StringRef Strtab,
-                StringRef ProducerIdentification, LLVMContext &Context,
-                Triple BitcodeTargetTriple);
+                StringRef ProducerIdentification, LLVMContext &Context);
 
   Error materializeForwardReferencedFunctions();
 
@@ -890,6 +889,20 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
     return readConstantRange(Record, OpNum, BitWidth);
   }
 
+  /// Cache target triple for for upgrading AArch64 memory effects.
+  const Triple &getTargetTriple() {
+    if (!TargetTriple) {
+      BitstreamCursor TripleStream(Stream.getBitcodeBytes());
+      if (Expected<std::string> TripleStr = readTriple(TripleStream))
+        TargetTriple.emplace(*TripleStr);
+      else {
+        consumeError(TripleStr.takeError());
+        TargetTriple.emplace();
+      }
+    }
+    return *TargetTriple;
+  }
+
   /// Upgrades old-style typeless byval/sret/inalloca attributes by adding the
   /// corresponding argument's pointee type. Also upgrades intrinsics that now
   /// require an elementtype attribute.
@@ -1064,9 +1077,8 @@ std::error_code llvm::errorToErrorCodeAndEmitErrors(LLVMContext &Ctx,
 
 BitcodeReader::BitcodeReader(BitstreamCursor Stream, StringRef Strtab,
                              StringRef ProducerIdentification,
-                             LLVMContext &Context, Triple TTriple)
+                             LLVMContext &Context)
     : BitcodeReaderBase(std::move(Stream), Strtab), Context(Context),
-      BitcodeTargetTriple(TTriple),
       ValueList(this->Stream.SizeInBytes(),
                 [this](unsigned ValID, BasicBlock *InsertBB) {
                   return materializeValue(ValID, InsertBB);
@@ -2473,9 +2485,9 @@ Error BitcodeReader::parseAttributeGroupBlock() {
                         MemoryEffects::argMemOnly(ArgMem) |
                         MemoryEffects::errnoMemOnly(OtherMem) |
                         MemoryEffects::otherMemOnly(OtherMem);
-              // Old versions dont have target memory location.
-              // It was represented as Inaccessible memory for AArch64.
-              if (BitcodeTargetTriple.isAArch64())
+              // Old bitcode encoded AArch64 state as inaccessible memory.
+              // Upgrade those effects to target-specific memory locations.
+              if (getTargetTriple().isAArch64())
                 ME = ME.getWithModRef(IRMemLocation::TargetMem0,
                                       InaccessibleMem) |
                      ME.getWithModRef(IRMemLocation::TargetMem1,
@@ -2486,9 +2498,9 @@ Error BitcodeReader::parseAttributeGroupBlock() {
               // on newer versions.
               auto ME = MemoryEffects::createFromIntValue(
                   EncodedME & 0x00FFFFFFFFFFFFFFULL);
-              // Only from Version=2 onwards target memory location exist.
-              // It was represented as Inaccessible memory for AArch64.
-              if (Version == 1 && BitcodeTargetTriple.isAArch64())
+              // Upgrade to target-specific memory locations introduced in
+              // version 2.
+              if (Version == 1 && getTargetTriple().isAArch64())
                 ME = ME.getWithModRef(
                          IRMemLocation::TargetMem0,
                          ME.getModRef(IRMemLocation::InaccessibleMem)) |
@@ -4912,7 +4924,8 @@ Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata,
   MDCallbacks.MDType = Callbacks.MDType;
   MDLoader = MetadataLoader(Stream, *M, ValueList, IsImporting, MDCallbacks);
   SkipDebugIntrinsicUpgrade = Callbacks.SkipDebugIntrinsicUpgrade;
-  return parseModule(0, ShouldLazyLoadMetadata, Callbacks);
+  Error Err = parseModule(0, ShouldLazyLoadMetadata, Callbacks);
+  return Err;
 }
 
 Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {
@@ -8736,20 +8749,10 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll,
       return std::move(E);
   }
 
-  // Cache target triple early for target-memory attribute upgrading.
-  // Suppress target parser diagnostics during this early parse,
-  // because attribute parsing runs before target parsing.
-  Triple BitcodeTargetTriple;
-  BitstreamCursor TripleStream(Buffer);
-  if (Expected<std::string> TripleStr = readTriple(TripleStream))
-    BitcodeTargetTriple = Triple(*TripleStr);
-  else
-    consumeError(TripleStr.takeError());
-
   if (Error JumpFailed = Stream.JumpToBit(ModuleBit))
     return std::move(JumpFailed);
   auto *R = new BitcodeReader(std::move(Stream), Strtab, ProducerIdentification,
-                              Context, BitcodeTargetTriple);
+                              Context);
 
   std::unique_ptr<Module> M =
       std::make_unique<Module>(ModuleIdentifier, Context);

>From 2a3c03d24f51922f1c6e46140a4bbaa509bf7a5c Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Wed, 8 Jul 2026 11:23:20 +0200
Subject: [PATCH 2/3] !fixup stray

---
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index e022938595a33..aa90ebac6ddc1 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -4924,8 +4924,7 @@ Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata,
   MDCallbacks.MDType = Callbacks.MDType;
   MDLoader = MetadataLoader(Stream, *M, ValueList, IsImporting, MDCallbacks);
   SkipDebugIntrinsicUpgrade = Callbacks.SkipDebugIntrinsicUpgrade;
-  Error Err = parseModule(0, ShouldLazyLoadMetadata, Callbacks);
-  return Err;
+  return parseModule(0, ShouldLazyLoadMetadata, Callbacks);
 }
 
 Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {

>From 59c569f6d220e9d9c3fe0a4606bab38b734d289a Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Mon, 13 Jul 2026 15:59:46 +0200
Subject: [PATCH 3/3] !fixup avoid copy

---
 llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index aa90ebac6ddc1..0faa23f07f5e5 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -894,7 +894,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
     if (!TargetTriple) {
       BitstreamCursor TripleStream(Stream.getBitcodeBytes());
       if (Expected<std::string> TripleStr = readTriple(TripleStream))
-        TargetTriple.emplace(*TripleStr);
+        TargetTriple.emplace(std::move(*TripleStr));
       else {
         consumeError(TripleStr.takeError());
         TargetTriple.emplace();



More information about the llvm-commits mailing list