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
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 static char *source_file = __FILE__;
00054
00055 #include <errno.h>
00056
00057 #include "defs.h"
00058 #include "tracing.h"
00059 #include "erglob.h"
00060 #include "flags.h"
00061 #include "util.h"
00062
00063
00064 char *SBar =
00065 "-----------------------------------------------------------------------\n";
00066 char *DBar =
00067 "=======================================================================\n";
00068 char *Sharps =
00069 "#######################################################################\n";
00070
00071 #define INDENT 2
00072
00073
00074 static FILE *TFile_internal = NULL;
00075
00076
00077 #ifdef FRONT_END_F77
00078 extern FILE *Kqqgso();
00079 #endif
00080
00081
00082 INT32 Progress_Flags = 0;
00083
00084
00085 static BOOL Non_stdout_TFile = FALSE;
00086 static char *TFile_Name = "stdout";
00087
00088
00089 #define BB_COUNT 50
00090 #define PU_COUNT 10
00091 #define REGION_COUNT 10
00092 #define CTRL_COUNT 50
00093 static UINT TI_Mask;
00094 static UINT TD_Mask;
00095 static UINT TI_Phase[TP_COUNT];
00096 static UINT TS_Phase[TP_COUNT];
00097 static UINT TN_Phase[TP_COUNT];
00098 static UINT TA_Phase[TP_COUNT];
00099 static UINT TP_Mask[TP_COUNT];
00100 static UINT TB_Enable[BB_COUNT];
00101 static UINT BB_Cnt = 0;
00102 static UINT Xstop_Phase = TP_LAST;
00103 static UINT TC_Enable[CTRL_COUNT];
00104 static char *PU_Enable[PU_COUNT];
00105 static INT PU_Num_Enable[PU_COUNT];
00106 static UINT PU_Cnt = 0;
00107 static UINT PU_NCnt = 0;
00108 static INT Region_Num_Enable[REGION_COUNT];
00109 static UINT REGION_NCnt = 0;
00110
00111 static char *Current_PU_Name = NULL;
00112 static INT Current_PU_Number = 0;
00113 static INT Current_Region_Number = 0;
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 typedef struct {
00128 INT32 num;
00129 char *id;
00130 char *name;
00131 } PDESC;
00132
00133 #define PD_num(p) (p->num)
00134 #define PD_id(p) (p->id)
00135 #define PD_name(p) (p->name)
00136
00137
00138
00139
00140
00141
00142
00143
00144 static PDESC Phases[] = {
00145
00146 { TP_PTRACE1, "PT1", "Performance #1" },
00147 { TP_PTRACE2, "PT2", "Performance #2" },
00148 { TP_MISC, "MSC", "Miscellaneous" },
00149
00150
00151 { TP_SEMANTICS, "SEM", "Semantic analyzer" },
00152 { TP_IRB, "IRB", "IR (WHIRL) builder" },
00153
00154
00155 { TP_IR_READ, "IRR", "IR (WHIRL) reader/writer" },
00156 { TP_WHIRL2FC, "WH2", "WHIRL to Fortran/C" },
00157 { TP_WHIRLSIMP, "SMP", "WHIRL simplifier" },
00158 { TP_REGION, "RGN", "Region support" },
00159 { TP_ORI, "ORI", "Olimit Region Insertion" },
00160 { TP_FEEDBACK, "FDB", "Feedback support" },
00161 { TP_VHO_LOWER, "VHO", "VHO lowering" },
00162 { TP_LOWER, "LOW", "WHIRL lowering" },
00163 { TP_LOWER90, "L90", "F90 WHIRL lowering" },
00164
00165
00166 { TP_INLINE, "INL", "Inliner" },
00167 { TP_IPL, "IPL", "IPA local summary phase" },
00168 { TP_IPA, "IPA", "IPA analysis phase" },
00169 { TP_IPO, "IPO", "IPA optimization phase" },
00170 { TP_IPM, "IPM", "IPA miscellaneous" },
00171
00172
00173 { TP_ALIAS, "ALI", "Alias/mod/ref analysis" },
00174 { TP_WOPT1, "OPT", "Global optimization" },
00175 { TP_WOPT2, "OP2", "More global optimization" },
00176 { TP_WOPT3, "OP3", "Even more global optimization" },
00177
00178
00179 { TP_VECDD, "VDD", "Vector data dependency analysis" },
00180 { TP_LNOPT, "LNO", "Loop Nest Optimization" },
00181 { TP_LNOPT2, "LN2", "More Loop Nest Optimization" },
00182 { TP_LNOPT3, "LN3", "Even more Loop Nest Optimization" },
00183
00184
00185 { TP_CG, "CGM", "Code Generator miscellaneous" },
00186 { TP_DATALAYOUT, "LAY", "Data layout" },
00187 { TP_CGEXP, "EXP", "Code generator expansion" },
00188 { TP_LOCALIZE, "LOC", "Localize TNs" },
00189 { TP_FIND_GLOB, "GLR", "Find global register live ranges" },
00190 { TP_EBO, "EBO", "Extended Block Optimizer" },
00191 { TP_FLOWOPT, "FLW", "Control flow optimization" },
00192 { TP_HBF, "HBF", "Hyperblock Formation" },
00193 { TP_PQS, "PQS", "Predicate query system" },
00194 { TP_CGPREP, "PRP", "Code generator scheduling prep" },
00195 { TP_CGLOOP, "LOP", "Code generator loop optimization" },
00196 { TP_SWPIPE, "SWP", "Software pipelining" },
00197 { TP_SRA, "SRA", "Software pipelining register allocation" },
00198 { TP_SCHED, "SCH", "Scheduling" },
00199 { TP_GCM, "GCM", "Global code motion" },
00200 { TP_GRA, "GRA", "Global register allocation" },
00201 { TP_ALLOC, "LRA", "Local register allocation" },
00202 { TP_PSGCM, "PSG", "Post Schedule Global code motion" },
00203 { TP_THR, "THR", "Tree-Height Reduction" },
00204 { TP_EMIT, "EMT", "Code emission" },
00205
00206 { TP_TEMP, "TMP", "Temporary use" },
00207
00208
00209 { TP_COUNT, NULL, NULL }
00210 };
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 INT32
00226 Get_Trace_Phase_Number (
00227 char **cp,
00228 char *arg )
00229 {
00230
00231 if ( **cp >= '0' && **cp <= '9' ) {
00232 return Get_Numeric_Flag ( cp, 0, TP_LAST, 0, arg );
00233
00234
00235 } else {
00236 PDESC *phase = Phases;
00237
00238 while ( PD_num(phase) != TP_COUNT ) {
00239 if ( strncasecmp ( *cp, PD_id(phase), 3 ) == 0 ) {
00240 *cp += 3;
00241 return PD_num(phase);
00242 }
00243 ++phase;
00244 }
00245 ErrMsg ( EC_Trace_Phase, -1, TP_MIN, TP_LAST );
00246 return 0;
00247 }
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 void
00260 List_Phase_Numbers ( void )
00261 {
00262 PDESC *phase = Phases;
00263
00264 fprintf ( Get_Trace_File(),
00265 "Trace phase numbers supported and their values:\n" );
00266 while ( PD_num(phase) != TP_COUNT ) {
00267 fprintf ( Get_Trace_File(), " %3s: -tt%02d:0x%08x (%s)\n",
00268 PD_id(phase), PD_num(phase), TP_Mask[PD_num(phase)],
00269 PD_name(phase) );
00270 ++phase;
00271 }
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 void
00295 Set_Trace ( INT func, INT arg )
00296 {
00297
00298 if ( func < TKIND_MIN || func == 0 ) {
00299 ErrMsg ( EC_Trace_Func, func );
00300 return;
00301 } else if ( func > TP_LAST ) {
00302 ErrMsg ( EC_Trace_Phase, func, TKIND_MIN, TP_LAST );
00303 return;
00304 }
00305
00306
00307 switch ( func ) {
00308
00309 case TKIND_INFO:
00310 TI_Mask |= arg;
00311 return;
00312
00313
00314 case TKIND_DEBUG:
00315 TD_Mask |= arg;
00316 return;
00317
00318
00319 case TKIND_IR:
00320 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) {
00321 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST );
00322 } else {
00323 TI_Phase[arg] = TRUE;
00324 }
00325 return;
00326
00327
00328 case TKIND_SYMTAB:
00329 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) {
00330 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST );
00331 } else {
00332 TS_Phase[arg] = TRUE;
00333 }
00334 return;
00335
00336
00337 case TKIND_TN:
00338 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) {
00339 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST );
00340 } else {
00341 TN_Phase[arg] = TRUE;
00342 }
00343 return;
00344
00345
00346 case TKIND_ALLOC:
00347 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) {
00348 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST );
00349 } else {
00350 TA_Phase[arg] = TRUE;
00351 }
00352 return;
00353
00354
00355 case TKIND_BB:
00356 if ( ++BB_Cnt >= BB_COUNT ) {
00357 ErrMsg ( EC_Trace_BBs, arg );
00358 --BB_Cnt;
00359 } else {
00360 TB_Enable[BB_Cnt] = arg;
00361 }
00362 return;
00363
00364
00365 case TKIND_XPHASE:
00366 if ( arg != Check_Range (arg, TP_MIN, TP_LAST, 0) ) {
00367 ErrMsg ( EC_Trace_Phase, arg, TP_MIN, TP_LAST );
00368 } else {
00369 Xstop_Phase = arg;
00370 }
00371 return;
00372
00373
00374 case TKIND_CTRL:
00375 if ( arg != Check_Range (arg, 0, CTRL_COUNT-1, 0) ) {
00376 ErrMsg ( EC_Trace_Control, arg, CTRL_COUNT-1 );
00377 } else {
00378 TC_Enable[arg] = TRUE;
00379 }
00380 return;
00381
00382
00383 default:
00384 TP_Mask[func] |= arg;
00385 return;
00386 }
00387 }
00388
00389
00390 #define RID_CREATE_NEW_ID -1
00391 void
00392 Set_Current_PU_For_Trace ( char *name, INT number )
00393 {
00394 Current_PU_Name = name;
00395 Current_PU_Number = number;
00396
00397 Set_Current_Region_For_Trace(RID_CREATE_NEW_ID);
00398 }
00399
00400 void
00401 Set_Current_Region_For_Trace ( INT number )
00402 {
00403 Current_Region_Number = number;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 void
00416 Set_Trace_Pu ( char *name )
00417 {
00418 if ( ++PU_Cnt >= PU_COUNT ) {
00419 ErrMsg ( EC_Trace_PUs, name );
00420 --PU_Cnt;
00421 } else {
00422 PU_Enable[PU_Cnt] = name;
00423 }
00424 return;
00425 }
00426
00427 void
00428 Set_Trace_Pu_Number ( INT number )
00429 {
00430 if ( ++PU_NCnt >= PU_COUNT ) {
00431 ErrMsg ( EC_Trace_PUs, "<number>");
00432 --PU_NCnt;
00433 } else {
00434 PU_Num_Enable[PU_NCnt] = number;
00435 }
00436 return;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 void
00448 Set_Trace_Region_Number ( INT number )
00449 {
00450 if ( ++REGION_NCnt >= REGION_COUNT ) {
00451 ErrMsg ( EC_Trace_REGIONs, "<number>");
00452 --REGION_NCnt;
00453 } else
00454 Region_Num_Enable[REGION_NCnt] = number;
00455 return;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 BOOL
00470 Get_BB_Trace ( INT32 bb_id )
00471 {
00472 INT16 i;
00473 BOOL enabled = TRUE;
00474
00475 if ( PU_Cnt > 0 ) {
00476 for ( i = 1; i <= PU_Cnt; i++ ) {
00477 if ( strcmp(PU_Enable[i],Current_PU_Name) == 0 ) return TRUE;
00478 }
00479 enabled = FALSE;
00480 }
00481 if ( PU_NCnt > 0 ) {
00482 for ( i = 1; i <= PU_NCnt; i++ ) {
00483 if ( PU_Num_Enable[i] == Current_PU_Number ) return TRUE;
00484 }
00485 enabled = FALSE;
00486 }
00487
00488 if ( BB_Cnt > 0 ) {
00489 for ( i = 1; i <= BB_Cnt; i++ ) {
00490 if (TB_Enable[i] == bb_id) return TRUE;
00491 }
00492 return FALSE;
00493 }
00494
00495
00496 return enabled;
00497 }
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 BOOL
00509 Get_Trace ( INT func, INT arg )
00510 {
00511 BOOL result;
00512 INT16 i;
00513
00514
00515 switch ( func ) {
00516
00517 case TKIND_INFO:
00518 result = (TI_Mask & arg) != 0;
00519 break;
00520
00521 case TKIND_DEBUG:
00522 result = (TD_Mask & arg) != 0;
00523 break;
00524
00525 case TKIND_IR:
00526 result = TI_Phase[arg];
00527 break;
00528
00529 case TKIND_SYMTAB:
00530 result = TS_Phase[arg];
00531 break;
00532
00533 case TKIND_TN:
00534 result = TN_Phase[arg];
00535 break;
00536
00537 case TKIND_CTRL:
00538 result = TC_Enable[arg];
00539 break;
00540
00541 case TKIND_ALLOC:
00542 result = TA_Phase[arg];
00543 break;
00544
00545 case TKIND_BB:
00546 case TKIND_XPHASE:
00547
00548 default:
00549 result = (TP_Mask[func] & arg) != 0;
00550 break;
00551 }
00552
00553 if ( result && PU_Cnt > 0 ) {
00554 for ( i = 1; i <= PU_Cnt; i++ ) {
00555 if ( strcmp(PU_Enable[i], Current_PU_Name) == 0 )
00556 break;
00557 }
00558 if (i > PU_Cnt)
00559 result = FALSE;
00560 }
00561
00562 if ( result && PU_NCnt > 0 ) {
00563 for ( i = 1; i <= PU_NCnt; i++ ) {
00564 if ( PU_Num_Enable[i] == Current_PU_Number )
00565 break;
00566 }
00567 if (i > PU_NCnt)
00568 result = FALSE;
00569 }
00570
00571 if (result && REGION_NCnt > 0) {
00572 for ( i = 1; i <= REGION_NCnt; i++ ) {
00573 if ( Region_Num_Enable[i] == Current_Region_Number )
00574 break;
00575 }
00576 if ( i > REGION_NCnt )
00577 result = FALSE;
00578 }
00579
00580 return result;
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 BOOL
00595 Stop_Execution ( INT phase )
00596 {
00597 return phase >= Xstop_Phase;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 void
00614 Set_Trace_File (
00615 char *filename )
00616 {
00617 if ( Non_stdout_TFile && TFile_internal != NULL ) {
00618 #ifndef FRONT_END_F77
00619 fclose (TFile_internal);
00620 #endif
00621 Set_Error_Trace (NULL);
00622 }
00623
00624 if ( filename != NULL ) {
00625 #ifdef FRONT_END_F77
00626 TFile_internal = Kqqgso();
00627 #else
00628 TFile_internal = fopen ( filename, "w" );
00629 #endif
00630 if ( TFile_internal != NULL ) {
00631 TFile_Name = filename;
00632 Non_stdout_TFile = TRUE;
00633 Set_Error_Trace (TFile_internal);
00634 return;
00635 }
00636 ErrMsg ( EC_Trace_Open, filename, errno );
00637 }
00638 TFile_internal = stdout;
00639 TFile_Name = NULL;
00640 Non_stdout_TFile = FALSE;
00641 Set_Error_Trace (NULL);
00642 }
00643
00644 void Set_Trace_File_internal(FILE *f)
00645 {
00646 TFile_internal = f;
00647 }
00648
00649 FILE *Get_Trace_File(void)
00650 {
00651 if (TFile_internal == NULL)
00652 TFile_internal = stdout;
00653
00654 return TFile_internal;
00655 }
00656
00657 void
00658 Trace_To_Stderr(void)
00659 {
00660 if ( Non_stdout_TFile && TFile_internal != NULL ) {
00661 #ifndef FRONT_END_F77
00662 fclose (TFile_internal);
00663 #endif
00664 Set_Error_Trace (NULL);
00665 }
00666
00667 TFile_internal = stderr;
00668 TFile_Name = NULL;
00669 Non_stdout_TFile = FALSE;
00670 Set_Error_Trace (NULL);
00671 }
00672
00673
00674 #ifndef MONGOOSE_BE
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 void
00686 Nest_Indent ( FILE *fp )
00687 {
00688 fprintf ( fp, "%*c", ( INDENT * ( trace_stack(0,0) - 1 ) ), ' ' );
00689 }
00690 #endif