2 * Copyright 2010 Christoph Bumiller
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #include "nv50_context.h"
26 #include "util/u_simple_list.h"
28 #define NUM_REGISTER_FILES 4
33 uint32_t last
[NUM_REGISTER_FILES
];
34 uint32_t bits
[NUM_REGISTER_FILES
][8];
40 struct nv_instruction
**insns
;
47 ranges_coalesce(struct nv_range
*range
)
49 while (range
->next
&& range
->end
>= range
->next
->bgn
) {
50 struct nv_range
*rnn
= range
->next
->next
;
51 assert(range
->bgn
<= range
->next
->bgn
);
52 range
->end
= MAX2(range
->end
, range
->next
->end
);
59 add_range_ex(struct nv_value
*val
, int bgn
, int end
, struct nv_range
*new_range
)
61 struct nv_range
*range
, **nextp
= &val
->livei
;
63 for (range
= val
->livei
; range
; range
= range
->next
) {
65 break; /* insert before */
67 if (bgn
> range
->end
) {
69 continue; /* insert after */
73 if (bgn
< range
->bgn
) {
77 ranges_coalesce(range
);
80 if (end
> range
->end
) {
82 ranges_coalesce(range
);
85 assert(bgn
>= range
->bgn
);
86 assert(end
<= range
->end
);
91 new_range
= CALLOC_STRUCT(nv_range
);
95 new_range
->next
= range
;
101 add_range(struct nv_value
*val
, struct nv_basic_block
*b
, int end
)
105 if (!val
->insn
) /* ignore non-def values */
107 assert(b
->entry
->serial
<= b
->exit
->serial
);
108 assert(b
->phi
->serial
<= end
);
109 assert(b
->exit
->serial
+ 1 >= end
);
111 bgn
= val
->insn
->serial
;
112 if (bgn
< b
->entry
->serial
|| bgn
> b
->exit
->serial
)
113 bgn
= b
->entry
->serial
;
116 debug_printf("Aieee! BLOCK [%i, %i], RANGE [%i, %i)\n",
117 b
->entry
->serial
, b
->exit
->serial
, bgn
, end
);
121 if (bgn
< val
->insn
->serial
)
122 debug_printf("WARNING: leaking value %i ?\n", val
->n
);
124 add_range_ex(val
, bgn
, end
, NULL
);
127 #ifdef NV50_RA_DEBUG_JOIN
129 livei_print(struct nv_value
*a
)
131 struct nv_range
*r
= a
->livei
;
133 debug_printf("livei %i: ", a
->n
);
135 debug_printf("[%i, %i) ", r
->bgn
, r
->end
);
143 livei_unify(struct nv_value
*dst
, struct nv_value
*src
)
145 struct nv_range
*range
, *next
;
147 for (range
= src
->livei
; range
; range
= next
) {
149 if (add_range_ex(dst
, range
->bgn
, range
->end
, range
))
156 livei_release(struct nv_value
*val
)
158 struct nv_range
*range
, *next
;
160 for (range
= val
->livei
; range
; range
= next
) {
167 livei_have_overlap(struct nv_value
*a
, struct nv_value
*b
)
169 struct nv_range
*r_a
, *r_b
;
171 for (r_a
= a
->livei
; r_a
; r_a
= r_a
->next
) {
172 for (r_b
= b
->livei
; r_b
; r_b
= r_b
->next
) {
173 if (r_b
->bgn
< r_a
->end
&&
182 livei_end(struct nv_value
*a
)
184 struct nv_range
*r
= a
->livei
;
193 livei_contains(struct nv_value
*a
, int pos
)
197 for (r
= a
->livei
; r
&& r
->bgn
<= pos
; r
= r
->next
)
204 reg_assign(struct register_set
*set
, struct nv_value
**def
, int n
)
208 int f
= def
[0]->reg
.file
;
210 s
= n
<< (nv_type_order(def
[0]->reg
.type
) - 1);
215 for (i
= 0; i
* 32 < set
->last
[f
]; ++i
) {
216 if (set
->bits
[f
][i
] == 0xffffffff)
219 for (id
= 0; id
< 32; id
+= s
)
220 if (!(set
->bits
[f
][i
] & (m
<< id
)))
225 if (i
* 32 + id
> set
->last
[f
])
228 set
->bits
[f
][i
] |= m
<< id
;
232 set
->pc
->max_reg
[f
] = MAX2(set
->pc
->max_reg
[f
], id
+ s
- 1);
234 id
>>= nv_type_order(def
[0]->reg
.type
) - 1;
236 for (i
= 0; i
< n
; ++i
)
238 def
[i
]->reg
.id
= id
++;
244 reg_occupy(struct register_set
*set
, struct nv_value
*val
)
246 int s
, id
= val
->reg
.id
, f
= val
->reg
.file
;
251 s
= nv_type_order(val
->reg
.type
) - 1;
253 m
= (1 << (1 << s
)) - 1;
255 set
->bits
[f
][id
/ 32] |= m
<< (id
% 32);
257 if (set
->pc
->max_reg
[f
] < id
)
258 set
->pc
->max_reg
[f
] = id
;
262 reg_release(struct register_set
*set
, struct nv_value
*val
)
264 int s
, id
= val
->reg
.id
, f
= val
->reg
.file
;
270 s
= nv_type_order(val
->reg
.type
) - 1;
272 m
= (1 << (1 << s
)) - 1;
274 set
->bits
[f
][id
/ 32] &= ~(m
<< (id
% 32));
277 static INLINE boolean
278 join_allowed(struct nv_pc_pass
*ctx
, struct nv_value
*a
, struct nv_value
*b
)
281 struct nv_value
*val
;
283 if (a
->reg
.file
!= b
->reg
.file
||
284 nv_type_sizeof(a
->reg
.type
) != nv_type_sizeof(b
->reg
.type
))
287 if (a
->join
->reg
.id
== b
->join
->reg
.id
)
291 /* either a or b or both have been assigned */
293 if (a
->join
->reg
.id
>= 0 && b
->join
->reg
.id
>= 0)
296 if (b
->join
->reg
.id
>= 0) {
297 if (a
->join
->reg
.id
>= 0)
304 for (i
= 0; i
< ctx
->pc
->num_values
; ++i
) {
305 val
= &ctx
->pc
->values
[i
];
307 if (val
->join
->reg
.id
!= a
->join
->reg
.id
)
309 if (val
->join
!= a
->join
&& livei_have_overlap(val
->join
, b
->join
))
318 do_join_values(struct nv_pc_pass
*ctx
, struct nv_value
*a
, struct nv_value
*b
)
321 struct nv_value
*bjoin
= b
->join
;
323 if (b
->join
->reg
.id
>= 0)
324 a
->join
->reg
.id
= b
->join
->reg
.id
;
326 livei_unify(a
->join
, b
->join
);
328 #ifdef NV50_RA_DEBUG_JOIN
329 debug_printf("joining %i to %i\n", b
->n
, a
->n
);
332 /* make a->join the new representative */
333 for (j
= 0; j
< ctx
->pc
->num_values
; ++j
)
334 if (ctx
->pc
->values
[j
].join
== bjoin
)
335 ctx
->pc
->values
[j
].join
= a
->join
;
337 assert(b
->join
== a
->join
);
341 try_join_values(struct nv_pc_pass
*ctx
, struct nv_value
*a
, struct nv_value
*b
)
343 if (!join_allowed(ctx
, a
, b
)) {
344 #ifdef NV50_RA_DEBUG_JOIN
345 debug_printf("cannot join %i to %i: not allowed\n", b
->n
, a
->n
);
349 if (livei_have_overlap(a
->join
, b
->join
)) {
350 #ifdef NV50_RA_DEBUG_JOIN
351 debug_printf("cannot join %i to %i: livei overlap\n", b
->n
, a
->n
);
358 do_join_values(ctx
, a
, b
);
361 static INLINE boolean
362 need_new_else_block(struct nv_basic_block
*b
, struct nv_basic_block
*p
)
367 if (p
->out
[i
] && p
->out_kind
[i
] != CFG_EDGE_LOOP_LEAVE
)
370 return (b
->num_in
> 1) && (n
== 2);
373 /* For each operand of each PHI in b, generate a new value by inserting a MOV
374 * at the end of the block it is coming from and replace the operand with its
375 * result. This eliminates liveness conflicts and enables us to let values be
376 * copied to the right register if such a conflict exists nonetheless.
379 pass_generate_phi_movs(struct nv_pc_pass
*ctx
, struct nv_basic_block
*b
)
381 struct nv_instruction
*i
, *ni
;
382 struct nv_value
*val
;
383 struct nv_basic_block
*p
, *pn
;
386 b
->pass_seq
= ctx
->pc
->pass_seq
;
388 for (n
= 0; n
< b
->num_in
; ++n
) {
392 if (need_new_else_block(b
, p
)) {
393 pn
= new_basic_block(ctx
->pc
);
400 if (p
->exit
->target
== b
) /* target to new else-block */
401 p
->exit
->target
= pn
;
409 ctx
->pc
->current_block
= pn
;
411 for (i
= b
->phi
; i
&& i
->opcode
== NV_OP_PHI
; i
= i
->next
) {
412 for (j
= 0; j
< 4 && i
->src
[j
]; ++j
) {
413 if (nvbb_reachable_by(p
, i
->src
[j
]->value
->insn
->bb
, b
))
416 if (j
>= 4 || !i
->src
[j
])
418 val
= i
->src
[j
]->value
;
420 ni
= new_instruction(ctx
->pc
, NV_OP_MOV
);
422 /* TODO: insert instruction at correct position in the first place */
423 if (ni
->prev
&& ni
->prev
->target
)
424 nv_nvi_permute(ni
->prev
, ni
);
426 ni
->def
[0] = new_value(ctx
->pc
, val
->reg
.file
, val
->reg
.type
);
427 ni
->def
[0]->insn
= ni
;
428 ni
->src
[0] = new_ref(ctx
->pc
, val
);
430 nv_reference(ctx
->pc
, &i
->src
[j
], ni
->def
[0]);
433 if (pn
!= p
&& pn
->exit
) {
434 ctx
->pc
->current_block
= b
->in
[n
? 0 : 1];
435 ni
= new_instruction(ctx
->pc
, NV_OP_BRA
);
437 ni
->is_terminator
= 1;
441 for (j
= 0; j
< 2; ++j
)
442 if (b
->out
[j
] && b
->out
[j
]->pass_seq
< ctx
->pc
->pass_seq
)
443 pass_generate_phi_movs(ctx
, b
->out
[j
]);
449 pass_join_values(struct nv_pc_pass
*ctx
, int iter
)
453 for (n
= 0; n
< ctx
->num_insns
; ++n
) {
454 struct nv_instruction
*i
= ctx
->insns
[n
];
460 try_join_values(ctx
, i
->src
[0]->value
, i
->src
[1]->value
);
461 try_join_values(ctx
, i
->def
[0], i
->src
[0]->value
);
464 if (iter
&& i
->src
[0]->value
->insn
&&
465 !nv_is_vector_op(i
->src
[0]->value
->join
->insn
->opcode
))
466 try_join_values(ctx
, i
->def
[0], i
->src
[0]->value
);
471 assert(join_allowed(ctx
, i
->def
[0], i
->src
[0]->value
));
472 assert(join_allowed(ctx
, i
->def
[0], i
->src
[1]->value
));
473 do_join_values(ctx
, i
->def
[0], i
->src
[0]->value
);
474 do_join_values(ctx
, i
->def
[0], i
->src
[1]->value
);
482 for (c
= 0; c
< 4; ++c
) {
485 do_join_values(ctx
, i
->def
[c
], i
->src
[c
]->value
);
495 /* Order the instructions so that live intervals can be expressed in numbers. */
497 pass_order_instructions(void *priv
, struct nv_basic_block
*b
)
499 struct nv_pc_pass
*ctx
= (struct nv_pc_pass
*)priv
;
500 struct nv_instruction
*i
;
502 b
->pass_seq
= ctx
->pc
->pass_seq
;
504 assert(!b
->exit
|| !b
->exit
->next
);
505 for (i
= b
->phi
; i
; i
= i
->next
) {
506 i
->serial
= ctx
->num_insns
;
507 ctx
->insns
[ctx
->num_insns
++] = i
;
512 bb_live_set_print(struct nv_pc
*pc
, struct nv_basic_block
*b
)
514 #ifdef NV50_RA_DEBUG_LIVE_SETS
516 struct nv_value
*val
;
518 debug_printf("LIVE-INs of BB:%i: ", b
->id
);
520 for (j
= 0; j
< pc
->num_values
; ++j
) {
521 if (!(b
->live_set
[j
/ 32] & (1 << (j
% 32))))
523 val
= &pc
->values
[j
];
526 debug_printf("%i ", val
->n
);
533 live_set_add(struct nv_basic_block
*b
, struct nv_value
*val
)
535 if (!val
->insn
) /* don't add non-def values */
537 b
->live_set
[val
->n
/ 32] |= 1 << (val
->n
% 32);
541 live_set_rem(struct nv_basic_block
*b
, struct nv_value
*val
)
543 b
->live_set
[val
->n
/ 32] &= ~(1 << (val
->n
% 32));
546 static INLINE boolean
547 live_set_test(struct nv_basic_block
*b
, struct nv_ref
*ref
)
549 int n
= ref
->value
->n
;
550 return b
->live_set
[n
/ 32] & (1 << (n
% 32));
553 /* The live set of a block contains those values that are live immediately
554 * before the beginning of the block, so do a backwards scan.
557 pass_build_live_sets(struct nv_pc_pass
*ctx
, struct nv_basic_block
*b
)
559 struct nv_instruction
*i
;
562 debug_printf("pass_build_live_sets BB:%i\n", b
->id
);
564 if (b
->pass_seq
>= ctx
->pc
->pass_seq
) {
565 debug_printf("already visited\n");
568 b
->pass_seq
= ctx
->pc
->pass_seq
;
570 /* slight hack for undecidedness: set phi = entry if it's undefined */
574 for (n
= 0; n
< 2; ++n
) {
575 if (!b
->out
[n
] || b
->out
[n
] == b
)
577 ret
= pass_build_live_sets(ctx
, b
->out
[n
]);
582 for (j
= 0; j
< (ctx
->pc
->num_values
+ 31) / 32; ++j
)
583 b
->live_set
[j
] = b
->out
[n
]->live_set
[j
];
585 for (j
= 0; j
< (ctx
->pc
->num_values
+ 31) / 32; ++j
)
586 b
->live_set
[j
] |= b
->out
[n
]->live_set
[j
];
589 /* Kick values out of our live set that are created in incoming
590 * blocks of our successors that are not us.
592 for (i
= b
->out
[n
]->phi
; i
&& i
->opcode
== NV_OP_PHI
; i
= i
->next
) {
593 for (j
= 0; j
< 4; ++j
) {
596 assert(i
->src
[j
]->value
->insn
);
598 if (nvbb_reachable_by(b
, i
->src
[j
]->value
->insn
->bb
, b
->out
[n
])) {
599 live_set_add(b
, i
->src
[j
]->value
);
600 debug_printf("BB:%i liveset + %i\n", b
->id
, i
->src
[j
]->value
->n
);
602 live_set_rem(b
, i
->src
[j
]->value
);
603 debug_printf("BB:%i liveset - %i\n", b
->id
, i
->src
[j
]->value
->n
);
612 bb_live_set_print(ctx
->pc
, b
);
614 for (i
= b
->exit
; i
; i
= i
->prev
) {
615 for (j
= 0; j
< 4; j
++) {
618 live_set_rem(b
, i
->def
[j
]);
620 for (j
= 0; j
< 4; j
++) {
623 live_set_add(b
, i
->src
[j
]->value
);
626 live_set_add(b
, i
->src
[4]->value
);
628 live_set_rem(b
, i
->flags_def
);
630 live_set_add(b
, i
->flags_src
->value
);
632 bb_live_set_print(ctx
->pc
, b
);
637 static void collect_live_values(struct nv_basic_block
*b
, const int n
)
642 if (b
->out
[1]) { /* what to do about back-edges ? */
643 for (i
= 0; i
< n
; ++i
)
644 b
->live_set
[i
] = b
->out
[0]->live_set
[i
] | b
->out
[1]->live_set
[i
];
646 memcpy(b
->live_set
, b
->out
[0]->live_set
, n
* sizeof(uint32_t));
650 memcpy(b
->live_set
, b
->out
[1]->live_set
, n
* sizeof(uint32_t));
652 memset(b
->live_set
, 0, n
* sizeof(uint32_t));
656 /* NOTE: the live intervals of phi functions start the the first non-phi instruction */
658 pass_build_intervals(struct nv_pc_pass
*ctx
, struct nv_basic_block
*b
)
660 struct nv_instruction
*i
, *i_stop
;
662 const int n
= (ctx
->pc
->num_values
+ 31) / 32;
664 debug_printf("building intervals for BB %i\n", b
->id
);
666 /* verify that first block does not have live-in values */
668 for (j
= 0; j
< n
; ++j
)
669 assert(b
->live_set
[j
] == 0);
671 collect_live_values(b
, n
);
673 /* remove live-outs def'd in a parallel block, hopefully they're all phi'd */
674 for (j
= 0; j
< 2; ++j
) {
675 if (!b
->out
[j
] || !b
->out
[j
]->phi
)
677 for (i
= b
->out
[j
]->phi
; i
->opcode
== NV_OP_PHI
; i
= i
->next
) {
678 live_set_rem(b
, i
->def
[0]);
680 for (s
= 0; s
< 4; ++s
) {
683 assert(i
->src
[s
]->value
->insn
);
684 if (nvbb_reachable_by(b
, i
->src
[s
]->value
->insn
->bb
, b
->out
[j
]))
685 live_set_add(b
, i
->src
[s
]->value
);
687 live_set_rem(b
, i
->src
[s
]->value
);
692 /* remaining live-outs are live until the end */
694 for (j
= 0; j
< ctx
->pc
->num_values
; ++j
) {
695 if (!(b
->live_set
[j
/ 32] & (1 << (j
% 32))))
697 #ifdef NV50_RA_DEBUG_LIVEI
698 debug_printf("adding range for live value %i\n", j
);
700 add_range(&ctx
->pc
->values
[j
], b
, b
->exit
->serial
+ 1);
703 debug_printf("%s: looping through instructions now\n", __func__
);
705 i_stop
= b
->entry
? b
->entry
->prev
: NULL
;
707 /* don't have to include phi functions here (will have 0 live range) */
708 for (i
= b
->exit
; i
!= i_stop
; i
= i
->prev
) {
709 assert(i
->serial
>= b
->phi
->serial
&& i
->serial
<= b
->exit
->serial
);
710 for (j
= 0; j
< 4; ++j
) {
712 live_set_rem(b
, i
->def
[j
]);
715 live_set_rem(b
, i
->flags_def
);
717 for (j
= 0; j
< 5; ++j
) {
718 if (i
->src
[j
] && !live_set_test(b
, i
->src
[j
])) {
719 live_set_add(b
, i
->src
[j
]->value
);
720 #ifdef NV50_RA_DEBUG_LIVEI
721 debug_printf("adding range for source that ends living: %i\n",
722 i
->src
[j
]->value
->n
);
724 add_range(i
->src
[j
]->value
, b
, i
->serial
);
727 if (i
->flags_src
&& !live_set_test(b
, i
->flags_src
)) {
728 live_set_add(b
, i
->flags_src
->value
);
729 #ifdef NV50_RA_DEBUG_LIVEI
730 debug_printf("adding range for source that ends living: %i\n",
731 i
->flags_src
->value
->n
);
733 add_range(i
->flags_src
->value
, b
, i
->serial
);
737 b
->pass_seq
= ctx
->pc
->pass_seq
;
739 if (b
->out
[0] && b
->out
[0]->pass_seq
< ctx
->pc
->pass_seq
)
740 pass_build_intervals(ctx
, b
->out
[0]);
742 if (b
->out
[1] && b
->out
[1]->pass_seq
< ctx
->pc
->pass_seq
)
743 pass_build_intervals(ctx
, b
->out
[1]);
749 nv50_ctor_register_set(struct nv_pc
*pc
, struct register_set
*set
)
751 memset(set
, 0, sizeof(*set
));
753 set
->last
[NV_FILE_GPR
] = 255;
754 set
->last
[NV_FILE_OUT
] = 127;
755 set
->last
[NV_FILE_FLAGS
] = 4;
756 set
->last
[NV_FILE_ADDR
] = 4;
762 insert_ordered_tail(struct nv_value
*list
, struct nv_value
*nval
)
764 struct nv_value
*elem
= list
->prev
;
766 // debug_printf("inserting value %i\n", nval->n);
768 for (elem
= list
->prev
;
769 elem
!= list
&& elem
->livei
->bgn
> nval
->livei
->bgn
;
771 /* now elem begins before or at the same time as val */
774 nval
->next
= elem
->next
;
775 elem
->next
->prev
= nval
;
780 pass_linear_scan(struct nv_pc_pass
*ctx
, int iter
)
782 struct nv_instruction
*i
;
783 struct register_set f
, free
;
785 struct nv_value
*cur
, *val
, *tmp
[2];
786 struct nv_value active
, inactive
, handled
, unhandled
;
788 make_empty_list(&active
);
789 make_empty_list(&inactive
);
790 make_empty_list(&handled
);
791 make_empty_list(&unhandled
);
793 nv50_ctor_register_set(ctx
->pc
, &free
);
795 /* joined values should have range = NULL and thus not be added;
796 * also, fixed memory values won't be added because they're not
799 for (n
= 0; n
< ctx
->num_insns
; ++n
) {
802 for (k
= 0; k
< 4; ++k
) {
803 if (i
->def
[k
] && i
->def
[k
]->livei
)
804 insert_ordered_tail(&unhandled
, i
->def
[k
]);
807 debug_printf("skipping def'd value %i: no livei\n", i
->def
[k
]->n
);
809 if (i
->flags_def
&& i
->flags_def
->livei
)
810 insert_ordered_tail(&unhandled
, i
->flags_def
);
813 for (val
= unhandled
.next
; val
!= unhandled
.prev
; val
= val
->next
) {
814 assert(val
->join
== val
);
815 assert(val
->livei
->bgn
<= val
->next
->livei
->bgn
);
818 foreach_s(cur
, tmp
[0], &unhandled
) {
819 remove_from_list(cur
);
821 /* debug_printf("handling value %i\n", cur->n); */
823 foreach_s(val
, tmp
[1], &active
) {
824 if (livei_end(val
) <= cur
->livei
->bgn
) {
825 reg_release(&free
, val
);
826 move_to_head(&handled
, val
);
828 if (!livei_contains(val
, cur
->livei
->bgn
)) {
829 reg_release(&free
, val
);
830 move_to_head(&inactive
, val
);
834 foreach_s(val
, tmp
[1], &inactive
) {
835 if (livei_end(val
) <= cur
->livei
->bgn
)
836 move_to_head(&handled
, val
);
838 if (livei_contains(val
, cur
->livei
->bgn
)) {
839 reg_occupy(&free
, val
);
840 move_to_head(&active
, val
);
846 foreach(val
, &inactive
)
847 if (livei_have_overlap(val
, cur
))
850 foreach(val
, &unhandled
)
851 if (val
->reg
.id
>= 0 && livei_have_overlap(val
, cur
))
854 if (cur
->reg
.id
< 0) {
857 if (nv_is_vector_op(cur
->insn
->opcode
))
858 mem
= !reg_assign(&f
, &cur
->insn
->def
[0], 4);
861 mem
= !reg_assign(&f
, &cur
, 1);
864 NOUVEAU_ERR("out of registers\n");
868 insert_at_head(&active
, cur
);
869 reg_occupy(&free
, cur
);
876 nv_pc_exec_pass1(struct nv_pc
*pc
)
878 struct nv_pc_pass
*ctx
;
881 debug_printf("REGISTER ALLOCATION - entering\n");
883 ctx
= CALLOC_STRUCT(nv_pc_pass
);
888 nv_print_program(ctx
->pc
->root
);
890 ctx
->insns
= CALLOC(NV_PC_MAX_INSTRUCTIONS
, sizeof(struct nv_instruction
*));
893 ret
= pass_generate_phi_movs(ctx
, pc
->root
);
896 nv_print_program(ctx
->pc
->root
);
898 for (i
= 0; i
< pc
->loop_nesting_bound
; ++i
) {
900 ret
= pass_build_live_sets(ctx
, pc
->root
);
901 assert(!ret
&& "live sets");
903 NOUVEAU_ERR("failed to build live sets (iteration %d)\n", i
);
909 nv_pc_pass_in_order(pc
->root
, pass_order_instructions
, ctx
);
912 ret
= pass_build_intervals(ctx
, pc
->root
);
913 assert(!ret
&& "build intervals");
915 NOUVEAU_ERR("failed to build live intervals\n");
919 #ifdef NV50_RA_DEBUG_LIVEI
920 for (i
= 0; i
< pc
->num_values
; ++i
)
921 livei_print(&pc
->values
[i
]);
924 for (i
= 0; i
< 2; ++i
) {
925 ret
= pass_join_values(ctx
, i
);
928 ret
= pass_linear_scan(ctx
, i
);
932 assert(!ret
&& "joining");
934 for (i
= 0; i
< pc
->num_values
; ++i
)
935 livei_release(&pc
->values
[i
]);
937 debug_printf("REGISTER ALLOCATION - leaving\n");
938 nv_print_program(ctx
->pc
->root
);