llvm.org GIT mirror llvm / fae374b
Linker: Add flag to override linkage rules Add a flag to lib/Linker (and `llvm-link`) to override linkage rules. When set, the functions in the source module *always* replace those in the destination module. The `llvm-link` option is `-override=abc.ll`. All the "regular" modules are loaded and linked first, followed by the `-override` modules. This is useful for debugging workflows where some subset of the module (e.g., a single function) is extracted into a separate file where it's optimized differently, before being merged back in. Patch by Luqman Aden! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235473 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 5 years ago
11 changed file(s) with 135 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
6767 void deleteModule();
6868
6969 /// \brief Link \p Src into the composite. The source is destroyed.
70 /// Passing OverrideSymbols as true will have symbols from Src
71 /// shadow those in the Dest.
7072 /// Returns true on error.
71 bool linkInModule(Module *Src);
73 bool linkInModule(Module *Src, bool OverrideSymbols = false);
7274
7375 /// \brief Set the composite to the passed-in module.
7476 void setModule(Module *Dst);
423423
424424 DiagnosticHandlerFunction DiagnosticHandler;
425425
426 /// For symbol clashes, prefer those from Src.
427 bool OverrideFromSrc;
428
426429 public:
427430 ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module *srcM,
428 DiagnosticHandlerFunction DiagnosticHandler)
431 DiagnosticHandlerFunction DiagnosticHandler,
432 bool OverrideFromSrc)
429433 : DstM(dstM), SrcM(srcM), TypeMap(Set),
430434 ValMaterializer(TypeMap, DstM, LazilyLinkGlobalValues),
431 DiagnosticHandler(DiagnosticHandler) {}
435 DiagnosticHandler(DiagnosticHandler), OverrideFromSrc(OverrideFromSrc) {
436 }
432437
433438 bool run();
434439
724729 bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
725730 const GlobalValue &Dest,
726731 const GlobalValue &Src) {
732 // Should we unconditionally use the Src?
733 if (OverrideFromSrc) {
734 LinkFromSrc = true;
735 return false;
736 }
737
727738 // We always have to add Src if it has appending linkage.
728739 if (Src.hasAppendingLinkage()) {
729740 LinkFromSrc = true;
10701081 } else {
10711082 // If the GV is to be lazily linked, don't create it just yet.
10721083 // The ValueMaterializerTy will deal with creating it if it's used.
1073 if (!DGV && (SGV->hasLocalLinkage() || SGV->hasLinkOnceLinkage() ||
1074 SGV->hasAvailableExternallyLinkage())) {
1084 if (!DGV && !OverrideFromSrc &&
1085 (SGV->hasLocalLinkage() || SGV->hasLinkOnceLinkage() ||
1086 SGV->hasAvailableExternallyLinkage())) {
10751087 DoNotLinkFromSource.insert(SGV);
10761088 return false;
10771089 }
17371749 Composite = nullptr;
17381750 }
17391751
1740 bool Linker::linkInModule(Module *Src) {
1752 bool Linker::linkInModule(Module *Src, bool OverrideSymbols) {
17411753 ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src,
1742 DiagnosticHandler);
1754 DiagnosticHandler, OverrideSymbols);
17431755 bool RetCode = TheLinker.run();
17441756 Composite->dropTriviallyDeadConstantArrays();
17451757 return RetCode;
0 define linkonce i32 @foo(i32 %i) {
1 entry:
2 ret i32 4
3 }
0 define internal i32 @foo(i32 %i) {
1 entry:
2 ret i32 4
3 }
0 define i32 @foo(i32 %i) {
1 entry:
2 ret i32 4
3 }
0 define i32 @foo(i32 %i) {
1 entry:
2 ret i32 4
3 }
0 ; RUN: llvm-link %s -override %S/Inputs/override-different-linkage.ll -S | FileCheck %s
1 ; RUN: llvm-link -override %S/Inputs/override-different-linkage.ll %s -S | FileCheck %s
2
3
4 ; CHECK-LABEL: define linkonce i32 @foo
5 ; CHECK-NEXT: entry:
6 ; CHECK-NEXT: ret i32 4
7 define weak i32 @foo(i32 %i) {
8 entry:
9 %add = add nsw i32 %i, %i
10 ret i32 %add
11 }
12
13 ; Function Attrs: nounwind ssp uwtable
14 define i32 @main(i32 %argc, i8** %argv) {
15 entry:
16 %a = call i32 @foo(i32 2)
17 ret i32 %a
18 }
0 ; RUN: llvm-link %s -override %S/Inputs/override-with-internal-linkage-2.ll -S | FileCheck %s
1 ; RUN: llvm-link -override %S/Inputs/override-with-internal-linkage-2.ll %s -S | FileCheck %s
2
3 ; CHECK-LABEL: define i32 @foo
4 ; CHECK-NEXT: entry:
5 ; CHECK-NEXT: %add = add nsw i32 %i, %i
6 ; CHECK-NEXT: ret i32 %add
7 define i32 @foo(i32 %i) {
8 entry:
9 %add = add nsw i32 %i, %i
10 ret i32 %add
11 }
12
13 ; CHECK-LABEL: define internal i32 @foo1
14 ; CHECK-NEXT: entry:
15 ; CHECK-NEXT: ret i32 4
16
17 ; Function Attrs: nounwind ssp uwtable
18 define i32 @main(i32 %argc, i8** %argv) {
19 entry:
20 %a = call i32 @foo(i32 2)
21 ret i32 %a
22 }
0 ; RUN: llvm-link %s -override %S/Inputs/override-with-internal-linkage.ll -S | FileCheck %s
1 ; RUN: llvm-link -override %S/Inputs/override-with-internal-linkage.ll %s -S | FileCheck %s
2
3 ; CHECK-LABEL: define internal i32 @foo2
4 ; CHECK-NEXT: entry:
5 ; CHECK-NEXT: %add = add nsw i32 %i, %i
6 ; CHECK-NEXT: ret i32 %add
7
8 ; CHECK-LABEL: define i32 @foo
9 ; CHECK-NEXT: entry:
10 ; CHECK-NEXT: ret i32 4
11 define internal i32 @foo(i32 %i) {
12 entry:
13 %add = add nsw i32 %i, %i
14 ret i32 %add
15 }
16
17 ; Function Attrs: nounwind ssp uwtable
18 define i32 @main(i32 %argc, i8** %argv) {
19 entry:
20 %a = call i32 @foo(i32 2)
21 ret i32 %a
22 }
0 ; RUN: llvm-link %s -override %S/Inputs/override.ll -S | FileCheck %s
1 ; RUN: llvm-link -override %S/Inputs/override.ll %s -S | FileCheck %s
2
3
4 ; CHECK-LABEL: define i32 @foo
5 ; CHECK-NEXT: entry:
6 ; CHECK-NEXT: ret i32 4
7 define i32 @foo(i32 %i) {
8 entry:
9 %add = add nsw i32 %i, %i
10 ret i32 %add
11 }
12
13 ; Function Attrs: nounwind ssp uwtable
14 define i32 @main(i32 %argc, i8** %argv) {
15 entry:
16 %a = call i32 @foo(i32 2)
17 ret i32 %a
18 }
3636 static cl::list
3737 InputFilenames(cl::Positional, cl::OneOrMore,
3838 cl::desc(""));
39
40 static cl::list OverridingInputs(
41 "override", cl::ZeroOrMore, cl::value_desc("filename"),
42 cl::desc(
43 "input bitcode file which can override previously defined symbol(s)"));
3944
4045 static cl::opt
4146 OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
107112 }
108113
109114 static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
110 const cl::list &Files) {
115 const cl::list &Files,
116 bool OverrideDuplicateSymbols) {
111117 for (const auto &File : Files) {
112118 std::unique_ptr M = loadFile(argv0, File, Context);
113119 if (!M.get()) {
123129 if (Verbose)
124130 errs() << "Linking in '" << File << "'\n";
125131
126 if (L.linkInModule(M.get()))
132 if (L.linkInModule(M.get(), OverrideDuplicateSymbols))
127133 return false;
128134 }
129135
142148 auto Composite = make_unique("llvm-link", Context);
143149 Linker L(Composite.get(), diagnosticHandler);
144150
145 if (!linkFiles(argv[0], Context, L, InputFilenames))
151 // First add all the regular input files
152 if (!linkFiles(argv[0], Context, L, InputFilenames, false))
153 return 1;
154
155 // Next the -override ones.
156 if (!linkFiles(argv[0], Context, L, OverridingInputs, true))
146157 return 1;
147158
148159 if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;