Skip to content

Commit 9932561

Browse files
committed
[COFF] Move per-global .drective emission from AsmPrinter to TLOFCOFF
This changes the order of output sections and the output assembly, but is otherwise NFC. It simplifies the TLOF interface by removing two COFF-only methods.
1 parent 3c731ba commit 9932561

File tree

7 files changed

+119
-138
lines changed

7 files changed

+119
-138
lines changed

llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,6 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
167167
MCSection *getStaticDtorSection(unsigned Priority,
168168
const MCSymbol *KeySym) const override;
169169

170-
void emitLinkerFlagsForGlobal(raw_ostream &OS,
171-
const GlobalValue *GV) const override;
172-
173-
void emitLinkerFlagsForUsed(raw_ostream &OS,
174-
const GlobalValue *GV) const override;
175-
176170
const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
177171
const GlobalValue *RHS,
178172
const TargetMachine &TM) const override;
@@ -182,6 +176,9 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
182176
MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
183177
const Constant *C,
184178
Align &Alignment) const override;
179+
180+
private:
181+
void emitLinkerDirectives(MCStreamer &Streamer, Module &M) const;
185182
};
186183

187184
class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {

llvm/include/llvm/Target/TargetLoweringObjectFile.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,6 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
208208
return nullptr;
209209
}
210210

