@@ -27,9 +27,9 @@ import SIL
2727
2828private let verbose = false
2929
30- private func log( _ message: @autoclosure ( ) -> String ) {
30+ private func log( prefix : Bool = true , _ message: @autoclosure ( ) -> String ) {
3131 if verbose {
32- print ( " ### \( message ( ) ) " )
32+ debugLog ( prefix : prefix , message ( ) )
3333 }
3434}
3535
@@ -226,7 +226,7 @@ class LocalVariableAccessInfo: CustomStringConvertible {
226226 }
227227
228228 var description : String {
229- return " full- assign: \( _isFullyAssigned == nil ? " unknown " : String ( describing: _isFullyAssigned!) ) , "
229+ return " assign: \( _isFullyAssigned == nil ? " unknown " : String ( describing: _isFullyAssigned!) ) , "
230230 + " \( access) "
231231 }
232232
@@ -329,7 +329,7 @@ struct LocalVariableAccessMap: Collection, CustomStringConvertible {
329329 subscript( instruction: Instruction ) -> LocalVariableAccessInfo ? { accessMap [ instruction] }
330330
331331 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 " )
333333 }
334334}
335335
@@ -699,6 +699,7 @@ extension LocalVariableReachableAccess {
699699 case . escape:
700700 break
701701 }
702+ break
702703 }
703704 return currentEffect
704705 }
@@ -808,8 +809,8 @@ extension LocalVariableReachableAccess {
808809 forwardPropagateEffect ( in: block, blockInfo: blockInfo, effect: currentEffect, blockList: & blockList,
809810 accessStack: & accessStack)
810811 }
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 " ) ) " )
813814 return true
814815 }
815816
@@ -873,7 +874,7 @@ extension LocalVariableReachableAccess {
873874 private func findAllEscapesPriorToAccess( ) {
874875 var visitedBlocks = BasicBlockSet ( context)
875876 var escapedBlocks = BasicBlockSet ( context)
876- var blockList = BasicBlockWorklist ( context)
877+ var blockList = Stack < BasicBlock > ( context)
877878 defer {
878879 visitedBlocks. deinitialize ( )
879880 escapedBlocks. deinitialize ( )
@@ -886,19 +887,19 @@ extension LocalVariableReachableAccess {
886887 for successor in from. successors {
887888 if hasEscaped {
888889 if escapedBlocks. insert ( successor) {
889- blockList. pushIfNotVisited ( successor)
890+ blockList. push ( successor)
890891 }
891892 } else if visitedBlocks. insert ( successor) {
892- blockList. pushIfNotVisited ( successor)
893+ blockList. push ( successor)
893894 }
894895 }
895896 }
896897 var hasEscaped = propagateEscapeInBlock ( after: accessMap. allocation. nextInstruction, hasEscaped: false )
897898 forwardPropagate ( accessMap. allocation. parentBlock, hasEscaped)
898899 while let block = blockList. pop ( ) {
899- hasEscaped = escapedBlocks. insert ( block)
900+ hasEscaped = escapedBlocks. contains ( block)
900901 hasEscaped = propagateEscapeInBlock ( after: block. instructions. first!, hasEscaped: hasEscaped)
901- forwardPropagate ( accessMap . allocation . parentBlock , hasEscaped)
902+ forwardPropagate ( block , hasEscaped)
902903 }
903904 }
904905
@@ -917,3 +918,49 @@ extension LocalVariableReachableAccess {
917918 return hasEscaped
918919 }
919920}
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