forked from OSchip/llvm-project
[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
This commit is contained in:
parent
e82e07d74a
commit
3d0ab8638b
|
@ -28,6 +28,7 @@
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/GlobPattern.h"
|
||||||
#include "llvm/Support/LineIterator.h"
|
#include "llvm/Support/LineIterator.h"
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
@ -40,13 +41,13 @@ STATISTIC(NumAliases, "Number of aliases internalized");
|
||||||
STATISTIC(NumFunctions, "Number of functions internalized");
|
STATISTIC(NumFunctions, "Number of functions internalized");
|
||||||
STATISTIC(NumGlobals, "Number of global vars internalized");
|
STATISTIC(NumGlobals, "Number of global vars internalized");
|
||||||
|
|
||||||
// APIFile - A file which contains a list of symbols that should not be marked
|
// APIFile - A file which contains a list of symbol glob patterns that should
|
||||||
// external.
|
// not be marked external.
|
||||||
static cl::opt<std::string>
|
static cl::opt<std::string>
|
||||||
APIFile("internalize-public-api-file", cl::value_desc("filename"),
|
APIFile("internalize-public-api-file", cl::value_desc("filename"),
|
||||||
cl::desc("A file containing list of symbol names to preserve"));
|
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<std::string>
|
static cl::list<std::string>
|
||||||
APIList("internalize-public-api-list", cl::value_desc("list"),
|
APIList("internalize-public-api-list", cl::value_desc("list"),
|
||||||
cl::desc("A list of symbol names to preserve"), cl::CommaSeparated);
|
cl::desc("A list of symbol names to preserve"), cl::CommaSeparated);
|
||||||
|
@ -59,29 +60,44 @@ public:
|
||||||
PreserveAPIList() {
|
PreserveAPIList() {
|
||||||
if (!APIFile.empty())
|
if (!APIFile.empty())
|
||||||
LoadFile(APIFile);
|
LoadFile(APIFile);
|
||||||
ExternalNames.insert(APIList.begin(), APIList.end());
|
for (StringRef Pattern : APIList)
|
||||||
|
addGlob(Pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const GlobalValue &GV) {
|
bool operator()(const GlobalValue &GV) {
|
||||||
return ExternalNames.count(GV.getName());
|
return llvm::any_of(
|
||||||
|
ExternalNames, [&](GlobPattern &GP) { return GP.match(GV.getName()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Contains the set of symbols loaded from file
|
// Contains the set of symbols loaded from file
|
||||||
StringSet<> ExternalNames;
|
SmallVector<GlobPattern> 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) {
|
void LoadFile(StringRef Filename) {
|
||||||
// Load the APIFile...
|
// Load the APIFile...
|
||||||
ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
|
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
|
||||||
MemoryBuffer::getFile(Filename);
|
MemoryBuffer::getFile(Filename);
|
||||||
if (!Buf) {
|
if (!BufOrErr) {
|
||||||
errs() << "WARNING: Internalize couldn't load file '" << Filename
|
errs() << "WARNING: Internalize couldn't load file '" << Filename
|
||||||
<< "'! Continuing as if it's empty.\n";
|
<< "'! Continuing as if it's empty.\n";
|
||||||
return; // Just continue as if the file were empty
|
return; // Just continue as if the file were empty
|
||||||
}
|
}
|
||||||
for (line_iterator I(*Buf->get(), true), E; I != E; ++I)
|
Buf = std::move(*BufOrErr);
|
||||||
ExternalNames.insert(*I);
|
for (line_iterator I(*Buf, true), E; I != E; ++I)
|
||||||
|
addGlob(*I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MemoryBuffer> Buf;
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue