00001
00002
00003 #include <stdio.h>
00004 #include <string.h>
00005 #include <iostream.h>
00006
00007 #include "TinkerKnobs.H"
00008 #include "lego.H"
00009 #include "legoAn.H"
00010 #include "legoSO.H"
00011 #include "legoRForm.H"
00012
00013 #include "list_scheduler.H"
00014 #include "schedule.H"
00015 #include "modify.H"
00016 #include "scheduling_utilities.H"
00017 #include "hyperform.H"
00018
00019 #define YES 1
00020 #define NO 0
00021
00022 time_t start, finish;
00023 clock_t start_clock, finish_clock;
00024 clock_t start_rform, finish_rform;
00025 clock_t start_sched, finish_sched;
00026 clock_t start_dag, finish_dag;
00027 clock_t start_live, finish_live;
00028 clock_t start_rdef, finish_rdef;
00029 double total, total_clock, clocks_per_sec = CLOCKS_PER_SEC;
00030 double total_rform=0, total_sched=0, total_dag=0, total_live=0, total_rdef=0;
00031 extern chains* Chains;
00032 int dom_parallel_ops=0, copy_ops_added=0, speculated_ops=0;
00033 int liveness_renamed_ops=0, falsedep_renamed_ops=0, combine_renamed_ops=0;
00034 int liveness_calls=0, rdef_calls=0;
00035 int downward_motion_ops=0, unspeculated_ops=0, unspeculated_pbr_ops=0, dead_ops=0;
00036 double downward_dynamic_op_reduction=0, combine_dynamic_op_reduction=0;
00037 double speculative_dynamic_op_increase=0, multiway_dynamic_op_reduction=0;
00038 double copy_dynamic_op_increase=0;
00039 int total_branch_multiops=0, total_branch_ops=0, blocks_removed=0;
00040
00041 void
00042 ShowSyntax (void)
00043 {
00044 printf ("\n\nLEGO ccom Syntax\n\n");
00045 printf ("ccom [-h|-help] [-v|-verbose] [-K\"knob-name knob-type "
00046 "knob-value\"]*\n"
00047 " [-kf knob-file] [-n|-nooutput|-o output-file] file\n");
00048 exit(1);
00049 }
00050
00051 int
00052 main (int argc, char *argv[])
00053 {
00054 legoModule *M;
00055 knobs *K;
00056 char *knobfile = NULL, *inputfile = NULL, *outputfile = NULL;
00057 int verbose = 0, nooutput = 0;
00058 tree_stats *tree_st = NULL;
00059
00060 tree_st = new tree_stats ("will_not_dump");
00061
00062 for (int i = 1; i < argc; i++)
00063 {
00064 char *arg = argv[i];
00065
00066 if (strcmp (arg, "-help") == 0 ||
00067 strcmp (arg, "-h") == 0)
00068 ShowSyntax();
00069
00070 if (strcmp (arg, "-v") == 0 ||
00071 strcmp (arg, "-verbose") == 0)
00072 {
00073 verbose = 1;
00074 continue;
00075 }
00076
00077 if (strcmp (arg, "-n") == 0 ||
00078 strcmp (arg, "-nooutput") == 0)
00079 {
00080 nooutput = 1;
00081 continue;
00082 }
00083
00084 if (strcmp (arg, "-kf") == 0)
00085 {
00086 knobfile = argv[++i];
00087 continue;
00088 }
00089
00090 if (strcmp (arg, "-o") == 0)
00091 {
00092 outputfile = argv[++i];
00093 continue;
00094 }
00095
00096 if (arg[0] == '-' && arg[1] == 'K')
00097 continue;
00098
00099 inputfile = arg;
00100 }
00101
00102 if (inputfile == NULL)
00103 {
00104 printf ("ccom| No input file specified.");
00105 ShowSyntax();
00106 }
00107
00108 if (verbose)
00109 printf ("ccom| Reading in knobs.\n");
00110 K = new knobs (knobfile);
00111 K->Parse (argc, argv);
00112
00113 if (verbose)
00114 printf ("ccom| Loading input file %s.\n", inputfile);
00115 M = new legoModule;
00116 LegoRead_IA64 (inputfile, M);
00117 IA64Write(M,"ReadOutput.s");
00118
00119
00120
00121
00122
00123 char *regiontype;
00124 legoProc *P;
00125 legoTreegion *T;
00126 int maxid, ooc = M->GetOpCount();
00127
00128 K->SetDefaultPanel ("ccom");
00129
00130 K->Read ("region", regiontype);
00131 if (strcmp (regiontype, "basic-block") != 0 &&
00132 strcmp (regiontype, "treegion") != 0 &&
00133 strcmp (regiontype, "FICT") != 0 &&
00134 strcmp (regiontype, "lineartrees") != 0 &&
00135 strcmp (regiontype, "superblock") != 0)
00136 LegoFatal ("ccom", "Unknown region type \"%s\".", regiontype);
00137
00138 start = time(NULL);
00139 start_clock = clock();
00140
00141
00142 start_rform = clock();
00143
00144 if (verbose)
00145 printf ("ccom| Forming %ss \n", regiontype);
00146 if (strcmp (regiontype, "basic-block") == 0)
00147 {
00148 for (unsigned i = 0; i < M->GetCount(); i++)
00149 {
00150 P = (legoProc *) M->GetItem (i);
00151
00152 UnBindSB(P);
00153 if (verbose)
00154 {
00155 putchar ('.');
00156 fflush (stdout);
00157 }
00158 }
00159 if (verbose) putchar ('\n');
00160 }
00161 else
00162 if (strcmp (regiontype, "treegion") == 0)
00163 {
00164
00165 for (unsigned i = 0; i < M->GetCount(); i++)
00166 {
00167 P = (legoProc *) M->GetItem (i);
00168 NextPredRegNum = 0;
00169 maxid = (P->FindMaxRegionId())->GetRegionId();
00170 treeform (P, maxid, K, tree_st);
00171 if (verbose)
00172 {
00173 putchar ('.');
00174 fflush (stdout);
00175 }
00176 }
00177 if (verbose) putchar ('\n');
00178 }
00179 else if (strcmp (regiontype, "FICT") == 0)
00180 {
00181 if (verbose) {
00182 putchar ('\n');
00183 printf ("ccom| Start by forming Treegion \n");
00184 }
00185 for (unsigned i = 0; i < M->GetCount(); i++)
00186 {
00187 P = (legoProc *) M->GetItem (i);
00188 NextPredRegNum = 0;
00189 maxid = (P->FindMaxRegionId())->GetRegionId();
00190 treeform (P, maxid, K, tree_st);
00191 if (verbose)
00192 {
00193 putchar ('.');
00194 fflush (stdout);
00195 }
00196 }
00197 if (verbose) {
00198 putchar ('\n');
00199 printf ("ccom| Fully If-Converting Treegion \n");
00200 }
00201 for (unsigned i = 0; i < M->GetCount(); i++) {
00202 P = (legoProc *) M->GetItem (i);
00203 Chains = ReachingDefinitions (P, K);
00204 NextPredRegNum = 0;
00205 for (unsigned j = 0; j < P->GetCount(); j++) {
00206 T = (legoTreegion *) P->GetItem (j);
00207 FullyIfConvertTreeBranch (T, K);
00208 }
00209 if (verbose)
00210 {
00211 putchar ('.');
00212 fflush (stdout);
00213 }
00214 }
00215 if (verbose) putchar ('\n');
00216 }
00217 else if (strcmp (regiontype, "lineartrees") == 0)
00218 {
00219 if (verbose) {
00220 putchar ('\n');
00221 printf ("ccom| Start by forming Treegion \n");
00222 }
00223 for (unsigned i = 0; i < M->GetCount(); i++)
00224 {
00225 P = (legoProc *) M->GetItem (i);
00226 NextPredRegNum = 0;
00227 maxid = (P->FindMaxRegionId())->GetRegionId();
00228 treeform (P, maxid, K, tree_st);
00229 if (verbose)
00230 {
00231 putchar ('.');
00232 fflush (stdout);
00233 }
00234 }
00235 if (verbose) {
00236 putchar ('\n');
00237 printf ("ccom| Decomposing Treegion into Linear Trees \n");
00238 }
00239 for (unsigned i = 0; i < M->GetCount(); i++) {
00240 P = (legoProc *) M->GetItem (i);
00241 Chains = ReachingDefinitions (P, K);
00242 NextPredRegNum = 0;
00243 for (unsigned j = 0; j < P->GetCount(); j++) {
00244 T = (legoTreegion *) P->GetItem (j);
00245 lineartreesfromtreegions (T);
00246 }
00247 if (verbose)
00248 {
00249 putchar ('.');
00250 fflush (stdout);
00251 }
00252 }
00253 if (verbose) putchar ('\n');
00254 }
00255 else if (strcmp (regiontype, "superblock") == 0)
00256 {
00257 for (unsigned i = 0; i < M->GetCount(); i++)
00258 {
00259 P = (legoProc *) M->GetItem (i);
00260 superform (P, K);
00261 if (verbose)
00262 {
00263 putchar ('.');
00264 fflush (stdout);
00265 }
00266 }
00267 if (verbose) putchar ('\n');
00268 }
00269
00270 finish_rform = clock();
00271 IA64Write(M,"RegionOutput.s");
00272
00273
00274
00275
00276
00277
00278
00279 unsigned i;
00280 char *debug_stats;
00281 char do_schedule, two_pass, fully_predicate, if_convert_and_predicate, fully_if_convert, append_debug_stats;
00282
00283 ofstream debugstatsf;
00284 machine *mach;
00285 schedule_stats *ss;
00286 static_stats *st_st;
00287
00288 K->Read ("ccom:do-schedule", do_schedule);
00289
00290 K->Read ("ccom:two-pass", two_pass);
00291 K->Read ("ccom:fully-predicate", fully_predicate);
00292 K->Read ("ccom:if-convert-and-predicate", if_convert_and_predicate);
00293 K->Read ("ccom:fully-if-convert", fully_if_convert);
00294
00295 start_sched = clock();
00296
00297 ss = new schedule_stats;
00298 ss->original_op_count = ss->final_op_count = 0;
00299 ss->instrs_scheduled = ss->schedule_length = 0;
00300 ss->instr_count = ss->cycle_count = 0;
00301
00302 st_st = new static_stats;
00303
00304 if (do_schedule)
00305 {
00306 if (verbose)
00307 printf ("ccom| Scheduling \n\n");
00308 mach = new machine (K);
00309
00310
00311 K->Read ("ccom:debug-stats", debug_stats);
00312 if (debug_stats != NULL)
00313 {
00314 if (verbose)
00315 printf ("ccom| Writing debug stats to %s.\n", debug_stats);
00316 K->Read ("ccom:append-debug-stats", append_debug_stats);
00317 if (append_debug_stats)
00318 debugstatsf.open (debug_stats, ios::out);
00319 else
00320 debugstatsf.open (debug_stats, ios::app);
00321 }
00322
00323 for (i = 0; i < M->GetCount(); i++)
00324 {
00325 P = (legoProc *) M->GetItem (i);
00326 ResetSchedTimes( P );
00327 start_dag = clock();
00328 BuildDagsForProc (P, mach, K);
00329 finish_dag = clock();
00330 total_dag = total_dag + ((finish_dag - start_dag) / clocks_per_sec);
00331 SetNodeHeightsAndDepthsForProc (P);
00332 printf("7i=%d\n",i);
00333 SetValuesForProc (P, K);
00334 mach->resetMachine();
00335 if (strcmp (regiontype, "FICT") == 0)
00336 {
00337
00338 ScheduleProc (P, ss, 0, &debugstatsf, K, NO, YES);
00339 } else
00340 if (two_pass)
00341 ScheduleProc (P, ss, 0, &debugstatsf, K, NO, NO);
00342 else
00343 ScheduleProc (P, ss, 0, &debugstatsf, K, YES, NO);
00344 DeleteDagsInProc( P );
00345
00346 if (verbose)
00347 {
00348 putchar ('.');
00349 fflush (stdout);
00350 }
00351 }
00352
00353 if (two_pass)
00354 {
00355 if (fully_predicate)
00356 {
00357 if (verbose) {
00358 putchar ('\n');
00359 printf ("ccom| Fully Predicating Treegion \n");
00360 }
00361
00362 for (unsigned i = 0; i < M->GetCount(); i++)
00363 {
00364 P = (legoProc *) M->GetItem (i);
00365 Chains = ReachingDefinitions (P, K);
00366 NextPredRegNum = 0;
00367 for (unsigned j = 0; j < P->GetCount(); j++) {
00368 T = (legoTreegion *) P->GetItem (j);
00369 FullyPredicateTreeBranch (T);
00370 }
00371 if (verbose)
00372 {
00373 putchar ('.');
00374 fflush (stdout);
00375 }
00376 }
00377 if (verbose) putchar ('\n');
00378 }
00379 else if (if_convert_and_predicate)
00380 {
00381 if (verbose)
00382 {
00383 putchar ('\n');
00384 printf ("ccom| If-Converting and Predicating Treegion \n");
00385 }
00386 for (unsigned i = 0; i < M->GetCount(); i++)
00387 {
00388 P = (legoProc *) M->GetItem (i);
00389 Chains = ReachingDefinitions (P, K);
00390 NextPredRegNum = 0;
00391 for (unsigned j = 0; j < P->GetCount(); j++)
00392 {
00393 T = (legoTreegion *) P->GetItem (j);
00394 IfConvertAndPredicateTreeBranch (T, K);
00395 }
00396 if (verbose)
00397 {
00398 putchar ('.');
00399 fflush (stdout);
00400 }
00401 }
00402 if (verbose) putchar ('\n');
00403 }
00404 else if (fully_if_convert) {
00405 if (verbose) {
00406 putchar ('\n');
00407 printf ("ccom| Fully If-Converting Treegion \n");
00408 }
00409 for (unsigned i = 0; i < M->GetCount(); i++) {
00410 P = (legoProc *) M->GetItem (i);
00411 Chains = ReachingDefinitions (P, K);
00412 NextPredRegNum = 0;
00413 for (unsigned j = 0; j < P->GetCount(); j++) {
00414 T = (legoTreegion *) P->GetItem (j);
00415 FullyIfConvertTreeBranch (T, K);
00416 }
00417 if (verbose)
00418 {
00419 putchar ('.');
00420 fflush (stdout);
00421 }
00422 }
00423 if (verbose) putchar ('\n');
00424 }
00425 if (verbose)
00426 printf ("ccom| 2nd Pass Scheduling \n");
00427
00428 for (i = 0; i < M->GetCount(); i++)
00429 {
00430 P = (legoProc *) M->GetItem (i);
00431 ResetSchedTimes( P );
00432 start_dag = clock();
00433 BuildDagsForProc (P, mach, K);
00434 finish_dag = clock();
00435 total_dag = total_dag + ((finish_dag - start_dag) / clocks_per_sec);
00436
00437 SetNodeHeightsAndDepthsForProc (P);
00438 SetValuesForProc (P, K);
00439 mach->resetMachine();
00440 ScheduleProc (P, ss, 0, &debugstatsf, K, YES, YES);
00441 DeleteDagsInProc( P );
00442 if (verbose)
00443 {
00444 putchar ('.');
00445 fflush (stdout);
00446 }
00447 }
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457 st_st = StaticEstimate (M);
00458
00459 if (debug_stats != NULL) debugstatsf.close();
00460 delete mach;
00461
00462 if (verbose) putchar ('\n');
00463 }
00464
00465 finish_sched = clock();
00466 finish = time(NULL);
00467 total = difftime(finish, start);
00468 finish_clock = clock();
00469 total_clock = ((finish_clock - start_clock) / clocks_per_sec);
00470
00471
00472
00473
00474 char *stats;
00475 char append_stats;
00476 FILE *sf;
00477
00478
00479 ss->original_op_count = ooc;
00480
00481
00482 ss->final_op_count = M->GetOpCount();
00483
00484
00485
00486 K->Read ("ccom:stats", stats);
00487 if (stats != NULL)
00488 {
00489 if (verbose)
00490 printf ("ccom| Writing statistics to %s.\n", stats);
00491 K->Read ("ccom:append-stats", append_stats);
00492 if (append_stats)
00493 sf = fopen (stats, "a");
00494 else
00495 sf = fopen (stats, "w");
00496 if (sf == NULL)
00497 LegoFatal ("ccom", "Couldn't open statistics file %s.", stats);
00498 fprintf (sf, "Statistics for file %s:\n", inputfile);
00499 fprintf (sf, "\tOriginal op count: %d\n", ss->original_op_count);
00500 fprintf (sf, "\tFinal op count: %d\n", ss->final_op_count);
00501 fprintf (sf, "\tNumber of instructions scheduled: %d\n",
00502 ss->instrs_scheduled);
00503 fprintf (sf, "\tTotal schedule length: %d\n", ss->schedule_length);
00504 fprintf (sf, "\tTotal instruction count: %lf\n", ss->instr_count);
00505 fprintf (sf, "\tTotal cycle count: %lf\n", ss->cycle_count);
00506 fprintf (sf, "\tNEW -- number of Dynamic Ops: %lf\n", st_st->numDynamicOps);
00507 fprintf (sf, "\tNEW -- number of Cycles: %lf\n", st_st->numCycles);
00508 total_rform = ((finish_rform - start_rform) / clocks_per_sec);
00509 total_sched = ((finish_sched - start_sched) / clocks_per_sec);
00510 fprintf (sf, "\tMain elapsed time is %lf seconds\n", total);
00511 fprintf (sf, "\tMain elapsed time is %lf ticks\n", total_clock);
00512 fprintf (sf, "\tTotal of %d RDefs() calls elapsed time is %lf ticks\n", rdef_calls, total_rdef);
00513 fprintf (sf, "\tTotal of %d LiveVar() calls elapsed time is %lf ticks\n", liveness_calls, total_live);
00514 fprintf (sf, "\tTotal BuildDagsForProc() calls elapsed time is %lf ticks\n", total_dag);
00515 fprintf (sf, "\tNumber of trees formed is %d \n", tree_st->tree_count);
00516 fprintf (sf, "\tOriginal number of basic blocks is %d \n", tree_st->block_count);
00517 fprintf (sf, "\tBasic blocks removed is %d \n", blocks_removed);
00518 fprintf (sf, "\tStatic path blocks is %d \n", tree_st->path_blocks);
00519 fprintf (sf, "\tStatic path count is %d \n", tree_st->path_count);
00520 fprintf (sf, "\tDynamic path blocks is %lf \n", tree_st->dynamic_path_blocks);
00521 fprintf (sf, "\tDynamic path count is %lf \n", tree_st->dynamic_path_count);
00522 fprintf (sf, "\tTotal RForm elapsed time is %lf ticks\n", total_rform);
00523 fprintf (sf, "\tTotal Sched elapsed time is %lf ticks\n", total_sched);
00524 fprintf (sf, "\tNumber of combined ops removed is %d \n", dom_parallel_ops);
00525 fprintf (sf, "\tDynamic op reduction due to combining is %lf \n", combine_dynamic_op_reduction);
00526 fprintf (sf, "\tNumber of speculated ops is %d \n", speculated_ops);
00527 fprintf (sf, "\tDynamic op increase due to speculation is %lf \n", speculative_dynamic_op_increase);
00528 fprintf (sf, "\tNumber of renamed ops (liveness) is %d \n", liveness_renamed_ops);
00529 fprintf (sf, "\tNumber of renamed ops (falsedep) is %d \n", falsedep_renamed_ops);
00530 fprintf (sf, "\tNumber of renamed ops (combine) is %d \n", combine_renamed_ops);
00531 fprintf (sf, "\tNumber of copy ops added is %d \n", copy_ops_added);
00532 fprintf (sf, "\tDynamic op increase due to copy ops is %lf \n", copy_dynamic_op_increase);
00533 fprintf (sf, "\tNumber of downward motion ops is %d \n", downward_motion_ops);
00534 fprintf (sf, "\tNumber of unspeculated ops is %d \n", unspeculated_ops);
00535 fprintf (sf, "\tNumber of unspeculated pbr ops is %d \n", unspeculated_pbr_ops);
00536 fprintf (sf, "\tDynamic op reduction due to unspeculation is %lf \n", downward_dynamic_op_reduction);
00537 fprintf (sf, "\tNumber of dead ops is %d \n", dead_ops);
00538 fprintf (sf, "\tNumber of branch multiops is %d \n", total_branch_multiops);
00539 fprintf (sf, "\tNumber of branch ops is %d \n", total_branch_ops);
00540 fprintf (sf, "\tDynamic op reduction due to multiway is %lf \n\n", multiway_dynamic_op_reduction);
00541 fclose (sf);
00542 }
00543
00544
00545
00546
00547 if (verbose && !nooutput)
00548 printf ("ccom| Writing output to %s.\n", (outputfile != NULL ?
00549 outputfile : "stdout"));
00550 if (!nooutput)
00551 {
00552 if (outputfile != NULL)
00553 LegoWrite (M, outputfile);
00554 else
00555 LegoWrite (M);
00556 }
00557
00558
00559 return 0;
00560 }