diff options
Diffstat (limited to 'emulator/qtools/bbprof.cpp')
| -rw-r--r-- | emulator/qtools/bbprof.cpp | 222 | 
1 files changed, 0 insertions, 222 deletions
| diff --git a/emulator/qtools/bbprof.cpp b/emulator/qtools/bbprof.cpp deleted file mode 100644 index 36d0941..0000000 --- a/emulator/qtools/bbprof.cpp +++ /dev/null @@ -1,222 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include "trace_reader.h" -#include "armdis.h" - -struct MyStaticRec { -    StaticRec   bb; -    uint32_t    *insns; -    uint32_t    *cycles;    // number of cycles for each insn -    uint32_t    elapsed;    // number of cycles for basic block -    int         freq;       // execution frequency -    MyStaticRec *inner;     // pointer to an inner basic block -    int         is_thumb; -}; - -MyStaticRec **assign_inner_blocks(int num_blocks, MyStaticRec *blocks); - -// This function is called from quicksort to compare addresses of basic -// blocks. -int cmp_inc_addr(const void *a, const void *b) { -    MyStaticRec *bb1, *bb2; - -    bb1 = *(MyStaticRec**)a; -    bb2 = *(MyStaticRec**)b; -    if (bb1->bb.bb_addr < bb2->bb.bb_addr) -        return -1; -    if (bb1->bb.bb_addr > bb2->bb.bb_addr) -        return 1; -    return bb1->bb.bb_num - bb2->bb.bb_num; -} - -// This function is called from quicksort to compare the elapsed time -// of basic blocks. -int cmp_dec_elapsed(const void *a, const void *b) { -    MyStaticRec *bb1, *bb2; - -    bb1 = *(MyStaticRec**)a; -    bb2 = *(MyStaticRec**)b; -    if (bb1->elapsed < bb2->elapsed) -        return 1; -    if (bb1->elapsed > bb2->elapsed) -        return -1; -    return bb1->bb.bb_num - bb2->bb.bb_num; -} - -// This function is called from quicksort to compare frequencies of -// basic blocks. -int cmp_dec_freq(const void *a, const void *b) { -    MyStaticRec *bb1, *bb2; - -    bb1 = *(MyStaticRec**)a; -    bb2 = *(MyStaticRec**)b; -    if (bb1->freq < bb2->freq) -        return 1; -    if (bb1->freq > bb2->freq) -        return -1; -    return bb1->bb.bb_num - bb2->bb.bb_num; -} - -int main(int argc, char **argv) -{ -    if (argc != 2) { -        fprintf(stderr, "Usage: %s trace_file\n", argv[0]); -        exit(1); -    } - -    char *trace_filename = argv[1]; -    TraceReaderBase *trace = new TraceReaderBase; -    trace->Open(trace_filename); -    TraceHeader *header = trace->GetHeader(); -    uint32_t num_static_bb = header->num_static_bb; - -    // Allocate space for all of the static blocks -    MyStaticRec *blocks = new MyStaticRec[num_static_bb]; - -    // Read in all the static blocks -    for (uint32_t ii = 0; ii < num_static_bb; ++ii) { -        trace->ReadStatic(&blocks[ii].bb); -        blocks[ii].is_thumb = blocks[ii].bb.bb_addr & 1; -        blocks[ii].bb.bb_addr &= ~1; -        uint32_t num_insns = blocks[ii].bb.num_insns; -        blocks[ii].insns = new uint32_t[num_insns]; -        blocks[ii].cycles = new uint32_t[num_insns]; -        memset(blocks[ii].cycles, 0, num_insns * sizeof(uint32_t)); -        trace->ReadStaticInsns(num_insns, blocks[ii].insns); -        blocks[ii].elapsed = 0; -        blocks[ii].freq = 0; -        blocks[ii].inner = NULL; -    } - -    MyStaticRec **sorted = assign_inner_blocks(num_static_bb, blocks); - -    uint32_t prev_time = 0; -    uint32_t elapsed = 0; -    uint32_t dummy; -    uint32_t *cycle_ptr = &dummy; -    uint32_t *bb_elapsed_ptr = &dummy; -    while (1) { -        BBEvent event; - -        if (trace->ReadBB(&event)) -            break; -        // Assign frequencies to each basic block -        uint64_t bb_num = event.bb_num; -        int num_insns = event.num_insns; -        blocks[bb_num].freq += 1; -        for (MyStaticRec *bptr = blocks[bb_num].inner; bptr; bptr = bptr->inner) -            bptr->freq += 1; - -        // Assign simulation time to each instruction -        for (MyStaticRec *bptr = &blocks[bb_num]; bptr; bptr = bptr->inner) { -            uint32_t bb_num_insns = bptr->bb.num_insns; -            for (uint32_t ii = 0; num_insns && ii < bb_num_insns; ++ii, --num_insns) { -                uint32_t sim_time = trace->ReadInsnTime(event.time); -                elapsed = sim_time - prev_time; -                prev_time = sim_time; - -                // Attribute the elapsed time to the previous instruction and -                // basic block. -                *cycle_ptr += elapsed; -                *bb_elapsed_ptr += elapsed; -                cycle_ptr = &bptr->cycles[ii]; -                bb_elapsed_ptr = &bptr->elapsed; -            } -        } -    } -    *cycle_ptr += 1; -    *bb_elapsed_ptr += 1; - -    // Sort the basic blocks into decreasing elapsed time -    qsort(sorted, num_static_bb, sizeof(MyStaticRec*), cmp_dec_elapsed); - -    char spaces[80]; -    memset(spaces, ' ', 79); -    spaces[79] = 0; -    for (uint32_t ii = 0; ii < num_static_bb; ++ii) { -        printf("bb %lld addr: 0x%x, insns: %d freq: %u elapsed: %u\n", -               sorted[ii]->bb.bb_num, sorted[ii]->bb.bb_addr, -               sorted[ii]->bb.num_insns, sorted[ii]->freq, -               sorted[ii]->elapsed); -        int num_insns = sorted[ii]->bb.num_insns; -        uint32_t addr = sorted[ii]->bb.bb_addr; -        for (int jj = 0; jj < num_insns; ++jj) { -            uint32_t elapsed = sorted[ii]->cycles[jj]; -            uint32_t insn = sorted[ii]->insns[jj]; -            if (insn_is_thumb(insn)) { -                insn = insn_unwrap_thumb(insn); - -                // thumb_pair is true if this is the first of a pair of -                // thumb instructions (BL or BLX). -                bool thumb_pair = ((insn & 0xf800) == 0xf000); - -                // Get the next thumb instruction (if any) because we may need -                // it for the case where insn is BL or BLX. -                uint32_t insn2 = 0; -                if (thumb_pair && (jj + 1 < num_insns)) { -                    insn2 = sorted[ii]->insns[jj + 1]; -                    insn2 = insn_unwrap_thumb(insn2); -                    jj += 1; -                } -                char *disasm = disasm_insn_thumb(addr, insn, insn2, NULL); -                if (thumb_pair) { -                    printf("  %4u %08x %04x %04x %s\n", elapsed, addr, insn, -                           insn2, disasm); -                    addr += 2; -                } else { -                    printf("  %4u %08x     %04x %s\n", elapsed, addr, insn, -                           disasm); -                } -                addr += 2; -            } else { -                char *disasm = Arm::disasm(addr, insn, NULL); -                printf("  %4u %08x %08x %s\n", elapsed, addr, insn, disasm); -                addr += 4; -            } -        } -    } - -    delete[] sorted; -    return 0; -} - -// Find the basic blocks that are subsets of other basic blocks. -MyStaticRec **assign_inner_blocks(int num_blocks, MyStaticRec *blocks) -{ -    int ii; -    uint32_t addr_end, addr_diff; - -    // Create a list of pointers to the basic blocks that we can sort. -    MyStaticRec **sorted = new MyStaticRec*[num_blocks]; -    for (ii = 0; ii < num_blocks; ++ii) { -        sorted[ii] = &blocks[ii]; -    } - -    // Sort the basic blocks into increasing address order -    qsort(sorted, num_blocks, sizeof(MyStaticRec*), cmp_inc_addr); - -    // Create pointers to inner blocks and break up the enclosing block -    // so that there is no overlap. -    for (ii = 0; ii < num_blocks - 1; ++ii) { -        int num_bytes; -        if (sorted[ii]->is_thumb) -            num_bytes = sorted[ii]->bb.num_insns << 1; -        else -            num_bytes = sorted[ii]->bb.num_insns << 2; -        addr_end = sorted[ii]->bb.bb_addr + num_bytes; -        if (addr_end > sorted[ii + 1]->bb.bb_addr) { -            sorted[ii]->inner = sorted[ii + 1]; -            addr_diff = sorted[ii + 1]->bb.bb_addr - sorted[ii]->bb.bb_addr; -            uint32_t num_insns; -            if (sorted[ii]->is_thumb) -                num_insns = addr_diff >> 1; -            else -                num_insns = addr_diff >> 2; -            sorted[ii]->bb.num_insns = num_insns; -        } -    } - -    return sorted; -} | 
