added TRANSFORM_ASSUMED_SIZE_PARAMETERS pass, fixed shared memory parallelization

This commit is contained in:
ALEXks
2025-07-26 20:22:15 +03:00
parent 3095510826
commit d3d6d0bec7
5 changed files with 168 additions and 85 deletions

View File

@@ -1914,6 +1914,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
calculateStatsForPredictor(allFuncInfo, gCovInfo);
parseDvmDirForPredictor(declaredArrays, commonBlocks, allFuncInfo, gCovInfo);
}
else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS)
transformAssumedSizeParameters(allFuncInfo);
const float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - timeForPass).count() / 1000.;
const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.;
@@ -2149,6 +2151,8 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
runAnalysis(*project, REMOVE_COPIES, false);
runAnalysis(*project, SWAP_LOOPS, false);
runPass(TRANSFORM_ASSUMED_SIZE_PARAMETERS, proj_name, folderName);
if (folderName || consoleMode)
runAnalysis(*project, UNPARSE_FILE, true, additionalName.c_str(), folderName);
}

View File

@@ -185,6 +185,8 @@ enum passes {
FIND_PRIVATE_ARRAYS,
TRANSFORM_ASSUMED_SIZE_PARAMETERS,
TEST_PASS,
EMPTY_PASS
};
@@ -371,6 +373,8 @@ static void setPassValues()
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS";
passNames[TRANSFORM_ASSUMED_SIZE_PARAMETERS] = "TRANSFORM_ASSUMED_SIZE_PARAMETERS";
passNames[TEST_PASS] = "TEST_PASS";
}

View File

