This commit is contained in:
2025-03-12 12:37:19 +03:00
parent 1c851baa7e
commit 6a4040be3e
426 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,473 @@
#include "../Utils/leak_detector.h"
#include <stdio.h>
#include <fstream>
#include <iostream>
#include <string>
#include <map>
#include "dvm.h"
#include "gCov_parser_func.h"
#include "../Utils/SgUtils.h"
using namespace std;
enum key_word
{
UNKNOWN,
BRANCH,
CALL,
};
static const char *key_words[] =
{
"",
"branch",
"call",
"taken",
"returned",
NULL
};
static const char *symbols_neverExecuted[] =
{
"",
"#####",
"%%%%%",
"$$$$$",
"=====",
NULL
};
static void isKeyWord(const string &lex, key_word &lineType)
{
int i = 1;
bool find = false;
while ((!find) && key_words[i]) {
if (lex.compare(key_words[i]) == 0)
find = true;
else
i++;
}
switch (i) {
case 1:
lineType = BRANCH;
break;
case 2:
lineType = CALL;
break;
default:
if (lineType != UNKNOWN)
{
__spf_print(1, "Error: Wrong work of analysis keywords\n");
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
}
static bool isNeverExecuted(const string &lex)
{
int i = 1;
bool find = false;
while ((!find) && symbols_neverExecuted[i])
{
if (lex.compare(symbols_neverExecuted[i]) == 0)
find = true;
else
i++;
}
return find;
}
static void getInfo(map<int, Gcov_info> &info, const string &str)
{
Gcov_info infoLine;
Perform infoPerform;
string num, lex;
key_word lineType = UNKNOWN;
bool executedCountGot = false;
int i = 0;
int len = str.length();
int minus = 0;
int ddot = 0;
while (i != len)
{
char c = str[i];
if ((c >= 48) && (c <= 57)) //symbols '0'-'9'
num.push_back(c);
else
{
switch (c)
{
case ' ':
if ((!lex.empty()) && (lineType == UNKNOWN))
isKeyWord(lex, lineType);
lex.clear();
if ((!num.empty()) && ((lineType == BRANCH) || (lineType == CALL)))
infoPerform.setNumber(stoi(num, nullptr));
num.clear();
break;
case ':':
ddot++;
if ((!lex.empty()) && (isNeverExecuted(lex)))
{
executedCountGot = true;
infoLine.setExecutedCount(0);
}
if (!num.empty())
{
if (!executedCountGot)
{
const int64_t value = stoll(num);
if (minus == 1 && ddot == 1 && value == 0)
infoLine.setExecutedCount(-1);
else
infoLine.setExecutedCount(value);
executedCountGot = true;
}
else
infoLine.setNumLine(stoi(num, nullptr));
}
num.clear();
break;
case '%':
if (!num.empty())
infoPerform.setPercent(stoi(num, nullptr));
num.clear();
break;
case '-':
minus++;
num.push_back('0');
break;
default:
//Try find 'branch' or 'call'
lex.push_back(c);
}
}
i++;
}
if (infoLine.getNumLine() != -1)
info.insert(make_pair(infoLine.getNumLine(), infoLine));
switch (lineType)
{
case BRANCH:
((*(info.rbegin())).second).setBranch(infoPerform);
break;
case CALL:
((*(info.rbegin())).second).setCall(infoPerform);
break;
case UNKNOWN:
break;
default:
__spf_print(1, "Error: get unreal type\n");
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
break;
}
}
static void printPerform(map<int, Perform> info, ostream &myfile)
{
map<int, Perform>::iterator cur;
for (cur = info.begin(); cur != info.end(); cur++)
myfile << (*cur).first << ")" << (*cur).second;
}
static void printInfo2file(map<int, Gcov_info> &info, ostream &myfile)
{
map<int, Gcov_info>::iterator cur;
for (cur = info.begin(); cur != info.end(); cur++)
{
Gcov_info cur_gcov = (*cur).second;
myfile << "_________________\n";
myfile << "" << (*cur).first << endl << cur_gcov;
if (cur_gcov.getCountCalls() != 0)
{
myfile << "-----Calls----\n";
printPerform(cur_gcov.getCalls(), myfile);
}
if (cur_gcov.getCountBranches() != 0)
{
myfile << "----Branches----\n";
printPerform(cur_gcov.getBranches(), myfile);
}
}
}
static inline string modify_name(const string &name)
{
return name + "_pgcov.txt";
}
/*
-добавить флаги при компиляции : gfortran -O2 -g -fprofile-arcs -ftest-coverage
- запустить программу
- отдать исходник профилировщику с флагом : LANG=en_US.utf8 gcov -b file.f
*/
static void fixGcovInfo(SgFile *fileSg, map<int, Gcov_info> &gCovInfo)
{
for (SgStatement *st = fileSg->firstStatement(); st; st = st->lexNext())
{
if (isSgExecutableStatement(st) && !isDVM_stat(st) && !isSPF_stat(st) &&
(st->variant() != DVM_INTERVAL_DIR && st->variant() != DVM_ENDINTERVAL_DIR))
{
auto next = st->lexNext();
const int currLine = st->lineNumber();
const int nextLine = next ? next->lineNumber() : -1;
if (next)
{
if (nextLine == currLine)
continue;
auto it = gCovInfo.find(currLine);
if (it != gCovInfo.end())
{
if (it->second.getExecutedCount() <= 0)
{
int nextL = currLine + 1;
while (nextL != nextLine)
{
auto itNext = gCovInfo.find(nextL);
if (itNext != gCovInfo.end())
{
if (itNext->second.getExecutedCount() >= 0)
{
it->second.clear();
it->second.setExecutedCount(itNext->second.getExecutedCount());
for (auto &call : itNext->second.getCalls())
it->second.setCall(call.second);
for (auto &branch : itNext->second.getBranches())
it->second.setBranch(branch.second);
// copy to between
for (int z = currLine + 1; z != nextL; ++z)
{
auto itZ = gCovInfo.find(z);
if (itZ != gCovInfo.end())
{
itZ->second.clear();
itZ->second.setExecutedCount(itNext->second.getExecutedCount());
for (auto &call : itNext->second.getCalls())
itZ->second.setCall(call.second);
for (auto &branch : itNext->second.getBranches())
itZ->second.setBranch(branch.second);
}
}
break;
}
}
nextL++;
}
}
}
}
}
}
for (SgStatement *st = fileSg->firstStatement(); st; st = st->lexNext())
{
if (isSgExecutableStatement(st) && !isDVM_stat(st) && !isSPF_stat(st) &&
(st->variant() != DVM_INTERVAL_DIR && st->variant() != DVM_ENDINTERVAL_DIR))
{
if (st->variant() == CONTROL_END)
{
auto cp = st->controlParent();
auto it = gCovInfo.find(cp->lineNumber());
if (it != gCovInfo.end() && cp->variant() != PROG_HEDR &&
cp->variant() != PROC_HEDR && cp->variant() != FUNC_HEDR &&
isSgExecutableStatement(cp))
{
auto it = gCovInfo.find(st->lineNumber());
auto itCp = gCovInfo.find(cp->lineNumber());
if (it != gCovInfo.end())
{
it->second.clear();
it->second.setExecutedCount(itCp->second.getExecutedCount());
for (auto &call : itCp->second.getCalls())
it->second.setCall(call.second);
for (auto &branch : itCp->second.getBranches())
it->second.setBranch(branch.second);
}
}
continue;
}
}
}
}
static map<string, map<int, Gcov_info>*> allGCovInfo;
void parse_gcovfile(SgFile *fileSg, const string &basefileNameIn, map<int, Gcov_info> &gCovInfo, bool keep)
{
if (basefileNameIn == "")
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
else
{
const string basefileName = basefileNameIn + ".gcov";
ifstream file;
file.open(basefileName, ios::in);
if (file.is_open())
{
string str;
while (!file.eof())
{
getline(file, str);
getInfo(gCovInfo, str);
}
file.close();
fixGcovInfo(fileSg, gCovInfo);
if (keep)
{
// FOR DEBUG ONLY
string name_f = modify_name(basefileName);
ofstream myfile(name_f);
if (myfile.is_open())
printInfo2file(gCovInfo, myfile);
else
__spf_print(1, " Error: unable to create file %s\n", name_f.c_str());
}
}
else
__spf_print(1, " Error: unable to open file %s\n", basefileName.c_str());
}
allGCovInfo[fileSg->filename()] = &gCovInfo;
}
bool __gcov_doesThisLineExecuted(const string &file, const int line)
{
bool ret = true;
auto itF = allGCovInfo.find(file);
if (itF != allGCovInfo.end())
{
auto itL = itF->second->find(line);
if (itL != itF->second->end())
ret = itL->second.getExecutedCount() != 0;
}
return ret;
}
pair<int, int64_t> __gcov_GetExecuted(const string &file, const int line)
{
pair<int, int64_t> ret = make_pair(0, 0);
auto itF = allGCovInfo.find(file);
if (itF != allGCovInfo.end())
{
auto itL = itF->second->find(line);
if (itL != itF->second->end())
ret.second = itL->second.getExecutedCount();
else
ret.first = -1;
}
else
ret.first = -1;
return ret;
}
void parseTimesDvmStatisticFile(const string &file, map<string, vector<SpfInterval*>> &intervals)
{
map<string, map<int, SpfInterval*>> mapOfIntervals;
for (auto &intByfile : intervals)
createMapOfinterval(mapOfIntervals[intByfile.first], intByfile.second);
FILE *stat = fopen(file.c_str(), "r");
if (stat)
{
char buf[8192];
int execDone = 1;
int line = -1;
string fileN = "";
SpfInterval *curr = NULL;
while (!feof(stat))
{
char *read = fgets(buf, 8192, stat);
if (read)
{
const string origLine(read);
auto itF = origLine.find("INTERVAL");
auto itTypeU = origLine.find("USER");
auto itExpr = origLine.find("EXPR=");
if (itF != string::npos && itTypeU != string::npos && itExpr != string::npos)
{
execDone = 0;
line = -1;
fileN = "";
int expr = 0;
curr = NULL;
auto itL = origLine.find("NLINE=");
if (itL != string::npos)
{
string lineS = "";
for (size_t z = itL + 6; origLine[z] != ' '; ++z)
lineS += origLine[z];
line = atoi(lineS.c_str());
}
auto itS = origLine.find("SOURCE=");
if (itS != string::npos)
{
string source = "";
for (size_t z = itS + 7; origLine[z] != ' '; ++z)
source += origLine[z];
fileN = source;
convertToLower(fileN);
}
string exprS = "";
for (size_t z = itExpr + 5; origLine[z] != '\n'; ++z)
exprS += origLine[z];
expr = atoi(exprS.c_str());
if (line != -1 && fileN != "")
{
auto itIntF = mapOfIntervals.find(fileN);
if (itIntF == mapOfIntervals.end())
{
//TODO: error
}
else
{
for (auto &inter : itIntF->second)
{
if (inter.second->tag == expr)
{
curr = inter.second;
string execCountS = "";
auto itExec = origLine.find("EXE_COUNT=");
string execS = "";
for (size_t z = itExec + 10; origLine[z] != ' '; ++z)
execS += origLine[z];
inter.second->exec_count = atoi(execS.c_str());
break;
}
}
}
}
}
auto itE = origLine.find("Execution time");
if (itE != string::npos && execDone == 0)
{
execDone = 1;
size_t idx = 16;
while (origLine[idx++] == ' ');
string execC = "";
for (size_t z = idx - 1; z < origLine.size(); ++z)
execC += origLine[z];
double execTime = atof(execC.c_str());
if (line != -1 && fileN != "" && curr)
curr->exec_time += execTime;
}
}
}
fclose(stat);
}
else
__spf_print(1, " Error: unable to open file %s\n", file.c_str());
}