void dump_mp_times() { tcfg_edge_t *e; loop_t *lp; int edge_id, hm, num_hm, set, *t; printf("dump mispred timing estimates for basic blocks\n"); for (edge_id = 0; edge_id < num_tcfg_edges; edge_id++) { e = tcfg_edges[edge_id]; printf("%d.%d -> %d.%d\n", bbi_pid(e->src), bbi_bid(e->src), bbi_pid(e->dst), bbi_bid(e->dst)); num_hm = num_hit_miss[tcfg_edges[edge_id]->dst->id]; for (hm = 0; hm < num_hm; hm++) { lp = bbi_hm_list[e->dst->id][hm]; if (lp == NULL) continue; printf(" hm[%d]:", hm); t = mp_times[edge_id][hm]; for (set = 0; set < cache.ns; set++) { if (t[set] != 0) printf(" s[%x]=%d", set, t[set]); } printf("\n"); } } printf("\n"); }
void dump_unit_time(int edge_id, int hm, int bp) { int t; tcfg_edge_t *e = tcfg_edges[edge_id]; if (bp == BP_CPRED) t = cpred_times[edge_id][hm]; else t = mpred_times[edge_id][hm]; printf(" %d.%d -> %d.%d (hm:%d bp:%d): %d\n", bbi_pid(e->src), bbi_bid(e->src), bbi_pid(e->dst), bbi_bid(e->dst), hm, bp, t); }
void dump_edge_mp_times(int edge_id, int hm) { int *t, set; tcfg_edge_t *e = tcfg_edges[edge_id]; tcfg_node_t *bbi = e->dst; loop_t *lp; t = mp_times[edge_id][hm]; printf(" %d.%d -> %d.%d (hm:%d): ", bbi_pid(e->src), bbi_bid(e->src), bbi_pid(e->dst), bbi_bid(e->dst), hm); for (set = 0; set < cache.ns; set++) { if (t[set] != 0) printf(" s[%d]=%d", set, t[set]); } printf("\n"); }
// return 1 if e->dst exits the loop to which e->src belongs static int exit_loop(tcfg_edge_t *e) { loop_t *lp; int head_bid, tail_bid, dst_bid; lp = loop_map[e->src->id]; if (lp == loops[0]) return 0; if (bbi_pid(e->dst) != bbi_pid(lp->head)) return 0; head_bid = bbi_bid(lp->head); tail_bid = bbi_bid(lp->tail); dst_bid = bbi_bid(e->dst); if ((dst_bid > tail_bid) || (dst_bid < head_bid)) return 1; else return 0; }
void dump_gen() { tcfg_node_t *src, *dst; mem_blk_t *mblk; int i; for (i = 0; i < num_tcfg_edges; i++) { src = tcfg_edges[i]->src; dst = tcfg_edges[i]->dst; printf("tcfg_edge: %d.%d -> %d.%d\n", bbi_pid(src), bbi_bid(src), bbi_pid(dst), bbi_bid(dst)); for (mblk = gen[src->id]; mblk->set != MAX_CACHE_SETS; mblk++) printf("\tset=%x: %x\n", mblk->set, mblk->tag); if (mp_gen[i] == NULL) continue; printf("\t---------------\n"); for (mblk = mp_gen[i]; mblk->set != MAX_CACHE_SETS; mblk++) printf("\tset=%x: %x\n", mblk->set, mblk->tag); } }
static void dump_xlogs(code_link_t **xlogs) { tcfg_node_t *src, *dst; int i, k; code_link_t *log; mas_inst_t *mas_inst; for (i = 0; i < num_tcfg_edges; i++) { src = tcfg_edges[i]->src; dst = tcfg_edges[i]->dst; printf("\nedge: %d.%d -> %d.%d", bbi_pid(src), bbi_bid(src), bbi_pid(dst), bbi_bid(dst)); for (log = xlogs[i]; log != NULL; log = log->next) { for (k = 0; k < log->num_inst; k++) { mas_inst = &log->code[k]; if ((k & 7) == 0) printf("\n %x", mas_inst->inst->addr); else printf(" %x", mas_inst->inst->addr); if (mas_inst->bp_flag == BP_MPRED) printf("/M"); else if (mas_inst->bp_flag == BP_UNCLEAR) printf("/U"); else printf("/C"); if (mas_inst->ic_flag == IC_MISS) printf("M"); else if (mas_inst->ic_flag == IC_UNCLEAR) printf("U"); else printf("H"); } printf("\n -------------------------------------------"); printf("-------------------------------------------\n"); } } }
static void dump_loops() { int i; tcfg_node_t *x, *y, *z; printf("\ndump loops\n"); printf("----------------\n"); for (i = 0; i < num_tcfg_nodes; i++) { x = tcfg[i]; if (loop_map[i] == NULL) continue; // for non-reachable nods, such as block 2.51 in minver y = loop_map[i]->head; z = loop_map[i]->tail; if (y == tcfg[0]) printf("%d.%d: \t%d[start - end]\n", bbi_pid(x), bbi_bid(x), loop_map[i]->id); else printf("%d.%d: \t%d[%d.%d - %d.%d] / parent:%d\n", bbi_pid(x), bbi_bid(x), loop_map[i]->id, bbi_pid(y), bbi_bid(y), bbi_pid(z), bbi_bid(z), loop_map[i]->parent->id); } }
void dump_units_times() { tcfg_edge_t *e; int edge_id, hm, num_hm; printf("dump timing estimates for basic blocks\n"); for (edge_id = 0; edge_id < num_tcfg_edges; edge_id++) { e = tcfg_edges[edge_id]; printf("%d.%d -> %d.%d\n", bbi_pid(e->src), bbi_bid(e->src), bbi_pid(e->dst), bbi_bid(e->dst)); if (enable_icache) { num_hm = num_hit_miss[tcfg_edges[edge_id]->dst->id]; } else num_hm = 1; for (hm = 0; hm < num_hm; hm++) { printf(" hm[%d]: %d", hm, cpred_times[edge_id][hm]); if ((bpred_scheme != NO_BPRED) && cond_bbi(e->src)) printf(" %d(m)", mpred_times[edge_id][hm]); printf("\n"); } } printf("\n"); }
static void deal_exit_edge(tcfg_edge_t *e) { loop_t *lp; tcfg_node_t *dst; int head_bid, tail_bid, lp_pid, bid, pid; reg_loop_exit(e); dst = e->dst; if (loop_map[dst->id] != NULL) { if (dst != loop_map[dst->id]->head) return; // hit a loop head if (loop_map[dst->id]->parent != NULL) return; for (lp = loop_map[e->src->id]->parent; lp != loops[0]; lp = lp->parent) { head_bid = bbi_bid(lp->head); tail_bid = bbi_bid(lp->tail); lp_pid = bbi_pid(lp->head); bid = bbi_bid(dst); pid = bbi_pid(dst); if ((pid != lp_pid) || ((bid >= head_bid) && (bid <= tail_bid))) { loop_map[dst->id]->parent = lp; break; } } if (loop_map[dst->id]->parent == NULL) loop_map[dst->id]->parent = loops[0]; return; } for (lp = loop_map[e->src->id]->parent; lp != loops[0]; lp = lp->parent) { head_bid = bbi_bid(lp->head); tail_bid = bbi_bid(lp->tail); lp_pid = bbi_pid(lp->head); bid = bbi_bid(dst); pid = bbi_pid(dst); if ((pid != lp_pid) || ((bid >= head_bid) && (bid <= tail_bid))) { loop_map[dst->id] = lp; break; } } if (loop_map[dst->id] == NULL) loop_map[dst->id] = loops[0]; }
/* * Parses loop bound information and stores known block execution counts, * to be used in constraint formulation. */ int readBlockCounts( char *obj_file ) { FILE *f; char tmp[256]; int i, pid, bid, pid2, entry, count; inf_proc_t *ip; inf_node_t *ib; for( i = 0; i < num_tcfg_nodes; i++ ) { tcfg[i]->loop_id = -1; tcfg[i]->exec_count = -1; } // absolute counts sprintf( tmp, "cat %s.cons | tr 'c' '\\ ' | awk '$2 ~ \"=\" {print $1,$NF}' | tr '.' '\\ ' > counts", obj_file ); system( tmp ); f = fopen( "counts", "r" ); while( fscanf( f, "%d %d %d", &pid, &bid, &count ) != EOF ) { tcfg_nlink_t *ndlink; //printf( "Detected absolute count %d::%d = %d\n", pid, bid, count ); if( !include_proc[pid] ) { printf( "Ignoring count for excluded function.\n" ); continue; } inf_procs[pid].inf_cfg[bid].exec_count = count; // propagate to tcfg nodes for( ndlink = bbi_map[pid][bid]; ndlink != NULL; ndlink = ndlink->next ) setCount( ndlink->bbi, count ); } fclose( f ); // loopbounds sprintf( tmp, "grep \\< %s.cons | sed '/+/d' | tr '-' '\\ ' | tr '=' '\\ ' | tr '\\<' '\\ ' > tmp", obj_file ); system( tmp ); system( "awk '{if(NF==4) print $1,$3,$2}' tmp | tr 'c' '\\ ' | tr '.' '\\ ' > bounds" ); num_inf_loops = 0; inf_loops = NULL; for( pid = 0; pid < prog.num_procs; pid++ ) { if( include_proc[pid] ) { ip = &(inf_procs[pid]); for( bid = 0; bid < ip->num_bb; bid++ ) ip->inf_cfg[bid].loop_id = -1; } } f = fopen( "bounds", "r" ); while( fscanf( f, "%d %d %d %d %d", &pid, &bid, &pid2, &entry, &count ) != EOF ) { int lpid, head, tail; loop_t *lpn; inf_loop_t *lp; inf_node_t *hd, *ta; char *checked; //printf( "Detected loop bound for %d::%d (entry: %d) = %d\n", pid, bid, entry, count ); if( !include_proc[pid] || !include_proc[pid2] ) { printf( "Ignoring bound for excluded function.\n" ); continue; } ip = &(inf_procs[pid]); ib = &(ip->inf_cfg[bid]); lpid = num_inf_loops++; inf_loops = (inf_loop_t*) realloc( inf_loops, num_inf_loops * sizeof(inf_loop_t) ); lp = &(inf_loops[lpid]); lp->pid = pid; lp->entry = entry; lp->bound = count; // mark all blocks in the loop body // traverse from tail upwards until head is found; all traversed block is in the loop lpn = loop_map[bbi_map[pid][bid]->bbi->id]; head = bbi_bid( lpn->head ); tail = bbi_bid( lpn->tail ); hd = &(ip->inf_cfg[head]); ta = &(ip->inf_cfg[tail]); checked = (char*) calloc( ip->num_bb, sizeof(char) ); markLoop( ip, hd, ta, lpid, &checked ); free( checked ); } fclose( f ); system( "rm tmp counts bounds" ); return 0; }