Skip to content

[Batch mode]: Move SupplementaryOutputs into each InputFile and use the proper supplementary output. (7) #14702

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 1 commit into from
Feb 28, 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
23 changes: 18 additions & 5 deletions include/swift/Basic/PrimarySpecificPaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,39 @@

#include "swift/Basic/LLVM.h"
#include "swift/Basic/SupplementaryOutputPaths.h"
#include "llvm/ADT/StringRef.h"

#include <string>

namespace swift {

/// Holds all of the output paths, and debugging-info path that are
/// specific to which primary file is being compiled at the moment.

class PrimarySpecificPaths {
public:
/// The name of the main output file,
/// that is, the .o file for this input. If there is no such file, contains an
/// empty string. If the output is to be written to stdout, contains "-".
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())
PrimarySpecificPaths(StringRef OutputFilename = StringRef(),
StringRef MainInputFilenameForDebugInfo = StringRef(),
SupplementaryOutputPaths SupplementaryOutputs =
SupplementaryOutputPaths())
: OutputFilename(OutputFilename),
SupplementaryOutputs(SupplementaryOutputs),
MainInputFilenameForDebugInfo(MainInputFilenameForDebugInfo) {}

bool haveModuleOrModuleDocOutputPaths() const {
return !SupplementaryOutputs.ModuleOutputPath.empty() ||
!SupplementaryOutputs.ModuleDocOutputPath.empty();
}
};
} // namespace swift

