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 #ifndef cg_grouping_INCLUDED
00071 #define cg_grouping_INCLUDED
00072
00073 #include <vector>
00074 #include "mempool_allocator.h"
00075 #include "ti_si.h"
00076 #include "topcode.h"
00077 #include "targ_issue_port.h"
00078
00079 typedef mempool_allocator<INT32> INT32_MEMALLOC;
00080 typedef std::vector<INT32, INT32_MEMALLOC> INT32_VECTOR;
00081
00082 class CG_GROUPING
00083 {
00084 private:
00085
00086
00087
00088
00089 SI_RESOURCE_ID _mi_unit_id;
00090 SI_RESOURCE_ID _m_unit_id;
00091 SI_RESOURCE_ID _m0_unit_id;
00092 SI_RESOURCE_ID _m2_unit_id;
00093 SI_RESOURCE_ID _m_ld_unit_id;
00094 SI_RESOURCE_ID _m_st_unit_id;
00095 SI_RESOURCE_ID _i_unit_id;
00096 SI_RESOURCE_ID _i0_unit_id;
00097 SI_RESOURCE_ID _f_unit_id;
00098 SI_RESOURCE_ID _f0_unit_id;
00099 SI_RESOURCE_ID _b_unit_id;
00100 INT32_VECTOR _reserved;
00101 ISA_EXEC_UNIT_PROPERTY _bundling_preference[ISA_MAX_SLOTS][ISA_EXEC_MAX];
00102 ISA_EXEC_UNIT_PROPERTY _no_of_preferences[ISA_MAX_SLOTS];
00103 INT _total_no_of_bundles;
00104 INT _no_of_bundles_in_group;
00105
00106 void _init_resource(const char *name, SI_RESOURCE_ID res_id)
00107 {
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 bool unknown_resource = FALSE;
00119
00120 Is_True(name != NULL, ("CG_GROUPING cannot handle unnamed resource"));
00121
00122 switch (name[0])
00123 {
00124 case 'B':
00125 if ( strcmp("B0_or_B1", name) != 0
00126 && strcmp("B0_or_B2", name) != 0
00127 && strcmp("B2", name) != 0)
00128 unknown_resource = TRUE;
00129 break;
00130
00131 case 'b':
00132 if (strcmp("branch", name) == 0)
00133 _b_unit_id = res_id;
00134 else
00135 unknown_resource = TRUE;
00136 break;
00137
00138 case 'f':
00139 if (strcmp("floating-point0", name) == 0)
00140 _f0_unit_id = res_id;
00141 else if (strcmp("floating-point", name) == 0)
00142 _f_unit_id = res_id;
00143 else
00144 unknown_resource = TRUE;
00145 break;
00146
00147 case 'i':
00148 if (strcmp("integer_or_memory", name) == 0)
00149 _mi_unit_id = res_id;
00150 else if (strcmp("integer0", name) == 0)
00151 _i0_unit_id = res_id;
00152 else if (strcmp("integer", name) == 0)
00153 _i_unit_id = res_id;
00154 else if (strcmp("issue", name) != 0)
00155 unknown_resource = TRUE;
00156 break;
00157
00158 case 'm':
00159 if (strcmp("memory0", name) == 0)
00160 _m0_unit_id = res_id;
00161 else if (strcmp("memory", name) == 0)
00162 _m_unit_id = res_id;
00163 else if (strcmp("memory_ld", name) == 0)
00164 _m_ld_unit_id = res_id;
00165 else if (strcmp("memory_st", name) == 0)
00166 _m_st_unit_id = res_id;
00167 else if (strcmp("memory2", name) == 0)
00168 _m2_unit_id = res_id;
00169 else
00170 unknown_resource = TRUE;
00171 break;
00172
00173 case 's':
00174 if (strcmp("sem", name) != 0)
00175 unknown_resource = TRUE;
00176 break;
00177
00178 default:
00179 unknown_resource = TRUE;
00180 break;
00181 }
00182 Is_True(!unknown_resource,
00183 ("CG_GROUPING cannot handle unknown resource (%s)", name));
00184 }
00185
00186 public:
00187
00188 CG_GROUPING(MEM_POOL *mpool, SI_RESOURCE_ID resource_count) :
00189 _reserved(resource_count, 0, INT32_VECTOR::allocator_type(mpool)),
00190 _total_no_of_bundles(0),
00191 _no_of_bundles_in_group(0)
00192 {
00193 for (SI_RESOURCE_ID res_id = 0; res_id < resource_count; ++res_id)
00194 _init_resource(SI_RESOURCE_ID_Name(res_id), res_id);
00195
00196
00197
00198
00199
00200 Is_True(ISA_MAX_SLOTS == 3, ("Unexpected bundle size for CG_GROUPING"));
00201
00202
00203
00204 _no_of_preferences[0] = 2;
00205 _bundling_preference[0][0] = ISA_EXEC_PROPERTY_M_Unit;
00206 _bundling_preference[0][1] = ISA_EXEC_PROPERTY_B_Unit;
00207
00208
00209
00210 _no_of_preferences[1] = 4;
00211 _bundling_preference[1][0] = ISA_EXEC_PROPERTY_I_Unit;
00212 _bundling_preference[1][1] = ISA_EXEC_PROPERTY_F_Unit;
00213 _bundling_preference[1][2] = ISA_EXEC_PROPERTY_M_Unit;
00214 _bundling_preference[1][3] = ISA_EXEC_PROPERTY_B_Unit;
00215
00216
00217
00218 _no_of_preferences[2] = 5;
00219 _bundling_preference[2][0] = ISA_EXEC_PROPERTY_I_Unit;
00220 _bundling_preference[2][1] = ISA_EXEC_PROPERTY_F_Unit;
00221 _bundling_preference[2][2] = ISA_EXEC_PROPERTY_I2_Unit;
00222 _bundling_preference[2][3] = ISA_EXEC_PROPERTY_B_Unit;
00223 _bundling_preference[2][4] = ISA_EXEC_PROPERTY_B2_Unit;
00224 }
00225
00226
00227
00228
00229 bool is_branch(TOP top) const
00230 {
00231 return EXEC_PROPERTY_is_B_Unit(top) || EXEC_PROPERTY_is_B2_Unit(top);
00232 }
00233
00234 bool has_resource_choice(TOP top) const
00235 {
00236 return EXEC_PROPERTY_is_I_Unit(top) && EXEC_PROPERTY_is_M_Unit(top);
00237 }
00238
00239 bool need_f0_unit(TOP top) const
00240 {
00241 SI_RESOURCE_TOTAL* rvec = TSI_Resource_Total_Vector(top);
00242 const UINT size = TSI_Resource_Total_Vector_Size(top);
00243 for (UINT i = 0; i < size; ++i )
00244 {
00245 SI_RESOURCE_ID id = SI_RESOURCE_TOTAL_Resource_Id(&rvec[i]);
00246 if (id == _f0_unit_id)
00247 return true;
00248 }
00249 return false;
00250 }
00251
00252 INT num_slots(TOP top) const {return ISA_PACK_Inst_Words(top);}
00253 INT max_slots_per_group() const {return ISA_MAX_SLOTS * ISA_MAX_ISSUE_BUNDLES; }
00254
00255 INT bundling_order(TOP top) const
00256 {
00257
00258
00259
00260
00261
00262
00263 return (EXEC_PROPERTY_is_B_Unit(top)? 20 :
00264 EXEC_PROPERTY_is_B2_Unit(top)? 30 :
00265 EXEC_PROPERTY_is_L_Unit(top)? 6 :
00266 (EXEC_PROPERTY_is_M_Unit(top) &&
00267 EXEC_PROPERTY_is_I_Unit(top))? 10 :
00268 EXEC_PROPERTY_is_M_Unit(top)? 1 :
00269 EXEC_PROPERTY_is_I_Unit(top)? 8 :
00270 EXEC_PROPERTY_is_I2_Unit(top)? 15 :
00271 EXEC_PROPERTY_is_F_Unit(top)?
00272 (need_f0_unit(top) ? 4 : 5) :
00273 16 );
00274 }
00275
00276
00277
00278
00279
00280
00281 void start_new_group(bool in_current_bundle)
00282 {
00283 _no_of_bundles_in_group = (in_current_bundle? 1 : 0);
00284 }
00285 void start_new_bundle(TI_BUNDLE *bundle)
00286 {
00287 TI_BUNDLE_Clear(bundle);
00288 ++_no_of_bundles_in_group;
00289 ++_total_no_of_bundles;
00290 }
00291 bool new_bundle_will_break_cycle() const
00292 {
00293 return (_no_of_bundles_in_group >= max_slots_per_group()/ISA_MAX_SLOTS);
00294 }
00295 bool in_first_bundle_of_group() const
00296 {
00297 return (_no_of_bundles_in_group == 1);
00298 }
00299 INT total_no_of_bundles() const
00300 {
00301 return _total_no_of_bundles;
00302 }
00303 INT absolute_slot_no(INT slot_in_bundle) const
00304 {
00305 return (_total_no_of_bundles - 1)*ISA_MAX_SLOTS + slot_in_bundle;
00306 }
00307
00308 INT no_of_preferred_slot_kinds(INT slot) const
00309 {
00310 return _no_of_preferences[slot];
00311 }
00312
00313 ISA_EXEC_UNIT_PROPERTY get_preferred_slot_kind(INT slot, INT pref) const
00314 {
00315 if (pref < _no_of_preferences[slot])
00316 return _bundling_preference[slot][pref];
00317 else
00318 return _bundling_preference[slot][_no_of_preferences[slot] - 1];
00319 }
00320
00321
00322
00323
00324 INT avail_m_units() const
00325 {
00326 return SI_RESOURCE_ID_Avail_Per_Cycle(_m_unit_id) - _reserved[_m_unit_id];
00327 }
00328 INT avail_i_units() const
00329 {
00330 return SI_RESOURCE_ID_Avail_Per_Cycle(_i_unit_id) - _reserved[_i_unit_id];
00331 }
00332 INT avail_f_units() const
00333 {
00334 return SI_RESOURCE_ID_Avail_Per_Cycle(_f_unit_id) - _reserved[_f_unit_id];
00335 }
00336 INT avail_b_units() const
00337 {
00338 return SI_RESOURCE_ID_Avail_Per_Cycle(_b_unit_id) - _reserved[_b_unit_id];
00339 }
00340
00341 INT avail_resource_units(ISA_EXEC_UNIT_PROPERTY prop)
00342 {
00343 if (prop == ISA_EXEC_PROPERTY_M_Unit)
00344 return avail_m_units();
00345 else if (prop == ISA_EXEC_PROPERTY_I_Unit ||
00346 prop == ISA_EXEC_PROPERTY_I2_Unit)
00347 return avail_i_units();
00348 else if (prop == ISA_EXEC_PROPERTY_F_Unit)
00349 return avail_f_units();
00350 else if (prop == ISA_EXEC_PROPERTY_B_Unit ||
00351 prop == ISA_EXEC_PROPERTY_B2_Unit)
00352 return avail_b_units();
00353 else
00354 return 0;
00355 }
00356
00357
00358
00359
00360 void clear_reserved()
00361 {
00362 for (INT32_VECTOR::iterator it = _reserved.begin();
00363 it != _reserved.end();
00364 ++it)
00365 *it = 0;
00366 }
00367
00368 bool inorder_reserve_resource(TOP top)
00369 {
00370
00371
00372
00373 bool reserved_ok = TRUE;
00374 SI_RESOURCE_TOTAL* rvec = TSI_Resource_Total_Vector(top);
00375 const UINT size = TSI_Resource_Total_Vector_Size(top);
00376
00377
00378
00379 for (UINT i = 0; reserved_ok && i < size; ++i )
00380 {
00381 SI_RESOURCE_ID id = SI_RESOURCE_TOTAL_Resource_Id(&rvec[i]);
00382 if (_reserved[id] > SI_RESOURCE_ID_Avail_Per_Cycle(id))
00383 reserved_ok = false;
00384 else
00385 ++_reserved[id];
00386 }
00387
00388 if (reserved_ok)
00389 {
00390
00391
00392 if (_reserved[_m_unit_id] > 0 && _reserved[_m0_unit_id] == 0)
00393 _reserved[_m0_unit_id] = 1;
00394 else if (_reserved[_f_unit_id] > 0 && _reserved[_f0_unit_id] == 0)
00395 _reserved[_f0_unit_id] = 1;
00396 else if (_reserved[_i_unit_id] > 0 && _reserved[_i0_unit_id] == 0)
00397 _reserved[_i0_unit_id] = 1;
00398 }
00399 return reserved_ok;
00400 }
00401
00402 bool reserve_resource(ISA_EXEC_UNIT_PROPERTY prop)
00403 {
00404 bool ok = true;
00405
00406 if (prop == ISA_EXEC_PROPERTY_M_Unit)
00407 {
00408 ++_reserved[_m_unit_id];
00409 if (_reserved[_m0_unit_id] == 0)
00410 _reserved[_m0_unit_id] = 1;
00411 }
00412 else if (prop == ISA_EXEC_PROPERTY_I_Unit)
00413 {
00414 ++_reserved[_i_unit_id];
00415 if (_reserved[_i0_unit_id] == 0)
00416 _reserved[_i0_unit_id] = 1;
00417 }
00418 else if (prop == ISA_EXEC_PROPERTY_F_Unit)
00419 {
00420 ++_reserved[_f_unit_id];
00421 if (_reserved[_f0_unit_id] == 0)
00422 _reserved[_f0_unit_id] = 1;
00423 }
00424 else if (prop == ISA_EXEC_PROPERTY_B_Unit ||
00425 prop == ISA_EXEC_PROPERTY_B2_Unit)
00426 ++_reserved[_b_unit_id];
00427 else
00428 ok = false;
00429
00430 return ok;
00431 }
00432
00433 INT resource_slack(TOP top) const
00434 {
00435
00436
00437
00438
00439
00440
00441
00442 INT slack = INT_MAX;
00443 SI_RESOURCE_TOTAL* rvec = TSI_Resource_Total_Vector(top);
00444 const UINT size = TSI_Resource_Total_Vector_Size(top);
00445 for (UINT i = 0; i < size; ++i )
00446 {
00447 UINT diff = (SI_RESOURCE_TOTAL_Avail_Per_Cycle(&rvec[i]) -
00448 SI_RESOURCE_TOTAL_Total_Used(&rvec[i]));
00449 if (diff < slack)
00450 slack = diff;
00451 }
00452 return slack;
00453 }
00454
00455 };
00456
00457
00458 #endif // cg_grouping_INCLUDED