@@ -283,13 +283,30 @@ getvariables(Node *fn)
283
283
// For arguments and results, the bitmap covers all variables,
284
284
// so we must include all the variables, even the ones without
285
285
// pointers.
286
+ //
287
+ // The Node.opt field is available for use by optimization passes.
288
+ // We use it to hold the index of the node in the variables array, plus 1
289
+ // (so that 0 means the Node is not in the variables array).
290
+ // Each pass should clear opt when done, but you never know,
291
+ // so clear them all ourselves too.
292
+ // The Node.curfn field is supposed to be set to the current function
293
+ // already, but for some compiler-introduced names it seems not to be,
294
+ // so fix that here.
295
+ // Later, when we want to find the index of a node in the variables list,
296
+ // we will check that n->curfn == curfn and n->opt > 0. Then n->opt - 1
297
+ // is the index in the variables list.
298
+ ll -> n -> opt = nil ;
299
+ ll -> n -> curfn = curfn ;
286
300
switch (ll -> n -> class ) {
287
301
case PAUTO :
288
- if (haspointers (ll -> n -> type ))
302
+ if (haspointers (ll -> n -> type )) {
303
+ ll -> n -> opt = (void * )(uintptr )(arraylength (result )+ 1 );
289
304
arrayadd (result , & ll -> n );
305
+ }
290
306
break ;
291
307
case PPARAM :
292
308
case PPARAMOUT :
309
+ ll -> n -> opt = (void * )(uintptr )(arraylength (result )+ 1 );
293
310
arrayadd (result , & ll -> n );
294
311
break ;
295
312
}
@@ -718,14 +735,16 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
718
735
}
719
736
if (info .flags & (LeftRead | LeftWrite | LeftAddr )) {
720
737
from = & prog -> from ;
721
- if (from -> node != nil && from -> sym != nil ) {
738
+ if (from -> node != nil && from -> sym != nil && from -> node -> curfn == curfn ) {
722
739
switch (from -> node -> class & ~PHEAP ) {
723
740
case PAUTO :
724
741
case PPARAM :
725
742
case PPARAMOUT :
726
- pos = arrayindexof ( vars , from -> node );
743
+ pos = ( int )( uintptr ) from -> node -> opt - 1 ; // index in vars
727
744
if (pos == -1 )
728
745
goto Next ;
746
+ if (pos >= arraylength (vars ) || * (Node * * )arrayget (vars , pos ) != from -> node )
747
+ fatal ("bad bookkeeping in liveness %N %d" , from -> node , pos );
729
748
if (from -> node -> addrtaken ) {
730
749
bvset (avarinit , pos );
731
750
} else {
@@ -741,14 +760,16 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
741
760
Next :
742
761
if (info .flags & (RightRead | RightWrite | RightAddr )) {
743
762
to = & prog -> to ;
744
- if (to -> node != nil && to -> sym != nil ) {
763
+ if (to -> node != nil && to -> sym != nil && to -> node -> curfn == curfn ) {
745
764
switch (to -> node -> class & ~PHEAP ) {
746
765
case PAUTO :
747
766
case PPARAM :
748
767
case PPARAMOUT :
749
- pos = arrayindexof ( vars , to -> node );
768
+ pos = ( int )( uintptr ) to -> node -> opt - 1 ; // index in vars
750
769
if (pos == -1 )
751
770
goto Next1 ;
771
+ if (pos >= arraylength (vars ) || * (Node * * )arrayget (vars , pos ) != to -> node )
772
+ fatal ("bad bookkeeping in liveness %N %d" , to -> node , pos );
752
773
if (to -> node -> addrtaken ) {
753
774
if (prog -> as != AVARKILL )
754
775
bvset (avarinit , pos );
@@ -1020,6 +1041,9 @@ checkptxt(Node *fn, Prog *firstp)
1020
1041
{
1021
1042
Prog * p ;
1022
1043
1044
+ if (debuglive == 0 )
1045
+ return ;
1046
+
1023
1047
for (p = firstp ; p != P ; p = p -> link ) {
1024
1048
if (0 )
1025
1049
print ("analyzing '%P'\n" , p );
@@ -1172,21 +1196,17 @@ twobitlivepointermap(Liveness *lv, Bvec *liveout, Array *vars, Bvec *args, Bvec
1172
1196
vlong xoffset ;
1173
1197
int32 i ;
1174
1198
1175
- for (i = 0 ; i < arraylength ( vars ) ; i ++ ) {
1199
+ for (i = 0 ; ( i = bvnext ( liveout , i )) >= 0 ; i ++ ) {
1176
1200
node = * (Node * * )arrayget (vars , i );
1177
1201
switch (node -> class ) {
1178
1202
case PAUTO :
1179
- if (bvget (liveout , i )) {
1180
- xoffset = node -> xoffset + stkptrsize ;
1181
- twobitwalktype1 (node -> type , & xoffset , locals );
1182
- }
1203
+ xoffset = node -> xoffset + stkptrsize ;
1204
+ twobitwalktype1 (node -> type , & xoffset , locals );
1183
1205
break ;
1184
1206
case PPARAM :
1185
1207
case PPARAMOUT :
1186
- if (bvget (liveout , i )) {
1187
- xoffset = node -> xoffset ;
1188
- twobitwalktype1 (node -> type , & xoffset , args );
1189
- }
1208
+ xoffset = node -> xoffset ;
1209
+ twobitwalktype1 (node -> type , & xoffset , args );
1190
1210
break ;
1191
1211
}
1192
1212
}
@@ -1944,6 +1964,7 @@ liveness(Node *fn, Prog *firstp, Sym *argssym, Sym *livesym)
1944
1964
Array * cfg , * vars ;
1945
1965
Liveness * lv ;
1946
1966
int debugdelta ;
1967
+ NodeList * l ;
1947
1968
1948
1969
// Change name to dump debugging information only for a specific function.
1949
1970
debugdelta = 0 ;
@@ -1984,6 +2005,9 @@ liveness(Node *fn, Prog *firstp, Sym *argssym, Sym *livesym)
1984
2005
twobitwritesymbol (lv -> argslivepointers , argssym );
1985
2006
1986
2007
// Free everything.
2008
+ for (l = fn -> dcl ; l != nil ; l = l -> next )
2009
+ if (l -> n != N )
2010
+ l -> n -> opt = nil ;
1987
2011
freeliveness (lv );
1988
2012
arrayfree (vars );
1989
2013
freecfg (cfg );
0 commit comments