Files
SAPFOR/src/Transformations/FunctionPurifying/function_purifying.cpp

2200 lines
81 KiB
C++
Raw Normal View History

#include "leak_detector.h"
2023-09-14 19:43:13 +03:00
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <map>
#include <vector>
#include <set>
#include <string>
#include "dvm.h"
2025-06-04 13:08:38 +03:00
#include "graph_calls_func.h"
#include "SgUtils.h"
#include "CommonBlock.h"
#include "DefUseList.h"
#include "expr_transform.h"
2023-09-14 19:43:13 +03:00
#include "../VerificationCode/verifications.h"
#include "../DvmhRegions/DvmhRegionInserter.h"
#include "function_purifying.h"
using std::vector;
using std::map;
using std::set;
using std::pair;
using std::tuple;
using std::string;
using std::wstring;
using std::make_pair;
using std::to_string;
2024-05-03 16:32:39 +03:00
static bool isIntrincis(const string& name);
2024-05-02 11:05:56 +03:00
void insertIntrinsicStat(const vector<FuncInfo*>& allFuncInfo)
{
for (auto& func : allFuncInfo)
{
auto start = func->funcPointer->GetOriginal();
auto end = start->lastNodeOfStmt();
SgStatement* st = start;
SgStatement* intr = NULL;
//find last decl place
for ( ; st != end; st = st->lexNext())
{
if (isSgExecutableStatement(st))
break;
if (st->variant() == CONTAINS_STMT)
break;
if (st->variant() == INTRIN_STAT)
intr = st;
}
map<string, SgSymbol*> intrincis;
for (auto& call : func->callsFromDetailed)
{
auto name = call.detailCallsFrom.first;
if (intrincis.find(name) != intrincis.end())
continue;
2024-05-03 16:32:39 +03:00
if (!isIntrincis(name))
2024-05-02 11:05:56 +03:00
continue;
void* ptr = call.pointerDetailCallsFrom.first;
int var = call.pointerDetailCallsFrom.second;
SgSymbol* s = NULL;
if (var == PROC_STAT)
s = ((SgStatement*)ptr)->symbol();
else if (var == FUNC_CALL)
s = ((SgExpression*)ptr)->symbol();
else
continue;
if ((s->attributes() & INTRINSIC_BIT) != 0)
continue;
intrincis[name] = s;
}
if (!intrincis.size())
continue;
if (intr == NULL)
{
vector<SgExpression*> list;
for (auto& elem : intrincis)
list.push_back(new SgVarRefExp(elem.second));
SgStatement* intr = new SgStatement(INTRIN_STAT);
intr->setExpression(0, makeExprList(list));
auto prev = (st->variant() == FOR_NODE) ? st->lexPrev() : st;
int line = prev->lineNumber();
while (line <= 0 && !isSgProgHedrStmt(prev)) {
prev = prev->lexPrev();
line = prev->lineNumber();
}
if (line <= 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
intr->setlineNumber(line);
2024-05-02 11:05:56 +03:00
st->insertStmtBefore(*intr, *func->funcPointer);
}
else
{
SgExprListExp* list = isSgExprListExp(intr->expr(0));
checkNull(list, convertFileName(__FILE__).c_str(), __LINE__);
for (auto& elem : intrincis)
list->append(*new SgVarRefExp(elem.second));
}
}
}
2023-09-14 19:43:13 +03:00
bool checkOutCalls(const set<string>& outCalls)
{
for (auto& elem : outCalls)
if (isIntrinsicFunctionName(elem.c_str()) == 0)
return true;
return false;
}
2024-05-02 11:05:56 +03:00
void createInterfacesForOutCalls(FuncInfo* func)
{
2023-11-15 13:20:28 +03:00
if (func->isPure && !func->isMain)
{
bool hasOutCalls = checkOutCalls(func->callsFrom);
if (hasOutCalls)
DvmhRegionInserter::createInterfaceBlockForOutCalls(func);
}
}
2024-05-03 16:32:39 +03:00
static bool changeIfHasStarRange(SgExpression* arrayDecl, bool doReplace = false)
2024-05-02 11:05:56 +03:00
{
SgExpression* list = arrayDecl->lhs();
2024-05-03 16:32:39 +03:00
bool has = doReplace;
2024-05-02 11:05:56 +03:00
while (list)
{
2024-05-03 16:32:39 +03:00
const int var = list->lhs()->variant();
if (var == STAR_RANGE)
2024-05-02 11:05:56 +03:00
has = true;
list = list->rhs();
}
if (has)
{
list = arrayDecl->lhs();
while (list)
{
list->setLhs(new SgExpression(DDOT));
list = list->rhs();
}
}
return has;
}
2024-05-03 16:32:39 +03:00
static void removeExternalStat(SgStatement* func, const set<string>& addedInterfaceFor)
{
vector<SgStatement*> toRem;
for (auto st = func; st != func->lastNodeOfStmt(); st = st->lexNext())
{
if (isSgExecutableStatement(st))
break;
if (st->variant() == CONTAINS_STMT)
break;
if (st->variant() == EXTERN_STAT)
{
vector<SgExpression*> list;
SgExpression* ex = st->expr(0);
int count = 0;
while (ex)
{
if (addedInterfaceFor.find(ex->lhs()->symbol()->identifier()) == addedInterfaceFor.end())
list.push_back(ex->lhs());
count++;
ex = ex->rhs();
}
if (count == list.size())
continue;
if (list.size() == 0)
toRem.push_back(st);
else
st->setExpression(0, makeExprList(list, false));
}
}
for (auto& rem : toRem)
rem->deleteStmt();
}
2024-05-22 21:02:04 +03:00
template<typename T>
static vector<FuncInfo*> sortByName(const T &funcs)
{
vector<FuncInfo*> funcList;
for (auto& elem : funcs)
funcList.push_back(elem);
std::sort(funcList.begin(), funcList.end(), [](FuncInfo* a, FuncInfo* b) { return a->funcName > b->funcName; });
return funcList;
}
//XXX: incorrect!!
/*void createInterfacesForAssumedSize(const map<string, vector<FuncInfo*>>& allFuncInfo)
2024-05-02 11:05:56 +03:00
{
set<FuncInfo*> hasAssumedSizeArrays;
for (auto& funcByFile : allFuncInfo)
{
if (SgFile::switchToFile(funcByFile.first) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& func : funcByFile.second)
{
SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal());
if (prog == NULL)
continue;
2024-05-03 16:32:39 +03:00
vector<SgExpression*> arrayRefs;
bool hasRefs = false;
2024-05-02 11:05:56 +03:00
for (int z = 0; z < func->funcParams.countOfPars; ++z)
{
if (func->funcParams.parametersT[z] == ARRAY_T)
{
auto s = prog->parameter(z);
const string name = s->identifier();
vector<SgStatement*> allDecls;
declaratedInStmt(s, &allDecls);
for (auto& decl : allDecls)
{
SgExpression* list = decl->expr(0);
while (list)
{
if (list->lhs() && list->lhs()->symbol()->identifier() == name)
{
if (changeIfHasStarRange(list->lhs()))
2024-05-03 16:32:39 +03:00
{
hasRefs = true;
2024-05-02 11:05:56 +03:00
hasAssumedSizeArrays.insert(func);
2024-05-03 16:32:39 +03:00
}
else
arrayRefs.push_back(list->lhs());
2024-05-02 11:05:56 +03:00
break;
}
list = list->rhs();
}
}
}
}
2024-05-03 16:32:39 +03:00
if (hasRefs)
for (auto& ref : arrayRefs)
changeIfHasStarRange(ref, true);
2024-05-02 11:05:56 +03:00
}
}
if (hasAssumedSizeArrays.size() == 0)
return;
for (auto& funcByFile : allFuncInfo)
{
if (SgFile::switchToFile(funcByFile.first) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
2024-05-22 21:02:04 +03:00
for (auto& func : sortByName(funcByFile.second))
2024-05-02 11:05:56 +03:00
{
2024-05-03 16:32:39 +03:00
SgProgHedrStmt* prog = isSgProgHedrStmt(func->funcPointer->GetOriginal());
if (prog == NULL)
continue;
set<string> addedInterfaceFor;
2024-05-22 21:02:04 +03:00
for (auto& elem : sortByName(func->callsFromV))
2024-05-02 11:05:56 +03:00
{
auto it = hasAssumedSizeArrays.find(elem);
if (it != hasAssumedSizeArrays.end())
{
auto callFrom = *it;
DvmhRegionInserter::createInterfaceBlockForOutCall(func, callFrom);
2024-05-03 16:32:39 +03:00
addedInterfaceFor.insert(callFrom->funcName);
2024-05-02 11:05:56 +03:00
}
}
2024-05-03 16:32:39 +03:00
if (addedInterfaceFor.size())
removeExternalStat(prog, addedInterfaceFor);
}
2024-05-02 11:05:56 +03:00
}
}*/
2024-05-02 11:05:56 +03:00
2023-09-14 19:43:13 +03:00
static void setPureStatus(FuncInfo* func)
{
if (func->isPure && !func->isMain)
{
SgStatement* header = func->funcPointer->GetOriginal();
if (header->switchToFile() == false)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
bool isFunc = (header->variant() == FUNC_HEDR);
bool hasOut = false;
for (int z = 0; z < func->funcParams.countOfPars; ++z)
hasOut |= func->funcParams.isArgOut(z);
bool hasPure = (header->expr(2) != NULL) || ((header->symbol()->attributes() & PURE_BIT) != 0);
bool hasIO = func->linesOfIO.size() || func->linesOfStop.size();
2023-11-15 13:20:28 +03:00
if (!hasPure && !hasIO && ((isFunc == false) || (isFunc && hasOut == false)))
{
2023-09-14 19:43:13 +03:00
header->setExpression(2, new SgExpression(PURE_OP));
header->symbol()->setAttribute(header->symbol()->attributes() | PURE_BIT);
}
}
}
void setPureStatus(const set<FuncInfo*>& funcInfo)
{
for (auto& func : funcInfo)
setPureStatus(func);
}
void setPureStatus(const map<string, vector<FuncInfo*>>& allFuncInfo)
{
for (auto& funcByFile : allFuncInfo)
for (auto& func : funcByFile.second)
setPureStatus(func);
2023-11-15 13:20:28 +03:00
for (auto& funcByFile : allFuncInfo)
for (auto& func : funcByFile.second)
createInterfacesForOutCalls(func);
2023-09-14 19:43:13 +03:00
}
map<SgStatement*, set<string>> fillFromIntent(SgStatement* header)
{
map<SgStatement*, set<string>> intentS;
if (header->variant() == ENTRY_STAT)
while (isSgProgHedrStmt(header) == NULL)
header = header->controlParent();
SgStatement* last = header->lastNodeOfStmt();
for (auto stmt = header->lexNext(); stmt && stmt != last; stmt = stmt->lexNext())
{
if (stmt->variant() == CONTAINS_STMT)
break;
if (isSgExecutableStatement(stmt))
break;
if (stmt->variant() == INTENT_STMT)
{
SgIntentStmt* s = (SgIntentStmt*)stmt;
for (int i = 0; i < s->numberOfVars(); i++)
intentS[s].insert(s->var(i)->symbol()->identifier());
}
else
{
//check intent in decl
SgExpression* ex = stmt->expr(2);
bool containsIntent = false;
while (ex)
{
if (ex->lhs())
{
int var = ex->lhs()->variant();
if (var == IN_OP || var == INOUT_OP || var == OUT_OP)
containsIntent = true;
}
ex = ex->rhs();
}
if (containsIntent)
{
SgExpression* ex = stmt->expr(0);
while (ex)
{
if (ex->lhs() && ex->lhs()->symbol())
intentS[stmt].insert(ex->lhs()->symbol()->identifier());
ex = ex->rhs();
}
}
}
}
return intentS;
}
2024-05-12 13:37:42 +03:00
static void insertIntents(set<string>& identificators, SgStatement* header, const map<string, SgSymbol*>& parSym, int intentVariant, int intentBit)
2023-09-14 19:43:13 +03:00
{
2024-05-12 13:37:42 +03:00
if (identificators.size() == 0)
return;
2023-09-14 19:43:13 +03:00
if (header->variant() == ENTRY_STAT)
while (isSgProgHedrStmt(header) == NULL)
header = header->controlParent();
SgStatement* last = header->lastNodeOfStmt();
SgStatement* lastDecl = header;
for (auto stmt = header->lexNext(); stmt && stmt != last; stmt = stmt->lexNext())
{
if (stmt->variant() == CONTAINS_STMT)
break;
if (isSgExecutableStatement(stmt))
break;
if (stmt->variant() != ENTRY_STAT)
lastDecl = stmt;
2024-05-12 13:37:42 +03:00
if (stmt->variant() == VAR_DECL_90)
2023-09-14 19:43:13 +03:00
{
SgVarDeclStmt* s = (SgVarDeclStmt*)stmt;
2024-05-12 13:37:42 +03:00
for (int i = 0; i < s->numberOfAttributes(); i++)
2023-09-14 19:43:13 +03:00
{
if (s->attribute(i)->variant() == intentVariant)
{
2024-05-12 13:37:42 +03:00
for (int i = 0; i < s->numberOfVars(); i++)
2023-09-14 19:43:13 +03:00
{
2024-05-12 13:37:42 +03:00
auto sname = s->var(i)->symbol()->identifier();
if (identificators.count(sname))
identificators.erase(sname);
2023-09-14 19:43:13 +03:00
}
}
}
}
2024-05-12 13:37:42 +03:00
else if (stmt->variant() == INTENT_STMT)
2023-09-14 19:43:13 +03:00
{
SgIntentStmt* s = (SgIntentStmt*)stmt;
2024-05-12 13:37:42 +03:00
if (s->attribute()->variant() == intentVariant)
2023-09-14 19:43:13 +03:00
{
2024-05-12 13:37:42 +03:00
for (int i = 0; i < s->numberOfVars(); i++)
2023-09-14 19:43:13 +03:00
{
2024-05-12 13:37:42 +03:00
auto sname = s->var(i)->symbol()->identifier();
if (identificators.count(sname))
identificators.erase(sname);
2023-09-14 19:43:13 +03:00
}
}
}
}
2024-05-12 13:37:42 +03:00
SgExpression* attr = new SgExpression(intentVariant);
2024-05-25 17:41:28 +03:00
vector<SgExpression*> args;
2024-05-12 13:37:42 +03:00
for (auto& par : identificators)
2023-09-14 19:43:13 +03:00
{
2024-05-12 13:37:42 +03:00
if (parSym.count(par) == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
2023-09-14 19:43:13 +03:00
2024-05-25 17:41:28 +03:00
auto s = parSym.at(par);
args.push_back(new SgVarRefExp(s));
2024-05-12 13:37:42 +03:00
s->setAttribute(s->attributes() | intentBit);
}
2024-05-25 17:41:28 +03:00
if (args.size())
2024-05-12 13:37:42 +03:00
{
2024-05-25 17:41:28 +03:00
SgIntentStmt* intent = new SgIntentStmt(*makeExprList(args), *attr);
intent->setlineNumber(lastDecl->lineNumber());
2024-05-12 13:37:42 +03:00
lastDecl->insertStmtAfter(*intent, (header == lastDecl) ? *header : *lastDecl->controlParent());
2023-09-14 19:43:13 +03:00
}
}
static SgSymbol* getParameter(SgStatement* stat, int n)
{
SgSymbol* retVal = NULL;
auto funcStat = isSgProgHedrStmt(stat);
if (funcStat)
retVal = funcStat->parameter(n);
else if (stat->variant() == ENTRY_STAT)
{
SgExpression* list = stat->expr(0);
while (n != 0)
{
--n;
list = list->rhs();
}
retVal = list->lhs()->symbol();
}
checkNull(retVal, convertFileName(__FILE__).c_str(), __LINE__);
return retVal;
}
static void intentInsert(const FuncInfo* func, SgStatement* headerSt)
{
if (func == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
2024-05-12 13:37:42 +03:00
if (func->funcPointer->variant() == ENTRY_STAT)
return;
2023-09-14 19:43:13 +03:00
2024-05-12 13:37:42 +03:00
set<string> InIdentificators;
set<string> OutIdentificators;
set<string> InOutIdentificators;
map<string, SgSymbol*> parSym;
2023-09-14 19:43:13 +03:00
set<string> intentS;
auto intentsByStat = fillFromIntent(headerSt);
for (auto& elem : intentsByStat)
intentS.insert(elem.second.begin(), elem.second.end());
intentS.insert(func->callsFrom.begin(), func->callsFrom.end());
for (int i = 0; i < func->funcParams.countOfPars; i++)
{
SgSymbol* parS = getParameter(headerSt, i);
const string ident = parS->identifier();
2024-05-12 13:37:42 +03:00
if (ident == "*" || parS->attributes() & EXTERNAL_BIT)
2023-09-14 19:43:13 +03:00
continue;
parSym[ident] = parS;
if (intentS.find(ident) != intentS.end())
continue;
if (func->funcParams.isArgInOut(i))
2024-05-12 13:37:42 +03:00
InOutIdentificators.insert(ident);
2023-09-14 19:43:13 +03:00
else if (func->funcParams.isArgIn(i))
2024-05-12 13:37:42 +03:00
InIdentificators.insert(ident);
2023-09-14 19:43:13 +03:00
else if (func->funcParams.isArgOut(i))
2024-05-12 13:37:42 +03:00
OutIdentificators.insert(ident);
}
//remove conflicted intents
for (auto& entry : func->entry)
{
for (int i = 0; i < entry->funcParams.countOfPars; i++)
{
const auto& ident = entry->funcParams.identificators[i];
if (entry->funcParams.isArgInOut(i))
{
if (InIdentificators.count(ident))
InIdentificators.erase(ident);
if (OutIdentificators.count(ident))
OutIdentificators.erase(ident);
}
else if (entry->funcParams.isArgIn(i))
{
if (InOutIdentificators.count(ident))
InOutIdentificators.erase(ident);
if (OutIdentificators.count(ident))
OutIdentificators.erase(ident);
}
else if (entry->funcParams.isArgOut(i))
{
if (InIdentificators.count(ident))
InIdentificators.erase(ident);
if (InOutIdentificators.count(ident))
InOutIdentificators.erase(ident);
}
}
2023-09-14 19:43:13 +03:00
}
insertIntents(InOutIdentificators, headerSt, parSym, INOUT_OP, INOUT_BIT);
insertIntents(InIdentificators, headerSt, parSym, IN_OP, IN_BIT);
insertIntents(OutIdentificators, headerSt, parSym, OUT_OP, OUT_BIT);
}
void intentInsert(const vector<FuncInfo*>& allFuncInfo)
{
for (auto& func : allFuncInfo)
{
if (func->isMain)
continue;
intentInsert(func, func->funcPointer->GetOriginal());
}
}
void intentInsertToInterfaces(const map<string, vector<FuncInfo*>>& allFuncInfo)
{
for (auto& funcByFile : allFuncInfo)
{
if (SgFile::switchToFile(funcByFile.first) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& func : funcByFile.second)
{
if (func->interfaceBlocks.size() == 0)
continue;
auto start = func->funcPointer->GetOriginal();
auto end = start->lastNodeOfStmt();
for (auto st = start; st != end; st = st->lexNext())
{
if (isSgExecutableStatement(st))
break;
2024-05-02 11:05:56 +03:00
if (st->variant() == CONTAINS_STMT)
break;
2023-09-14 19:43:13 +03:00
if (st->controlParent()->variant() == INTERFACE_STMT)
{
if (st->variant() == PROC_HEDR || st->variant() == FUNC_HEDR)
{
auto it = func->interfaceBlocks.find(st->symbol()->identifier());
if (it == func->interfaceBlocks.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
intentInsert(it->second, st);
}
}
}
}
}
}
//DEBUG
/*static void printcvu(map<string, vector<int>>& commonVarsUsed)
{
for (auto& common : commonVarsUsed)
{
printf(">%s\n", common.first.c_str());
for (int posVar : common.second)
printf("\t%d\n", posVar);
}
}*/
static void collectForChange(set<FuncInfo*>& allForChange, FuncInfo* start)
{
allForChange.insert(start);
bool chagned = true;
while (chagned)
{
set<FuncInfo*> newAdd;
for (auto& elem : allForChange)
for (auto& call : elem->callsFromV)
if (allForChange.find(call) == allForChange.end())
newAdd.insert(call);
chagned = newAdd.size() != 0;
allForChange.insert(newAdd.begin(), newAdd.end());
}
}
template<typename CallExp>
static void transferVarToArg(const map<string, vector<int>>& commonVarsUsed, const map<string, CommonBlock*>& commonBlocks,
const FuncInfo* curFunc, CallExp* callExp)
{
for (auto& common : commonVarsUsed)
{
for (auto& posVar : common.second)
{
const Variable* var = commonBlocks.find(common.first)->second->getGroupedVars().find(posVar)->second[0];
string name = "";
if (curFunc->isMain && curFunc->commonBlocks.count(common.first) > 0)
{
for (auto& v : commonBlocks.find(common.first)->second->getVariables(curFunc->fileName, curFunc->funcName))
{
if (v->getPosition() == posVar)
{
name = v->getName();
break;
}
}
}
else if ((int)(string(var->getName()).find("c_" + common.first + "_")) < 0)
name = "c_" + common.first + "_" + var->getName();
else
name = var->getName();
SgSymbol* s = new SgSymbol(var->getSymbol()->variant(), name.c_str());
callExp->addArg(*new SgVarRefExp(*s));
}
}
}
static void findInterfaces(FuncInfo* func, vector<SgStatement*>& ifaces)
{
for (auto& callFunc : func->callsTo)
{
SgStatement* iface = NULL;
if (callFunc->interfaceBlocks.find(func->funcName) != callFunc->interfaceBlocks.end())
{
SgStatement* hedr = callFunc->funcPointer->GetOriginal();
for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext())
{
if (start->variant() == INTERFACE_STMT)
{
for (int i = 0; i < start->numberOfChildrenList1(); i++)
{
if ((isSgProgHedrStmt(start->childList1(i))) && start->childList1(i)->symbol()->identifier() == func->funcName)
{
iface = start->childList1(i);
break;
}
}
}
if (iface)
{
ifaces.push_back(iface);
break;
}
}
}
}
}
static void transferCommons(set<FuncInfo*>& allForChange, map <FuncInfo*, map<string, vector<int>>>& funcCommons, map<string, vector<int>>& commonVarsUsed,
FuncInfo* curFunc, FuncInfo* precFunc, const map<string, CommonBlock*>& commonBlocks, map<FuncInfo*, set<string>>& funcCommonDeclared)
{
if (commonVarsUsed.empty())
return;
if (funcCommons.count(curFunc) == 0)
funcCommons[curFunc] = map<string, vector<int>>();
//add params to calls
if (curFunc != precFunc)
{
if (SgFile::switchToFile(curFunc->fileName) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& callInfo : curFunc->callsFromDetailed)
2023-09-14 19:43:13 +03:00
{
auto& call = callInfo.pointerDetailCallsFrom;
2023-09-14 19:43:13 +03:00
if (isSgFuncHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == FUNC_CALL)
{
SgFunctionCallExp* callExp = (SgFunctionCallExp*)call.first;
if (callExp->funName()->identifier() == precFunc->funcName)
transferVarToArg(commonVarsUsed, commonBlocks, curFunc, callExp);
}
else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT)
{
SgCallStmt* callSt = (SgCallStmt*)call.first;
if (callSt->name()->identifier() == precFunc->funcName)
transferVarToArg(commonVarsUsed, commonBlocks, curFunc, callSt);
}
}
}
map<string, vector<int>> nextCommonVarsUsed;
//find the things we have already done
for (auto& common : commonVarsUsed)
{
if (funcCommons[curFunc].count(common.first) == 0)
funcCommons[curFunc][common.first] = vector<int>();
for (auto& var : common.second)
{
bool done = false;
for (auto& v : funcCommons[curFunc][common.first])
if (v == var)
done = true;
if (!done)
{
funcCommons[curFunc][common.first].push_back(var);
if (nextCommonVarsUsed.count(common.first) == 0)
nextCommonVarsUsed[common.first] = vector<int>();
nextCommonVarsUsed[common.first].push_back(var);
}
}
}
vector<SgStatement*> ifaces;
ifaces.push_back(curFunc->funcPointer->GetOriginal());
findInterfaces(curFunc, ifaces);
for (auto& common : nextCommonVarsUsed)
{
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;
const vector<const Variable*>& vars = commonBlocks.find(common.first)->second->getVariables(curFunc->fileName, curFunc->funcName);
if (allForChange.count(curFunc))
{
for (auto& var : vars)
{
bool contains = false;
for (auto& v : common.second)
if (v == var->getPosition())
contains = true;
if (contains)
{
for (auto& varUse : var->getAllUse())
{
if (varUse.getFileName() == curFunc->fileName && varUse.getFunctionName() == curFunc->funcName)
{
string name;
if ((int)(string(groupedVars[var->getPosition()][0]->getName()).find("c_" + common.first + "_")) < 0)
name = "c_" + common.first + "_" + groupedVars[var->getPosition()][0]->getName();
else
name = groupedVars[var->getPosition()][0]->getName();
varUse.getUseS()->changeName(name.c_str());
break;
}
}
}
}
}
}
else if (!allForChange.count(curFunc)) //add of commons to main
{
SgExprListExp* res = NULL;
vector <SgSymbol*> varsToDeclare = vector <SgSymbol*>();
for (auto it = groupedVars.rbegin(); it != groupedVars.rend(); it++)
{
string name;
if ((int)(string(it->second[0]->getName()).find("c_" + common.first + "_")) < 0)
name = "c_" + common.first + "_" + it->second[0]->getName();
else
name = it->second[0]->getName();
SgSymbol* symb = it->second[0]->getSymbol();
SgType* type = symb->type();
SgSymbol* s = new SgSymbol(symb->variant(), name.c_str(), type, curFunc->funcPointer);
SgVarRefExp* vr = new SgVarRefExp(s);
SgExprListExp* el = new SgExprListExp();
el->setLhs(vr);
el->setRhs(res);
res = el;
varsToDeclare.push_back(s);
}
SgSymbol* commSymb = new SgSymbol(VARIABLE_NAME, common.first.c_str());
SgExprListExp* commList = new SgExprListExp(COMM_LIST);
SgStatement* commStat = new SgStatement(COMM_STAT);
commStat->setExpression(0, *commList);
commList->setSymbol(commSymb);
commList->setLhs(res);
SgStatement* firstExDec, * hedr = curFunc->funcPointer->GetOriginal();
for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext())
{
if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && !strcmp(hedr->fileName(), start->fileName())) {
firstExDec = start;
break;
}
}
commStat->setlineNumber(firstExDec->lineNumber());
firstExDec->insertStmtBefore(*commStat, *(hedr));
for (auto& var : varsToDeclare)
{
vector<SgSymbol*> varVec = vector<SgSymbol*>();
varVec.push_back(var);
SgStatement* decl = makeDeclaration(NULL, varVec);
for (int i = 0; i < 3; i++)
{
SgExpression* e;
if (e = decl->expr(i))
decl->setExpression(i, CalculateInteger(ReplaceConstant(e)));
}
decl->setlineNumber(firstExDec->lineNumber());
decl->setFileName(hedr->fileName());
commStat->insertStmtAfter(*decl, *(hedr));
}
}
//parametrs add
if (allForChange.count(curFunc))
{
for (int i = 0; i < ifaces.size(); i++) {
for (auto& posVar : common.second)
{
const Variable* var = commonBlocks.find(common.first)->second->getGroupedVars().find(posVar)->second[0];
SgSymbol* symb = var->getSymbol();
string name;
if ((int)(string(symb->identifier()).find("c_" + common.first + "_")) < 0)
name = "c_" + common.first + "_" + var->getSymbol()->identifier();
else
name = symb->identifier();
SgSymbol* s = new SgSymbol(symb->variant(), name.c_str(), symb->type(), ifaces[i]);
SgStatement* hedr = ifaces[i];
SgExpression* result = hedr->expr(0) == NULL ? NULL : hedr->expr(0)->copyPtr();
if (isSgFuncHedrStmt(hedr))
isSgFuncHedrStmt(hedr)->AddArg(*new SgVarRefExp(s));
else if (isSgProcHedrStmt(hedr))
isSgProcHedrStmt(hedr)->AddArg(*new SgVarRefExp(s));
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (result == NULL)
{
if (hedr->expr(0) != NULL)
hedr->setExpression(0, NULL);
}
else
{
if (hedr->expr(0) != NULL)
hedr->setExpression(0, result);
else if (string(hedr->expr(0)->unparse()) != result->unparse())
hedr->setExpression(0, result);
}
curFunc->funcPointer->GetOriginal()->lexNext()->deleteStmt();
if (!funcCommonDeclared[curFunc].count(common.first) || i!=0)
{
vector<SgSymbol*> varVec = vector<SgSymbol*>();
varVec.push_back(s);
SgStatement* decl = makeDeclaration(NULL, varVec);
for (int i = 0; i < 3; i++)
{
SgExpression* e;
if (e = decl->expr(i))
decl->setExpression(i, CalculateInteger(ReplaceConstant(e)));
}
SgStatement* firstExDec;
for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext())
{
if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && !strcmp(hedr->fileName(), start->fileName())) {
firstExDec = start;
break;
}
}
decl->setlineNumber(firstExDec->lineNumber());
decl->setFileName(hedr->fileName());
firstExDec->insertStmtBefore(*decl, *(hedr));
}
}
}
}
}
for (auto& callFunc : curFunc->callsTo)
transferCommons(allForChange, funcCommons, nextCommonVarsUsed, callFunc, curFunc, commonBlocks, funcCommonDeclared);
}
static void fillUsedVars(set<string>& usedVars, SgExpression* exp)
{
if (exp)
{
if (exp->variant() == VAR_REF || exp->variant() == ARRAY_REF)
usedVars.insert(exp->symbol()->identifier());
fillUsedVars(usedVars, exp->lhs());
fillUsedVars(usedVars, exp->rhs());
}
}
void commonTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo, const map<string, CommonBlock*>& commonBlocks)
{
map <FuncInfo*, map<string, vector<int>>> funcCommons;
map <FuncInfo*, set<string>> funcCommonDeclared;
FuncInfo* start = NULL;
set<FuncInfo*> allForChange;
for (auto& byfile : allFuncInfo)
{
if (SgFile::switchToFile(byfile.first) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& func : byfile.second)
{
SgStatement* st = func->funcPointer->GetOriginal();
if (st->variant() < 0 || func->isInterface)
continue;
if (func->commonBlocks.size() > 0 && st->variant() != PROG_HEDR)
{
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 (funcCommonDeclared.count(func) == 0)
funcCommonDeclared[func] = set<string>();
for (SgExpression* e = start->expr(0); e; e = e->rhs())
funcCommonDeclared[func].insert(e->symbol() ? e->symbol()->identifier() : "spf_unnamed");
start->deleteStmt();
}
start = next;
}
}
if (func->isMain)
start = func;
}
}
checkNull(start, convertFileName(__FILE__).c_str(), __LINE__);
collectForChange(allForChange, start);
allForChange.erase(start);
for (auto& func : allForChange)
{
if (SgFile::switchToFile(func->fileName) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* st = func->funcPointer->GetOriginal();
if (st->variant() < 0 || st->variant() == PROG_HEDR || func->isInterface)
continue;
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())
{
if (start->variant() == CONTAINS_STMT)
break;
if (isSgExecutableStatement(start))
for (int i = 0; i < 3; i++)
fillUsedVars(usedVars, start->expr(i));
}
for (auto& var : usedVars)
{
for (auto& common : func->commonBlocks)
{
const string name = common.first;
if (common.second.count(var) > 0)
{
if (commonVarsUsed.count(common.first) == 0)
commonVarsUsed[name] = vector<int>();
for (auto& cvar : commonBlocks.find(name)->second->getVariables(func->fileName, func->funcName))
if (cvar->getName() == var)
commonVarsUsed[name].push_back(cvar->getPosition());
}
}
}
transferCommons(allForChange, funcCommons, commonVarsUsed, func, func, commonBlocks, funcCommonDeclared);
}
}
}
2024-05-14 12:53:31 +03:00
static string changeData(const string& data, const map<string, string>& constSymVars, const map<string, string>& locVars)
2023-09-14 19:43:13 +03:00
{
int curChar = 0;
string ident = "";
string res = "";
while (curChar < data.length())
{
switch (data[curChar])
{
case ' ':
case ',':
case ')':
case '(':
case '=':
case '*':
case '/':
case '\n':
case '\t':
if (ident.size() > 0)
{
if (constSymVars.count(ident) > 0)
res += constSymVars.at(ident);
else if (locVars.count(ident) > 0)
res += locVars.at(ident);
else
res += ident;
ident = "";
}
res += tolower(data[curChar]);
curChar++;
break;
default:
ident += tolower(data[curChar]);
curChar++;
break;
}
}
return res;
}
static void transferSave(map<FuncInfo*, set<FuncInfo*>>& funcAddedVarsFuncs, vector <SgSymbol*>& varsToTransfer, vector <string>& dataToTransfer,
FuncInfo* curFunc, FuncInfo* precFunc, FuncInfo* startFunc)
{
if (curFunc != precFunc)
{
if (SgFile::switchToFile(curFunc->fileName) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& callInfo : curFunc->callsFromDetailed)
2023-09-14 19:43:13 +03:00
{
auto& call = callInfo.pointerDetailCallsFrom;
2023-09-14 19:43:13 +03:00
if (isSgFuncHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == FUNC_CALL)
{
SgFunctionCallExp* callExp = (SgFunctionCallExp*)call.first;
if (callExp->funName()->identifier() == precFunc->funcName)
for (auto& var : varsToTransfer)
callExp->addArg(*new SgVarRefExp(*var));
}
else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT)
{
SgCallStmt* callSt = (SgCallStmt*)call.first;
if (callSt->name()->identifier() == precFunc->funcName)
for (auto& var : varsToTransfer)
callSt->addArg(*new SgVarRefExp(*var));
}
}
}
if (!funcAddedVarsFuncs.count(curFunc))
funcAddedVarsFuncs[curFunc] = set<FuncInfo*>();
else if (funcAddedVarsFuncs[curFunc].count(startFunc))
return;
vector<SgStatement*> ifaces;
ifaces.push_back(curFunc->funcPointer->GetOriginal());
findInterfaces(curFunc, ifaces);
funcAddedVarsFuncs[curFunc].insert(startFunc);
if (!curFunc->isMain)
{
for (int i = 0; i < ifaces.size(); i++)
{
SgStatement* hedr = ifaces[i];
for (auto& var : varsToTransfer)
{
((SgProcHedrStmt*)(hedr))->AddArg(*new SgVarRefExp(var->copy()));
hedr->lexNext()->deleteStmt();
if (curFunc != startFunc || i!=0)
{
vector<SgSymbol*> varVec = vector<SgSymbol*>();
varVec.push_back(var);
SgStatement* decl = makeDeclaration(NULL, varVec);
for (int i = 0; i < 3; i++)
{
SgExpression* e;
if (e = decl->expr(i))
decl->setExpression(i, CalculateInteger(ReplaceConstant(e)));
}
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()))
{
firstExDec = start;
break;
}
}
checkNull(firstExDec, convertFileName(__FILE__).c_str(), __LINE__);
decl->setlineNumber(firstExDec->lineNumber());
decl->setFileName(hedr->fileName());
firstExDec->insertStmtBefore(*decl, *(hedr));
}
}
}
for (auto& callFunc : curFunc->callsTo)
transferSave(funcAddedVarsFuncs, varsToTransfer, dataToTransfer, callFunc, curFunc, startFunc);
}
else
{
SgStatement* firstExDec = NULL;
auto hedr = curFunc->funcPointer->GetOriginal();
for (SgStatement* start = hedr->lexNext(), *end = hedr->lastNodeOfStmt(); start != end; start = start->lexNext())
{
if ((isSgExecutableStatement(start) || isSgDeclarationStatement(start)) && !strcmp(hedr->fileName(), start->fileName()))
{
firstExDec = start;
break;
}
}
checkNull(firstExDec, convertFileName(__FILE__).c_str(), __LINE__);
for (auto& var : varsToTransfer)
{
vector<SgSymbol*> varVec = vector<SgSymbol*>();
varVec.push_back(var);
SgStatement* decl = makeDeclaration(NULL, varVec);
for (int i = 0; i < 3; i++)
{
SgExpression* e;
if (e = decl->expr(i))
decl->setExpression(i, CalculateInteger(ReplaceConstant(e)));
}
decl->setlineNumber(firstExDec->lineNumber());
decl->setFileName(hedr->fileName());
firstExDec->insertStmtBefore(*decl, *(hedr));
}
for (auto& data : dataToTransfer)
firstExDec->addComment(data.c_str());
}
}
void saveTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
{
FuncInfo* start = NULL;
set<FuncInfo*> allForChange;
map<FuncInfo*, set<FuncInfo*>> funcAddedVarsFuncs;
for (auto& byfile : allFuncInfo)
for (auto& func : byfile.second)
if (func->isMain)
start = func;
collectForChange(allForChange, start);
allForChange.erase(start);
for (auto& func : allForChange)
{
if (SgFile::switchToFile(func->fileName) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* st = func->funcPointer->GetOriginal();
vector <SgSymbol*> varsToTransfer;
vector <string> dataToTransfer;
map<SgSymbol*, SgExpression*> varInit;
map<string, string> constSymVars;
map <string, string> locVars;
set <string> params;
bool hasComplType = false;
SgStatement* lst = st->lastNodeOfStmt();
SgSymbol* s, * sl;
bool allSave = false;
for (SgStatement* start = st, *end = lst; start != end; start = start->lexNext())
{
if (start->variant() == CONTAINS_STMT)
break;
if (start->variant() == SAVE_DECL && !start->expr(0))
allSave = true;
}
for (auto& s : func->funcParams.identificators)
params.insert(s);
sl = lst->lexNext() ? lst->lexNext()->symbol() : NULL;
for (s = st->symbol(); s != sl && s != NULL; s = s->next())
{
SgConstantSymb* sc = isSgConstantSymb(s);
if (sc && sc->constantValue())
constSymVars[string(s->identifier())] = string(sc->constantValue()->unparse());
if (s->scope() == st)
{
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)
{
hasComplType = true;
break;
}
string newName = "s_" + func->funcName + "_" + s->identifier();
locVars[s->identifier()] = newName;
s->changeName(newName.c_str());
varsToTransfer.push_back(s);
}
}
}
if (hasComplType)
continue;
for (SgStatement* start = st, *end = lst; start != end;)
{
SgStatement* next = start->lexNext();
if (strcmp(start->fileName(), st->fileName()))
{
start = next;
continue;
}
if (start->variant() == DATA_DECL)
{
dataToTransfer.push_back(changeData(start->sunparse(), constSymVars, locVars));
start->deleteStmt();
}
else if (start->variant() == SAVE_DECL)
start->deleteStmt();
else if (start->variant() == VAR_DECL || start->variant() == VAR_DECL_90)
{
SgVarDeclStmt* vst = (SgVarDeclStmt*)start;
for (int i = 0; i < vst->numberOfVars(); i++)
{
if (vst->initialValue(i))
{
string data = " data " + vst->var(i)->lhs()->sunparse() + " / " + vst->initialValue(i)->sunparse() + " / \n";
dataToTransfer.push_back(changeData(data, constSymVars, locVars));
vst->clearInitialValue(i);
}
}
SgExprListExp* attrsNoSave = new SgExprListExp();
bool needChange = false;
for (int i = 0; i < vst->numberOfAttributes(); i++)
{
if (vst->attribute(i)->variant() != SAVE_OP)
{
attrsNoSave->append(vst->attribute(i)->copy());
}
else
needChange = true;
}
if (needChange)
{
SgVarDeclStmt* newVst;
if (!attrsNoSave->length())
newVst = new SgVarDeclStmt(vst->varList()->copy(), *attrsNoSave, vst->type()->copy());
else
newVst = new SgVarDeclStmt(vst->varList()->copy(), vst->type()->copy());
newVst->setlineNumber(vst->lineNumber());
newVst->setComments(vst->comments());
vst->replaceWithStmt(*newVst);
}
}
start = next;
}
if (varsToTransfer.size())
transferSave(funcAddedVarsFuncs, varsToTransfer, dataToTransfer, func, func, func);
}
}
//DEBUG
/*static void printmbu(map<string, vector<pair<SgSymbol*, SgSymbol*>>> modByUse)
{
for (auto& mod : modByUse)
{
printf("|%s| \n", mod.first.c_str());
for (auto& var : mod.second)
printf("\t%s => %s\n", var.first->identifier(), var.second->identifier());
}
}*/
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();
SgSymbol* modS = OriginalSymbol(var)->scope()->symbol();
string varOrName = OriginalSymbol(var)->identifier();
size_t um = useMod.count(modName), mbu = modByUse.count(modName), mbuo = modByUseOnly.count(modName);
if (um && !mbu && !mbuo)
name = varOrName;
else if (mbu)
{
for (auto& elem : modByUse.at(modName))
{
if ((elem.second ? elem.second : elem.first)->identifier() == varOrName)
{
name = elem.first->identifier();
break;
}
}
if (!name.length())
name = varOrName;
}
else if (mbuo)
{
for (auto& elem : modByUseOnly.at(modName))
{
if ((elem.second ? elem.second : elem.first)->identifier() == varOrName)
{
name = elem.first->identifier();
break;
}
}
if (!name.length())
{
name = "m_" + modName + "_" + varOrName;
if (!modVarsToAdd.count(modS))
modVarsToAdd[modS] = set<SgSymbol*>();
modVarsToAdd[modS].insert(OriginalSymbol(var));
}
}
else
{
name = "m_" + modName + "_" + varOrName;
if (!modVarsToAdd.count(modS))
modVarsToAdd[modS] = set<SgSymbol*>();
modVarsToAdd[modS].insert(OriginalSymbol(var));
}
return name;
}
2025-07-05 20:49:23 +03:00
static bool filterFromList(SgStatement* st, const set<string>& idents, bool exclude = false)
{
bool empty = false;
SgExpression* list = st->expr(0);
vector<SgExpression*> newList;
int total = 0;
while (list)
{
if (exclude)
{
if (idents.find(list->lhs()->symbol()->identifier()) == idents.end())
newList.push_back(list->lhs());
}
else
{
if (idents.find(list->lhs()->symbol()->identifier()) != idents.end())
newList.push_back(list->lhs());
}
total++;
list = list->rhs();
}
if (newList.size() == 0)
empty = true;
else if (total != newList.size())
st->setExpression(0, makeExprList(newList));
return empty;
}
2023-09-14 19:43:13 +03:00
static string getInterfaceBlock(SgStatement* func, const FuncParam& pars)
{
string oldFile = current_file->filename();
if (!func->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto copy = duplicateProcedure(func, NULL, false, false, false, true);
2025-07-05 20:49:23 +03:00
const set<string> idents(pars.identificators.begin(), pars.identificators.end());
2023-09-14 19:43:13 +03:00
//remove all exec
SgStatement* st = copy->lexNext();
SgStatement* last = copy->lastNodeOfStmt();
vector<SgStatement*> toExtract;
2025-07-05 20:49:23 +03:00
2023-09-14 19:43:13 +03:00
while (st != last)
{
if (isDVM_stat(st) || isSPF_stat(st))
{
if (st->variant() != ACC_ROUTINE_DIR)
{
2025-07-05 20:49:23 +03:00
toExtract.push_back(st);
st = st->lexNext();
2023-09-14 19:43:13 +03:00
}
else
st = st->lexNext();
}
else if (isSgExecutableStatement(st))
{
SgStatement* next = st->lastNodeOfStmt();
if (next != last)
next = next->lexNext();
toExtract.push_back(st);
st = next;
}
else
st = st->lexNext();
}
//remove unused declarations
st = copy->lexNext();
while (st != last)
{
2025-07-05 20:49:23 +03:00
const int var = st->variant();
2023-09-14 19:43:13 +03:00
2025-07-05 20:49:23 +03:00
if (var == VAR_DECL || var == VAR_DECL_90 || var == DIM_STAT ||
var == INTENT_STMT || var == EXTERN_STAT)
{
bool empty = filterFromList(st, idents);
if (empty)
2023-09-14 19:43:13 +03:00
{
toExtract.push_back(st);
2025-07-05 20:49:23 +03:00
st = st->lexNext();
2023-09-14 19:43:13 +03:00
continue;
}
}
2025-07-05 20:49:23 +03:00
else if (!isDVM_stat(st) && !isSPF_stat(st))
2023-09-14 19:43:13 +03:00
toExtract.push_back(st);
if (st->variant() == CONTAINS_STMT)
break;
st = st->lexNext();
}
for (auto& elem : toExtract)
elem->extractStmt();
2025-07-05 20:49:23 +03:00
string codeString = copy->unparse();
2023-09-14 19:43:13 +03:00
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
2025-07-05 20:49:23 +03:00
//insert tabs
const string tab = " ";
const int countEnds = std::count(codeString.begin(), codeString.end(), '\n');
string retVal = " ";
retVal.reserve(retVal.size() + codeString.size() + countEnds * tab.size());
for (int z = 0, ends = 0; z < codeString.size(); ++z)
{
retVal += codeString[z];
if (codeString[z] == '\n')
{
ends++;
if (ends == countEnds)
continue;
int p = z + 1;
while (codeString[p] == ' ' && p < codeString.size())
++p;
auto start = p;
auto end = string::npos;
auto sub = codeString.find("subroutine", p);
auto func = codeString.find("function", p);
auto end_sub = codeString.find("end subroutine", p);
auto end_func = codeString.find("end function", p);
if (sub != end && sub == start || end_sub != end && end_sub == start ||
func != end && func == start || end_func != end && end_func == start)
{
retVal += " ";
}
else
retVal += tab;
}
}
2023-09-14 19:43:13 +03:00
return retVal;
}
2025-07-05 20:49:23 +03:00
void insertInterface(SgStatement* func, const FuncInfo *callFrom)
2023-09-14 19:43:13 +03:00
{
2025-07-05 20:49:23 +03:00
const string& iface = getInterfaceBlock(callFrom->funcPointer->GetOriginal(), callFrom->funcParams);
const string& fName = callFrom->funcName;
2023-09-14 19:43:13 +03:00
string oldFile = current_file->filename();
if (!func->switchToFile())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* st = func->lexNext();
SgStatement* last = func->lastNodeOfStmt();
while (st != last)
{
2025-07-05 20:49:23 +03:00
if (st->variant() == VAR_DECL || st->variant() == VAR_DECL_90)
{
bool empty = filterFromList(st, { fName }, true);
if (empty)
{
SgStatement* next = st->lexNext();
st->extractStmt();
st = next;
continue;
}
}
2023-09-14 19:43:13 +03:00
if (isSgExecutableStatement(st))
break;
st = st->lexNext();
}
SgStatement* ifaceBlock = new SgStatement(INTERFACE_STMT);
addControlEndToStmt(ifaceBlock->thebif);
2025-07-05 20:49:23 +03:00
ifaceBlock->setlineNumber(getNextNegativeLineNumber());
2023-09-14 19:43:13 +03:00
ifaceBlock->setFileName(st->fileName());
st->insertStmtBefore(*ifaceBlock, *st->controlParent());
ifaceBlock->lastNodeOfStmt()->addComment(iface.c_str());
if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
static void createInterfaceBlockForToCalls(FuncInfo* func)
{
for (auto& callTo : func->callsTo)
{
if (callTo->interfaceBlocks.find(func->funcName) == callTo->interfaceBlocks.end())
{
callTo->interfaceBlocks[func->funcName] = func;
2025-07-05 20:49:23 +03:00
insertInterface(callTo->funcPointer, func);
2023-09-14 19:43:13 +03:00
}
}
}
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();
map<SgSymbol*, set< SgSymbol*>> modVarsToAdd;
if (curFunc != precFunc)
{
if (SgFile::switchToFile(curFunc->fileName) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
set<string> useMod;
map<string, vector<pair<SgSymbol*, SgSymbol*>>> modByUse;
map<string, vector<pair<SgSymbol*, SgSymbol*>>> modByUseOnly;
if (!allForChange.count(curFunc))
{
for (SgStatement* start = st; start != st->lastNodeOfStmt(); start = start->lexNext())
{
if (isSgExecutableStatement(start))
break;
if (start->variant() == CONTAINS_STMT)
break;
if (start != st && (start->variant() == PROC_HEDR || start->variant() == FUNC_HEDR))
break;
fillUseStatement(start, useMod, modByUse, modByUseOnly);
}
}
for (auto& callInfo : curFunc->callsFromDetailed)
2023-09-14 19:43:13 +03:00
{
auto& call = callInfo.pointerDetailCallsFrom;
2023-09-14 19:43:13 +03:00
if (isSgFuncHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == FUNC_CALL)
{
SgFunctionCallExp* callExp = (SgFunctionCallExp*)call.first;
if (callExp->funName()->identifier() == precFunc->funcName)
{
for (auto& var : varsToTransfer)
{
if (allForChange.count(curFunc))
callExp->addArg(*new SgVarRefExp(*var));
else
{
string name = makeName(var, modVarsToAdd, useMod, modByUse, modByUseOnly);
SgSymbol* s = new SgSymbol(VARIABLE_NAME, name.c_str());
callExp->addArg(*new SgVarRefExp(*s));
}
}
}
}
else if (isSgProcHedrStmt(precFunc->funcPointer->GetOriginal()) && call.second == PROC_STAT)
{
SgCallStmt* callSt = (SgCallStmt*)call.first;
if (callSt->name()->identifier() == precFunc->funcName)
{
for (auto& var : varsToTransfer)
{
if (allForChange.count(curFunc))
callSt->addArg(*new SgVarRefExp(*var));
else
{
string name = makeName(var, modVarsToAdd, useMod, modByUse, modByUseOnly);
SgSymbol* s = new SgSymbol(VARIABLE_NAME, name.c_str());
callSt->addArg(*new SgVarRefExp(*s));
}
}
}
}
}
}
map<SgSymbol*, set< SgSymbol*>> modVarsNeedToAdd;
vector <SgSymbol*> nextVarsToTransfer;
if (!funcAddedVarsMods.count(curFunc))
funcAddedVarsMods[curFunc] = set<SgSymbol*>();
for (auto& var : varsToTransfer)
{
if (!funcAddedVarsMods[curFunc].count(OriginalSymbol(var)))
{
SgSymbol* modS = OriginalSymbol(var)->scope()->symbol();
if (modVarsToAdd.count(modS) && modVarsToAdd[modS].count(OriginalSymbol(var)))
{
if (!modVarsNeedToAdd.count(modS))
modVarsNeedToAdd[modS] = set< SgSymbol*>();
modVarsNeedToAdd[modS].insert(OriginalSymbol(var));
}
nextVarsToTransfer.push_back(var);
funcAddedVarsMods[curFunc].insert(OriginalSymbol(var));
}
}
vector<SgStatement*> ifaces;
ifaces.push_back(curFunc->funcPointer->GetOriginal());
findInterfaces(curFunc, ifaces);
if (allForChange.count(curFunc))
{
for (int i = 0; i < ifaces.size(); i++)
{
SgStatement* hedr = ifaces[i];
for (auto& var : nextVarsToTransfer)
{
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*>();
varVec.push_back(var);
SgStatement* decl = makeDeclaration(NULL, varVec);
/*TODO:: add some other*/
if (var->attributes() && ALLOCATABLE_BIT)
{
bool isAuto = false;
if (decl->expr(0)->lhs()->variant() == ARRAY_REF && decl->expr(0)->lhs()->lhs())
{
for (SgExpression* e = decl->expr(0)->lhs()->lhs(); e; e = e->rhs())
{
if (e->lhs()->variant() == DDOT && (e->lhs()->rhs() || e->lhs()->lhs()) ||
e->lhs()->variant() != DDOT)
{
isAuto = true;
break;
}
}
}
if (!isAuto)
{
funcForInterfaceAdd.insert(curFunc);
SgAttributeExp* a = new SgAttributeExp(ALLOCATABLE_OP);
SgExprListExp* l = new SgExprListExp();
l->setLhs(a);
((SgVarDeclStmt*)decl)->addAttributeExpression(a);
}
}
for (int i = 0; i < 3; i++)
{
SgExpression* e;
if (e = decl->expr(i))
decl->setExpression(i, CalculateInteger(ReplaceConstant(e)));
}
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()))
{
firstExDec = start;
break;
}
}
checkNull(firstExDec, convertFileName(__FILE__).c_str(), __LINE__);
decl->setlineNumber(firstExDec->lineNumber());
decl->setFileName(hedr->fileName());
firstExDec->insertStmtBefore(*decl, *(hedr));
}
}
for (auto& callFunc : curFunc->callsTo)
transferModule(funcAddedVarsMods, allForChange, nextVarsToTransfer, callFunc, curFunc, funcForInterfaceAdd);
}
else
{
for (auto& mod : modVarsNeedToAdd)
{
SgSymbol modS = mod.first->copy();
SgExpression* onlyE = new SgExpression(ONLY_NODE);
SgExprListExp* renameL = NULL;
for (auto& var : mod.second)
{
string name = "m_" + string(modS.identifier()) + "_" + var->identifier();
SgSymbol varS = SgSymbol(VARIABLE_NAME, name.c_str());
SgExprListExp* el = new SgExprListExp();
SgVarRefExp* nvr = new SgVarRefExp(varS), * vr = new SgVarRefExp(var);
SgExpression* renameE = new SgExpression(RENAME_NODE, nvr, vr);
el->setLhs(renameE);
el->setRhs(renameL);
renameL = el;
}
onlyE->setLhs(renameL);
SgStatement* useSt = new SgStatement(USE_STMT);
useSt->setSymbol(modS);
useSt->setExpression(0, onlyE);
st->insertStmtAfter(*useSt, *st);
}
}
}
static void fillUsedVars(set<SgSymbol*>& usedVars, SgExpression* exp)
{
if (exp)
{
if (exp->variant() == VAR_REF || exp->variant() == ARRAY_REF)
usedVars.insert(exp->symbol());
fillUsedVars(usedVars, exp->lhs());
fillUsedVars(usedVars, exp->rhs());
}
}
void moduleTransfer(const map<string, vector<FuncInfo*>>& allFuncInfo)
{
FuncInfo* start = NULL;
set<FuncInfo*> allForChange;
map<FuncInfo*, set<SgSymbol*>> funcAddedVarsMods;
set<FuncInfo*> funcForInterfaceAdd;
for (auto& byfile : allFuncInfo)
{
for (auto& func : byfile.second)
if (func->isMain)
start = func;
}
collectForChange(allForChange, start);
allForChange.erase(start);
for (auto& func : allForChange)
{
if (SgFile::switchToFile(func->fileName) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgStatement* st = func->funcPointer->GetOriginal();
vector <SgSymbol*> varsToTransfer;
map <string, string> locVars;
SgStatement* lst = st->lastNodeOfStmt();
SgSymbol* s, * sl;
bool allSave = false;
set< SgSymbol*> usedVars;
for (SgStatement* start = st->lexNext(), *end = st->lastNodeOfStmt(); start != end;)
{
if (start->variant() == CONTAINS_STMT)
break;
SgStatement* next = start->lexNext();
if (start->variant() == USE_STMT)
{
SgExpression* onlyE = start->expr(0);
if (onlyE)
{
SgExprListExp* renameL = NULL;
for (SgExpression* ex = onlyE->lhs(); ex; ex = ex->rhs())
{
if (ex->lhs()->variant() == RENAME_NODE)
{
SgSymbol* left = NULL, *right = NULL;
if (ex->lhs()->lhs()->symbol())
left = ex->lhs()->lhs()->symbol();
if (ex->lhs()->rhs() && ex->lhs()->rhs()->symbol())
right = ex->lhs()->rhs()->symbol();
if (!(right && (right->variant() == VARIABLE_NAME) || left && (left->variant() == VARIABLE_NAME)))
{
SgExprListExp* el = new SgExprListExp();
el->setLhs(ex->lhs());
el->setRhs(renameL);
renameL = el;
}
}
}
if (renameL)
onlyE->setLhs(renameL);
else
start->deleteStmt();
}
}
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;
}
sl = lst->lexNext() ? lst->lexNext()->symbol() : NULL;
for (s = st->symbol(); s != sl && s != NULL; s = s->next())
{
if (OriginalSymbol(s)->scope()->variant() == MODULE_STMT && (s->variant() == VARIABLE_NAME) && usedVars.count(s))
{
string newName = "m_" + string(OriginalSymbol(s)->scope()->symbol()->identifier()) + "_" + OriginalSymbol(s)->identifier();
locVars[s->identifier()] = newName;
s->changeName(newName.c_str());
varsToTransfer.push_back(s);
}
}
transferModule(funcAddedVarsMods, allForChange, varsToTransfer, func, func, funcForInterfaceAdd);
}
for (auto& func : funcForInterfaceAdd)
createInterfaceBlockForToCalls(func);
}
2024-05-03 16:32:39 +03:00
static bool isIntrincis(const string& name)
{
static set<string> intrinsicF;
if (intrinsicF.size() == 0)
{
intrinsicF.insert(string("abs"));
intrinsicF.insert(string("adjustl"));
intrinsicF.insert(string("and"));
intrinsicF.insert(string("any"));
intrinsicF.insert(string("associated"));
intrinsicF.insert(string("allocated"));
intrinsicF.insert(string("amod"));
intrinsicF.insert(string("aimax0"));
intrinsicF.insert(string("ajmax0"));
intrinsicF.insert(string("akmax0"));
intrinsicF.insert(string("aimin0"));
intrinsicF.insert(string("ajmin0"));
intrinsicF.insert(string("akmin0"));
intrinsicF.insert(string("amax1"));
intrinsicF.insert(string("amax0"));
intrinsicF.insert(string("amin1"));
intrinsicF.insert(string("amin0"));
intrinsicF.insert(string("aimag"));
intrinsicF.insert(string("alog"));
intrinsicF.insert(string("alog10"));
intrinsicF.insert(string("asin"));
intrinsicF.insert(string("asind"));
intrinsicF.insert(string("asinh"));
intrinsicF.insert(string("acos"));
intrinsicF.insert(string("acosd"));
intrinsicF.insert(string("acosh"));
intrinsicF.insert(string("atan"));
intrinsicF.insert(string("atand"));
intrinsicF.insert(string("atanh"));
intrinsicF.insert(string("atan2"));
intrinsicF.insert(string("atan2d"));
intrinsicF.insert(string("aint"));
intrinsicF.insert(string("anint"));
intrinsicF.insert(string("achar"));
intrinsicF.insert(string("babs"));
intrinsicF.insert(string("bbits"));
intrinsicF.insert(string("bbset"));
intrinsicF.insert(string("bdim"));
intrinsicF.insert(string("biand"));
intrinsicF.insert(string("bieor"));
intrinsicF.insert(string("bior"));
intrinsicF.insert(string("bixor"));
intrinsicF.insert(string("btest"));
intrinsicF.insert(string("bbtest"));
intrinsicF.insert(string("bbclr"));
intrinsicF.insert(string("bitest"));
intrinsicF.insert(string("bjtest"));
intrinsicF.insert(string("bktest"));
intrinsicF.insert(string("bessel_j0"));
intrinsicF.insert(string("bessel_j1"));
intrinsicF.insert(string("bessel_jn"));
intrinsicF.insert(string("bessel_y0"));
intrinsicF.insert(string("bessel_y1"));
intrinsicF.insert(string("bessel_yn"));
intrinsicF.insert(string("bmod"));
intrinsicF.insert(string("bnot"));
intrinsicF.insert(string("bshft"));
intrinsicF.insert(string("bshftc"));
intrinsicF.insert(string("bsign"));
intrinsicF.insert(string("cos"));
intrinsicF.insert(string("ccos"));
intrinsicF.insert(string("cdcos"));
intrinsicF.insert(string("cosd"));
intrinsicF.insert(string("cosh"));
intrinsicF.insert(string("cotan"));
intrinsicF.insert(string("cotand"));
intrinsicF.insert(string("ceiling"));
intrinsicF.insert(string("cexp"));
intrinsicF.insert(string("conjg"));
intrinsicF.insert(string("csqrt"));
intrinsicF.insert(string("clog"));
intrinsicF.insert(string("clog10"));
intrinsicF.insert(string("cdlog"));
intrinsicF.insert(string("cdlog10"));
intrinsicF.insert(string("csin"));
intrinsicF.insert(string("cabs"));
intrinsicF.insert(string("cdabs"));
intrinsicF.insert(string("cdexp"));
intrinsicF.insert(string("cdsin"));
intrinsicF.insert(string("cdsqrt"));
intrinsicF.insert(string("cdtan"));
intrinsicF.insert(string("cmplx"));
intrinsicF.insert(string("char"));
intrinsicF.insert(string("ctan"));
intrinsicF.insert(string("cpu_time"));
intrinsicF.insert(string("dim"));
intrinsicF.insert(string("ddim"));
intrinsicF.insert(string("dble"));
intrinsicF.insert(string("dfloat"));
intrinsicF.insert(string("dfloti"));
intrinsicF.insert(string("dflotj"));
intrinsicF.insert(string("dflotk"));
intrinsicF.insert(string("dint"));
intrinsicF.insert(string("dmax1"));
intrinsicF.insert(string("dmin1"));
intrinsicF.insert(string("dmod"));
intrinsicF.insert(string("dprod"));
intrinsicF.insert(string("dreal"));
intrinsicF.insert(string("dsign"));
intrinsicF.insert(string("dshiftl"));
intrinsicF.insert(string("dshiftr"));
intrinsicF.insert(string("dabs"));
intrinsicF.insert(string("dsqrt"));
intrinsicF.insert(string("dexp"));
intrinsicF.insert(string("dlog"));
intrinsicF.insert(string("dlog10"));
intrinsicF.insert(string("dsin"));
intrinsicF.insert(string("dcos"));
intrinsicF.insert(string("dcosd"));
intrinsicF.insert(string("dtan"));
intrinsicF.insert(string("dtand"));
intrinsicF.insert(string("dasin"));
intrinsicF.insert(string("dasind"));
intrinsicF.insert(string("dasinh"));
intrinsicF.insert(string("dacos"));
intrinsicF.insert(string("dacosd"));
intrinsicF.insert(string("dacosh"));
intrinsicF.insert(string("datan"));
intrinsicF.insert(string("datand"));
intrinsicF.insert(string("datanh"));
intrinsicF.insert(string("datan2"));
intrinsicF.insert(string("datan2d"));
intrinsicF.insert(string("derf"));
intrinsicF.insert(string("derfc"));
intrinsicF.insert(string("dsind"));
intrinsicF.insert(string("dsinh"));
intrinsicF.insert(string("dcosh"));
intrinsicF.insert(string("dcotan"));
intrinsicF.insert(string("dcotand"));
intrinsicF.insert(string("dtanh"));
intrinsicF.insert(string("dnint"));
intrinsicF.insert(string("dcmplx"));
intrinsicF.insert(string("dconjg"));
intrinsicF.insert(string("dimag"));
intrinsicF.insert(string("exp"));
intrinsicF.insert(string("erf"));
intrinsicF.insert(string("erfc"));
intrinsicF.insert(string("erfc_scaled"));
intrinsicF.insert(string("etime"));
intrinsicF.insert(string("float"));
intrinsicF.insert(string("floati"));
intrinsicF.insert(string("floatj"));
intrinsicF.insert(string("floatk"));
intrinsicF.insert(string("floor"));
intrinsicF.insert(string("flush"));
intrinsicF.insert(string("gamma"));
intrinsicF.insert(string("habs"));
intrinsicF.insert(string("hbclr"));
intrinsicF.insert(string("hbits"));
intrinsicF.insert(string("hbset"));
intrinsicF.insert(string("hdim"));
intrinsicF.insert(string("hiand"));
intrinsicF.insert(string("hieor"));
intrinsicF.insert(string("hior"));
intrinsicF.insert(string("hixor"));
intrinsicF.insert(string("hmod"));
intrinsicF.insert(string("hnot"));
intrinsicF.insert(string("hshft"));
intrinsicF.insert(string("hshftc"));
intrinsicF.insert(string("hsign"));
intrinsicF.insert(string("htest"));
intrinsicF.insert(string("huge"));
intrinsicF.insert(string("hypot"));
intrinsicF.insert(string("iiabs"));
intrinsicF.insert(string("iargc"));
intrinsicF.insert(string("iiand"));
intrinsicF.insert(string("iibclr"));
intrinsicF.insert(string("iibits"));
intrinsicF.insert(string("iibset"));
intrinsicF.insert(string("iidim"));
intrinsicF.insert(string("iieor"));
intrinsicF.insert(string("iior"));
intrinsicF.insert(string("iishft"));
intrinsicF.insert(string("iishftc"));
intrinsicF.insert(string("iisign"));
intrinsicF.insert(string("iixor"));
intrinsicF.insert(string("int"));
intrinsicF.insert(string("idint"));
intrinsicF.insert(string("ifix"));
intrinsicF.insert(string("idim"));
intrinsicF.insert(string("isign"));
intrinsicF.insert(string("index"));
intrinsicF.insert(string("iabs"));
intrinsicF.insert(string("ibits"));
intrinsicF.insert(string("idnint"));
intrinsicF.insert(string("ichar"));
intrinsicF.insert(string("iachar"));
intrinsicF.insert(string("isnan"));
intrinsicF.insert(string("iand"));
intrinsicF.insert(string("ior"));
intrinsicF.insert(string("ibset"));
intrinsicF.insert(string("ibclr"));
intrinsicF.insert(string("ibchng"));
intrinsicF.insert(string("ieor"));
intrinsicF.insert(string("ilen"));
intrinsicF.insert(string("imag"));
intrinsicF.insert(string("imax0"));
intrinsicF.insert(string("imax1"));
intrinsicF.insert(string("imin0"));
intrinsicF.insert(string("imin1"));
intrinsicF.insert(string("imod"));
intrinsicF.insert(string("inot"));
intrinsicF.insert(string("isha"));
intrinsicF.insert(string("ishc"));
intrinsicF.insert(string("ishft"));
intrinsicF.insert(string("ishftc"));
intrinsicF.insert(string("ishl"));
intrinsicF.insert(string("ixor"));
intrinsicF.insert(string("jiabs"));
intrinsicF.insert(string("jiand"));
intrinsicF.insert(string("jibclr"));
intrinsicF.insert(string("jibits"));
intrinsicF.insert(string("jibset"));
intrinsicF.insert(string("jidim"));
intrinsicF.insert(string("jieor"));
intrinsicF.insert(string("jior"));
intrinsicF.insert(string("jishft"));
intrinsicF.insert(string("jishftc"));
intrinsicF.insert(string("jisign"));
intrinsicF.insert(string("jixor"));
intrinsicF.insert(string("jmax0"));
intrinsicF.insert(string("jmax1"));
intrinsicF.insert(string("jmin0"));
intrinsicF.insert(string("jmin1"));
intrinsicF.insert(string("jmod"));
intrinsicF.insert(string("jnot"));
intrinsicF.insert(string("kiabs"));
intrinsicF.insert(string("kiand"));
intrinsicF.insert(string("kibclr"));
intrinsicF.insert(string("kibits"));
intrinsicF.insert(string("kibset"));
intrinsicF.insert(string("kidim"));
intrinsicF.insert(string("kieor"));
intrinsicF.insert(string("kior"));
intrinsicF.insert(string("kishft"));
intrinsicF.insert(string("kishftc"));
intrinsicF.insert(string("kisign"));
intrinsicF.insert(string("kmax0"));
intrinsicF.insert(string("kmax1"));
intrinsicF.insert(string("kmin0"));
intrinsicF.insert(string("kmin1"));
intrinsicF.insert(string("kmod"));
intrinsicF.insert(string("knot"));
intrinsicF.insert(string("len"));
intrinsicF.insert(string("len_trim"));
intrinsicF.insert(string("lge"));
intrinsicF.insert(string("lgt"));
intrinsicF.insert(string("lle"));
intrinsicF.insert(string("llt"));
intrinsicF.insert(string("log_gamma"));
intrinsicF.insert(string("log"));
intrinsicF.insert(string("log10"));
intrinsicF.insert(string("lshft"));
intrinsicF.insert(string("lshift"));
intrinsicF.insert(string("max"));
intrinsicF.insert(string("max0"));
intrinsicF.insert(string("max1"));
intrinsicF.insert(string("merge_bits"));
intrinsicF.insert(string("min"));
intrinsicF.insert(string("minval"));
intrinsicF.insert(string("maxval"));
intrinsicF.insert(string("min0"));
intrinsicF.insert(string("min1"));
intrinsicF.insert(string("mod"));
intrinsicF.insert(string("modulo"));
intrinsicF.insert(string("not"));
intrinsicF.insert(string("nint"));
intrinsicF.insert(string("null"));
intrinsicF.insert(string("or"));
intrinsicF.insert(string("popcnt"));
intrinsicF.insert(string("poppar"));
intrinsicF.insert(string("random_number"));
intrinsicF.insert(string("real"));
intrinsicF.insert(string("reshape"));
intrinsicF.insert(string("present"));
intrinsicF.insert(string("repeat"));
intrinsicF.insert(string("rshft"));
intrinsicF.insert(string("rshift"));
intrinsicF.insert(string("sign"));
intrinsicF.insert(string("size"));
intrinsicF.insert(string("scan"));
intrinsicF.insert(string("sizeof"));
intrinsicF.insert(string("sngl"));
intrinsicF.insert(string("sqrt"));
intrinsicF.insert(string("sin"));
intrinsicF.insert(string("sind"));
intrinsicF.insert(string("sinh"));
intrinsicF.insert(string("shifta"));
intrinsicF.insert(string("shiftl"));
intrinsicF.insert(string("shiftr"));
intrinsicF.insert(string("sum"));
intrinsicF.insert(string("tan"));
intrinsicF.insert(string("tand"));
intrinsicF.insert(string("tanh"));
intrinsicF.insert(string("tiny"));
intrinsicF.insert(string("trailz"));
intrinsicF.insert(string("trim"));
intrinsicF.insert(string("xor"));
intrinsicF.insert(string("zabs"));
intrinsicF.insert(string("zcos"));
intrinsicF.insert(string("zexp"));
intrinsicF.insert(string("zlog"));
intrinsicF.insert(string("zsin"));
intrinsicF.insert(string("zsqrt"));
intrinsicF.insert(string("ztan"));
}
if (intrinsicF.find(name) != intrinsicF.end())
return true;
return false;
}