[llvm] [MC][AsmParser]: Cache files loaded by .incbin across repeated directives (PR #194254)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 27 13:07:49 PDT 2026


https://github.com/SergeantCooper updated https://github.com/llvm/llvm-project/pull/194254

>From 0715a44155467a34c1b7343c6067d8b6a0654d0e Mon Sep 17 00:00:00 2001
From: Ujjawal Kumar <ujjawalkumarchouhan7895 at gmail.com>
Date: Sun, 26 Apr 2026 22:24:49 +0530
Subject: [PATCH] AsmParser.cpp: Cache files loaded by .incbin across repeated
 directives

Each .incbin directive previously called SourceMgr::AddIncludeFile, which
unconditionally reads a fresh copy of the referenced file into a new
MemoryBuffer and retains it in the SourceMgr's buffer list for the
lifetime of the parser. As a result, N .incbin directives that name the
same file consume memory equal to N*filesize even though the bytes are never
modified between loads.

Cache the file buffers based on their names.

Measured on a stress test of 1000 .incbin directives against a 1 MB blob:

                  Max RSS
    Before       ~1.04 GB
    After        ~13.8 MB
---
 llvm/lib/MC/MCParser/AsmParser.cpp | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 4e95bf47bb7ee..10b9e57dc82ad 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -166,6 +166,9 @@ class AsmParser : public MCAsmParser {
 
   SmallSet<StringRef, 2> LTODiscardSymbols;
 
+  /// Cache IncbinFiles by file names
+  StringMap<unsigned> IncbinFileCache;
+
   /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
   unsigned AssemblerDialect = ~0U;
 
@@ -860,14 +863,22 @@ bool AsmParser::processIncbinFile(const std::string &Filename, int64_t Skip,
   if (SymbolScanningMode)
     return false;
 
-  std::string IncludedFile;
-  unsigned NewBuf =
-      SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
-  if (!NewBuf)
+  unsigned BufferIdx = 0;
+  auto It = IncbinFileCache.find(Filename);
+  if (It == IncbinFileCache.end()) {
+    std::string IncludedFile;
+    BufferIdx = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
+    if (!BufferIdx)
+      return true;
+    IncbinFileCache.try_emplace(Filename, BufferIdx);
+  } else
+    BufferIdx = It->second;
+
+  if (!BufferIdx)
     return true;
 
-  // Pick up the bytes from the file and emit them.
-  StringRef Bytes = SrcMgr.getMemoryBuffer(NewBuf)->getBuffer();
+  // Pick up the bytes from the file(cached) and emit them.
+  StringRef Bytes = SrcMgr.getMemoryBuffer(BufferIdx)->getBuffer();
   Bytes = Bytes.drop_front(Skip);
   if (Count) {
     int64_t Res;



More information about the llvm-commits mailing list