4444 "FixRegistersPass" ,
4545 "NoHazardsAllocationPass" ,
4646 "RandomAllocationPass" ,
47+ "TargetLastWrittenRegisterPass" ,
4748]
4849
4950# Functions
@@ -70,6 +71,9 @@ def __init__(
7071 """
7172 super (DefaultRegisterAllocationPass , self ).__init__ ()
7273 self ._rand = rand
74+ self ._rand_imm = random .Random ()
75+ self ._rand_imm .setstate (rand .getstate ())
76+
7377 self ._min = minimize
7478 if self ._min :
7579 raise NotImplementedError (
@@ -174,7 +178,7 @@ def __call__(self, building_block, target):
174178
175179 else :
176180 operand .set_value (
177- operand .type .random_value (self ._rand )
181+ operand .type .random_value (self ._rand_imm )
178182 )
179183
180184 elif operand .type .address_relative :
@@ -896,7 +900,7 @@ def __call__(self, building_block, target):
896900
897901 # Balance things: in case there are lots of inputs/outputs and few inputs or outputs.
898902 # Make sure we always have a minimum of 4 outputs and inputs
899-
903+
900904 rtypes = set ([reg .type for reg in inputoutputs + inputs + outputs ])
901905 for rtype in rtypes :
902906 for cset in [inputs , outputs ]:
@@ -913,10 +917,9 @@ def __call__(self, building_block, target):
913917 if len (vset ) == 0 :
914918 break
915919
916- cset .append (vset [0 ])
920+ cset .append (vset [0 ])
917921 bset .remove (vset [0 ])
918922 rcset = set ([reg for reg in cset if reg .type == rtype ])
919-
920923
921924 LOG .debug ("-" * 80 )
922925 LOG .debug ("BEFORE ALLOCATING 2" )
@@ -926,12 +929,12 @@ def __call__(self, building_block, target):
926929 LOG .debug ("Reserved %s" , rregs )
927930 LOG .debug ("-" * 80 )
928931
929-
930932 for s1 , s2 in zip (
931933 [inputs , inputoutputs , outputs , rregs ],
932934 [inputs , inputoutputs , outputs , rregs ]):
933935
934- if s1 == s2 : continue
936+ if s1 == s2 :
937+ continue
935938 assert set (s1 ).isdisjoint (set (s2 ))
936939
937940 if "MICROPROBEMAXREG" in os .environ :
@@ -1109,7 +1112,6 @@ def __call__(self, building_block, target):
11091112 LOG .debug ("Operand set to: %s" , regs [0 ])
11101113 operand .set_value (regs [0 ])
11111114
1112-
11131115 for value in operand .type .access (operand .value ):
11141116
11151117 if value in inputoutputs :
@@ -1160,6 +1162,43 @@ def __call__(self, building_block, target):
11601162 operand .unset_value ()
11611163
11621164
1165+ class TargetLastWrittenRegisterPass (microprobe .passes .Pass ):
1166+ def __init__ (self , rand : random .Random , set_inputs = False ):
1167+ super (TargetLastWrittenRegisterPass , self ).__init__ ()
1168+ self .description = "Set output operand of the current instruction to the last written register operand"
1169+ self ._rand = rand
1170+ self ._si = set_inputs
1171+
1172+ def __call__ (self , building_block , target ):
1173+
1174+ wreg = {}
1175+
1176+ for bbl in building_block .cfg .bbls :
1177+ for instr in bbl .instrs :
1178+ for operand in instr .operands ():
1179+ if not self ._si :
1180+ if not operand .is_output :
1181+ continue
1182+
1183+ if operand .type .immediate :
1184+ continue
1185+ regs = list (operand .type .values ())
1186+ rtype = regs [0 ].type
1187+ if operand .value is not None and operand .is_output :
1188+ wreg [rtype ] = operand .value
1189+ elif operand .value is None :
1190+ if rtype not in wreg :
1191+ operand .set_value (operand .type .random_value (self ._rand ))
1192+ if operand .is_output :
1193+ wreg [rtype ] = operand .value
1194+ elif wreg [rtype ] not in operand .type .values ():
1195+ operand .set_value (operand .type .random_value (self ._rand ))
1196+ if operand .is_output :
1197+ wreg [rtype ] = operand .value
1198+ else :
1199+ operand .set_value (wreg [rtype ])
1200+
1201+
11631202class RandomAllocationPass (microprobe .passes .Pass ):
11641203 """RandomAllocationPass pass."""
11651204
0 commit comments