Skip to content

Commit baa3bf8

Browse files
committed
Bring r254336 back:
The difference is that now we don't error on out-of-comdat access to internal global values. We copy them instead. This seems to match the expectation of COFF linkers (see pr25686). Original message: Start deciding earlier what to link. A traditional linker is roughly split in symbol resolution and "copying stuff". The two tasks are badly mixed in lib/Linker. This starts splitting them apart. With this patch there are no direct call to linkGlobalValueBody or linkGlobalValueProto. Everything is linked via WapValue. This also includes a few fixes: * A GV goes undefined if the comdat is dropped (comdat11.ll). * We error if an internal GV goes undefined (comdat13.ll). * We don't link an unused comdat. The first two match the behavior of an ELF linker. The second one is equivalent to running globaldce on the input. llvm-svn: 254418
1 parent 6c800eb commit baa3bf8

File tree

8 files changed

+153
-80
lines changed

8 files changed

+153
-80
lines changed

llvm/lib/Linker/LinkModules.cpp

Lines changed: 78 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,8 @@ class ModuleLinker {
436436
/// references.
437437
bool DoneLinkingBodies;
438438

439+
bool HasError = false;
440+
439441
public:
440442
ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module *srcM,
441443
DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags,
@@ -483,6 +485,7 @@ class ModuleLinker {
483485
/// Helper method for setting a message and returning an error code.
484486
bool emitError(const Twine &Message) {
485487
DiagnosticHandler(LinkDiagnosticInfo(DS_Error, Message));
488+
HasError = true;
486489
return true;
487490
}
488491

@@ -531,6 +534,7 @@ class ModuleLinker {
531534
void upgradeMismatchedGlobalArray(StringRef Name);
532535
void upgradeMismatchedGlobals();
533536

537+
bool linkIfNeeded(GlobalValue &GV);
534538
bool linkAppendingVarProto(GlobalVariable *DstGV,
535539
const GlobalVariable *SrcGV);
536540

@@ -904,16 +908,12 @@ Value *ModuleLinker::materializeDeclFor(Value *V) {
904908
if (doneLinkingBodies())
905909
return nullptr;
906910

907-
GlobalValue *DGV = copyGlobalValueProto(TypeMap, SGV);
908-
909-
if (Comdat *SC = SGV->getComdat()) {
910-
if (auto *DGO = dyn_cast<GlobalObject>(DGV)) {
911-
Comdat *DC = DstM->getOrInsertComdat(SC->getName());
912-
DGO->setComdat(DC);
913-
}
914-
}
915-
916-
return DGV;
911+
linkGlobalValueProto(SGV);
912+
if (HasError)
913+
return nullptr;
914+
Value *Ret = ValueMap[SGV];
915+
assert(Ret);
916+
return Ret;
917917
}
918918

919919
void ValueMaterializerTy::materializeInitFor(GlobalValue *New,
@@ -922,15 +922,27 @@ void ValueMaterializerTy::materializeInitFor(GlobalValue *New,
922922
}
923923

924924
void ModuleLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old) {
925+
if (auto *F = dyn_cast<Function>(New)) {
926+
if (!F->isDeclaration())
927+
return;
928+
} else if (auto *V = dyn_cast<GlobalVariable>(New)) {
929+
if (V->hasInitializer())
930+
return;
931+
} else {
932+
auto *A = cast<GlobalAlias>(New);
933+
if (A->getAliasee())
934+
return;
935+
}
936+
937+
if (Old->isDeclaration())
938+
return;
939+
925940
if (isPerformingImport() && !doImportAsDefinition(Old))
926941
return;
927942

928-
// Skip declarations that ValueMaterializer may have created in
929-
// case we link in only some of SrcM.
930-
if (shouldLinkOnlyNeeded() && Old->isDeclaration())
943+
if (!New->hasLocalLinkage() && DoNotLinkFromSource.count(Old))
931944
return;
932945

933-
assert(!Old->isDeclaration() && "users should not pass down decls");
934946
linkGlobalValueBody(*Old);
935947
}
936948

@@ -1405,7 +1417,8 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) {
14051417
std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];
14061418
C = DstM->getOrInsertComdat(SC->getName());
14071419
C->setSelectionKind(SK);
1408-
ComdatMembers[SC].push_back(SGV);
1420+
if (SGV->hasInternalLinkage())
1421+
LinkFromSrc = true;
14091422
} else if (DGV) {
14101423
if (shouldLinkFromSource(LinkFromSrc, *DGV, *SGV))
14111424
return true;
@@ -1425,31 +1438,12 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) {
14251438
if (DGV)
14261439
HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr();
14271440

1428-
if (!LinkFromSrc && !DGV)
1429-
return false;
1430-
14311441
GlobalValue *NewGV;
1432-
if (!LinkFromSrc) {
1442+
if (!LinkFromSrc && DGV) {
14331443
NewGV = DGV;
14341444
// When linking from source we setVisibility from copyGlobalValueProto.
14351445
setVisibility(NewGV, SGV, DGV);
14361446
} else {
1437-
// If the GV is to be lazily linked, don't create it just yet.
1438-
// The ValueMaterializerTy will deal with creating it if it's used.
1439-
if (!DGV && !shouldOverrideFromSrc() && SGV != ImportFunction &&
1440-
(SGV->hasLocalLinkage() || SGV->hasLinkOnceLinkage() ||
1441-
SGV->hasAvailableExternallyLinkage())) {
1442-
DoNotLinkFromSource.insert(SGV);
1443-
return false;
1444-
}
1445-
1446-
// When we only want to link in unresolved dependencies, blacklist
1447-
// the symbol unless unless DestM has a matching declaration (DGV).
1448-
if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) {
1449-
DoNotLinkFromSource.insert(SGV);
1450-
return false;
1451-
}
1452-
14531447
NewGV = copyGlobalValueProto(TypeMap, SGV, DGV);
14541448

14551449
if (isPerformingImport() && !doImportAsDefinition(SGV))
@@ -1459,7 +1453,7 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) {
14591453
NewGV->setUnnamedAddr(HasUnnamedAddr);
14601454

14611455
if (auto *NewGO = dyn_cast<GlobalObject>(NewGV)) {
1462-
if (C)
1456+
if (C && LinkFromSrc)
14631457
NewGO->setComdat(C);
14641458

14651459
if (DGV && DGV->hasCommonLinkage() && SGV->hasCommonLinkage())
@@ -1842,6 +1836,38 @@ static std::string mergeTriples(const Triple &SrcTriple, const Triple &DstTriple
18421836
return DstTriple.str();
18431837
}
18441838

1839+
bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
1840+
GlobalValue *DGV = getLinkedToGlobal(&GV);
1841+
1842+
if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration()))
1843+
return false;
1844+
1845+
if (DGV && !GV.hasLocalLinkage()) {
1846+
GlobalValue::VisibilityTypes Visibility =
1847+
getMinVisibility(DGV->getVisibility(), GV.getVisibility());
1848+
DGV->setVisibility(Visibility);
1849+
GV.setVisibility(Visibility);
1850+
}
1851+
1852+
if (const Comdat *SC = GV.getComdat()) {
1853+
bool LinkFromSrc;
1854+
Comdat::SelectionKind SK;
1855+
std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];
1856+
if (!LinkFromSrc) {
1857+
DoNotLinkFromSource.insert(&GV);
1858+
return false;
1859+
}
1860+
}
1861+
1862+
if (!DGV && !shouldOverrideFromSrc() &&
1863+
(GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() ||
1864+
GV.hasAvailableExternallyLinkage())) {
1865+
return false;
1866+
}
1867+
MapValue(&GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer);
1868+
return HasError;
1869+
}
1870+
18451871
bool ModuleLinker::run() {
18461872
assert(DstM && "Null destination module");
18471873
assert(SrcM && "Null source module");
@@ -1901,24 +1927,30 @@ bool ModuleLinker::run() {
19011927
// Upgrade mismatched global arrays.
19021928
upgradeMismatchedGlobals();
19031929

1930+
for (GlobalVariable &GV : SrcM->globals())
1931+
if (const Comdat *SC = GV.getComdat())
1932+
ComdatMembers[SC].push_back(&GV);
1933+
1934+
for (Function &SF : *SrcM)
1935+
if (const Comdat *SC = SF.getComdat())
1936+
ComdatMembers[SC].push_back(&SF);
1937+
1938+
for (GlobalAlias &GA : SrcM->aliases())
1939+
if (const Comdat *SC = GA.getComdat())
1940+
ComdatMembers[SC].push_back(&GA);
1941+
19041942
// Insert all of the globals in src into the DstM module... without linking
19051943
// initializers (which could refer to functions not yet mapped over).
19061944
for (GlobalVariable &GV : SrcM->globals())
1907-
if (linkGlobalValueProto(&GV))
1945+
if (linkIfNeeded(GV))
19081946
return true;
19091947

1910-
// Link the functions together between the two modules, without doing function
1911-
// bodies... this just adds external function prototypes to the DstM
1912-
// function... We do this so that when we begin processing function bodies,
1913-
// all of the global values that may be referenced are available in our
1914-
// ValueMap.
1915-
for (Function &F :*SrcM)
1916-
if (linkGlobalValueProto(&F))
1948+
for (Function &SF : *SrcM)
1949+
if (linkIfNeeded(SF))
19171950
return true;
19181951

1919-
// If there were any aliases, link them now.
19201952
for (GlobalAlias &GA : SrcM->aliases())
1921-
if (linkGlobalValueProto(&GA))
1953+
if (linkIfNeeded(GA))
19221954
return true;
19231955

19241956
for (AppendingVarInfo &AppendingVar : AppendingVars)
@@ -1933,37 +1965,6 @@ bool ModuleLinker::run() {
19331965
MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer);
19341966
}
19351967

1936-
// Link in the function bodies that are defined in the source module into
1937-
// DstM.
1938-
for (Function &SF : *SrcM) {
1939-
// Skip if no body (function is external).
1940-
if (SF.isDeclaration())
1941-
continue;
1942-
1943-
// Skip if not linking from source.
1944-
if (DoNotLinkFromSource.count(&SF))
1945-
continue;
1946-
1947-
if (linkGlobalValueBody(SF))
1948-
return true;
1949-
}
1950-
1951-
// Resolve all uses of aliases with aliasees.
1952-
for (GlobalAlias &Src : SrcM->aliases()) {
1953-
if (DoNotLinkFromSource.count(&Src))
1954-
continue;
1955-
linkGlobalValueBody(Src);
1956-
}
1957-
1958-
// Update the initializers in the DstM module now that all globals that may
1959-
// be referenced are in DstM.
1960-
for (GlobalVariable &Src : SrcM->globals()) {
1961-
// Only process initialized GV's or ones not already in dest.
1962-
if (!Src.hasInitializer() || DoNotLinkFromSource.count(&Src))
1963-
continue;
1964-
linkGlobalValueBody(Src);
1965-
}
1966-
19671968
// Note that we are done linking global value bodies. This prevents
19681969
// metadata linking from creating new references.
19691970
DoneLinkingBodies = true;

llvm/lib/Transforms/Utils/ValueMapper.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
4141
if (Value *NewV =
4242
Materializer->materializeDeclFor(const_cast<Value *>(V))) {
4343
VM[V] = NewV;
44-
if (auto *GV = dyn_cast<GlobalValue>(V))
45-
Materializer->materializeInitFor(cast<GlobalValue>(NewV),
46-
const_cast<GlobalValue *>(GV));
44+
if (auto *NewGV = dyn_cast<GlobalValue>(NewV))
45+
Materializer->materializeInitFor(
46+
NewGV, const_cast<GlobalValue *>(cast<GlobalValue>(V)));
4747
return NewV;
4848
}
4949
}