Expand Down
12 changes: 12 additions & 0 deletions include/swift/Basic/SupplementaryOutputPaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,40 @@
namespace swift {
struct SupplementaryOutputPaths {
/// The path to which we should emit an Objective-C header for the module.
/// Currently only makes sense when the compiler has whole module knowledge.
/// The modes for which it makes sense incuide both WMO and the "merge
/// modules" job that happens after the normal compilation jobs. That's where
/// the header is emitted in single-file mode, since it needs whole-module
/// information.

std::string ObjCHeaderOutputPath;

/// The path to which we should emit a serialized module.
/// It is valid whenever there are any inputs.
std::string ModuleOutputPath;

/// The path to which we should emit a module documentation file.
/// It is valid whenever there are any inputs.
std::string ModuleDocOutputPath;

/// The path to which we should output a Make-style dependencies file.
/// It is valid whenever there are any inputs.
std::string DependenciesFilePath;

/// The path to which we should output a Swift reference dependencies file.
/// It is valid whenever there are any inputs.
std::string ReferenceDependenciesFilePath;

/// Path to a file which should contain serialized diagnostics for this
/// frontend invocation.
std::string SerializedDiagnosticsPath;

/// The path to which we should output a loaded module trace file.
/// It is currently only used with WMO, but could be generalized.
std::string LoadedModuleTracePath;

/// The path to which we should output a TBD file.
/// It is currently only used with WMO, but could be generalized.
std::string TBDPath;

SupplementaryOutputPaths() = default;
Expand Down
4 changes: 2 additions & 2 deletions include/swift/Frontend/ArgsToFrontendOutputsConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ArgsToFrontendOutputsConverter {
Diags(diags) {}

bool convert(std::vector<std::string> &mainOutputs,
SupplementaryOutputPaths &supplementaryOutputs);
std::vector<SupplementaryOutputPaths> &supplementaryOutputs);

/// Try to read an output file list file.
/// \returns `None` if it could not open the filelist.
Expand All @@ -57,7 +57,7 @@ class OutputFilesComputer {
const FrontendInputsAndOutputs &InputsAndOutputs;
const std::vector<std::string> OutputFileArguments;
const std::string OutputDirectoryArgument;
const StringRef FirstInput;
const std::string FirstInput;
const FrontendOptions::ActionType RequestedAction;
const llvm::opt::Arg *const ModuleNameArg;
const StringRef Suffix;
Expand Down
41 changes: 23 additions & 18 deletions include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,6 @@ class CompilerInvocation {
return SearchPathOpts.SDKPath;
}

void setSerializedDiagnosticsPath(StringRef Path) {
FrontendOpts.InputsAndOutputs.supplementaryOutputs()
.SerializedDiagnosticsPath = Path;
}
StringRef getSerializedDiagnosticsPath() const {
return FrontendOpts.InputsAndOutputs.supplementaryOutputs()
.SerializedDiagnosticsPath;
}

LangOptions &getLangOptions() {
return LangOpts;
}
Expand Down Expand Up @@ -245,8 +236,7 @@ class CompilerInvocation {
return FrontendOpts.ModuleName;
}


StringRef getOutputFilename() const {
std::string getOutputFilename() const {
return FrontendOpts.InputsAndOutputs.getSingleOutputFilename();
}

Expand Down Expand Up @@ -302,11 +292,25 @@ class CompilerInvocation {
return FrontendOpts.InputKind == InputFileKind::IFK_Swift_Library;
}

PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary() const;
PrimarySpecificPaths
const PrimarySpecificPaths &
getPrimarySpecificPathsForAtMostOnePrimary() const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForPrimary(StringRef filename) const;
PrimarySpecificPaths
const PrimarySpecificPaths &
getPrimarySpecificPathsForSourceFile(const SourceFile &SF) const;

std::string getOutputFilenameForAtMostOnePrimary() const;
std::string getMainInputFilenameForDebugInfoForAtMostOnePrimary() const;
std::string getObjCHeaderOutputPathForAtMostOnePrimary() const;
std::string getModuleOutputPathForAtMostOnePrimary() const;
std::string
getReferenceDependenciesFilePathForPrimary(StringRef filename) const;
std::string getSerializedDiagnosticsPathForAtMostOnePrimary() const;

/// TBDPath only makes sense in whole module compilation mode,
/// so return the TBDPath when in that mode and fail an assert
/// if not in that mode.
std::string getTBDPathForWholeModule() const;
};

/// A class which manages the state and execution of the compiler.
Expand Down Expand Up @@ -584,12 +588,13 @@ class CompilerInstance {
void finishTypeChecking(OptionSet<TypeCheckingFlags> TypeCheckOptions);

public:
PrimarySpecificPaths
const PrimarySpecificPaths &
getPrimarySpecificPathsForWholeModuleOptimizationMode() const;
PrimarySpecificPaths
const PrimarySpecificPaths &
getPrimarySpecificPathsForPrimary(StringRef filename) const;
PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary() const;
PrimarySpecificPaths
const PrimarySpecificPaths &
getPrimarySpecificPathsForAtMostOnePrimary() const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForSourceFile(const SourceFile &SF) const;
};

Expand Down
73 changes: 33 additions & 40 deletions include/swift/Frontend/FrontendInputsAndOutputs.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ class FrontendInputsAndOutputs {
friend class ArgsToFrontendInputsConverter;

std::vector<InputFile> AllInputs;

llvm::StringMap<unsigned> PrimaryInputs;
llvm::StringMap<unsigned> PrimaryInputsByName;
std::vector<unsigned> PrimaryInputsInOrder;

/// In Single-threaded WMO mode, all inputs are used
/// both for importing and compiling.
Expand All @@ -45,25 +45,10 @@ class FrontendInputsAndOutputs {
/// Punt where needed to enable batch mode experiments.
bool AreBatchModeChecksBypassed = false;

SupplementaryOutputPaths SupplementaryOutputs;

public:
bool areBatchModeChecksBypassed() const { return AreBatchModeChecksBypassed; }
void setBypassBatchModeChecks(bool bbc) { AreBatchModeChecksBypassed = bbc; }

const SupplementaryOutputPaths &supplementaryOutputs() const {
return SupplementaryOutputs;
}
SupplementaryOutputPaths &supplementaryOutputs() {
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 All @@ -88,6 +73,9 @@ class FrontendInputsAndOutputs {

std::vector<std::string> getInputFilenames() const;

/// \return nullptr if not a primary input file.
const InputFile *primaryInputNamed(StringRef name) const;

unsigned inputCount() const { return AllInputs.size(); }

bool hasInputs() const { return !AllInputs.empty(); }
Expand All @@ -99,21 +87,23 @@ class FrontendInputsAndOutputs {

const InputFile &lastInput() const { return AllInputs.back(); }

StringRef getFilenameOfFirstInput() const;
const std::string &getFilenameOfFirstInput() const;

bool isReadingFromStdin() const;

void forEachInput(llvm::function_ref<void(const InputFile &)> fn) const;
/// If \p fn returns true, exits early and returns true.
bool forEachInput(llvm::function_ref<bool(const InputFile &)> fn) const;

// Primaries:

const InputFile &firstPrimaryInput() const;
const InputFile &lastPrimaryInput() const;

void
forEachPrimaryInput(llvm::function_ref<void(const InputFile &)> fn) const;
/// If \p fn returns true, exit early and return true.
bool
forEachPrimaryInput(llvm::function_ref<bool(const InputFile &)> fn) const;

unsigned primaryInputCount() const { return PrimaryInputs.size(); }
unsigned primaryInputCount() const { return PrimaryInputsInOrder.size(); }

// Primary count readers:

Expand Down Expand Up @@ -143,11 +133,8 @@ class FrontendInputsAndOutputs {

const InputFile &getRequiredUniquePrimaryInput() const;

/// \return the name of the unique primary input, or an empty StrinRef if
/// there isn't one.
StringRef getNameOfUniquePrimaryInputFile() const;

/// Combines all primaries for stats reporter
/// FIXME: Should combine all primaries for the result
/// instead of just answering "batch" if there is more than one primary.
std::string getStatsFileMangledInputName() const;

bool isInputPrimary(StringRef file) const;
Expand Down Expand Up @@ -181,9 +168,9 @@ class FrontendInputsAndOutputs {
private:
friend class ArgsToFrontendOptionsConverter;

void
setMainAndSupplementaryOutputs(ArrayRef<std::string> outputFiles,
SupplementaryOutputPaths supplementaryOutputs);
void setMainAndSupplementaryOutputs(
ArrayRef<std::string> outputFiles,
ArrayRef<SupplementaryOutputPaths> supplementaryOutputs);

public:
unsigned countOfInputsProducingMainOutputs() const;
Expand All @@ -198,17 +185,18 @@ class FrontendInputsAndOutputs {
/// Under single-threaded WMO, we pretend that the first input
/// generates the main output, even though it will include code
/// generated from all of them.
void forEachInputProducingAMainOutputFile(
llvm::function_ref<void(const InputFile &)> fn) const;
///
/// If \p fn returns true, return early and return true.
bool forEachInputProducingAMainOutputFile(
llvm::function_ref<bool(const InputFile &)> fn) const;

std::vector<std::string> copyOutputFilenames() const;

void
forEachOutputFilename(llvm::function_ref<void(const std::string &)> fn) const;
void forEachOutputFilename(llvm::function_ref<void(StringRef)> fn) const;

/// Gets the name of the specified output filename.
/// If multiple files are specified, the last one is returned.
StringRef getSingleOutputFilename() const;
std::string getSingleOutputFilename() const;

bool isOutputFilenameStdout() const;
bool isOutputFileDirectory() const;
Expand All @@ -218,17 +206,22 @@ class FrontendInputsAndOutputs {

unsigned countOfFilesProducingSupplementaryOutput() const;

void forEachInputProducingSupplementaryOutput(
llvm::function_ref<void(const InputFile &)> fn) const;
/// If \p fn returns true, exit early and return true.
bool forEachInputProducingSupplementaryOutput(
llvm::function_ref<bool(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.
const PrimarySpecificPaths &
getPrimarySpecificPathsForAtMostOnePrimary() const;

PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary() const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForPrimary(StringRef) const;

PrimarySpecificPaths
getPrimarySpecificPathsForPrimary(StringRef filename) const;
bool hasSupplementaryOutputPath(
llvm::function_ref<const std::string &(const SupplementaryOutputPaths &)>
extractorFn) const;

bool hasDependenciesPath() const;
bool hasReferenceDependenciesPath() const;
Expand Down
10 changes: 5 additions & 5 deletions include/swift/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class FrontendOptions {
InputFileKind InputKind = InputFileKind::IFK_Swift;

void forAllOutputPaths(const InputFile &input,
std::function<void(const std::string &)> fn) const;
std::function<void(StringRef)> fn) const;

bool isOutputFileDirectory() const;

Expand Down Expand Up @@ -273,17 +273,17 @@ class FrontendOptions {
return llvm::hash_value(0);
}

StringRef originalPath() const;

StringRef determineFallbackModuleName() const;

bool isCompilingExactlyOneSwiftFile() const {
return InputKind == InputFileKind::IFK_Swift &&
InputsAndOutputs.hasSingleInput();
}

PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary() const;
PrimarySpecificPaths getPrimarySpecificPathsForPrimary(StringRef) const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForAtMostOnePrimary() const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForPrimary(StringRef) const;

private:
static bool canActionEmitDependencies(ActionType);
Expand Down
Loading