llvm.org GIT mirror llvm / b1290a6
A Partitioned Boolean Quadratic Programming (PBQP) based register allocator. Contributed by Lang Hames. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56959 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 11 years ago
5 changed file(s) with 2214 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
3434 (void) llvm::createLocalRegisterAllocator();
3535 (void) llvm::createBigBlockRegisterAllocator();
3636 (void) llvm::createLinearScanRegisterAllocator();
37 (void) llvm::createPBQPRegisterAllocator();
3738
3839 (void) llvm::createSimpleRegisterCoalescer();
3940
109109 ///
110110 FunctionPass *createLinearScanRegisterAllocator();
111111
112 /// PBQPRegisterAllocation Pass - This pass implements the Partitioned Boolean
113 /// Quadratic Prograaming (PBQP) based register allocator.
114 ///
115 FunctionPass *createPBQPRegisterAllocator();
116
112117 /// SimpleRegisterCoalescing Pass - Coalesce all copies possible. Can run
113118 /// independently of the register allocator.
114119 ///
0 //===---------------- PBQP.cpp --------- PBQP Solver ------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Developed by: Bernhard Scholz
10 // The Univesity of Sydney
11 // http://www.it.usyd.edu.au/~scholz
12 //===----------------------------------------------------------------------===//
13
14
15 #include
16 #include
17
18 #include "PBQP.h"
19
20 namespace llvm {
21
22 /**************************************************************************
23 * Data Structures
24 **************************************************************************/
25
26 /* edge of PBQP graph */
27 typedef struct adjnode {
28 struct adjnode *prev, /* doubly chained list */
29 *succ,
30 *reverse; /* reverse edge */
31 int adj; /* adj. node */
32 PBQPMatrix *costs; /* cost matrix of edge */
33
34 bool tc_valid; /* flag whether following fields are valid */
35 int *tc_safe_regs; /* safe registers */
36 int tc_impact; /* impact */
37 } adjnode;
38
39 /* bucket node */
40 typedef struct bucketnode {
41 struct bucketnode *prev; /* doubly chained list */
42 struct bucketnode *succ;
43 int u; /* node */
44 } bucketnode;
45
46 /* data structure of partitioned boolean quadratic problem */
47 struct pbqp {
48 int num_nodes; /* number of nodes */
49 int max_deg; /* maximal degree of a node */
50 bool solved; /* flag that indicates whether PBQP has been solved yet */
51 bool optimal; /* flag that indicates whether PBQP is optimal */
52 PBQPNum min;
53 bool changed; /* flag whether graph has changed in simplification */
54
55 /* node fields */
56 PBQPVector **node_costs; /* cost vectors of nodes */
57 int *node_deg; /* node degree of nodes */
58 int *solution; /* solution for node */
59 adjnode **adj_list; /* adj. list */
60 bucketnode **bucket_ptr; /* bucket pointer of a node */
61
62 /* node stack */
63 int *stack; /* stack of nodes */
64 int stack_ptr; /* stack pointer */
65
66 /* bucket fields */
67 bucketnode **bucket_list; /* bucket list */
68
69 int num_r0; /* counters for number statistics */
70 int num_ri;
71 int num_rii;
72 int num_rn;
73 int num_rn_special;
74 };
75
76 bool isInf(PBQPNum n) { return n == std::numeric_limits::infinity(); }
77
78 /*****************************************************************************
79 * allocation/de-allocation of pbqp problem
80 ****************************************************************************/
81
82 /* allocate new partitioned boolean quadratic program problem */
83 pbqp *alloc_pbqp(int num_nodes)
84 {
85 pbqp *this_;
86 int u;
87
88 assert(num_nodes > 0);
89
90 /* allocate memory for pbqp data structure */
91 this_ = (pbqp *)malloc(sizeof(pbqp));
92
93 /* Initialize pbqp fields */
94 this_->num_nodes = num_nodes;
95 this_->solved = false;
96 this_->optimal = true;
97 this_->min = 0.0;
98 this_->max_deg = 0;
99 this_->changed = false;
100 this_->num_r0 = 0;
101 this_->num_ri = 0;
102 this_->num_rii = 0;
103 this_->num_rn = 0;
104 this_->num_rn_special = 0;
105
106 /* initialize/allocate stack fields of pbqp */
107 this_->stack = (int *) malloc(sizeof(int)*num_nodes);
108 this_->stack_ptr = 0;
109
110 /* initialize/allocate node fields of pbqp */
111 this_->adj_list = (adjnode **) malloc(sizeof(adjnode *)*num_nodes);
112 this_->node_deg = (int *) malloc(sizeof(int)*num_nodes);
113 this_->solution = (int *) malloc(sizeof(int)*num_nodes);
114 this_->bucket_ptr = (bucketnode **) malloc(sizeof(bucketnode **)*num_nodes);
115 this_->node_costs = (PBQPVector**) malloc(sizeof(PBQPVector*) * num_nodes);
116 for(u=0;u
117 this_->solution[u]=-1;
118 this_->adj_list[u]=NULL;
119 this_->node_deg[u]=0;
120 this_->bucket_ptr[u]=NULL;
121 this_->node_costs[u]=NULL;
122 }
123
124 /* initialize bucket list */
125 this_->bucket_list = NULL;
126
127 return this_;
128 }
129
130 /* free pbqp problem */
131 void free_pbqp(pbqp *this_)
132 {
133 int u;
134 int deg;
135 adjnode *adj_ptr,*adj_next;
136 bucketnode *bucket,*bucket_next;
137
138 assert(this_ != NULL);
139
140 /* free node cost fields */
141 for(u=0;u < this_->num_nodes;u++) {
142 delete this_->node_costs[u];
143 }
144 free(this_->node_costs);
145
146 /* free bucket list */
147 for(deg=0;deg<=this_->max_deg;deg++) {
148 for(bucket=this_->bucket_list[deg];bucket!=NULL;bucket=bucket_next) {
149 this_->bucket_ptr[bucket->u] = NULL;
150 bucket_next = bucket-> succ;
151 free(bucket);
152 }
153 }
154 free(this_->bucket_list);
155
156 /* free adj. list */
157 assert(this_->adj_list != NULL);
158 for(u=0;u < this_->num_nodes; u++) {
159 for(adj_ptr = this_->adj_list[u]; adj_ptr != NULL; adj_ptr = adj_next) {
160 adj_next = adj_ptr -> succ;
161 if (u < adj_ptr->adj) {
162 assert(adj_ptr != NULL);
163 delete adj_ptr->costs;
164 }
165 if (adj_ptr -> tc_safe_regs != NULL) {
166 free(adj_ptr -> tc_safe_regs);
167 }
168 free(adj_ptr);
169 }
170 }
171 free(this_->adj_list);
172
173 /* free other node fields */
174 free(this_->node_deg);
175 free(this_->solution);
176 free(this_->bucket_ptr);
177
178 /* free stack */
179 free(this_->stack);
180
181 /* free pbqp data structure itself */
182 free(this_);
183 }
184
185
186 /****************************************************************************
187 * adj. node routines
188 ****************************************************************************/
189
190 /* find data structure of adj. node of a given node */
191 static
192 adjnode *find_adjnode(pbqp *this_,int u,int v)
193 {
194 adjnode *adj_ptr;
195
196 assert (this_ != NULL);
197 assert (u >= 0 && u < this_->num_nodes);
198 assert (v >= 0 && v < this_->num_nodes);
199 assert(this_->adj_list != NULL);
200
201 for(adj_ptr = this_ -> adj_list[u];adj_ptr != NULL; adj_ptr = adj_ptr -> succ) {
202 if (adj_ptr->adj == v) {
203 return adj_ptr;
204 }
205 }
206 return NULL;
207 }
208
209 /* allocate a new data structure for adj. node */
210 static
211 adjnode *alloc_adjnode(pbqp *this_,int u, PBQPMatrix *costs)
212 {
213 adjnode *p;
214
215 assert(this_ != NULL);
216 assert(costs != NULL);
217 assert(u >= 0 && u < this_->num_nodes);
218
219 p = (adjnode *)malloc(sizeof(adjnode));
220 assert(p != NULL);
221
222 p->adj = u;
223 p->costs = costs;
224
225 p->tc_valid= false;
226 p->tc_safe_regs = NULL;
227 p->tc_impact = 0;
228
229 return p;
230 }
231
232 /* insert adjacence node to adj. list */
233 static
234 void insert_adjnode(pbqp *this_, int u, adjnode *adj_ptr)
235 {
236
237 assert(this_ != NULL);
238 assert(adj_ptr != NULL);
239 assert(u >= 0 && u < this_->num_nodes);
240
241 /* if adjacency list of node is not empty -> update
242 first node of the list */
243 if (this_ -> adj_list[u] != NULL) {
244 assert(this_->adj_list[u]->prev == NULL);
245 this_->adj_list[u] -> prev = adj_ptr;
246 }
247
248 /* update doubly chained list pointers of pointers */
249 adj_ptr -> succ = this_->adj_list[u];
250 adj_ptr -> prev = NULL;
251
252 /* update adjacency list pointer of node u */
253 this_->adj_list[u] = adj_ptr;
254 }
255
256 /* remove entry in an adj. list */
257 static
258 void remove_adjnode(pbqp *this_, int u, adjnode *adj_ptr)
259 {
260 assert(this_!= NULL);
261 assert(u >= 0 && u <= this_->num_nodes);
262 assert(this_->adj_list != NULL);
263 assert(adj_ptr != NULL);
264
265 if (adj_ptr -> prev == NULL) {
266 this_->adj_list[u] = adj_ptr -> succ;
267 } else {
268 adj_ptr -> prev -> succ = adj_ptr -> succ;
269 }
270
271 if (adj_ptr -> succ != NULL) {
272 adj_ptr -> succ -> prev = adj_ptr -> prev;
273 }
274
275 if(adj_ptr->reverse != NULL) {
276 adjnode *rev = adj_ptr->reverse;
277 rev->reverse = NULL;
278 }
279
280 if (adj_ptr -> tc_safe_regs != NULL) {
281 free(adj_ptr -> tc_safe_regs);
282 }
283
284 free(adj_ptr);
285 }
286
287 /*****************************************************************************
288 * node functions
289 ****************************************************************************/
290
291 /* get degree of a node */
292 static
293 int get_deg(pbqp *this_,int u)
294 {
295 adjnode *adj_ptr;
296 int deg = 0;
297
298 assert(this_ != NULL);
299 assert(u >= 0 && u < this_->num_nodes);
300 assert(this_->adj_list != NULL);
301
302 for(adj_ptr = this_ -> adj_list[u];adj_ptr != NULL; adj_ptr = adj_ptr -> succ) {
303 deg ++;
304 }
305 return deg;
306 }
307
308 /* reinsert node */
309 static
310 void reinsert_node(pbqp *this_,int u)
311 {
312 adjnode *adj_u,
313 *adj_v;
314
315 assert(this_!= NULL);
316 assert(u >= 0 && u <= this_->num_nodes);
317 assert(this_->adj_list != NULL);
318
319 for(adj_u = this_ -> adj_list[u]; adj_u != NULL; adj_u = adj_u -> succ) {
320 int v = adj_u -> adj;
321 adj_v = alloc_adjnode(this_,u,adj_u->costs);
322 insert_adjnode(this_,v,adj_v);
323 }
324 }
325
326 /* remove node */
327 static
328 void remove_node(pbqp *this_,int u)
329 {
330 adjnode *adj_ptr;
331
332 assert(this_!= NULL);
333 assert(u >= 0 && u <= this_->num_nodes);
334 assert(this_->adj_list != NULL);
335
336 for(adj_ptr = this_ -> adj_list[u]; adj_ptr != NULL; adj_ptr = adj_ptr -> succ) {
337 remove_adjnode(this_,adj_ptr->adj,adj_ptr -> reverse);
338 }
339 }
340
341 /*****************************************************************************
342 * edge functions
343 ****************************************************************************/
344
345 /* insert edge to graph */
346 /* (does not check whether edge exists in graph */
347 static
348 void insert_edge(pbqp *this_, int u, int v, PBQPMatrix *costs)
349 {
350 adjnode *adj_u,
351 *adj_v;
352
353 /* create adjanceny entry for u */
354 adj_u = alloc_adjnode(this_,v,costs);
355 insert_adjnode(this_,u,adj_u);
356
357
358 /* create adjanceny entry for v */
359 adj_v = alloc_adjnode(this_,u,costs);
360 insert_adjnode(this_,v,adj_v);
361
362 /* create link for reverse edge */
363 adj_u -> reverse = adj_v;
364 adj_v -> reverse = adj_u;
365 }
366
367 /* delete edge */
368 static
369 void delete_edge(pbqp *this_,int u,int v)
370 {
371 adjnode *adj_ptr;
372 adjnode *rev;
373
374 assert(this_ != NULL);
375 assert( u >= 0 && u < this_->num_nodes);
376 assert( v >= 0 && v < this_->num_nodes);
377
378 adj_ptr=find_adjnode(this_,u,v);
379 assert(adj_ptr != NULL);
380 assert(adj_ptr->reverse != NULL);
381
382 delete adj_ptr -> costs;
383
384 rev = adj_ptr->reverse;
385 remove_adjnode(this_,u,adj_ptr);
386 remove_adjnode(this_,v,rev);
387 }
388
389 /*****************************************************************************
390 * cost functions
391 ****************************************************************************/
392
393 /* Note: Since cost(u,v) = transpose(cost(v,u)), it would be necessary to store
394 two matrices for both edges (u,v) and (v,u). However, we only store the
395 matrix for the case u < v. For the other case we transpose the stored matrix
396 if required.
397 */
398
399 /* add costs to cost vector of a node */
400 void add_pbqp_nodecosts(pbqp *this_,int u, PBQPVector *costs)
401 {
402 assert(this_ != NULL);
403 assert(costs != NULL);
404 assert(u >= 0 && u <= this_->num_nodes);
405
406 if (!this_->node_costs[u]) {
407 this_->node_costs[u] = new PBQPVector(*costs);
408 } else {
409 *this_->node_costs[u] += *costs;
410 }
411 }
412
413 /* get cost matrix ptr */
414 static
415 PBQPMatrix *get_costmatrix_ptr(pbqp *this_, int u, int v)
416 {
417 adjnode *adj_ptr;
418 PBQPMatrix *m = NULL;
419
420 assert (this_ != NULL);
421 assert (u >= 0 && u < this_->num_nodes);
422 assert (v >= 0 && v < this_->num_nodes);
423
424 adj_ptr = find_adjnode(this_,u,v);
425
426 if (adj_ptr != NULL) {
427 m = adj_ptr -> costs;
428 }
429
430 return m;
431 }
432
433 /* get cost matrix ptr */
434 /* Note: only the pointer is returned for
435 cost(u,v), if u < v.
436 */
437 static
438 PBQPMatrix *pbqp_get_costmatrix(pbqp *this_, int u, int v)
439 {
440 adjnode *adj_ptr = find_adjnode(this_,u,v);
441
442 if (adj_ptr != NULL) {
443 if ( u < v) {
444 return new PBQPMatrix(*adj_ptr->costs);
445 } else {
446 return new PBQPMatrix(adj_ptr->costs->transpose());
447 }
448 } else {
449 return NULL;
450 }
451 }
452
453 /* add costs to cost matrix of an edge */
454 void add_pbqp_edgecosts(pbqp *this_,int u,int v, PBQPMatrix *costs)
455 {
456 PBQPMatrix *adj_costs;
457
458 assert(this_!= NULL);
459 assert(costs != NULL);
460 assert(u >= 0 && u <= this_->num_nodes);
461 assert(v >= 0 && v <= this_->num_nodes);
462
463 /* does the edge u-v exists ? */
464 if (u == v) {
465 PBQPVector *diag = new PBQPVector(costs->diagonalize());
466 add_pbqp_nodecosts(this_,v,diag);
467 delete diag;
468 } else if ((adj_costs = get_costmatrix_ptr(this_,u,v))!=NULL) {
469 if ( u < v) {
470 *adj_costs += *costs;
471 } else {
472 *adj_costs += costs->transpose();
473 }
474 } else {
475 adj_costs = new PBQPMatrix((u < v) ? *costs : costs->transpose());
476 insert_edge(this_,u,v,adj_costs);
477 }
478 }
479
480 /* remove bucket from bucket list */
481 static
482 void pbqp_remove_bucket(pbqp *this_, bucketnode *bucket)
483 {
484 int u = bucket->u;
485
486 assert(this_ != NULL);
487 assert(u >= 0 && u < this_->num_nodes);
488 assert(this_->bucket_list != NULL);
489 assert(this_->bucket_ptr[u] != NULL);
490
491 /* update predecessor node in bucket list
492 (if no preceeding bucket exists, then
493 the bucket_list pointer needs to be
494 updated.)
495 */
496 if (bucket->prev != NULL) {
497 bucket->prev-> succ = bucket->succ;
498 } else {
499 this_->bucket_list[this_->node_deg[u]] = bucket -> succ;
500 }
501
502 /* update successor node in bucket list */
503 if (bucket->succ != NULL) {
504 bucket->succ-> prev = bucket->prev;
505 }
506 }
507
508 /**********************************************************************************
509 * pop functions
510 **********************************************************************************/
511
512 /* pop node of given degree */
513 static
514 int pop_node(pbqp *this_,int deg)
515 {
516 bucketnode *bucket;
517 int u;
518
519 assert(this_ != NULL);
520 assert(deg >= 0 && deg <= this_->max_deg);
521 assert(this_->bucket_list != NULL);
522
523 /* get first bucket of bucket list */
524 bucket = this_->bucket_list[deg];
525 assert(bucket != NULL);
526
527 /* remove bucket */
528 pbqp_remove_bucket(this_,bucket);
529 u = bucket->u;
530 free(bucket);
531 return u;
532 }
533
534 /**********************************************************************************
535 * reorder functions
536 **********************************************************************************/
537
538 /* add bucket to bucketlist */
539 static
540 void add_to_bucketlist(pbqp *this_,bucketnode *bucket, int deg)
541 {
542 bucketnode *old_head;
543
544 assert(bucket != NULL);
545 assert(this_ != NULL);
546 assert(deg >= 0 && deg <= this_->max_deg);
547 assert(this_->bucket_list != NULL);
548
549 /* store node degree (for re-ordering purposes)*/
550 this_->node_deg[bucket->u] = deg;
551
552 /* put bucket to front of doubly chained list */
553 old_head = this_->bucket_list[deg];
554 bucket -> prev = NULL;
555 bucket -> succ = old_head;
556 this_ -> bucket_list[deg] = bucket;
557 if (bucket -> succ != NULL ) {
558 assert ( old_head -> prev == NULL);
559 old_head -> prev = bucket;
560 }
561 }
562
563
564 /* reorder node in bucket list according to
565 current node degree */
566 static
567 void reorder_node(pbqp *this_, int u)
568 {
569 int deg;
570
571 assert(this_ != NULL);
572 assert(u>= 0 && u < this_->num_nodes);
573 assert(this_->bucket_list != NULL);
574 assert(this_->bucket_ptr[u] != NULL);
575
576 /* get current node degree */
577 deg = get_deg(this_,u);
578
579 /* remove bucket from old bucket list only
580 if degree of node has changed. */
581 if (deg != this_->node_deg[u]) {
582 pbqp_remove_bucket(this_,this_->bucket_ptr[u]);
583 add_to_bucketlist(this_,this_->bucket_ptr[u],deg);
584 }
585 }
586
587 /* reorder adj. nodes of a node */
588 static
589 void reorder_adjnodes(pbqp *this_,int u)
590 {
591 adjnode *adj_ptr;
592
593 assert(this_!= NULL);
594 assert(u >= 0 && u <= this_->num_nodes);
595 assert(this_->adj_list != NULL);
596
597 for(adj_ptr = this_ -> adj_list[u]; adj_ptr != NULL; adj_ptr = adj_ptr -> succ) {
598 reorder_node(this_,adj_ptr->adj);
599 }
600 }
601
602 /**********************************************************************************
603 * creation functions
604 **********************************************************************************/
605
606 /* create new bucket entry */
607 /* consistency of the bucket list is not checked! */
608 static
609 void create_bucket(pbqp *this_,int u,int deg)
610 {
611 bucketnode *bucket;
612
613 assert(this_ != NULL);
614 assert(u >= 0 && u < this_->num_nodes);
615 assert(this_->bucket_list != NULL);
616
617 bucket = (bucketnode *)malloc(sizeof(bucketnode));
618 assert(bucket != NULL);
619
620 bucket -> u = u;
621 this_->bucket_ptr[u] = bucket;
622
623 add_to_bucketlist(this_,bucket,deg);
624 }
625
626 /* create bucket list */
627 static
628 void create_bucketlist(pbqp *this_)
629 {
630 int u;
631 int max_deg;
632 int deg;
633
634 assert(this_ != NULL);
635 assert(this_->bucket_list == NULL);
636
637 /* determine max. degree of the nodes */
638 max_deg = 2; /* at least of degree two! */
639 for(u=0;unum_nodes;u++) {
640 deg = this_->node_deg[u] = get_deg(this_,u);
641 if (deg > max_deg) {
642 max_deg = deg;
643 }
644 }
645 this_->max_deg = max_deg;
646
647 /* allocate bucket list */
648 this_ -> bucket_list = (bucketnode **)malloc(sizeof(bucketnode *)*(max_deg + 1));
649 memset(this_->bucket_list,0,sizeof(bucketnode *)*(max_deg + 1));
650 assert(this_->bucket_list != NULL);
651
652 /* insert nodes to the list */
653 for(u=0;unum_nodes;u++) {
654 create_bucket(this_,u,this_->node_deg[u]);
655 }
656 }
657
658 /*****************************************************************************
659 * PBQP simplification for trivial nodes
660 ****************************************************************************/
661
662 /* remove trivial node with cost vector length of one */
663 static
664 void disconnect_trivialnode(pbqp *this_,int u)
665 {
666 int v;
667 adjnode *adj_ptr,
668 *next;
669 PBQPMatrix *c_uv;
670 PBQPVector *c_v;
671
672 assert(this_ != NULL);
673 assert(this_->node_costs != NULL);
674 assert(u >= 0 && u < this_ -> num_nodes);
675 assert(this_->node_costs[u]->getLength() == 1);
676
677 /* add edge costs to node costs of adj. nodes */
678 for(adj_ptr = this_->adj_list[u]; adj_ptr != NULL; adj_ptr = next){
679 next = adj_ptr -> succ;
680 v = adj_ptr -> adj;
681 assert(v >= 0 && v < this_ -> num_nodes);
682
683 /* convert matrix to cost vector offset for adj. node */
684 c_uv = pbqp_get_costmatrix(this_,u,v);
685 c_v = new PBQPVector(c_uv->getRowAsVector(0));
686 *this_->node_costs[v] += *c_v;
687
688 /* delete edge & free vec/mat */
689 delete c_v;
690 delete c_uv;
691 delete_edge(this_,u,v);
692 }
693 }
694
695 /* find all trivial nodes and disconnect them */
696 static
697 void eliminate_trivial_nodes(pbqp *this_)
698 {
699 int u;
700
701 assert(this_ != NULL);
702 assert(this_ -> node_costs != NULL);
703
704 for(u=0;u < this_ -> num_nodes; u++) {
705 if (this_->node_costs[u]->getLength() == 1) {
706 disconnect_trivialnode(this_,u);
707 }
708 }
709 }
710
711 /*****************************************************************************
712 * Normal form for PBQP
713 ****************************************************************************/
714
715 /* simplify a cost matrix. If the matrix
716 is independent, then simplify_matrix
717 returns true - otherwise false. In
718 vectors u and v the offset values of
719 the decomposition are stored.
720 */
721
722 static
723 bool normalize_matrix(PBQPMatrix *m, PBQPVector *u, PBQPVector *v)
724 {
725 assert( m != NULL);
726 assert( u != NULL);
727 assert( v != NULL);
728 assert( u->getLength() > 0);
729 assert( v->getLength() > 0);
730
731 assert(m->getRows() == u->getLength());
732 assert(m->getCols() == v->getLength());
733
734 /* determine u vector */
735 for(unsigned r = 0; r < m->getRows(); ++r) {
736 PBQPNum min = m->getRowMin(r);
737 (*u)[r] += min;
738 if (!isInf(min)) {
739 m->subFromRow(r, min);
740 } else {
741 m->setRow(r, 0);
742 }
743 }
744
745 /* determine v vector */
746 for(unsigned c = 0; c < m->getCols(); ++c) {
747 PBQPNum min = m->getColMin(c);
748 (*v)[c] += min;
749 if (!isInf(min)) {
750 m->subFromCol(c, min);
751 } else {
752 m->setCol(c, 0);
753 }
754 }
755
756 /* determine whether matrix is
757 independent or not.
758 */
759 return m->isZero();
760 }
761
762 /* simplify single edge */
763 static
764 void simplify_edge(pbqp *this_,int u,int v)
765 {
766 PBQPMatrix *costs;
767 bool is_zero;
768
769 assert (this_ != NULL);
770 assert (u >= 0 && u num_nodes);
771 assert (v >= 0 && v num_nodes);
772 assert (u != v);
773
774 /* swap u and v if u > v in order to avoid un-necessary
775 tranpositions of the cost matrix */
776
777 if (u > v) {
778 int swap = u;
779 u = v;
780 v = swap;
781 }
782
783 /* get cost matrix and simplify it */
784 costs = get_costmatrix_ptr(this_,u,v);
785 is_zero=normalize_matrix(costs,this_->node_costs[u],this_->node_costs[v]);
786
787 /* delete edge */
788 if(is_zero){
789 delete_edge(this_,u,v);
790 this_->changed = true;
791 }
792 }
793
794 /* normalize cost matrices and remove
795 edges in PBQP if they ary independent,
796 i.e. can be decomposed into two
797 cost vectors.
798 */
799 static
800 void eliminate_independent_edges(pbqp *this_)
801 {
802 int u,v;
803 adjnode *adj_ptr,*next;
804
805 assert(this_ != NULL);
806 assert(this_ -> adj_list != NULL);
807
808 this_->changed = false;
809 for(u=0;u < this_->num_nodes;u++) {
810 for (adj_ptr = this_ -> adj_list[u]; adj_ptr != NULL; adj_ptr = next) {
811 next = adj_ptr -> succ;
812 v = adj_ptr -> adj;
813 assert(v >= 0 && v < this_->num_nodes);
814 if (u < v) {
815 simplify_edge(this_,u,v);
816 }
817 }
818 }
819 }
820
821
822 /*****************************************************************************
823 * PBQP reduction rules
824 ****************************************************************************/
825
826 /* RI reduction
827 This reduction rule is applied for nodes
828 of degree one. */
829
830 static
831 void apply_RI(pbqp *this_,int x)
832 {
833 int y;
834 unsigned xlen,
835 ylen;
836 PBQPMatrix *c_yx;
837 PBQPVector *c_x, *delta;
838
839 assert(this_ != NULL);
840 assert(x >= 0 && x < this_->num_nodes);
841 assert(this_ -> adj_list[x] != NULL);
842 assert(this_ -> adj_list[x] -> succ == NULL);
843
844 /* get adjacence matrix */
845 y = this_ -> adj_list[x] -> adj;
846 assert(y >= 0 && y < this_->num_nodes);
847
848 /* determine length of cost vectors for node x and y */
849 xlen = this_ -> node_costs[x]->getLength();
850 ylen = this_ -> node_costs[y]->getLength();
851
852 /* get cost vector c_x and matrix c_yx */
853 c_x = this_ -> node_costs[x];
854 c_yx = pbqp_get_costmatrix(this_,y,x);
855 assert (c_yx != NULL);
856
857
858 /* allocate delta vector */
859 delta = new PBQPVector(ylen);
860
861 /* compute delta vector */
862 for(unsigned i = 0; i < ylen; ++i) {
863 PBQPNum min = (*c_yx)[i][0] + (*c_x)[0];
864 for(unsigned j = 1; j < xlen; ++j) {
865 PBQPNum c = (*c_yx)[i][j] + (*c_x)[j];
866 if ( c < min )
867 min = c;
868 }
869 (*delta)[i] = min;
870 }
871
872 /* add delta vector */
873 *this_ -> node_costs[y] += *delta;
874
875 /* delete node x */
876 remove_node(this_,x);
877
878 /* reorder adj. nodes of node x */
879 reorder_adjnodes(this_,x);
880
881 /* push node x on stack */
882 assert(this_ -> stack_ptr < this_ -> num_nodes);
883 this_->stack[this_ -> stack_ptr++] = x;
884
885 /* free vec/mat */
886 delete c_yx;
887 delete delta;
888
889 /* increment counter for number statistic */
890 this_->num_ri++;
891 }
892
893 /* RII reduction
894 This reduction rule is applied for nodes
895 of degree two. */
896
897 static
898 void apply_RII(pbqp *this_,int x)
899 {
900 int y,z;
901 unsigned xlen,ylen,zlen;
902 adjnode *adj_yz;
903
904 PBQPMatrix *c_yx, *c_zx;
905 PBQPVector *cx;
906 PBQPMatrix *delta;
907
908 assert(this_ != NULL);
909 assert(x >= 0 && x < this_->num_nodes);
910 assert(this_ -> adj_list[x] != NULL);
911 assert(this_ -> adj_list[x] -> succ != NULL);
912 assert(this_ -> adj_list[x] -> succ -> succ == NULL);
913
914 /* get adjacence matrix */
915 y = this_ -> adj_list[x] -> adj;
916 z = this_ -> adj_list[x] -> succ -> adj;
917 assert(y >= 0 && y < this_->num_nodes);
918 assert(z >= 0 && z < this_->num_nodes);
919
920 /* determine length of cost vectors for node x and y */
921 xlen = this_ -> node_costs[x]->getLength();
922 ylen = this_ -> node_costs[y]->getLength();
923 zlen = this_ -> node_costs[z]->getLength();
924
925 /* get cost vector c_x and matrix c_yx */
926 cx = this_ -> node_costs[x];
927 c_yx = pbqp_get_costmatrix(this_,y,x);
928 c_zx = pbqp_get_costmatrix(this_,z,x);
929 assert(c_yx != NULL);
930 assert(c_zx != NULL);
931
932 /* Colour Heuristic */
933 if ( (adj_yz = find_adjnode(this_,y,z)) != NULL) {
934 adj_yz->tc_valid = false;
935 adj_yz->reverse->tc_valid = false;
936 }
937
938 /* allocate delta matrix */
939 delta = new PBQPMatrix(ylen, zlen);
940
941 /* compute delta matrix */
942 for(unsigned i=0;i
943 for(unsigned j=0;j
944 PBQPNum min = (*c_yx)[i][0] + (*c_zx)[j][0] + (*cx)[0];
945 for(unsigned k=1;k
946 PBQPNum c = (*c_yx)[i][k] + (*c_zx)[j][k] + (*cx)[k];
947 if ( c < min ) {
948 min = c;
949 }
950 }
951 (*delta)[i][j] = min;
952 }
953 }
954
955 /* add delta matrix */
956 add_pbqp_edgecosts(this_,y,z,delta);
957
958 /* delete node x */
959 remove_node(this_,x);
960
961 /* simplify cost matrix c_yz */
962 simplify_edge(this_,y,z);
963
964 /* reorder adj. nodes */
965 reorder_adjnodes(this_,x);
966
967 /* push node x on stack */
968 assert(this_ -> stack_ptr < this_ -> num_nodes);
969 this_->stack[this_ -> stack_ptr++] = x;
970
971 /* free vec/mat */
972 delete c_yx;
973 delete c_zx;
974 delete delta;
975
976 /* increment counter for number statistic */
977 this_->num_rii++;
978
979 }
980
981 /* RN reduction */
982 static
983 void apply_RN(pbqp *this_,int x)
984 {
985 unsigned xlen;
986
987 assert(this_ != NULL);
988 assert(x >= 0 && x < this_->num_nodes);
989 assert(this_ -> node_costs[x] != NULL);
990
991 xlen = this_ -> node_costs[x] -> getLength();
992
993 /* after application of RN rule no optimality
994 can be guaranteed! */
995 this_ -> optimal = false;
996
997 /* push node x on stack */
998 assert(this_ -> stack_ptr < this_ -> num_nodes);
999 this_->stack[this_ -> stack_ptr++] = x;
1000
1001 /* delete node x */
1002 remove_node(this_,x);
1003
1004 /* reorder adj. nodes of node x */
1005 reorder_adjnodes(this_,x);
1006
1007 /* increment counter for number statistic */
1008 this_->num_rn++;
1009 }
1010
1011
1012 static
1013 void compute_tc_info(pbqp *this_, adjnode *p)
1014 {
1015 adjnode *r;
1016 PBQPMatrix *m;
1017 int x,y;
1018 PBQPVector *c_x, *c_y;
1019 int *row_inf_counts;
1020
1021 assert(p->reverse != NULL);
1022
1023 /* set flags */
1024 r = p->reverse;
1025 p->tc_valid = true;
1026 r->tc_valid = true;
1027
1028 /* get edge */
1029 x = r->adj;
1030 y = p->adj;
1031
1032 /* get cost vectors */
1033 c_x = this_ -> node_costs[x];
1034 c_y = this_ -> node_costs[y];
1035
1036 /* get cost matrix */
1037 m = pbqp_get_costmatrix(this_, x, y);
1038
1039
1040 /* allocate allowed set for edge (x,y) and (y,x) */
1041 if (p->tc_safe_regs == NULL) {
1042 p->tc_safe_regs = (int *) malloc(sizeof(int) * c_x->getLength());
1043 }
1044
1045 if (r->tc_safe_regs == NULL ) {
1046 r->tc_safe_regs = (int *) malloc(sizeof(int) * c_y->getLength());
1047 }
1048
1049 p->tc_impact = r->tc_impact = 0;
1050
1051 row_inf_counts = (int *) alloca(sizeof(int) * c_x->getLength());
1052
1053 /* init arrays */
1054 p->tc_safe_regs[0] = 0;
1055 row_inf_counts[0] = 0;
1056 for(unsigned i = 1; i < c_x->getLength(); ++i){
1057 p->tc_safe_regs[i] = 1;
1058 row_inf_counts[i] = 0;
1059 }
1060
1061 r->tc_safe_regs[0] = 0;
1062 for(unsigned j = 1; j < c_y->getLength(); ++j){
1063 r->tc_safe_regs[j] = 1;
1064 }
1065
1066 for(unsigned j = 0; j < c_y->getLength(); ++j) {
1067 int col_inf_counts = 0;
1068 for (unsigned i = 0; i < c_x->getLength(); ++i) {
1069 if (isInf((*m)[i][j])) {
1070 ++col_inf_counts;
1071 ++row_inf_counts[i];
1072
1073 p->tc_safe_regs[i] = 0;
1074 r->tc_safe_regs[j] = 0;
1075 }
1076 }
1077 if (col_inf_counts > p->tc_impact) {
1078 p->tc_impact = col_inf_counts;
1079 }
1080 }
1081
1082 for(unsigned i = 0; i < c_x->getLength(); ++i){
1083 if (row_inf_counts[i] > r->tc_impact)
1084 {
1085 r->tc_impact = row_inf_counts[i];
1086 }
1087 }
1088
1089 delete m;
1090 }
1091
1092 /*
1093 * Checks whether node x can be locally coloured.
1094 */
1095 static
1096 int is_colorable(pbqp *this_,int x)
1097 {
1098 adjnode *adj_ptr;
1099 PBQPVector *c_x;
1100 int result = 1;
1101 int *allowed;
1102 int num_allowed = 0;
1103 unsigned total_impact = 0;
1104
1105 assert(this_ != NULL);
1106 assert(x >= 0 && x < this_->num_nodes);
1107 assert(this_ -> node_costs[x] != NULL);
1108
1109 c_x = this_ -> node_costs[x];
1110
1111 /* allocate allowed set */
1112 allowed = (int *)malloc(sizeof(int) * c_x->getLength());
1113 for(unsigned i = 0; i < c_x->getLength(); ++i){
1114 if (!isInf((*c_x)[i]) && i > 0) {
1115 allowed[i] = 1;
1116 ++num_allowed;
1117 } else {
1118 allowed[i] = 0;
1119 }
1120 }
1121
1122 /* determine local minimum */
1123 for(adj_ptr=this_->adj_list[x] ;adj_ptr != NULL; adj_ptr = adj_ptr -> succ) {
1124 if (!adj_ptr -> tc_valid) {
1125 compute_tc_info(this_, adj_ptr);
1126 }
1127
1128 total_impact += adj_ptr->tc_impact;
1129
1130 if (num_allowed > 0) {
1131 for (unsigned i = 1; i < c_x->getLength(); ++i){
1132 if (allowed[i]){
1133 if (!adj_ptr->tc_safe_regs[i]){
1134 allowed[i] = 0;
1135 --num_allowed;
1136 if (num_allowed == 0)
1137 break;
1138 }
1139 }
1140 }
1141 }
1142
1143 if ( total_impact >= c_x->getLength() - 1 && num_allowed == 0 ) {
1144 result = 0;
1145 break;
1146 }
1147 }
1148 free(allowed);
1149
1150 return result;
1151 }
1152
1153 /* use briggs heuristic
1154 note: this_ is not a general heuristic. it only is useful for
1155 interference graphs.
1156 */
1157 int pop_colorablenode(pbqp *this_)
1158 {
1159 int deg;
1160 bucketnode *min_bucket=NULL;
1161 PBQPNum min = std::numeric_limits::infinity();
1162
1163 /* select node where the number of colors is less than the node degree */
1164 for(deg=this_->max_deg;deg > 2;deg--) {
1165 bucketnode *bucket;
1166 for(bucket=this_->bucket_list[deg];bucket!= NULL;bucket = bucket -> succ) {
1167 int u = bucket->u;
1168 if (is_colorable(this_,u)) {
1169 pbqp_remove_bucket(this_,bucket);
1170 this_->num_rn_special++;
1171 free(bucket);
1172 return u;
1173 }
1174 }
1175 }
1176
1177 /* select node with minimal ratio between average node costs and degree of node */
1178 for(deg=this_->max_deg;deg >2; deg--) {
1179 bucketnode *bucket;
1180 for(bucket=this_->bucket_list[deg];bucket!= NULL;bucket = bucket -> succ) {
1181 PBQPNum h;
1182 int u;
1183
1184 u = bucket->u;
1185 assert(u>=0 && u < this_->num_nodes);
1186 h = (*this_->node_costs[u])[0] / (PBQPNum) deg;
1187 if (h < min) {
1188 min_bucket = bucket;
1189 min = h;
1190 }
1191 }
1192 }
1193
1194 /* return node and free bucket */
1195 if (min_bucket != NULL) {
1196 int u;
1197
1198 pbqp_remove_bucket(this_,min_bucket);
1199 u = min_bucket->u;
1200 free(min_bucket);
1201 return u;
1202 } else {
1203 return -1;
1204 }
1205 }
1206
1207
1208 /*****************************************************************************
1209 * PBQP graph parsing
1210 ****************************************************************************/
1211
1212 /* reduce pbqp problem (first phase) */
1213 static
1214 void reduce_pbqp(pbqp *this_)
1215 {
1216 int u;
1217
1218 assert(this_ != NULL);
1219 assert(this_->bucket_list != NULL);
1220
1221 for(;;){
1222
1223 if (this_->bucket_list[1] != NULL) {
1224 u = pop_node(this_,1);
1225 apply_RI(this_,u);
1226 } else if (this_->bucket_list[2] != NULL) {
1227 u = pop_node(this_,2);
1228 apply_RII(this_,u);
1229 } else if ((u = pop_colorablenode(this_)) != -1) {
1230 apply_RN(this_,u);
1231 } else {
1232 break;
1233 }
1234 }
1235 }
1236
1237 /*****************************************************************************
1238 * PBQP back propagation
1239 ****************************************************************************/
1240
1241 /* determine solution of a reduced node. Either
1242 RI or RII was applied for this_ node. */
1243 static
1244 void determine_solution(pbqp *this_,int x)
1245 {
1246 PBQPVector *v = new PBQPVector(*this_ -> node_costs[x]);
1247 adjnode *adj_ptr;
1248
1249 assert(this_ != NULL);
1250 assert(x >= 0 && x < this_->num_nodes);
1251 assert(this_ -> adj_list != NULL);
1252 assert(this_ -> solution != NULL);
1253
1254 for(adj_ptr=this_->adj_list[x] ;adj_ptr != NULL; adj_ptr = adj_ptr -> succ) {
1255 int y = adj_ptr -> adj;
1256 int y_sol = this_ -> solution[y];
1257
1258 PBQPMatrix *c_yx = pbqp_get_costmatrix(this_,y,x);
1259 assert(y_sol >= 0 && y_sol < (int)this_->node_costs[y]->getLength());
1260 (*v) += c_yx->getRowAsVector(y_sol);
1261 delete c_yx;
1262 }
1263 this_ -> solution[x] = v->minIndex();
1264
1265 delete v;
1266 }
1267
1268 /* back popagation phase of PBQP */
1269 static
1270 void back_propagate(pbqp *this_)
1271 {
1272 int i;
1273
1274 assert(this_ != NULL);
1275 assert(this_->stack != NULL);
1276 assert(this_->stack_ptr < this_->num_nodes);
1277
1278 for(i=this_ -> stack_ptr-1;i>=0;i--) {
1279 int x = this_ -> stack[i];
1280 assert( x >= 0 && x < this_ -> num_nodes);
1281 reinsert_node(this_,x);
1282 determine_solution(this_,x);
1283 }
1284 }
1285
1286 /* solve trivial nodes of degree zero */
1287 static
1288 void determine_trivialsolution(pbqp *this_)
1289 {
1290 int u;
1291 PBQPNum delta;
1292
1293 assert( this_ != NULL);
1294 assert( this_ -> bucket_list != NULL);
1295
1296 /* determine trivial solution */
1297 while (this_->bucket_list[0] != NULL) {
1298 u = pop_node(this_,0);
1299
1300 assert( u >= 0 && u < this_ -> num_nodes);
1301
1302 this_->solution[u] = this_->node_costs[u]->minIndex();
1303 delta = (*this_->node_costs[u])[this_->solution[u]];
1304 this_->min = this_->min + delta;
1305
1306 /* increment counter for number statistic */
1307 this_->num_r0++;
1308 }
1309 }
1310
1311 /*****************************************************************************
1312 * debug facilities
1313 ****************************************************************************/
1314 static
1315 void check_pbqp(pbqp *this_)
1316 {
1317 int u,v;
1318 PBQPMatrix *costs;
1319 adjnode *adj_ptr;
1320
1321 assert( this_ != NULL);
1322
1323 for(u=0;u< this_->num_nodes; u++) {
1324 assert (this_ -> node_costs[u] != NULL);
1325 for(adj_ptr = this_ -> adj_list[u];adj_ptr != NULL; adj_ptr = adj_ptr -> succ) {
1326 v = adj_ptr -> adj;
1327 assert( v>= 0 && v < this_->num_nodes);
1328 if (u < v ) {
1329 costs = adj_ptr -> costs;
1330 assert( costs->getRows() == this_->node_costs[u]->getLength() &&
1331 costs->getCols() == this_->node_costs[v]->getLength());
1332 }
1333 }
1334 }
1335 }
1336
1337 /*****************************************************************************
1338 * PBQP solve routines
1339 ****************************************************************************/
1340
1341 /* solve PBQP problem */
1342 void solve_pbqp(pbqp *this_)
1343 {
1344 assert(this_ != NULL);
1345 assert(!this_->solved);
1346
1347 /* check vector & matrix dimensions */
1348 check_pbqp(this_);
1349
1350 /* simplify PBQP problem */
1351
1352 /* eliminate trivial nodes, i.e.
1353 nodes with cost vectors of length one. */
1354 eliminate_trivial_nodes(this_);
1355
1356 /* eliminate edges with independent
1357 cost matrices and normalize matrices */
1358 eliminate_independent_edges(this_);
1359
1360 /* create bucket list for graph parsing */
1361 create_bucketlist(this_);
1362
1363 /* reduce phase */
1364 reduce_pbqp(this_);
1365
1366 /* solve trivial nodes */
1367 determine_trivialsolution(this_);
1368
1369 /* back propagation phase */
1370 back_propagate(this_);
1371
1372 this_->solved = true;
1373 }
1374
1375 /* get solution of a node */
1376 int get_pbqp_solution(pbqp *this_,int x)
1377 {
1378 assert(this_ != NULL);
1379 assert(this_->solution != NULL);
1380 assert(this_ -> solved);
1381
1382 return this_->solution[x];
1383 }
1384
1385 /* is solution optimal? */
1386 bool is_pbqp_optimal(pbqp *this_)
1387 {
1388 assert(this_ -> solved);
1389 return this_->optimal;
1390 }
1391
1392 }
1393
1394 /* end of pbqp.c */
0 //===---------------- PBQP.cpp --------- PBQP Solver ------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Developed by: Bernhard Scholz
10 // The Univesity of Sydney
11 // http://www.it.usyd.edu.au/~scholz
12 //===----------------------------------------------------------------------===//
13
14 // TODO:
15 //
16 // * Default to null costs on vector initialisation?
17 // * C++-ify the rest of the solver.
18
19 #ifndef LLVM_CODEGEN_PBQPSOLVER_H
20 #define LLVM_CODEGEN_PBQPSOLVER_H
21
22 #include
23 #include
24 #include
25
26 namespace llvm {
27
28 //! \brief Floating point type to use in PBQP solver.
29 typedef double PBQPNum;
30
31 //! \brief PBQP Vector class.
32 class PBQPVector {
33 public:
34
35 //! \brief Construct a PBQP vector of the given size.
36 explicit PBQPVector(unsigned length) :
37 length(length), data(new PBQPNum[length]) {
38 std::fill(data, data + length, 0);
39 }
40
41 //! \brief Copy construct a PBQP vector.
42 PBQPVector(const PBQPVector &v) :
43 length(v.length), data(new PBQPNum[length]) {
44 std::copy(v.data, v.data + length, data);
45 }
46
47 ~PBQPVector() { delete[] data; }
48
49 //! \brief Assignment operator.
50 PBQPVector& operator=(const PBQPVector &v) {
51 delete[] data;
52 length = v.length;
53 data = new PBQPNum[length];
54 std::copy(v.data, v.data + length, data);
55 return *this;
56 }
57
58 //! \brief Return the length of the vector
59 unsigned getLength() const throw () {
60 return length;
61 }
62
63 //! \brief Element access.
64 PBQPNum& operator[](unsigned index) {
65 assert(index < length && "PBQPVector element access out of bounds.");
66 return data[index];
67 }
68
69 //! \brief Const element access.
70 const PBQPNum& operator[](unsigned index) const {
71 assert(index < length && "PBQPVector element access out of bounds.");
72 return data[index];
73 }
74
75 //! \brief Add another vector to this one.
76 PBQPVector& operator+=(const PBQPVector &v) {
77 assert(length == v.length && "PBQPVector length mismatch.");
78 std::transform(data, data + length, v.data, data, std::plus());
79 return *this;
80 }
81
82 //! \brief Subtract another vector from this one.
83 PBQPVector& operator-=(const PBQPVector &v) {
84 assert(length == v.length && "PBQPVector length mismatch.");
85 std::transform(data, data + length, v.data, data, std::minus());
86 return *this;
87 }
88
89 //! \brief Returns the index of the minimum value in this vector
90 unsigned minIndex() const {
91 return std::min_element(data, data + length) - data;
92 }
93
94 private:
95 unsigned length;
96 PBQPNum *data;
97 };
98
99
100 //! \brief PBQP Matrix class
101 class PBQPMatrix {
102 public:
103
104 //! \brief Construct a PBQP Matrix with the given dimensions.
105 PBQPMatrix(unsigned rows, unsigned cols) :
106 rows(rows), cols(cols), data(new PBQPNum[rows * cols]) {
107 std::fill(data, data + (rows * cols), 0);
108 }
109
110 //! \brief Copy construct a PBQP matrix.
111 PBQPMatrix(const PBQPMatrix &m) :
112 rows(m.rows), cols(m.cols), data(new PBQPNum[rows * cols]) {
113 std::copy(m.data, m.data + (rows * cols), data);
114 }
115
116 ~PBQPMatrix() { delete[] data; }
117
118 //! \brief Assignment operator.
119 PBQPMatrix& operator=(const PBQPMatrix &m) {
120 delete[] data;
121 rows = m.rows; cols = m.cols;
122 data = new PBQPNum[rows * cols];
123 std::copy(m.data, m.data + (rows * cols), data);
124 return *this;
125 }
126
127 //! \brief Return the number of rows in this matrix.
128 unsigned getRows() const throw () { return rows; }
129
130 //! \brief Return the number of cols in this matrix.
131 unsigned getCols() const throw () { return cols; }
132
133 //! \brief Matrix element access.
134 PBQPNum* operator[](unsigned r) {
135 assert(r < rows && "Row out of bounds.");
136 return data + (r * cols);
137 }
138
139 //! \brief Matrix element access.
140 const PBQPNum* operator[](unsigned r) const {
141 assert(r < rows && "Row out of bounds.");
142 return data + (r * cols);
143 }
144
145 //! \brief Returns the given row as a vector.
146 PBQPVector getRowAsVector(unsigned r) const {
147 PBQPVector v(cols);
148 for (unsigned c = 0; c < cols; ++c)
149 v[c] = (*this)[r][c];
150 return v;
151 }
152
153 //! \brief Reset the matrix to the given value.
154 PBQPMatrix& reset(PBQPNum val = 0) {
155 std::fill(data, data + (rows * cols), val);
156 return *this;
157 }
158
159 //! \brief Set a single row of this matrix to the given value.
160 PBQPMatrix& setRow(unsigned r, PBQPNum val) {
161 assert(r < rows && "Row out of bounds.");
162 std::fill(data + (r * cols), data + ((r + 1) * cols), val);
163 return *this;
164 }
165
166 //! \brief Set a single column of this matrix to the given value.
167 PBQPMatrix& setCol(unsigned c, PBQPNum val) {
168 assert(c < cols && "Column out of bounds.");
169 for (unsigned r = 0; r < rows; ++r)
170 (*this)[r][c] = val;
171 return *this;
172 }
173
174 //! \brief Matrix transpose.
175 PBQPMatrix transpose() const {
176 PBQPMatrix m(cols, rows);
177 for (unsigned r = 0; r < rows; ++r)
178 for (unsigned c = 0; c < cols; ++c)
179 m[c][r] = (*this)[r][c];
180 return m;
181 }
182
183 //! \brief Returns the diagonal of the matrix as a vector.
184 //!
185 //! Matrix must be square.
186 PBQPVector diagonalize() const {
187 assert(rows == cols && "Attempt to diagonalize non-square matrix.");
188
189 PBQPVector v(rows);
190 for (unsigned r = 0; r < rows; ++r)
191 v[r] = (*this)[r][r];
192 return v;
193 }
194
195 //! \brief Add the given matrix to this one.
196 PBQPMatrix& operator+=(const PBQPMatrix &m) {
197 assert(rows == m.rows && cols == m.cols &&
198 "Matrix dimensions mismatch.");
199 std::transform(data, data + (rows * cols), m.data, data,
200 std::plus());
201 return *this;
202 }
203
204 //! \brief Returns the minimum of the given row
205 PBQPNum getRowMin(unsigned r) const {
206 assert(r < rows && "Row out of bounds");
207 return *std::min_element(data + (r * cols), data + ((r + 1) * cols));
208 }
209
210 //! \brief Returns the minimum of the given column
211 PBQPNum getColMin(unsigned c) const {
212 PBQPNum minElem = (*this)[0][c];
213 for (unsigned r = 1; r < rows; ++r)
214 if ((*this)[r][c] < minElem) minElem = (*this)[r][c];
215 return minElem;
216 }
217
218 //! \brief Subtracts the given scalar from the elements of the given row.
219 PBQPMatrix& subFromRow(unsigned r, PBQPNum val) {
220 assert(r < rows && "Row out of bounds");
221 std::transform(data + (r * cols), data + ((r + 1) * cols),
222 data + (r * cols),
223 std::bind2nd(std::minus(), val));
224 return *this;
225 }
226
227 //! \brief Subtracts the given scalar from the elements of the given column.
228 PBQPMatrix& subFromCol(unsigned c, PBQPNum val) {
229 for (unsigned r = 0; r < rows; ++r)
230 (*this)[r][c] -= val;
231 return *this;
232 }
233
234 //! \brief Returns true if this is a zero matrix.
235 bool isZero() const {
236 return find_if(data, data + (rows * cols),
237 std::bind2nd(std::not_equal_to(), 0)) ==
238 data + (rows * cols);
239 }
240
241 private:
242 unsigned rows, cols;
243 PBQPNum *data;
244 };
245
246 #define EPS (1E-8)
247
248 #ifndef PBQP_TYPE
249 #define PBQP_TYPE
250 struct pbqp;
251 typedef struct pbqp pbqp;
252 #endif
253
254 /*****************
255 * PBQP routines *
256 *****************/
257
258 /* allocate pbqp problem */
259 pbqp *alloc_pbqp(int num);
260
261 /* add node costs */
262 void add_pbqp_nodecosts(pbqp *this_,int u, PBQPVector *costs);
263
264 /* add edge mat */
265 void add_pbqp_edgecosts(pbqp *this_,int u,int v,PBQPMatrix *costs);
266
267 /* solve PBQP problem */
268 void solve_pbqp(pbqp *this_);
269
270 /* get solution of a node */
271 int get_pbqp_solution(pbqp *this_,int u);
272
273 /* alloc PBQP */
274 pbqp *alloc_pbqp(int num);
275
276 /* free PBQP */
277 void free_pbqp(pbqp *this_);
278
279 /* is optimal */
280 bool is_pbqp_optimal(pbqp *this_);
281
282 }
283 #endif
0 //===------ RegAllocPBQP.cpp ---- PBQP Register Allocator -------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a Partitioned Boolean Quadratic Programming (PBQP) based
10 // register allocator for LLVM. This allocator works by constructing a PBQP
11 // problem representing the register allocation problem under consideration,
12 // solving this using a PBQP solver, and mapping the solution back to a
13 // register assignment. If any variables are selected for spilling then spill
14 // code is inserted and the process repeated.
15 //
16 // The PBQP solver (pbqp.c) provided for this allocator uses a heuristic tuned
17 // for register allocation. For more information on PBQP for register
18 // allocation see the following papers:
19 //
20 // (1) Hames, L. and Scholz, B. 2006. Nearly optimal register allocation with
21 // PBQP. In Proceedings of the 7th Joint Modular Languages Conference
22 // (JMLC'06). LNCS, vol. 4228. Springer, New York, NY, USA. 346-361.
23 //
24 // (2) Scholz, B., Eckstein, E. 2002. Register allocation for irregular
25 // architectures. In Proceedings of the Joint Conference on Languages,
26 // Compilers and Tools for Embedded Systems (LCTES'02), ACM Press, New York,
27 // NY, USA, 139-148.
28 //
29 // Author: Lang Hames
30 // Email: lhames@gmail.com
31 //
32 //===----------------------------------------------------------------------===//
33
34 // TODO:
35 //
36 // * Use of std::set in constructPBQPProblem destroys allocation order preference.
37 // Switch to an order preserving container.
38 //
39 // * Coalescing support.
40
41 #define DEBUG_TYPE "regalloc"
42
43 #include "PBQP.h"
44 #include "VirtRegMap.h"
45 #include "llvm/CodeGen/MachineFunctionPass.h"
46 #include "llvm/CodeGen/RegAllocRegistry.h"
47 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
48 #include "llvm/CodeGen/MachineRegisterInfo.h"
49 #include "llvm/CodeGen/MachineLoopInfo.h"
50 #include "llvm/Target/TargetMachine.h"
51 #include "llvm/Target/TargetInstrInfo.h"
52 #include "llvm/Support/Debug.h"
53 #include
54 #include
55 #include
56 #include
57 #include
58
59 using namespace llvm;
60
61 static RegisterRegAlloc
62 registerPBQPRepAlloc("pbqp", " PBQP register allocator",
63 createPBQPRegisterAllocator);
64
65
66 namespace {
67
68 //!
69 //! PBQP based allocators solve the register allocation problem by mapping
70 //! register allocation problems to Partitioned Boolean Quadratic
71 //! Programming problems.
72 class VISIBILITY_HIDDEN PBQPRegAlloc : public MachineFunctionPass {
73 public:
74
75 static char ID;
76
77 //! Construct a PBQP register allocator.
78 PBQPRegAlloc() : MachineFunctionPass((intptr_t)&ID) {}
79
80 //! Return the pass name.
81 virtual const char* getPassName() const throw() {
82 return "PBQP Register Allocator";
83 }
84
85 //! PBQP analysis usage.
86 virtual void getAnalysisUsage(AnalysisUsage &au) const {
87 au.addRequired();
88 au.addRequired();
89 MachineFunctionPass::getAnalysisUsage(au);
90 }
91
92 //! Perform register allocation
93 virtual bool runOnMachineFunction(MachineFunction &MF);
94
95 private:
96 typedef std::map LI2NodeMap;
97 typedef std::vector Node2LIMap;
98 typedef std::vector AllowedSet;
99 typedef std::vector AllowedSetMap;
100 typedef std::set IgnoreSet;
101
102 MachineFunction *mf;
103 const TargetMachine *tm;
104 const TargetRegisterInfo *tri;
105 const TargetInstrInfo *tii;
106 const MachineLoopInfo *loopInfo;
107 MachineRegisterInfo *mri;
108
109 LiveIntervals *li;
110 VirtRegMap *vrm;
111
112 LI2NodeMap li2Node;
113 Node2LIMap node2LI;
114 AllowedSetMap allowedSets;
115 IgnoreSet ignoreSet;
116
117 //! Builds a PBQP cost vector.
118 template
119 PBQPVector* buildCostVector(const Container &allowed,
120 PBQPNum spillCost) const;
121
122 //! \brief Builds a PBQP interfernce matrix.
123 //!
124 //! @return Either a pointer to a non-zero PBQP matrix representing the
125 //! allocation option costs, or a null pointer for a zero matrix.
126 //!
127 //! Expects allowed sets for two interfering LiveIntervals. These allowed
128 //! sets should contain only allocable registers from the LiveInterval's
129 //! register class, with any interfering pre-colored registers removed.
130 template
131 PBQPMatrix* buildInterferenceMatrix(const Container &allowed1,
132 const Container &allowed2) const;
133
134 //!
135 //! Expects allowed sets for two potentially coalescable LiveIntervals,
136 //! and an estimated benefit due to coalescing. The allowed sets should
137 //! contain only allocable registers from the LiveInterval's register
138 //! classes, with any interfering pre-colored registers removed.
139 template
140 PBQPMatrix* buildCoalescingMatrix(const Container &allowed1,
141 const Container &allowed2,
142 PBQPNum cBenefit) const;
143
144 //! \brief Helper functior for constructInitialPBQPProblem().
145 //!
146 //! This function iterates over the Function we are about to allocate for
147 //! and computes spill costs.
148 void calcSpillCosts();
149
150 //! \brief Scans the MachineFunction being allocated to find coalescing
151 // opportunities.
152 void findCoalescingOpportunities();
153
154 //! \brief Constructs a PBQP problem representation of the register
155 //! allocation problem for this function.
156 //!
157 //! @return a PBQP solver object for the register allocation problem.
158 pbqp* constructPBQPProblem();
159
160 //! \brief Given a solved PBQP problem maps this solution back to a register
161 //! assignment.
162 bool mapPBQPToRegAlloc(pbqp *problem);
163
164 };
165
166 char PBQPRegAlloc::ID = 0;
167 }
168
169
170 template
171 PBQPVector* PBQPRegAlloc::buildCostVector(const Container &allowed,
172 PBQPNum spillCost) const {
173
174 // Allocate vector. Additional element (0th) used for spill option
175 PBQPVector *v = new PBQPVector(allowed.size() + 1);
176
177 (*v)[0] = spillCost;
178
179 return v;
180 }
181
182 template
183 PBQPMatrix* PBQPRegAlloc::buildInterferenceMatrix(
184 const Container &allowed1, const Container &allowed2) const {
185
186 typedef typename Container::const_iterator ContainerIterator;
187
188 // Construct a PBQP matrix representing the cost of allocation options. The
189 // rows and columns correspond to the allocation options for the two live
190 // intervals. Elements will be infinite where corresponding registers alias,
191 // since we cannot allocate aliasing registers to interfering live intervals.
192 // All other elements (non-aliasing combinations) will have zero cost. Note
193 // that the spill option (element 0,0) has zero cost, since we can allocate
194 // both intervals to memory safely (the cost for each individual allocation
195 // to memory is accounted for by the cost vectors for each live interval).
196 PBQPMatrix *m = new PBQPMatrix(allowed1.size() + 1, allowed2.size() + 1);
197
198 // Assume this is a zero matrix until proven otherwise. Zero matrices occur
199 // between interfering live ranges with non-overlapping register sets (e.g.
200 // non-overlapping reg classes, or disjoint sets of allowed regs within the
201 // same class). The term "overlapping" is used advisedly: sets which do not
202 // intersect, but contain registers which alias, will have non-zero matrices.
203 // We optimize zero matrices away to improve solver speed.
204 bool isZeroMatrix = true;
205
206
207 // Row index. Starts at 1, since the 0th row is for the spill option, which
208 // is always zero.
209 unsigned ri = 1;
210
211 // Iterate over allowed sets, insert infinities where required.
212 for (ContainerIterator a1Itr = allowed1.begin(), a1End = allowed1.end();
213 a1Itr != a1End; ++a1Itr) {
214
215 // Column index, starts at 1 as for row index.
216 unsigned ci = 1;
217 unsigned reg1 = *a1Itr;
218
219 for (ContainerIterator a2Itr = allowed2.begin(), a2End = allowed2.end();
220 a2Itr != a2End; ++a2Itr) {
221
222 unsigned reg2 = *a2Itr;
223
224 // If the row/column regs are identical or alias insert an infinity.
225 if ((reg1 == reg2) || tri->areAliases(reg1, reg2)) {
226 (*m)[ri][ci] = std::numeric_limits::infinity();
227 isZeroMatrix = false;
228 }
229
230 ++ci;
231 }
232
233 ++ri;
234 }
235
236 // If this turns out to be a zero matrix...
237 if (isZeroMatrix) {
238 // free it and return null.
239 delete m;
240 return 0;
241 }
242
243 // ...otherwise return the cost matrix.
244 return m;
245 }
246
247 void PBQPRegAlloc::calcSpillCosts() {
248
249 // Calculate the spill cost for each live interval by iterating over the
250 // function counting loads and stores, with loop depth taken into account.
251 for (MachineFunction::const_iterator bbItr = mf->begin(), bbEnd = mf->end();
252 bbItr != bbEnd; ++bbItr) {
253
254 const MachineBasicBlock *mbb = &*bbItr;
255 float loopDepth = loopInfo->getLoopDepth(mbb);
256
257 for (MachineBasicBlock::const_iterator
258 iItr = mbb->begin(), iEnd = mbb->end(); iItr != iEnd; ++iItr) {
259
260 const MachineInstr *instr = &*iItr;
261
262 for (unsigned opNo = 0; opNo < instr->getNumOperands(); ++opNo) {
263
264 const MachineOperand &mo = instr->getOperand(opNo);
265
266 // We're not interested in non-registers...
267 if (!mo.isRegister())
268 continue;
269
270 unsigned moReg = mo.getReg();
271
272 // ...Or invalid registers...
273 if (moReg == 0)
274 continue;
275
276 // ...Or physical registers...
277 if (TargetRegisterInfo::isPhysicalRegister(moReg))
278 continue;
279
280 assert ((mo.isUse() || mo.isDef()) &&
281 "Not a use, not a def, what is it?");
282
283 //... Just the virtual registers. We treat loads and stores as equal.
284 li->getInterval(moReg).weight += powf(10.0f, loopDepth);
285 }
286
287 }
288
289 }
290
291 }
292
293 pbqp* PBQPRegAlloc::constructPBQPProblem() {
294
295 typedef std::vector LIVector;
296 typedef std::set RegSet;
297
298 // These will store the physical & virtual intervals, respectively.
299 LIVector physIntervals, virtIntervals;
300
301 // Start by clearing the old node <-> live interval mappings & allowed sets
302 li2Node.clear();
303 node2LI.clear();
304 allowedSets.clear();
305
306 // Iterate over intervals classifying them as physical or virtual, and
307 // constructing live interval <-> node number mappings.
308 for (LiveIntervals::iterator itr = li->begin(), end = li->end();
309 itr != end; ++itr) {
310
311 if (itr->second->getNumValNums() != 0) {
312 DOUT << "Live range has " << itr->second->getNumValNums() << ": " << itr->second << "\n";
313 }
314
315 if (TargetRegisterInfo::isPhysicalRegister(itr->first)) {
316 physIntervals.push_back(itr->second);
317 mri->setPhysRegUsed(itr->second->reg);
318 }
319 else {
320
321 // If we've allocated this virtual register interval a stack slot on a
322 // previous round then it's not an allocation candidate
323 if (ignoreSet.find(itr->first) != ignoreSet.end())
324 continue;
325
326 li2Node[itr->second] = node2LI.size();
327 node2LI.push_back(itr->second);
328 virtIntervals.push_back(itr->second);
329 }
330 }
331
332 // Early out if there's no regs to allocate for.
333 if (virtIntervals.empty())
334 return 0;
335
336 // Construct a PBQP solver for this problem
337 pbqp *solver = alloc_pbqp(virtIntervals.size());
338
339 // Resize allowedSets container appropriately.
340 allowedSets.resize(virtIntervals.size());
341
342 // Iterate over virtual register intervals to compute allowed sets...
343 for (unsigned node = 0; node < node2LI.size(); ++node) {
344
345 // Grab pointers to the interval and its register class.
346 const LiveInterval *li = node2LI[node];
347 const TargetRegisterClass *liRC = mri->getRegClass(li->reg);
348
349 // Start by assuming all allocable registers in the class are allowed...
350 RegSet liAllowed(liRC->allocation_order_begin(*mf),
351 liRC->allocation_order_end(*mf));
352
353 // If this range is non-empty then eliminate the physical registers which
354 // overlap with this range, along with all their aliases.
355 if (!li->empty()) {
356 for (LIVector::iterator pItr = physIntervals.begin(),
357 pEnd = physIntervals.end(); pItr != pEnd; ++pItr) {
358
359 if (li->overlaps(**pItr)) {
360
361 unsigned pReg = (*pItr)->reg;
362
363 // Remove the overlapping reg...
364 liAllowed.erase(pReg);
365
366 const unsigned *aliasItr = tri->getAliasSet(pReg);
367
368 if (aliasItr != 0) {
369 // ...and its aliases.
370 for (; *aliasItr != 0; ++aliasItr) {
371 liAllowed.erase(*aliasItr);
372 }
373
374 }
375
376 }
377
378 }
379
380 }
381
382 // Copy the allowed set into a member vector for use when constructing cost
383 // vectors & matrices, and mapping PBQP solutions back to assignments.
384 allowedSets[node] = AllowedSet(liAllowed.begin(), liAllowed.end());
385
386 // Set the spill cost to the interval weight, or epsilon if the
387 // interval weight is zero
388 PBQPNum spillCost = (li->weight != 0.0) ?
389 li->weight : std::numeric_limits::min();
390
391 // Build a cost vector for this interval.
392 add_pbqp_nodecosts(solver, node,
393 buildCostVector(allowedSets[node], spillCost));
394
395 }
396
397 // Now add the cost matrices...
398 for (unsigned node1 = 0; node1 < node2LI.size(); ++node1) {
399
400 const LiveInterval *li = node2LI[node1];
401
402 if (li->empty())
403 continue;
404
405 // Test for live range overlaps and insert interference matrices.
406 for (unsigned node2 = node1 + 1; node2 < node2LI.size(); ++node2) {
407 const LiveInterval *li2 = node2LI[node2];
408
409 if (li2->empty())
410 continue;
411
412 if (li->overlaps(*li2)) {
413 PBQPMatrix *m =
414 buildInterferenceMatrix(allowedSets[node1], allowedSets[node2]);
415
416 if (m != 0) {
417 add_pbqp_edgecosts(solver, node1, node2, m);
418 delete m;
419 }
420 }
421 }
422 }
423
424 // We're done, PBQP problem constructed - return it.
425 return solver;
426 }
427
428 bool PBQPRegAlloc::mapPBQPToRegAlloc(pbqp *problem) {
429
430 // Set to true if we have any spills
431 bool anotherRoundNeeded = false;
432
433 // Clear the existing allocation.
434 vrm->clearAllVirt();
435
436 // Iterate over the nodes mapping the PBQP solution to a register assignment.
437 for (unsigned node = 0; node < node2LI.size(); ++node) {
438 unsigned symReg = node2LI[node]->reg,
439 allocSelection = get_pbqp_solution(problem, node);
440
441 // If the PBQP solution is non-zero it's a physical register...
442 if (allocSelection != 0) {
443 // Get the physical reg, subtracting 1 to account for the spill option.
444 unsigned physReg = allowedSets[node][allocSelection - 1];
445
446 // Add to the virt reg map and update the used phys regs.
447 vrm->assignVirt2Phys(symReg, physReg);
448 mri->setPhysRegUsed(physReg);
449 }
450 // ...Otherwise it's a spill.
451 else {
452
453 // Make sure we ignore this virtual reg on the next round
454 // of allocation
455 ignoreSet.insert(node2LI[node]->reg);
456
457 float SSWeight;
458
459 // Insert spill ranges for this live range
460 SmallVector spillIs;
461 std::vector newSpills =
462 li->addIntervalsForSpills(*node2LI[node], spillIs, loopInfo, *vrm,
463 SSWeight);
464
465 // We need another round if spill intervals were added.
466 anotherRoundNeeded |= !newSpills.empty();
467 }
468 }
469
470 return !anotherRoundNeeded;
471 }
472
473 bool PBQPRegAlloc::runOnMachineFunction(MachineFunction &MF) {
474
475 mf = &MF;
476 tm = &mf->getTarget();
477 tri = tm->getRegisterInfo();
478 mri = &mf->getRegInfo();
479
480 li = &getAnalysis();
481 loopInfo = &getAnalysis();
482
483 std::auto_ptr vrmAutoPtr(new VirtRegMap(*mf));
484 vrm = vrmAutoPtr.get();
485
486 // Allocator main loop:
487 //
488 // * Map current regalloc problem to a PBQP problem
489 // * Solve the PBQP problem
490 // * Map the solution back to a register allocation
491 // * Spill if necessary
492 //
493 // This process is continued till no more spills are generated.
494
495 bool regallocComplete = false;
496
497 // Calculate spill costs for intervals
498 calcSpillCosts();
499
500 while (!regallocComplete) {
501 pbqp *problem = constructPBQPProblem();
502
503 // Fast out if there's no problem to solve.
504 if (problem == 0)
505 return true;
506
507 solve_pbqp(problem);
508
509 regallocComplete = mapPBQPToRegAlloc(problem);
510
511 free_pbqp(problem);
512 }
513
514 ignoreSet.clear();
515
516 std::auto_ptr spiller(createSpiller());
517
518 spiller->runOnMachineFunction(*mf, *vrm);
519
520 return true;
521 }
522
523 FunctionPass* llvm::createPBQPRegisterAllocator() {
524 return new PBQPRegAlloc();
525 }
526
527
528 #undef DEBUG_TYPE