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,882 @@
#include "CreateInterTree.h"
#include "../Utils/SgUtils.h"
#include "../Utils/utils.h"
#include "../GraphCall/graph_calls_func.h"
using std::string;
using std::wstring;
using std::vector;
using std::list;
using std::map;
using std::pair;
using std::set;
using std::cout;
using std::endl;
using std::fstream;
static long int getNextTag()
{
static long int INTERVAL_TAG = 0;
return INTERVAL_TAG++;
}
//Debug funcs
static void printTree(SpfInterval* inter, fstream &file, int level)
{
if (!(inter->ifInclude))
{
for (int i = 0; i < inter->nested.size(); i++)
printTree(inter->nested[i], file, level + 1);
return;
}
if (!inter->begin->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (int i = 0; i < level; i++)
file << " ";
file << " Begin INTERVAL #" << inter->tag << " (var " << tag[inter->begin->variant()];
if (inter->begin->variant() == PROC_HEDR || inter->begin->variant() == FUNC_HEDR)
{
string name(inter->begin->symbol()->identifier());
convertToUpper(name);
file << ", " << name;
}
file << ", gcov_calls " << inter->calls_count << ") ";
file << " [" << inter->lineFile.first << ", " << inter->lineFile.second << "]";
if (inter->parent == NULL && level != 0)
file << " -- through PROC_CALL --";
file << "\n";
for (int i = 0; i < inter->nested.size(); i++)
printTree(inter->nested[i], file, level + 1);
for (int i = 0; i < inter->ends.size(); i++)
{
for (int i = 0; i < level; i++)
file << " ";
file << " End INTERVAL #" << inter->tag << " (exit lvl " << inter->exit_levels[i] << ", var " << tag[inter->ends[i]->variant()] << ") ";
file << "line " << inter->ends[i]->lineNumber() << endl;
}
if (level == 0)
file << endl;
}
void saveIntervals(const string &fileName, map<string, vector<SpfInterval*>> &intervals)
{
fstream file_intervals;
file_intervals.open(fileName, fstream::out);
for (auto &byfile : intervals)
{
file_intervals << "**** INTERVALS FOR FILE '" << byfile.first << "'\n";
for (auto &interval : byfile.second)
printTree(interval, file_intervals, 0);
}
file_intervals.close();
}
//Labels funcs
static void matchGotoLabels(SgStatement *st, map<int, vector<int>> &gotoStmts)
{
map<int, vector<int>> labelsRef;
findAllRefsToLables(st, labelsRef, false);
for (auto &key : labelsRef)
for (auto &it : key.second)
gotoStmts[it].push_back(key.first);
}
static void findAllLabels(SgStatement* st, map<int, int> &labelsRef)
{
SgStatement* end = st->lastNodeOfStmt();
while (st != end)
{
if (st->hasLabel())
labelsRef[st->label()->id()] = st->lineNumber();
st = st->lexNext();
}
if (end->hasLabel())
labelsRef[end->label()->id()] = end->lineNumber();
}
//Nested intervals removal
static int getNestedLevel(SgStatement* loop_stmt)
{
int depth = 0;
SgStatement *current_loop = loop_stmt->lexNext();
SgStatement* controlEnd = loop_stmt->lastNodeOfStmt()->lexPrev();
SgStatement *controlEnd2 = current_loop->lastNodeOfStmt();
while (isSgForStmt(current_loop) && isSgControlEndStmt(controlEnd) && controlEnd == controlEnd2)
{
current_loop = current_loop->lexNext();
controlEnd = controlEnd->lexPrev();
controlEnd2 = current_loop->lastNodeOfStmt();
depth++;
}
return depth;
}
static void removeNestedIntervals(SpfInterval* interval)
{
if (isSgForStmt(interval->begin))
{
int depth = getNestedLevel(interval->begin);
SpfInterval *current_interval = interval;
for (int i = 0; i < depth; i++)
{
current_interval = current_interval->nested[0];
current_interval->ifInclude = false;
}
}
for (auto &include : interval->nested)
removeNestedIntervals(include);
}
// Merge trees functions.
static int compareIntervals(SpfInterval* interval1, SpfInterval* interval2)
{
SgStatement* begin_st_1 = interval1->begin;
while (!isSgExecutableStatement(begin_st_1) || isSPF_stat(begin_st_1) || isDVM_stat(begin_st_1))
begin_st_1 = begin_st_1->lexNext();
SgStatement* begin_st_2 = interval2->begin;
while (!isSgExecutableStatement(begin_st_2) || isSPF_stat(begin_st_2) || isDVM_stat(begin_st_2))
begin_st_2 = begin_st_2->lexNext();
int begin_1 = begin_st_1->lineNumber();
int begin_2 = begin_st_2->lineNumber();
int end_1 = interval1->ends[0]->lineNumber();
int end_2 = interval2->ends[0]->lineNumber();
if((begin_1 == begin_2 && end_1 == end_2) || end_1 <= begin_2 || begin_1 >= end_2)
return 0;
if(begin_1 <= begin_2 && end_1 >= end_2)
return 1;
return -1;
}
static void insertIntervalIntoTree(vector<SpfInterval*> &tree, SpfInterval* userInterval)
{
bool ifDeleteNested = false;
for(int i = 0; i < tree.size(); i++)
{
int compare_result = compareIntervals(tree[i], userInterval);
if(compare_result == 0)
continue;
if(compare_result > 0)
{
int amount = 0;
for(int j = 1; j < tree[i]->ends.size(); j++)
{
int endLineNumber = tree[i]->ends[j]->lineNumber();
if(endLineNumber >= userInterval->begin->lineNumber() && endLineNumber <= userInterval->ends[0]->lineNumber())
{
userInterval->ends.push_back(tree[i]->ends[j]);
userInterval->exit_levels.push_back(0);
tree[i]->ends[j] = NULL;
amount++;
}
}
tree[i]->ends.erase(std::remove_if(tree[i]->ends.begin(), tree[i]->ends.end(), [](SgStatement* stmt) {return (stmt == NULL);}), tree[i]->ends.end());
for(int j = 0; j < amount; j++)
tree[i]->exit_levels.pop_back();
insertIntervalIntoTree(tree[i]->nested, userInterval);
return;
}
userInterval->nested.push_back(tree[i]);
userInterval->parent = tree[i]->parent;
tree[i]->parent = userInterval;
tree[i] = userInterval;
if(ifDeleteNested)
tree[i] = NULL;
else
ifDeleteNested = true;
}
tree.erase(std::remove_if(tree.begin(), tree.end(), [](SpfInterval* interval) {return (interval == NULL);}), tree.end());
}
static void mergeTrees(vector<SpfInterval*> &fileIntervals, vector<SpfInterval*> &userIntervals)
{
for(auto &userInterval : userIntervals)
insertIntervalIntoTree(fileIntervals, userInterval);
}
// Calibrate interval exits.
static void calibrateExits(const vector<SpfInterval*>& fileIntervals, const map<int, int> &labelsRef, map<int, vector<int>> &gotoStmts, int level)
{
for(auto &interval : fileIntervals)
{
for(int i = 1; i < interval->ends.size(); i++)
{
int variant = interval->ends[i]->variant();
int &exit_level = interval->exit_levels[i];
if (variant == RETURN_STAT || variant == STOP_STAT || variant == EXIT_STMT)
exit_level = level;
if (variant == EXIT_STMT)
exit_level = 1;
for (auto&lab : gotoStmts[interval->ends[i]->lineNumber()])
{
auto itL = labelsRef.find(lab);
if (itL == labelsRef.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const int label_line = itL->second;
if (label_line == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
int depth = 0;
SpfInterval* searchInterval = interval;
while (label_line < searchInterval->begin->lineNumber() || label_line > searchInterval->ends[0]->lineNumber())
{
searchInterval = searchInterval->parent;
depth++;
if (searchInterval == NULL)
break;
}
exit_level = depth;
}
}
calibrateExits(interval->nested, labelsRef, gotoStmts, level + 1);
}
}
static void removeUserIntervals(SgFile *file)
{
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
{
const int var = st->variant();
if (var == DVM_INTERVAL_DIR || var == DVM_EXIT_INTERVAL_DIR || var == DVM_ENDINTERVAL_DIR)
{
//move comment to next statement
if (st->comments())
{
const char* comms = st->comments();
string comments(comms);
st->delComments();
SgStatement* next = st->lexNext();
if (next)
next->addComment(comments.c_str());
}
st = st->lexPrev();
st->lexNext()->deleteStmt();
}
}
}
// Find intervals functions.
static void findUserIntervals(SgStatement *startSt, vector<SpfInterval*> &userIntervals, vector<Messages> &messages)
{
SpfInterval *currentInterval = NULL;
SgStatement *endSt = startSt->lastNodeOfStmt();
SgStatement *currentSt = startSt;
set<SpfInterval*> userIntervalsSet;
while (currentSt != endSt)
{
if(currentSt->variant() == DVM_INTERVAL_DIR)
{
SgStatement* begin = currentSt;
while (isDVM_stat(begin))
begin = begin->lexNext();
SpfInterval *inter = new SpfInterval(currentSt->lineNumber());
inter->begin = begin;
inter->lineFile = std::make_pair(begin->lineNumber(), begin->fileName());
inter->parent = currentInterval;
inter->tag = getNextTag();
userIntervals.push_back(inter);
currentInterval = inter;
userIntervalsSet.insert(currentInterval);
}
if(currentSt->variant() == DVM_ENDINTERVAL_DIR)
{
if (currentInterval == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* end = currentSt;
while(isDVM_stat(end))
end = end->lexPrev();
currentInterval->ends.push_back(end);
currentInterval->exit_levels.push_back(0);
currentInterval = currentInterval->parent;
}
currentSt = currentSt->lexNext();
}
bool error = false;
//check for ends
for (auto& inter : userIntervalsSet)
{
if (inter->begin == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (inter->ends.size() == 0)
{
wstring messageR, messageE;
__spf_printToLongBuf(messageE, L"Can not find end of DVM's interval");
__spf_printToLongBuf(messageR, R150);
messages.push_back(Messages(ERROR, inter->userIntervalLine, messageR, messageE, 1052));
error = true;
}
}
if (error)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
static void findIntervals(SpfInterval *interval, map<int, int> &labelsRef, map<int, vector<int>> &gotoStmts, SgStatement *&currentSt)
{
int currentVar = -1;
SgStatement* endStatement = interval->parent ? interval->ends[0] : interval->begin->lastNodeOfStmt();
while (currentSt != endStatement && currentVar != CONTAINS_STMT)
{
currentSt = currentSt->lexNext();
currentVar = currentSt->variant();
if (currentSt->fileName() != string(interval->begin->fileName()))
continue;
if (currentVar == RETURN_STAT || currentVar == STOP_STAT || currentVar == EXIT_STMT || currentVar == CONTAINS_STMT)
{
if (endStatement != currentSt)
{
interval->ends.push_back(currentSt);
interval->exit_levels.push_back(0);
}
}
if (gotoStmts.find(currentSt->lineNumber()) != gotoStmts.end() && currentVar != LOGIF_NODE)
{
vector<int>& labels = gotoStmts[currentSt->lineNumber()];
for (auto& lab : labels)
{
auto itL = labelsRef.find(lab);
if (itL == labelsRef.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const int label_line = itL->second;
if (label_line == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (label_line < interval->begin->lineNumber() || label_line > interval->ends[0]->lineNumber())
{
interval->ends.push_back(currentSt);
interval->exit_levels.push_back(0);
}
}
}
if (currentSt == endStatement || currentVar != FOR_NODE)
continue;
SpfInterval* inter = new SpfInterval(-1);
inter->begin = currentSt;
inter->ends.push_back(currentSt->lastNodeOfStmt());
inter->lineFile = std::make_pair(currentSt->lineNumber(), currentSt->fileName());
inter->parent = interval;
inter->exit_levels.push_back(0);
inter->tag = getNextTag();
interval->nested.push_back(inter);
findIntervals(inter, labelsRef, gotoStmts, currentSt);
}
}
void createInterTree(SgFile *file, vector<SpfInterval*> &fileIntervals, bool nested_on, vector<Messages> &messages)
{
int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; i++)
{
map<int, int> labelsRef; // id => line
map<int, vector<int>> gotoStmts; // line => label_ids
vector<SpfInterval*> userIntervals;
// Find labels.
findAllLabels(file->functions(i), labelsRef);
matchGotoLabels(file->functions(i), gotoStmts);
// Find user intervals.
findUserIntervals(file->functions(i), userIntervals, messages);
SpfInterval *func_inters = new SpfInterval(-1);
// Set begining of the interval.
func_inters->begin = file->functions(i);
func_inters->lineFile = std::make_pair(func_inters->begin->lineNumber(), file->functions(i)->fileName());
func_inters->tag = getNextTag();
// Set ending of the interval.
SgStatement *lastNode = func_inters->begin->lastNodeOfStmt()->lexPrev();
while (isDVM_stat(lastNode) || isSPF_stat(lastNode))
lastNode = lastNode->lexPrev();
SgStatement *prevLastNode = lastNode->lexPrev();
while (isDVM_stat(prevLastNode) || isSPF_stat(prevLastNode))
prevLastNode = prevLastNode->lexPrev();
if (lastNode->variant() == RETURN_STAT || lastNode->variant() == EXIT_STMT || lastNode->variant() == STOP_STAT)
{
bool cond = false;
if (lastNode->lexNext()->variant() == CONTROL_END)
if (isSgProgHedrStmt(lastNode->lexNext()->controlParent()))
cond = true;
if (cond)
func_inters->ends.push_back(lastNode);
else
func_inters->ends.push_back(prevLastNode);
}
else
func_inters->ends.push_back(lastNode);
func_inters->exit_levels.push_back(0);
// Find inner intervals.
SgStatement *currentSt = func_inters->begin;
findIntervals(func_inters, labelsRef, gotoStmts, currentSt);
vector<SpfInterval*> oneInterval;
oneInterval.push_back(func_inters);
mergeTrees(oneInterval, userIntervals);
calibrateExits(oneInterval, labelsRef, gotoStmts, 1);
fileIntervals.push_back(oneInterval[0]);
}
if (nested_on)
for (auto &interval : fileIntervals)
removeNestedIntervals(interval);
}
//SpfInterval insertion funcs
static void insertTree(SpfInterval* interval, const string &fileName)
{
if (interval->ifInclude && interval->begin->fileName() == fileName)
{
SgStatement* beg_inter = new SgStatement(DVM_INTERVAL_DIR);
SgExpression* expr = new SgValueExp(interval->tag);
beg_inter->setExpression(0, *expr);
SgStatement* end_inter = new SgStatement(DVM_ENDINTERVAL_DIR);
// Skip to executables.
SgStatement* beginSt = interval->begin;
while (!isSgExecutableStatement(beginSt) || isSPF_stat(beginSt) || isDVM_stat(beginSt))
beginSt = beginSt->lexNext();
if (beginSt->lexPrev()->variant() == LOGIF_NODE)
LogIftoIfThen(beginSt->lexPrev());
// Insert begining
beginSt->insertStmtBefore(*beg_inter, *beginSt->controlParent());
beg_inter->setlineNumber(beginSt->lineNumber());
interval->ends[0]->insertStmtAfter(*end_inter, *beginSt->controlParent());
for (int i = 1; i < interval->ends.size(); i++)
{
int depth = interval->exit_levels[i];
SpfInterval* curr_inter = interval->parent;
SgExprListExp* expli = new SgExprListExp(*(new SgValueExp(interval->tag)));
SgExprListExp* curr_list_elem = expli;
for (int j = 1; j < depth; j++)
{
if(curr_inter->ifInclude)
{
curr_list_elem->setRhs(new SgExprListExp(*(new SgValueExp(curr_inter->tag))));
curr_list_elem = curr_list_elem->next();
}
curr_inter = curr_inter->parent;
}
curr_list_elem->setRhs(NULL);
SgStatement* exit_inter = new SgStatement(DVM_EXIT_INTERVAL_DIR);
exit_inter->setExpression(0, *expli);
if (interval->ends[i]->lexPrev()->variant() == LOGIF_NODE)
LogIftoIfThen(interval->ends[i]->lexPrev());
interval->ends[i]->insertStmtBefore(*exit_inter, *interval->ends[i]->controlParent());
}
}
for (int i = 0; i < interval->nested.size(); i++)
insertTree(interval->nested[i], fileName);
}
void insertIntervals(SgFile *file, const vector<SpfInterval*> &fileIntervals)
{
const string currFile = file->filename();
removeUserIntervals(file);
for (auto &interval : fileIntervals)
insertTree(interval, currFile);
}
//Profiling funcs
static map<int, long long> parseProfiles(fstream &file)
{
map<int, long long> fileProfile;
string line;
while (!file.eof())
{
getline(file, line);
auto pos_type = line.find(":");
string type = line.substr(0, pos_type);
if (type == "lcount")
{
if ((int)line.size() >= pos_type + 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
string nums = line.substr(pos_type + 1);
auto pos_com = nums.find(",");
auto line_num = stoi(nums.substr(0, pos_com));
if ((int)nums.size() >= pos_com + 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
long long calls_num = stoll(nums.substr(pos_com + 1));
fileProfile[line_num] = calls_num;
}
}
return fileProfile;
}
static void assignRec(SpfInterval* inter, map<int, long long> &fp)
{
for (int i = 0; i < inter->nested.size(); i++)
assignRec(inter->nested[i], fp);
inter->calls_count = fp[inter->begin->lineNumber()];
}
void assignCallsToFile(const string &baseFilename, vector<SpfInterval*> &intervals)
{
fstream file;
file.open(baseFilename + ".gcov", fstream::in);
if (!file.good())
return;
map<int, long long> fileProfile = parseProfiles(file);
file.close();
for (auto &interval : intervals)
assignRec(interval, fileProfile);
}
//Deleting intervals funcs
static void removeNode(SpfInterval* inter, long long threshold)
{
if (inter->calls_count >= threshold)
inter->ifInclude = false;
for (int i = 0; i < inter->nested.size(); i++)
removeNode(inter->nested[i], threshold);
}
static void fillListWithValues(list<long long> &interval_calls, SpfInterval* interval)
{
auto it = interval_calls.begin();
for(; it != interval_calls.end(); it++)
if(interval->calls_count < *it)
{
interval_calls.insert(it, interval->calls_count);
break;
}
if(it == interval_calls.end())
interval_calls.push_back(interval->calls_count);
for (auto &i : interval->nested)
fillListWithValues(interval_calls, i);
}
void removeNodes(int threshold, vector<SpfInterval*> &intervals, vector<string> &include_functions)
{
if (threshold == 100)
return;
for (auto &interval : intervals)
{
string func_name = interval->begin->symbol()->identifier();
if (find(include_functions.begin(), include_functions.end(), func_name) != include_functions.end())
continue;
list<long long> interval_calls;
fillListWithValues(interval_calls, interval);
int amount = interval_calls.size() / 100.f * threshold;
auto it = interval_calls.begin();
advance(it, amount);
removeNode(interval, *it);
}
}
void createMapOfinterval(map<int, SpfInterval*> &mapIntervals, const vector<SpfInterval*> &intervals)
{
for (auto &inter : intervals)
{
auto it = mapIntervals.find(inter->begin->lineNumber());
if (it != mapIntervals.end())
continue;
mapIntervals[inter->begin->lineNumber()] = inter;
createMapOfinterval(mapIntervals, inter->nested);
}
}
void initTimeForIntervalTree(const int numOfTopologies, vector<SpfInterval*> &intervals)
{
for (auto &inter : intervals)
{
inter->predictedTimes.resize(numOfTopologies);
inter->predictedRemoteTimes.resize(numOfTopologies);
std::fill(inter->predictedTimes.begin(), inter->predictedTimes.end(), -1);
std::fill(inter->predictedRemoteTimes.begin(), inter->predictedRemoteTimes.end(), 0);
initTimeForIntervalTree(numOfTopologies, inter->nested);
}
}
void aggregatePredictedTimes(vector<SpfInterval*> &itervals)
{
for (auto &interval : itervals)
{
if (interval->predictedTimes.size() && interval->predictedTimes[0] != -1)
continue;
if (interval->nested.size())
aggregatePredictedTimes(interval->nested);
for (int topo = 0; topo < interval->predictedTimes.size(); ++topo)
{
double newTimeSum = 0;
for (auto &nestedI : interval->nested)
{
if (nestedI->predictedTimes[topo] == -1)
newTimeSum += nestedI->exec_time + nestedI->predictedRemoteTimes[topo];
else
newTimeSum += nestedI->predictedTimes[topo] + nestedI->predictedRemoteTimes[topo];
}
interval->predictedTimes[topo] = newTimeSum;
}
}
}
SpfInterval* getMainInterval(SgProject *project, const map<string, vector<SpfInterval*>> &intervals, map<string, vector<Messages>> &SPF_messages)
{
SgStatement *mainUnit = findMainUnit(project, SPF_messages);
SpfInterval *mainIterval = NULL;
checkNull(mainUnit, convertFileName(__FILE__).c_str(), __LINE__);
auto itMainVec = intervals.find(mainUnit->fileName());
if (itMainVec == intervals.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (itMainVec->second.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
else if (itMainVec->second.size() > 1)
{
for (auto &elem : itMainVec->second)
if (elem->begin->variant() == PROG_HEDR)
mainIterval = elem;
checkNull(mainIterval, convertFileName(__FILE__).c_str(), __LINE__);
}
else
mainIterval = itMainVec->second[0];
return mainIterval;
}
SpfInterval* findNearestUp(const map<SgStatement*, SpfInterval*> &intervals, SgStatement *st)
{
SpfInterval *found = NULL;
while (st)
{
auto it = intervals.find(st);
if (it != intervals.end())
{
found = it->second;
break;
}
else
st = st->controlParent();
}
checkNull(found, convertFileName(__FILE__).c_str(), __LINE__);
return found;
}
SpfInterval* findNearestDown(const map<SgStatement*, SpfInterval*> &intervals, SgStatement *st)
{
SpfInterval *found = NULL;
while (st)
{
auto it = intervals.find(st);
if (it != intervals.end())
{
found = it->second;
break;
}
else
st = st->lexNext();
}
checkNull(found, convertFileName(__FILE__).c_str(), __LINE__);
return found;
}
static FuncInfo* getFunc(const string &file, const int line, const map<string, FuncInfo*> &allFuncs)
{
for (auto &func : allFuncs)
if (func.second->linesNum.first == line && func.second->fileName == file)
return func.second;
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return NULL;
}
static void createMapOfIntervals(const vector<SpfInterval*> &intervals, map<SgStatement*, SpfInterval*> &intervalsBySt)
{
for (auto &interval : intervals)
intervalsBySt[interval->begin] = interval;
for (auto &interval : intervals)
if (interval->nested.size())
createMapOfIntervals(interval->nested, intervalsBySt);
}
static void insertAndSort(SpfInterval *nearest, SpfInterval *toInsert, SgStatement *stLine)
{
if (nearest->nested.size() == 0)
nearest->nested.push_back(toInsert);
else
{
const int line = stLine->lineNumber();
for (int z = 0; z < nearest->nested.size(); ++z)
{
if (nearest->nested[z]->parent)
{
if (nearest->nested[z]->lineFile.first > line)
{
nearest->nested.insert(nearest->nested.begin() + z, toInsert);
return;
}
}
}
nearest->nested.push_back(toInsert);
}
}
void uniteIntervalsBetweenProcCalls(map<string, vector<SpfInterval*>> &intervals, const map<string, vector<FuncInfo*>> &allFuncInfo)
{
map<string, map<SgStatement*, SpfInterval*>> intervalsBySt;
for (auto &byFile : intervals)
createMapOfIntervals(byFile.second, intervalsBySt[byFile.first]);
map<string, FuncInfo*> allFuncs;
createMapOfFunc(allFuncInfo, allFuncs);
for (auto &byFile : intervals)
{
for (auto &intvl : byFile.second)
{
if (intvl->begin->variant() != PROG_HEDR)
{
if (!intvl->begin->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* funcSt = intvl->begin;
if (isSgProgHedrStmt(intvl->begin) == NULL)
funcSt = intvl->begin->controlParent();
const string name = funcSt->symbol()->identifier();
auto currF = getFunc(funcSt->fileName(), funcSt->lineNumber(), allFuncs);
for (auto &callsTo : currF->callsTo)
{
if (SgFile::switchToFile(callsTo->fileName) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto &callsInfo: callsTo->callsFromDetailed)
{
auto& callsFrom = callsInfo.pointerDetailCallsFrom;
SgStatement *base = NULL;
if (callsFrom.second == PROC_STAT)
{
base = (SgStatement*)callsFrom.first;
if (base->symbol()->identifier() != name)
base = NULL;
}
else if (callsFrom.second == FUNC_CALL)
{
SgExpression *ex = (SgExpression*)callsFrom.first;
if (ex->symbol()->identifier() == name)
base = SgStatement::getStatmentByExpression(ex);
}
if (base == NULL)
continue;
else
{
auto itI = intervalsBySt.find(callsTo->fileName);
if (itI == intervalsBySt.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto nearest = findNearestUp(itI->second, base);
insertAndSort(nearest, intvl, base);
}
}
}
}
}
}
}