static void readPerfHits(Group2BaseMap& f2b, FILE* file) { std::string line; while (readLine(line, file)) { HFTRACE(2, "readPerfHits: line: %s\n", line.c_str()); if (!line.size()) continue; if (line[0] == '#') continue; if (isspace(line[0])) continue; if (!readLine(line, file)) error("reading perf data"); FuncId idTop = getFuncId(line.c_str()); if (idTop == InvalidId) continue; idTop = f2b[cg.funcs[idTop].group][0]; cg.funcs[idTop].samples++; HFTRACE(2, "readPerfHits: idTop: %u %s\n", idTop, cg.funcs[idTop].mangledNames[0].c_str()); if (!readLine(line, file)) error("reading perf data"); FuncId idCaller = getFuncId(line.c_str()); if (idCaller != InvalidId) { idCaller = f2b[cg.funcs[idCaller].group][0]; cg.incArcWeight(idCaller, idTop); HFTRACE(2, "readPerfData: idCaller: %u %s\n", idCaller, cg.funcs[idCaller].mangledNames[0].c_str()); } } // Normalize incoming arc weights for each node. for (auto& func : cg.funcs) { double inWeight = 0; for (auto arc : func.inArcs) { auto& pred = cg.funcs[arc->src]; inWeight += arc->weight * pred.samples / pred.outArcs.size(); } if (!inWeight) inWeight = 1; for (auto arc : func.inArcs) { auto& pred = cg.funcs[arc->src]; arc->normalizedWeight = arc->weight * pred.samples / (inWeight * pred.outArcs.size()); } } }
void readPerfData(gzFile file, bool computeArcWeight) { char line[BUFLEN]; while (gzgets(file, line, BUFLEN) != Z_NULL) { HFTRACE(2, "readPerfData: line: %s\n", line); if (line[0] == '#') continue; if (isspace(line[0])) continue; // process one sample if (gzgets(file, line, BUFLEN) == Z_NULL) error("reading perf data"); auto addrTop = getAddr(line); FuncId idTop = getFuncId(addrTop); if (idTop == InvalidId) continue; cg.funcs[idTop].samples++; HFTRACE(2, "readPerfData: idTop: %u %s\n", idTop, cg.funcs[idTop].mangledNames[0].c_str()); if (gzgets(file, line, BUFLEN) == Z_NULL) error("reading perf data"); auto addrCaller = getAddr(line); FuncId idCaller = getFuncId(addrCaller); if (idCaller != InvalidId) { auto arc = cg.getArc(idCaller, idTop); if (computeArcWeight) { arc->weight++; arc->avgCallOffset += addrCaller - cg.funcs[idCaller].addr; } HFTRACE(2, "readPerfData: idCaller: %u %s\n", idCaller, cg.funcs[idCaller].mangledNames[0].c_str()); } } if (!computeArcWeight) return; // Normalize incoming arc weights and compute avgCallOffset for each node. for (auto& func : cg.funcs) { for (auto arc : func.inArcs) { arc->normalizedWeight = arc->weight / func.samples; arc->avgCallOffset = arc->avgCallOffset / arc->weight; } } }