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,315 @@
#pragma once
#include <string>
#include <set>
#include "../Utils/AstWrapper.h"
#include "../Utils/utils.h"
#include "../DirectiveProcessing/shadow.h"
#include "../GraphLoop/graph_loops.h"
static const char* paramNames[] =
{ "NONE_T", "ARRAY_T", "STRING_ARRAY_T", "STRING_T", "SCALAR_CHAR_T", "SCALAR_BOOL_T", "SCALAR_SHORT_T", "SCALAR_INT_T", "SCALAR_LONG_INT_T",
"SCALAR_FLOAT_T", "SCALAR_DOUBLE_T",
"SCALAR_CMPLX_FLOAT_T", "SCALAR_CMPLX_DOUBLE_T", "EXTERNAL_T", "UNKNOWN_T" };
typedef enum parF { NONE_T, ARRAY_T, STRING_ARRAY_T, STRING_T, SCALAR_CHAR_T, SCALAR_BOOL_T, SCALAR_SHORT_T, SCALAR_INT_T, SCALAR_LONG_INT_T,
SCALAR_FLOAT_T, SCALAR_DOUBLE_T,
SCALAR_CMPLX_FLOAT_T, SCALAR_CMPLX_DOUBLE_T, EXTERNAL_T, UNKNOWN_T} paramType;
#ifndef IN_BIT
#define IN_BIT 16
#endif
#ifndef OUT_BIT
#define OUT_BIT 256
#endif
struct FuncParam
{
FuncParam() { countOfPars = 0; }
void init(const int numPar)
{
countOfPars = numPar;
if (numPar)
{
parameters.resize(numPar);
parametersT.resize(numPar);
inout_types.resize(numPar);
std::fill(parametersT.begin(), parametersT.end(), NONE_T);
std::fill(inout_types.begin(), inout_types.end(), 0);
}
}
void completeParams()
{
for (int z = 0; z < countOfPars; ++z)
if (inout_types[z] == 0)
inout_types[z] = IN_BIT;
}
bool isArgIn(const int num) const
{
if (num >= countOfPars)
return false;
else
return (inout_types[num] & IN_BIT) != 0;
}
bool isArgOut(const int num) const
{
if (num >= countOfPars)
return false;
else
return (inout_types[num] & OUT_BIT) != 0;
}
bool isArgInOut(const int num) const
{
if (num >= countOfPars)
return false;
else
return isArgIn(num) && isArgOut(num);
}
static bool isArgIn(int64_t type) { return (type & IN_BIT) != 0; }
static bool isArgOut(int64_t type) { return (type & OUT_BIT) != 0; }
static bool isArgInOut(int64_t type) { return isArgIn(type) && isArgOut(type); }
std::vector<std::string> identificators;
std::vector<void*> parameters;
std::vector<paramType> parametersT;
std::vector<int> inout_types;
int countOfPars;
};
#ifndef IN_BIT
#undef IN_BIT
#endif
#ifndef OUT_BIT
#undef OUT_BIT
#endif
struct NestedFuncCall
{
std::string CalledFuncName;
std::vector<std::vector<int>> NoOfParamUsedForCall;
NestedFuncCall(std::string funcName) : CalledFuncName(funcName) { }
NestedFuncCall(std::string funcName, int ParsNum) :
CalledFuncName(funcName),
NoOfParamUsedForCall(std::vector<std::vector<int>>(ParsNum))
{ }
};
struct FuncInfoCallFrom {
// <name, line>
std::pair<std::string, int> detailCallsFrom;
// <pointer, SG_VAR> SgStatement for PROC_STAT, SgExpression for FUNC_CALL, VAR_REF for external calls
std::pair<void*, int> pointerDetailCallsFrom;
// parent SgStatement* of FUNC_CALL
void* parentForPointer;
FuncParam actualParams;
};
struct FuncInfo
{
std::string funcName;
std::pair<int, int> linesNum;
std::string fileName;
Statement *funcPointer;
bool isMain;
bool isInterface;
std::set<std::string> callsFrom; //calls from this function
std::set<FuncInfo*> callsFromV;
std::vector<FuncInfoCallFrom> callsFromDetailed;
std::map<std::string, std::set<std::string>> commonBlocks;
std::vector<FuncInfo*> callsTo; //calls of this function
FuncParam funcParams;
std::vector<bool> isParamUsedAsIndex;
std::vector<NestedFuncCall> funcsCalledFromThis; // size = amount of calls in this func;
// if (FuncsCalledFromThis[func_call_idx].
// NoOfParamUsedForCall.size() == 0) - no params of cur func used
ShadowNode* shadowTreeStart;
ShadowNode* shadowTreeEnd;
std::map<void*, ShadowNode*> allShadowNodes;
std::set<DIST::Array*> allUsedArrays; // real array refs
std::set<DIST::Array*> usedArraysWrite; // real array refs
std::vector<LoopGraph*> loopsInFunc;
std::set<int> linesOfIO;
std::set<int> linesOfStop;
std::map<std::string, FuncInfo*> interfaceBlocks;
std::map<std::string, FuncInfo*> interfaceSynonims;
std::vector<FuncInfo*> entry; // all entry points
std::set<std::string> externalCalls;
bool isPure; // does this func or funcs called from this have common block[s] and have no side effects
bool doNotInline;
bool doNotAnalyze;
bool needToInline;
bool deadFunction;
// for RESOLVE_PAR_REGIONS
int inRegion; // 0 - none, 1 - explicit, 2 - implicit, 3 - indirect
std::set<uint64_t> callRegions; // 0 - default; forall i > 0, i - user region
bool isInRegion() { return inRegion == 1 || inRegion == 2; }
bool isIndirect() { return inRegion == 3; }
//
std::vector<FuncInfo*> fullCopiesOfThisFunction;
FuncInfo() :
doNotInline(false), funcPointer(NULL), doNotAnalyze(false), needToInline(false),
deadFunction(false), inRegion(0), isPure(false), isMain(false), shadowTreeStart(NULL), shadowTreeEnd(NULL),
isInterface(false) { }
FuncInfo(const std::string &funcName, const std::pair<int, int> &lineNum) :
funcName(funcName), linesNum(lineNum), doNotInline(false), funcPointer(NULL),
doNotAnalyze(false), needToInline(false), deadFunction(false), inRegion(0), isMain(false),
isPure(false), shadowTreeStart(NULL), shadowTreeEnd(NULL), isInterface(false) { }
#if !__SPC
FuncInfo(const std::string &funcName, const std::pair<int, int> &lineNum, Statement *pointer) :
funcName(funcName), linesNum(lineNum), doNotInline(false), funcPointer(pointer),
doNotAnalyze(false), needToInline(false), deadFunction(false), inRegion(0), isMain(false),
isPure(false), shadowTreeStart(NULL), shadowTreeEnd(NULL), isInterface(false) { fileName = pointer->fileName(); }
#endif
std::vector<std::pair<void*, int>> GetDetailedCallInfo(const std::string &funcName)
{
std::vector<std::pair<void*, int>> result;
for (int i = 0; i < callsFromDetailed.size(); ++i)
{
if (callsFromDetailed[i].detailCallsFrom.first == funcName)
result.push_back(callsFromDetailed[i].pointerDetailCallsFrom);
}
return result;
}
std::string getFuncNameWithContainsByRegion(const uint64_t regionId)
{
if (regionId && callRegions.size() > 1 && callRegions.find(regionId) != callRegions.end())
return funcName + "_r" + std::to_string(regionId);
return funcName;
}
std::string getFuncNameByRegion(const std::string &shortName, const uint64_t regionId)
{
if (regionId && callRegions.size() > 1 && callRegions.find(regionId) != callRegions.end())
return shortName + "_r" + std::to_string(regionId);
return shortName;
}
void removeNonDistrArrays()
{
std::set<DIST::Array*> newUsedArrays;
for (auto &elem : allUsedArrays)
if (elem->GetDistributeFlagVal() == DIST::DISTR)
newUsedArrays.insert(elem);
allUsedArrays = newUsedArrays;
}
bool usesIO() const { return (linesOfIO.size() != 0 || linesOfStop.size() != 0); }
std::string getCallName(const std::pair<void*, int>& call_info, const std::string& name, int line)
{
if (line <= 0)
return name;
std::set<std::string> names;
for (auto& call : callsFromDetailed)
{
if (call.pointerDetailCallsFrom == call_info && call.detailCallsFrom.second == line)
return call.detailCallsFrom.first;
if (call.detailCallsFrom.second == line)
if (call.detailCallsFrom.first.find(name) != std::string::npos)
names.insert(call.detailCallsFrom.first);
}
//TODO: detect func call better
if (names.size() == 1)
return *names.begin();
//try to find in next lvl calls
for (auto& call : callsFromDetailed)
{
if (call.detailCallsFrom.second == line)
{
std::string name_next = call.detailCallsFrom.first;
std::set<FuncInfo*> next, done;
for (auto& callFrom : callsFromV)
if (callFrom->funcName == name_next)
next.insert(callFrom);
done = next;
while (next.size())
{
auto curr = next;
next.clear();
for (auto& callFrom : curr)
{
for (auto& call : callFrom->callsFromDetailed)
{
if (call.detailCallsFrom.first == name)
return call.detailCallsFrom.first;
}
for (auto& callFromNext : callFrom->callsFromV)
{
if (done.find(callFromNext) == done.end())
{
next.insert(callFromNext);
done.insert(callFromNext);
}
}
}
}
}
}
return "";
}
};
struct CallV
{
std::string fName;
std::string fileName;
bool isMain;
int inRegion;
CallV() : inRegion(0), isMain(false) { }
CallV(const std::string &fName) :
fName(fName), fileName(""), isMain(false), inRegion(0)
{ }
CallV(const std::string &fName, const std::string &fileName, bool isMain) :
fName(fName), fileName(fileName), isMain(isMain), inRegion(0)
{ }
std::string to_string()
{
return fName + "@" + fileName + "@" + (isMain ? "1" : "0") + "@" + std::to_string(inRegion);
}
};
void propagateArrayFlags(const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls, const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays, std::map<std::string, std::vector<Messages>> &SPF_messages);
void removeDistrStateFromDeadFunctions(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);
bool detectMpiCalls(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, std::map<std::string, std::vector<Messages>>& SPF_messages);
int getLvlCall(FuncInfo* currF, int lvl, const std::string& func, const std::string& file, int line);
void compliteArrayUsage(DIST::Arrays<int>& allArraysForRegion, std::map<std::tuple<int, std::string, std::string>, DIST::Array*>& createdArrays, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, const std::map<DIST::Array*, std::tuple<int, std::string, std::string>>& tableOfUniqNamesByArray);
void remoteNotUsedArrays(std::map<std::tuple<int, std::string, std::string>, DIST::Array*>& createdArrays, const std::set<DIST::Array*>& usedArraysAcrossRegions, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);