155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <stdio.h> 255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <stdlib.h> 355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <string.h> 455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <inttypes.h> 555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include "trace_reader.h" 655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projecttypedef struct MyStaticRec { 855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project StaticRec bb; 955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint32_t *insns; 1055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project} MyStaticRec; 1155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 1255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectconst int kNumPids = 32768; 1355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectchar usedPids[kNumPids]; 1455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 1555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectint main(int argc, char **argv) { 1655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint32_t insns[kMaxInsnPerBB]; 1755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 1855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (argc != 2) { 1955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project fprintf(stderr, "Usage: %s trace_file\n", argv[0]); 2055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project exit(1); 2155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 2255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 2355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project char *trace_filename = argv[1]; 2455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project TraceReaderBase *trace = new TraceReaderBase; 2555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->SetPostProcessing(true); 2655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->Open(trace_filename); 2755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 2855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Count the number of static basic blocks and instructions. 2955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint64_t num_static_bb = 0; 3055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint64_t num_static_insn = 0; 3155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project while (1) { 3255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project StaticRec static_rec; 3355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 3455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (trace->ReadStatic(&static_rec)) 3555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project break; 3655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (static_rec.bb_num != num_static_bb) { 3755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project fprintf(stderr, 3855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project "Error: basic block numbers out of order; expected %lld, got %lld\n", 3955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project num_static_bb, static_rec.bb_num); 4055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project exit(1); 4155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 4255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project num_static_bb += 1; 4355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project num_static_insn += static_rec.num_insns; 4455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->ReadStaticInsns(static_rec.num_insns, insns); 4555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 4655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->Close(); 4755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 4855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Allocate space for all of the static blocks 4955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project MyStaticRec *blocks = new MyStaticRec[num_static_bb]; 5055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 5155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Read the static blocks again and save pointers to them 5255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->Open(trace_filename); 5355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project for (uint32_t ii = 0; ii < num_static_bb; ++ii) { 5455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->ReadStatic(&blocks[ii].bb); 5555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint32_t num_insns = blocks[ii].bb.num_insns; 5655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (num_insns > 0) { 5755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project blocks[ii].insns = new uint32_t[num_insns]; 5855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->ReadStaticInsns(num_insns, blocks[ii].insns); 5955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 6055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 6155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 6255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Check the last basic block. If it contains a special undefined 6355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // instruction, then truncate the basic block at that point. 6455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint32_t num_insns = blocks[num_static_bb - 1].bb.num_insns; 6555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint32_t *insn_ptr = blocks[num_static_bb - 1].insns; 6655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project for (uint32_t ii = 0; ii < num_insns; ++ii, ++insn_ptr) { 6755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (*insn_ptr == 0xe6c00110) { 6855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint32_t actual_num_insns = ii + 1; 6955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project blocks[num_static_bb - 1].bb.num_insns = actual_num_insns; 7055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project num_static_insn -= (num_insns - actual_num_insns); 7155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 7255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Write the changes back to the trace file 7355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->TruncateLastBlock(actual_num_insns); 7455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project break; 7555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 7655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 7755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project TraceHeader *header = trace->GetHeader(); 7855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project strcpy(header->ident, TRACE_IDENT); 7955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project header->num_static_bb = num_static_bb; 8055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project header->num_dynamic_bb = 0; 8155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project header->num_static_insn = num_static_insn; 8255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project header->num_dynamic_insn = 0; 8355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->WriteHeader(header); 8455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 8555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Reopen the trace file in order to force the trace manager to reread 8655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // the static blocks now that we have written that information to the 8755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // header. 8855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->Close(); 8955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->Open(trace_filename); 9055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 9155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Count the number of dynamic executions of basic blocks and instructions. 9255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Also keep track of which process ids are used. 9355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint64_t num_dynamic_bb = 0; 9455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project uint64_t num_dynamic_insn = 0; 9555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project while (1) { 9655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project BBEvent event; 9755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 9855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (trace->ReadBB(&event)) 9955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project break; 10055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (event.bb_num >= num_static_bb) { 10155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project fprintf(stderr, 10255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project "Error: basic block number (%lld) too large (num blocks: %lld)\n", 10355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project event.bb_num, num_static_bb); 10455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project exit(1); 10555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 10655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project usedPids[event.pid] = 1; 10755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project num_dynamic_bb += 1; 10855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project num_dynamic_insn += event.num_insns; 10955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 11055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 11155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Count the number of process ids that are used and remember the first 11255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // unused pid. 11355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project int numUsedPids = 0; 11455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project int unusedPid = -1; 11555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project for (int pid = 0; pid < kNumPids; pid++) { 11655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (usedPids[pid] == 1) { 11755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project numUsedPids += 1; 11855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } else if (unusedPid == -1) { 11955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project unusedPid = pid; 12055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 12155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 12255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 12355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Rewrite the header with the dynamic counts 12455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project header->num_dynamic_bb = num_dynamic_bb; 12555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project header->num_dynamic_insn = num_dynamic_insn; 12655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project header->num_used_pids = numUsedPids; 12755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project header->first_unused_pid = unusedPid; 12855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->WriteHeader(header); 12955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project trace->Close(); 13055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 13155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project printf("Static basic blocks: %llu, Dynamic basic blocks: %llu\n", 13255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project num_static_bb, num_dynamic_bb); 13355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project printf("Static instructions: %llu, Dynamic instructions: %llu\n", 13455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project num_static_insn, num_dynamic_insn); 13555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 13655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project double elapsed_secs = header->elapsed_usecs / 1000000.0; 13755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project double insn_per_sec = 0; 13855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (elapsed_secs != 0) 13955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project insn_per_sec = num_dynamic_insn / elapsed_secs; 140d4d5b4f63a5760b2212166f539f906edda0bc4deJack Veenstra const char *suffix = ""; 14155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (insn_per_sec >= 1000000) { 14255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project insn_per_sec /= 1000000.0; 14355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project suffix = "M"; 14455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } else if (insn_per_sec > 1000) { 14555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project insn_per_sec /= 1000.0; 14655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project suffix = "K"; 14755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 14855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project printf("Elapsed seconds: %.2f, simulated instructions/sec: %.1f%s\n", 14955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project elapsed_secs, insn_per_sec, suffix); 15055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return 0; 15155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project} 152