@@ -279,8 +279,10 @@ extension ModuleDependencyGraph {
279
279
fileprivate enum RecordID : UInt64 {
280
280
case metadata = 1
281
281
case moduleDepGraphNode = 2
282
- case identifierNode = 3
282
+ case dependsOnNode = 3
283
+ case useIDNode = 4
283
284
case externalDepNode = 5
285
+ case identifierNode = 6
284
286
285
287
/// The human-readable name of this record.
286
288
///
@@ -293,6 +295,10 @@ extension ModuleDependencyGraph {
293
295
return " METADATA "
294
296
case . moduleDepGraphNode:
295
297
return " MODULE_DEP_GRAPH_NODE "
298
+ case . dependsOnNode:
299
+ return " DEPENDS_ON_NODE "
300
+ case . useIDNode:
301
+ return " USE_ID_NODE "
296
302
case . externalDepNode:
297
303
return " EXTERNAL_DEP_NODE "
298
304
case . identifierNode:
@@ -309,6 +315,7 @@ extension ModuleDependencyGraph {
309
315
case malformedFingerprintRecord
310
316
case malformedIdentifierRecord
311
317
case malformedModuleDepGraphNodeRecord
318
+ case malformedDependsOnRecord
312
319
case malformedExternalDepNodeRecord
313
320
case unknownRecord
314
321
case unexpectedSubblock
@@ -334,13 +341,16 @@ extension ModuleDependencyGraph {
334
341
let data = try fileSystem. readFileContents ( path)
335
342
336
343
struct Visitor : BitstreamVisitor {
337
- let graph : ModuleDependencyGraph
344
+ private let graph : ModuleDependencyGraph
338
345
var majorVersion : UInt64 ?
339
346
var minorVersion : UInt64 ?
340
347
var compilerVersionString : String ?
341
348
342
349
// The empty string is hardcoded as identifiers[0]
343
350
private var identifiers : [ String ] = [ " " ]
351
+ private var currentDefKey : DependencyKey ? = nil
352
+ private var nodeUses : [ DependencyKey : [ Int ] ] = [ : ]
353
+ private var allNodes : [ Node ] = [ ]
344
354
345
355
init (
346
356
diagnosticEngine: DiagnosticsEngine ,
@@ -352,8 +362,21 @@ extension ModuleDependencyGraph {
352
362
verifyDependencyGraphAfterEveryImport: false )
353
363
}
354
364
365
+ func finalizeGraph( ) -> ModuleDependencyGraph {
366
+ for (dependencyKey, useIDs) in self . nodeUses {
367
+ for useID in useIDs {
368
+ let isNewUse = self . graph. nodeFinder
369
+ . record ( def: dependencyKey, use: self . allNodes [ useID] )
370
+ assert ( isNewUse, " Duplicate use def-use arc in graph? " )
371
+ }
372
+ }
373
+ return self . graph
374
+ }
375
+
355
376
func validate( signature: Bitcode . Signature ) throws {
356
- guard signature == . init( string: ModuleDependencyGraph . signature) else { throw ReadError . badMagic }
377
+ guard signature == . init( string: ModuleDependencyGraph . signature) else {
378
+ throw ReadError . badMagic
379
+ }
357
380
}
358
381
359
382
mutating func shouldEnterBlock( id: UInt64 ) throws -> Bool {
@@ -362,7 +385,8 @@ extension ModuleDependencyGraph {
362
385
363
386
mutating func didExitBlock( ) throws { }
364
387
365
- private func finalize( node newNode: Node ) {
388
+ private mutating func finalize( node newNode: Node ) {
389
+ self . allNodes. append ( newNode)
366
390
let oldNode = self . graph. nodeFinder. insert ( newNode)
367
391
assert ( oldNode == nil ,
368
392
" Integrated the same node twice: \( oldNode!) , \( newNode) " )
@@ -388,9 +412,6 @@ extension ModuleDependencyGraph {
388
412
self . minorVersion = record. fields [ 1 ]
389
413
self . compilerVersionString = compilerVersionString
390
414
case . moduleDepGraphNode:
391
- if let node = node {
392
- self . finalize ( node: node)
393
- }
394
415
let kindCode = record. fields [ 0 ]
395
416
guard record. fields. count == 7 ,
396
417
let declAspect = DependencyKey . DeclAspect ( record. fields [ 1 ] ) ,
@@ -413,6 +434,28 @@ extension ModuleDependencyGraph {
413
434
let swiftDeps = try swiftDepsStr
414
435
. map ( { try VirtualPath ( path: $0) } )
415
436
. map ( ModuleDependencyGraph . SwiftDeps. init)
437
+ self . finalize ( node: Node ( key: key,
438
+ fingerprint: fingerprint,
439
+ swiftDeps: swiftDeps) )
440
+ case . dependsOnNode:
441
+ let kindCode = record. fields [ 0 ]
442
+ guard record. fields. count == 4 ,
443
+ let declAspect = DependencyKey . DeclAspect ( record. fields [ 1 ] ) ,
444
+ record. fields [ 2 ] < identifiers. count,
445
+ record. fields [ 3 ] < identifiers. count
446
+ else {
447
+ throw ReadError . malformedDependsOnRecord
448
+ }
449
+ let context = identifiers [ Int ( record. fields [ 2 ] ) ]
450
+ let identifier = identifiers [ Int ( record. fields [ 3 ] ) ]
451
+ let designator = try DependencyKey . Designator (
452
+ kindCode: kindCode, context: context, name: identifier)
453
+ self . currentDefKey = DependencyKey ( aspect: declAspect, designator: designator)
454
+ case . useIDNode:
455
+ guard let key = self . currentDefKey, record. fields. count == 1 else {
456
+ throw ReadError . malformedDependsOnRecord
457
+ }
458
+ self . nodeUses [ key, default: [ ] ] . append ( Int ( record. fields [ 0 ] ) )
416
459
case . externalDepNode:
417
460
guard record. fields. count == 1 ,
418
461
record. fields [ 0 ] < identifiers. count
@@ -448,7 +491,7 @@ extension ModuleDependencyGraph {
448
491
else {
449
492
throw ReadError . malformedMetadataRecord
450
493
}
451
- return visitor. graph
494
+ return visitor. finalizeGraph ( )
452
495
}
453
496
}
454
497
}
@@ -491,6 +534,8 @@ extension ModuleDependencyGraph {
491
534
private var identifiersToWrite = [ String] ( )
492
535
private var identifierIDs = [ String: Int] ( )
493
536
private var lastIdentifierID : Int = 1
537
+ fileprivate private( set) var nodeIDs = [ Node: Int] ( )
538
+ private var lastNodeID : Int = 0
494
539
495
540
private init ( compilerVersion: String ) {
496
541
self . compilerVersion = compilerVersion
@@ -529,6 +574,8 @@ extension ModuleDependencyGraph {
529
574
self . emitBlockID ( . firstApplicationID, " RECORD_BLOCK " )
530
575
self . emitRecordID ( . metadata)
531
576
self . emitRecordID ( . moduleDepGraphNode)
577
+ self . emitRecordID ( . useIDNode)
578
+ self . emitRecordID ( . externalDepNode)
532
579
self . emitRecordID ( . identifierNode)
533
580
}
534
581
}
@@ -562,8 +609,15 @@ extension ModuleDependencyGraph {
562
609
return UInt32 ( self . identifierIDs [ string] !)
563
610
}
564
611
565
- private func writeStrings( in graph: ModuleDependencyGraph ) {
612
+ private func cacheNodeID( for node: Node ) {
613
+ defer { self . lastNodeID += 1 }
614
+ nodeIDs [ node] = self . lastNodeID
615
+ }
616
+
617
+ private func populateCaches( from graph: ModuleDependencyGraph ) {
566
618
graph. nodeFinder. forEachNode { node in
619
+ self . cacheNodeID ( for: node)
620
+
567
621
if let swiftDeps = node. swiftDeps? . file. name {
568
622
self . addIdentifier ( swiftDeps)
569
623
}
@@ -575,6 +629,15 @@ extension ModuleDependencyGraph {
575
629
}
576
630
}
577
631
632
+ for key in graph. nodeFinder. usesByDef. keys {
633
+ if let context = key. designator. context {
634
+ self . addIdentifier ( context)
635
+ }
636
+ if let name = key. designator. name {
637
+ self . addIdentifier ( name)
638
+ }
639
+ }
640
+
578
641
for path in graph. externalDependencies {
579
642
self . addIdentifier ( path. fileName)
580
643
}
@@ -615,6 +678,23 @@ extension ModuleDependencyGraph {
615
678
// fingerprint bytes
616
679
. blob,
617
680
] )
681
+ self . abbreviate ( . dependsOnNode, [
682
+ . literal( RecordID . dependsOnNode. rawValue) ,
683
+ // dependency kind discriminator
684
+ . fixed( bitWidth: 3 ) ,
685
+ // dependency decl aspect discriminator
686
+ . fixed( bitWidth: 1 ) ,
687
+ // dependency context
688
+ . vbr( chunkBitWidth: 13 ) ,
689
+ // dependency name
690
+ . vbr( chunkBitWidth: 13 ) ,
691
+ ] )
692
+
693
+ self . abbreviate ( . useIDNode, [
694
+ . literal( RecordID . useIDNode. rawValue) ,
695
+ // node ID
696
+ . vbr( chunkBitWidth: 13 ) ,
697
+ ] )
618
698
self . abbreviate ( . externalDepNode, [
619
699
. literal( RecordID . externalDepNode. rawValue) ,
620
700
// path ID
@@ -648,7 +728,7 @@ extension ModuleDependencyGraph {
648
728
649
729
serializer. writeMetadata ( )
650
730
651
- serializer. writeStrings ( in : graph)
731
+ serializer. populateCaches ( from : graph)
652
732
653
733
graph. nodeFinder. forEachNode { node in
654
734
serializer. stream. writeRecord ( serializer. abbreviations [ . moduleDepGraphNode] !, {
@@ -666,6 +746,28 @@ extension ModuleDependencyGraph {
666
746
} , blob: node. fingerprint ?? " " )
667
747
}
668
748
749
+ for key in graph. nodeFinder. usesByDef. keys {
750
+ serializer. stream. writeRecord ( serializer. abbreviations [ . dependsOnNode] !) {
751
+ $0. append ( RecordID . dependsOnNode)
752
+ $0. append ( key. designator. code)
753
+ $0. append ( key. aspect. code)
754
+ $0. append ( serializer. lookupIdentifierCode (
755
+ for: key. designator. context ?? " " ) )
756
+ $0. append ( serializer. lookupIdentifierCode (
757
+ for: key. designator. name ?? " " ) )
758
+ }
759
+ for use in graph. nodeFinder. usesByDef [ key] ? . values ?? [ ] {
760
+ guard let useID = serializer. nodeIDs [ use] else {
761
+ fatalError ( " Node ID was not registered! \( use) " )
762
+ }
763
+
764
+ serializer. stream. writeRecord ( serializer. abbreviations [ . useIDNode] !) {
765
+ $0. append ( RecordID . useIDNode)
766
+ $0. append ( UInt32 ( useID) )
767
+ }
768
+ }
769
+ }
770
+
669
771
for dep in graph. externalDependencies {
670
772
serializer. stream. writeRecord ( serializer. abbreviations [ . externalDepNode] !) {
671
773
$0. append ( RecordID . externalDepNode)
0 commit comments