@@ -27,9 +27,9 @@ import SIL
27
27
28
28
private let verbose = false
29
29
30
- private func log( _ message: @autoclosure ( ) -> String ) {
30
+ private func log( prefix : Bool = true , _ message: @autoclosure ( ) -> String ) {
31
31
if verbose {
32
- print ( " ### \( message ( ) ) " )
32
+ debugLog ( prefix : prefix , message ( ) )
33
33
}
34
34
}
35
35
@@ -226,7 +226,7 @@ class LocalVariableAccessInfo: CustomStringConvertible {
226
226
}
227
227
228
228
var description : String {
229
- return " full- assign: \( _isFullyAssigned == nil ? " unknown " : String ( describing: _isFullyAssigned!) ) , "
229
+ return " assign: \( _isFullyAssigned == nil ? " unknown " : String ( describing: _isFullyAssigned!) ) , "
230
230
+ " \( access) "
231
231
}
232
232
@@ -329,7 +329,7 @@ struct LocalVariableAccessMap: Collection, CustomStringConvertible {
329
329
subscript( instruction: Instruction ) -> LocalVariableAccessInfo ? { accessMap [ instruction] }
330
330
331
331
var description : String {
332
- " Access map: \n " + map( { String ( describing: $0) } ) . joined ( separator: " \n " )
332
+ " Access map for: \( allocation ) \n " + map( { String ( describing: $0) } ) . joined ( separator: " \n " )
333
333
}
334
334
}
335
335
@@ -699,6 +699,7 @@ extension LocalVariableReachableAccess {
699
699
case . escape:
700
700
break
701
701
}
702
+ break
702
703
}
703
704
return currentEffect
704
705
}
@@ -808,8 +809,8 @@ extension LocalVariableReachableAccess {
808
809
forwardPropagateEffect ( in: block, blockInfo: blockInfo, effect: currentEffect, blockList: & blockList,
809
810
accessStack: & accessStack)
810
811
}
811
- log ( " \( accessMap) " )
812
- log ( " Reachable access: \n \( accessStack. map ( { String ( describing: $0) } ) . joined ( separator: " \n " ) ) " )
812
+ log ( " \n \ ( accessMap) " )
813
+ log ( prefix : false , " Reachable access: \n \( accessStack. map ( { String ( describing: $0) } ) . joined ( separator: " \n " ) ) " )
813
814
return true
814
815
}
815
816
@@ -873,7 +874,7 @@ extension LocalVariableReachableAccess {
873
874
private func findAllEscapesPriorToAccess( ) {
874
875
var visitedBlocks = BasicBlockSet ( context)
875
876
var escapedBlocks = BasicBlockSet ( context)
876
- var blockList = BasicBlockWorklist ( context)
877
+ var blockList = Stack < BasicBlock > ( context)
877
878
defer {
878
879
visitedBlocks. deinitialize ( )
879
880
escapedBlocks. deinitialize ( )
@@ -886,19 +887,19 @@ extension LocalVariableReachableAccess {
886
887
for successor in from. successors {
887
888
if hasEscaped {
888
889
if escapedBlocks. insert ( successor) {
889
- blockList. pushIfNotVisited ( successor)
890
+ blockList. push ( successor)
890
891
}
891
892
} else if visitedBlocks. insert ( successor) {
892
- blockList. pushIfNotVisited ( successor)
893
+ blockList. push ( successor)
893
894
}
894
895
}
895
896
}
896
897
var hasEscaped = propagateEscapeInBlock ( after: accessMap. allocation. nextInstruction, hasEscaped: false )
897
898
forwardPropagate ( accessMap. allocation. parentBlock, hasEscaped)
898
899
while let block = blockList. pop ( ) {
899
- hasEscaped = escapedBlocks. insert ( block)
900
+ hasEscaped = escapedBlocks. contains ( block)
900
901
hasEscaped = propagateEscapeInBlock ( after: block. instructions. first!, hasEscaped: hasEscaped)
901
- forwardPropagate ( accessMap . allocation . parentBlock , hasEscaped)
902
+ forwardPropagate ( block , hasEscaped)
902
903
}
903
904
}
904
905
@@ -917,3 +918,49 @@ extension LocalVariableReachableAccess {
917
918
return hasEscaped
918
919
}
919
920
}
921
+
922
+ let localVariableReachingAssignmentsTest = FunctionTest ( " local_variable_reaching_assignments " ) {
923
+ function, arguments, context in
924
+ let allocation = arguments. takeValue ( )
925
+ let instruction = arguments. takeInstruction ( )
926
+ print ( " ### Allocation: \( allocation) " )
927
+ let localReachabilityCache = LocalVariableReachabilityCache ( )
928
+ guard let localReachability = localReachabilityCache. reachability ( for: allocation, context) else {
929
+ print ( " No reachability " )
930
+ return
931
+ }
932
+ print ( " ### Access map: " )
933
+ print ( localReachability. accessMap)
934
+ print ( " ### Instruction: \( instruction) " )
935
+ var reachingAssignments = Stack < LocalVariableAccess > ( context)
936
+ defer { reachingAssignments. deinitialize ( ) }
937
+ guard localReachability. gatherReachingAssignments ( for: instruction, in: & reachingAssignments) else {
938
+ print ( " !!! Reaching escape " )
939
+ return
940
+ }
941
+ print ( " ### Reachable assignments: " )
942
+ print ( reachingAssignments. map ( { String ( describing: $0) } ) . joined ( separator: " \n " ) )
943
+ }
944
+
945
+ let localVariableReachableUsesTest = FunctionTest ( " local_variable_reachable_uses " ) {
946
+ function, arguments, context in
947
+ let allocation = arguments. takeValue ( )
948
+ let modify = arguments. takeInstruction ( )
949
+ print ( " ### Allocation: \( allocation) " )
950
+ let localReachabilityCache = LocalVariableReachabilityCache ( )
951
+ guard let localReachability = localReachabilityCache. reachability ( for: allocation, context) else {
952
+ print ( " No reachability " )
953
+ return
954
+ }
955
+ print ( " ### Access map: " )
956
+ print ( localReachability. accessMap)
957
+ print ( " ### Modify: \( modify) " )
958
+ var reachableUses = Stack < LocalVariableAccess > ( context)
959
+ defer { reachableUses. deinitialize ( ) }
960
+ guard localReachability. gatherAllReachableUses ( of: modify, in: & reachableUses) else {
961
+ print ( " !!! Reachable escape " )
962
+ return
963
+ }
964
+ print ( " ### Reachable access: " )
965
+ print ( reachableUses. map ( { String ( describing: $0) } ) . joined ( separator: " \n " ) )
966
+ }
0 commit comments