211-
virtual void emitLinkerFlagsForGlobal(raw_ostream &OS,
212-
const GlobalValue *GV) const {}
213-
214-
virtual void emitLinkerFlagsForUsed(raw_ostream &OS,
215-
const GlobalValue *GV) const {}
216-
217211
/// If supported, return the section to use for the llvm.commandline
218212
/// metadata. Otherwise, return nullptr.
219213
virtual MCSection *getSectionForCommandLines() const {

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,51 +1720,6 @@ bool AsmPrinter::doFinalization(Module &M) {
17201720
if (MCSection *S = MAI->getNonexecutableStackSection(OutContext))
17211721
OutStreamer->SwitchSection(S);
17221722

1723-
if (TM.getTargetTriple().isOSBinFormatCOFF()) {
1724-
// Emit /EXPORT: flags for each exported global as necessary.
1725-
const auto &TLOF = getObjFileLowering();
1726-
std::string Flags;
1727-
1728-
for (const GlobalValue &GV : M.global_values()) {
1729-
raw_string_ostream OS(Flags);
1730-
TLOF.emitLinkerFlagsForGlobal(OS, &GV);
1731-
OS.flush();
1732-
if (!Flags.empty()) {
1733-
OutStreamer->SwitchSection(TLOF.getDrectveSection());
1734-
OutStreamer->emitBytes(Flags);
1735-
}
1736-
Flags.clear();
1737-
}
1738-
1739-
// Emit /INCLUDE: flags for each used global as necessary.
1740-
if (const auto *LU = M.getNamedGlobal("llvm.used")) {
1741-
assert(LU->hasInitializer() &&
1742-
"expected llvm.used to have an initializer");
1743-
assert(isa<ArrayType>(LU->getValueType()) &&
1744-
"expected llvm.used to be an array type");
1745-
if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {
1746-
for (const Value *Op : A->operands()) {
1747-
const auto *GV = cast<GlobalValue>(Op->stripPointerCasts());
1748-
// Global symbols with internal or private linkage are not visible to
1749-
// the linker, and thus would cause an error when the linker tried to
1750-
// preserve the symbol due to the `/include:` directive.
1751-
if (GV->hasLocalLinkage())
1752-
continue;
1753-
1754-
raw_string_ostream OS(Flags);
1755-
TLOF.emitLinkerFlagsForUsed(OS, GV);
1756-
OS.flush();
1757-
1758-
if (!Flags.empty()) {
1759-
OutStreamer->SwitchSection(TLOF.getDrectveSection());
1760-
OutStreamer->emitBytes(Flags);
1761-
}
1762-
Flags.clear();
1763-
}
1764-
}
1765-
}
1766-
}
1767-
17681723
if (TM.Options.EmitAddrsig) {
17691724
// Emit address-significance attributes for all globals.
17701725
OutStreamer->emitAddrsig();

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,21 +1551,7 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
15511551

15521552
void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
15531553
Module &M) const {
1554-
if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
1555-
// Emit the linker options to the linker .drectve section. According to the
1556-
// spec, this section is a space-separated string containing flags for
1557-
// linker.
1558-
MCSection *Sec = getDrectveSection();
1559-
Streamer.SwitchSection(Sec);
1560-
for (const auto *Option : LinkerOptions->operands()) {
1561-
for (const auto &Piece : cast<MDNode>(Option)->operands()) {
1562-
// Lead with a space for consistency with our dllexport implementation.
1563-
std::string Directive(" ");
1564-
Directive.append(std::string(cast<MDString>(Piece)->getString()));
1565-
Streamer.emitBytes(Directive);
1566-
}
1567-
}
1568-
}
1554+
emitLinkerDirectives(Streamer, M);
15691555

15701556
unsigned Version = 0;
15711557
unsigned Flags = 0;
@@ -1588,6 +1574,65 @@ void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
15881574
emitCGProfile(Streamer, M);
15891575
}
15901576

1577+
void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
1578+
MCStreamer &Streamer, Module &M) const {
1579+
if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
1580+
// Emit the linker options to the linker .drectve section. According to the
1581+
// spec, this section is a space-separated string containing flags for
1582+
// linker.
1583+
MCSection *Sec = getDrectveSection();
1584+
Streamer.SwitchSection(Sec);
1585+
for (const auto *Option : LinkerOptions->operands()) {
1586+
for (const auto &Piece : cast<MDNode>(Option)->operands()) {
1587+
// Lead with a space for consistency with our dllexport implementation.
1588+
std::string Directive(" ");
1589+
Directive.append(std::string(cast<MDString>(Piece)->getString()));
1590+
Streamer.emitBytes(Directive);
1591+
}
1592+
}
1593+
}
1594+
1595+
// Emit /EXPORT: flags for each exported global as necessary.
1596+
std::string Flags;
1597+
for (const GlobalValue &GV : M.global_values()) {
1598+
raw_string_ostream OS(Flags);
1599+
emitLinkerFlagsForGlobalCOFF(OS, &GV, getTargetTriple(), getMangler());
1600+
OS.flush();
1601+
if (!Flags.empty()) {
1602+
Streamer.SwitchSection(getDrectveSection());
1603+
Streamer.emitBytes(Flags);
1604+
}
1605+
Flags.clear();
1606+
}
1607+
1608+
// Emit /INCLUDE: flags for each used global as necessary.
1609+
if (const auto *LU = M.getNamedGlobal("llvm.used")) {
1610+
assert(LU->hasInitializer() && "expected llvm.used to have an initializer");
1611+
assert(isa<ArrayType>(LU->getValueType()) &&
1612+
"expected llvm.used to be an array type");
1613+
if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {
1614+
for (const Value *Op : A->operands()) {
1615+
const auto *GV = cast<GlobalValue>(Op->stripPointerCasts());
1616+
// Global symbols with internal or private linkage are not visible to
1617+
// the linker, and thus would cause an error when the linker tried to
1618+
// preserve the symbol due to the `/include:` directive.
1619+
if (GV->hasLocalLinkage())
1620+
continue;
1621+
1622+
raw_string_ostream OS(Flags);
1623+
emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
1624+
OS.flush();
1625+
1626+
if (!Flags.empty()) {
1627+
Streamer.SwitchSection(getDrectveSection());
1628+
Streamer.emitBytes(Flags);
1629+
}
1630+
Flags.clear();
1631+
}
1632+
}
1633+
}
1634+
}
1635+
15911636
void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
15921637
const TargetMachine &TM) {
15931638
TargetLoweringObjectFile::Initialize(Ctx, TM);
@@ -1665,16 +1710,6 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
16651710
cast<MCSectionCOFF>(StaticDtorSection));
16661711
}
16671712

