00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #define __STDC_LIMIT_MACROS
00087 #include <stdint.h>
00088 #ifndef STANDALONE_SWP_ALLOCATOR
00089 #include <stdio.h>
00090 #include <stdarg.h>
00091 #include <vector>
00092 #include <algorithm>
00093 #include <utility>
00094 #include "defs.h"
00095 #include "glob.h"
00096 #include "timing.h"
00097 #include "tracing.h"
00098 #include "cgprep.h"
00099 #include "cg.h"
00100 #include "cg_swp.h"
00101 #include "cg_swp_allocator.h"
00102 #include "cg_swp_options.h"
00103 #include "cg_swp_target.h"
00104 #include "cg_loop.h"
00105
00106 static BOOL Trace_SWP_Alloc = FALSE;
00107 #define SA_TRACE(action) if (Trace_SWP_Alloc) {action;}
00108
00109
00110
00111 #ifdef max
00112 #undef max
00113 #endif
00114 #ifdef min
00115 #undef min
00116 #endif
00117
00118 #endif // ifndef STANDALONE_SWP_ALLOCATOR
00119
00120
00121 #ifdef STANDALONE_SWP_ALLOCATOR
00122 #include <stdio.h>
00123 #include <stdarg.h>
00124 #include <vector>
00125 #include <algorithm>
00126 #include "defs.h"
00127 #include "cg_swp_allocator.h"
00128
00129 #define TFile stdout
00130 #define SA_TRACE(action) action
00131
00132 const char *Swp_Assert_File = NULL;
00133 INT32 Swp_Assert_Line = -1;
00134
00135 void Swp_Assert(const char *msg, ...)
00136 {
00137 char c[512];
00138 va_list arg_ptr;
00139 if (Swp_Assert_File != NULL)
00140 (void)sprintf(&c[0], "SWP_ALLOCATOR ASSERTION (%s:%d): %s\n",
00141 Swp_Assert_File, Swp_Assert_Line, msg);
00142 else
00143 (void)sprintf(&c[0], "SWP_ALLOCATOR ASSERTION: %s\n", msg);
00144
00145 va_start(arg_ptr, msg);
00146 vfprintf(stderr, &c[0], arg_ptr);
00147 va_end(arg_ptr);
00148 }
00149
00150 #endif // STANDALONE_SWP_ALLOCATOR
00151
00152
00153 #define TP_SRA_SUMMARY 0x01 // summary traces
00154 #define TP_SRA_LR_SUMMARY 0x02 // live range summary
00155 #define TP_SRA_LR_DETAIL 0x04 // live range detail
00156 #define TP_SRA_ADJACENCY 0x08 // adjacency matrix
00157 #define TP_SRA_ALLOCATION 0x10 // final allocation
00158 #define TP_SRA_ALLOC_DETAIL 0x20 // allocation detail
00159
00160 static const char ErrTunitChar = '*';
00161 static const char AvailTunitChar = '.';
00162 static const char LiveInChar = '>';
00163 static const char LiveOutChar = '>';
00164
00165 static const char PlotChar[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
00166 '9',
00167 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
00168 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
00169 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
00170 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
00171 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
00172 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
00173
00174
00175
00176
00177
00178 void
00179 SWP_LIFETIME::print(FILE *outf)
00180 {
00181 if (location() == InvalidLoc)
00182 fprintf(outf, "[start,end,omega,alpha]=[%d %d %d %d] UNALLOCATED\n",
00183 start(), end(), omega(), alpha());
00184 else
00185 fprintf(outf, "[start,end,omega,alpha]=[%d %d %d %d] pseudo-loc=%d\n",
00186 start(), end(), omega(), alpha(), location());
00187 }
00188
00189
00190
00191
00192
00193 INT32
00194 SWP_ALLOCATOR::_regnum_dist(const SWP_LIFETIME <1,
00195 const SWP_LIFETIME <2) const
00196 {
00197
00198
00199
00200
00201
00202
00203
00204
00205 const SWP_TUNIT du = lt1.end() - lt2.start();
00206 INT32 d = du/_ii;
00207
00208 Is_True(<1 != <2,
00209 ("Cannot calculate register number distance lifetime and itself"));
00210
00211 if (du > _ii*d)
00212 d += 1;
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 if ( lt2.omega() > 0)
00228 d = std::max(d, lt1.omega());
00229
00230
00231
00232
00233
00234 if ( lt1.alpha() > 0)
00235 d = std::max(d, lt1.alpha());
00236
00237 return d;
00238 }
00239
00240
00241 void
00242 SWP_ALLOCATOR::_calculate_dist(INT32_MATRIX &dist)
00243 {
00244
00245
00246
00247
00248
00249 Is_True(dist.rows() == dist.cols(),
00250 ("Dimensions for distance matrix must be equal"));
00251
00252 for (INT i = 0; i < dist.rows(); i++)
00253 for (INT j = 0; j < i; j++)
00254 {
00255 dist(i,j) = _regnum_dist(_lifetime[i], _lifetime[j]);
00256 dist(j,i) = _regnum_dist(_lifetime[j], _lifetime[i]);
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 class START_TIME_CMP
00272 {
00273 private:
00274
00275 const SWP_ALLOCATOR::LIFETIME_SET *_lt_set;
00276 SWP_TUNIT _ii;
00277
00278 const SWP_LIFETIME &_lt(INT32 i) const {return (*_lt_set)[i];}
00279
00280 public:
00281
00282 START_TIME_CMP(const SWP_ALLOCATOR::LIFETIME_SET <_set, SWP_TUNIT ii):
00283 _lt_set(<_set), _ii(ii)
00284 {}
00285
00286 bool operator ()(INT32 i, INT32 j)
00287 {
00288 return (_lt(i).start() == _lt(j).start()?
00289 _lt(i).end()%_ii < _lt(j).end()%_ii :
00290 _lt(i).start() < _lt(j).start());
00291 }
00292 };
00293
00294
00295 INT32
00296 SWP_ALLOCATOR::_adjacency_order_dist(const INT32_MATRIX &dist,
00297 INT32 from_lt,
00298 INT32 to_lt) const
00299 {
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 return (dist(from_lt, to_lt) * _ii +
00314 (_lifetime[to_lt].start() - _lifetime[from_lt].end()));
00315 }
00316
00317
00318 void
00319 SWP_ALLOCATOR::_adjacency_order_sort(const INT32_MATRIX &dist,
00320 INT32_VECTOR &ordered)
00321 {
00322
00323
00324
00325
00326
00327
00328
00329
00330 INT32_VECTOR sorted(0, 0, SWP_USE_POOL(INT32_VECTOR, _mpool));
00331 BOOL_VECTOR is_sorted(ordered.size(), false,
00332 SWP_USE_POOL(BOOL_VECTOR, _mpool));
00333 INT32 last_lt = 0;
00334
00335 Is_True(ordered.size() > 0,
00336 ("Attempt to sort empty set of lifetimes"));
00337
00338 sorted.reserve(ordered.size());
00339 sorted.push_back(ordered[last_lt]);
00340 is_sorted[last_lt] = true;
00341
00342 for (INT32 i = 1; i < ordered.size(); i++)
00343 {
00344
00345
00346
00347
00348 INT32 min_dist = INT32_MAX;
00349 INT32 next_lt = INT32_MIN;
00350
00351 for (INT32 j = 1; j < ordered.size(); j++)
00352 {
00353 if (!is_sorted[j])
00354 {
00355
00356
00357
00358 const INT32 adj_dist =
00359 _adjacency_order_dist(dist, ordered[last_lt], ordered[j]);
00360
00361 Is_True(adj_dist >= 0,
00362 ("Unexpected negative adjacency order distance"));
00363
00364 if (adj_dist < min_dist)
00365 {
00366 min_dist = adj_dist;
00367 next_lt = j;
00368 }
00369 }
00370 }
00371
00372
00373
00374
00375 sorted.push_back(ordered[next_lt]);
00376 last_lt = next_lt;
00377 is_sorted[last_lt] = true;
00378
00379 }
00380
00381
00382
00383
00384 std::copy(sorted.begin(), sorted.end(), ordered.begin());
00385
00386 }
00387
00388
00389
00390
00391
00392 void
00393 SWP_ALLOCATOR::_update_conflicts(BOOL_MATRIX &conflicts,
00394 const INT32_MATRIX &dist,
00395 INT32_VECTOR::const_iterator begin_unalloced,
00396 INT32_VECTOR::const_iterator end_unalloced,
00397 INT32 new_allocated_lt,
00398 INT32 new_location)
00399 {
00400
00401
00402
00403 for (INT32_VECTOR::const_iterator unallocated = begin_unalloced;
00404 unallocated != end_unalloced;
00405 ++unallocated)
00406 {
00407 const INT32 unallocated_lt = *unallocated;
00408 const INT32 start_loc =
00409 _ub_loc(dist, new_location, new_allocated_lt, unallocated_lt) + 1;
00410 const INT32 end_loc =
00411 _lb_loc(dist, new_location, new_allocated_lt, unallocated_lt);
00412
00413 for (INT32 loc = start_loc; loc < end_loc; loc++)
00414 conflicts(unallocated_lt, _wraparound(loc)) = true;
00415 }
00416 }
00417
00418
00419 INT32
00420 SWP_ALLOCATOR::_num_new_conflicts(
00421 const BOOL_MATRIX &conflicts,
00422 const INT32_MATRIX &dist,
00423 INT32_VECTOR::const_iterator begin_unalloced,
00424 INT32_VECTOR::const_iterator end_unalloced,
00425 INT32 new_allocated_lt,
00426 INT32 new_location) const
00427 {
00428
00429
00430 INT32 sum = 0;
00431
00432 for (INT32_VECTOR::const_iterator unallocated = begin_unalloced;
00433 unallocated != end_unalloced;
00434 ++unallocated)
00435 {
00436 const INT32 unallocated_lt = *unallocated;
00437 const INT32 start_loc =
00438 _ub_loc(dist, new_location, new_allocated_lt, unallocated_lt) + 1;
00439 const INT32 end_loc =
00440 _lb_loc(dist, new_location, new_allocated_lt, unallocated_lt);
00441
00442 for (INT32 loc = start_loc; loc < end_loc; loc++)
00443 if (!conflicts(unallocated_lt, _wraparound(loc)))
00444 sum += 1;
00445 }
00446 return sum;
00447 }
00448
00449
00450
00451
00452
00453 SWP_ALLOCATOR::INT32_PAIR
00454 SWP_ALLOCATOR::_candidate_locs(const INT32_MATRIX &dist,
00455 INT32_VECTOR::const_iterator begin_alloced,
00456 INT32_VECTOR::const_iterator end_alloced,
00457 INT32 candidate_lt) const
00458 {
00459
00460
00461
00462
00463
00464 INT32 from_loc = INT32_MAX;
00465 INT32 to_loc = INT32_MIN;
00466
00467 for (INT32_VECTOR::const_iterator allocated = begin_alloced;
00468 allocated != end_alloced;
00469 ++allocated)
00470 {
00471 const INT32 allocated_lt = *allocated;
00472 const INT32 allocated_loc = _lifetime[allocated_lt].location();
00473
00474 const INT32 ub = _ub_loc(dist, allocated_loc, allocated_lt, candidate_lt);
00475 const INT32 lb = _lb_loc(dist, allocated_loc, allocated_lt, candidate_lt);
00476
00477 if (ub < from_loc)
00478 from_loc = ub;
00479 if (lb > to_loc)
00480 to_loc = lb;
00481 }
00482 return INT32_PAIR(from_loc, to_loc);
00483 }
00484
00485
00486 SWP_ALLOCATOR::INT32_PAIR
00487 SWP_ALLOCATOR::_logical_reg_seq(INT32 lt_idx, INT32 physical_reg) const
00488 {
00489
00490
00491
00492
00493
00494
00495
00496
00497 INT32 first_logical_reg =
00498 _logical_reg(_lifetime[lt_idx].start(), physical_reg);
00499 INT32 last_logical_reg =
00500 _logical_reg(_lifetime[lt_idx].end() - 1, physical_reg);
00501
00502 if (_lifetime[lt_idx].omega() > 0)
00503 first_logical_reg =
00504 std::min(first_logical_reg,
00505 _livein_logical_reg(1, physical_reg));
00506
00507 if (_lifetime[lt_idx].alpha() > 0)
00508 last_logical_reg =
00509 std::max(last_logical_reg,
00510 _liveout_logical_reg(_lifetime[lt_idx].alpha(), physical_reg));
00511
00512 Is_True(first_logical_reg >= physical_reg &&
00513 last_logical_reg >= first_logical_reg,
00514 ("Unexpected logical register range for a physical register"));
00515
00516 return INT32_PAIR(first_logical_reg, last_logical_reg);
00517 }
00518
00519
00520 SWP_ALLOCATOR::STATUS
00521 SWP_ALLOCATOR::_best_fit(const INT32_MATRIX &dist,
00522 const INT32_VECTOR &ordered)
00523 {
00524
00525
00526
00527
00528
00529
00530
00531 INT32_VECTOR::const_iterator current = ordered.begin();
00532 BOOL_MATRIX conflicts(_lifetime.size(), _no_of_regs, false,
00533 SWP_USE_POOL(BOOL_MATRIX, _mpool));
00534
00535 STATUS status = ALLOCATED;
00536 const INT32 first_loc = 0;
00537 INT32_PAIR logical_regs = _logical_reg_seq(*current, first_loc);
00538 INT32 smallest_logical_reg = logical_regs.first;
00539 INT32 largest_logical_reg = logical_regs.second;
00540
00541
00542
00543 if ((largest_logical_reg - smallest_logical_reg + 1) > _no_of_regs)
00544 {
00545 status = NEED_MORE_REGS;
00546 while (current != ordered.end())
00547 {
00548 _lifetime[*current].set_location(SWP_LIFETIME::InvalidLoc);
00549 ++current;
00550 }
00551 }
00552 else
00553 {
00554 _lifetime[*current].set_location(first_loc);
00555 _update_conflicts(conflicts, dist,
00556 current+1, ordered.end(),
00557 *current, first_loc);
00558
00559 SA_TRACE(fprintf(TFile, "candidate locs for %d = (%d to %d): chose %d\n",
00560 *current, first_loc, first_loc, first_loc));
00561 }
00562
00563 for (++current; current != ordered.end() && status == ALLOCATED; ++current)
00564 {
00565 const INT32 candidate_lt = *current;
00566 INT32 best_fit = INT32_MAX;
00567 INT32 best_conflicts = INT32_MAX;
00568 INT32 selected_loc = SWP_LIFETIME::InvalidLoc;
00569 INT32_PAIR selected_logical_regs(0,0);
00570
00571 const INT32_PAIR candidate_locations =
00572 _candidate_locs(dist, ordered.begin(), current, candidate_lt);
00573
00574 Is_True(candidate_locations.first <= candidate_locations.second,
00575 ("Unexpected negative range of physical register locations"));
00576
00577 for (INT32 loc = candidate_locations.second;
00578 loc >= candidate_locations.first;
00579 --loc)
00580 {
00581 if (!_has_conflicts(conflicts, candidate_lt, loc))
00582 {
00583
00584
00585
00586 logical_regs = _logical_reg_seq(candidate_lt, loc);
00587
00588 const INT32 total_logical_regs =
00589 (std::max(logical_regs.second, largest_logical_reg) -
00590 std::min(logical_regs.first, smallest_logical_reg) + 1);
00591
00592
00593
00594
00595
00596 INT32 num_conflicts = INT32_MAX;
00597 if (total_logical_regs <= best_fit)
00598 num_conflicts = _num_new_conflicts(conflicts, dist,
00599 current + 1,
00600 ordered.end(),
00601 candidate_lt, loc);
00602
00603
00604
00605
00606
00607
00608 if (total_logical_regs < best_fit ||
00609 (total_logical_regs == best_fit &&
00610 num_conflicts < best_conflicts))
00611 {
00612 selected_logical_regs = logical_regs;
00613 selected_loc = loc;
00614 best_fit = total_logical_regs;
00615 best_conflicts = num_conflicts;
00616 }
00617 }
00618 }
00619
00620 SA_TRACE(fprintf(TFile, "candidate locs for %d = (%d to %d): chose %d\n",
00621 candidate_lt,
00622 candidate_locations.first,
00623 candidate_locations.second,
00624 selected_loc));
00625
00626
00627
00628
00629 if (smallest_logical_reg > selected_logical_regs.first)
00630 smallest_logical_reg = selected_logical_regs.first;
00631 if (largest_logical_reg < selected_logical_regs.second)
00632 largest_logical_reg = selected_logical_regs.second;
00633
00634
00635
00636
00637 if (selected_loc == SWP_LIFETIME::InvalidLoc ||
00638 (largest_logical_reg - smallest_logical_reg + 1) > _no_of_regs)
00639 {
00640 status = NEED_MORE_REGS;
00641 while (current != ordered.end())
00642 {
00643 _lifetime[*current].set_location(SWP_LIFETIME::InvalidLoc);
00644 ++current;
00645 }
00646 }
00647 else
00648 {
00649 _lifetime[candidate_lt].set_location(selected_loc);
00650 _update_conflicts(conflicts, dist,
00651 current + 1, ordered.end(),
00652 candidate_lt, selected_loc);
00653 }
00654 }
00655
00656 _num_allocated_lifetimes = current - ordered.begin();
00657 _first_log_reg = smallest_logical_reg;
00658 _last_log_reg = largest_logical_reg;
00659 SA_TRACE(fprintf(TFile, "smallest_logical_reg = %d, largest_logical_reg = %d\n",
00660 smallest_logical_reg, largest_logical_reg));
00661
00662 return status;
00663 }
00664
00665
00666
00667
00668
00669 void
00670 SWP_ALLOCATOR::_print_ordered(FILE *outf,
00671 const char *msg,
00672 const INT32_VECTOR &ordered)
00673 {
00674 fprintf(outf, "ORDERED SEQUENCE (%s):", msg);
00675 for (INT32 i = 0; i < ordered.size(); i++)
00676 fprintf(outf, " %d", ordered[i]);
00677 fputc('\n', outf);
00678 }
00679
00680
00681 void
00682 SWP_ALLOCATOR::_print_dist(FILE *outf, INT32_MATRIX &dist)
00683 {
00684 INT32 j;
00685
00686 fprintf(outf, "DISTANCE_MATRIX:");
00687 fprintf(outf, "\n----------------\n");
00688 fprintf(outf, " ||");
00689 for (j = 0; j < dist.cols(); j++)
00690 fprintf(outf, "%.3d|", j);
00691 fprintf(outf, "\n===++");
00692 for (j = 0; j < dist.cols(); j++)
00693 fprintf(outf, "===+");
00694 for (INT32 i = 0; i < dist.rows(); i++)
00695 {
00696 fprintf(outf, "\n%.3d||", i);
00697 for (j = 0; j < dist.cols(); j++)
00698 if (dist(i,j) >= 0)
00699 fprintf(outf, "%.3d|", dist(i,j));
00700 else
00701 fprintf(outf, "%.2d|", dist(i,j));
00702
00703 fprintf(outf, "\n---++");
00704 for (j = 0; j < dist.cols(); j++)
00705 fprintf(outf, "---+");
00706 }
00707 fprintf(outf, "\n\n");
00708 }
00709
00710
00711 void
00712 SWP_ALLOCATOR::_print_status(FILE *outf)
00713 {
00714 fprintf(outf, "\nStatus = ");
00715 switch (_status)
00716 {
00717 case UNALLOCATED:
00718 fprintf(outf, "UNALLOCATED\n");
00719 break;
00720
00721 case ALLOCATED:
00722 fprintf(outf, "ALLOCATED to %d registers\n", num_allocated_regs());
00723 break;
00724
00725 case NEED_MORE_REGS:
00726 fprintf(outf,
00727 "Need more registers; "
00728 #if defined(BUILD_OS_DARWIN)
00729 "gave up after allocating %d (of %ld) lifetimes.\n"
00730 "The last allocation ran the register count up to %d\n",
00731 _num_allocated_lifetimes,
00732 (long) _lifetime.size(),
00733 #else
00734 "gave up after allocating %d (of %d) lifetimes.\n"
00735 "The last allocation ran the register count up to %d\n",
00736 _num_allocated_lifetimes,
00737 _lifetime.size(),
00738 #endif
00739 num_allocated_regs());
00740 break;
00741
00742 default:
00743 fprintf(outf, "\nUNKNOWN STATUS!!\n");
00744 break;
00745 }
00746 }
00747
00748
00749 void
00750 SWP_ALLOCATOR::_plot_line(CHAR_MATRIX &linebuf,
00751 INT32 reg,
00752 SWP_TUNIT from_tunit,
00753 SWP_TUNIT to_tunit,
00754 char plotc)
00755 {
00756 const INT32 rotating_reg = _wraparound(reg, linebuf.rows());
00757
00758 Is_True(from_tunit >= 0 && from_tunit <= to_tunit,
00759 ("Illegal time-line for reg %d (%d to %d)\n",
00760 reg, from_tunit, to_tunit));
00761
00762 for (SWP_TUNIT tunit = from_tunit;
00763 tunit < linebuf.cols() && tunit < to_tunit;
00764 ++tunit)
00765 {
00766 if (linebuf(rotating_reg, tunit) == AvailTunitChar)
00767 linebuf(rotating_reg, tunit) = plotc;
00768 else
00769 linebuf(rotating_reg, tunit) = ErrTunitChar;
00770 }
00771 }
00772
00773
00774 void
00775 SWP_ALLOCATOR::_plot_and_verify(CHAR_MATRIX &linebuf,
00776 INT32 num_used_regs,
00777 INT32 num_loop_iterations)
00778 {
00779
00780
00781
00782
00783 for (INT32 i = 0; i < _lifetime.size(); ++i)
00784 {
00785 const SWP_LIFETIME *lt = &_lifetime[i];
00786
00787 if (lt->location() != SWP_LIFETIME::InvalidLoc)
00788 {
00789 for (INT32 livein = lt->omega(); livein > 0; livein--)
00790 {
00791 const INT32 livein_end = lt->end() - _ii*livein;
00792
00793 if (livein_end >= 0)
00794 {
00795 INT32 reg = lt->location() + livein;
00796 if (reg >= num_used_regs) reg -= num_used_regs;
00797 _plot_line(linebuf,
00798 reg,
00799 0,
00800 livein_end,
00801 LiveInChar);
00802 }
00803 }
00804 for (INT32 iteration = 0; iteration < num_loop_iterations; ++iteration)
00805 {
00806 const char id = PlotChar[i%sizeof(PlotChar)];
00807 _plot_line(linebuf,
00808 lt->location() - iteration,
00809 lt->start() + _ii*iteration,
00810 lt->end() + _ii*iteration,
00811 id);
00812 }
00813 for (INT32 liveout = lt->alpha(); liveout > 0; liveout--)
00814 {
00815 if (liveout <= num_loop_iterations)
00816 {
00817 const INT32 end_iter_reg = lt->location() - num_loop_iterations;
00818 const INT32 lt_end = lt->end() + _ii*(num_loop_iterations - liveout);
00819 _plot_line(linebuf,
00820 end_iter_reg + liveout,
00821 lt_end,
00822 std::max(linebuf.cols(), lt_end),
00823 LiveOutChar);
00824 }
00825 }
00826 }
00827 }
00828 }
00829
00830
00831 void
00832 SWP_ALLOCATOR::_print_location_map(FILE *outf,
00833 INT32 num_loop_iterations,
00834 INT32 plot_cols)
00835 {
00836
00837
00838
00839
00840 const INT32 tunits_to_print = (_sc + num_loop_iterations)*_ii;
00841 const INT32 num_used_regs = num_allocated_regs();
00842 CHAR_MATRIX linebuf(num_used_regs, tunits_to_print, AvailTunitChar,
00843 SWP_USE_POOL(CHAR_MATRIX, _mpool));
00844
00845
00846
00847 _plot_and_verify(linebuf, num_used_regs, num_loop_iterations);
00848
00849
00850
00851
00852
00853 const INT32 num_plots = ((linebuf.cols() - 1)/plot_cols) + 1;
00854
00855 for (INT32 plot = 1; plot <= num_plots; ++plot)
00856 {
00857 const INT32 start_tunit = (plot - 1) * plot_cols;
00858 const INT32 end_tunit = std::min(plot * plot_cols, linebuf.cols());
00859
00860 fprintf(outf, "\nPlot for time units %d to %d\n",
00861 start_tunit, end_tunit - 1);
00862
00863 for (INT32 reg = linebuf.rows() - 1; reg >= 0; --reg)
00864 {
00865 fprintf(outf, "R%.2d ", reg);
00866 for (INT32 tunit = start_tunit; tunit < end_tunit; ++tunit)
00867 fputc(linebuf(reg, tunit), outf);
00868 fputc('\n', outf);
00869 }
00870 }
00871 }
00872
00873
00874 void
00875 SWP_ALLOCATOR::print(FILE *outf, INT32 num_iterations, INT32 plot_width)
00876 {
00877 if (_status == ALLOCATED || _status == NEED_MORE_REGS)
00878 {
00879 SWP_POOL_Push(_mpool);
00880 _print_location_map(outf, num_iterations, plot_width);
00881 SWP_POOL_Pop(_mpool);
00882 }
00883
00884 fprintf(outf, "\nLIFETIMES (ii=%d, sc=%d)\n", _ii, _sc);
00885 for (INT32 i = 0; i < _lifetime.size(); ++i)
00886 {
00887 const char id = PlotChar[i%sizeof(PlotChar)];
00888 SWP_LIFETIME * const lt = &_lifetime[i];
00889 const INT32_PAIR lr = _logical_reg_seq(i, lt->location());
00890
00891 fprintf(outf, "Lifetime=%d, Plot=%c ", i, id);
00892 lt->print(outf);
00893 fprintf(outf, " Logical regs %d..%d ", lr.first, lr.second);
00894 #ifndef STANDALONE_SWP_ALLOCATOR
00895 if (lt->tn() == NULL)
00896 fprintf(outf, "For special NIL tn\n");
00897 else
00898 fPrint_TN(outf, "For %s\n", lt->tn());
00899 #endif // STANDALONE_SWP_ALLOCATOR
00900 }
00901 }
00902
00903
00904
00905
00906
00907 bool SWP_ALLOCATOR::has_conflicts()
00908 {
00909 bool conflict = false;
00910
00911 SWP_POOL_Push(_mpool);
00912 {
00913 const INT32 num_loop_iterations = _sc + 1;
00914 const INT32 tunits_to_print = (_sc + num_loop_iterations)*_ii;
00915 const INT32 num_used_regs = num_allocated_regs();
00916 CHAR_MATRIX linebuf(num_used_regs, tunits_to_print, AvailTunitChar,
00917 SWP_USE_POOL(CHAR_MATRIX, _mpool));
00918
00919
00920
00921
00922 _plot_and_verify(linebuf, num_used_regs, num_loop_iterations);
00923
00924 for (INT32 reg = linebuf.rows() - 1; reg >= 0; --reg)
00925 for (INT32 tunit = linebuf.cols() - 1; tunit >= 0; --tunit)
00926 if (linebuf(reg, tunit) == ErrTunitChar)
00927 conflict = true;
00928 }
00929 SWP_POOL_Pop(_mpool);
00930
00931 return conflict;
00932 }
00933
00934
00935
00936
00937
00938 SWP_ALLOCATOR::STATUS
00939 SWP_ALLOCATOR::_allocate(bool use_adjacency)
00940 {
00941 STATUS status;
00942
00943 SWP_POOL_Push(_mpool);
00944 {
00945 INT32_VECTOR lt_order(0, 0, SWP_USE_POOL(INT32_VECTOR, _mpool));
00946 INT32_MATRIX dist(_lifetime.size(), _lifetime.size(), -1,
00947 SWP_USE_POOL(INT32_MATRIX, _mpool));
00948
00949 if ( Get_Trace ( TP_SRA, TP_SRA_ADJACENCY ) ) {
00950 SA_TRACE(fprintf(TFile,
00951 "\n-------------SWP_ALLOCATOR-------------------\n\n"));
00952 } else {
00953 SA_TRACE(fprintf(TFile,
00954 "\n-------------SWP_ALLOCATOR-------------------\n\n"));
00955 }
00956
00957 if (_lifetime.size() == 0)
00958 return ALLOCATED;
00959
00960
00961
00962
00963
00964
00965 _calculate_dist(dist);
00966
00967 SA_TRACE(_print_dist(TFile, dist));
00968 if ( Get_Trace ( TP_SRA, TP_SRA_ADJACENCY ) ) {
00969 _print_dist(TFile, dist);
00970 } else {
00971 SA_TRACE(_print_dist(TFile, dist));
00972 }
00973
00974
00975
00976
00977
00978
00979 lt_order.reserve(_lifetime.size());
00980 for (INT32 i = 0; i < _lifetime.size(); i++)
00981 lt_order.push_back(i);
00982
00983 SWP_POOL_Push(_mpool);
00984 std::sort(lt_order.begin(), lt_order.end(),
00985 START_TIME_CMP(_lifetime, _ii));
00986 SWP_POOL_Pop(_mpool);
00987 if ( Get_Trace ( TP_SRA, TP_SRA_ADJACENCY ) ) {
00988 _print_ordered(TFile, "start-time", lt_order);
00989 } else {
00990 SA_TRACE(_print_ordered(TFile, "start-time", lt_order));
00991 }
00992
00993
00994
00995
00996
00997
00998
00999 if (use_adjacency)
01000 {
01001 SWP_POOL_Push(_mpool);
01002 _adjacency_order_sort(dist, lt_order);
01003
01004 SWP_POOL_Pop(_mpool);
01005 if ( Get_Trace ( TP_SRA, TP_SRA_ADJACENCY ) ) {
01006 _print_ordered(TFile, "adjacency", lt_order);
01007 } else {
01008 SA_TRACE(_print_ordered(TFile, "adjacency", lt_order));
01009 }
01010 }
01011
01012
01013
01014 status = _best_fit(dist, lt_order);
01015
01016 }
01017 SWP_POOL_Pop(_mpool);
01018
01019 return status;
01020
01021 }
01022
01023
01024
01025
01026
01027 #ifndef STANDALONE_SWP_ALLOCATOR
01028
01029 typedef SWP_ALLOCATOR::LIFETIME_SET LIFETIME_SET;
01030 typedef std::map<TN*, INT32> TN2INT32_MAP;
01031 typedef SWP_REG_ASSIGNMENT::TN2REG_MAP TN2REG_MAP;
01032 typedef SWP_ALLOCATOR::INT32_VECTOR INT32_VECTOR;
01033
01034 inline bool
01035 SWP_Is_Variant(TN_SET *invariants, TN *tn)
01036 {
01037 return (TN_is_register(tn) &&
01038 !TN_is_dedicated(tn) &&
01039 !TN_SET_MemberP(invariants, tn));
01040 }
01041
01042
01043 static void
01044 SWP_Update_Lifetime(TN2INT32_MAP &tn2lt_map,
01045 LIFETIME_SET <,
01046 INT ii_slots,
01047 INT at_slot,
01048 INT end_of_defn_slot,
01049 INT omega,
01050 TN *tn,
01051 bool defn)
01052 {
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064 const INT32 start_slot = (defn? at_slot : INT32_MAX);
01065 const INT32 end_slot = (defn?
01066 end_of_defn_slot :
01067 at_slot + ii_slots*omega + 1);
01068
01069 Is_True((!defn || (omega==0 && start_slot < end_slot)),
01070 ("SWP_REG_ASSIGNMENT: Encountered negative lifetime range!"));
01071
01072
01073
01074 pair<TN2INT32_MAP::iterator, bool> insert_status =
01075 tn2lt_map.insert(TN2INT32_MAP::value_type(tn, -1));
01076
01077 if (insert_status.second)
01078 {
01079 const SWP_LIFETIME new_lt(start_slot, end_slot,
01080 0, 0, tn);
01081
01082 (insert_status.first)->second = lt.size();
01083 lt.push_back(new_lt);
01084 }
01085 else
01086 {
01087 SWP_LIFETIME * const ltp = <[(insert_status.first)->second];
01088
01089 if (start_slot < ltp->start())
01090 ltp->set_start(start_slot);
01091 if (end_slot > ltp->end())
01092 ltp->set_end(end_slot);
01093 }
01094
01095
01096 if ( Get_Trace ( TP_SRA, TP_SRA_LR_DETAIL ) ) {
01097 fprintf ( TFile, "[sra]\tTN%d\t%3d:%3d %s\t%s\n",
01098 TN_number(tn),
01099 start_slot, end_slot,
01100 defn?"def":"use",
01101 insert_status.second ? "" : "(new)" );
01102 };
01103
01104 }
01105
01106
01107 static void
01108 SWP_Gather_Lifetime_Extents(TN2INT32_MAP &tn2lt_map,
01109 LIFETIME_SET lt[ISA_REGISTER_CLASS_MAX+1],
01110 const SWP_OP_vector& op_state,
01111 MEM_POOL *apool)
01112 {
01113 INT i;
01114 INT32_VECTOR last_slot_for_mcycle(op_state.ii, -1024,
01115 SWP_USE_POOL(INT32_VECTOR, apool));
01116
01117
01118
01119 for (i = 0; i < op_state.size(); i++)
01120 if (op_state[i].op != NULL &&
01121 op_state[i].slot > last_slot_for_mcycle[op_state[i].modulo_cycle])
01122 last_slot_for_mcycle[op_state[i].modulo_cycle] = op_state[i].slot;
01123
01124
01125
01126
01127
01128 for (i = 0; i < op_state.size(); i++)
01129 {
01130 OP *op = op_state[i].op;
01131
01132 if (op != NULL)
01133 {
01134
01135
01136
01137
01138
01139
01140
01141
01142 const INT stage_first_slot =
01143 (op_state[i].cycle/op_state.ii) * op_state.ii_slots;
01144 const INT op_at_slot = stage_first_slot + op_state[i].slot;
01145 const INT end_of_defn_slot =
01146 (stage_first_slot +
01147 last_slot_for_mcycle[op_state[i].modulo_cycle] + 1);
01148
01149
01150 if ( Get_Trace ( TP_SRA, TP_SRA_LR_DETAIL ) ) {
01151 fprintf ( TFile, "[sra]\t" );
01152 Print_OP_No_SrcLine(op);
01153 }
01154
01155
01156
01157 for (INT k = 0; k < OP_results(op); k++)
01158 {
01159 TN *tn = OP_result(op, k);
01160
01161 if (SWP_Is_Variant(op_state.tn_non_rotating, tn))
01162 SWP_Update_Lifetime(tn2lt_map,
01163 lt[TN_register_class(tn)],
01164 op_state.ii_slots,
01165 op_at_slot,
01166 end_of_defn_slot,
01167 0,
01168 tn,
01169 TRUE);
01170 }
01171
01172
01173
01174 for (INT j = 0; j < OP_opnds(op); j++)
01175 {
01176 TN *tn = OP_opnd(op, j);
01177
01178 if (SWP_Is_Variant(op_state.tn_non_rotating, tn))
01179 SWP_Update_Lifetime(tn2lt_map,
01180 lt[TN_register_class(tn)],
01181 op_state.ii_slots,
01182 op_at_slot,
01183 0,
01184 OP_omega(op,j),
01185 tn,
01186 FALSE);
01187 }
01188 }
01189 }
01190 }
01191
01192
01193 static INT
01194 Get_Cycle_Of_Defining_SWP_Op (const SWP_OP_vector& op_state, TN *def_tn)
01195 {
01196 INT cycle = -1;
01197 for (INT i = 0; i < op_state.size(); i++) {
01198 OP *op = op_state[i].op;
01199 if (op) {
01200 for (INT k = 0; k < OP_results(op); k++) {
01201 if (OP_result(op,k) == def_tn) {
01202 Is_True(cycle < 0, ("multiple defs of tn %d in SWP body", TN_number(def_tn)));
01203 cycle = op_state[i].cycle;
01204 }
01205 }
01206 }
01207 }
01208 Is_True(cycle >= 0, ("no def of tn %d in SWP body", TN_number(def_tn)));
01209 return cycle;
01210 }
01211
01212 static void
01213 SWP_Gather_Lifetimes(LIFETIME_SET lt[ISA_REGISTER_CLASS_MAX+1],
01214 const SWP_OP_vector& op_state,
01215 BB *head,
01216 BB *tail,
01217 MEM_POOL *apool)
01218 {
01219 CG_LOOP_BACKPATCH *bp;
01220 TN2INT32_MAP tn2lt_map;
01221
01222
01223
01224
01225
01226
01227
01228 SWP_Gather_Lifetime_Extents(tn2lt_map, lt, op_state, apool);
01229
01230
01231
01232
01233 for (bp = CG_LOOP_Backpatch_First(head, NULL);
01234 bp != NULL;
01235 bp = CG_LOOP_Backpatch_Next(bp))
01236 {
01237 TN * const body_tn = CG_LOOP_BACKPATCH_body_tn(bp);
01238 if (SWP_Is_Variant(op_state.tn_non_rotating, body_tn)) {
01239 const INT omega = CG_LOOP_BACKPATCH_omega(bp);
01240 TN2INT32_MAP::iterator map = tn2lt_map.find(body_tn);
01241
01242 Is_True(map != tn2lt_map.end(),
01243 ("SWP_REG_ASSIGNMENT: Cannot find lifetime for prologue tn %d",
01244 TN_number(body_tn)));
01245
01246 SWP_LIFETIME *this_lt = &(lt[TN_register_class(body_tn)][map->second]);
01247
01248 if (this_lt->omega() < omega)
01249 this_lt->set_omega(omega);
01250 }
01251 }
01252
01253
01254
01255
01256 for (bp = CG_LOOP_Backpatch_First(tail, NULL);
01257 bp != NULL;
01258 bp = CG_LOOP_Backpatch_Next(bp)) {
01259 TN * const body_tn = CG_LOOP_BACKPATCH_body_tn(bp);
01260 if (SWP_Is_Variant(op_state.tn_non_rotating, body_tn)) {
01261 INT alpha = CG_LOOP_BACKPATCH_omega(bp) + 1;
01262 #ifdef TARG_IA64
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273 if (TN_register_class(body_tn) == ISA_REGISTER_CLASS_predicate) {
01274 INT def_cycle = Get_Cycle_Of_Defining_SWP_Op (op_state, body_tn);
01275 INT def_stage = (def_cycle/op_state.ii) + 1;
01276 DevWarn("liveout swp predicate, change alpha by %d", (op_state.sc-def_stage));
01277
01278 if ( ! Get_Trace(TP_SRA,0x1000) ) {
01279 alpha += (op_state.sc - def_stage);
01280 }
01281 }
01282 #endif
01283
01284 TN2INT32_MAP::iterator map = tn2lt_map.find(body_tn);
01285 Is_True(map != tn2lt_map.end(),
01286 ("SWP_REG_ASSIGNMENT: Cannot find lifetime for epilogue tn %d",
01287 TN_number(body_tn)));
01288
01289 SWP_LIFETIME *this_lt = &(lt[TN_register_class(body_tn)][map->second]);
01290
01291 if (this_lt->alpha() < alpha)
01292 this_lt->set_alpha(alpha);
01293 }
01294 }
01295
01296
01297
01298
01299
01300
01301
01302 #ifdef TARG_IA64
01303 if (op_state.is_doloop) {
01304 const SWP_LIFETIME
01305 cntrl_pred_lt(0 ,
01306 op_state.sc * op_state.ii_slots ,
01307 0 ,
01308 0 ,
01309 NULL);
01310
01311 lt[ISA_REGISTER_CLASS_predicate].push_back(cntrl_pred_lt);
01312 } else {
01313 TN *ptn = op_state.control_predicate_tn;
01314 Is_True(ptn != NULL, ("couldn't locate control predicate"));
01315 TN2INT32_MAP::iterator map = tn2lt_map.find(ptn);
01316 Is_True(map != tn2lt_map.end(),
01317 ("SWP_REG_ASSIGNMENT: Cannot find lifetime for control predicate tn %d",
01318 TN_number(ptn)));
01319
01320 SWP_LIFETIME *this_lt = &(lt[TN_register_class(ptn)][map->second]);
01321 this_lt->set_start(0);
01322 }
01323 #endif
01324 }
01325
01326
01327 static bool
01328 SWP_Allocate_Rotating_Regs(bool trace,
01329 MEM_POOL *apool,
01330 const SWP_OP_vector& op_state,
01331 ISA_REGISTER_CLASS reg_class,
01332 INT ii,
01333 INT sc,
01334 INT num_regs,
01335 const LIFETIME_SET <,
01336 INT &ctr_pred_loc,
01337 INT &used_regs,
01338 TN2REG_MAP &allocation)
01339 {
01340
01341
01342
01343
01344
01345
01346
01347
01348 SWP_ALLOCATOR allocator(ii, sc, num_regs, lt.begin(), lt.end(), apool);
01349 bool is_alloced = (allocator.status() == SWP_ALLOCATOR::ALLOCATED);
01350 INT max_alloced_reg = 0;
01351
01352
01353
01354
01355 if (!trace)
01356 Is_True(!allocator.has_conflicts(),
01357 ("Conflicts in SWP_Allocate_Rotating_Regs!!"));
01358
01359
01360
01361 used_regs = allocator.num_allocated_regs();
01362 ctr_pred_loc = SWP_LIFETIME::InvalidLoc;
01363
01364 #ifdef TARG_IA64
01365
01366 if (reg_class == ISA_REGISTER_CLASS_predicate) {
01367 #ifdef TARG_IA64
01368 BOOL success = allocator.adjust_predicate(op_state,used_regs);
01369
01370
01371
01372
01373 #endif
01374 }
01375 #endif
01376
01377 if (is_alloced)
01378 {
01379 LIFETIME_SET::const_iterator lt_itr;
01380 INT32 offset = INT32_MAX;
01381
01382
01383
01384
01385
01386 for (lt_itr = allocator.begin(); lt_itr != allocator.end(); ++lt_itr)
01387 if (lt_itr->location() < offset)
01388 offset = lt_itr->location();
01389
01390
01391
01392
01393 for (lt_itr = allocator.begin(); lt_itr != allocator.end(); ++lt_itr)
01394 {
01395 const INT32 loc = lt_itr->location() - offset;
01396
01397 #ifdef TARG_IA64
01398 if (reg_class == ISA_REGISTER_CLASS_predicate &&
01399 (lt_itr->tn() == NULL || lt_itr->tn() == op_state.control_predicate_tn)) {
01400 Is_True(ctr_pred_loc == SWP_LIFETIME::InvalidLoc,
01401 ("SWP_REG_ASSIGNMENT: Allocation has more than one "
01402 "control predicate location"));
01403
01404 ctr_pred_loc = loc;
01405 }
01406 if (reg_class != ISA_REGISTER_CLASS_predicate ||
01407 lt_itr->tn() != NULL) {
01408 Is_True(allocation.find(lt_itr->tn()) == allocation.end(),
01409 ("SWP_REG_ASSIGNMENT: Multiple locations assigned to a TN"));
01410
01411 CLASS_REG_PAIR rp;
01412
01413
01414
01415
01416 Set_CLASS_REG_PAIR(rp, reg_class, loc);
01417 allocation[lt_itr->tn()] = rp;
01418
01419 if (reg_class == ISA_REGISTER_CLASS_integer
01420 && loc > max_alloced_reg)
01421 {
01422 max_alloced_reg = loc;
01423 }
01424 }
01425 #endif
01426 }
01427 }
01428
01429 if (reg_class == ISA_REGISTER_CLASS_integer) {
01430
01431
01432
01433
01434
01435
01436
01437 if ( Get_Trace(TP_SRA,TP_SRA_ALLOCATION) ) {
01438 fprintf ( TFile,
01439 "used_regs = %d, max_alloced_reg = %d\n",
01440 used_regs, max_alloced_reg );
01441 }
01442 if ((used_regs/8) < (max_alloced_reg/8)) {
01443 DevWarn ( "increasing # rotating regs from %d to %d",
01444 used_regs, max_alloced_reg );
01445 }
01446 if (used_regs < max_alloced_reg) {
01447 used_regs = max_alloced_reg;
01448 }
01449 }
01450
01451 if ( Get_Trace(TP_SRA,TP_SRA_ALLOCATION)
01452 && allocator.begin() != allocator.end() )
01453 {
01454 #ifdef TARG_IA64
01455 const ISA_REGISTER_CLASS_INFO *reg_info =
01456 ISA_REGISTER_CLASS_Info(reg_class);
01457
01458 if (ISA_REGISTER_CLASS_INFO_Name(reg_info) != NULL)
01459 fprintf(TFile,
01460 "\n=============== SWP Allocator (%s) ================\n",
01461 ISA_REGISTER_CLASS_INFO_Name(reg_info));
01462 else
01463 #endif
01464 fprintf(TFile,
01465 "\n========= SWP Allocator (Unknown reg class) =========\n");
01466
01467 allocator.print(TFile, sc+3, 70);
01468 }
01469 return is_alloced;
01470
01471 }
01472
01473
01474 bool
01475 SWP_REG_ASSIGNMENT::Allocate_Loop_Variants(const SWP_OP_vector& op_state,
01476 BB *head,
01477 BB *tail)
01478 {
01479
01480
01481
01482
01483
01484
01485
01486 bool allocated = true;
01487 MEM_POOL allocator_pool;
01488
01489 Trace_SWP_Alloc = Get_Trace(TP_SWPIPE,0x40);
01490 SWP_POOL_Initialize(&allocator_pool, "CG_SWP_ALLOCATOR POOL", FALSE);
01491 SWP_POOL_Push(&allocator_pool);
01492 {
01493 INT32 ctrl_pred_loc;
01494 ISA_REGISTER_CLASS reg_class;
01495 LIFETIME_SET lt[ISA_REGISTER_CLASS_MAX+1];
01496
01497
01498
01499 FOR_ALL_ISA_REGISTER_CLASS(reg_class) {
01500 lt[reg_class] =
01501 LIFETIME_SET(0, SWP_LIFETIME(),
01502 SWP_USE_POOL(LIFETIME_SET, &allocator_pool));
01503 }
01504
01505
01506
01507
01508
01509 SWP_Gather_Lifetimes(lt, op_state, head, tail, &allocator_pool);
01510
01511
01512
01513
01514 FOR_ALL_ISA_REGISTER_CLASS(reg_class) {
01515 SWP_POOL_Push(&allocator_pool);
01516 allocated =
01517 (allocated &&
01518 SWP_Allocate_Rotating_Regs(Trace(),
01519 &allocator_pool,
01520 op_state,
01521 reg_class,
01522 op_state.ii_slots,
01523 op_state.sc,
01524 rotating_reg_avail[reg_class],
01525 lt[reg_class],
01526 ctrl_pred_loc,
01527 rotating_reg_used[reg_class],
01528 reg_allocation));
01529 SWP_POOL_Pop(&allocator_pool);
01530
01531 #ifdef TARG_IA64
01532 if (reg_class == ISA_REGISTER_CLASS_predicate)
01533 control_predicate_loc = ctrl_pred_loc;
01534 else
01535 {
01536 Is_True(ctrl_pred_loc == SWP_LIFETIME::InvalidLoc,
01537 ("SWP_REG_ASSIGNMENT: Encountered special location for wrong "
01538 "register class"));
01539 }
01540 #endif
01541 }
01542 if (Trace())
01543 fprintf(TFile,
01544 "\n========= Done with SWP Allocation =========\n");
01545 }
01546
01547 if (Trace())
01548 Print_Allocation(TFile);
01549
01550 SWP_POOL_Pop(&allocator_pool);
01551 SWP_POOL_Delete(&allocator_pool);
01552
01553 return allocated;
01554 }
01555
01556
01557 bool SWP_REG_ASSIGNMENT::Trace()
01558 {
01559 return Get_Trace(TP_SWPIPE, 0x80)
01560 || Get_Trace(TP_SRA, TP_SRA_LR_SUMMARY);
01561 }
01562
01563
01564 void SWP_REG_ASSIGNMENT::Print_Allocation(FILE *file)
01565 {
01566 TN2REG_MAP::iterator p;
01567 for (p = reg_allocation.begin(); p != reg_allocation.end(); p++) {
01568 TN *tn = (*p).first;
01569 CLASS_REG_PAIR rp = (*p).second;
01570 fprintf(file, "Allocation: TN%d CLASS%d REG%d\n", TN_number(tn),
01571 CLASS_REG_PAIR_rclass(rp), CLASS_REG_PAIR_reg(rp));
01572 }
01573 }
01574
01575 #endif // ifndef STANDALONE_SWP_ALLOCATOR