@@ -946,42 +946,90 @@ def _convert_ssa(v: Variable) -> Optional[Union[StateVariable, LocalVariable]]:
946
946
non_ssa_var = function .get_local_variable_from_name (v .name )
947
947
return non_ssa_var
948
948
949
- def update_read_write_using_ssa (self ) -> None :
950
- if not self . expression :
951
- return
952
- for ir in self . irs_ssa :
953
- if isinstance ( ir , PhiCallback ):
954
- continue
955
- if not isinstance ( ir , ( Phi , Index , Member )):
956
- self . _ssa_vars_read += [
957
- v for v in ir . read if isinstance ( v , ( StateIRVariable , LocalIRVariable ))
958
- ]
959
- for var in ir . read :
960
- if isinstance ( var , ReferenceVariable ):
961
- origin = var . points_to_origin
962
- if isinstance ( origin , ( StateIRVariable , LocalIRVariable )):
963
- self . _ssa_vars_read . append ( origin )
964
-
965
- elif isinstance ( ir , ( Member , Index )):
966
- variable_right : RVALUE = ir .variable_right
967
- if isinstance ( variable_right , ( StateIRVariable , LocalIRVariable )):
968
- self . _ssa_vars_read . append ( variable_right )
969
- if isinstance (variable_right , ReferenceVariable ):
970
- origin = variable_right .points_to_origin
949
+ def _update_read_using_ssa (self , ir : Operation ) -> None :
950
+ """
951
+ Update self._ssa_vars_read
952
+ This look for all operations that read a IRvariable
953
+ It uses the result of the storage pointer
954
+ - For "normal" operation, the read are mostly everything in ir.read
955
+ - For "index", the read is the left part (the right part being a reference variable)
956
+ - For Phi, nothing is considered read
957
+
958
+ """
959
+
960
+ # For variable read, phi and index have special treatments
961
+ # Phi don't lead to values read
962
+ # Index leads to read the variable right (the left variable is a ref variable, not the actual object)
963
+ # Not that Member is a normal operation here, given we filter out constant by checking for the IRvaraible
964
+ if not isinstance ( ir , ( Phi , Index )):
965
+ self . _ssa_vars_read += [
966
+ v for v in ir .read if isinstance ( v , ( StateIRVariable , LocalIRVariable ))
967
+ ]
968
+ for var in ir . read :
969
+ if isinstance (var , ReferenceVariable ):
970
+ origin = var .points_to_origin
971
971
if isinstance (origin , (StateIRVariable , LocalIRVariable )):
972
972
self ._ssa_vars_read .append (origin )
973
973
974
- if isinstance (ir , OperationWithLValue ):
975
- if isinstance (ir , (Index , Member , Length )):
976
- continue # Don't consider Member and Index operations -> ReferenceVariable
977
- var = ir .lvalue
978
- if isinstance (var , ReferenceVariable ):
979
- var = var .points_to_origin
974
+ # If we read from a storage variable (outside of phi operator)
975
+ if isinstance (var , LocalIRVariable ) and var .is_storage :
976
+ for refer_to in var .refers_to :
977
+ # the following should always be true
978
+ if isinstance (refer_to , (StateIRVariable , LocalIRVariable )):
979
+ self ._ssa_vars_read .append (refer_to )
980
+
981
+ elif isinstance (ir , Index ):
982
+ variable_right : RVALUE = ir .variable_right
983
+ if isinstance (variable_right , (StateIRVariable , LocalIRVariable )):
984
+ self ._ssa_vars_read .append (variable_right )
985
+
986
+ if isinstance (variable_right , ReferenceVariable ):
987
+ origin = variable_right .points_to_origin
988
+ if isinstance (origin , (StateIRVariable , LocalIRVariable )):
989
+ self ._ssa_vars_read .append (origin )
990
+
991
+ def _update_write_using_ssa (self , ir : Operation ) -> None :
992
+ """
993
+ Update self._ssa_vars_written
994
+ This look for all operations that write a IRvariable
995
+ It uses the result of the storage pointer
996
+
997
+ Index/member/Length are not considering writing to anything
998
+ For index/member it is implictely handled when their associated RefernceVarible are written
999
+
1000
+ """
1001
+
1002
+ if isinstance (ir , OperationWithLValue ) and not isinstance (ir , Phi ):
1003
+ if isinstance (ir , (Index , Member , Length )):
1004
+ return # Don't consider Member and Index operations -> ReferenceVariable
1005
+
1006
+ var = ir .lvalue
1007
+
1008
+ if isinstance (var , ReferenceVariable ):
1009
+ var = var .points_to_origin
1010
+
1011
+ candidates = [var ]
1012
+
1013
+ # If we write to a storage pointer, add everything it points to as target
1014
+ if isinstance (var , LocalIRVariable ) and var .is_storage :
1015
+ candidates += var .refers_to
1016
+
1017
+ for var in candidates :
980
1018
# Only store non-slithIR variables
981
1019
if var and isinstance (var , (StateIRVariable , LocalIRVariable )):
982
1020
if isinstance (ir , PhiCallback ):
983
1021
continue
984
1022
self ._ssa_vars_written .append (var )
1023
+
1024
+ def update_read_write_using_ssa (self ) -> None :
1025
+
1026
+ for ir in self .irs_ssa :
1027
+ if isinstance (ir , PhiCallback ):
1028
+ continue
1029
+
1030
+ self ._update_read_using_ssa (ir )
1031
+ self ._update_write_using_ssa (ir )
1032
+
985
1033
self ._ssa_vars_read = list (set (self ._ssa_vars_read ))
986
1034
self ._ssa_state_vars_read = [v for v in self ._ssa_vars_read if isinstance (v , StateVariable )]
987
1035
self ._ssa_local_vars_read = [v for v in self ._ssa_vars_read if isinstance (v , LocalVariable )]
0 commit comments