From: Joseph Huber Date: Fri, 22 Jul 2022 00:45:32 +0000 (-0400) Subject: [Internalize] Support glob patterns for API lists X-Git-Tag: upstream/15.0.7~827 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3d0ab8638ba4c29563a6bcc2379abbdbce34fd47;p=platform%2Fupstream%2Fllvm.git [Internalize] Support glob patterns for API lists The internalize pass supports an option to provide a list of symbols that should not be internalized. THis is useful retaining certain defintions that should be kept alive. However, this interface is somewhat difficult to use as it requires knowing every single symbol's name and specifying it. Many APIs provide common prefixes for the symbols exported by the library, so it would make sense to be able to match these using a simple glob pattern. This patch changes the handling from a simple string comparison to a glob pattern match. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D130319 --- diff --git a/llvm/lib/Transforms/IPO/Internalize.cpp b/llvm/lib/Transforms/IPO/Internalize.cpp index 5aa5b90..85b1a83 100644 --- a/llvm/lib/Transforms/IPO/Internalize.cpp +++ b/llvm/lib/Transforms/IPO/Internalize.cpp @@ -28,6 +28,7 @@ #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/GlobPattern.h" #include "llvm/Support/LineIterator.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -40,13 +41,13 @@ STATISTIC(NumAliases, "Number of aliases internalized"); STATISTIC(NumFunctions, "Number of functions internalized"); STATISTIC(NumGlobals, "Number of global vars internalized"); -// APIFile - A file which contains a list of symbols that should not be marked -// external. +// APIFile - A file which contains a list of symbol glob patterns that should +// not be marked external. static cl::opt APIFile("internalize-public-api-file", cl::value_desc("filename"), cl::desc("A file containing list of symbol names to preserve")); -// APIList - A list of symbols that should not be marked internal. +// APIList - A list of symbol glob patterns that should not be marked internal. static cl::list APIList("internalize-public-api-list", cl::value_desc("list"), cl::desc("A list of symbol names to preserve"), cl::CommaSeparated); @@ -59,29 +60,44 @@ public: PreserveAPIList() { if (!APIFile.empty()) LoadFile(APIFile); - ExternalNames.insert(APIList.begin(), APIList.end()); + for (StringRef Pattern : APIList) + addGlob(Pattern); } bool operator()(const GlobalValue &GV) { - return ExternalNames.count(GV.getName()); + return llvm::any_of( + ExternalNames, [&](GlobPattern &GP) { return GP.match(GV.getName()); }); } private: // Contains the set of symbols loaded from file - StringSet<> ExternalNames; + SmallVector ExternalNames; + + void addGlob(StringRef Pattern) { + auto GlobOrErr = GlobPattern::create(Pattern); + if (!GlobOrErr) { + errs() << "WARNING: when loading pattern: '" + << toString(GlobOrErr.takeError()) << "' ignoring"; + return; + } + ExternalNames.emplace_back(std::move(*GlobOrErr)); + } void LoadFile(StringRef Filename) { // Load the APIFile... - ErrorOr> Buf = + ErrorOr> BufOrErr = MemoryBuffer::getFile(Filename); - if (!Buf) { + if (!BufOrErr) { errs() << "WARNING: Internalize couldn't load file '" << Filename << "'! Continuing as if it's empty.\n"; return; // Just continue as if the file were empty } - for (line_iterator I(*Buf->get(), true), E; I != E; ++I) - ExternalNames.insert(*I); + Buf = std::move(*BufOrErr); + for (line_iterator I(*Buf, true), E; I != E; ++I) + addGlob(*I); } + + std::shared_ptr Buf; }; } // end anonymous namespace diff --git a/llvm/test/Transforms/Internalize/globs.ll b/llvm/test/Transforms/Internalize/globs.ll new file mode 100644 index 0000000..d65c8391 --- /dev/null +++ b/llvm/test/Transforms/Internalize/globs.ll @@ -0,0 +1,22 @@ +; RUN: opt < %s -internalize -internalize-public-api-list 'bar?,_*,*_,[ab]' -S | FileCheck %s + +; CHECK: @foo = internal global +@foo = global i32 0 + +; CHECK: @bar_ = global +@bar_ = global i32 0 + +; CHECK: @_foo = global +@_foo = global i32 0 + +; CHECK: @foo_ = global +@foo_ = global i32 0 + +; CHECK: @a = global +@a = global i32 0 + +; CHECK: @b = global +@b = global i32 0 + +; CHECK: @c = internal global +@c = global i32 0