Skip to content

[Batch Mode] Pass PrimarySpecificPaths through compiler. (4) #14230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions include/swift/AST/IRGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ enum class IRGenEmbedMode : unsigned {
/// The set of options supported by IR generation.
class IRGenOptions {
public:
/// The name of the first input file, used by the debug info.
std::string MainInputFilename;
std::vector<std::string> OutputFilenames;
std::string ModuleName;

/// The compilation directory for the debug info.
Expand Down Expand Up @@ -188,19 +185,6 @@ class IRGenOptions {
UseSwiftCall(false), GenerateProfile(false), CmdArgs(),
SanitizeCoverage(llvm::SanitizerCoverageOptions()) {}

/// Gets the name of the specified output filename.
/// If multiple files are specified, the last one is returned.
/// This function is used by (at least)
/// lldb/source/Symbol/SwiftASTContext.cpp:4603
/// FIXME: This function should go away in favor of
/// Instance.getFrontendOptions().InputsAndOutputs.getSingleOutputFilename
/// when batch mode handles all contingencies.
StringRef getSingleOutputFilename() const {
if (OutputFilenames.size() >= 1)
return OutputFilenames.back();
return StringRef();
}

// Get a hash of all options which influence the llvm compilation but are not
// reflected in the llvm module itself.
unsigned getLLVMCodeGenOptionsHash() {
Expand Down
41 changes: 41 additions & 0 deletions include/swift/Basic/PrimarySpecificPaths.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===--- PrimarySpecificPaths.h ---------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_BASIC_PRIMARYSPECIFICPATHS_H
#define SWIFT_BASIC_PRIMARYSPECIFICPATHS_H

#include "swift/Basic/LLVM.h"
#include "swift/Basic/SupplementaryOutputPaths.h"

#include <string>

namespace swift {
class PrimarySpecificPaths {
public:
std::string OutputFilename;
SupplementaryOutputPaths SupplementaryOutputs;

/// The name of the "main" input file, used by the debug info.
std::string MainInputFilenameForDebugInfo;

PrimarySpecificPaths(
std::string OutputFilename = std::string(),
std::string MainInputFilenameForDebugInfo = std::string(),
SupplementaryOutputPaths SupplementaryOutputs =
SupplementaryOutputPaths())
: OutputFilename(OutputFilename),
SupplementaryOutputs(SupplementaryOutputs),
MainInputFilenameForDebugInfo(MainInputFilenameForDebugInfo) {}
};
} // namespace swift

#endif /* SWIFT_BASIC_PRIMARYSPECIFICPATHS_H */
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ struct SupplementaryOutputPaths {

SupplementaryOutputPaths() = default;
SupplementaryOutputPaths(const SupplementaryOutputPaths &) = default;

bool empty() const {
return ObjCHeaderOutputPath.empty() && ModuleOutputPath.empty() &&
ModuleDocOutputPath.empty() && DependenciesFilePath.empty() &&
ReferenceDependenciesFilePath.empty() &&
SerializedDiagnosticsPath.empty() && LoadedModuleTracePath.empty() &&
TBDPath.empty();
}
};
} // namespace swift

Expand Down
2 changes: 1 addition & 1 deletion include/swift/Frontend/ArgsToFrontendOutputsConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
#include "swift/AST/DiagnosticConsumer.h"
#include "swift/AST/DiagnosticEngine.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/SupplementaryOutputPaths.h"
#include "swift/Frontend/FrontendOptions.h"
#include "swift/Frontend/SupplementaryOutputPaths.h"
#include "swift/Option/Options.h"
#include "llvm/Option/ArgList.h"

Expand Down
8 changes: 8 additions & 0 deletions include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ class CompilerInvocation {
bool hasSerializedAST() {
return FrontendOpts.InputKind == InputFileKind::IFK_Swift_Library;
}

PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary();
PrimarySpecificPaths getPrimarySpecificPathsForPrimary(StringRef filename);
};

/// A class which manages the state and execution of the compiler.
Expand Down Expand Up @@ -578,6 +581,11 @@ class CompilerInstance {
OptionSet<TypeCheckingFlags> TypeCheckOptions);

void finishTypeChecking(OptionSet<TypeCheckingFlags> TypeCheckOptions);

public:
PrimarySpecificPaths getPrimarySpecificPathsForWholeModuleOptimizationMode();
PrimarySpecificPaths getPrimarySpecificPathsForPrimary(StringRef filename);
PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary();
};

} // namespace swift
Expand Down
24 changes: 23 additions & 1 deletion include/swift/Frontend/FrontendInputsAndOutputs.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
#define SWIFT_FRONTEND_FRONTENDINPUTS_H

