// PReadCompressedTrace.C #include "PReadCompressedTrace.h" #include "traceFile.h" extern "C" { #include #include #include #include #include #include #include #include } #include "Assert.h" #define SHOWERR(s) fprintf(stderr, s) #define SHOWERR1(s,p) fprintf(stderr, s, p) /* Entry point of Consumer: */ extern "C" void my_main(int, char **, char **); /* Entry point of program. main() was kept in PReadCompressedTrace.C so as to be consistent with a client's use of BranchSimulator.C. A client of BranchXXX just fills out my_main(); main(), when SHADE is used, is defined by SHADE... so keeping client from conditionally knowing of main() was removed. */ PReadCompressedTrace::PReadCompressedTrace (char *traceFile, uint32 low, uint32 high, bool trace) { branchStream = NULL; branchdataMap = NULL; oldBranchdataMap = NULL; oldData = False; // make a copy of specified root trace file name: fTraceFile = new char[strlen(traceFile)+1]; runtimeAssert(fTraceFile != NULL, "PReadCompressedTrace::PReadCompressedTrace: Out of Memory"); strcpy(fTraceFile, traceFile); this->lowLimit = low; this->highLimit = high; this->branchesPassed = 0; this->traceFromStdin = trace; } PReadCompressedTrace::~PReadCompressedTrace () { delete branchStream; delete oldBranchdataMap; delete branchdataMap; delete fTraceFile; } /* Append to and then Open a file corresponding to effective filename for Write access: */ FILE *PReadCompressedTrace::openTraceFile (char *rootname, char *extension) { char n[100]; FILE *stream; // append file extension to specified trace file name: strcpy(n, rootname); strcat(n, extension); stream = fopen(n, "rb"); perrorAssert(stream != NULL,"PReadCompressedTrace::openTraceFile: Failed to open trace file"); return stream; } HashedBranch2uint16::elementType * PReadCompressedTrace::getBranchdataMap() { return branchdataMap; } uint16 PReadCompressedTrace::getNrOfTargets() { return nr_of_branchindices; } /* Translate the contents of a .map file (specified by the stream, s, into a memory-resident array. */ void PReadCompressedTrace::readMap () { char * fname = new char[strlen(fTraceFile)+ strlen(MAP_EXTENSION) + 1]; strcpy(fname,fTraceFile); strcat(fname,MAP_EXTENSION); int s = open(fname, O_RDONLY); perrorAssert(s != 0,"PReadCompressedTrace::readMap: Failed to open .map file"); fCompressHeader hdr; pread(s,(void *) &hdr,sizeof(hdr),0); nr_of_branchindices = hdr.mapsize; nr_of_branches = hdr.brsize; if (0 == strncmp(COMPRESS_MAGIC_STRING,hdr.magic,strlen(COMPRESS_MAGIC_STRING))) { oldData = True; } else if (0 == strncmp(RICHCOMPRESS_MAGIC_STRING,hdr.magic,strlen(RICHCOMPRESS_MAGIC_STRING))) { oldData = False; } else { fatal("unknown magic string in trace file"); } if (oldData) { // read the branchdata from the file using mmap oldBranchdataMap = (HashedBranch2uint16::oldElementType *) mmap((caddr_t) 0, sizeof(hdr) + (nr_of_branchindices) * sizeof (HashedBranch2uint16::oldElementType), PROT_READ, MAP_PRIVATE, s, 0); perrorAssert(oldBranchdataMap != MAP_FAILED, "PReadCompressedTrace::start: mmap Failed for old .map file"); // skip the header (can't use offset parameter for this, sinxe // it is constrained memcpy(&hdr,(void *)oldBranchdataMap,sizeof(hdr)); expectedNrOfBranches = hdr.brsize; oldBranchdataMap = (HashedBranch2uint16::oldElementType *) (((uint32)oldBranchdataMap) + sizeof(hdr)); } else { // read the branchdata from the file using mmap branchdataMap = (HashedBranch2uint16::elementType *) mmap((caddr_t) 0, sizeof(hdr) + (nr_of_branchindices) * sizeof (HashedBranch2uint16::elementType), PROT_READ, MAP_PRIVATE, s, 0); perrorAssert(branchdataMap != MAP_FAILED, "PReadCompressedTrace::start: mmap Failed for .map file"); // skip the header (can't use offset parameter for this, sinxe // it is constrained memcpy(&hdr,(void *)branchdataMap,sizeof(hdr)); expectedNrOfBranches = hdr.brsize; branchdataMap = (HashedBranch2uint16::elementType *) (((uint32)branchdataMap) + sizeof(hdr)); } close(s); } void PReadCompressedTrace::readProf () { char * fname = new char[strlen(fTraceFile)+ strlen(PROF_EXTENSION) + 1]; strcpy(fname,fTraceFile); strcat(fname,PROF_EXTENSION); int s = open(fname, O_RDONLY); if (s == -1) { profileAvailable = False; } else { profileAvailable = True; fCompressHeader hdr; pread(s,(void *) &hdr,sizeof(hdr),0); // already read by readmap // nr_of_branchindices = hdr.mapsize; // read the branchdata from the file using mmap branchprofMap = (RichBranch::profdata *) mmap((caddr_t) 0, sizeof(hdr) + (nr_of_branchindices) * sizeof (RichBranch::profdata), PROT_READ, MAP_PRIVATE, s, 0); perrorAssert(branchprofMap != MAP_FAILED, "PReadCompressedTrace::start: mmap Failed for .prof file"); // skip the header (can't use offset parameter for this, sinxe // it is constrained memcpy(&hdr,(void *)branchprofMap,sizeof(hdr)); branchprofMap = (RichBranch::profdata *) (((uint32)branchprofMap) + sizeof(hdr)); close(s); } } void PReadCompressedTrace::init () { readMap(); readProf(); } void PReadCompressedTrace::start () { int s; fCompressHeader dummy; if (traceFromStdin) { fread(&dummy,sizeof(fCompressHeader),1,stdin); } else { char * fname = new char[strlen(fTraceFile)+ strlen(BRANCH_EXTENSION) + 1]; strcpy(fname,fTraceFile); strcat(fname,BRANCH_EXTENSION); s = open(fname, O_RDONLY); perrorAssert(s != 0,"PReadCompressedTrace::start: Failed to open .br file"); // read the branchTrace from the file using mmap branchTrace = (uint16 *) mmap((caddr_t) 0, sizeof(fCompressHeader) + (nr_of_branches) * sizeof (uint16), PROT_READ, MAP_PRIVATE, s, 0); perrorAssert(branchTrace != MAP_FAILED, "PReadCompressedTrace::start: mmap Failed for .br file"); // skip the header (can't use offset parameter for this, since // it is constrained branchTrace = (uint16 *) (((uint32)branchTrace) + sizeof(fCompressHeader)); } } void PReadCompressedTrace::end () { fclose(branchStream); } // ignore all except indirect branches void PReadCompressedTrace::traceIndirectBranches() { // if called, implementation needed runtimeAssert(0,"ReadCompressedTrace::traceIndirectBranches not implemented"); } // trace all branches void PReadCompressedTrace::traceAllBranches() { // if called, implementation needed runtimeAssert(0,"ReadCompressedTrace::traceAllBranches not implemented"); } // trace all Instructions void PReadCompressedTrace::traceAllInstructions() { // if called, implementation needed runtimeAssert(0,"ReadCompressedTrace::traceAllInstructions not implemented"); } /* ...return next RichBranch.. */ RichBranch *PReadCompressedTrace::getNextBranch () { uint16 index; Branch oldresult; if (traceFromStdin) { fread(&index,sizeof(uint16),1,stdin); } else { index = *branchTrace; branchTrace++; } if (branchesPassed >= highLimit) { return NULL; }; if (branchesPassed < lowLimit) { do { if (traceFromStdin) { fread(&index,sizeof(uint16),1,stdin); } else { index = *branchTrace; branchTrace++; } if (index == 0) { runtimeAssert(branchesPassed = expectedNrOfBranches,"PReadCompressedTrace::getNextBranch: different number of branches passed than expected"); return NULL; } } while (branchesPassed < lowLimit); } if (index != 0) { if (oldData) { // convert to a rich branch by adding 0 data memcpy((void *) &(oldresult.d), (void *)&(oldBranchdataMap[index].d), sizeof(Branch::data)); result.d.address = oldresult.d.address; result.d.target = oldresult.d.target; result.d.sparccode = 0; result.d.frequency = 0; result.d.type = oldresult.d.type; result.d.prediction = oldresult.d.prediction; result.d.outcome = oldresult.d.outcome; } else { memcpy((void *) &(result.d), (void *)&(branchdataMap[index].d), sizeof(RichBranch::rdata)); } branchesPassed++; if (profileAvailable) { memcpy((void *) &(result.p), (void *)&(branchprofMap[index]), sizeof(RichBranch::profdata)); } else { result.p.frequency = 0; result.p.switchfreq = 0; result.p.nrTargets = 0; } return &result; } else { branchesPassed++; runtimeAssert(branchesPassed = expectedNrOfBranches,"PReadCompressedTrace::getNextBranch: different number of branches passed than expected"); return NULL; } }