1 #define VERSION "24-Jan-95"
2 #define PROGNAME "ICountByActivity"
19 int shade_run(Trace *, int);
21 #define DO_SPAT_PROFILING
22 #define __STG_USING_ULLONG__
23 #include "stgdefs.h" /* GHC ticky-counting stuff */
24 #define ACTIVITY_REG I_REG_g5
25 #define SpA_REG I_REG_i0
26 #define SpB_REG I_REG_i2
27 #define Hp_REG I_REG_i4
28 #define RET_REG I_REG_l0
29 #define NODE_REG I_REG_l1
30 #define INFO_REG I_REG_l2
31 #define R3_REG I_REG_l3
32 #define R7_REG I_REG_l7
34 /* Activity register and current activity */
36 #define EACT_CALL (ACTIVITIES+0)
37 #define EACT_STKADJ (ACTIVITIES+1)
38 #define EACT_ASTK (ACTIVITIES+2)
39 #define EACT_BSTK (ACTIVITIES+3)
40 #define EACT_RETREG (ACTIVITIES+4)
41 #define EACT_ARGREGS (ACTIVITIES+5)
43 #define EACT_TAILCALL (ACT_TAILCALL - ACT_BASE) /* use the TAILCALL slot */
44 #define EACT_OVERHEAD (ACT_OVERHEAD - ACT_BASE) /* only used herein */
46 #define EXTRA_ACTIVITIES 6
48 #define TOTAL_ACTIVITIES (ACTIVITIES+EXTRA_ACTIVITIES)
50 static ullong info[TOTAL_ACTIVITIES][NIHASH];
51 /*static ullong annulled_insns = 0;*/
53 #define STATS_FILE "ICNT_BY_ACTIVITY"
56 void print_results(char *);
57 void fprintf_ullong(FILE *, ullong);
59 #define CHECKPOINT (1024*1024) /* reporting frequency */
60 static long countdown = CHECKPOINT;
62 char *anal_usage = "";
63 char *anal_version = VERSION;
66 initialize(argc,argv,envp)
73 shade_trctl_trsize(sizeof(Trace));
75 shade_trctl_it (IT_ANY, 1, 0, TC_I | TC_IH);
76 shade_trctl_ih (IH_OR, 1, 0, TC_I | TC_IH | TC_RD);
77 shade_trctl_ih (IH_ADD, 1, 0, TC_I | TC_IH | TC_RD | TC_RS1);
78 shade_trctl_ih (IH_SETHI, 1, 0, TC_I | TC_IH | TC_RD);
79 shade_trctl_it (IT_LOAD, 1, 0, TC_I | TC_IH | TC_RD | TC_RS1);
80 shade_trctl_it (IT_ILOAD, 1, 0, TC_I | TC_IH | TC_RD | TC_RS1);
81 shade_trctl_it (IT_STORE, 1, 0, TC_I | TC_IH | TC_RD | TC_RS1);
82 shade_trctl_it (IT_ISTORE,1, 0, TC_I | TC_IH | TC_RD | TC_RS1);
83 /* trace all non-annulled instructions (... 1, 0, ...); For
84 them, we want the instruction text (TC_I), and the hashed
85 opcode (TC_IH). For "or" instructions, we also want the
86 contents the destination register that was written into
91 for (i = 0; i < TOTAL_ACTIVITIES; i++)
92 for (j = 0; j < NIHASH; j++)
96 int analyze(argc,argv,envp)
105 unsigned activity = (ACT_UNKNOWN - ACT_BASE);
106 ullong pending_sethi = 0LL;
107 ullong pending_or = 0LL;
108 ullong activity_chgs = 0LL;
110 #define ACCT_FOR() acctd_for = 1
112 for (i = 0LL; tr = shade_step(); i += 1LL) {
116 if ( ih == IH_OR && tr->tr_i.i_rd == ACTIVITY_REG) {
119 info[EACT_TAILCALL][IH_OR] += pending_or;
120 if ( pending_sethi ) {
121 fprintf(stderr, "pending_sethi still set!\n");
124 if (activity == (ACT_GC - ACT_BASE)) { /* only GC_STOP will stop it */
125 if (rd == ACT_GC_STOP) {
126 activity = ACT_UNKNOWN - ACT_BASE;
127 info[EACT_OVERHEAD][IH_OR] += 1LL;
130 info[activity][IH_OR] += 1LL;
134 if (rd < ACT_BASE || rd >= (ACT_BASE+ACTIVITIES)) {
135 info[activity][IH_OR] += 1LL;
138 activity = rd - ACT_BASE; /* reset! */
139 info[EACT_OVERHEAD][IH_OR] += 1LL;
143 activity_chgs += 1LL;
146 /* reset other things? */
148 } else if ( activity != EACT_TAILCALL ) { /* ordinary instruction */
149 info[activity][ih] += 1LL;
152 } else { /* TAILCALLing */
153 /* fprintf(stderr, "op=%d\n", ih); */
157 /* if ( pending_sethi ) {
158 fprintf(stderr, "pending_sethi already set!\n");
160 */ pending_sethi += 1LL;
166 info[EACT_CALL][ih] += 1LL;
167 info[EACT_CALL][IH_SETHI] += pending_sethi; /* really mystery? */
168 info[EACT_CALL][IH_OR] += pending_or; /* ditto? */
179 rs1 = tr->tr_i.i_rs1;
180 if ( rd == NODE_REG || rd == INFO_REG ) {
181 info[EACT_CALL][ih] += 1LL;
182 info[EACT_CALL][IH_SETHI] += pending_sethi;
183 info[EACT_CALL][IH_OR] += pending_or;
188 } else if (rd >= R3_REG && rd <= R7_REG) {
189 info[EACT_ARGREGS][ih] += 1LL;
190 info[EACT_ARGREGS][IH_SETHI] += pending_sethi;
191 info[EACT_ARGREGS][IH_OR] += pending_or;
197 info[EACT_TAILCALL][IH_SETHI] += pending_sethi;
198 info[EACT_TAILCALL][IH_OR] += pending_or;
202 if ( (rd == SpA_REG && rs1 == SpA_REG)
203 || (rd == SpB_REG && rs1 == SpB_REG) ) {
204 info[EACT_STKADJ][ih] += 1LL;
207 } else if ( rd >= I_REG_o0 && rd <= I_REG_o7 ) {
208 info[EACT_TAILCALL][ih] += 1LL;
211 } else if ( rd == I_REG_g0
212 && rs1 >= I_REG_o0 && rs1 <= I_REG_o7 ) {
213 info[EACT_TAILCALL][ih] += 1LL;
216 } else if ( rd == I_REG_g3 && rs1 == I_REG_g3 ) {
217 info[EACT_TAILCALL][ih] += 1LL;
221 fprintf(stderr, "IH_ADD: mystery op (%d) rd=%d rs1=%d\n",
230 if ( rd == RET_REG ) {
231 info[EACT_RETREG][ih] += 1LL + pending_or;
232 info[EACT_RETREG][IH_SETHI] += pending_sethi;
237 } else if ( rd == NODE_REG || rd == INFO_REG ) {
238 info[EACT_CALL][ih] += 1LL + pending_or;
239 info[EACT_CALL][IH_SETHI] += pending_sethi;
251 case IH_LDUB: /* ??? */
253 rs1 = tr->tr_i.i_rs1;
254 if ( rs1 == SpA_REG ) {
255 info[EACT_ASTK][ih] += 1LL;
256 info[EACT_ASTK][IH_SETHI] += pending_sethi;
257 info[EACT_ASTK][IH_OR] += pending_or;
262 } else if ( rs1 == SpB_REG ) {
263 info[EACT_BSTK][ih] += 1LL;
264 info[EACT_BSTK][IH_SETHI] += pending_sethi;
265 info[EACT_BSTK][IH_OR] += pending_or;
270 } else if ( rs1 == NODE_REG ) {
271 info[EACT_CALL][ih] += 1LL;
272 info[EACT_CALL][IH_SETHI] += pending_sethi;
273 info[EACT_CALL][IH_OR] += pending_or;
278 } else { /* random ld/st */
279 info[EACT_TAILCALL][ih] += 1LL;
280 info[EACT_TAILCALL][IH_SETHI] += pending_sethi;
281 info[EACT_TAILCALL][IH_OR] += pending_or;
288 case IH_AND: /* ??? */
289 case IH_BA: /* ??? */
302 info[EACT_TAILCALL][ih] += 1LL;
303 info[EACT_TAILCALL][IH_SETHI] += pending_sethi;
304 info[EACT_TAILCALL][IH_OR] += pending_or;
311 fprintf(stderr, "mystery TAIL op = %d\n", ih);
316 if (countdown-- < 0) {
317 print_results("Intermediate:");
318 countdown = CHECKPOINT;
321 fprintf(stderr, "insn op=%d not acctd for!\n", ih);
324 fprintf(stderr,"\n");
325 fprintf_ullong(stderr,i);
326 fprintf(stderr," iterations; ");
327 fprintf_ullong(stderr,activity_chgs);
328 fprintf(stderr," activity changes\n");
335 print_results("Final:");
339 print_results(header)
343 long total_slots = 0;
344 ullong total_instrs = 0;
345 static FILE *statf = NULL;
347 /* fprintf(stderr, "Printing %s\n", header); */
350 if ((statf = fopen(STATS_FILE, "w")) == NULL) {
351 fprintf(stderr, "Cannot open statistics file %s\n",STATS_FILE);
354 fprintf(statf, "%s\n\n", header);
355 /* fprintf(statf, "annulled insns = ");
356 fprintf_ullong(statf, annulled_insns);
357 */ fprintf(statf, "\n\n");
359 for (i = 0; i < NIHASH; i++) {
360 fprintf(statf, "%8d:", i);
361 for (j = 0; j < TOTAL_ACTIVITIES; j++) {
363 fprintf_ullong(statf, info[j][i]);
365 total_instrs += info[j][i];
367 fprintf(statf, "\n");
369 fprintf(statf, "total slots=%ld, total instructions=", total_slots);
370 fprintf_ullong(statf, total_instrs);
371 fprintf(statf, "\n");
377 fprintf_ullong(FILE *filep, ullong x)
379 if (x < (ullong)1000)
380 fprintf(filep, "%ld", (I_)x);
381 else if (x < (ullong)1000000)
382 fprintf(filep, "%ld%3.3ld",
383 (I_)((x)/(ullong)1000),
384 (I_)((x)%(ullong)1000));
385 else if (x < (ullong)1000000000)
386 fprintf(filep, "%ld%3.3ld%3.3ld",
387 (I_)((x)/(ullong)1000000),
388 (I_)((x)/(ullong)1000%(ullong)1000),
389 (I_)((x)%(ullong)1000));
391 fprintf(filep, "%ld%3.3ld%3.3ld%3.3ld",
392 (I_)((x)/(ullong)1000000000),
393 (I_)((x)/(ullong)1000000%(ullong)1000),
394 (I_)((x)/(ullong)1000%(ullong)1000),
395 (I_)((x)%(ullong)1000));