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