Skip to content

Commit 939034a

Browse files
author
David Ungar
authored
Merge pull request #29009 from davidungar/fine-grained-fixes-post-rb
[Incremental] Dependency fixes in preparation for fine-grained dependencies
2 parents b05a622 + ccb3840 commit 939034a

20 files changed

+1664
-347
lines changed

include/swift/AST/FineGrainedDependencies.h

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ class BiIndexedTwoStageMap {
325325
/// Write out the .swiftdeps file for a frontend compilation of a primary file.
326326
bool emitReferenceDependencies(DiagnosticEngine &diags, SourceFile *SF,
327327
const DependencyTracker &depTracker,
328-
StringRef outputPath);
328+
StringRef outputPath, bool alsoEmitDotFile);
329329
//==============================================================================
330330
// MARK: Enums
331331
//==============================================================================
@@ -438,8 +438,8 @@ class DependencyKey {
438438
name() {}
439439

440440
/// For constructing a key in the frontend.
441-
DependencyKey(NodeKind kind, DeclAspect aspect, std::string context,
442-
std::string name)
441+
DependencyKey(NodeKind kind, DeclAspect aspect, const std::string &context,
442+
const std::string &name)
443443
: kind(kind), aspect(aspect), context(context), name(name) {
444444
assert(verify());
445445
}
@@ -449,7 +449,7 @@ class DependencyKey {
449449
StringRef getContext() const { return context; }
450450
StringRef getName() const { return name; }
451451

452-
StringRef getSwiftDepsFromSourceFileProvide() const {
452+
StringRef getSwiftDepsFromASourceFileProvideNodeKey() const {
453453
assert(getKind() == NodeKind::sourceFileProvide &&
454454
"Receiver must be sourceFileProvide.");
455455
return getName();
@@ -494,11 +494,19 @@ class DependencyKey {
494494
static std::string computeNameForProvidedEntity(Entity);
495495

496496
/// Given some type of depended-upon entity create the key.
497-
template <NodeKind kind, typename Entity>
498-
static DependencyKey createDependedUponKey(const Entity &);
497+
static DependencyKey createDependedUponKey(StringRef mangledHolderName,
498+
StringRef memberBaseName);
499+
500+
template <NodeKind kind>
501+
static DependencyKey createDependedUponKey(StringRef);
502+
503+
static DependencyKey
504+
createTransitiveKeyForWholeSourceFile(StringRef swiftDeps);
499505

500506
std::string humanReadableName() const;
501507

508+
StringRef aspectName() const { return DeclAspectNames[size_t(aspect)]; }
509+
502510
void dump(llvm::raw_ostream &os) const { os << asString() << "\n"; }
503511
SWIFT_DEBUG_DUMP { dump(llvm::errs()); }
504512

@@ -535,6 +543,13 @@ struct std::hash<typename swift::fine_grained_dependencies::DeclAspect> {
535543
}
536544
};
537545

546+
namespace swift {
547+
namespace fine_grained_dependencies {
548+
using ContextNameFingerprint =
549+
std::tuple<std::string, std::string, Optional<std::string>>;
550+
}
551+
} // namespace swift
552+
538553
//==============================================================================
539554
// MARK: DepGraphNode
540555
//==============================================================================
@@ -684,6 +699,9 @@ class SourceFileDepGraphNode : public DepGraphNode {
684699
}
685700

686701
/// Record the sequence number, \p n, of another use.
702+
/// The relationship between an interface and its implementation is NOT
703+
/// included here. See \c
704+
/// SourceFileDepGraph::findExistingNodePairOrCreateAndAddIfNew.
687705
void addDefIDependUpon(size_t n) {
688706
if (n != getSequenceNumber())
689707
defsIDependUpon.insert(n);
@@ -727,6 +745,25 @@ class SourceFileDepGraph {
727745
SourceFileDepGraph(const SourceFileDepGraph &g) = delete;
728746
SourceFileDepGraph(SourceFileDepGraph &&g) = default;
729747

748+
/// Simulate loading for unit testing:
749+
/// \param swiftDepsFileName The name of the swiftdeps file of the phony job
750+
/// \param includePrivateDeps Whether the graph includes intra-file arcs
751+
/// \param hadCompilationError Simulate a compilation error
752+
/// \param interfaceHash The interface hash of the simulated graph
753+
/// \param simpleNamesByRDK A map of vectors of names keyed by reference
754+
/// dependency key \param compoundNamesByRDK A map of (mangledHolder,
755+
/// baseName) pairs keyed by reference dependency key. For single-name
756+
/// dependencies, an initial underscore indicates that the name does not
757+
/// cascade. For compound names, it is the first name, the holder which
758+
/// indicates non-cascading. For member names, an initial underscore indicates
759+
/// file-privacy.
760+
static SourceFileDepGraph
761+
simulateLoad(std::string swiftDepsFileName, const bool includePrivateDeps,
762+
const bool hadCompilationError, std::string interfaceHash,
763+
llvm::StringMap<std::vector<std::string>> simpleNamesByRDK,
764+
llvm::StringMap<std::vector<std::pair<std::string, std::string>>>
765+
compoundNamesByRDK);
766+
730767
/// Nodes are owned by the graph.
731768
~SourceFileDepGraph() {
732769
forEachNode([&](SourceFileDepGraphNode *n) { delete n; });
@@ -746,7 +783,7 @@ class SourceFileDepGraph {
746783
InterfaceAndImplementationPair<SourceFileDepGraphNode>
747784
getSourceFileNodePair() const;
748785

749-
StringRef getSwiftDepsFromSourceFileProvide() const;
786+
StringRef getSwiftDepsOfJobThatProducedThisGraph() const;
750787

751788
std::string getGraphID() const {
752789
return getSourceFileNodePair().getInterface()->getKey().humanReadableName();
@@ -770,12 +807,13 @@ class SourceFileDepGraph {
770807
/// The frontend creates a pair of nodes for every tracked Decl and the source
771808
/// file itself.
772809
InterfaceAndImplementationPair<SourceFileDepGraphNode>
773-
findExistingNodePairOrCreateAndAddIfNew(NodeKind k, StringRef context,
774-
StringRef name,
775-
Optional<std::string> fingerprint);
810+
findExistingNodePairOrCreateAndAddIfNew(
811+
NodeKind k, const ContextNameFingerprint &contextNameFingerprint);
776812

777-
SourceFileDepGraphNode *findExistingNodeOrCreateIfNew(
778-
DependencyKey key, Optional<std::string> fingerprint, bool isProvides);
813+
SourceFileDepGraphNode *
814+
findExistingNodeOrCreateIfNew(DependencyKey key,
815+
const Optional<std::string> &fingerprint,
816+
bool isProvides);
779817

780818
/// \p Use is the Node that must be rebuilt when \p def changes.
781819
/// Record that fact in the graph.
@@ -892,7 +930,7 @@ template <typename GraphT> class DotFileEmitter {
892930
}
893931
void emitArcs() {
894932
g.forEachArc([&](const NodeT *def, const NodeT *use) {
895-
if (includeGraphArc(use, def))
933+
if (includeGraphArc(def, use))
896934
emitGraphArc(def, use);
897935
});
898936
}

include/swift/Basic/LangOptions.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,14 @@ namespace swift {
282282
/// Whether to verify the parsed syntax tree and emit related diagnostics.
283283
bool VerifySyntaxTree = false;
284284

285-
/// Scaffolding to permit experimentation with finer-grained dependencies
286-
/// and faster rebuilds.
285+
/// Emit the newer, finer-grained swiftdeps file. Eventually will support
286+
/// faster rebuilds.
287287
bool EnableFineGrainedDependencies = false;
288-
288+
289+
/// When using fine-grained dependencies, emit dot files for every swiftdeps
290+
/// file.
291+
bool EmitFineGrainedDependencySourcefileDotFiles = false;
292+
289293
/// To mimic existing system, set to false.
290294
/// To experiment with including file-private and private dependency info,
291295
/// set to true.

include/swift/Driver/Action.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,23 @@ class CompileJobAction : public JobAction {
168168
static bool classof(const Action *A) {
169169
return A->getKind() == Action::Kind::CompileJob;
170170
}
171+
172+
/// Return a _single_ TY_Swift InputAction, if one exists;
173+
/// if 0 or >1 such inputs exist, return nullptr.
174+
const InputAction *findSingleSwiftInput() const {
175+
auto Inputs = getInputs();
176+
auto isSwiftInput = [](const Action *A) -> const InputAction* {
177+
if (auto const *S = dyn_cast<InputAction>(A))
178+
return S->getType() == file_types::TY_Swift ? S : nullptr;
179+
return nullptr;
180+
};
181+
const auto loc1 = std::find_if(Inputs.begin(), Inputs.end(), isSwiftInput);
182+
if (loc1 == Inputs.end())
183+
return nullptr; // none found
184+
// Ensure uniqueness
185+
const auto loc2 = std::find_if(loc1 + 1, Inputs.end(), isSwiftInput);
186+
return loc2 == Inputs.end() ? dyn_cast<InputAction>(*loc1) : nullptr;
187+
}
171188
};
172189

173190
class InterpretJobAction : public JobAction {

include/swift/Driver/Compilation.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,18 @@ class Compilation {
521521
/// How many .swift input files?
522522
unsigned countSwiftInputs() const;
523523

524+
/// Unfortunately the success or failure of a Swift compilation is currently
525+
/// sensitive to the order in which files are processed, at least in terms of
526+
/// the order of processing extensions (and likely other ways we haven't
527+
/// discovered yet). So long as this is true, we need to make sure any batch
528+
/// job we build names its inputs in an order that's a subsequence of the
529+
/// sequence of inputs the driver was initially invoked with.
530+
///
531+
/// Also use to write out information in a consistent order.
532+
void sortJobsToMatchCompilationInputs(
533+
ArrayRef<const Job *> unsortedJobs,
534+
SmallVectorImpl<const Job *> &sortedJobs) const;
535+
524536
private:
525537
/// Perform all jobs.
526538
///

0 commit comments

Comments
 (0)