Fix ReferencedNameTracker in preparation for batch mode.

This commit is contained in:
David Ungar
2018-02-10 21:08:58 -08:00
parent e7ba87f613
commit 488db9fb9b
14 changed files with 113 additions and 114 deletions

View File

@@ -22,18 +22,19 @@
#include "swift/AST/Identifier.h"
#include "swift/AST/LookupKinds.h"
#include "swift/AST/RawComment.h"
#include "swift/AST/ReferencedNameTracker.h"
#include "swift/AST/Type.h"
#include "swift/Basic/Compiler.h"
#include "swift/Basic/OptionSet.h"
#include "swift/Basic/SourceLoc.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Basic/SourceLoc.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MD5.h"
@@ -811,7 +812,7 @@ private:
TypeRefinementContext *TRC = nullptr;
/// If non-null, used to track name lookups that happen within this file.
ReferencedNameTracker *ReferencedNames = nullptr;
Optional<ReferencedNameTracker> ReferencedNames;
/// The class in this file marked \@NS/UIApplicationMain.
ClassDecl *MainClass = nullptr;
@@ -966,13 +967,10 @@ public:
SourceLoc diagLoc = {});
/// @}
ReferencedNameTracker *getReferencedNameTracker() const {
return ReferencedNames;
}
void setReferencedNameTracker(ReferencedNameTracker *Tracker) {
assert(!ReferencedNames && "This file already has a name tracker.");
ReferencedNames = Tracker;
ReferencedNameTracker *getReferencedNameTracker() {
return ReferencedNames ? ReferencedNames.getPointer() : nullptr;
}
void createReferencedNameTracker();
/// \brief The buffer ID for the file that was imported, or None if there
/// is no associated buffer.

View File

@@ -302,8 +302,11 @@ public:
return FrontendOpts.InputKind == InputFileKind::IFK_Swift_Library;
}
PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary();
PrimarySpecificPaths getPrimarySpecificPathsForPrimary(StringRef filename);
PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary() const;
PrimarySpecificPaths
getPrimarySpecificPathsForPrimary(StringRef filename) const;
PrimarySpecificPaths
getPrimarySpecificPathsForSourceFile(const SourceFile &SF) const;
};
/// A class which manages the state and execution of the compiler.
@@ -322,7 +325,6 @@ class CompilerInstance {
std::unique_ptr<SILModule> TheSILModule;
DependencyTracker *DepTracker = nullptr;
ReferencedNameTracker *NameTracker = nullptr;
ModuleDecl *MainModule = nullptr;
SerializedModuleLoader *SML = nullptr;
@@ -393,14 +395,6 @@ public:
return DepTracker;
}
void setReferencedNameTracker(ReferencedNameTracker *tracker) {
assert(PrimarySourceFiles.empty() && "must be called before performSema()");
NameTracker = tracker;
}
ReferencedNameTracker *getReferencedNameTracker() {
return NameTracker;
}
/// Set the SIL module for this compilation instance.
///
/// The CompilerInstance takes ownership of the given SILModule object.
@@ -583,9 +577,13 @@ private:
void finishTypeChecking(OptionSet<TypeCheckingFlags> TypeCheckOptions);
public:
PrimarySpecificPaths getPrimarySpecificPathsForWholeModuleOptimizationMode();
PrimarySpecificPaths getPrimarySpecificPathsForPrimary(StringRef filename);
PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary();
PrimarySpecificPaths
getPrimarySpecificPathsForWholeModuleOptimizationMode() const;
PrimarySpecificPaths
getPrimarySpecificPathsForPrimary(StringRef filename) const;
PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary() const;
PrimarySpecificPaths
getPrimarySpecificPathsForSourceFile(const SourceFile &SF) const;
};
} // namespace swift

View File

@@ -224,13 +224,11 @@ public:
/// 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);
PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary() const;
PrimarySpecificPaths
getPrimarySpecificPathsForPrimary(StringRef filename) const;
bool hasDependenciesPath() const;
bool hasReferenceDependenciesPath() const;

View File

