afa8fbee1903886ccc7a4d5a53c303b2dcffa744
[ghc-hetmet.git] / utils / prof / cgprof / main.c
1 /* ------------------------------------------------------------------------
2  * $Id: main.c,v 1.4 2005/12/02 12:45:16 simonmar Exp $
3  *                                                                      
4  *      Copyright (C) 1995-2000 University of Oxford
5  *                                                                      
6  * Permission to use, copy, modify, and distribute this software,
7  * and to incorporate it, in whole or in part, into other software,
8  * is hereby granted without fee, provided that
9  *   (1) the above copyright notice and this permission notice appear in
10  *       all copies of the source code, and the above copyright notice
11  *       appear in clearly visible form on all supporting documentation
12  *       and distribution media;
13  *   (2) modified versions of this software be accompanied by a complete
14  *       change history describing author, date, and modifications made;
15  *       and
16  *   (3) any redistribution of the software, in original or modified
17  *       form, be without fee and subject to these same conditions.
18  * --------------------------------------------------------------------- */
19
20 #include "ghcconfig.h"
21
22 #include <stdio.h>
23
24 #if HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 #if HAVE_STRING_H
28 #include <string.h>
29 #endif
30
31 #include "symbol.h"
32 #include "cgprof.h"
33 #include "matrix.h"
34 #include "daVinci.h"
35
36 #if HAVE_WINDOWS_H
37 #include <windows.h>
38 #define sleep(x) Sleep((x)*1000)
39 #endif
40
41
42 #define NoDeletes 80
43
44 int     CriticalPath=CRITICAL_SYNCS;
45 int     CriticalType=CRITTYPE_ABSOLUTE;
46 int     Verbose=1;
47 int     NodeviewTime=1;
48 int     NodeviewCompress=1;
49 int     PrintLogo=1;
50 int     Colour=1;
51 int     DeltaNormalise=1;
52 int     PieView=TCL_COMP;
53 int     PieCombine=0;
54 char   *Pgm;
55 char   *ProfileData;
56 int     NoNodes,root;
57 char    usage[]="usage:  cgprof profile-data [See man 1 cgprof]";
58 char    helpUrl[]="http://www.dcs.warwick.ac.uk/people/academic/Stephen.Jarvis/profiler/";
59 Matrix  graph; /* NoNodes x NoNodes matrix of integers */
60 Matrix  costs; /* NoNodes x 1       matrix of costs    */
61
62 double   TotalComp, TotalComm, TotalCompIdle;
63 int      TotalSyncs;
64 long int TotalH;
65
66 char    *dateProfiled, *machineName;
67 double minNodeSize = 0.01;   /* i.e, don't show nodes with _combined_
68                                     comp and comm % less than this */
69 double bsp_s = 74.0;
70 double bsp_l = 1902;
71 double bsp_g = 9.3;
72 int    bsp_p;
73
74 FILE *logFile;
75
76
77 extern void printDaVinci(int);
78
79 int 
80 main(int argc, char *argv[]) {
81   char davinci_stdin[MAX_PROFILE_LINE_LENGTH];
82   FILE   *fptr;
83   int i,j,k,going=1,*select_nodes, select_nodes_next,MaxNoNodes;
84   davinciCmd cmd;
85   int *undo_stack, undo_stack_next;
86   float temp_f;
87   char *ptr;
88   int mode = 0;
89   char *tempstring = malloc (80);
90   char *tempstring2 = malloc (80);
91   
92
93   /* printf("Starting main routine of browser script\n"); */
94   /* fflush(stderr); */
95
96   if (argc!=14) {
97     fprintf(stderr,"The perl script bspsgprof is buggered\n");
98     exit(1);
99   }
100
101   /* Most (if not all) of these BSP specific arguments can be removed */
102
103   Pgm         = argv[0];
104   ProfileData = argv[1];
105   bsp_p       = atoi(argv[2]);
106   machineName = argv[3];
107   dateProfiled= argv[4];
108   sscanf(argv[5],"%f",&temp_f);
109   bsp_s = temp_f;
110   sscanf(argv[6],"%f",&temp_f);
111   bsp_l = temp_f;
112   sscanf(argv[7],"%f",&temp_f);
113   bsp_g = temp_f;
114   sscanf(argv[8],"%f",&temp_f);
115   minNodeSize=temp_f;
116   Verbose = atoi(argv[9]);
117   PrintLogo=atoi(argv[10]);
118   Colour=atoi(argv[11]);
119   DeltaNormalise=atoi(argv[12]);
120   MaxNoNodes=atoi(argv[13]);
121
122   /* printf("Initialisation done\n"); */
123
124   if (Verbose) sleep(10);  
125   if (!(fptr=fopen(ProfileData,"r"))) {
126     fprintf(stderr,"%s: unable to open profile data in \"%s\".\n%s\n",
127             Pgm,ProfileData,usage);
128     exit(1);
129   }
130   if (!(logFile=fopen("ghcprof.log","w"))) {
131     fprintf(stderr,"%s: unable to open log file for writing\n",Pgm);
132     exit(1);
133   }
134
135   /* printf("Files opened OK\n"); */
136
137   if (!fgets(davinci_stdin, MAX_PROFILE_LINE_LENGTH, stdin) || 
138        strcmp(davinci_stdin,"ok\n")) {
139     fprintf(stderr,"%s{%s}: failed to receive ok from daVinci.\n",
140             davinci_stdin,Pgm);
141     exit(1);
142   }
143
144   /* printf("Initialising daVinci\n"); */
145
146   initDaVinci();
147   
148   /* printf("Ending initialisation of daVinci\n"); */
149  
150   if (Verbose) fprintf(logFile,"%s: opened profile file \"%s\".\n",Pgm,ProfileData);
151   readRawProfile(fptr,&NoNodes,MaxNoNodes);
152   fclose(fptr);
153   if (Verbose) fprintf(logFile,"%s: %d nodes in profile.\n",Pgm,NoNodes);
154
155   if (NoNodes<=0) {
156     fprintf(logFile,"%s: no call-graph profile data in \"%s\".\n"
157             "Re-run your program using the appropriate profiling flags\n",
158             Pgm,ProfileData);
159     exit(1);
160   }
161   if (Verbose) printRawProfile();
162
163   /* Do we want INHERITANCE to begin with or not? Set to yes. */
164   createConnectivityMatrix(NoNodes,&graph,&costs,&root,1);
165
166   TotalComp     = Mat(object_cost,costs,root,0).comp_max;
167   TotalComm     = Mat(object_cost,costs,root,0).comm_max;
168   TotalCompIdle = Mat(object_cost,costs,root,0).comp_idle_max;
169   TotalH        = Mat(object_cost,costs,root,0).hrel_max;
170   TotalSyncs    = Mat(object_cost,costs,root,0).syncs;
171   if (Verbose) printConnectivityMatrix(graph,costs,root);
172   fflush(logFile);
173   graphToDaVinci(root,&graph,&costs,0);
174   fflush(stdout);
175   undo_stack   = calloc(NoDeletes,sizeof(int));
176   select_nodes = calloc(NoNodes,sizeof(int));
177   if (undo_stack==NULL || select_nodes==NULL) {
178     fprintf(stderr,"Unable to allocate storage for undo stack\n");
179     exit(1);
180   }
181   undo_stack_next=0;
182   select_nodes_next=0;
183   // Pie chart stuff not wanted for GHC
184   // tclPieInit();
185   // tclPieUpdate(&Mat(object_cost,costs,root,0),root,PieView);
186   select_nodes_next=1;
187   select_nodes[0]=root;
188   while (fgets(davinci_stdin, MAX_PROFILE_LINE_LENGTH, stdin) && going) {
189     cmd = parseDaVinciCmd(davinci_stdin);
190     if (Verbose) fprintf(logFile,"From davinci=\"%s\"\n",davinci_stdin);
191     switch (cmd.type) {
192     case DAVINCI_OK:
193       continue;
194
195     case DAVINCI_QUIT:
196       going=0;
197       break;
198
199     case DAVINCI_NODE:
200       select_nodes_next=cmd.size;
201       for(i=0;((i<cmd.size) && (i<NoNodes));i++)
202         select_nodes[i]=atoi(cmd.list[i]);
203       if (select_nodes_next>0)
204         //Pie chart stuff not wanted for GHC
205         //tclPieUpdate(&Mat(object_cost,costs,select_nodes[0],0),
206         //                   select_nodes[0],
207         //                   PieView);
208       if (mode==3) 
209       {
210          mode = atoi(cmd.list[0]);
211          getNameFromSymbolTable(mode,tempstring);
212          for(ptr=tempstring;*ptr!='\0';ptr++)
213             if (*ptr=='&') *ptr=' ';
214          mode = 3;
215          strcpy(tempstring2,"window(show_status(\"");
216          strcat(tempstring2,tempstring);
217          strcat(tempstring2,"\"))");
218          cmdDaVinci(tempstring2);
219          strcpy(tempstring,"");
220          strcpy(tempstring2,"");
221       }
222       break;
223
224     case DAVINCI_MENU:
225       if (cmd.size>0) {
226         if (strcmp(cmd.list[0], "jump")==0)  {
227           if ((select_nodes_next>=0)      && 
228               (select_nodes[0]>0)         &&
229               (select_nodes[0] < NoNodes) &&
230               (Mat_dense(graph,select_nodes[0],select_nodes[0]))) {
231             cmdDaVinci("special(focus_node(\"%d\"))\n",select_nodes[0]);
232           }
233         }
234       }
235       break;
236
237     case DAVINCI_ICON:
238       if (cmd.size>0) {
239         if (strcmp(cmd.list[0], "sync")==0) {
240           CriticalPath=CRITICAL_SYNCS;
241           activateDaVinciMenu(cmd.list[0]);
242           cmdDaVinci("window(show_status(\"Graph view\"))");
243           updateColours(root,&graph,&costs);
244
245         } else if (strcmp(cmd.list[0], "comp")==0) {
246           CriticalPath=CRITICAL_COMP;
247           activateDaVinciMenu(cmd.list[0]);
248           cmdDaVinci("window(show_status(\"SCCs critical path\"))");
249           updateColours(root,&graph,&costs);
250           
251         } else if (strcmp(cmd.list[0], "comm")==0) {
252           CriticalPath=CRITICAL_COMM;
253           activateDaVinciMenu(cmd.list[0]);
254           cmdDaVinci("window(show_status(\"Computation time critical path\"))");
255           updateColours(root,&graph,&costs);
256           
257         } else if (strcmp(cmd.list[0], "wait")==0) {
258           CriticalPath=CRITICAL_WAIT;
259           activateDaVinciMenu(cmd.list[0]);
260           cmdDaVinci("window(show_status(\"Heap usage critical path\"))"); 
261           updateColours(root,&graph,&costs);
262           
263         } else if (strcmp(cmd.list[0], "hrel")==0) {
264
265           if (mode != 3)
266           {
267             cmdDaVinci("window(show_status(\"Node spy on\"))");
268             mode = 3;
269           }
270           else 
271           {
272             mode = 0;
273             cmdDaVinci("window(show_status(\"Node spy off\"))");
274           }
275
276         } else if (strcmp(cmd.list[0], "absolute")==0) {
277           /* Now deals with inheritance profile */
278           CriticalType=CRITTYPE_ABSOLUTE;
279           activateDaVinciMenu(cmd.list[0]);
280           cmdDaVinci("window(show_status(\"Inheritance profile\"))");
281           freeMat(&graph); 
282           freeMat(&costs); 
283           createConnectivityMatrix(NoNodes,&graph,&costs,&root,1);
284           graphToDaVinci(root,&graph,&costs,0);
285           cmdDaVinci("window(show_status(\"Inheritance profile\"))");
286           updateColours(root,&graph,&costs);
287
288         } else if (strcmp(cmd.list[0], "absdelta")==0) {
289           /* Now deals with flat profile */
290           CriticalType=CRITTYPE_ABSDELTA;
291           activateDaVinciMenu(cmd.list[0]);
292           cmdDaVinci("window(show_status(\"Flat profile\"))");
293           freeMat(&graph); 
294           freeMat(&costs); 
295           createConnectivityMatrix(NoNodes,&graph,&costs,&root,0);
296           graphToDaVinci(root,&graph,&costs,0);
297           cmdDaVinci("window(show_status(\"Flat profile\"))");
298           updateColours(root,&graph,&costs);
299
300         } else if (strcmp(cmd.list[0], "reldelta")==0) {
301           CriticalType=CRITTYPE_ABSOLUTE;
302           activateDaVinciMenu(cmd.list[0]);
303           cmdDaVinci("window(show_status(\"Trimmed zero-cost sub-trees\"))");
304           strcpy(cmd.list[0], "absolute");
305           activateDaVinciMenu(cmd.list[0]);
306           graphToDaVinci(root,&graph,&costs,2);
307           updateColours(root,&graph,&costs);
308           
309         } else if (strcmp(cmd.list[0], "weightdelta")==0) {
310           CriticalType=CRITTYPE_ABSOLUTE;
311           activateDaVinciMenu(cmd.list[0]);
312           cmdDaVinci("window(show_status(\"Marked zero-cost nodes ready for deletion\"))");
313           strcpy(cmd.list[0], "absolute");
314           activateDaVinciMenu(cmd.list[0]);
315           graphToDaVinci(root,&graph,&costs,1);
316           updateColours(root,&graph,&costs);
317           
318         } else if (strcmp(cmd.list[0],"help")==0) {
319           cmdDaVinci("special(show_url(\"%s\"))",helpUrl);
320
321         } else if (strcmp(cmd.list[0],"time")==0) {
322           NodeviewTime=1;
323           activateDaVinciMenu(cmd.list[0]);
324           cmdDaVinci("window(show_status(\"Cost metric view\"))");
325           graphToDaVinci(root,&graph,&costs,0);
326
327         } else if (strcmp(cmd.list[0],"percent")==0) {
328           NodeviewTime=0;
329           activateDaVinciMenu(cmd.list[0]);
330           cmdDaVinci("window(show_status(\"Percentage view\"))");
331           graphToDaVinci(root,&graph,&costs,0);
332
333         } else if (strcmp(cmd.list[0],"compress")==0) {
334           NodeviewCompress=1;
335           activateDaVinciMenu(cmd.list[0]);
336           cmdDaVinci("window(show_status(\"Compressed node view\"))");
337           cmdDaVinci("menu(layout(compact_all))");
338           graphToDaVinci(root,&graph,&costs,0);
339
340         } else if (strcmp(cmd.list[0],"uncompress")==0) {
341           NodeviewCompress=0;
342           activateDaVinciMenu(cmd.list[0]);
343           cmdDaVinci("window(show_status(\"Uncompressed node view\"))");
344           graphToDaVinci(root,&graph,&costs,0);
345
346         } else if ((strcmp(cmd.list[0],"delete")==0) ||
347                    (strcmp(cmd.list[0],"undo")==0)) {
348           if (strcmp(cmd.list[0],"delete")==0) {
349             if (undo_stack_next==0) 
350               activateDaVinciMenu("undo");
351             for(i=0;(i<select_nodes_next) && (undo_stack_next<NoNodes);i++) 
352               undo_stack[undo_stack_next++] = select_nodes[i];
353             if (undo_stack_next==NoDeletes) 
354               activateDaVinciMenu("delete");
355             cmdDaVinci("window(show_status(\"Deleted node (s)\"))");
356             select_nodes_next=0;
357           } else {
358             if (undo_stack_next==NoDeletes) 
359               activateDaVinciMenu("delete");
360             undo_stack_next--;
361             if (undo_stack_next==0) 
362               activateDaVinciMenu("undo");
363             cmdDaVinci("window(show_status(\"Undone deletion\"))");
364             select_nodes_next=1;
365             select_nodes[0]=undo_stack[undo_stack_next];
366             
367             for(i=0;i<raw_profile_next;i++)
368               raw_profile[i].active=1;
369           }
370           activateDaVinciMenu("default");
371           for(i=0;i<undo_stack_next;i++) {
372             for(j=0;j<raw_profile_next;j++) {
373               for(k=0;k<raw_profile[j].stack_size;k++) {
374                 if (raw_profile[j].stack[k]==undo_stack[i])
375                   raw_profile[j].active=0;
376               }
377             }
378           }
379           cmdDaVinci("window(show_message(\"Deleting node...\"))");
380           freeMat(&graph);
381           freeMat(&costs);
382           createConnectivityMatrix(NoNodes,&graph,&costs,&root,1);
383           graphToDaVinci(root,&graph,&costs,0);
384           if (strcmp(cmd.list[0],"undo")==0) {
385             if ((select_nodes[0]>0)         &&
386                 (select_nodes[0] < NoNodes) &&
387                 (Mat_dense(graph,select_nodes[0],select_nodes[0]))) {
388             cmdDaVinci("special(focus_node(\"%d\"))\n",select_nodes[0]);
389             cmdDaVinci("special(select_nodes([\"%d\"]))",select_nodes[0]);
390             //Pie chart stuff not wanted for GHC
391             //tclPieUpdate(&Mat(object_cost,costs,select_nodes[0],0),
392             //         select_nodes[0],
393             //         PieView);
394             }
395           }
396         }    
397       }
398       break;
399     case DAVINCI_TCL: 
400     // This stuff can go as it is related to the input for the Pie chart tool
401       if (cmd.size>0) {
402         if        (strcmp(cmd.list[0], "comm")==0)  {
403           PieView=TCL_COMM;
404         } else if (strcmp(cmd.list[0], "comp")==0)  {
405           PieView=TCL_COMP;
406         } else if (strcmp(cmd.list[0], "hrel")==0)  {
407           PieView=TCL_HREL;
408         } else if (strcmp(cmd.list[0], "wait")==0)  {
409           PieView=TCL_WAIT;
410         } else if (strcmp(cmd.list[0], "combine")==0)  {
411           PieCombine=!PieCombine;
412         } else if (strlen(cmd.list[0])==0) {
413           break;
414         }
415         if (select_nodes_next>0) break;
416           //Added a break for compiliation above since it does not compile if 
417           //we just remove the Pie chart code 
418           //tclPieUpdate(&Mat(object_cost,costs,select_nodes[0],0),
419           //           select_nodes[0],
420           //           PieView);
421       }
422       break;
423     case DAVINCI_ERROR:  
424     default:
425       fprintf(stderr,"CGPROF error:\n"
426                      "\tCommand = %s\n"
427                      "\tError   = %s\n",lastDavinciCmd,davinci_stdin);
428       exit(1); 
429       break;
430     }
431     fflush(stdout);
432     fflush(logFile);
433   }  
434
435   return 0;
436 }