aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2020-09-18 13:43:13 -0700
committerReid Kleckner <rnk@google.com>2020-09-18 14:31:01 -0700
commit9932561b4892b6e9bbb0c2369272dfff2305fdb9 (patch)
treef7dc6a6c92310b40e00c8a2406ea79b7f1d41c9f /llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
parent3c731ba5f1b604c873e96ac137bfea723690ba95 (diff)
downloadllvm-9932561b4892b6e9bbb0c2369272dfff2305fdb9.zip
llvm-9932561b4892b6e9bbb0c2369272dfff2305fdb9.tar.gz
llvm-9932561b4892b6e9bbb0c2369272dfff2305fdb9.tar.bz2
[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.
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r--llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp85
1 files changed, 60 insertions, 25 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 08dfbd1..0c43ec8 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -1551,21 +1551,7 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
Module &M) const {
- if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
- // Emit the linker options to the linker .drectve section. According to the
- // spec, this section is a space-separated string containing flags for
- // linker.
- MCSection *Sec = getDrectveSection();
- Streamer.SwitchSection(Sec);
- for (const auto *Option : LinkerOptions->operands()) {
- for (const auto &Piece : cast<MDNode>(Option)->operands()) {
- // Lead with a space for consistency with our dllexport implementation.
- std::string Directive(" ");
- Directive.append(std::string(cast<MDString>(Piece)->getString()));
- Streamer.emitBytes(Directive);
- }
- }
- }
+ emitLinkerDirectives(Streamer, M);
unsigned Version = 0;
unsigned Flags = 0;
@@ -1588,6 +1574,65 @@ void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer,
emitCGProfile(Streamer, M);
}
+void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
+ MCStreamer &Streamer, Module &M) const {
+ if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) {
+ // Emit the linker options to the linker .drectve section. According to the
+ // spec, this section is a space-separated string containing flags for
+ // linker.
+ MCSection *Sec = getDrectveSection();
+ Streamer.SwitchSection(Sec);
+ for (const auto *Option : LinkerOptions->operands()) {
+ for (const auto &Piece : cast<MDNode>(Option)->operands()) {
+ // Lead with a space for consistency with our dllexport implementation.
+ std::string Directive(" ");
+ Directive.append(std::string(cast<MDString>(Piece)->getString()));
+ Streamer.emitBytes(Directive);
+ }
+ }
+ }
+
+ // Emit /EXPORT: flags for each exported global as necessary.
+ std::string Flags;
+ for (const GlobalValue &GV : M.global_values()) {
+ raw_string_ostream OS(Flags);
+ emitLinkerFlagsForGlobalCOFF(OS, &GV, getTargetTriple(), getMangler());
+ OS.flush();
+ if (!Flags.empty()) {
+ Streamer.SwitchSection(getDrectveSection());
+ Streamer.emitBytes(Flags);
+ }
+ Flags.clear();
+ }
+
+ // Emit /INCLUDE: flags for each used global as necessary.
+ if (const auto *LU = M.getNamedGlobal("llvm.used")) {
+ assert(LU->hasInitializer() && "expected llvm.used to have an initializer");
+ assert(isa<ArrayType>(LU->getValueType()) &&
+ "expected llvm.used to be an array type");
+ if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {
+ for (const Value *Op : A->operands()) {
+ const auto *GV = cast<GlobalValue>(Op->stripPointerCasts());
+ // Global symbols with internal or private linkage are not visible to
+ // the linker, and thus would cause an error when the linker tried to
+ // preserve the symbol due to the `/include:` directive.
+ if (GV->hasLocalLinkage())
+ continue;
+
+ raw_string_ostream OS(Flags);
+ emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
+ OS.flush();
+
+ if (!Flags.empty()) {
+ Streamer.SwitchSection(getDrectveSection());
+ Streamer.emitBytes(Flags);
+ }
+ Flags.clear();
+ }
+ }
+ }
+}
+
void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
TargetLoweringObjectFile::Initialize(Ctx, TM);
@@ -1665,16 +1710,6 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
cast<MCSectionCOFF>(StaticDtorSection));
}
-void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
- raw_ostream &OS, const GlobalValue *GV) const {
- emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler());
-}
-
-void TargetLoweringObjectFileCOFF::emitLinkerFlagsForUsed(
- raw_ostream &OS, const GlobalValue *GV) const {
- emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
-}
-
const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
const GlobalValue *LHS, const GlobalValue *RHS,
const TargetMachine &TM) const {