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 #include <sys/types.h>
00037 #include "tracing.h"
00038 #include "ipa_section.h"
00039 #include "reshape.h"
00040
00041
00042
00043
00044
00045
00046 RESHAPE::RESHAPE(PROJECTED_REGION* caller_shape_proj_region,
00047 PROJECTED_REGION* callee_shape_proj_region,
00048 PROJECTED_REGION* callee_proj_region,
00049 PROJECTED_REGION* callsite_region,
00050 MEM_POOL* m,
00051 BOOL trace) :
00052 _caller_shape_proj_region (caller_shape_proj_region),
00053 _callee_shape_proj_region (callee_shape_proj_region),
00054 _callee_proj_region (callee_proj_region),
00055 _callsite_region (callsite_region),
00056 _callee_proj_reshaped_region (NULL),
00057 _m (m)
00058 {
00059 #ifdef Is_True_On
00060 if (trace) {
00061 fprintf(TFile, "\nRESHAPE::RESHAPE\n");
00062 fprintf(TFile, " caller_shape: ");
00063 if (_caller_shape_proj_region) {
00064 _caller_shape_proj_region->Print(TFile);
00065 } else {
00066 fprintf(TFile, "NULL\n");
00067 }
00068 fprintf(TFile, " callee_shape: ");
00069 if (_callee_shape_proj_region) {
00070 _callee_shape_proj_region->Print(TFile);
00071 } else {
00072 fprintf(TFile, "NULL\n");
00073 }
00074 fprintf(TFile, " callee_proj_region: ");
00075 if (_callee_proj_region) {
00076 _callee_proj_region->Print(TFile);
00077 } else {
00078 fprintf(TFile, "NULL\n");
00079 }
00080 fprintf(TFile, " callsite_region: ");
00081 if (_callsite_region) {
00082 _callsite_region->Print(TFile);
00083 } else {
00084 fprintf(TFile, "NULL\n");
00085 }
00086 }
00087 #endif // Is_True_On
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 BOOL RESHAPE::Constant_Type_Reshape()
00101 {
00102 return _caller_shape_proj_region->Constant_bounds(1)
00103 && _callee_shape_proj_region->Constant_bounds(1)
00104 && _callee_proj_region->Constant_bounds(0);
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 PROJECTED_REGION* RESHAPE::Reshape_Callee_To_Caller(BOOL trace)
00116 {
00117
00118 #ifdef Is_True_On
00119 if (trace) {
00120 fprintf(TFile, "RESHAPE::Perform_Reshape\n");
00121 }
00122 #endif
00123
00124 Is_True(_callee_proj_region != NULL && _caller_shape_proj_region != NULL,
00125 ("Reshape_Callee_To_Caller: NULL projected region\n"));
00126
00127 UINT depth = _caller_shape_proj_region->Get_depth();
00128 UINT num_dims = _caller_shape_proj_region->Get_num_dims();
00129
00130
00131
00132
00133
00134 if (_callee_proj_region->Is_messy_region() ||
00135 _callee_proj_region->Has_Messy_Bounds() ||
00136 _caller_shape_proj_region->Is_messy_region() ||
00137 _caller_shape_proj_region->Has_Important_Messy_Bounds() ||
00138 (_callsite_region && (_callsite_region->Is_messy_region() ||
00139 _callsite_region->Has_Messy_Bounds())) ||
00140 ! Constant_Type_Reshape()) {
00141 _callee_proj_reshaped_region =
00142 CXX_NEW (PROJECTED_REGION (MESSY_REGION, depth, num_dims, _m), _m);
00143 } else {
00144
00145
00146
00147
00148 _callee_proj_reshaped_region = Reshape_Constant_Shape();
00149 }
00150
00151 #ifdef Is_True_On
00152 if (trace) {
00153 fprintf(TFile, " callee_proj_reshaped_region: ");
00154 _callee_proj_reshaped_region->Print(TFile);
00155 }
00156 #endif
00157
00158 Is_True(_callee_proj_reshaped_region->Get_num_dims() == num_dims,
00159 ("Reshape_Callee_To_Caller: Dims reshaped callee (%d) != caller shape (%d)",
00160 num_dims, _callee_proj_reshaped_region->Get_num_dims()));
00161
00162 return _callee_proj_reshaped_region;
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172 static void Linearize_Shape(PROJECTED_REGION* pr_callee,
00173 PROJECTED_REGION* pr_callee_shape,
00174 INT* lin_lower,
00175 INT* lin_upper,
00176 INT* lin_stride)
00177 {
00178
00179 *lin_upper = 0;
00180 *lin_lower = 0;
00181 INT dim_size = 1;
00182 INT last_callee_dim = pr_callee->Get_num_dims() - 1;
00183 for (INT i = last_callee_dim; i >= 0; i--) {
00184 PROJECTED_NODE* region_node = pr_callee->Get_projected_node(i);
00185 LINEX* stride = region_node->Get_step_linex();
00186 LINEX* ub = region_node->Get_upper_linex();
00187 LINEX* lb = region_node->Get_lower_linex();
00188 if (i == last_callee_dim) {
00189 Is_True(stride->Num_terms() == 0
00190 && stride->Get_term(0)->Get_type() == LTKIND_CONST,
00191 ("Linearize_Shape: Dim %d ub for callee is NOT constant", i));
00192 *lin_stride = stride->Get_constant_term();
00193 }
00194 Is_True(ub->Num_terms() == 0
00195 && ub->Get_term(0)->Get_type() == LTKIND_CONST,
00196 ("Linearize_Shape: Dim %d ub for callee is NOT constant", i));
00197 Is_True(lb->Num_terms() == 0
00198 && lb->Get_term(0)->Get_type() == LTKIND_CONST,
00199 ("Linearize_Shape: Dim %d lb for callee is NOT constant", i));
00200 *lin_upper += ub->Get_constant_term() * dim_size;
00201 *lin_lower += lb->Get_constant_term() * dim_size;
00202
00203 if (i != 0) {
00204 PROJECTED_NODE* node = pr_callee_shape->Get_projected_node(i);
00205 LINEX* upper = node->Get_upper_linex();
00206 LINEX* lower = node->Get_lower_linex();
00207 Is_True(upper->Num_terms() == 0
00208 && upper->Get_term(0)->Get_type() == LTKIND_CONST,
00209 ("Linearize_Shape: Dim %d ub for callee shape is NOT constant", i));
00210 Is_True(lower->Num_terms() == 0
00211 && lower->Get_term(0)->Get_type() == LTKIND_CONST,
00212 ("Linearize_Shape: Dim %d lb for callee shape is NOT constant", i));
00213 dim_size *= abs(upper->Get_constant_term()
00214 - lower->Get_constant_term() + 1);
00215 }
00216 }
00217 }
00218
00219
00220
00221
00222
00223
00224 static INT Dim_Length(PROJECTED_REGION* pr_shape,
00225 INT k)
00226 {
00227 PROJECTED_NODE* p = pr_shape->Get_projected_node(k);
00228 Is_True(!p->Is_messy_ub(), ("Dim_Length: Messy upper bound"));
00229 Is_True(!p->Is_messy_lb(), ("Dim_Length: Messy lower bound"));
00230 Is_True(!p->Is_messy_step(), ("Dim_Length: Messy step"));
00231 Is_True(p->Get_upper_linex()->Is_const(),
00232 ("Dim_Length: Non-constant upper bound"));
00233 Is_True(p->Get_lower_linex()->Is_const(),
00234 ("Dim_Length: Non-constant lower bound"));
00235 Is_True(p->Get_step_linex()->Is_const(),
00236 ("Dim_Length: Non-constant step"));
00237 INT upper_val = p->Get_upper_linex()->Get_term(0)->Get_coeff();
00238 INT lower_val = p->Get_lower_linex()->Get_term(0)->Get_coeff();
00239 INT step_val = p->Get_step_linex()->Get_term(0)->Get_coeff();
00240 Is_True(lower_val == 0, ("Dim_Length: Expecting shape lower bound of 0"));
00241 Is_True(step_val == 1, ("Dim_Length: Expecting shape step of 1"));
00242 return upper_val + 1;
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 static void Delinearize_Shape(PROJECTED_REGION* pr_caller,
00255 PROJECTED_REGION* pr_caller_shape,
00256 INT lin_lower,
00257 INT lin_upper,
00258 INT lin_stride,
00259 INT lb_caller_dim,
00260 INT ub_caller_dim,
00261 INT total_dims)
00262 {
00263 INT lb_current = lin_lower;
00264 INT ub_current = lin_upper;
00265 BOOL fill_in_max = FALSE;
00266 for (INT j = lb_caller_dim; j < ub_caller_dim; j++) {
00267 INT dim_size = 1;
00268 for (INT k = j + 1; k < total_dims; k++)
00269 dim_size *= Dim_Length(pr_caller_shape, k);
00270 INT lb_current_dim = -1;
00271 INT ub_current_dim = -1;
00272 if (fill_in_max) {
00273 PROJECTED_NODE* p = pr_caller_shape->Get_projected_node(j);
00274 lb_current_dim = 0;
00275 ub_current_dim = p->Get_upper_linex()->Get_term(0)->Get_coeff();
00276 } else {
00277 lb_current_dim = lb_current / dim_size;
00278 ub_current_dim = ub_current / dim_size;
00279 }
00280 PROJECTED_NODE* pn_return = pr_caller->Get_projected_node(j);
00281 INT stride = j == total_dims - 1 ? lin_stride : 1;
00282 pn_return->Set_constant_linexs(ub_current_dim, lb_current_dim,
00283 lin_stride, 0, 0);
00284 lb_current -= lb_current_dim * dim_size;
00285 ub_current -= ub_current_dim * dim_size;
00286 if (lb_current_dim < ub_current_dim)
00287 fill_in_max = TRUE;
00288 }
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 PROJECTED_REGION* RESHAPE::Reshape_Constant_Shape(BOOL trace)
00298 {
00299
00300 #ifdef Is_True_On
00301 if (trace) {
00302 fprintf(TFile, "RESHAPE::Reshape_Constant_Shape\n");
00303 }
00304 #endif
00305
00306 Is_True(Constant_Type_Reshape(),
00307 ("Reshape_Constant_Shape: Expecting constant shapes"));
00308
00309 UINT caller_depth = _caller_shape_proj_region->Get_depth();
00310 UINT caller_dims = _caller_shape_proj_region->Get_num_dims();
00311 PROJECTED_REGION* region =
00312 CXX_NEW(PROJECTED_REGION(NON_MESSY_REGION,caller_depth,caller_dims,_m),_m);
00313
00314
00315 INT lin_upper = 0;
00316 INT lin_lower = 0;
00317 INT lin_stride = 0;
00318 Linearize_Shape(_callee_proj_region, _callee_shape_proj_region,
00319 &lin_lower, &lin_upper, &lin_stride);
00320
00321 #ifdef Is_True_On
00322 if (trace) {
00323 fprintf(TFile, " Linearized callee_projected_region: [%d:%d:1]\n",
00324 lin_lower, lin_upper);
00325 }
00326 #endif
00327
00328 Is_True(lin_upper >= lin_lower,
00329 ("Reshape_Constant_Shape: After linearization lb (%d) > ub (%d)\n",
00330 lin_lower, lin_upper));
00331
00332
00333 INT segment_length = -1;
00334 INT segment_stride = -1;
00335 PROJECTED_NODE* pr_node = _callee_proj_region->Get_projected_node(0);
00336 if (pr_node->Get_segment_length_linex() != NULL
00337 && pr_node->Get_segment_length_linex()->Is_const()
00338 && pr_node->Get_segment_length_linex()->Is_const()) {
00339 segment_length = pr_node->Get_segment_length_linex()->Get_constant_term();
00340 segment_stride = pr_node->Get_segment_stride_linex()->Get_constant_term();
00341 }
00342
00343
00344 if (segment_stride == -1) {
00345 Delinearize_Shape(region, _caller_shape_proj_region, lin_lower,
00346 lin_upper, lin_stride, 0, caller_dims, caller_dims);
00347 } else {
00348 INT stride_dims = 0;
00349 INT local_stride = 1;
00350 for (INT i = caller_dims - 1; i >= 0; i--) {
00351 stride_dims++;
00352 local_stride *= Dim_Length(_caller_shape_proj_region, i);
00353 if (local_stride >= segment_stride)
00354 break;
00355 }
00356 if (local_stride != segment_stride) {
00357 Delinearize_Shape(region, _caller_shape_proj_region, lin_lower,
00358 lin_upper, lin_stride, 0, caller_dims, caller_dims);
00359 } else {
00360 Delinearize_Shape(region, _caller_shape_proj_region, lin_lower,
00361 lin_upper, 1, 0, caller_dims - stride_dims, caller_dims);
00362 Delinearize_Shape(region, _caller_shape_proj_region, 0,
00363 segment_length - 1, lin_stride, caller_dims - stride_dims,
00364 caller_dims, caller_dims);
00365 }
00366 }
00367
00368 return region;
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378 BOOL RESHAPE::Reshapeable_Passed_Section(BOOL trace)
00379 {
00380
00381 #ifdef Is_True_On
00382 if (trace) {
00383 fprintf(TFile, "RESHAPE::Actual_Passed_Reshapable\n");
00384 }
00385 #endif
00386
00387 Is_True(_callsite_region != NULL,
00388 ("Actual_Passed_Reshapeable: NULL callsite region"));
00389
00390 if (_callsite_region->Is_messy_region()) {
00391 return FALSE;
00392 }
00393
00394 Is_True(_callsite_region->Is_unprojected_region(),
00395 ("Actual_Passed_Reshapeable: Projected callsite region"));
00396
00397 for (INT i = 1; i < _callsite_region->Get_num_dims(); i++) {
00398 PROJECTED_NODE* pn_callsite
00399 = _callsite_region->Get_projected_node(i);
00400 PROJECTED_NODE* pn_caller_shape
00401 = _caller_shape_proj_region->Get_projected_node(i);
00402 PROJECTED_NODE* pn_caller
00403 = _callee_proj_reshaped_region->Get_projected_node(i);
00404 LINEX* lx_callsite = pn_callsite->Get_lower_linex();
00405 LINEX* lx_caller_lower = pn_caller->Get_lower_linex();
00406 LINEX* lx_caller_upper = pn_caller->Get_upper_linex();
00407 LINEX* lx_caller_shape_lower = pn_caller_shape->Get_lower_linex();
00408 LINEX* lx_caller_shape_upper = pn_caller_shape->Get_upper_linex();
00409 LINEX* lx_caller_diff = lx_caller_upper->Subtract(lx_caller_lower);
00410 lx_caller_diff->Simplify();
00411
00412 #ifdef Is_True_On
00413 if (trace) {
00414 fprintf(TFile, " dim[%d] - ", i);
00415 fprintf(TFile, "callsite: ");
00416 pn_callsite->Print(TFile);
00417 fprintf(TFile, " caller_shape: ");
00418 pn_caller_shape->Print(TFile);
00419 }
00420 #endif
00421
00422 if (!lx_caller_diff->Is_const()
00423 || lx_caller_diff->Get_constant_term() != 0) {
00424 LINEX* lx_high = lx_caller_upper->Merge(lx_callsite);
00425 LINEX* lx_over = lx_high->Subtract(lx_caller_shape_upper);
00426 if (!lx_over->Is_const() || lx_over->Get_constant_term() > 0)
00427 return FALSE;
00428 LINEX* lx_low = lx_caller_lower->Merge(lx_callsite);
00429 LINEX* lx_under = lx_low->Subtract(lx_caller_shape_lower);
00430 if (!lx_under->Is_const() || lx_under->Get_constant_term() > 0)
00431 return FALSE;
00432 }
00433 }
00434
00435 return TRUE;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444 void RESHAPE::Reshape_Passed_Section(PROJECTED_REGION* callee_reshaped,
00445 BOOL trace)
00446 {
00447
00448 #ifdef Is_True_On
00449 if (trace) {
00450 fprintf(TFile, "RESHAPE::Reshape_Passed_Section\n");
00451 }
00452 #endif
00453
00454 INT num_dims = callee_reshaped->Get_num_dims();
00455 for (INT dim_idx = 0; dim_idx < num_dims; dim_idx++) {
00456 PROJECTED_NODE* pn_callsite = _callsite_region->Get_projected_node(dim_idx);
00457 LINEX* lx_callsite = pn_callsite->Get_lower_linex();
00458 PROJECTED_NODE* pn_reshaped = callee_reshaped->Get_projected_node(dim_idx);
00459 LINEX* lx_lower = lx_callsite->Merge(pn_reshaped->Get_lower_linex());
00460 LINEX* lx_upper = lx_callsite->Merge(pn_reshaped->Get_upper_linex());
00461 pn_reshaped->Get_lower_linex()->Free_terms();
00462 pn_reshaped->Set_lower_linex(lx_lower);
00463
00464 INT i;
00465
00466 for (i = 0; i <= pn_reshaped->Get_lower_linex()->Num_terms(); i++) {
00467 TERM* tm = pn_reshaped->Get_lower_linex()->Get_term(i);
00468 switch (tm->Get_type()) {
00469 case LTKIND_LINDEX:
00470 case LTKIND_SUBSCR:
00471 pn_reshaped->Set_messy_lb();
00472 break;
00473 }
00474 }
00475
00476 pn_reshaped->Get_upper_linex()->Free_terms();
00477 pn_reshaped->Set_upper_linex(lx_upper);
00478
00479 for (i = 0; i <= pn_reshaped->Get_upper_linex()->Num_terms(); i++) {
00480
00481 TERM* tm = pn_reshaped->Get_upper_linex()->Get_term(i);
00482 switch (tm->Get_type()) {
00483 case LTKIND_LINDEX:
00484 case LTKIND_SUBSCR:
00485 pn_reshaped->Set_messy_ub();
00486 break;
00487 }
00488 }
00489 }
00490
00491
00492 #ifdef Is_True_On
00493 if (trace) {
00494 fprintf(TFile, "New reshaped section\n");
00495 callee_reshaped->Print(TFile);
00496 }
00497 #endif
00498
00499 }