6 void live_analysis (list worklist
)
8 while (list_size (worklist
) != 0) {
9 struct basicedge
*edge
;
10 struct basicblock
*block
, *bref
;
11 struct subroutine
*sub
;
12 int i
, changed
, regno
;
15 block
= list_removehead (worklist
);
17 for (i
= 0; i
< NUM_REGMASK
; i
++)
18 block
->reg_live_out
[i
] =
19 (block
->reg_live_in
[i
] & ~(block
->reg_kill
[i
])) | block
->reg_gen
[i
];
21 ref
= list_head (block
->inrefs
);
25 edge
= element_getvalue (ref
);
28 for (i
= 0; i
< NUM_REGMASK
; i
++) {
29 changed
= changed
|| (block
->reg_live_out
[i
] & (~bref
->reg_live_in
[i
]));
30 bref
->reg_live_in
[i
] |= block
->reg_live_out
[i
];
33 if (changed
&& !bref
->mark1
) {
34 list_inserttail (worklist
, bref
);
38 ref
= element_next (ref
);
41 sub
= block
->info
.call
.calltarget
;
42 if (block
->type
== BLOCK_CALL
&& sub
) {
44 for (regno
= REGISTER_GPR_V0
; regno
<= REGISTER_GPR_V1
; regno
++) {
45 if (IS_BIT_SET (block
->reg_live_in
, regno
)) {
46 sub
->numregout
= MAX (sub
->numregout
, regno
- REGISTER_GPR_V0
+ 1);
50 if (sub
->status
& SUBROUTINE_OPERATIONS_EXTRACTED
) {
52 for (regno
= REGISTER_GPR_V0
; regno
<= REGISTER_GPR_V1
; regno
++) {
53 if (IS_BIT_SET (block
->reg_live_in
, regno
)) {
54 changed
= changed
|| !IS_BIT_SET (sub
->endblock
->reg_gen
, regno
);
55 BIT_SET (sub
->endblock
->reg_gen
, regno
);
58 if (changed
&& !sub
->endblock
->mark1
) {
59 list_inserttail (worklist
, sub
->endblock
);
60 sub
->endblock
->mark1
= 1;
65 if (block
->type
== BLOCK_START
) {
68 for (regno
= REGISTER_GPR_A0
; regno
<= REGISTER_GPR_T3
; regno
++) {
69 if (IS_BIT_SET (block
->reg_live_in
, regno
)) {
70 sub
->numregargs
= MAX (sub
->numregargs
, regno
- REGISTER_GPR_A0
+ 1);
74 ref
= list_head (sub
->whereused
);
76 bref
= element_getvalue (ref
);
78 for (regno
= REGISTER_GPR_A0
; regno
<= REGISTER_GPR_T3
; regno
++) {
79 if (IS_BIT_SET (block
->reg_live_in
, regno
)) {
80 changed
= changed
|| !IS_BIT_SET (bref
->reg_gen
, regno
);
81 BIT_SET (bref
->reg_gen
, regno
);
84 if (changed
&& !bref
->mark1
) {
85 list_inserttail (worklist
, bref
);
88 ref
= element_next (ref
);
94 void live_registers (struct code
*c
)
96 list worklist
= list_alloc (c
->lstpool
);
97 element el
= list_head (c
->subroutines
);
100 struct subroutine
*sub
= element_getvalue (el
);
101 if (!sub
->import
&& !sub
->haserror
) {
103 sub
->status
|= SUBROUTINE_LIVE_REGISTERS
;
104 sub
->endblock
->mark1
= 1;
105 list_inserthead (worklist
, sub
->endblock
);
107 el
= element_next (el
);
110 live_analysis (worklist
);
111 list_free (worklist
);
114 void live_registers_imports (struct code
*c
)
116 element el
= list_head (c
->subroutines
);
119 struct subroutine
*sub
= element_getvalue (el
);
120 if (sub
->import
&& sub
->numregargs
== -1) {
123 ref
= list_head (sub
->whereused
);
125 struct basicblock
*block
= element_getvalue (ref
);
126 struct operation
*op
= list_tailvalue (block
->operations
);
127 int count
= 0, maxcount
= 0;
130 opel
= list_head (op
->info
.callop
.arguments
);
132 struct value
*val
= element_getvalue (opel
);
135 if (list_size (val
->val
.variable
->uses
) == 1 &&
136 val
->val
.variable
->def
->type
!= OP_START
&&
137 val
->val
.variable
->def
->type
!= OP_CALL
) {
138 if (maxcount
< count
) maxcount
= count
;
140 opel
= element_next (opel
);
143 if (sub
->numregargs
< maxcount
)
144 sub
->numregargs
= maxcount
;
146 ref
= element_next (ref
);
149 ref
= list_head (sub
->whereused
);
151 struct basicblock
*block
= element_getvalue (ref
);
152 struct subroutine
*target
= block
->sub
;
154 target
->status
&= ~(SUBROUTINE_SSA
| SUBROUTINE_FIXUP_CALL_ARGS
);
155 ref
= element_next (ref
);
158 el
= element_next (el
);
161 el
= list_head (c
->subroutines
);
164 struct subroutine
*sub
= element_getvalue (el
);
165 if (!sub
->import
&& !sub
->haserror
&&
166 !(sub
->status
& SUBROUTINE_SSA
)) {
168 remove_call_arguments (sub
);
170 el
= element_next (el
);