llvm/test/Linker/Inputs/comdat11.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
$foo = comdat any
2+
@foo = global i8 1, comdat
3+
define void @zed() {
4+
call void @bar()
5+
ret void
6+
}
7+
define void @bar() comdat($foo) {
8+
ret void
9+
}

llvm/test/Linker/Inputs/comdat13.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
$foo = comdat any
2+
@foo = internal global i8 1, comdat
3+
define i8* @zed() {
4+
call void @bax()
5+
ret i8* @foo
6+
}
7+
define internal void @bax() comdat($foo) {
8+
ret void
9+
}

llvm/test/Linker/comdat11.ll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: llvm-link -S %s %p/Inputs/comdat11.ll -o - | FileCheck %s
2+
3+
$foo = comdat any
4+
@foo = global i8 0, comdat
5+
6+
; CHECK: @foo = global i8 0, comdat
7+
8+
; CHECK: define void @zed() {
9+
; CHECK: call void @bar()
10+
; CHECK: ret void
11+
; CHECK: }
12+
13+
; CHECK: declare void @bar()

llvm/test/Linker/comdat12.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; RUN: llvm-link %s -S -o - | FileCheck %s
2+
3+
$foo = comdat largest
4+
define internal void @foo() comdat($foo) {
5+
ret void
6+
}
7+
8+
; CHECK-NOT: foo

