Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

ccom.C

Go to the documentation of this file.
00001 // ccom.C
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 //#include "legoSched.H"
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 } // end ShowSyntax
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    /* READ ARGUMENTS */ 
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                 } // end if
00076 
00077                 if (strcmp (arg, "-n") == 0 ||
00078                   strcmp (arg, "-nooutput") == 0)
00079                 {
00080                   nooutput = 1;
00081                   continue;
00082                 } // end if
00083 
00084                 if (strcmp (arg, "-kf") == 0)
00085                 {
00086                   knobfile = argv[++i];
00087                   continue;
00088                 } // end if
00089 
00090                 if (strcmp (arg, "-o") == 0)
00091                 {
00092                   outputfile = argv[++i];
00093                   continue;
00094                 } // end if
00095 
00096                 if (arg[0] == '-' && arg[1] == 'K')
00097                 continue;
00098 
00099                 inputfile = arg;
00100         } // end for
00101 
00102         if (inputfile == NULL)
00103         {
00104                 printf ("ccom| No input file specified.");
00105                 ShowSyntax();
00106         } // end if
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   // 1. REGION FORMATION
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   //cerr.setf(ios::fixed,ios::floatfield); 
00141   //cerr.precision(4); 
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                         // UnBindSB elcor superblocks (represented as hbs) for true BBs
00152                         UnBindSB(P);
00153                         if (verbose)
00154                         {
00155                            putchar ('.');
00156                            fflush (stdout);
00157                         } // end if
00158                 } // end for    
00159                 if (verbose) putchar ('\n');
00160         }
00161         else
00162         if (strcmp (regiontype, "treegion") == 0)
00163         {
00164         //      for (unsigned i = 1; i <= 1; i++)
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                          } // end if
00176                 } // end for
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                                  } // end if
00196                         } // end for
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                           } // end if
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                          } // end if
00234                 } // end for
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                   } // end if
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                          } // end if
00266                 } // end for
00267                         if (verbose) putchar ('\n');
00268         } // end else
00269 
00270   finish_rform = clock();
00271   IA64Write(M,"RegionOutput.s");
00272 
00273   //=====================================================================
00274   // 
00275   // 2. SCHEDULING
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   //char op_schedule;
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   //K->Read ("ccom:op-schedule", op_schedule);
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);                 // The constructor of machine class
00309                                                                                                 // also loads the lmdes file. 
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                 } // end if
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                          // Do not allow speculation during scheduling if regiontype is FICT
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                   } // end if
00351                 } // end for
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                         //        for (unsigned i = 1; i <= 1; i++)
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                                 } // end if
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                                         } // end if
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                                 } // end if
00422                   }
00423                   if (verbose) putchar ('\n');
00424                 }
00425                 if (verbose)
00426                   printf ("ccom| 2nd Pass Scheduling \n");
00427                 //      for (unsigned i = 1; i <= 1; i++)
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                          //cerr << "total_dag ticks = " << total_dag << " so far\n";
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                                 } // end if
00447                   } // end for  
00448                         }
00449 
00450                 // Have to backpatch the original_op_count, since the scheduler
00451                 // will have never seen the old count.
00452         // want tail-duplication expansion even if no sched, now doing below uncond. 
00453         //      ss->original_op_count = ooc;
00454                 
00455 
00456                 // Add the new static estimation
00457                 st_st = StaticEstimate (M);
00458 
00459                 if (debug_stats != NULL) debugstatsf.close();
00460                 delete mach;
00461 
00462                 if (verbose) putchar ('\n');
00463         } // end if
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   // REPORTING
00473 
00474   char *stats;
00475   char append_stats;
00476   FILE *sf;
00477 
00478 // want tail-duplication expansion even if no sched
00479   ss->original_op_count = ooc;
00480 // delay of removing dom // ops using dp_remove (so rdefs are maintained) 
00481 // fucks up final count, so re-do now 
00482   ss->final_op_count = M->GetOpCount();
00483 
00484 //  if (do_schedule)
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         } // end if
00543 //    } // end if
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          } // end if
00557 
00558   
00559   return 0;
00560 } // end main

Generated on Mon Jul 21 20:24:03 2003 for TINKER LEGO DOC by doxygen 1.3.2