2265 lines
83 KiB
C++
2265 lines
83 KiB
C++
#include "leak_detector.h"
|
|
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <cstdint>
|
|
|
|
#include <map>
|
|
#include <vector>
|
|
#include <set>
|
|
#include <string>
|
|
|
|
#include "dvm.h"
|
|
#include "graph_calls_func.h"
|
|
#include "SgUtils.h"
|
|
#include "CommonBlock.h"
|
|
#include "DefUseList.h"
|
|
#include "expr_transform.h"
|
|
#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;
|
|
|
|
static bool isIntrincis(const string& name);
|
|
|
|
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;
|
|
|
|
if (!isIntrincis(name))
|
|
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(getNextNegativeLineNumber());
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
|
|
bool checkOutCalls(const set<string>& outCalls)
|
|
{
|
|
for (auto& elem : outCalls)
|
|
if (isIntrinsicFunctionName(elem.c_str()) == 0)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
void createInterfacesForOutCalls(FuncInfo* func)
|
|
{
|
|
if (func->isPure && !func->isMain)
|
|
{
|
|
bool hasOutCalls = checkOutCalls(func->callsFrom);
|
|
if (hasOutCalls)
|
|
DvmhRegionInserter::createInterfaceBlockForOutCalls(func);
|
|
}
|
|
}
|
|
|
|
static bool changeIfHasStarRange(SgExpression* arrayDecl, SgStatement* scope, vector<SgSymbol*>& parNames)
|
|
{
|
|
SgExpression* list = arrayDecl->lhs();
|
|
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;
|
|
|
|
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)
|
|
{
|
|
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();
|
|
}*/
|
|
|
|
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;
|
|
}
|
|
|
|
static bool hasDvmParallel(SgStatement *func)
|
|
{
|
|
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)
|
|
{
|
|
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;
|
|
|
|
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)
|
|
{
|
|
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(), scope, parNames))
|
|
assumedSizeArraysByFunc[func->funcName].push_back(z);
|
|
break;
|
|
}
|
|
list = list->rhs();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (parNames.size())
|
|
{
|
|
SgProcHedrStmt* proc = isSgProcHedrStmt(func->funcPointer->GetOriginal());
|
|
checkNull(proc, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
//makeDeclaration(parNames, scope);
|
|
|
|
for (auto& newPar : parNames)
|
|
proc->AddArg(*new SgVarRefExp(newPar));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (assumedSizeArraysByFunc.size() == 0)
|
|
return;
|
|
|
|
for (auto& funcByFile : allFuncInfo)
|
|
{
|
|
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;
|
|
|
|
for (auto& detailedCall : func->callsFromDetailed)
|
|
{
|
|
auto it = assumedSizeArraysByFunc.find(detailedCall.detailCallsFrom.first);
|
|
if (it != assumedSizeArraysByFunc.end())
|
|
{
|
|
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__);
|
|
|
|
//TODO: need to do it better
|
|
SgExpression* parArray = pars[parNum]->copyPtr();
|
|
parArray->setLhs(NULL);
|
|
parArray->setRhs(NULL);
|
|
|
|
SgFunctionCallExp* call = new SgFunctionCallExp(*funcSize, *parArray);
|
|
|
|
last->setRhs(new SgExpression(EXPR_LIST, call));
|
|
last = last->rhs();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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();
|
|
|
|
if (!hasPure && !hasIO && ((isFunc == false) || (isFunc && hasOut == false)))
|
|
{
|
|
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);
|
|
|
|
for (auto& funcByFile : allFuncInfo)
|
|
for (auto& func : funcByFile.second)
|
|
createInterfacesForOutCalls(func);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static void insertIntents(set<string>& identificators, SgStatement* header, const map<string, SgSymbol*>& parSym, int intentVariant, int intentBit)
|
|
{
|
|
if (identificators.size() == 0)
|
|
return;
|
|
|
|
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;
|
|
|
|
if (stmt->variant() == VAR_DECL_90)
|
|
{
|
|
SgVarDeclStmt* s = (SgVarDeclStmt*)stmt;
|
|
for (int i = 0; i < s->numberOfAttributes(); i++)
|
|
{
|
|
if (s->attribute(i)->variant() == intentVariant)
|
|
{
|
|
for (int i = 0; i < s->numberOfVars(); i++)
|
|
{
|
|
auto sname = s->var(i)->symbol()->identifier();
|
|
if (identificators.count(sname))
|
|
identificators.erase(sname);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (stmt->variant() == INTENT_STMT)
|
|
{
|
|
SgIntentStmt* s = (SgIntentStmt*)stmt;
|
|
if (s->attribute()->variant() == intentVariant)
|
|
{
|
|
for (int i = 0; i < s->numberOfVars(); i++)
|
|
{
|
|
auto sname = s->var(i)->symbol()->identifier();
|
|
if (identificators.count(sname))
|
|
identificators.erase(sname);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SgExpression* attr = new SgExpression(intentVariant);
|
|
vector<SgExpression*> args;
|
|
for (auto& par : identificators)
|
|
{
|
|
if (parSym.count(par) == 0)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
auto s = parSym.at(par);
|
|
args.push_back(new SgVarRefExp(s));
|
|
s->setAttribute(s->attributes() | intentBit);
|
|
}
|
|
|
|
if (args.size())
|
|
{
|
|
SgIntentStmt* intent = new SgIntentStmt(*makeExprList(args), *attr);
|
|
intent->setlineNumber(getNextNegativeLineNumber());
|
|
|
|
lastDecl->insertStmtAfter(*intent, (header == lastDecl) ? *header : *lastDecl->controlParent());
|
|
}
|
|
}
|
|
|
|
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__);
|
|
|
|
if (func->funcPointer->variant() == ENTRY_STAT)
|
|
return;
|
|
|
|
set<string> InIdentificators;
|
|
set<string> OutIdentificators;
|
|
set<string> InOutIdentificators;
|
|
|
|
map<string, SgSymbol*> parSym;
|
|
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();
|
|
|
|
if (ident == "*" || parS->attributes() & EXTERNAL_BIT)
|
|
continue;
|
|
|
|
parSym[ident] = parS;
|
|
if (intentS.find(ident) != intentS.end())
|
|
continue;
|
|
|
|
if (func->funcParams.isArgInOut(i))
|
|
InOutIdentificators.insert(ident);
|
|
else if (func->funcParams.isArgIn(i))
|
|
InIdentificators.insert(ident);
|
|
else if (func->funcParams.isArgOut(i))
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
if (st->variant() == CONTAINS_STMT)
|
|
break;
|
|
|
|
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)
|
|
{
|
|
auto& call = callInfo.pointerDetailCallsFrom;
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
static string changeData(const string& data, const map<string, string>& constSymVars, const map<string, string>& locVars)
|
|
{
|
|
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)
|
|
{
|
|
auto& call = callInfo.pointerDetailCallsFrom;
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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);
|
|
const set<string> idents(pars.identificators.begin(), pars.identificators.end());
|
|
|
|
//remove all exec
|
|
SgStatement* st = copy->lexNext();
|
|
SgStatement* last = copy->lastNodeOfStmt();
|
|
vector<SgStatement*> toExtract;
|
|
|
|
while (st != last)
|
|
{
|
|
if (isDVM_stat(st) || isSPF_stat(st))
|
|
{
|
|
if (st->variant() != ACC_ROUTINE_DIR)
|
|
{
|
|
toExtract.push_back(st);
|
|
st = st->lexNext();
|
|
}
|
|
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)
|
|
{
|
|
const int var = st->variant();
|
|
|
|
if (var == VAR_DECL || var == VAR_DECL_90 || var == DIM_STAT ||
|
|
var == INTENT_STMT || var == EXTERN_STAT)
|
|
{
|
|
bool empty = filterFromList(st, idents);
|
|
if (empty)
|
|
{
|
|
toExtract.push_back(st);
|
|
st = st->lexNext();
|
|
continue;
|
|
}
|
|
}
|
|
else if (!isDVM_stat(st) && !isSPF_stat(st))
|
|
toExtract.push_back(st);
|
|
|
|
if (st->variant() == CONTAINS_STMT)
|
|
break;
|
|
st = st->lexNext();
|
|
}
|
|
|
|
for (auto& elem : toExtract)
|
|
elem->extractStmt();
|
|
|
|
string codeString = copy->unparse();
|
|
|
|
if (SgFile::switchToFile(oldFile) == -1)
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
//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;
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
void insertInterface(SgStatement* func, const FuncInfo *callFrom)
|
|
{
|
|
const string& iface = getInterfaceBlock(callFrom->funcPointer->GetOriginal(), callFrom->funcParams);
|
|
const string& fName = callFrom->funcName;
|
|
|
|
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)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
if (isSgExecutableStatement(st))
|
|
break;
|
|
st = st->lexNext();
|
|
}
|
|
SgStatement* ifaceBlock = new SgStatement(INTERFACE_STMT);
|
|
addControlEndToStmt(ifaceBlock->thebif);
|
|
|
|
ifaceBlock->setlineNumber(getNextNegativeLineNumber());
|
|
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;
|
|
insertInterface(callTo->funcPointer, func);
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
auto& call = callInfo.pointerDetailCallsFrom;
|
|
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);
|
|
}
|
|
|
|
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;
|
|
} |