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
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 #ifndef cg_swp_allocator_INCLUDED
00133 #define cg_swp_allocator_INCLUDED
00134
00135 #ifdef STANDALONE_SWP_ALLOCATOR
00136
00137 extern const char *Swp_Assert_File;
00138 extern INT32 Swp_Assert_Line;
00139 extern void Swp_Assert(const char *msg, ...);
00140
00141 #define SWP_ASSERT_LOC(a_truth, diag_handler, diag_args) \
00142 ((a_truth) ? \
00143 (void) 0 : \
00144 ((Swp_Assert_File=__FILE__, Swp_Assert_Line=__LINE__), \
00145 diag_handler ## diag_args))
00146
00147 #define Is_True(a_truth, args) SWP_ASSERT_LOC(a_truth, Swp_Assert, args)
00148
00149 #include "matrix.h"
00150
00151 struct TN;
00152 struct MEM_POOL;
00153 #define SWP_MEMALLOC(T) std::allocator<T>
00154 #define SWP_USE_POOL(T,P) T::allocator_type()
00155 #define Malloc_Mem_Pool NULL
00156 #define SWP_POOL_Initialize(a, b, c) (a) = NULL
00157 #define SWP_POOL_Delete(a) (void)(1)
00158 #define SWP_POOL_Push(p) (void)(1)
00159 #define SWP_POOL_Pop(p) (void)(1)
00160
00161 #else // !STANDALONE_SWP_ALLOCATOR
00162
00163 #include "mempool_allocator.h"
00164 #include "matrix.h"
00165
00166 #define SWP_MEMALLOC(T) mempool_allocator<T>
00167 #define SWP_USE_POOL(T,P) T::allocator_type(P)
00168 #define SWP_POOL_Initialize(a, b, c) MEM_POOL_Initialize((a), (b), (c))
00169 #define SWP_POOL_Delete(a) MEM_POOL_Delete(a)
00170 #define SWP_POOL_Push(p) MEM_POOL_Push(p)
00171 #define SWP_POOL_Pop(p) MEM_POOL_Pop(p)
00172
00173 #endif // STANDALONE_SWP_ALLOCATOR
00174
00175
00176
00177
00178
00179 typedef INT32 SWP_TUNIT;
00180
00181 class SWP_LIFETIME
00182 {
00183 private:
00184
00185 SWP_TUNIT _start;
00186 SWP_TUNIT _end;
00187 INT32 _omega;
00188 INT32 _alpha;
00189 INT32 _loc;
00190 TN *_tn;
00191
00192 public:
00193
00194 static const INT32 InvalidLoc = INT32_MIN;
00195
00196 SWP_LIFETIME():
00197 _start(0), _end(0), _omega(0), _alpha(0), _loc(0), _tn(NULL)
00198 {}
00199
00200 SWP_LIFETIME(SWP_TUNIT start,
00201 SWP_TUNIT end,
00202 INT32 omega,
00203 INT32 alpha,
00204 TN *tn = NULL):
00205 _start(start), _end(end), _omega(omega), _alpha(alpha), _loc(0), _tn(tn)
00206 {}
00207
00208 SWP_TUNIT start() const {return _start;}
00209 SWP_TUNIT end() const {return _end;}
00210 INT32 omega() const {return _omega;}
00211 INT32 alpha() const {return _alpha;}
00212 INT32 location() const {return _loc;}
00213 TN *tn() const {return _tn;}
00214
00215 void set_start(INT32 start) {_start = start;}
00216 void set_end(INT32 end) {_end = end;}
00217 void set_omega(INT32 omega) {_omega = omega;}
00218 void set_alpha(INT32 alpha) {_alpha = alpha;}
00219 void set_location(INT32 loc) {_loc = loc;}
00220
00221 void print(FILE *outf);
00222
00223 };
00224
00225
00226
00227
00228
00229 class SWP_ALLOCATOR
00230 {
00231 public:
00232
00233 enum STATUS {UNALLOCATED, ALLOCATED, NEED_MORE_REGS};
00234
00235 typedef SWP_MEMALLOC(SWP_LIFETIME) LIFETIME_MEMALLOC;
00236 typedef std::vector<SWP_LIFETIME, LIFETIME_MEMALLOC> LIFETIME_SET;
00237
00238 typedef SWP_MEMALLOC(INT32) INT32_MEMALLOC;
00239 typedef std::vector<INT32, INT32_MEMALLOC> INT32_VECTOR;
00240
00241 private:
00242
00243 typedef std::pair<INT32,INT32> INT32_PAIR;
00244
00245 typedef SWP_MEMALLOC(char) CHAR_MEMALLOC;
00246 typedef SWP_MEMALLOC(bool) BOOL_MEMALLOC;
00247
00248 typedef std::vector<bool, BOOL_MEMALLOC> BOOL_VECTOR;
00249
00250 typedef MATRIX<INT32, INT32_MEMALLOC> INT32_MATRIX;
00251 typedef MATRIX<char, CHAR_MEMALLOC> CHAR_MATRIX;
00252 typedef MATRIX<bool, BOOL_MEMALLOC> BOOL_MATRIX;
00253
00254
00255 LIFETIME_SET _lifetime;
00256 SWP_TUNIT _ii;
00257 INT32 _sc;
00258 INT32 _no_of_regs;
00259 INT32 _first_log_reg;
00260 INT32 _last_log_reg;
00261 INT32 _num_allocated_lifetimes;
00262 STATUS _status;
00263 MEM_POOL *_mpool;
00264
00265
00266
00267
00268
00269 INT32 _logical_reg(SWP_TUNIT at_unit, INT32 physical_reg) const
00270 {
00271 return (physical_reg + at_unit/_ii);
00272 }
00273
00274 INT32 _livein_logical_reg(INT32 omega, INT32 physical_reg) const
00275 {
00276 return (physical_reg + omega);
00277 }
00278
00279 INT32 _liveout_logical_reg(INT32 alpha, INT32 physical_reg) const
00280 {
00281 return (physical_reg + (_sc - 1) + alpha);
00282 }
00283
00284
00285
00286
00287
00288 INT32 _wraparound(INT32 p, INT32 num_regs) const
00289 {
00290 INT32 r = p;
00291 if (r > num_regs)
00292 r = r % num_regs;
00293 else
00294 while (r < 0) r = num_regs + r;
00295 return r;
00296 }
00297
00298 INT32 _wraparound(INT32 p) const
00299 {
00300 return _wraparound(p, _no_of_regs);
00301 }
00302
00303
00304
00305
00306
00307 INT32 _regnum_dist(const SWP_LIFETIME <1, const SWP_LIFETIME <2) const;
00308
00309 void _calculate_dist(INT32_MATRIX &dist);
00310
00311 INT32 _ub_loc(const INT32_MATRIX &dist,
00312 INT32 allocated_loc,
00313 INT32 allocated_lt,
00314 INT32 unallocated_lt) const
00315 {
00316
00317
00318
00319 return allocated_loc - dist(unallocated_lt, allocated_lt);
00320 }
00321
00322 INT32 _lb_loc(const INT32_MATRIX &dist,
00323 INT32 allocated_loc,
00324 INT32 allocated_lt,
00325 INT32 unallocated_lt) const
00326 {
00327
00328
00329
00330 return allocated_loc + dist(allocated_lt, unallocated_lt);
00331 }
00332
00333
00334
00335
00336 INT32 _adjacency_order_dist(const INT32_MATRIX &dist,
00337 INT32 from_lt,
00338 INT32 to_lt) const;
00339
00340 void _adjacency_order_sort(const INT32_MATRIX &dist,
00341 INT32_VECTOR &ordered);
00342
00343
00344
00345 INT32_PAIR _candidate_locs(const INT32_MATRIX &dist,
00346 INT32_VECTOR::const_iterator begin_alloced,
00347 INT32_VECTOR::const_iterator end_alloced,
00348 INT32 candidate_lt) const;
00349
00350 INT32_PAIR _logical_reg_seq(INT32 lt_idx, INT32 physical_reg) const;
00351
00352 bool _has_conflicts(const BOOL_MATRIX &conflicts,
00353 INT32 new_allocated_lt,
00354 INT32 new_location) const
00355 {
00356 return conflicts(new_allocated_lt, _wraparound(new_location));
00357 }
00358
00359 void _update_conflicts(BOOL_MATRIX &conflicts,
00360 const INT32_MATRIX &dist,
00361 INT32_VECTOR::const_iterator begin_unalloced,
00362 INT32_VECTOR::const_iterator end_unalloced,
00363 INT32 new_allocated_lt,
00364 INT32 new_location);
00365
00366 INT32 _num_new_conflicts(const BOOL_MATRIX &conflicts,
00367 const INT32_MATRIX &dist,
00368 INT32_VECTOR::const_iterator begin_unalloced,
00369 INT32_VECTOR::const_iterator end_unalloced,
00370 INT32 new_allocated_lt,
00371 INT32 new_location) const;
00372
00373 STATUS _best_fit(const INT32_MATRIX &dist,
00374 const INT32_VECTOR &ordered);
00375
00376 STATUS _allocate(bool use_adjacency);
00377
00378
00379
00380 void _plot_line(CHAR_MATRIX &linebuf,
00381 INT32 reg,
00382 INT32 from_tunit,
00383 INT32 to_tunit,
00384 char plotc);
00385 void _plot_and_verify(CHAR_MATRIX &linebuf,
00386 INT32 num_used_regs,
00387 INT32 num_loop_iterations);
00388 void _print_ordered(FILE *outf,
00389 const char *msg,
00390 const INT32_VECTOR &ordered);
00391 void _print_dist(FILE *outf, INT32_MATRIX &dist);
00392 void _print_status(FILE *outf);
00393 void _print_location_map(FILE *outf,
00394 INT32 num_loop_iterations,
00395 INT32 plot_cols);
00396
00397 public:
00398
00399 typedef LIFETIME_SET::iterator LIFETIME_IT;
00400
00401 template <class InputIterator>
00402 SWP_ALLOCATOR(SWP_TUNIT ii,
00403 INT32 sc,
00404 INT32 no_of_available_regs,
00405 InputIterator lifetimes_begin,
00406 InputIterator lifetimes_end,
00407 MEM_POOL *mpool = Malloc_Mem_Pool,
00408 bool use_adjacency_order = true):
00409 _lifetime(lifetimes_begin,
00410 lifetimes_end,
00411 SWP_USE_POOL(LIFETIME_SET, mpool)),
00412 _ii(ii),
00413 _sc(sc),
00414 _no_of_regs(no_of_available_regs),
00415 _first_log_reg(SWP_LIFETIME::InvalidLoc),
00416 _last_log_reg(SWP_LIFETIME::InvalidLoc),
00417 _num_allocated_lifetimes(0),
00418 _status(UNALLOCATED),
00419 _mpool(mpool)
00420 {
00421 _status = _allocate(use_adjacency_order);
00422 }
00423
00424 STATUS status() const {return _status;}
00425 LIFETIME_IT begin() {return _lifetime.begin();}
00426 LIFETIME_IT end() {return _lifetime.end();}
00427
00428 INT32 num_allocated_regs() const
00429 {
00430 return (_last_log_reg - _first_log_reg + 1);
00431 }
00432
00433 INT32 num_allocated_lifetimes() const
00434 {
00435 return _num_allocated_lifetimes;
00436 }
00437
00438 void print(FILE *outf, INT32 num_iterations, INT32 plot_width);
00439 void dump() {print(stderr, _sc+1, 65);}
00440
00441 bool has_conflicts();
00442 #ifdef TARG_IA64
00443 bool adjust_predicate(const SWP_OP_vector& op_state,INT32 &used_regs) {
00444 INT32 offset = INT32_MAX;
00445
00446 for (INT32 i = 0; i < _lifetime.size(); ++i) {
00447 SWP_LIFETIME *lt = &_lifetime[i];
00448 if (lt->location() < offset) offset = lt->location();
00449 }
00450
00451
00452
00453
00454 INT32 control_pred_loc = 0;
00455 BOOL need_adjust = FALSE;
00456 for (INT32 i = 0; i < _lifetime.size(); ++i) {
00457 SWP_LIFETIME *lt = &_lifetime[i];
00458 const INT32 loc = lt->location() - offset;
00459
00460 if ((lt->tn() == NULL || lt->tn() == op_state.control_predicate_tn)) {
00461
00462 control_pred_loc = loc;
00463 }
00464 }
00465
00466 INT32 adjust_value = 0;
00467
00468 for (INT32 i = 0; i < _lifetime.size(); ++i) {
00469 SWP_LIFETIME *lt = &_lifetime[i];
00470 INT32_PAIR lr = _logical_reg_seq(i, lt->location());
00471 INT32 start = lr.first - offset;
00472 INT32 end = lr.second - offset;
00473 if ((start < control_pred_loc) && (end >= control_pred_loc)) {
00474 INT32 temp_adjust = end - control_pred_loc +1;
00475
00476 if (temp_adjust > adjust_value) adjust_value = temp_adjust;
00477
00478 }
00479
00480
00481 }
00482
00483
00484
00485
00486
00487
00488 used_regs +=adjust_value;
00489 if (adjust_value != 0) {
00490 for (INT32 i = 0; i < _lifetime.size(); ++i) {
00491 SWP_LIFETIME *lt = &_lifetime[i];
00492 if ((lt->location() - offset) < control_pred_loc ) {
00493 INT32 new_loc = lt->location() - adjust_value;
00494 lt->set_location(new_loc);
00495 }
00496 }
00497 }
00498 }
00499
00500 #endif // TARG_IA64
00501 };
00502
00503 #endif // cg_swp_allocator_INCLUDED