00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "errors.h"
00028 #include "ggc.h"
00029 #include "tree.h"
00030 #include "target.h"
00031
00032 #include "rtl.h"
00033 #include "basic-block.h"
00034 #include "diagnostic.h"
00035 #include "tree-flow.h"
00036 #include "tree-dump.h"
00037 #include "timevar.h"
00038 #include "cfgloop.h"
00039 #include "expr.h"
00040 #include "optabs.h"
00041 #include "tree-chrec.h"
00042 #include "tree-data-ref.h"
00043 #include "tree-scalar-evolution.h"
00044 #include "tree-pass.h"
00045 #include "varray.h"
00046 #include "lambda.h"
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 static void
00094 gather_interchange_stats (varray_type dependence_relations,
00095 varray_type datarefs,
00096 struct loop *loop,
00097 struct loop *first_loop,
00098 unsigned int *dependence_steps,
00099 unsigned int *nb_deps_not_carried_by_loop,
00100 unsigned int *access_strides)
00101 {
00102 unsigned int i;
00103
00104 *dependence_steps = 0;
00105 *nb_deps_not_carried_by_loop = 0;
00106 *access_strides = 0;
00107
00108 for (i = 0; i < VARRAY_ACTIVE_SIZE (dependence_relations); i++)
00109 {
00110 int dist;
00111 struct data_dependence_relation *ddr =
00112 (struct data_dependence_relation *)
00113 VARRAY_GENERIC_PTR (dependence_relations, i);
00114
00115
00116
00117
00118
00119 if (DDR_DIST_VECT (ddr) == NULL
00120 || DDR_ARE_DEPENDENT (ddr) == chrec_dont_know
00121 || DDR_ARE_DEPENDENT (ddr) == chrec_known)
00122 continue;
00123
00124
00125
00126 dist = DDR_DIST_VECT (ddr)[loop->depth - first_loop->depth];
00127 if (dist == 0)
00128 (*nb_deps_not_carried_by_loop) += 1;
00129 else if (dist < 0)
00130 (*dependence_steps) += -dist;
00131 else
00132 (*dependence_steps) += dist;
00133 }
00134
00135
00136 for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
00137 {
00138 unsigned int it;
00139 struct data_reference *dr = VARRAY_GENERIC_PTR (datarefs, i);
00140 tree stmt = DR_STMT (dr);
00141 struct loop *stmt_loop = loop_containing_stmt (stmt);
00142 struct loop *inner_loop = first_loop->inner;
00143
00144 if (inner_loop != stmt_loop
00145 && !flow_loop_nested_p (inner_loop, stmt_loop))
00146 continue;
00147 for (it = 0; it < DR_NUM_DIMENSIONS (dr); it++)
00148 {
00149 tree chrec = DR_ACCESS_FN (dr, it);
00150 tree tstride = evolution_part_in_loop_num
00151 (chrec, loop->num);
00152
00153 if (tstride == NULL_TREE
00154 || TREE_CODE (tstride) != INTEGER_CST)
00155 continue;
00156
00157 (*access_strides) += int_cst_value (tstride);
00158 }
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 static lambda_trans_matrix
00171 try_interchange_loops (lambda_trans_matrix trans,
00172 unsigned int depth,
00173 varray_type dependence_relations,
00174 varray_type datarefs,
00175 struct loop *first_loop)
00176 {
00177 struct loop *loop_i;
00178 struct loop *loop_j;
00179 unsigned int dependence_steps_i, dependence_steps_j;
00180 unsigned int access_strides_i, access_strides_j;
00181 unsigned int nb_deps_not_carried_by_i, nb_deps_not_carried_by_j;
00182 struct data_dependence_relation *ddr;
00183
00184
00185
00186 ddr = (struct data_dependence_relation *)
00187 VARRAY_GENERIC_PTR (dependence_relations, 0);
00188 if (ddr == NULL || DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
00189 return trans;
00190
00191
00192 for (loop_j = first_loop->inner;
00193 loop_j;
00194 loop_j = loop_j->inner)
00195 for (loop_i = first_loop;
00196 loop_i->depth < loop_j->depth;
00197 loop_i = loop_i->inner)
00198 {
00199 gather_interchange_stats (dependence_relations, datarefs,
00200 loop_i, first_loop,
00201 &dependence_steps_i,
00202 &nb_deps_not_carried_by_i,
00203 &access_strides_i);
00204 gather_interchange_stats (dependence_relations, datarefs,
00205 loop_j, first_loop,
00206 &dependence_steps_j,
00207 &nb_deps_not_carried_by_j,
00208 &access_strides_j);
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 if (dependence_steps_i < dependence_steps_j
00222 || nb_deps_not_carried_by_i > nb_deps_not_carried_by_j
00223 || access_strides_i < access_strides_j)
00224 {
00225 lambda_matrix_row_exchange (LTM_MATRIX (trans),
00226 loop_i->depth - first_loop->depth,
00227 loop_j->depth - first_loop->depth);
00228
00229
00230 if (!lambda_transform_legal_p (trans, depth, dependence_relations))
00231 lambda_matrix_row_exchange (LTM_MATRIX (trans),
00232 loop_i->depth - first_loop->depth,
00233 loop_j->depth - first_loop->depth);
00234 }
00235 }
00236
00237 return trans;
00238 }
00239
00240
00241
00242 void
00243 linear_transform_loops (struct loops *loops)
00244 {
00245 unsigned int i;
00246
00247 compute_immediate_uses (TDFA_USE_OPS | TDFA_USE_VOPS, NULL);
00248 for (i = 1; i < loops->num; i++)
00249 {
00250 unsigned int depth = 0;
00251 varray_type datarefs;
00252 varray_type dependence_relations;
00253 struct loop *loop_nest = loops->parray[i];
00254 struct loop *temp;
00255 VEC (tree) *oldivs = NULL;
00256 VEC (tree) *invariants = NULL;
00257 lambda_loopnest before, after;
00258 lambda_trans_matrix trans;
00259 bool problem = false;
00260 bool need_perfect_nest = false;
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 if (!loop_nest->inner)
00276 continue;
00277 depth = 1;
00278 for (temp = loop_nest->inner; temp; temp = temp->inner)
00279 {
00280 flow_loop_scan (temp, LOOP_ALL);
00281
00282 if (temp->next || temp->num_exits != 1)
00283 {
00284 problem = true;
00285 break;
00286 }
00287 depth ++;
00288 }
00289 if (problem)
00290 continue;
00291
00292
00293
00294 VARRAY_GENERIC_PTR_INIT (datarefs, 10, "datarefs");
00295 VARRAY_GENERIC_PTR_INIT (dependence_relations, 10,
00296 "dependence_relations");
00297
00298
00299 compute_data_dependences_for_loop (depth, loop_nest,
00300 &datarefs, &dependence_relations);
00301 if (dump_file && (dump_flags & TDF_DETAILS))
00302 {
00303 unsigned int j;
00304 for (j = 0; j < VARRAY_ACTIVE_SIZE (dependence_relations); j++)
00305 {
00306 struct data_dependence_relation *ddr =
00307 (struct data_dependence_relation *)
00308 VARRAY_GENERIC_PTR (dependence_relations, j);
00309
00310 if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
00311 {
00312 fprintf (dump_file, "DISTANCE_V (");
00313 print_lambda_vector (dump_file, DDR_DIST_VECT (ddr),
00314 DDR_SIZE_VECT (ddr));
00315 fprintf (dump_file, ")\n");
00316 fprintf (dump_file, "DIRECTION_V (");
00317 print_lambda_vector (dump_file, DDR_DIR_VECT (ddr),
00318 DDR_SIZE_VECT (ddr));
00319 fprintf (dump_file, ")\n");
00320 }
00321 }
00322 fprintf (dump_file, "\n\n");
00323 }
00324
00325 trans = lambda_trans_matrix_new (depth, depth);
00326 lambda_matrix_id (LTM_MATRIX (trans), depth);
00327
00328 trans = try_interchange_loops (trans, depth, dependence_relations,
00329 datarefs, loop_nest);
00330
00331 if (lambda_trans_matrix_id_p (trans))
00332 {
00333 if (dump_file)
00334 fprintf (dump_file, "Won't transform loop. Optimal transform is the identity transform\n");
00335 continue;
00336 }
00337
00338
00339 if (!lambda_transform_legal_p (trans, depth, dependence_relations))
00340 {
00341 if (dump_file)
00342 fprintf (dump_file, "Can't transform loop, transform is illegal:\n");
00343 continue;
00344 }
00345 if (!perfect_nest_p (loop_nest))
00346 need_perfect_nest = true;
00347 before = gcc_loopnest_to_lambda_loopnest (loops,
00348 loop_nest, &oldivs,
00349 &invariants,
00350 need_perfect_nest);
00351 if (!before)
00352 continue;
00353
00354 if (dump_file)
00355 {
00356 fprintf (dump_file, "Before:\n");
00357 print_lambda_loopnest (dump_file, before, 'i');
00358 }
00359
00360 after = lambda_loopnest_transform (before, trans);
00361 if (dump_file)
00362 {
00363 fprintf (dump_file, "After:\n");
00364 print_lambda_loopnest (dump_file, after, 'u');
00365 }
00366 lambda_loopnest_to_gcc_loopnest (loop_nest, oldivs, invariants,
00367 after, trans);
00368 if (dump_file)
00369 fprintf (dump_file, "Successfully transformed loop.\n");
00370 oldivs = NULL;
00371 invariants = NULL;
00372 free_dependence_relations (dependence_relations);
00373 free_data_refs (datarefs);
00374 }
00375 free_df ();
00376 scev_reset ();
00377 rewrite_into_ssa (false);
00378 rewrite_into_loop_closed_ssa ();
00379 #ifdef ENABLE_CHECKING
00380 verify_loop_closed_ssa ();
00381 #endif
00382 }