@@ -275,8 +275,8 @@ public:
InputsAndOutputs.hasSingleInput();
}
PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary();
PrimarySpecificPaths getPrimarySpecificPathsForPrimary(StringRef);
PrimarySpecificPaths getPrimarySpecificPathsForAtMostOnePrimary() const;
PrimarySpecificPaths getPrimarySpecificPathsForPrimary(StringRef) const;
private:
static bool canActionEmitDependencies(ActionType);

View File

@@ -1472,6 +1472,11 @@ void SourceFile::setTypeRefinementContext(TypeRefinementContext *Root) {
TRC = Root;
}
void SourceFile::createReferencedNameTracker() {
assert(!ReferencedNames && "This file already has a name tracker.");
ReferencedNames.emplace(ReferencedNameTracker());
}
//===----------------------------------------------------------------------===//
// Miscellaneous
//===----------------------------------------------------------------------===//

View File

@@ -54,15 +54,20 @@ std::string CompilerInvocation::getPCHHash() const {
}
PrimarySpecificPaths
CompilerInvocation::getPrimarySpecificPathsForAtMostOnePrimary() {
CompilerInvocation::getPrimarySpecificPathsForAtMostOnePrimary() const {
return getFrontendOptions().getPrimarySpecificPathsForAtMostOnePrimary();
}
PrimarySpecificPaths
CompilerInvocation::getPrimarySpecificPathsForPrimary(StringRef filename) {
PrimarySpecificPaths CompilerInvocation::getPrimarySpecificPathsForPrimary(
StringRef filename) const {
return getFrontendOptions().getPrimarySpecificPathsForPrimary(filename);
}
PrimarySpecificPaths CompilerInvocation::getPrimarySpecificPathsForSourceFile(
const SourceFile &SF) const {
return getPrimarySpecificPathsForPrimary(SF.getFilename());
}
void CompilerInstance::createSILModule() {
assert(MainModule && "main module not created yet");
// Assume WMO if a -primary-file option was not provided.
@@ -78,7 +83,7 @@ void CompilerInstance::recordPrimaryInputBuffer(unsigned BufID) {
void CompilerInstance::recordPrimarySourceFile(SourceFile *SF) {
assert(MainModule && "main module not created yet");
PrimarySourceFiles.push_back(SF);
SF->setReferencedNameTracker(NameTracker);
SF->createReferencedNameTracker();
if (SF->getBufferID().hasValue())
recordPrimaryInputBuffer(SF->getBufferID().getValue());
}
@@ -837,14 +842,19 @@ void CompilerInstance::freeASTContext() {
void CompilerInstance::freeSILModule() { TheSILModule.reset(); }
PrimarySpecificPaths
CompilerInstance::getPrimarySpecificPathsForWholeModuleOptimizationMode() {
CompilerInstance::getPrimarySpecificPathsForWholeModuleOptimizationMode()
const {
return getPrimarySpecificPathsForAtMostOnePrimary();
}
PrimarySpecificPaths
CompilerInstance::getPrimarySpecificPathsForAtMostOnePrimary() {
CompilerInstance::getPrimarySpecificPathsForAtMostOnePrimary() const {
return Invocation.getPrimarySpecificPathsForAtMostOnePrimary();
}
PrimarySpecificPaths
CompilerInstance::getPrimarySpecificPathsForPrimary(StringRef filename) {
CompilerInstance::getPrimarySpecificPathsForPrimary(StringRef filename) const {
return Invocation.getPrimarySpecificPathsForPrimary(filename);
}
PrimarySpecificPaths CompilerInstance::getPrimarySpecificPathsForSourceFile(
const SourceFile &SF) const {
return Invocation.getPrimarySpecificPathsForSourceFile(SF);
}

View File

@@ -397,13 +397,13 @@ bool FrontendInputsAndOutputs::hasDependencyTrackerPath() const {
hasLoadedModuleTracePath();
}
PrimarySpecificPaths &
FrontendInputsAndOutputs::getPrimarySpecificPathsForAtMostOnePrimary() {
PrimarySpecificPaths
FrontendInputsAndOutputs::getPrimarySpecificPathsForAtMostOnePrimary() const {
return PrimarySpecificPathsForAtMostOnePrimary;
}
PrimarySpecificPaths &
PrimarySpecificPaths
FrontendInputsAndOutputs::getPrimarySpecificPathsForPrimary(
StringRef filename) {
StringRef filename) const {
return getPrimarySpecificPathsForAtMostOnePrimary(); // just a stub for now
}

View File

@@ -388,11 +388,11 @@ bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) {
}
PrimarySpecificPaths
FrontendOptions::getPrimarySpecificPathsForAtMostOnePrimary() {
FrontendOptions::getPrimarySpecificPathsForAtMostOnePrimary() const {
return InputsAndOutputs.getPrimarySpecificPathsForAtMostOnePrimary();
}
PrimarySpecificPaths
FrontendOptions::getPrimarySpecificPathsForPrimary(StringRef filename) {
FrontendOptions::getPrimarySpecificPathsForPrimary(StringRef filename) const {
return InputsAndOutputs.getPrimarySpecificPathsForPrimary(filename);
}

View File

@@ -298,7 +298,7 @@ static bool writeSIL(SILModule &SM, ModuleDecl *M, bool EmitVerboseSIL,
return false;
}
static bool writeSIL(SILModule &SM, const PrimarySpecificPaths PSPs,
static bool writeSIL(SILModule &SM, const PrimarySpecificPaths &PSPs,
CompilerInstance &Instance,
CompilerInvocation &Invocation) {
const FrontendOptions &opts = Invocation.getFrontendOptions();
@@ -482,10 +482,12 @@ static void countStatsPostSema(UnifiedStatsReporter &Stats,
C.NumDependencies = D->getDependencies().size();
}
if (auto *R = Instance.getReferencedNameTracker()) {
C.NumReferencedTopLevelNames = R->getTopLevelNames().size();
C.NumReferencedDynamicNames = R->getDynamicLookupNames().size();
C.NumReferencedMemberNames = R->getUsedMembers().size();
for (auto SF : Instance.getPrimarySourceFiles()) {
if (auto *R = SF->getReferencedNameTracker()) {
C.NumReferencedTopLevelNames += R->getTopLevelNames().size();
C.NumReferencedDynamicNames += R->getDynamicLookupNames().size();
C.NumReferencedMemberNames += R->getUsedMembers().size();
}
}
if (!Instance.getPrimarySourceFiles().empty()) {
@@ -734,8 +736,8 @@ static Optional<bool> dumpASTIfNeeded(CompilerInvocation &Invocation,
return Context.hadError();
}
static void emitReferenceDependenciesIfNeeded(CompilerInvocation &Invocation,
CompilerInstance &Instance) {
static void emitReferenceDependenciesForAllPrimaryInputsIfNeeded(
CompilerInvocation &Invocation, CompilerInstance &Instance) {
if (Invocation.getFrontendOptions()
.InputsAndOutputs.supplementaryOutputs()
.ReferenceDependenciesFilePath.empty())
@@ -746,9 +748,12 @@ static void emitReferenceDependenciesIfNeeded(CompilerInvocation &Invocation,
return;
}
for (auto *SF : Instance.getPrimarySourceFiles()) {
emitReferenceDependencies(Instance.getASTContext().Diags, SF,
std::string referenceDependenciesFilePath =
Invocation.getPrimarySpecificPathsForSourceFile(*SF)
.SupplementaryOutputs.ReferenceDependenciesFilePath;
emitReferenceDependenciesIfNeeded(Instance.getASTContext().Diags, SF,
*Instance.getDependencyTracker(),
Invocation.getFrontendOptions());
referenceDependenciesFilePath);
}
}
@@ -804,7 +809,7 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) {
auto SM = performSILGeneration(*PrimaryFile, SILOpts, None);
std::deque<PostSILGenInputs> PSGIs;
const PrimarySpecificPaths PSPs =
Instance.getPrimarySpecificPathsForPrimary(PrimaryFile->getFilename());
Instance.getPrimarySpecificPathsForSourceFile(*PrimaryFile);
PSGIs.push_back(PostSILGenInputs{std::move(SM), true, PrimaryFile, PSPs});
return PSGIs;
}
@@ -826,15 +831,11 @@ generateSILModules(CompilerInvocation &Invocation, CompilerInstance &Instance) {
return PSGIs;
}
static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
CompilerInvocation &Invocation,
std::unique_ptr<SILModule> SM,
bool astGuaranteedToCorrespondToSIL,
ModuleOrSourceFile MSF,
PrimarySpecificPaths PSPs,
bool moduleIsPublic,
int &ReturnValue,
FrontendObserver *observer,
static bool performCompileStepsPostSILGen(
CompilerInstance &Instance, CompilerInvocation &Invocation,
std::unique_ptr<SILModule> SM, bool astGuaranteedToCorrespondToSIL,
ModuleOrSourceFile MSF, const PrimarySpecificPaths &PSPs,
bool moduleIsPublic, int &ReturnValue, FrontendObserver *observer,
UnifiedStatsReporter *Stats);
/// Performs the compile requested by the user.
@@ -863,11 +864,6 @@ static bool performCompile(CompilerInstance &Instance,
if (Invocation.getInputKind() == InputFileKind::IFK_LLVM_IR)
return compileLLVMIR(Invocation, Instance, Stats);
ReferencedNameTracker nameTracker;
if (!opts.InputsAndOutputs.supplementaryOutputs()
.ReferenceDependenciesFilePath.empty())
Instance.setReferencedNameTracker(&nameTracker);
if (FrontendOptions::shouldActionOnlyParse(Action))
Instance.performParseOnly();
else
@@ -914,7 +910,7 @@ static bool performCompile(CompilerInstance &Instance,
(void)emitMakeDependencies(Context.Diags, *Instance.getDependencyTracker(),
opts);
emitReferenceDependenciesIfNeeded(Invocation, Instance);
emitReferenceDependenciesForAllPrimaryInputsIfNeeded(Invocation, Instance);
(void)emitLoadedModuleTraceIfNeeded(Context, Instance.getDependencyTracker(),
opts);
@@ -1177,15 +1173,11 @@ static bool generateCode(CompilerInvocation &Invocation,
EffectiveLanguageVersion, OutputFilename, Stats);
}
static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
CompilerInvocation &Invocation,
std::unique_ptr<SILModule> SM,
bool astGuaranteedToCorrespondToSIL,
ModuleOrSourceFile MSF,
const PrimarySpecificPaths PSPs,
bool moduleIsPublic,
int &ReturnValue,
FrontendObserver *observer,
static bool performCompileStepsPostSILGen(
CompilerInstance &Instance, CompilerInvocation &Invocation,
std::unique_ptr<SILModule> SM, bool astGuaranteedToCorrespondToSIL,
ModuleOrSourceFile MSF, const PrimarySpecificPaths &PSPs,
bool moduleIsPublic, int &ReturnValue, FrontendObserver *observer,
UnifiedStatsReporter *Stats) {
FrontendOptions opts = Invocation.getFrontendOptions();

View File

@@ -123,30 +123,30 @@ swift::reversePathSortedFilenames(const ArrayRef<std::string> elts) {
return tmp;
}
bool swift::emitReferenceDependencies(DiagnosticEngine &diags,
bool swift::emitReferenceDependenciesIfNeeded(DiagnosticEngine &diags,
SourceFile *SF,
DependencyTracker &depTracker,
const FrontendOptions &opts) {
StringRef outputPath) {
assert(SF && "Cannot emit reference dependencies without a SourceFile");
const ReferencedNameTracker *const tracker = SF->getReferencedNameTracker();
if (!tracker) {
assert(outputPath.empty());
return false;
}
assert(!outputPath.empty());
// Before writing to the dependencies file path, preserve any previous file
// that may have been there. No error handling -- this is just a nicety, it
// doesn't matter if it fails.
llvm::sys::fs::rename(opts.InputsAndOutputs.supplementaryOutputs()
.ReferenceDependenciesFilePath,
opts.InputsAndOutputs.supplementaryOutputs()
.ReferenceDependenciesFilePath +
"~");
llvm::sys::fs::rename(outputPath, outputPath + "~");
std::error_code EC;
llvm::raw_fd_ostream out(opts.InputsAndOutputs.supplementaryOutputs()
.ReferenceDependenciesFilePath,
EC, llvm::sys::fs::F_None);
llvm::raw_fd_ostream out(outputPath, EC, llvm::sys::fs::F_None);
if (out.has_error() || EC) {
diags.diagnose(SourceLoc(), diag::error_opening_output,
opts.InputsAndOutputs.supplementaryOutputs()
.ReferenceDependenciesFilePath,
diags.diagnose(SourceLoc(), diag::error_opening_output, outputPath,
EC.message());
out.clear_error();
return true;
@@ -330,8 +330,6 @@ bool swift::emitReferenceDependencies(DiagnosticEngine &diags,
}
}
ReferencedNameTracker *tracker = SF->getReferencedNameTracker();
auto sortedByName =
[](const llvm::DenseMap<DeclBaseName, bool> map) ->
SmallVector<std::pair<DeclBaseName, bool>, 16> {

View File

@@ -13,9 +13,10 @@
#ifndef SWIFT_FRONTENDTOOL_REFERENCEDEPENDENCIES_H
#define SWIFT_FRONTENDTOOL_REFERENCEDEPENDENCIES_H
#include "swift/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include <vector>
#include <string>
#include <vector>
namespace swift {
@@ -31,10 +32,9 @@ std::vector<std::string>
reversePathSortedFilenames(const llvm::ArrayRef<std::string> paths);
/// Emit a Swift-style dependencies file for \p SF.
bool emitReferenceDependencies(DiagnosticEngine &diags,
SourceFile *SF,
bool emitReferenceDependenciesIfNeeded(DiagnosticEngine &diags, SourceFile *SF,
DependencyTracker &depTracker,
const FrontendOptions &opts);
StringRef outputPath);
} // end namespace swift
#endif

View File

@@ -260,12 +260,12 @@ bool swift::immediate::IRGenImportedModules(
}
runSILLoweringPasses(*SILMod);
const auto PSPs = CI.getPrimarySpecificPathsForAtMostOnePrimary();
// FIXME: We shouldn't need to use the global context here, but
// something is persisting across calls to performIRGeneration.
auto SubModule = performIRGeneration(
IRGenOpts, import, std::move(SILMod), import->getName().str(),
CI.getPrimarySpecificPathsForAtMostOnePrimary(), getGlobalLLVMContext(),
ArrayRef<std::string>());
IRGenOpts, import, std::move(SILMod), import->getName().str(), PSPs,
getGlobalLLVMContext(), ArrayRef<std::string>());
if (CI.getASTContext().hadError()) {
hadError = true;
@@ -299,12 +299,12 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
// IRGen the main module.
auto *swiftModule = CI.getMainModule();
const auto PSPs = CI.getPrimarySpecificPathsForAtMostOnePrimary();
// FIXME: We shouldn't need to use the global context here, but
// something is persisting across calls to performIRGeneration.
auto ModuleOwner = performIRGeneration(
IRGenOpts, swiftModule, CI.takeSILModule(), swiftModule->getName().str(),
CI.getPrimarySpecificPathsForAtMostOnePrimary(), getGlobalLLVMContext(),
ArrayRef<std::string>());
PSPs, getGlobalLLVMContext(), ArrayRef<std::string>());
auto *Module = ModuleOwner.get();
if (Context.hadError())

View File

@@ -900,10 +900,10 @@ private:
// IRGen the current line(s).
// FIXME: We shouldn't need to use the global context here, but
// something is persisting across calls to performIRGeneration.
const auto PSPs = CI.getPrimarySpecificPathsForAtMostOnePrimary();
auto LineModule = performIRGeneration(
IRGenOpts, REPLInputFile, std::move(sil), "REPLLine",
CI.getPrimarySpecificPathsForAtMostOnePrimary(), getGlobalLLVMContext(),
RC.CurIRGenElem);
IRGenOpts, REPLInputFile, std::move(sil), "REPLLine", PSPs,
getGlobalLLVMContext(), RC.CurIRGenElem);
RC.CurIRGenElem = RC.CurElem;
if (CI.getASTContext().hadError())

View File

@@ -204,7 +204,7 @@ int main(int argc, char **argv) {
SL->getAll();
}
PrimarySpecificPaths PSPs(OutputFilename, InputFilename);
const PrimarySpecificPaths PSPs(OutputFilename, InputFilename);
std::unique_ptr<llvm::Module> Mod =
performIRGeneration(Opts, CI.getMainModule(), CI.takeSILModule(),
CI.getMainModule()->getName().str(),