@@ -66,7 +66,7 @@ void insertIntrinsicStat(const vector<FuncInfo*>& allFuncInfo)
void* ptr = call.pointerDetailCallsFrom.first;
int var = call.pointerDetailCallsFrom.second;
SgSymbol* s = NULL;
if (var == PROC_STAT)
s = ((SgStatement*)ptr)->symbol();
@@ -126,7 +126,7 @@ bool checkOutCalls(const set<string>& outCalls)
return false;
}
void createInterfacesForOutCalls(FuncInfo* func)
void createInterfacesForOutCalls(FuncInfo* func)
{
if (func->isPure && !func->isMain)
{
@@ -136,33 +136,41 @@ void createInterfacesForOutCalls(FuncInfo* func)
}
}
static bool changeIfHasStarRange(SgExpression* arrayDecl, bool doReplace = false)
static bool changeIfHasStarRange(SgExpression* arrayDecl, SgStatement* scope, vector<SgSymbol*>& parNames)
{
SgExpression* list = arrayDecl->lhs();
bool has = doReplace;
string varN = arrayDecl->symbol()->identifier() + string("_sz");
bool has = false;
SgExpression* allDimsBefore = NULL;
while (list)
{
const int var = list->lhs()->variant();
if (var == STAR_RANGE)
has = true;
list = list->rhs();
}
if (has)
{
list = arrayDecl->lhs();
while (list)
{
list->setLhs(new SgExpression(DDOT));
list = list->rhs();
has = true;
parNames.push_back(new SgSymbol(VARIABLE_NAME, varN.c_str(), SgTypeInt(), scope));
SgExpression* par = allDimsBefore ? &(*new SgVarRefExp(parNames.back()) / *allDimsBefore) : (new SgVarRefExp(parNames.back()));
list->setLhs(par);
break;
}
else
{
if (allDimsBefore == NULL)
allDimsBefore = list->lhs();
else
allDimsBefore = &(*allDimsBefore * *list->lhs()->copyPtr());
}
list = list->rhs();
}
return has;
}
static void removeExternalStat(SgStatement* func, const set<string>& addedInterfaceFor)
/*static void removeExternalStat(SgStatement* func, const set<string>& addedInterfaceFor)
{
vector<SgStatement*> toRem;
for (auto st = func; st != func->lastNodeOfStmt(); st = st->lexNext())
@@ -197,7 +205,7 @@ static void removeExternalStat(SgStatement* func, const set<string>& addedInterf
for (auto& rem : toRem)
rem->deleteStmt();
}
}*/
template<typename T>
static vector<FuncInfo*> sortByName(const T &funcs)
@@ -210,10 +218,25 @@ static vector<FuncInfo*> sortByName(const T &funcs)
return funcList;
}
//XXX: incorrect!!
/*void createInterfacesForAssumedSize(const map<string, vector<FuncInfo*>>& allFuncInfo)
static bool hasDvmParallel(SgStatement *func)
{
set<FuncInfo*> hasAssumedSizeArrays;
for (auto st = func; st != func->lastNodeOfStmt(); st = st->lexNext())
{
const int var = st->variant();
if (var == DVM_PARALLEL_ON_DIR || var == ACC_REGION_DIR ||
var == ACC_ACTUAL_DIR || var == ACC_GET_ACTUAL_DIR)
return true;
if (st->variant() == CONTAINS_STMT)
break;
}
return false;
}
void transformAssumedSizeParameters(const map<string, vector<FuncInfo*>>& allFuncInfo)
{
map<string, vector<int>> assumedSizeArraysByFunc;
for (auto& funcByFile : allFuncInfo)
{
@@ -221,11 +244,17 @@ static vector<FuncInfo*> sortByName(const T &funcs)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& func : funcByFile.second)
{
{
SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal());
if (prog == NULL)
continue;
if (!hasDvmParallel(prog))
continue;
vector<SgSymbol*> parNames;
SgStatement* scope = prog->getScopeForDeclare();
vector<SgExpression*> arrayRefs;
bool hasRefs = false;
for (int z = 0; z < func->funcParams.countOfPars; ++z)
@@ -245,13 +274,8 @@ static vector<FuncInfo*> sortByName(const T &funcs)
{
if (list->lhs() && list->lhs()->symbol()->identifier() == name)
{
if (changeIfHasStarRange(list->lhs()))
{
hasRefs = true;
hasAssumedSizeArrays.insert(func);
}
else
arrayRefs.push_back(list->lhs());
if (changeIfHasStarRange(list->lhs(), scope, parNames))
assumedSizeArraysByFunc[func->funcName].push_back(z);
break;
}
list = list->rhs();
@@ -260,13 +284,33 @@ static vector<FuncInfo*> sortByName(const T &funcs)
}
}
if (hasRefs)
for (auto& ref : arrayRefs)
changeIfHasStarRange(ref, true);
if (parNames.size())
{
SgProcHedrStmt* proc = isSgProcHedrStmt(func->funcPointer->GetOriginal());
checkNull(proc, convertFileName(__FILE__).c_str(), __LINE__);
makeDeclaration(parNames, scope);
for (auto& newPar : parNames)
{
auto arg = new SgVarRefExp(newPar);
BIF_LL1(proc->thebif) = addToExprList(BIF_LL1(proc->thebif), arg->thellnd);
PTR_LLND ll;
PTR_SYMB symb;
ll = giveLlSymbInDeclList(arg->thellnd);
if (ll && (symb = NODE_SYMB(ll)))
{
appendSymbToArgList(BIF_SYMB(proc->thebif), symb);
SYMB_SCOPE(symb) = proc->thebif;
}
//proc->AddArg(*new SgVarRefExp(newPar));
}
}
}
}
if (hasAssumedSizeArrays.size() == 0)
if (assumedSizeArraysByFunc.size() == 0)
return;
for (auto& funcByFile : allFuncInfo)
@@ -274,29 +318,58 @@ static vector<FuncInfo*> sortByName(const T &funcs)
if (SgFile::switchToFile(funcByFile.first) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgSymbol* funcSize = new SgSymbol(FUNCTION_NAME, "size");
for (auto& func : sortByName(funcByFile.second))
{
SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal());
if (prog == NULL)
continue;
set<string> addedInterfaceFor;
for (auto& elem : sortByName(func->callsFromV))
for (auto& detailedCall : func->callsFromDetailed)
{
auto it = hasAssumedSizeArrays.find(elem);
if (it != hasAssumedSizeArrays.end())
auto it = assumedSizeArraysByFunc.find(detailedCall.detailCallsFrom.first);
if (it != assumedSizeArraysByFunc.end())
{
auto callFrom = *it;
DvmhRegionInserter::createInterfaceBlockForOutCall(func, callFrom);
addedInterfaceFor.insert(callFrom->funcName);
auto pointer = detailedCall.pointerDetailCallsFrom;
SgExpression* list = NULL;
if (pointer.second == FUNC_CALL)
{
SgExpression* p = (SgExpression*)pointer.first;
list = p->lhs();
}
else
{
SgStatement* p = (SgStatement*)pointer.first;
list = p->expr(0);
}
SgExpression* last = list;
vector<SgExpression*> pars;
while (list)
{
last = list;
pars.push_back(list->lhs());
list = list->rhs();
}
for (int z = 0; z < it->second.size(); ++z)
{
int parNum = it->second[z];
if (parNum >= pars.size())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgFunctionCallExp* call = new SgFunctionCallExp(*funcSize, *pars[parNum]);
last->setRhs(new SgExpression(EXPR_LIST, call));
last = last->rhs();
}
}
}
if (addedInterfaceFor.size())
removeExternalStat(prog, addedInterfaceFor);
}
}
}
}*/
}
static void setPureStatus(FuncInfo* func)
{
@@ -314,7 +387,7 @@ static void setPureStatus(FuncInfo* func)
bool hasIO = func->linesOfIO.size() || func->linesOfStop.size();
if (!hasPure && !hasIO && ((isFunc == false) || (isFunc && hasOut == false)))
{
{
header->setExpression(2, new SgExpression(PURE_OP));
header->symbol()->setAttribute(header->symbol()->attributes() | PURE_BIT);
}
@@ -528,7 +601,7 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
OutIdentificators.insert(ident);
}
//remove conflicted intents
//remove conflicted intents
for (auto& entry : func->entry)
{
for (int i = 0; i < entry->funcParams.countOfPars; i++)
@@ -559,11 +632,11 @@ static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
}
insertIntents(InOutIdentificators, headerSt, parSym, INOUT_OP, INOUT_BIT);
insertIntents(InIdentificators, headerSt, parSym, IN_OP, IN_BIT);
insertIntents(InIdentificators, headerSt, parSym, IN_OP, IN_BIT);
insertIntents(OutIdentificators, headerSt, parSym, OUT_OP, OUT_BIT);
}
void intentInsert(const vector<FuncInfo*>& allFuncInfo)
void intentInsert(const vector<FuncInfo*>& allFuncInfo)
{
for (auto& func : allFuncInfo)
{
@@ -632,7 +705,7 @@ static void collectForChange(set<FuncInfo*>& allForChange, FuncInfo* start)
for (auto& call : elem->callsFromV)
if (allForChange.find(call) == allForChange.end())
newAdd.insert(call);
chagned = newAdd.size() != 0;
allForChange.insert(newAdd.begin(), newAdd.end());
@@ -640,7 +713,7 @@ static void collectForChange(set<FuncInfo*>& allForChange, FuncInfo* start)
}
template<typename CallExp>
static void transferVarToArg(const map<string, vector<int>>& commonVarsUsed, const map<string, CommonBlock*>& commonBlocks,
static void transferVarToArg(const map<string, vector<int>>& commonVarsUsed, const map<string, CommonBlock*>& commonBlocks,
const FuncInfo* curFunc, CallExp* callExp)
{
for (auto& common : commonVarsUsed)
@@ -724,7 +797,7 @@ static void transferCommons(set<FuncInfo*>& allForChange, map <FuncInfo*, map<st
{
SgFunctionCallExp* callExp = (SgFunctionCallExp*)call.first;
if (callExp->funName()->identifier() == precFunc->funcName)
transferVarToArg(commonVarsUsed, commonBlocks, curFunc, callExp);
transferVarToArg(commonVarsUsed, commonBlocks, curFunc, callExp);
}
else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT)
{
@@ -749,7 +822,7 @@ static void transferCommons(set<FuncInfo*>& allForChange, map <FuncInfo*, map<st
if (v == var)
done = true;
if (!done)
if (!done)
{
funcCommons[curFunc][common.first].push_back(var);
if (nextCommonVarsUsed.count(common.first) == 0)
@@ -767,7 +840,7 @@ static void transferCommons(set<FuncInfo*>& allForChange, map <FuncInfo*, map<st
{
bool uses = false;
auto groupedVars = commonBlocks.find(common.first)->second->getGroupedVars();
if (curFunc->commonBlocks.count(common.first) > 0) //rename common vars in funcs
{
uses = true;
@@ -799,7 +872,7 @@ static void transferCommons(set<FuncInfo*>& allForChange, map <FuncInfo*, map<st
}
}
}
}
}
else if (!allForChange.count(curFunc)) //add of commons to main
{
SgExprListExp* res = NULL;
@@ -962,13 +1035,13 @@ void commonTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo, const map
if (func->commonBlocks.size() > 0 && st->variant() != PROG_HEDR)
{
for (SgStatement* start = st, *end = st->lastNodeOfStmt(); start != end;)
for (SgStatement* start = st, *end = st->lastNodeOfStmt(); start != end;)
{
if (start->variant() == CONTAINS_STMT)
break;
SgStatement* next = start->lexNext();
if (start->variant() == COMM_STAT && string(start->fileName()) == func->fileName)
if (start->variant() == COMM_STAT && string(start->fileName()) == func->fileName)
{
if (funcCommonDeclared.count(func) == 0)
funcCommonDeclared[func] = set<string>();
@@ -999,11 +1072,11 @@ void commonTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo, const map
if (st->variant() < 0 || st->variant() == PROG_HEDR || func->isInterface)
continue;
if (func->commonBlocks.size() > 0)
if (func->commonBlocks.size() > 0)
{
map<string, vector<int>> commonVarsUsed;
set<string> usedVars;
for (SgStatement* start = st->lastDeclaration()->lexNext(), *end = st->lastNodeOfStmt(); start != end; start = start->lexNext())
for (SgStatement* start = st->lastDeclaration()->lexNext(), *end = st->lastNodeOfStmt(); start != end; start = start->lexNext())
{
if (start->variant() == CONTAINS_STMT)
break;
@@ -1073,7 +1146,7 @@ static string changeData(const string& data, const map<string, string>& constSym
return res;
}
static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vector <SgSymbol*>& varsToTransfer, vector <string>& dataToTransfer,
static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vector <SgSymbol*>& varsToTransfer, vector <string>& dataToTransfer,
FuncInfo* curFunc, FuncInfo* precFunc, FuncInfo* startFunc)
{
if (curFunc != precFunc)
@@ -1094,7 +1167,7 @@ static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vec
else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT)
{
SgCallStmt* callSt = (SgCallStmt*)call.first;
if (callSt->name()->identifier() == precFunc->funcName)
if (callSt->name()->identifier() == precFunc->funcName)
for (auto& var : varsToTransfer)
callSt->addArg(*new SgVarRefExp(*var));
}
@@ -1120,7 +1193,7 @@ static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vec
{
((SgProcHedrStmt*)(hedr))->AddArg(*new SgVarRefExp(var->copy()));
hedr->lexNext()->deleteStmt();
if (curFunc != startFunc || i!=0)
if (curFunc != startFunc || i!=0)
{
vector<SgSymbol*> varVec = vector<SgSymbol*>();
varVec.push_back(var);
@@ -1160,7 +1233,7 @@ static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vec
for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext())
{
if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && !strcmp(hedr->fileName(), start->fileName()))
if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && !strcmp(hedr->fileName(), start->fileName()))
{
firstExDec = start;
break;
@@ -1199,7 +1272,7 @@ void saveTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
for (auto& byfile : allFuncInfo)
for (auto& func : byfile.second)
if (func->isMain)
start = func;
start = func;
collectForChange(allForChange, start);
allForChange.erase(start);
@@ -1241,8 +1314,8 @@ void saveTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
if (s->scope() == st)
{
if ( (s->attributes() & SAVE_BIT) ||
(s->attributes() & DATA_BIT) ||
if ( (s->attributes() & SAVE_BIT) ||
(s->attributes() & DATA_BIT) ||
allSave && s->variant() == VARIABLE_NAME && !params.count(s->identifier()))
{
if ((s->type() ? s->type()->variant() : (T_COMPLEX + 1)) > T_COMPLEX)
@@ -1293,21 +1366,21 @@ void saveTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
SgExprListExp* attrsNoSave = new SgExprListExp();
bool needChange = false;
for (int i = 0; i < vst->numberOfAttributes(); i++)
for (int i = 0; i < vst->numberOfAttributes(); i++)
{
if (vst->attribute(i)->variant() != SAVE_OP)
{
attrsNoSave->append(vst->attribute(i)->copy());
}
}
else
needChange = true;
needChange = true;
}
if (needChange)
if (needChange)
{
SgVarDeclStmt* newVst;
if (!attrsNoSave->length())
newVst = new SgVarDeclStmt(vst->varList()->copy(), *attrsNoSave, vst->type()->copy());
newVst = new SgVarDeclStmt(vst->varList()->copy(), *attrsNoSave, vst->type()->copy());
else
newVst = new SgVarDeclStmt(vst->varList()->copy(), vst->type()->copy());
@@ -1335,8 +1408,8 @@ void saveTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
}
}*/
static string makeName(SgSymbol* var, map<SgSymbol*, set< SgSymbol*>>& modVarsToAdd, const set<string>& useMod,
const map<string, vector<pair<SgSymbol*, SgSymbol*>>>& modByUse,
static string makeName(SgSymbol* var, map<SgSymbol*, set< SgSymbol*>>& modVarsToAdd, const set<string>& useMod,
const map<string, vector<pair<SgSymbol*, SgSymbol*>>>& modByUse,
const map<string, vector<pair<SgSymbol*, SgSymbol*>>>& modByUseOnly)
{
string name = "", modName = OriginalSymbol(var)->scope()->symbol()->identifier();
@@ -1358,7 +1431,7 @@ static string makeName(SgSymbol* var, map<SgSymbol*, set< SgSymbol*>>& modVarsTo
}
if (!name.length())
name = varOrName;
name = varOrName;
}
else if (mbuo)
{
@@ -1492,7 +1565,7 @@ static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
//insert tabs
const string tab = " ";
const string tab = " ";
const int countEnds = std::count(codeString.begin(), codeString.end(), '\n');
string retVal = " ";
@@ -1584,7 +1657,7 @@ static void createInterfaceBlockForToCalls(FuncInfo* func)
}
}
static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, set<FuncInfo*>& allForChange,
static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, set<FuncInfo*>& allForChange,
vector<SgSymbol*>& varsToTransfer, FuncInfo* curFunc, FuncInfo* precFunc, set<FuncInfo*>& funcForInterfaceAdd)
{
SgStatement* st = curFunc->funcPointer->GetOriginal();
@@ -1636,7 +1709,7 @@ static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, se
else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT)
{
SgCallStmt* callSt = (SgCallStmt*)call.first;
if (callSt->name()->identifier() == precFunc->funcName)
if (callSt->name()->identifier() == precFunc->funcName)
{
for (auto& var : varsToTransfer)
{
@@ -1688,7 +1761,7 @@ static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, se
{
if (i == 0)
curFunc->funcParams.identificators.push_back(var->identifier());
((SgProcHedrStmt*)(hedr))->AddArg(*new SgVarRefExp(var->copy()));
hedr->lexNext()->deleteStmt();
vector<SgSymbol*> varVec = vector<SgSymbol*>();
@@ -1712,7 +1785,7 @@ static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, se
}
}
if (!isAuto)
if (!isAuto)
{
funcForInterfaceAdd.insert(curFunc);
SgAttributeExp* a = new SgAttributeExp(ALLOCATABLE_OP);
@@ -1732,8 +1805,8 @@ static void transferModule(map<FuncInfo*, set<SgSymbol*>>& funcAddedVarsMods, se
SgStatement* firstExDec = NULL;
for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext())
{
if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) &&
!strcmp(hedr->fileName(), start->fileName()))
if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) &&
!strcmp(hedr->fileName(), start->fileName()))
{
firstExDec = start;
break;
@@ -1824,7 +1897,7 @@ void moduleTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
break;
SgStatement* next = start->lexNext();
if (start->variant() == USE_STMT)
if (start->variant() == USE_STMT)
{
SgExpression* onlyE = start->expr(0);
if (onlyE)
@@ -1850,7 +1923,7 @@ void moduleTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
}
if (renameL)
onlyE->setLhs(renameL);
onlyE->setLhs(renameL);
else
start->deleteStmt();
}
@@ -1858,7 +1931,7 @@ void moduleTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
if (isSgExecutableStatement(start)|| isSgDeclarationStatement(start))
for (int i = 0; i < 3; i++)
fillUsedVars(usedVars, start->expr(i));
// if (start->variant() == IMPL_DECL)
// start->deleteStmt();
start = next;

View File

@@ -14,4 +14,6 @@ void commonTransfer(const std::map<std::string, std::vector<FuncInfo*>>& allFunc
void saveTransfer(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
void moduleTransfer(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
void insertInterface(SgStatement* func, const FuncInfo* callFrom);
void insertInterface(SgStatement* func, const FuncInfo* callFrom);
void transformAssumedSizeParameters(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2436"
#define VERSION_SPF "2437"