Skip to content

Commit 902461e

Browse files
Merge pull request #2229 from swiftwasm/katei/fix-wasm-llvm-lto-autolink
Use swift-autolink-extract for wasm target LLVM LTO
2 parents ad75aa3 + 69174f1 commit 902461e

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

lib/Driver/Driver.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2202,7 +2202,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
22022202
// argument input file to the linker.
22032203
const auto &Triple = TC.getTriple();
22042204
SmallVector<const Action *, 2> AutolinkExtractInputs;
2205-
for (const Action *A : AllLinkerInputs)
2205+
for (const Action *A : AllLinkerInputs) {
22062206
if (A->getType() == file_types::TY_Object) {
22072207
// Shared objects on ELF platforms don't have a swift1_autolink_entries
22082208
// section in them because the section in the .o files is marked as
@@ -2214,12 +2214,14 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
22142214
continue;
22152215
}
22162216
AutolinkExtractInputs.push_back(A);
2217+
} else if (A->getType() == file_types::TY_LLVM_BC) {
2218+
AutolinkExtractInputs.push_back(A);
22172219
}
2220+
}
22182221
const bool AutolinkExtractRequired =
2219-
((Triple.getObjectFormat() == llvm::Triple::ELF && !Triple.isPS4()) ||
2220-
Triple.getObjectFormat() == llvm::Triple::Wasm ||
2221-
Triple.isOSCygMing()) &&
2222-
!shouldPerformLTO;
2222+
((Triple.getObjectFormat() == llvm::Triple::ELF && !Triple.isPS4() && !shouldPerformLTO) ||
2223+
Triple.getObjectFormat() == llvm::Triple::Wasm ||
2224+
(Triple.isOSCygMing() && !shouldPerformLTO));
22232225
if (!AutolinkExtractInputs.empty() && AutolinkExtractRequired) {
22242226
auto *AutolinkExtractAction =
22252227
C.createAction<AutolinkExtractJobAction>(AutolinkExtractInputs);

lib/Driver/WebAssemblyToolChains.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ ToolChain::InvocationInfo toolchains::WebAssembly::constructInvocation(
5555

5656
addPrimaryInputsOfType(Arguments, context.Inputs, context.Args,
5757
file_types::TY_Object);
58+
addPrimaryInputsOfType(Arguments, context.Inputs, context.Args,
59+
file_types::TY_LLVM_BC);
5860
addInputsOfType(Arguments, context.InputActions, file_types::TY_Object);
61+
addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC);
5962

6063
Arguments.push_back("-o");
6164
Arguments.push_back(

tools/driver/autolink_extract_main.cpp

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@
3333
#include "llvm/Object/ObjectFile.h"
3434
#include "llvm/Object/ELFObjectFile.h"
3535
#include "llvm/Object/Wasm.h"
36+
#include "llvm/Object/IRObjectFile.h"
3637
#include "llvm/BinaryFormat/Wasm.h"
38+
#include "llvm/IR/Module.h"
39+
#include "llvm/IR/Constants.h"
3740

3841
using namespace swift;
3942
using namespace llvm::opt;
@@ -172,6 +175,27 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
172175
return false;
173176
}
174177

178+
static bool
179+
extractLinkerFlagsFromObjectFile(const llvm::object::IRObjectFile *ObjectFile,
180+
std::vector<std::string> &LinkerFlags,
181+
CompilerInstance &Instance) {
182+
for (const auto &M : ObjectFile->modules()) {
183+
llvm::GlobalVariable *var = M.getGlobalVariable("_swift1_autolink_entries", true);
184+
if (!var) continue;
185+
if (auto Entries = dyn_cast<llvm::ConstantDataArray>(var->getInitializer())) {
186+
StringRef SegmentData = Entries->getAsString();
187+
// entries are null-terminated, so extract them and push them into
188+
// the set.
189+
llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
190+
SegmentData.split(SplitFlags, llvm::StringRef("\0", 1), -1,
191+
/*KeepEmpty=*/false);
192+
for (const auto &Flag : SplitFlags)
193+
LinkerFlags.push_back(Flag.str());
194+
}
195+
}
196+
return false;
197+
}
198+
175199
/// Look inside the binary 'Bin' and append any linker flags found in its
176200
/// ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
177201
/// recursively look inside all children within the archive. Return 'true' if
@@ -184,6 +208,8 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
184208
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance);
185209
} else if (auto *ObjectFile = llvm::dyn_cast<llvm::object::WasmObjectFile>(Bin)) {
186210
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance);
211+
} else if (auto *BitCodeFile = llvm::dyn_cast<llvm::object::IRObjectFile>(Bin)) {
212+
return extractLinkerFlagsFromObjectFile(BitCodeFile, LinkerFlags, Instance);
187213
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
188214
llvm::Error Error = llvm::Error::success();
189215
for (const auto &Child : Archive->children(Error)) {
@@ -215,6 +241,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
215241
void *MainAddr) {
216242
CompilerInstance Instance;
217243
PrintingDiagnosticConsumer PDC;
244+
llvm::LLVMContext Context;
218245
Instance.addDiagnosticConsumer(&PDC);
219246

220247
AutolinkExtractInvocation Invocation;
@@ -231,20 +258,28 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
231258

232259
// Extract the linker flags from the objects.
233260
for (const auto &BinaryFileName : Invocation.getInputFilenames()) {
234-
auto BinaryOwner = llvm::object::createBinary(BinaryFileName);
235-
if (!BinaryOwner) {
261+
auto FileOrErr = llvm::MemoryBuffer::getFileOrSTDIN(BinaryFileName, /*FileSize=*/-1,
262+
/*RequiresNullTerminator=*/false);
263+
if (std::error_code EC = FileOrErr.getError()) {
264+
Instance.getDiags().diagnose(SourceLoc(), diag::error_open_input_file,
265+
BinaryFileName, EC.message());
266+
return 1;
267+
}
268+
std::unique_ptr<llvm::MemoryBuffer> &Buffer = FileOrErr.get();
269+
auto Binary = llvm::object::createBinary(Buffer->getMemBufferRef(), &Context);
270+
if (!Binary) {
236271
std::string message;
237272
{
238273
llvm::raw_string_ostream os(message);
239-
logAllUnhandledErrors(BinaryOwner.takeError(), os, "");
274+
logAllUnhandledErrors(Binary.takeError(), os, "");
240275
}
241276

242277
Instance.getDiags().diagnose(SourceLoc(), diag::error_open_input_file,
243278
BinaryFileName, message);
244279
return 1;
245280
}
246281

247-
if (extractLinkerFlags(BinaryOwner->getBinary(), Instance, BinaryFileName,
282+
if (extractLinkerFlags(Binary->get(), Instance, BinaryFileName,
248283
LinkerFlags)) {
249284
return 1;
250285
}

0 commit comments

Comments
 (0)