#include "swift/AST/Module.h"
#include "swift/Basic/PrimarySpecificPaths.h"
#include "swift/Basic/SupplementaryOutputPaths.h"
#include "swift/Frontend/InputFile.h"
#include "swift/Frontend/SupplementaryOutputPaths.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/MapVector.h"

Expand Down Expand Up @@ -57,6 +58,12 @@ class FrontendInputsAndOutputs {
return SupplementaryOutputs;
}

/// When performing a compilation for zero or one primary input file,
/// this will hold the PrimarySpecificPaths.
/// In a future PR, each InputFile will hold its own PrimarySpecificPaths and
/// this will go away.
PrimarySpecificPaths PrimarySpecificPathsForAtMostOnePrimary;

FrontendInputsAndOutputs() = default;
FrontendInputsAndOutputs(const FrontendInputsAndOutputs &other);
FrontendInputsAndOutputs &operator=(const FrontendInputsAndOutputs &other);
Expand Down Expand Up @@ -181,6 +188,10 @@ class FrontendInputsAndOutputs {
public:
unsigned countOfInputsProducingMainOutputs() const;

bool hasInputsProducingMainOutputs() const {
return countOfInputsProducingMainOutputs() != 0;
}

const InputFile &firstInputProducingOutput() const;
const InputFile &lastInputProducingOutput() const;

Expand Down Expand Up @@ -210,6 +221,17 @@ class FrontendInputsAndOutputs {
void forEachInputProducingSupplementaryOutput(
llvm::function_ref<void(const InputFile &)> fn) const;

/// Assumes there is not more than one primary input file, if any.
/// Otherwise, you would need to call getPrimarySpecificPathsForPrimary
/// to tell it which primary input you wanted the outputs for.
///
/// Must not be constructed on-the-fly because some parts of the compiler
/// receive StringRefs to its components, so it must live as long as the
/// compiler.
PrimarySpecificPaths &getPrimarySpecificPathsForAtMostOnePrimary();

PrimarySpecificPaths &getPrimarySpecificPathsForPrimary(StringRef filename);

bool hasDependenciesPath() const;
bool hasReferenceDependenciesPath() const;
bool hasObjCHeaderOutputPath() const;
Expand Down
3 changes: 3 additions & 0 deletions include/swift/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ class FrontendOptions {
InputsAndOutputs.hasSingleInput();
}

PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary();
PrimarySpecificPaths getPrimarySpecificPathsForPrimary(StringRef);

private:
static bool canActionEmitDependencies(ActionType);
static bool canActionEmitObjCHeader(ActionType);
Expand Down
4 changes: 3 additions & 1 deletion include/swift/IRGen/IRGenPublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class IRGenModule;

/// Create an IRGen module.
std::pair<IRGenerator *, IRGenModule *>
createIRGenModule(SILModule *SILMod, llvm::LLVMContext &LLVMContext);
createIRGenModule(SILModule *SILMod, StringRef OutputFilename,
StringRef MainInputFilenameForDebugInfo,
llvm::LLVMContext &LLVMContext);

/// Delete the IRGenModule and IRGenerator obtained by the above call.
void deleteIRGenModule(std::pair<IRGenerator *, IRGenModule *> &Module);
Expand Down
12 changes: 8 additions & 4 deletions include/swift/Subsystems.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "swift/Basic/LLVM.h"
#include "swift/Basic/OptionSet.h"
#include "swift/Basic/PrimarySpecificPaths.h"
#include "swift/Basic/Version.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/ADT/ArrayRef.h"
Expand Down Expand Up @@ -259,7 +260,9 @@ namespace swift {
std::unique_ptr<llvm::Module>
performIRGeneration(IRGenOptions &Opts, ModuleDecl *M,
std::unique_ptr<SILModule> SILMod,
StringRef ModuleName, llvm::LLVMContext &LLVMContext,
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
llvm::LLVMContext &LLVMContext,
ArrayRef<std::string> parallelOutputFilenames,
llvm::GlobalVariable **outModuleHash = nullptr);

/// Turn the given Swift module into either LLVM IR or native code
Expand All @@ -268,7 +271,8 @@ namespace swift {
std::unique_ptr<llvm::Module>
performIRGeneration(IRGenOptions &Opts, SourceFile &SF,
std::unique_ptr<SILModule> SILMod,
StringRef ModuleName, llvm::LLVMContext &LLVMContext,
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
llvm::LLVMContext &LLVMContext,
unsigned StartElem = 0,
llvm::GlobalVariable **outModuleHash = nullptr);

Expand All @@ -283,8 +287,8 @@ namespace swift {
StringRef OutputPath);

/// Turn the given LLVM module into native code and return true on error.
bool performLLVM(IRGenOptions &Opts, ASTContext &Ctx,
llvm::Module *Module,
bool performLLVM(IRGenOptions &Opts, ASTContext &Ctx, llvm::Module *Module,
StringRef OutputFilename,
UnifiedStatsReporter *Stats=nullptr);

/// Run the LLVM passes. In multi-threaded compilation this will be done for
Expand Down
12 changes: 0 additions & 12 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -829,18 +829,6 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
if (Args.hasArg(OPT_autolink_force_load))
Opts.ForceLoadSymbolName = Args.getLastArgValue(OPT_module_link_name);

// TODO: investigate whether these should be removed, in favor of definitions
// in other classes.
if (!SILOpts.SILOutputFileNameForDebugging.empty()) {
Opts.MainInputFilename = SILOpts.SILOutputFileNameForDebugging;
} else if (const InputFile *input =
FrontendOpts.InputsAndOutputs.getUniquePrimaryInput()) {
Opts.MainInputFilename = input->file();
} else if (FrontendOpts.InputsAndOutputs.hasSingleInput()) {
Opts.MainInputFilename =
FrontendOpts.InputsAndOutputs.getFilenameOfFirstInput();
}
Opts.OutputFilenames = FrontendOpts.InputsAndOutputs.copyOutputFilenames();
Opts.ModuleName = FrontendOpts.ModuleName;

if (Args.hasArg(OPT_use_jit))
Expand Down
23 changes: 23 additions & 0 deletions lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ std::string CompilerInvocation::getPCHHash() const {
return llvm::APInt(64, Code).toString(36, /*Signed=*/false);
}

PrimarySpecificPaths
CompilerInvocation::getPrimarySpecificPathsForAtMostOnePrimary() {
return getFrontendOptions().getPrimarySpecificPathsForAtMostOnePrimary();
}

PrimarySpecificPaths
CompilerInvocation::getPrimarySpecificPathsForPrimary(StringRef filename) {
return getFrontendOptions().getPrimarySpecificPathsForPrimary(filename);
}

void CompilerInstance::createSILModule() {
assert(MainModule && "main module not created yet");
// Assume WMO if a -primary-file option was not provided.
Expand Down Expand Up @@ -825,3 +835,16 @@ void CompilerInstance::freeASTContext() {
}

void CompilerInstance::freeSILModule() { TheSILModule.reset(); }

PrimarySpecificPaths
CompilerInstance::getPrimarySpecificPathsForWholeModuleOptimizationMode() {
return getPrimarySpecificPathsForAtMostOnePrimary();
}
PrimarySpecificPaths
CompilerInstance::getPrimarySpecificPathsForAtMostOnePrimary() {
return Invocation.getPrimarySpecificPathsForAtMostOnePrimary();
}
PrimarySpecificPaths
CompilerInstance::getPrimarySpecificPathsForPrimary(StringRef filename) {
return Invocation.getPrimarySpecificPathsForPrimary(filename);
}
28 changes: 28 additions & 0 deletions lib/Frontend/FrontendInputsAndOutputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "swift/Frontend/FrontendInputsAndOutputs.h"

#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/Basic/PrimarySpecificPaths.h"
#include "swift/Frontend/FrontendOptions.h"
#include "swift/Option/Options.h"
#include "swift/Parse/Lexer.h"
Expand All @@ -36,6 +37,8 @@ FrontendInputsAndOutputs::FrontendInputsAndOutputs(
addInput(input);
IsSingleThreadedWMO = other.IsSingleThreadedWMO;
SupplementaryOutputs = other.SupplementaryOutputs;
PrimarySpecificPathsForAtMostOnePrimary =
other.PrimarySpecificPathsForAtMostOnePrimary;
}

FrontendInputsAndOutputs &FrontendInputsAndOutputs::
Expand All @@ -45,6 +48,8 @@ operator=(const FrontendInputsAndOutputs &other) {
addInput(input);
IsSingleThreadedWMO = other.IsSingleThreadedWMO;
SupplementaryOutputs = other.SupplementaryOutputs;
PrimarySpecificPathsForAtMostOnePrimary =
other.PrimarySpecificPathsForAtMostOnePrimary;
return *this;
}

Expand Down Expand Up @@ -303,6 +308,18 @@ void FrontendInputsAndOutputs::setMainAndSupplementaryOutputs(
AllInputs[i].setOutputFilename(outputFiles[i]);
}
SupplementaryOutputs = supplementaryOutputs;

if (hasUniquePrimaryInput() || (hasInputs() && isWholeModule())) {
// When batch mode is fully implemented, each InputFile will own
// a PrimarySpecificPaths.
PrimarySpecificPathsForAtMostOnePrimary.OutputFilename =
getSingleOutputFilename();
PrimarySpecificPathsForAtMostOnePrimary.MainInputFilenameForDebugInfo =
hasInputsProducingMainOutputs() ? firstInputProducingOutput().file()
: StringRef();
PrimarySpecificPathsForAtMostOnePrimary.SupplementaryOutputs =
supplementaryOutputs;
}
}

std::vector<std::string> FrontendInputsAndOutputs::copyOutputFilenames() const {
Expand Down Expand Up @@ -379,3 +396,14 @@ bool FrontendInputsAndOutputs::hasDependencyTrackerPath() const {
return hasDependenciesPath() || hasReferenceDependenciesPath() ||
hasLoadedModuleTracePath();
}

PrimarySpecificPaths &
FrontendInputsAndOutputs::getPrimarySpecificPathsForAtMostOnePrimary() {
return PrimarySpecificPathsForAtMostOnePrimary;
}

PrimarySpecificPaths &
FrontendInputsAndOutputs::getPrimarySpecificPathsForPrimary(
StringRef filename) {
return getPrimarySpecificPathsForAtMostOnePrimary(); // just a stub for now
}
10 changes: 10 additions & 0 deletions lib/Frontend/FrontendOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,3 +386,13 @@ bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) {
return true;
}
}

PrimarySpecificPaths
FrontendOptions::getPrimarySpecificPathsForAtMostOnePrimary() {
return InputsAndOutputs.getPrimarySpecificPathsForAtMostOnePrimary();
}

PrimarySpecificPaths
FrontendOptions::getPrimarySpecificPathsForPrimary(StringRef filename) {
return InputsAndOutputs.getPrimarySpecificPathsForPrimary(filename);
}
Loading