1668-
void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
1669-
raw_ostream &OS, const GlobalValue *GV) const {
1670-
emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler());
1671-
}
1672-
1673-
void TargetLoweringObjectFileCOFF::emitLinkerFlagsForUsed(
1674-
raw_ostream &OS, const GlobalValue *GV) const {
1675-
emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
1676-
}
1677-
16781713
const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
16791714
const GlobalValue *LHS, const GlobalValue *RHS,
16801715
const TargetMachine &TM) const {

llvm/test/CodeGen/ARM/global-merge-dllexport.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ define void @f1(i32 %a1, i32 %a2) {
1313
}
1414

1515
; CHECK: .lcomm .L_MergedGlobals,8,4
16+
; CHECK: .section .drectve,"yn"
17+
; CHECK: .ascii " /EXPORT:y,DATA"
1618
; CHECK: .globl x
1719
; CHECK: .set x, .L_MergedGlobals
1820
; CHECK: .globl y
1921
; CHECK: .set y, .L_MergedGlobals+4
20-
; CHECK: .section .drectve,"yn"
21-
; CHECK: .ascii " /EXPORT:y,DATA"

llvm/test/CodeGen/X86/dllexport-x86_64.ll

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -61,45 +61,13 @@ define weak_odr dllexport void @weak1() {
6161
@WeakVar3 = weak_odr dllexport global i32 0, align 4
6262

6363

64-
; CHECK: .globl alias
65-
; CHECK: .set alias, notExported
66-
@alias = dllexport alias void(), void()* @notExported
67-
68-
; CHECK: .globl aliasNotExported
69-
; CHECK: .set aliasNotExported, f1
70-
@aliasNotExported = alias void(), void()* @f1
71-
72-
; CHECK: .globl alias2
73-
; CHECK: .set alias2, f1
74-
@alias2 = dllexport alias void(), void()* @f1
75-
76-
; CHECK: .globl alias3
77-
; CHECK: .set alias3, notExported
78-
@alias3 = dllexport alias void(), void()* @notExported
79-
80-
; CHECK: .weak weak_alias
81-
; CHECK: .set weak_alias, f1
82-
@weak_alias = weak_odr dllexport alias void(), void()* @f1
83-
84-
@blob = global [6 x i8] c"\B8*\00\00\00\C3", section ".text", align 16
85-
@blob_alias = dllexport alias i32 (), bitcast ([6 x i8]* @blob to i32 ()*)
86-
87-
@exportedButNotDefinedVariable = external dllexport global i32
88-
declare dllexport void @exportedButNotDefinedFunction()
89-
define void @foo() {
90-
entry:
91-
store i32 4, i32* @exportedButNotDefinedVariable, align 4
92-
call void @exportedButNotDefinedFunction()
93-
ret void
94-
}
95-
9664
; Verify items that should not be exported do not appear in the export table.
9765
; We use a separate check prefix to avoid confusion between -NOT and -SAME.
9866
; NOTEXPORTED: .section .drectve
99-
; NOTEXPORTED-NOT: notExported
100-
; NOTEXPORTED-NOT: aliasNotExported
101-
; NOTEXPORTED-NOT: exportedButNotDefinedVariable
102-
; NOTEXPORTED-NOT: exportedButNotDefinedFunction
67+
; NOTEXPORTED-NOT: :notExported
68+
; NOTEXPORTED-NOT: :aliasNotExported
69+
; NOTEXPORTED-NOT: :exportedButNotDefinedVariable
70+
; NOTEXPORTED-NOT: :exportedButNotDefinedFunction
10371

10472
; CHECK: .section .drectve
10573
; WIN32: .ascii " /EXPORT:f1"
@@ -134,3 +102,35 @@ entry:
134102
; MINGW: .ascii " -export:alias3"
135103
; MINGW: .ascii " -export:weak_alias"
136104
; MINGW: .ascii " -export:blob_alias"
105+
106+
; CHECK: .globl alias
107+
; CHECK: .set alias, notExported
108+
@alias = dllexport alias void(), void()* @notExported
109+
110+
; CHECK: .globl aliasNotExported
111+
; CHECK: .set aliasNotExported, f1
112+
@aliasNotExported = alias void(), void()* @f1
113+
114+
; CHECK: .globl alias2
115+
; CHECK: .set alias2, f1
116+
@alias2 = dllexport alias void(), void()* @f1
117+
118+
; CHECK: .globl alias3
119+
; CHECK: .set alias3, notExported
120+
@alias3 = dllexport alias void(), void()* @notExported
121+
122+
; CHECK: .weak weak_alias
123+
; CHECK: .set weak_alias, f1
124+
@weak_alias = weak_odr dllexport alias void(), void()* @f1
125+
126+
@blob = global [6 x i8] c"\B8*\00\00\00\C3", section ".text", align 16
127+
@blob_alias = dllexport alias i32 (), bitcast ([6 x i8]* @blob to i32 ()*)
128+
129+
@exportedButNotDefinedVariable = external dllexport global i32
130+
declare dllexport void @exportedButNotDefinedFunction()
131+
define void @foo() {
132+
entry:
133+
store i32 4, i32* @exportedButNotDefinedVariable, align 4
134+
call void @exportedButNotDefinedFunction()
135+
ret void
136+
}

llvm/test/CodeGen/X86/dllexport.ll

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,27 +82,11 @@ define weak_odr dllexport void @weak1() {
8282
@WeakVar2 = weak_odr dllexport unnamed_addr constant i32 1
8383

8484

85-
; CHECK: .globl _alias
86-
; CHECK: .set _alias, _notExported
87-
@alias = dllexport alias void(), void()* @notExported
88-
89-
; CHECK: .globl _alias2
90-
; CHECK: .set _alias2, _f1
91-
@alias2 = dllexport alias void(), void()* @f1
92-
93-
; CHECK: .globl _alias3
94-
; CHECK: .set _alias3, _notExported
95-
@alias3 = dllexport alias void(), void()* @notExported
96-
97-
; CHECK: .weak _weak_alias
98-
; CHECK: .set _weak_alias, _f1
99-
@weak_alias = weak_odr dllexport alias void(), void()* @f1
100-
10185
; Verify items that should not be exported do not appear in the export table.
10286
; We use a separate check prefix to avoid confusion between -NOT and -SAME.
10387
; NOTEXPORTED: .section .drectve
104-
; NOTEXPORTED-NOT: notExported
105-
; NOTEXPORTED-NOT: notDefined
88+
; NOTEXPORTED-NOT: :notExported
89+
; NOTEXPORTED-NOT: :notDefined
10690

10791
; CHECK: .section .drectve
10892
; CHECK-CL: .ascii " /EXPORT:_f1"
@@ -139,3 +123,19 @@ define weak_odr dllexport void @weak1() {
139123
; CHECK-GCC: .ascii " -export:alias2"
140124
; CHECK-GCC: .ascii " -export:alias3"
141125
; CHECK-GCC: .ascii " -export:weak_alias"
126+
127+
; CHECK: .globl _alias
128+
; CHECK: .set _alias, _notExported
129+
@alias = dllexport alias void(), void()* @notExported
130+
131+
; CHECK: .globl _alias2
132+
; CHECK: .set _alias2, _f1
133+
@alias2 = dllexport alias void(), void()* @f1
134+
135+
; CHECK: .globl _alias3
136+
; CHECK: .set _alias3, _notExported
137+
@alias3 = dllexport alias void(), void()* @notExported
138+
139+
; CHECK: .weak _weak_alias
140+
; CHECK: .set _weak_alias, _f1
141+
@weak_alias = weak_odr dllexport alias void(), void()* @f1

0 commit comments

Comments
 (0)