@@ -279,7 +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
284
+ case externalDepNode = 5
285
+ case identifierNode = 6
283
286
284
287
/// The human-readable name of this record.
285
288
///
@@ -292,6 +295,12 @@ extension ModuleDependencyGraph {
292
295
return " METADATA "
293
296
case . moduleDepGraphNode:
294
297
return " MODULE_DEP_GRAPH_NODE "
298
+ case . dependsOnNode:
299
+ return " DEPENDS_ON_NODE "
300
+ case . useIDNode:
301
+ return " USE_ID_NODE "
302
+ case . externalDepNode:
303
+ return " EXTERNAL_DEP_NODE "
295
304
case . identifierNode:
296
305
return " IDENTIFIER_NODE "
297
306
}
@@ -306,6 +315,8 @@ extension ModuleDependencyGraph {
306
315
case malformedFingerprintRecord
307
316
case malformedIdentifierRecord
308
317
case malformedModuleDepGraphNodeRecord
318
+ case malformedDependsOnRecord
319
+ case malformedExternalDepNodeRecord
309
320
case unknownRecord
310
321
case unexpectedSubblock
311
322
case bogusNameOrContext
@@ -330,15 +341,16 @@ extension ModuleDependencyGraph {
330
341
let data = try fileSystem. readFileContents ( path)
331
342
332
343
struct Visitor : BitstreamVisitor {
333
- let graph : ModuleDependencyGraph
344
+ private let graph : ModuleDependencyGraph
334
345
var majorVersion : UInt64 ?
335
346
var minorVersion : UInt64 ?
336
347
var compilerVersionString : String ?
337
348
338
- private var node : Node ? = nil
339
349
// The empty string is hardcoded as identifiers[0]
340
350
private var identifiers : [ String ] = [ " " ]
341
- private var sequenceNumber = 0
351
+ private var currentDefKey : DependencyKey ? = nil
352
+ private var nodeUses : [ DependencyKey : [ Int ] ] = [ : ]
353
+ private var allNodes : [ Node ] = [ ]
342
354
343
355
init (
344
356
diagnosticEngine: DiagnosticsEngine ,
@@ -350,23 +362,31 @@ extension ModuleDependencyGraph {
350
362
verifyDependencyGraphAfterEveryImport: false )
351
363
}
352
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
+
353
376
func validate( signature: Bitcode . Signature ) throws {
354
- guard signature == . init( string: ModuleDependencyGraph . signature) else { throw ReadError . badMagic }
377
+ guard signature == . init( string: ModuleDependencyGraph . signature) else {
378
+ throw ReadError . badMagic
379
+ }
355
380
}
356
381
357
382
mutating func shouldEnterBlock( id: UInt64 ) throws -> Bool {
358
383
return true
359
384
}
360
385
361
- mutating func didExitBlock( ) throws {
362
- // Finalize the current node if needed.
363
- guard let newNode = node else {
364
- return
365
- }
366
- self . finalize ( node: newNode)
367
- }
386
+ mutating func didExitBlock( ) throws { }
368
387
369
- private func finalize( node newNode: Node ) {
388
+ private mutating func finalize( node newNode: Node ) {
389
+ self . allNodes. append ( newNode)
370
390
let oldNode = self . graph. nodeFinder. insert ( newNode)
371
391
assert ( oldNode == nil ,
372
392
" Integrated the same node twice: \( oldNode!) , \( newNode) " )
@@ -392,9 +412,6 @@ extension ModuleDependencyGraph {
392
412
self . minorVersion = record. fields [ 1 ]
393
413
self . compilerVersionString = compilerVersionString
394
414
case . moduleDepGraphNode:
395
- if let node = node {
396
- self . finalize ( node: node)
397
- }
398
415
let kindCode = record. fields [ 0 ]
399
416
guard record. fields. count == 7 ,
400
417
let declAspect = DependencyKey . DeclAspect ( record. fields [ 1 ] ) ,
@@ -417,10 +434,36 @@ extension ModuleDependencyGraph {
417
434
let swiftDeps = try swiftDepsStr
418
435
. map ( { try VirtualPath ( path: $0) } )
419
436
. map ( ModuleDependencyGraph . SwiftDeps. init)
420
- node = Node ( key: key,
421
- fingerprint: fingerprint,
422
- swiftDeps: swiftDeps)
423
- sequenceNumber += 1
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 ] ) )
459
+ case . externalDepNode:
460
+ guard record. fields. count == 1 ,
461
+ record. fields [ 0 ] < identifiers. count
462
+ else {
463
+ throw ReadError . malformedExternalDepNodeRecord
464
+ }
465
+ let path = identifiers [ Int ( record. fields [ 0 ] ) ]
466
+ self . graph. externalDependencies. insert ( ExternalDependency ( path) )
424
467
case . identifierNode:
425
468
guard record. fields. count == 0 ,
426
469
case . blob( let identifierBlob) = record. payload,
@@ -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,13 +629,84 @@ 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
+
641
+ for path in graph. externalDependencies {
642
+ self . addIdentifier ( path. fileName)
643
+ }
644
+
578
645
for str in self . identifiersToWrite {
579
646
self . stream. writeRecord ( self . abbreviations [ . identifierNode] !, {
580
647
$0. append ( RecordID . identifierNode)
581
648
} , blob: str)
582
649
}
583
650
}
584
651
652
+ private func registerAbbreviations( ) {
653
+ self . abbreviate ( . metadata, [
654
+ . literal( RecordID . metadata. rawValue) ,
655
+ // Major version
656
+ . fixed( bitWidth: 16 ) ,
657
+ // Minor version
658
+ . fixed( bitWidth: 16 ) ,
659
+ // Frontend version
660
+ . blob,
661
+ ] )
662
+ self . abbreviate ( . moduleDepGraphNode, [
663
+ . literal( RecordID . moduleDepGraphNode. rawValue) ,
664
+ // dependency kind discriminator
665
+ . fixed( bitWidth: 3 ) ,
666
+ // dependency decl aspect discriminator
667
+ . fixed( bitWidth: 1 ) ,
668
+ // dependency context
669
+ . vbr( chunkBitWidth: 13 ) ,
670
+ // dependency name
671
+ . vbr( chunkBitWidth: 13 ) ,
672
+ // swiftdeps?
673
+ . fixed( bitWidth: 1 ) ,
674
+ // swiftdeps path
675
+ . vbr( chunkBitWidth: 13 ) ,
676
+ // fingerprint?
677
+ . fixed( bitWidth: 1 ) ,
678
+ // fingerprint bytes
679
+ . blob,
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
+ ] )
698
+ self . abbreviate ( . externalDepNode, [
699
+ . literal( RecordID . externalDepNode. rawValue) ,
700
+ // path ID
701
+ . vbr( chunkBitWidth: 13 ) ,
702
+ ] )
703
+ self . abbreviate ( . identifierNode, [
704
+ . literal( RecordID . identifierNode. rawValue) ,
705
+ // identifier data
706
+ . blob
707
+ ] )
708
+ }
709
+
585
710
private func abbreviate(
586
711
_ record: RecordID ,
587
712
_ operands: [ Bitstream . Abbreviation . Operand ]
@@ -599,43 +724,11 @@ extension ModuleDependencyGraph {
599
724
serializer. writeBlockInfoBlock ( )
600
725
601
726
serializer. stream. withSubBlock ( . firstApplicationID, abbreviationBitWidth: 8 ) {
602
- serializer. abbreviate ( . metadata, [
603
- . literal( RecordID . metadata. rawValue) ,
604
- // Major version
605
- . fixed( bitWidth: 16 ) ,
606
- // Minor version
607
- . fixed( bitWidth: 16 ) ,
608
- // Frontend version
609
- . blob,
610
- ] )
611
- serializer. abbreviate ( . moduleDepGraphNode, [
612
- . literal( RecordID . moduleDepGraphNode. rawValue) ,
613
- // dependency kind discriminator
614
- . fixed( bitWidth: 3 ) ,
615
- // dependency decl aspect discriminator
616
- . fixed( bitWidth: 1 ) ,
617
- // dependency context
618
- . vbr( chunkBitWidth: 13 ) ,
619
- // dependency name
620
- . vbr( chunkBitWidth: 13 ) ,
621
- // swiftdeps?
622
- . fixed( bitWidth: 1 ) ,
623
- // swiftdeps path
624
- . vbr( chunkBitWidth: 13 ) ,
625
- // fingerprint?
626
- . fixed( bitWidth: 1 ) ,
627
- // fingerprint bytes
628
- . blob,
629
- ] )
630
- serializer. abbreviate ( . identifierNode, [
631
- . literal( RecordID . identifierNode. rawValue) ,
632
- // identifier data
633
- . blob
634
- ] )
727
+ serializer. registerAbbreviations ( )
635
728
636
729
serializer. writeMetadata ( )
637
730
638
- serializer. writeStrings ( in : graph)
731
+ serializer. populateCaches ( from : graph)
639
732
640
733
graph. nodeFinder. forEachNode { node in
641
734
serializer. stream. writeRecord ( serializer. abbreviations [ . moduleDepGraphNode] !, {
@@ -652,6 +745,35 @@ extension ModuleDependencyGraph {
652
745
$0. append ( ( node. fingerprint != nil ) ? UInt32 ( 1 ) : UInt32 ( 0 ) )
653
746
} , blob: node. fingerprint ?? " " )
654
747
}
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
+
771
+ for dep in graph. externalDependencies {
772
+ serializer. stream. writeRecord ( serializer. abbreviations [ . externalDepNode] !) {
773
+ $0. append ( RecordID . externalDepNode)
774
+ $0. append ( serializer. lookupIdentifierCode ( for: dep. fileName) )
775
+ }
776
+ }
655
777
}
656
778
return ByteString ( serializer. stream. data)
657
779
}
@@ -765,11 +887,11 @@ fileprivate extension DependencyKey.Designator {
765
887
case . dynamicLookup( name: let name) :
766
888
return name
767
889
case . externalDepend( let path) :
768
- return path. file ? . basename
890
+ return path. fileName
769
891
case . sourceFileProvide( name: let name) :
770
892
return name
771
893
case . incrementalExternalDependency( let path) :
772
- return path. file ? . basename
894
+ return path. fileName
773
895
case . member( context: _, name: let name) :
774
896
return name
775
897
case . nominal( context: _) :
0 commit comments