llvm/test/Linker/comdat13.ll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: llvm-link -S %s %p/Inputs/comdat13.ll -o - | FileCheck %s
2+
3+
; In Inputs/comdat13.ll a function not in the $foo comdat (zed) references an
4+
; internal function in the comdat $foo.
5+
; The IR would be ilegal on ELF ("relocation refers to discarded section"),
6+
; but COFF linkers seem to just duplicate the comdat.
7+
8+
$foo = comdat any
9+
@foo = internal global i8 0, comdat
10+
define i8* @bar() {
11+
ret i8* @foo
12+
}
13+
14+
; CHECK: $foo = comdat any
15+
16+
; CHECK: @foo = internal global i8 0, comdat
17+
; CHECK: @foo.1 = internal global i8 1, comdat($foo)
18+
19+
; CHECK: define i8* @bar() {
20+
; CHECK-NEXT: ret i8* @foo
21+
; CHECK-NEXT: }
22+
23+
; CHECK: define i8* @zed() {
24+
; CHECK-NEXT: call void @bax()
25+
; CHECK-NEXT: ret i8* @foo.1
26+
; CHECK-NEXT: }
27+
28+
; CHECK: define internal void @bax() comdat($foo) {
29+
; CHECK-NEXT: ret void
30+
; CHECK-NEXT: }

llvm/test/Linker/comdat9.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ $f2 = comdat largest
1414
define internal void @f2() comdat($f2) {
1515
ret void
1616
}
17+
define void @f3() comdat($f2) {
18+
ret void
19+
}
1720

1821
; CHECK-DAG: $f2 = comdat largest
1922
; CHECK-DAG: define internal void @f2() comdat {

0 commit comments

Comments
 (0)