[PATCH] llvm-link: Add -override flag to prefer duplicate symbols from one module.
Luqman Aden
me+llvm at luqman.ca
Mon Apr 20 13:28:22 PDT 2015
>From df1b11c561dc826d8e4836b9e910ac75185bcf05 Mon Sep 17 00:00:00 2001
From: Luqman Aden <luqman at apple.com>
Date: Wed, 15 Apr 2015 12:22:32 -0700
Subject: [PATCH] llvm-link: Add -override flag to prefer one of a duplicate
symbol.
---
include/llvm/Linker/Linker.h | 4 +++-
lib/Linker/LinkModules.cpp | 20 +++++++++++++++----
test/tools/llvm-link/Inputs/foo.ll | 4 ++++
test/tools/llvm-link/hello.ll | 20 +++++++++++++++++++
test/tools/llvm-link/lit.local.cfg | 1 +
tools/llvm-link/llvm-link.cpp | 40
++++++++++++++++++++++++--------------
6 files changed, 69 insertions(+), 20 deletions(-)
create mode 100644 test/tools/llvm-link/Inputs/foo.ll
create mode 100644 test/tools/llvm-link/hello.ll
create mode 100644 test/tools/llvm-link/lit.local.cfg
diff --git a/include/llvm/Linker/Linker.h b/include/llvm/Linker/Linker.h
index 5ca815c..c43b90e 100644
--- a/include/llvm/Linker/Linker.h
+++ b/include/llvm/Linker/Linker.h
@@ -68,8 +68,10 @@ public:
void deleteModule();
/// \brief Link \p Src into the composite. The source is destroyed.
+ /// Passing OverrideSymbols as true will have symbols from Src
+ /// shadow those in the Dest.
/// Returns true on error.
- bool linkInModule(Module *Src);
+ bool linkInModule(Module *Src, bool OverrideSymbols = false);
/// \brief Set the composite to the passed-in module.
void setModule(Module *Dst);
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 21edc50..3a46a33 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -424,12 +424,17 @@ class ModuleLinker {
DiagnosticHandlerFunction DiagnosticHandler;
+ /// For symbol clashes, prefer those from Src.
+ bool OverrideFromSrc;
+
public:
ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module
*srcM,
- DiagnosticHandlerFunction DiagnosticHandler)
+ DiagnosticHandlerFunction DiagnosticHandler,
+ bool Override = false)
: DstM(dstM), SrcM(srcM), TypeMap(Set),
ValMaterializer(TypeMap, DstM, LazilyLinkGlobalValues),
- DiagnosticHandler(DiagnosticHandler) {}
+ DiagnosticHandler(DiagnosticHandler),
+ OverrideFromSrc(Override) {}
bool run();
@@ -725,6 +730,12 @@ bool ModuleLinker::getComdatResult(const Comdat *SrcC,
bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
const GlobalValue &Dest,
const GlobalValue &Src) {
+ // Should we unconditionally use the Src?
+ if (OverrideFromSrc) {
+ LinkFromSrc = true;
+ return false;
+ }
+
// We always have to add Src if it has appending linkage.
if (Src.hasAppendingLinkage()) {
LinkFromSrc = true;
@@ -794,6 +805,7 @@ bool ModuleLinker::shouldLinkFromSource(bool
&LinkFromSrc,
assert(!Dest.hasExternalWeakLinkage());
assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() &&
"Unexpected linkage type!");
+
return emitError("Linking globals named '" + Src.getName() +
"': symbol multiply defined!");
}
@@ -1742,9 +1754,9 @@ void Linker::deleteModule() {
Composite = nullptr;
}
-bool Linker::linkInModule(Module *Src) {
+bool Linker::linkInModule(Module *Src, bool OverrideSymbols) {
ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src,
- DiagnosticHandler);
+ DiagnosticHandler, OverrideSymbols);
bool RetCode = TheLinker.run();
Composite->dropTriviallyDeadConstantArrays();
return RetCode;
diff --git a/test/tools/llvm-link/Inputs/foo.ll
b/test/tools/llvm-link/Inputs/foo.ll
new file mode 100644
index 0000000..6e06fa5
--- /dev/null
+++ b/test/tools/llvm-link/Inputs/foo.ll
@@ -0,0 +1,4 @@
+define i32 @foo(i32 %i) {
+entry:
+ ret i32 4
+}
diff --git a/test/tools/llvm-link/hello.ll b/test/tools/llvm-link/hello.ll
new file mode 100644
index 0000000..c124864
--- /dev/null
+++ b/test/tools/llvm-link/hello.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as %s -o %t-hello.bc
+; RUN: llvm-as %p/Inputs/foo.ll -o %t-foo.bc
+; RUN: llvm-link %t-hello.bc -override %t-foo.bc -S | FileCheck %s
+
+
+; CHECK-LABEL: define i32 @foo
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i32 4
+define i32 @foo(i32 %i) {
+entry:
+ %add = add nsw i32 %i, %i
+ ret i32 %add
+}
+
+; Function Attrs: nounwind ssp uwtable
+define i32 @main(i32 %argc, i8** %argv) {
+entry:
+ %a = call i32 @foo(i32 2)
+ ret i32 %a
+}
diff --git a/test/tools/llvm-link/lit.local.cfg
b/test/tools/llvm-link/lit.local.cfg
new file mode 100644
index 0000000..c6106e4
--- /dev/null
+++ b/test/tools/llvm-link/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll']
diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp
index 6924aa5..54d49f5 100644
--- a/tools/llvm-link/llvm-link.cpp
+++ b/tools/llvm-link/llvm-link.cpp
@@ -38,6 +38,11 @@ static cl::list<std::string>
InputFilenames(cl::Positional, cl::OneOrMore,
cl::desc("<input bitcode files>"));
+static cl::list<std::string>
+OverridingInputs("override", cl::ZeroOrMore, cl::value_desc("filename"),
+ cl::desc("input bitcode file which can "
+ "override previously defined symbol"));
+
static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
cl::value_desc("filename"));
@@ -109,24 +114,29 @@ int main(int argc, char **argv) {
auto Composite = make_unique<Module>("llvm-link", Context);
Linker L(Composite.get(), diagnosticHandler);
- for (unsigned i = 0; i < InputFilenames.size(); ++i) {
- std::unique_ptr<Module> M = loadFile(argv[0], InputFilenames[i],
Context);
- if (!M.get()) {
- errs() << argv[0] << ": error loading file '" <<InputFilenames[i]<<
"'\n";
- return 1;
- }
+ auto linkFiles = [&](const cl::list<std::string>& Files, bool Override) {
+ for (auto File : Files) {
+ std::unique_ptr<Module> M = loadFile(argv[0], File, Context);
+ if (!M.get()) {
+ errs() << argv[0] << ": error loading file '" << File << "'\n";
+ exit(1);
+ }
- if (verifyModule(*M, &errs())) {
- errs() << argv[0] << ": " << InputFilenames[i]
- << ": error: input module is broken!\n";
- return 1;
- }
+ if (verifyModule(*M, &errs())) {
+ errs() << argv[0] << ": " << File
+ << ": error: input module is broken!\n";
+ exit(1);
+ }
- if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n";
+ if (Verbose) errs() << "Linking in '" << File << "'\n";
- if (L.linkInModule(M.get()))
- return 1;
- }
+ if (L.linkInModule(M.get(), Override))
+ exit(1);
+ }
+ };
+
+ linkFiles(InputFilenames, false);
+ linkFiles(OverridingInputs, true);
if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;
--
2.3.0 (Apple Git-54)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150420/9b1a7ed9/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-llvm-link-Add-override-flag-to-prefer-one-of-a-dupli.patch
Type: application/octet-stream
Size: 6926 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150420/9b1a7ed9/attachment.obj>
More information about the llvm-commits
mailing list