2025-06-02 19:08:09 +03:00
|
|
|
|
#include "leak_detector.h"
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include <map>
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
|
|
#include "dvm.h"
|
|
|
|
|
|
#include "../Utils/errors.h"
|
|
|
|
|
|
#include "../Utils/utils.h"
|
|
|
|
|
|
#include "../Utils/SgUtils.h"
|
|
|
|
|
|
#include "../GraphCall/graph_calls_func.h"
|
|
|
|
|
|
#include "inliner.h"
|
|
|
|
|
|
#include "../VisualizerCalls/SendMessage.h"
|
2025-06-02 19:08:09 +03:00
|
|
|
|
#include "expr_transform.h"
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
using std::set;
|
|
|
|
|
|
using std::map;
|
|
|
|
|
|
using std::vector;
|
|
|
|
|
|
using std::pair;
|
|
|
|
|
|
using std::make_pair;
|
|
|
|
|
|
using std::string;
|
|
|
|
|
|
using std::wstring;
|
|
|
|
|
|
using std::to_string;
|
2023-11-26 18:57:05 +03:00
|
|
|
|
using std::get;
|
|
|
|
|
|
using std::tuple;
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
#define DEB 0
|
|
|
|
|
|
|
|
|
|
|
|
extern map<string, vector<SgStatement*>> hiddenData;
|
|
|
|
|
|
|
|
|
|
|
|
static map<SgSymbol*, SgSymbol*> linkToOrig;
|
|
|
|
|
|
static map<pair<string, int>, map<string, SgSymbol*>> createdByFunc; // key == <funcName, fileID>
|
|
|
|
|
|
static map<string, int> createdVarCounterByName;
|
|
|
|
|
|
static map<pair<string, int>, map<string, pair<SgSymbol*, string>>> replacedConstRef; // key == <funcName, fileID>
|
|
|
|
|
|
static map<pair<string, int>, set<SgValueExp*>> dataDeclsByFunc; // key == <funcName, fileID>
|
|
|
|
|
|
static map<pair<string, int>, map<string, SgExpression*>> dataDeclsByFuncS; // key == <funcName, fileID>
|
|
|
|
|
|
|
|
|
|
|
|
struct PointCall
|
|
|
|
|
|
{
|
|
|
|
|
|
private:
|
|
|
|
|
|
bool findChainCall(FuncInfo* call, int lvl, vector<string>& str, const string& toFind) const
|
|
|
|
|
|
{
|
|
|
|
|
|
bool found = false;
|
|
|
|
|
|
if (lvl == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& elem : call->callsFromV)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (elem->funcName == toFind)
|
|
|
|
|
|
{
|
|
|
|
|
|
str.push_back(elem->funcName);
|
|
|
|
|
|
found = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& elem : call->callsFromV)
|
|
|
|
|
|
{
|
|
|
|
|
|
str.push_back(elem->funcName);
|
|
|
|
|
|
found = findChainCall(elem, lvl - 1, str, toFind);
|
|
|
|
|
|
if (found)
|
|
|
|
|
|
break;
|
|
|
|
|
|
else
|
|
|
|
|
|
str.pop_back();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return found;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
pair<string, int> mainPoint;
|
|
|
|
|
|
FuncInfo *func;
|
|
|
|
|
|
string currCall;
|
|
|
|
|
|
int currLvl;
|
|
|
|
|
|
|
|
|
|
|
|
string getChainCall() const
|
|
|
|
|
|
{
|
|
|
|
|
|
string str = func->funcName;
|
|
|
|
|
|
if (currLvl)
|
|
|
|
|
|
{
|
|
|
|
|
|
vector<string> chain;
|
|
|
|
|
|
findChainCall(func, currLvl - 1, chain, currCall);
|
|
|
|
|
|
if (chain.size() != currLvl)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
for (int z = 0; z < chain.size(); ++z)
|
|
|
|
|
|
str += "->" + chain[z];
|
|
|
|
|
|
}
|
|
|
|
|
|
return str;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void checkSymbols(const int currFileId, const set<SgSymbol*>& symbs)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& symb : symbs)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (symb->getFileId() != currFileId)
|
|
|
|
|
|
{
|
2023-11-28 12:58:22 +03:00
|
|
|
|
__spf_print(1, "check failed - given %d, correct %d\n", symb->getFileId(), currFileId);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static map<string, SgExpression*> createMapOfArgs(SgStatement* tempHedr, SgExpression* actualArgs)
|
|
|
|
|
|
{
|
2023-11-28 12:58:22 +03:00
|
|
|
|
__spf_print(DEB, "------create map of vars------\n");
|
|
|
|
|
|
|
|
|
|
|
|
SgProgHedrStmt* hedr = isSgProgHedrStmt(tempHedr);
|
|
|
|
|
|
checkNull(hedr, convertFileName(__FILE__).c_str(), __LINE__);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
2023-11-28 12:58:22 +03:00
|
|
|
|
int numPars = hedr->numberOfParameters();
|
|
|
|
|
|
map<string, SgExpression*> vars;
|
2023-09-14 19:43:13 +03:00
|
|
|
|
int i = 0;
|
|
|
|
|
|
while (actualArgs)
|
|
|
|
|
|
{
|
2023-11-28 12:58:22 +03:00
|
|
|
|
if (i >= numPars)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
auto actualArg = actualArgs->lhs();
|
2023-11-28 12:58:22 +03:00
|
|
|
|
auto formalArg = hedr->parameter(i++);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
auto it = vars.find(formalArg->identifier());
|
|
|
|
|
|
if (it == vars.end())
|
|
|
|
|
|
vars.insert(it, make_pair(formalArg->identifier(), actualArg));
|
|
|
|
|
|
else
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
actualArgs = actualArgs->rhs();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return vars;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-23 13:04:46 +03:00
|
|
|
|
static bool isAllocated(SgSymbol* s)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (s->attributes() & ALLOCATABLE_BIT) || (s->attributes() & POINTER_BIT);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
static inline SgSymbol* createSymbAndDecl(const string& funcName, const string& varName, SgSymbol* newS, set<SgSymbol*>& newSymbols, SgType* type = NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgSymbol* original = newS;
|
|
|
|
|
|
if (newS)
|
|
|
|
|
|
newS = &newS->copy();
|
|
|
|
|
|
|
|
|
|
|
|
int* count;
|
|
|
|
|
|
if (createdVarCounterByName.find(varName) == createdVarCounterByName.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
createdVarCounterByName[varName] = 0;
|
|
|
|
|
|
count = &createdVarCounterByName[varName];
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
count = &createdVarCounterByName[varName];
|
|
|
|
|
|
|
|
|
|
|
|
const string base = varName + "_";
|
|
|
|
|
|
int nextCount = checkSymbNameAndCorrect(base, count[0]);
|
|
|
|
|
|
const string newName = base + to_string(nextCount);
|
|
|
|
|
|
|
|
|
|
|
|
const pair<string, int> key = make_pair(funcName, current_file_id);
|
|
|
|
|
|
if (newS)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isSgConstantSymb(newS))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (funcName != "null" && createdByFunc[key].find(varName) == createdByFunc[key].end() ||
|
|
|
|
|
|
funcName == "null")
|
|
|
|
|
|
{
|
|
|
|
|
|
auto it = replacedConstRef[key].find(newS->identifier());
|
|
|
|
|
|
if (it != replacedConstRef[key].end() && it->second.first->identifier() != it->second.second)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
if (it == replacedConstRef[key].end())
|
|
|
|
|
|
{
|
|
|
|
|
|
//check replaces
|
|
|
|
|
|
SgSymbol* wasDone = NULL;
|
|
|
|
|
|
for (auto& elem : replacedConstRef[key])
|
|
|
|
|
|
if (elem.second.second == varName)
|
|
|
|
|
|
wasDone = elem.second.first;
|
|
|
|
|
|
|
|
|
|
|
|
if (wasDone == NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
replacedConstRef[key][newS->identifier()] = make_pair(newS, newName.c_str());
|
|
|
|
|
|
newS->changeName(newName.c_str());
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
newS = wasDone;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (funcName != "null" && createdByFunc[key].find(varName) != createdByFunc[key].end())
|
|
|
|
|
|
{
|
|
|
|
|
|
; //skip
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
newS->changeName(newName.c_str());
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
newS->changeName(newName.c_str());
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
newS = findSymbolOrCreate(current_file, newName, type);
|
|
|
|
|
|
|
|
|
|
|
|
if (newS->variant() == PROCEDURE_NAME)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
if (funcName != "null")
|
|
|
|
|
|
{
|
|
|
|
|
|
auto itS = createdByFunc[key].find(varName);
|
|
|
|
|
|
if (itS == createdByFunc[key].end())
|
|
|
|
|
|
{
|
|
|
|
|
|
createdByFunc[key][varName] = newS;
|
|
|
|
|
|
count[0] = nextCount;
|
2024-01-23 13:04:46 +03:00
|
|
|
|
if (original && isAllocated(original))
|
2023-09-14 19:43:13 +03:00
|
|
|
|
linkToOrig[newS] = original;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
newS = itS->second;
|
|
|
|
|
|
}
|
|
|
|
|
|
//printf("newS %s = %d\n", newS->identifier(), newS->id());
|
|
|
|
|
|
newSymbols.insert(newS);
|
|
|
|
|
|
checkSymbols(current_file_id, newSymbols);
|
|
|
|
|
|
return newS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-05 18:20:31 +03:00
|
|
|
|
static SgStatement* findDuplicateInHidden(SgStatement* data)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgStatement* clone = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
auto itF = hiddenData.find(current_file->filename());
|
|
|
|
|
|
if (itF == hiddenData.end())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& func : itF->second)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (func->fileName() != string(data->fileName()))
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
SgStatement* st = func->lexNext();
|
|
|
|
|
|
SgStatement* last = func->lastNodeOfStmt();
|
|
|
|
|
|
|
|
|
|
|
|
while (st != last)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (data->lineNumber() == st->lineNumber() && data->variant() == st->variant())
|
|
|
|
|
|
{
|
|
|
|
|
|
clone = st;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
st = st->lexNext();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (clone)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
checkNull(clone, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
return clone;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
static SgValueExp* oneExpr = NULL;
|
|
|
|
|
|
static SgValueExp* zeroExpr = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
static vector<SgExpression*> getLowBounds(SgSymbol* arrayS)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (oneExpr == NULL)
|
|
|
|
|
|
oneExpr = new SgValueExp(1);
|
|
|
|
|
|
|
|
|
|
|
|
SgExpression* list = NULL;
|
|
|
|
|
|
|
2024-01-23 13:04:46 +03:00
|
|
|
|
if (isAllocated(arrayS))
|
2023-09-14 19:43:13 +03:00
|
|
|
|
{
|
|
|
|
|
|
SgSymbol* copyFrom = NULL;
|
|
|
|
|
|
if (linkToOrig.find(arrayS) == linkToOrig.end())
|
|
|
|
|
|
copyFrom = arrayS;
|
|
|
|
|
|
else
|
|
|
|
|
|
copyFrom = linkToOrig[arrayS];
|
|
|
|
|
|
|
|
|
|
|
|
SgStatement* decl = declaratedInStmt(copyFrom);
|
|
|
|
|
|
checkNull(decl, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
int consistInAllocates = 0;
|
|
|
|
|
|
const string origName = OriginalSymbol(copyFrom)->identifier();
|
|
|
|
|
|
|
2024-02-25 11:16:56 +03:00
|
|
|
|
auto allocData = getAttributes<SgStatement*, SgStatement*>(decl, set<int>{ ALLOCATE_STMT });
|
|
|
|
|
|
if (allocData.size() == 0) // try to find statements in original file
|
|
|
|
|
|
{
|
|
|
|
|
|
string declFile(decl->fileName());
|
|
|
|
|
|
int line = decl->lineNumber();
|
|
|
|
|
|
string file_name = current_file->filename();
|
|
|
|
|
|
|
|
|
|
|
|
if (current_file->filename() != declFile)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto trueDecl = SgStatement::getStatementByFileAndLine(declFile, line);
|
|
|
|
|
|
if (trueDecl)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto trueData = getAttributes<SgStatement*, SgStatement*>(trueDecl, set<int>{ ALLOCATE_STMT });
|
|
|
|
|
|
if (trueData.size())
|
|
|
|
|
|
allocData = trueData;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
SgFile::switchToFile(file_name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (auto data : allocData)
|
2023-09-14 19:43:13 +03:00
|
|
|
|
{
|
|
|
|
|
|
if (data->variant() != ALLOCATE_STMT)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
2023-11-05 18:20:31 +03:00
|
|
|
|
if (data->getFileId() != current_file_id)
|
|
|
|
|
|
data = findDuplicateInHidden(data);
|
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
SgExpression* iter = data->expr(0);
|
|
|
|
|
|
|
|
|
|
|
|
while (iter)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgArrayRefExp* arrayRef = isSgArrayRefExp(iter->lhs());
|
|
|
|
|
|
if (arrayRef != NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgSymbol* origS = OriginalSymbol(arrayRef->symbol());
|
|
|
|
|
|
if (origS->identifier() == origName)
|
|
|
|
|
|
{
|
|
|
|
|
|
consistInAllocates++;
|
|
|
|
|
|
list = iter->lhs()->lhs();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
iter = iter->rhs();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (consistInAllocates != 1)
|
|
|
|
|
|
list = NULL;
|
|
|
|
|
|
|
2024-02-11 21:09:44 +03:00
|
|
|
|
if (list == NULL)
|
2024-02-25 11:16:56 +03:00
|
|
|
|
__spf_print(1, "find for %s, consistInAllocates = %d\n", arrayS->identifier(), consistInAllocates);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
checkNull(list, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
auto type = isSgArrayType(arrayS->type());
|
|
|
|
|
|
list = type->getDimList();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<SgExpression*> bounds;
|
|
|
|
|
|
while (list)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgExpression* elem = list->lhs();
|
|
|
|
|
|
if (elem->variant() == DDOT)
|
|
|
|
|
|
bounds.push_back(elem->lhs());
|
|
|
|
|
|
else
|
|
|
|
|
|
bounds.push_back(oneExpr);
|
|
|
|
|
|
list = list->rhs();
|
|
|
|
|
|
}
|
|
|
|
|
|
return bounds;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static vector<SgExpression*> getBoundsExpression(SgSymbol* arrayS)
|
|
|
|
|
|
{
|
2024-01-23 13:04:46 +03:00
|
|
|
|
if (isAllocated(arrayS))
|
2023-09-14 19:43:13 +03:00
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
auto type = isSgArrayType(arrayS->type());
|
|
|
|
|
|
auto list = type->getDimList();
|
|
|
|
|
|
|
|
|
|
|
|
vector<SgExpression*> bounds;
|
|
|
|
|
|
while (list)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgExpression* elem = list->lhs();
|
|
|
|
|
|
if (elem->variant() == DDOT)
|
|
|
|
|
|
bounds.push_back(&(elem->rhs()->copy() - elem->lhs()->copy() + *new SgValueExp(1)));
|
|
|
|
|
|
else
|
|
|
|
|
|
bounds.push_back(elem->copyPtr());
|
|
|
|
|
|
list = list->rhs();
|
|
|
|
|
|
}
|
|
|
|
|
|
return bounds;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static SgArrayRefExp* addressPass(SgArrayRefExp* result, SgArrayRefExp* arrayExpOld, SgArrayRefExp* arrayExpNew,
|
|
|
|
|
|
const vector<SgExpression*>& boundsOld, const vector<SgExpression*>& boundsNew,
|
|
|
|
|
|
map<SgExpression*, string>& collection)
|
|
|
|
|
|
{
|
|
|
|
|
|
//TODO: check dims position
|
|
|
|
|
|
for (int z = 0; z < boundsOld.size(); ++z)
|
|
|
|
|
|
{
|
|
|
|
|
|
checkNull(boundsOld[z], convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
checkNull(boundsNew[z], convertFileName(__FILE__).c_str(), __LINE__);
|
2024-02-11 21:09:44 +03:00
|
|
|
|
SgExpression* shift = NULL;
|
|
|
|
|
|
SgExpression& baseShift = (boundsNew[z]->copy() - boundsOld[z]->copy());
|
|
|
|
|
|
|
|
|
|
|
|
if (arrayExpNew->subscript(z) &&
|
|
|
|
|
|
!isEqExpressions(arrayExpNew->subscript(z), boundsNew[z], collection))
|
|
|
|
|
|
{
|
|
|
|
|
|
shift = &(arrayExpNew->subscript(z)->copy() - boundsNew[z]->copy());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SgExpression& oldSub = arrayExpOld->subscript(z)->copy();
|
2023-09-14 19:43:13 +03:00
|
|
|
|
if (isEqExpressions(boundsOld[z], boundsNew[z], collection))
|
2024-02-11 21:09:44 +03:00
|
|
|
|
result->addSubscript(shift ? (oldSub + *shift) : oldSub);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
else
|
2024-02-11 21:09:44 +03:00
|
|
|
|
result->addSubscript(shift ? (oldSub + baseShift + *shift) : (oldSub + baseShift));
|
2023-09-14 19:43:13 +03:00
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static SgArrayRefExp* linearize(SgArrayRefExp* result, SgArrayRefExp* arrayExpOld, SgExpression* oldExp,
|
|
|
|
|
|
map<string, vector<pair<SgSymbol*, SgExpression*>>>& argVarsLinearForm,
|
|
|
|
|
|
const vector<SgExpression*>& boundsOld, const vector<SgExpression*>& boundsNew,
|
|
|
|
|
|
map<SgExpression*, string>& collection)
|
|
|
|
|
|
{
|
|
|
|
|
|
const string arrayName = oldExp->symbol()->identifier();
|
|
|
|
|
|
const int numOldSubs = arrayExpOld->numberOfSubscripts();
|
|
|
|
|
|
|
|
|
|
|
|
auto itL = argVarsLinearForm.find(arrayName);
|
|
|
|
|
|
if (itL == argVarsLinearForm.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
vector<pair<SgSymbol*, SgExpression*>> newVars;
|
|
|
|
|
|
int boundsN = 0;
|
|
|
|
|
|
auto initDeclareBounds = getBoundsExpression(oldExp->symbol());
|
|
|
|
|
|
for (int z = 0; z < boundsOld.size() - 1; ++z)
|
|
|
|
|
|
{
|
|
|
|
|
|
pair<SgSymbol*, SgExpression*> forDim;
|
|
|
|
|
|
string dimName = "s_";
|
|
|
|
|
|
int nextBoound = checkSymbNameAndCorrect(dimName, boundsN);
|
|
|
|
|
|
dimName += to_string(nextBoound);
|
|
|
|
|
|
|
|
|
|
|
|
forDim.first = new SgSymbol(VARIABLE_NAME, dimName.c_str());
|
|
|
|
|
|
forDim.second = initDeclareBounds[z];
|
|
|
|
|
|
newVars.push_back(forDim);
|
|
|
|
|
|
}
|
|
|
|
|
|
itL = argVarsLinearForm.insert(itL, make_pair(arrayName, newVars));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SgExpression* linearForm = NULL;
|
|
|
|
|
|
if (numOldSubs != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int z = 0; z < boundsOld.size(); ++z)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgExpression* nextArg = &(arrayExpOld->subscript(z)->copy() - boundsOld[z]->copy());
|
|
|
|
|
|
|
|
|
|
|
|
for (int p = 0; p < z; ++p)
|
|
|
|
|
|
nextArg = &(*nextArg * *new SgVarRefExp(itL->second[p].first));
|
|
|
|
|
|
|
|
|
|
|
|
if (linearForm)
|
|
|
|
|
|
linearForm = &(*linearForm + *nextArg);
|
|
|
|
|
|
else
|
|
|
|
|
|
linearForm = nextArg;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int numS = result->numberOfSubscripts();
|
|
|
|
|
|
if (!isEqExpressions(zeroExpr, boundsNew[0], collection) && numS == 0)
|
|
|
|
|
|
linearForm = &(*linearForm + boundsNew[0]->copy());
|
|
|
|
|
|
|
|
|
|
|
|
if (numS == 0)
|
|
|
|
|
|
result->addSubscript(*linearForm);
|
|
|
|
|
|
else if (numS == 1)
|
|
|
|
|
|
result->replaceSubscripts(*result->subscript(0) + *linearForm);
|
|
|
|
|
|
else // TODO
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static SgExpression* doReplace(SgExpression* oldExp, SgExpression* newExp, map<SgExpression*, string>& collection,
|
|
|
|
|
|
map<string, vector<pair<SgSymbol*, SgExpression*>>>& argVarsLinearForm,
|
|
|
|
|
|
map<string, vector<Messages>>& messages,
|
|
|
|
|
|
const PointCall& point)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (oneExpr == NULL)
|
|
|
|
|
|
oneExpr = new SgValueExp(1);
|
|
|
|
|
|
|
|
|
|
|
|
if (zeroExpr == NULL)
|
|
|
|
|
|
zeroExpr = new SgValueExp(0);
|
|
|
|
|
|
|
|
|
|
|
|
SgExpression* retVal = NULL;
|
|
|
|
|
|
if (oldExp)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (oldExp->variant() == ARRAY_REF && oldExp->symbol() && oldExp->symbol()->type()->variant() == T_ARRAY)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (newExp->variant() != ARRAY_REF)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
SgArrayRefExp* arrayExpOld = isSgArrayRefExp(oldExp);
|
|
|
|
|
|
SgArrayRefExp* arrayExpNew = isSgArrayRefExp(newExp);
|
|
|
|
|
|
|
2024-02-11 21:09:44 +03:00
|
|
|
|
/*arrayExpOld->unparsestdout();
|
|
|
|
|
|
arrayExpNew->unparsestdout();
|
|
|
|
|
|
printf("\n");*/
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
auto boundsOld = getLowBounds(oldExp->symbol());
|
|
|
|
|
|
auto boundsNew = getLowBounds(newExp->symbol());
|
2024-02-11 21:09:44 +03:00
|
|
|
|
|
|
|
|
|
|
/*for (auto& elem : boundsOld)
|
|
|
|
|
|
elem->unparsestdout();
|
|
|
|
|
|
printf("--\n");
|
|
|
|
|
|
for (auto& elem : boundsNew)
|
|
|
|
|
|
elem->unparsestdout();
|
|
|
|
|
|
printf("--\n");*/
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
const int numOldSubs = arrayExpOld->numberOfSubscripts();
|
|
|
|
|
|
const int numNewSubs = arrayExpNew->numberOfSubscripts();
|
|
|
|
|
|
if (numNewSubs == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgArrayRefExp* result = (SgArrayRefExp*)arrayExpNew->copyPtr();
|
|
|
|
|
|
if (boundsOld.size() != boundsNew.size() && boundsNew.size() != 1 && boundsOld.size() != 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::wstring bufE, bufR;
|
|
|
|
|
|
__spf_printToLongBuf(bufE, L"Can not do replace argument of call '%s': sizes mismatch of array reference '%s'",
|
|
|
|
|
|
to_wstring(point.getChainCall()).c_str(), to_wstring(oldExp->symbol()->identifier()).c_str());
|
|
|
|
|
|
__spf_printToLongBuf(bufR, R180, to_wstring(point.getChainCall()).c_str(), to_wstring(oldExp->symbol()->identifier()).c_str());
|
|
|
|
|
|
getObjectForFileFromMap(point.mainPoint.first.c_str(), messages).push_back(Messages(ERROR, point.mainPoint.second, bufR, bufE, 2014));
|
|
|
|
|
|
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (boundsNew.size() == 1 && boundsOld.size() > 1)
|
|
|
|
|
|
result = linearize(result, arrayExpOld, oldExp, argVarsLinearForm, boundsOld, boundsNew, collection);
|
|
|
|
|
|
else if (boundsNew.size() > 1 && boundsOld.size() == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::wstring bufE, bufR;
|
|
|
|
|
|
__spf_printToLongBuf(bufE, L"Can not do replace argument of call '%s': sizes mismatch of array reference '%s'",
|
|
|
|
|
|
to_wstring(point.getChainCall()).c_str(), to_wstring(oldExp->symbol()->identifier()).c_str());
|
|
|
|
|
|
__spf_printToLongBuf(bufR, R180, to_wstring(point.getChainCall()).c_str(), to_wstring(oldExp->symbol()->identifier()).c_str());
|
|
|
|
|
|
getObjectForFileFromMap(point.mainPoint.first.c_str(), messages).push_back(Messages(ERROR, point.mainPoint.second, bufR, bufE, 2014));
|
|
|
|
|
|
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (numOldSubs != 0)
|
|
|
|
|
|
result = addressPass(result, arrayExpOld, arrayExpNew, boundsOld, boundsNew, collection);
|
|
|
|
|
|
retVal = result;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (numNewSubs >= numOldSubs && numOldSubs != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgArrayRefExp* result = new SgArrayRefExp(*arrayExpNew->symbol());
|
|
|
|
|
|
if (boundsOld.size() > boundsNew.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
std::wstring bufE, bufR;
|
|
|
|
|
|
__spf_printToLongBuf(bufE, L"Can not do replace argument of call '%s': sizes mismatch of array reference '%s'",
|
|
|
|
|
|
to_wstring(point.getChainCall()).c_str(), to_wstring(oldExp->symbol()->identifier()).c_str());
|
|
|
|
|
|
__spf_printToLongBuf(bufR, R180, to_wstring(point.getChainCall()).c_str(), to_wstring(oldExp->symbol()->identifier()).c_str());
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
result = addressPass(result, arrayExpOld, arrayExpNew, boundsOld, boundsNew, collection);
|
|
|
|
|
|
for (int z = 0; z < boundsNew.size() - boundsOld.size(); ++z)
|
|
|
|
|
|
result->addSubscript(arrayExpNew->subscript(boundsOld.size() + z)->copy());
|
|
|
|
|
|
retVal = result;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (boundsNew.size() == 1 && boundsOld.size() > 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgArrayRefExp* result = (SgArrayRefExp*)arrayExpNew->copyPtr();
|
|
|
|
|
|
retVal = linearize(result, arrayExpOld, oldExp, argVarsLinearForm, boundsOld, boundsNew, collection);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
retVal = newExp->copyPtr();
|
|
|
|
|
|
retVal->setLhs(oldExp->lhs());
|
|
|
|
|
|
retVal->setRhs(oldExp->rhs());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
retVal = newExp->copyPtr();
|
|
|
|
|
|
}
|
|
|
|
|
|
if (retVal == NULL)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
return retVal;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//return 0 - local, 1 - common, 2 - module
|
|
|
|
|
|
static int isGlobal(SgStatement* st, SgSymbol* toCheckS, vector<SgSymbol*>* allInCommon = NULL, string* globalName = NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto scope = toCheckS->scope();
|
|
|
|
|
|
bool isFunctionS = (toCheckS->variant() == FUNCTION_NAME);
|
|
|
|
|
|
|
|
|
|
|
|
if (toCheckS != OriginalSymbol(toCheckS) || (scope && scope->variant() == MODULE_STMT && !isFunctionS))
|
|
|
|
|
|
{
|
|
|
|
|
|
//TODO for module
|
|
|
|
|
|
//globalName =
|
|
|
|
|
|
return 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const string toCheck = toCheckS->identifier();
|
|
|
|
|
|
SgStatement* func = getFuncStat(st);
|
|
|
|
|
|
map<string, vector<SgExpression*>> commonBlocksRef;
|
|
|
|
|
|
getCommonBlocksRef(commonBlocksRef, func, func ? func->lastNodeOfStmt() : NULL);
|
|
|
|
|
|
|
|
|
|
|
|
int isCommon = 0;
|
|
|
|
|
|
for (auto& commonBlockRef : commonBlocksRef)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& commExp : commonBlockRef.second)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto exp = commExp->lhs(); exp; exp = exp->rhs())
|
|
|
|
|
|
{
|
|
|
|
|
|
SgSymbol* varSymb = exp->lhs()->symbol();
|
|
|
|
|
|
string varName = varSymb->identifier();
|
|
|
|
|
|
|
|
|
|
|
|
if (toCheck == varName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (globalName)
|
|
|
|
|
|
globalName[0] = commonBlockRef.first;
|
|
|
|
|
|
isCommon = 1;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isCommon == 1)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isCommon == 1 && allInCommon)
|
|
|
|
|
|
for (auto& commExp : commonBlockRef.second)
|
|
|
|
|
|
for (auto exp = commExp->lhs(); exp; exp = exp->rhs())
|
|
|
|
|
|
allInCommon[0].push_back(exp->lhs()->symbol());
|
|
|
|
|
|
|
|
|
|
|
|
if (isCommon == 1)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
return isCommon;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline static void findAllConstRef(SgExpression* ex, set<SgSymbol*>& result)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex->variant() == CONST_REF)
|
|
|
|
|
|
{
|
|
|
|
|
|
result.insert(ex->symbol());
|
|
|
|
|
|
auto constS = isSgConstantSymb(ex->symbol());
|
|
|
|
|
|
if (!constS)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
auto val = constS->constantValue();
|
|
|
|
|
|
if (!val)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
findAllConstRef(val, result);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
findAllConstRef(ex->lhs(), result);
|
|
|
|
|
|
findAllConstRef(ex->rhs(), result);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//globalType: 0 - local, 1 - common, 2 - module
|
|
|
|
|
|
static void detectTypeOfSymbol(const string& funcName, SgSymbol* s, int globalType, set<SgSymbol*>& newSymbols,
|
|
|
|
|
|
const vector<SgSymbol*>& allInCommon, const string& globalName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (newSymbols.find(s) == newSymbols.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
char* newAttr = new char[globalName.size() + 1];
|
|
|
|
|
|
strcpy(newAttr, globalName.c_str());
|
|
|
|
|
|
if (globalType == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (allInCommon.size() == 0)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
const pair<string, int> key = make_pair(funcName, current_file_id);
|
|
|
|
|
|
int pos = 0;
|
|
|
|
|
|
for (auto& commS : allInCommon)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto attrsC = getAttributes<SgSymbol*, char*>(commS, set<int> { COMM_STAT });
|
|
|
|
|
|
auto attrsPos = getAttributes<SgSymbol*, int*>(commS, set<int> { COMM_LIST });
|
|
|
|
|
|
|
|
|
|
|
|
if (attrsC.size() == 0 && attrsPos.size() == 0 ||
|
|
|
|
|
|
attrsC.size() && attrsPos.size() && (attrsC[0] != string(newAttr) || *attrsPos[0] != pos))
|
|
|
|
|
|
{
|
|
|
|
|
|
commS->addAttribute(COMM_STAT, newAttr, sizeof(char*));
|
|
|
|
|
|
int* posS = new int[1];
|
|
|
|
|
|
posS[0] = pos;
|
|
|
|
|
|
commS->addAttribute(COMM_LIST, posS, sizeof(int*));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isSgArrayType(commS->type()))
|
|
|
|
|
|
{
|
|
|
|
|
|
set<SgSymbol*> constInDecl;
|
|
|
|
|
|
auto arrT = isSgArrayType(commS->type());
|
|
|
|
|
|
findAllConstRef(arrT->getDimList(), constInDecl);
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& elem : constInDecl)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto itS = replacedConstRef[key].find(elem->identifier());
|
|
|
|
|
|
if (itS == replacedConstRef[key].end())
|
|
|
|
|
|
{
|
|
|
|
|
|
replacedConstRef[key][elem->identifier()] = make_pair(elem, elem->identifier());
|
|
|
|
|
|
newSymbols.insert(elem);
|
|
|
|
|
|
checkSymbols(current_file_id, newSymbols);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
newSymbols.insert(commS);
|
|
|
|
|
|
checkSymbols(current_file_id, newSymbols);
|
|
|
|
|
|
|
|
|
|
|
|
if (funcName != "null" && commS->attributes() & DATA_BIT)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto itS = createdByFunc[key].find(commS->identifier());
|
|
|
|
|
|
if (itS == createdByFunc[key].end())
|
|
|
|
|
|
createdByFunc[key][commS->identifier()] = commS;
|
|
|
|
|
|
}
|
|
|
|
|
|
++pos;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (globalType == 2)
|
|
|
|
|
|
s->addAttribute(MODULE_STMT, newAttr, sizeof(char*));
|
|
|
|
|
|
else
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
if (globalType != 2)
|
|
|
|
|
|
newSymbols.insert(s);
|
|
|
|
|
|
|
|
|
|
|
|
checkSymbols(current_file_id, newSymbols);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void replaceSymbInExp(SgStatement* st, SgExpression* exp, SgExpression* par, const int expIdx, const bool isLeft,
|
|
|
|
|
|
const map<string, SgExpression*>& argVars, map<string, SgSymbol*>& locVars, set<SgSymbol*>& newSymbols,
|
|
|
|
|
|
const string& funcName, const string& resultName, SgSymbol*& newHedrSymb, map<SgExpression*, string>& collection,
|
|
|
|
|
|
map<string, vector<pair<SgSymbol*, SgExpression*>>>& argVarsLinearForm,
|
|
|
|
|
|
map<string, vector<Messages>>& messages, const PointCall& point)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (exp)
|
|
|
|
|
|
{
|
|
|
|
|
|
replaceSymbInExp(st, exp->lhs(), exp, expIdx, true, argVars, locVars, newSymbols, funcName, resultName, newHedrSymb, collection, argVarsLinearForm, messages, point);
|
|
|
|
|
|
replaceSymbInExp(st, exp->rhs(), exp, expIdx, false, argVars, locVars, newSymbols, funcName, resultName, newHedrSymb, collection, argVarsLinearForm, messages, point);
|
|
|
|
|
|
|
|
|
|
|
|
const int var = exp->variant();
|
|
|
|
|
|
if (var == FUNC_CALL && exp->symbol())
|
|
|
|
|
|
if (!isIntrinsicFunctionName(exp->symbol()->identifier()) || exp->symbol()->identifier() == string("dvtime"))
|
|
|
|
|
|
newSymbols.insert(exp->symbol());
|
|
|
|
|
|
|
|
|
|
|
|
if ((var == VAR_REF || var == ARRAY_REF || var == CONST_REF || var == IOACCESS) && exp->symbol())
|
|
|
|
|
|
{
|
|
|
|
|
|
const string varName = exp->symbol()->identifier();
|
|
|
|
|
|
auto it = argVars.find(varName);
|
|
|
|
|
|
if (it != argVars.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
SgExpression* copy = NULL;
|
|
|
|
|
|
if (!par)
|
|
|
|
|
|
{
|
|
|
|
|
|
copy = doReplace(st->expr(expIdx), it->second, collection, argVarsLinearForm, messages, point);
|
|
|
|
|
|
st->setExpression(expIdx, copy);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
copy = doReplace((isLeft ? par->lhs() : par->rhs()), it->second, collection, argVarsLinearForm, messages, point);
|
|
|
|
|
|
isLeft ? par->setLhs(copy) : par->setRhs(copy);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
auto expS = exp->symbol();
|
|
|
|
|
|
string globalName;
|
|
|
|
|
|
vector<SgSymbol*> allInCommon;
|
|
|
|
|
|
int globalType = isGlobal(st, expS, &allInCommon, &globalName);
|
|
|
|
|
|
if (globalType == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto it = locVars.find(varName);
|
|
|
|
|
|
if (it == locVars.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto symb = createSymbAndDecl(funcName, varName, expS, newSymbols);
|
|
|
|
|
|
it = locVars.insert(it, make_pair(varName, symb));
|
|
|
|
|
|
|
|
|
|
|
|
if (varName == resultName && !newHedrSymb)
|
|
|
|
|
|
newHedrSymb = symb;
|
|
|
|
|
|
|
|
|
|
|
|
if (newHedrSymb != symb)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto arrType = isSgArrayType(symb->type());
|
|
|
|
|
|
if (arrType)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto allList = arrType->getDimList();
|
|
|
|
|
|
while (allList)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto list = allList;
|
|
|
|
|
|
if (list && list->lhs())
|
|
|
|
|
|
replaceSymbInExp(NULL, list->lhs(), list, -1, true, argVars, locVars, newSymbols, funcName, resultName, newHedrSymb, collection, argVarsLinearForm, messages, point);
|
|
|
|
|
|
allList = allList->rhs();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
exp->setSymbol(*it->second);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
detectTypeOfSymbol(funcName, expS, globalType, newSymbols, allInCommon, globalName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline static void replaceSymbInStat(SgStatement* st, SgStatement* tempHedr,
|
|
|
|
|
|
const map<string, SgExpression*>& argVars, map<string, SgSymbol*>& locVars, set<SgSymbol*>& newSymbols,
|
|
|
|
|
|
const string& funcName, const string& resultName, SgSymbol*& newHedrSymb, map<SgExpression*, string>& collection,
|
|
|
|
|
|
map<string, vector<pair<SgSymbol*, SgExpression*>>>& argVarsLinearForm,
|
|
|
|
|
|
map<string, vector<Messages>>& messages, const PointCall& point)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->variant() == SPF_PARALLEL_REG_DIR)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (st->symbol() && st->variant() != PROC_STAT)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto s = st->symbol();
|
|
|
|
|
|
|
|
|
|
|
|
const string varName = s->identifier();
|
|
|
|
|
|
auto it = argVars.find(varName);
|
|
|
|
|
|
if (it != argVars.end())
|
|
|
|
|
|
st->setSymbol(*it->second->symbol());
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
string globalName;
|
|
|
|
|
|
vector<SgSymbol*> allInCommon;
|
|
|
|
|
|
int globalType = isGlobal(st, s, &allInCommon, &globalName);
|
|
|
|
|
|
if (globalType == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto it = locVars.find(varName);
|
|
|
|
|
|
if (it == locVars.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto symb = createSymbAndDecl(funcName, varName, s, newSymbols);
|
|
|
|
|
|
it = locVars.insert(it, make_pair(varName, symb));
|
|
|
|
|
|
|
|
|
|
|
|
if (varName == resultName && !newHedrSymb)
|
|
|
|
|
|
newHedrSymb = symb;
|
|
|
|
|
|
}
|
|
|
|
|
|
st->setSymbol(*it->second);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
detectTypeOfSymbol(funcName, s, globalType, newSymbols, allInCommon, globalName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; ++i)
|
|
|
|
|
|
replaceSymbInExp(st, st->expr(i), NULL, i, false, argVars, locVars, newSymbols, funcName, resultName, newHedrSymb, collection, argVarsLinearForm, messages, point);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline void remapVars(SgStatement* tempHedr,
|
|
|
|
|
|
map<string, SgExpression*> argVars, map<string, SgSymbol*>& locVars,
|
|
|
|
|
|
set<SgSymbol*>& newSymbols, const string& funcName, const string& resultName,
|
|
|
|
|
|
SgSymbol*& newHedrSymb, map<string, vector<Messages>>& messages, const PointCall& point)
|
|
|
|
|
|
{
|
|
|
|
|
|
map<SgExpression*, string> collection;
|
|
|
|
|
|
map<string, vector<pair<SgSymbol*, SgExpression*>>> argVarsLinearForm;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto st = tempHedr; st != tempHedr->lastNodeOfStmt(); st = st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->variant() == CONTAINS_STMT)
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
if (st->variant() == ENTRY_STAT) // exclude same argVars
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->symbol())
|
|
|
|
|
|
{
|
|
|
|
|
|
SgExpression* parList = st->expr(0);
|
|
|
|
|
|
for (SgExpression* p = parList; p; p = p->rhs())
|
|
|
|
|
|
{
|
|
|
|
|
|
string parName = p->lhs()->symbol()->identifier();
|
|
|
|
|
|
if (argVars.find(parName) != argVars.end())
|
|
|
|
|
|
argVars.erase(parName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isSgExecutableStatement(st))
|
|
|
|
|
|
replaceSymbInStat(st, tempHedr, argVars, locVars, newSymbols, funcName, resultName, newHedrSymb, collection, argVarsLinearForm, messages, point);
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->variant() == DATA_DECL)
|
|
|
|
|
|
dataDeclsByFunc[make_pair(funcName, current_file_id)].insert((SgValueExp*)st->expr(0));
|
|
|
|
|
|
else if (st->variant() == VAR_DECL_90 || st->variant() == VAR_DECL)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgExpression* list = st->expr(0);
|
|
|
|
|
|
while (list)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto ex = list->lhs();
|
|
|
|
|
|
if (ex->variant() == ASSGN_OP)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgExpression* tmp = new SgExprListExp();
|
|
|
|
|
|
map<string, vector<pair<SgSymbol*, SgExpression*>>> dummy;
|
|
|
|
|
|
|
|
|
|
|
|
auto copy = ex->rhs()->copyPtr();
|
|
|
|
|
|
tmp->setLhs(copy);
|
|
|
|
|
|
replaceSymbInExp(NULL, tmp->lhs(), tmp, -1, true, argVars, locVars, newSymbols, funcName, resultName, newHedrSymb, collection, dummy, messages, point);
|
|
|
|
|
|
|
|
|
|
|
|
dataDeclsByFuncS[make_pair(funcName, current_file_id)][OriginalSymbol(ex->lhs()->symbol())->identifier()] = copy;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
list = list->rhs();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (argVarsLinearForm.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
SgStatement* lastDecl = tempHedr;
|
|
|
|
|
|
for (auto st = tempHedr; st != tempHedr->lastNodeOfStmt(); st = st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->variant() == CONTAINS_STMT)
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
auto next = st->lexNext();
|
|
|
|
|
|
|
|
|
|
|
|
if (next && isSgExecutableStatement(next))
|
|
|
|
|
|
{
|
|
|
|
|
|
lastDecl = st;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SgExpression* tmp = new SgExprListExp();
|
|
|
|
|
|
map<string, vector<pair<SgSymbol*, SgExpression*>>> dummy;
|
|
|
|
|
|
for (auto& bySymb : argVarsLinearForm)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& elem : bySymb.second)
|
|
|
|
|
|
{
|
|
|
|
|
|
newSymbols.insert(elem.first);
|
|
|
|
|
|
checkSymbols(current_file_id, newSymbols);
|
|
|
|
|
|
|
|
|
|
|
|
tmp->setLhs(elem.second);
|
|
|
|
|
|
|
|
|
|
|
|
replaceSymbInExp(NULL, tmp->lhs(), tmp, -1, true, argVars, locVars, newSymbols, funcName, resultName, newHedrSymb, collection, dummy, messages, point);
|
|
|
|
|
|
|
|
|
|
|
|
SgAssignStmt* init = new SgAssignStmt(*new SgVarRefExp(elem.first), *tmp->lhs());
|
|
|
|
|
|
lastDecl->insertStmtAfter(*init, *tempHedr);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void addComment(SgStatement* st, bool isStart, string ident)
|
|
|
|
|
|
{
|
|
|
|
|
|
string comments = "";
|
|
|
|
|
|
if (st->comments())
|
|
|
|
|
|
{
|
|
|
|
|
|
comments = st->comments();
|
|
|
|
|
|
if (isStart)
|
|
|
|
|
|
comments += "![INLINING] start of '" + ident + "'\n";
|
|
|
|
|
|
else
|
|
|
|
|
|
comments = "![INLINING] end of '" + ident + "'\n" + comments;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
comments = (isStart ? "![INLINING] start of '" : "![INLINING] end of '") + ident + "'\n";
|
|
|
|
|
|
st->setComments(comments.c_str());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void insert(SgStatement* callSt, SgStatement* tempHedr, SgStatement* begin, SgSymbol* newHedrSymb,
|
|
|
|
|
|
vector<SgStatement*>& toDelete, set<SgStatement*>& useStats)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto prev = callSt->lexPrev();
|
|
|
|
|
|
auto last = tempHedr->lastNodeOfStmt();
|
|
|
|
|
|
|
|
|
|
|
|
auto firstExec = begin->lexNext();
|
|
|
|
|
|
auto lastExec = callSt->lexNext();
|
|
|
|
|
|
while (lastExec && lastExec->variant() == GLOBAL) // bounds marker
|
|
|
|
|
|
lastExec = lastExec->lexNext();
|
|
|
|
|
|
|
|
|
|
|
|
vector<SgStatement*> formats;
|
|
|
|
|
|
|
|
|
|
|
|
for (; firstExec && firstExec != tempHedr->lastNodeOfStmt(); firstExec = firstExec->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (firstExec->variant() == USE_STMT)
|
|
|
|
|
|
useStats.insert(firstExec->copyPtr());
|
|
|
|
|
|
|
|
|
|
|
|
if (isSgExecutableStatement(firstExec))
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
if (firstExec->variant() == FORMAT_STAT)
|
|
|
|
|
|
formats.push_back(firstExec->copyPtr());
|
|
|
|
|
|
}
|
|
|
|
|
|
checkNull(firstExec, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
tempHedr->extractStmt();
|
|
|
|
|
|
|
|
|
|
|
|
SgLabel* callLabel = callSt->label();
|
|
|
|
|
|
|
|
|
|
|
|
prev->insertStmtAfter(*firstExec, *callSt->controlParent());
|
|
|
|
|
|
|
|
|
|
|
|
auto next = prev->lexNext();
|
|
|
|
|
|
if (callSt->comments())
|
|
|
|
|
|
{
|
2024-02-25 11:16:56 +03:00
|
|
|
|
string callCom(callSt->comments());
|
|
|
|
|
|
if (next->comments()) {
|
|
|
|
|
|
string newCom = callCom + next->comments();
|
|
|
|
|
|
next->setComments(newCom.c_str());
|
|
|
|
|
|
}
|
2023-09-14 19:43:13 +03:00
|
|
|
|
else
|
2024-02-25 11:16:56 +03:00
|
|
|
|
next->addComment(callCom.c_str());
|
|
|
|
|
|
callSt->delComments();
|
2023-09-14 19:43:13 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auto ident = string(tempHedr->symbol()->identifier());
|
|
|
|
|
|
addComment(next, true, ident);
|
|
|
|
|
|
addComment(lastExec, false, ident);
|
|
|
|
|
|
|
|
|
|
|
|
if (callLabel)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (firstExec->label())
|
|
|
|
|
|
{
|
|
|
|
|
|
SgContinueStmt* contSt = new SgContinueStmt();
|
|
|
|
|
|
contSt->setLabel(*callLabel);
|
|
|
|
|
|
prev->insertStmtAfter(*contSt, *callSt->controlParent());
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
firstExec->setLabel(*callLabel);
|
|
|
|
|
|
|
|
|
|
|
|
if (callSt->variant() != PROC_STAT) // function calls
|
|
|
|
|
|
callSt->deleteLabel(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (auto &fmt : formats)
|
|
|
|
|
|
prev->insertStmtAfter(*fmt, *callSt->controlParent());
|
|
|
|
|
|
|
|
|
|
|
|
for (auto st = prev->lexNext(); st != callSt; st = st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->lineNumber() > 0)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
st->setlineNumber(getNextNegativeLineNumber());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-30 12:17:35 +03:00
|
|
|
|
next = prev->lexNext();
|
|
|
|
|
|
next->setlineNumber(callSt->lineNumber());
|
|
|
|
|
|
next->setFileName(callSt->fileName());
|
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
last->extractStmt();
|
|
|
|
|
|
|
|
|
|
|
|
if (callSt->variant() == PROC_STAT)
|
|
|
|
|
|
toDelete.push_back(callSt);
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
callSt->setExpression(1, new SgExpression(VAR_REF));
|
|
|
|
|
|
callSt->expr(1)->setSymbol(newHedrSymb);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int clean(const string& funcName, SgStatement* funcSt, const map<string, FuncInfo*>& funcMap, vector<SgStatement*>& toDelete)
|
|
|
|
|
|
{
|
|
|
|
|
|
// site-independent transformation
|
|
|
|
|
|
int gotoLabelId = -1;
|
|
|
|
|
|
SgLabel* contLab = NULL;
|
|
|
|
|
|
SgStatement* cont = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
// return goto label if entry function is called
|
|
|
|
|
|
auto it = funcMap.find(funcName);
|
|
|
|
|
|
if (it != funcMap.end() && it->second->funcPointer->variant() == ENTRY_STAT)
|
|
|
|
|
|
gotoLabelId = getNextFreeLabel();
|
|
|
|
|
|
|
|
|
|
|
|
vector<SgStatement*> insertBeforeEnd;
|
|
|
|
|
|
// TODO: move all ENTRY points to the top of the subprogram
|
|
|
|
|
|
for (auto st = funcSt; st != funcSt->lastNodeOfStmt()->lexNext(); st = st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (st->variant())
|
|
|
|
|
|
{
|
|
|
|
|
|
case ENTRY_STAT:
|
|
|
|
|
|
{
|
|
|
|
|
|
SgLabel* gotoLab = new SgLabel(getNextFreeLabel());
|
|
|
|
|
|
SgContinueStmt* contSt = new SgContinueStmt();
|
|
|
|
|
|
contSt->setLabel(*gotoLab);
|
|
|
|
|
|
st->insertStmtBefore(*contSt, *st->controlParent());
|
|
|
|
|
|
|
|
|
|
|
|
// return goto label if entry function is called
|
|
|
|
|
|
if (st->symbol()->identifier() == funcName)
|
|
|
|
|
|
gotoLabelId = gotoLab->getLabNumber();
|
|
|
|
|
|
|
|
|
|
|
|
toDelete.push_back(st);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case RETURN_STAT:
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->lexNext()->variant() == CONTROL_END && funcSt->lastNodeOfStmt() == st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->label())
|
|
|
|
|
|
{
|
|
|
|
|
|
SgStatement* cont = new SgStatement(CONT_STAT);
|
|
|
|
|
|
cont->setLabel(*st->label());
|
|
|
|
|
|
st->insertStmtBefore(*cont, *st->controlParent());
|
|
|
|
|
|
}
|
|
|
|
|
|
toDelete.push_back(st);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!cont) // create CONT_STAT
|
|
|
|
|
|
{
|
|
|
|
|
|
contLab = new SgLabel(getNextFreeLabel());
|
|
|
|
|
|
cont = new SgStatement(CONT_STAT);
|
|
|
|
|
|
cont->setLabel(*contLab);
|
|
|
|
|
|
insertBeforeEnd.push_back(cont);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SgGotoStmt* gotoSt = new SgGotoStmt(*contLab);
|
|
|
|
|
|
st->insertStmtBefore(*gotoSt, *st->controlParent());
|
|
|
|
|
|
|
|
|
|
|
|
toDelete.push_back(st);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::reverse(insertBeforeEnd.begin(), insertBeforeEnd.end());
|
|
|
|
|
|
for (auto& beforeEnd : insertBeforeEnd)
|
|
|
|
|
|
funcSt->lastNodeOfStmt()->insertStmtBefore(*beforeEnd, *funcSt);
|
|
|
|
|
|
|
|
|
|
|
|
return gotoLabelId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// true if inserted
|
|
|
|
|
|
static inline bool insert(SgStatement* callSt, SgStatement* funcStat, SgExpression* args, set<SgSymbol*>& newSymbols,
|
|
|
|
|
|
const map<string, FuncInfo*>& funcMap, vector<SgStatement*>& toDelete, set<SgStatement*>& useStats,
|
|
|
|
|
|
map<string, vector<Messages>>& messages, const PointCall& point)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgSymbol* funcSymb = funcStat->symbol();
|
|
|
|
|
|
bool isEntry = false;
|
|
|
|
|
|
SgSymbol* entrySymb = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
SgStatement* tempHedr = NULL;
|
|
|
|
|
|
SgSymbol* tempSymb = NULL;
|
|
|
|
|
|
|
2023-11-28 12:58:22 +03:00
|
|
|
|
__spf_print(DEB, "------creating template------\n");
|
2023-09-14 19:43:13 +03:00
|
|
|
|
// 2.a create function template
|
|
|
|
|
|
auto funcSt = funcSymb->body();
|
|
|
|
|
|
if (funcSt->variant() == ENTRY_STAT)
|
|
|
|
|
|
{
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
//TODO:
|
|
|
|
|
|
isEntry = true;
|
|
|
|
|
|
entrySymb = funcSymb;
|
|
|
|
|
|
|
|
|
|
|
|
while (funcSt && funcSt->variant() != FUNC_HEDR)
|
|
|
|
|
|
funcSt = funcSt->lexPrev();
|
|
|
|
|
|
checkNull(funcSt, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
funcSymb = funcSt->symbol();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// insert template after global statement in current file
|
|
|
|
|
|
tempHedr = duplicateProcedure(funcStat, NULL, true, false, false);
|
|
|
|
|
|
tempSymb = tempHedr->symbol();
|
|
|
|
|
|
|
|
|
|
|
|
if (string(tempSymb->identifier()) != funcSymb->identifier())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
// set first inserting statement
|
|
|
|
|
|
SgStatement* begin = NULL;
|
|
|
|
|
|
if (isEntry)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto st = tempHedr; st != tempHedr->lastNodeOfStmt(); st = st->lexNext())
|
|
|
|
|
|
if (st->variant() == ENTRY_STAT && st->symbol()->identifier() == string(entrySymb->identifier()))
|
|
|
|
|
|
begin = st;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
begin = tempHedr;
|
|
|
|
|
|
checkNull(begin, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
// create map of arguments
|
|
|
|
|
|
SgSymbol* newHedrSymb = NULL; // requires for function with return variable
|
|
|
|
|
|
map<string, SgExpression*> argVars = createMapOfArgs(tempHedr, args); // local argument variable -> top argument variable
|
|
|
|
|
|
map<string, SgSymbol*> locVars; // local varname -> new local var
|
|
|
|
|
|
|
|
|
|
|
|
const string funcName = begin->symbol()->identifier();
|
|
|
|
|
|
string resultName = funcName;
|
|
|
|
|
|
if (isSgFuncHedrStmt(begin))
|
|
|
|
|
|
if (begin->expr(0) && begin->expr(0)->symbol())
|
|
|
|
|
|
resultName = begin->expr(0)->symbol()->identifier();
|
|
|
|
|
|
|
|
|
|
|
|
remapVars(tempHedr, argVars, locVars, newSymbols, funcName, resultName, newHedrSymb, messages, point);
|
|
|
|
|
|
|
|
|
|
|
|
if (!newHedrSymb && tempSymb->variant() == FUNCTION_NAME) // if no textual use of return variable, create new anyway
|
|
|
|
|
|
newHedrSymb = createSymbAndDecl("null", string(tempSymb->identifier()) + "_spf", tempSymb, newSymbols);
|
|
|
|
|
|
|
|
|
|
|
|
if (newHedrSymb)
|
|
|
|
|
|
{
|
|
|
|
|
|
//set clear name for module symbols
|
|
|
|
|
|
const string clearName = getClearName(newHedrSymb->identifier());
|
|
|
|
|
|
if (clearName != newHedrSymb->identifier())
|
|
|
|
|
|
newHedrSymb->changeName(clearName.c_str());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// clean function
|
|
|
|
|
|
int gotoLabId = clean(funcSymb->identifier(), tempHedr, funcMap, toDelete);
|
|
|
|
|
|
if (gotoLabId != -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgLabel* gotoLab = new SgLabel(gotoLabId);
|
|
|
|
|
|
SgGotoStmt* gotoSt = new SgGotoStmt(*gotoLab);
|
|
|
|
|
|
callSt->insertStmtBefore(*gotoSt, *callSt->controlParent());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// insert template
|
|
|
|
|
|
insert(callSt, tempHedr, begin, newHedrSymb, toDelete, useStats);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline void replaceCall(SgExpression* exp, SgExpression* par, const int i, const bool lhs,
|
|
|
|
|
|
SgStatement* callSt, set<SgSymbol*>& newSymbols, SgStatement* insertPlace)
|
|
|
|
|
|
{
|
|
|
|
|
|
// create new call variable for this call and its declaration
|
|
|
|
|
|
SgSymbol* v = createSymbAndDecl("null", "arg", exp->symbol(), newSymbols);
|
|
|
|
|
|
|
|
|
|
|
|
SgAssignStmt* assign = new SgAssignStmt(*new SgVarRefExp(*v), *exp->copyPtr());
|
|
|
|
|
|
assign->setlineNumber(getNextNegativeLineNumber());
|
2023-11-22 20:21:18 +03:00
|
|
|
|
assign->setLocalLineNumber(callSt->lineNumber());
|
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
insertPlace->insertStmtBefore(*assign, *callSt->controlParent());
|
|
|
|
|
|
|
|
|
|
|
|
// replace function call to a new variable
|
|
|
|
|
|
if (!par)
|
|
|
|
|
|
callSt->setExpression(i, new SgVarRefExp(*v));
|
|
|
|
|
|
else
|
|
|
|
|
|
lhs ? par->setLhs(new SgVarRefExp(*v)) : par->setRhs(new SgVarRefExp(*v));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-22 20:21:18 +03:00
|
|
|
|
static void recFindFuncCall(FuncInfo* currentFuncI,
|
|
|
|
|
|
SgExpression* exp, SgExpression* par, const int i, const bool lhs,
|
2023-09-14 19:43:13 +03:00
|
|
|
|
const string& funcName, bool& foundCall,
|
|
|
|
|
|
SgStatement* callSt, set<SgSymbol*>& newSymbols, SgStatement* insertPlace)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (exp)
|
|
|
|
|
|
{
|
2023-11-22 20:21:18 +03:00
|
|
|
|
recFindFuncCall(currentFuncI, exp->rhs(), exp, i, false, funcName, foundCall, callSt, newSymbols, insertPlace);
|
|
|
|
|
|
recFindFuncCall(currentFuncI, exp->lhs(), exp, i, true, funcName, foundCall, callSt, newSymbols, insertPlace);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
2023-11-22 20:21:18 +03:00
|
|
|
|
if (exp->variant() == FUNC_CALL && exp->symbol() &&
|
|
|
|
|
|
currentFuncI->getCallName(make_pair(exp, exp->variant()), exp->symbol()->identifier(), callSt->lineNumber()) == funcName)
|
2023-09-14 19:43:13 +03:00
|
|
|
|
{
|
|
|
|
|
|
foundCall = true;
|
|
|
|
|
|
if (par) // do not extract external func call
|
|
|
|
|
|
replaceCall(exp, par, i, lhs, callSt, newSymbols, insertPlace);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int ParameterType(SgExpression* exp, SgStatement* st)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isSgVarRefExp(exp) || // scalar variable
|
|
|
|
|
|
isSgArrayRefExp(exp) || // array variable
|
|
|
|
|
|
exp->variant() == CONST_REF || // symbol (named) constant
|
|
|
|
|
|
isSgValueExp(exp))// && exp->type()->variant() != T_STRING) // literal constant
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline void PrecalculateExpression(SgSymbol* sp, SgExpression* e, SgStatement* stmt)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgStatement* newst;
|
|
|
|
|
|
newst = new SgAssignStmt(*new SgVarRefExp(sp), *e);
|
|
|
|
|
|
newst->setlineNumber(getNextNegativeLineNumber());
|
|
|
|
|
|
stmt->insertStmtBefore(*newst, *stmt->controlParent());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static SgType* SgTypeFromFile(SgFile* f, int type)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgType* t;
|
|
|
|
|
|
for (t = f->firstType(); t; t = t->next())
|
|
|
|
|
|
if (t->variant() == type)
|
|
|
|
|
|
return t;
|
|
|
|
|
|
|
|
|
|
|
|
return new SgType(type);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//TODO: more types
|
|
|
|
|
|
static SgType* getTrueType(SgType* inExp, parF funcParType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (funcParType == SCALAR_FLOAT_T)
|
|
|
|
|
|
return SgTypeFloat();
|
|
|
|
|
|
else if (funcParType == SCALAR_DOUBLE_T)
|
|
|
|
|
|
return SgTypeDouble();
|
|
|
|
|
|
else if (funcParType == SCALAR_CMPLX_FLOAT_T)
|
|
|
|
|
|
return SgTypeFromFile(current_file, T_COMPLEX);
|
|
|
|
|
|
else if (funcParType == SCALAR_CMPLX_DOUBLE_T)
|
|
|
|
|
|
return SgTypeFromFile(current_file, T_DCOMPLEX);
|
|
|
|
|
|
else
|
|
|
|
|
|
return inExp;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-22 20:21:18 +03:00
|
|
|
|
static inline void PrecalculateActualParameters(SgStatement* st, SgExpression* e,
|
2023-09-14 19:43:13 +03:00
|
|
|
|
const FuncInfo* func, set<SgSymbol*>& newSymbols)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Precalculate actual parameter expressions
|
|
|
|
|
|
// e - actual parameter list
|
|
|
|
|
|
SgExpression* el;
|
|
|
|
|
|
SgSymbol* sp;
|
|
|
|
|
|
if (!e)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
//TODO: added exclude list!
|
|
|
|
|
|
//if (is_NoExpansionFunction(s))
|
|
|
|
|
|
//return;
|
|
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
for (el = e; el; el = el->rhs(), i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (ParameterType(el->lhs(), st))
|
|
|
|
|
|
{
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
break; // actual parameter can be accessed by reference
|
|
|
|
|
|
//case 2: PrecalculateSubscripts(el->lhs(),stmt); break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
sp = createSymbAndDecl("null", "arg", NULL, newSymbols, getTrueType(el->lhs()->type(), func->funcParams.parametersT[i]));
|
|
|
|
|
|
PrecalculateExpression(sp, el->lhs(), st); //to support access by reference
|
|
|
|
|
|
el->setLhs(new SgVarRefExp(sp)); //replace actual parameter expression by 'sp' reference
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void renameArgs(SgExpression* ex, const map<string, string>& remapArgs)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex->variant() == VAR_REF || ex->variant() == ARRAY_REF)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto s = ex->symbol();
|
|
|
|
|
|
if (s)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto it = remapArgs.find(s->identifier());
|
|
|
|
|
|
if (it != remapArgs.end())
|
|
|
|
|
|
ex->setSymbol(findSymbolOrCreate(current_file, it->second, s->type()));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
renameArgs(ex->lhs(), remapArgs);
|
|
|
|
|
|
renameArgs(ex->rhs(), remapArgs);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void renameArgsIfGlobalNameIntersection(FuncInfo* func, const set<string>& globalNames)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (func->isMain)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
map<string, string> remapArgs;
|
|
|
|
|
|
for (auto& par : func->funcParams.identificators)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (globalNames.find(par) != globalNames.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
int tmp = 0;
|
|
|
|
|
|
string newName = "";
|
|
|
|
|
|
do {
|
|
|
|
|
|
newName = par + to_string(tmp++);
|
|
|
|
|
|
} while (globalNames.find(newName) != globalNames.end());
|
|
|
|
|
|
remapArgs[par] = newName;
|
|
|
|
|
|
par = newName;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (remapArgs.size() == 0)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
auto header = func->funcPointer->GetOriginal();
|
|
|
|
|
|
auto last = header->lastNodeOfStmt();
|
|
|
|
|
|
for (SgStatement* st = header->lexNext(); st != last; st = st->lexNext())
|
|
|
|
|
|
for (int z = 0; z < 3; ++z)
|
|
|
|
|
|
renameArgs(st->expr(z), remapArgs);
|
|
|
|
|
|
|
2023-11-28 12:58:22 +03:00
|
|
|
|
auto prog = isSgProcHedrStmt(header);
|
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
PTR_SYMB listP = SYMB_FUNC_PARAM(BIF_SYMB(prog->thebif));
|
|
|
|
|
|
vector<PTR_SYMB> newElems;
|
|
|
|
|
|
for (int p = 0; p < prog->numberOfParameters(); ++p)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgSymbol* par = prog->parameter(p);
|
|
|
|
|
|
auto it = remapArgs.find(par->identifier());
|
|
|
|
|
|
|
|
|
|
|
|
if (it != remapArgs.end())
|
|
|
|
|
|
{
|
2023-11-28 12:58:22 +03:00
|
|
|
|
SgSymbol* replace = par->copyPtr();
|
|
|
|
|
|
replace->changeName(it->second.c_str());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
newElems.push_back(replace->thesymb);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2023-11-28 12:58:22 +03:00
|
|
|
|
newElems.push_back(duplicateSymbol(listP));
|
2023-09-14 19:43:13 +03:00
|
|
|
|
listP = SYMB_NEXT_DECL(listP);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
listP = newElems[0];
|
|
|
|
|
|
PTR_SYMB p = listP;
|
|
|
|
|
|
for (int z = 1; z < newElems.size(); ++z)
|
|
|
|
|
|
{
|
|
|
|
|
|
SYMB_NEXT_DECL(p) = newElems[z];
|
|
|
|
|
|
p = SYMB_NEXT_DECL(p);
|
|
|
|
|
|
}
|
|
|
|
|
|
SYMB_FUNC_PARAM(BIF_SYMB(prog->thebif)) = listP;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void findUsed(SgExpression* ex, set<string>& used)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex->variant() == VAR_REF)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto s = ex->symbol();
|
|
|
|
|
|
if (s)
|
|
|
|
|
|
used.insert(s->identifier());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
findUsed(ex->lhs(), used);
|
|
|
|
|
|
findUsed(ex->rhs(), used);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static map<SgStatement*, set<string>> usedByFunc;
|
|
|
|
|
|
|
|
|
|
|
|
static bool run_inliner(const map<string, FuncInfo*>& funcMap, set<SgStatement*>& toInsert, map<string, vector<Messages>>& SPF_messages,
|
|
|
|
|
|
const string& fileName, const FuncInfo* func, map<SgStatement*, set<SgSymbol*>>& newSymbsToDeclare,
|
|
|
|
|
|
const PointCall& point,
|
|
|
|
|
|
const map<string, CommonBlock*>& commonBlocks)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool isInlined = false;
|
|
|
|
|
|
const string& funcName = func->funcName;
|
|
|
|
|
|
|
|
|
|
|
|
set<string> globalNames;
|
|
|
|
|
|
for (auto& common : commonBlocks)
|
|
|
|
|
|
for (auto& var : common.second->getVariables())
|
|
|
|
|
|
globalNames.insert(var->getName());
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& callSt : toInsert)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgStatement* insertPlace = callSt;
|
2023-11-22 20:21:18 +03:00
|
|
|
|
SgProgHedrStmt* currentFunc = (SgProgHedrStmt*) getFuncStat(callSt);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
if (usedByFunc.find(currentFunc) == usedByFunc.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
set<string> used;
|
|
|
|
|
|
for (auto st = currentFunc->lexNext(); st != currentFunc->lastNodeOfStmt(); st = st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isSgExecutableStatement(st))
|
|
|
|
|
|
for (int z = 0; z < 3; ++z)
|
|
|
|
|
|
findUsed(st->expr(z), used);
|
|
|
|
|
|
|
|
|
|
|
|
if (st->variant() == CONTAINS_STMT)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
usedByFunc[currentFunc] = used;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-22 20:21:18 +03:00
|
|
|
|
auto itF = funcMap.find(currentFunc->nameWithContains());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
if (itF == funcMap.end())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
2023-11-22 20:21:18 +03:00
|
|
|
|
FuncInfo* currentFuncI = itF->second;
|
|
|
|
|
|
renameArgsIfGlobalNameIntersection(currentFuncI, globalNames);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
set<string> useStatsInFunc;
|
|
|
|
|
|
for (SgStatement* s = currentFunc; s != currentFunc->lastNodeOfStmt(); s = s->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s->variant() == CONTAINS_STMT)
|
|
|
|
|
|
break;
|
|
|
|
|
|
if (s->variant() == USE_STMT)
|
|
|
|
|
|
useStatsInFunc.insert(s->unparse());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SgStatement* funcStat = func->funcPointer->GetOriginal();
|
|
|
|
|
|
if (funcStat->fileName() != fileName)
|
|
|
|
|
|
{
|
|
|
|
|
|
//get from shadow copies
|
|
|
|
|
|
auto itF = hiddenData.find(fileName);
|
|
|
|
|
|
if (itF == hiddenData.end())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
const string fromFile = funcStat->fileName();
|
|
|
|
|
|
const int line = funcStat->lineNumber();
|
|
|
|
|
|
|
|
|
|
|
|
bool done = false;
|
|
|
|
|
|
for (auto& shadowFunc : itF->second)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (shadowFunc->fileName() == fromFile && shadowFunc->lineNumber() == line)
|
|
|
|
|
|
{
|
|
|
|
|
|
funcStat = shadowFunc;
|
|
|
|
|
|
done = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!done)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
set<SgSymbol*> newSymbols;
|
|
|
|
|
|
bool foundCall = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (!callSt || !isSgExecutableStatement(callSt))
|
|
|
|
|
|
{
|
|
|
|
|
|
wstring messageE, messageR;
|
|
|
|
|
|
__spf_printToLongBuf(messageE, L"It is allowed to inline function only at execution code section.");
|
|
|
|
|
|
__spf_printToLongBuf(messageR, R177);
|
2024-09-30 20:24:34 +03:00
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
getObjectForFileFromMap(fileName.c_str(), SPF_messages).push_back(Messages(ERROR, insertPlace->lineNumber(), messageR, messageE, 2011));
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-28 12:58:22 +03:00
|
|
|
|
__spf_print(DEB, "------start inliner-----\n");
|
|
|
|
|
|
__spf_print(DEB, "---statement preprocessing---\n");
|
2023-09-14 19:43:13 +03:00
|
|
|
|
//simple convertation
|
|
|
|
|
|
if (callSt->controlParent()->variant() == LOGIF_NODE)
|
|
|
|
|
|
LogIftoIfThen(callSt->controlParent());
|
|
|
|
|
|
|
|
|
|
|
|
SgStatement* begin = callSt->lexPrev();
|
|
|
|
|
|
SgStatement* end = callSt->lexNext();
|
|
|
|
|
|
|
|
|
|
|
|
// 1.a: make statement preprocessing
|
|
|
|
|
|
// if call statement contains several inlining functions, split every such call
|
|
|
|
|
|
for (int i = 0; i < 3; ++i)
|
2023-11-22 20:21:18 +03:00
|
|
|
|
recFindFuncCall(currentFuncI, callSt->expr(i), NULL, i, false, funcName, foundCall, callSt, newSymbols, insertPlace);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
2023-11-28 12:58:22 +03:00
|
|
|
|
__spf_print(DEB, "---argument preprocessing---\n");
|
2023-09-14 19:43:13 +03:00
|
|
|
|
// 1.b: make argument preprocessing
|
|
|
|
|
|
checkNull(begin, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
// if call statement has any expression as its artument, split this expression for separate statement
|
|
|
|
|
|
// if call statement has any function as its argument, split this call
|
|
|
|
|
|
for (auto st = begin->lexNext(); st != end; st = st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->variant() == ASSIGN_STAT)
|
|
|
|
|
|
{
|
2023-11-22 20:21:18 +03:00
|
|
|
|
auto rPart = st->expr(1);
|
|
|
|
|
|
int line = st->lineNumber() < 0 ? st->localLineNumber() : st->lineNumber();
|
|
|
|
|
|
if (rPart->variant() == FUNC_CALL && rPart->symbol() &&
|
|
|
|
|
|
currentFuncI->getCallName(make_pair(rPart, rPart->variant()), rPart->symbol()->identifier(), line) == funcName)
|
|
|
|
|
|
{
|
2023-09-14 19:43:13 +03:00
|
|
|
|
if (isSgVarRefExp(st->expr(0)) || isSgArrayRefExp(st->expr(0)) && !isSgArrayType(st->expr(0)->type()))
|
2023-11-22 20:21:18 +03:00
|
|
|
|
PrecalculateActualParameters(st, st->expr(1)->lhs(), func, newSymbols);
|
|
|
|
|
|
}
|
2023-09-14 19:43:13 +03:00
|
|
|
|
}
|
|
|
|
|
|
else if (st->variant() == PROC_STAT)
|
|
|
|
|
|
{
|
2023-11-22 20:21:18 +03:00
|
|
|
|
if (st->symbol() &&
|
|
|
|
|
|
currentFuncI->getCallName(make_pair(st, st->variant()), st->symbol()->identifier(), st->lineNumber()) == funcName)
|
2023-09-14 19:43:13 +03:00
|
|
|
|
{
|
|
|
|
|
|
foundCall = true;
|
|
|
|
|
|
if (st->expr(0))
|
2023-11-22 20:21:18 +03:00
|
|
|
|
PrecalculateActualParameters(st, st->expr(0), func, newSymbols);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
set<SgStatement*> useStats;
|
2023-11-28 12:58:22 +03:00
|
|
|
|
__spf_print(DEB, "---start inlining---\n");
|
2023-09-14 19:43:13 +03:00
|
|
|
|
// 2. create function template to modify and insert it
|
|
|
|
|
|
if (foundCall)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool change = true;
|
|
|
|
|
|
|
|
|
|
|
|
while (change)
|
|
|
|
|
|
{
|
|
|
|
|
|
change = false;
|
|
|
|
|
|
vector<SgStatement*> toDelete;
|
|
|
|
|
|
for (auto st = begin->lexNext(); st != end; st = st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (st->variant())
|
|
|
|
|
|
{
|
|
|
|
|
|
case ASSIGN_STAT:
|
|
|
|
|
|
{
|
2023-11-22 20:21:18 +03:00
|
|
|
|
auto rPart = st->expr(1);
|
|
|
|
|
|
int line = st->lineNumber() < 0 ? st->localLineNumber() : st->lineNumber();
|
|
|
|
|
|
if (rPart->variant() == FUNC_CALL && rPart->symbol() &&
|
|
|
|
|
|
currentFuncI->getCallName(make_pair(rPart, rPart->variant()), rPart->symbol()->identifier(), line) == funcName)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool doInline = insert(st, funcStat, rPart->lhs(), newSymbols, funcMap, toDelete, useStats, SPF_messages, point);
|
|
|
|
|
|
change |= doInline;
|
|
|
|
|
|
isInlined |= doInline;
|
|
|
|
|
|
}
|
2023-09-14 19:43:13 +03:00
|
|
|
|
}
|
2023-11-22 20:21:18 +03:00
|
|
|
|
break;
|
2023-09-14 19:43:13 +03:00
|
|
|
|
case PROC_STAT:
|
2023-11-22 20:21:18 +03:00
|
|
|
|
if (st->symbol() &&
|
|
|
|
|
|
currentFuncI->getCallName(make_pair(st, st->variant()), st->symbol()->identifier(), st->lineNumber()) == funcName)
|
2023-09-14 19:43:13 +03:00
|
|
|
|
{
|
|
|
|
|
|
bool doInline = insert(st, funcStat, st->expr(0), newSymbols, funcMap, toDelete, useStats, SPF_messages, point);
|
|
|
|
|
|
change |= doInline;
|
|
|
|
|
|
isInlined |= doInline;
|
|
|
|
|
|
}
|
2023-11-22 20:21:18 +03:00
|
|
|
|
break;
|
2023-09-14 19:43:13 +03:00
|
|
|
|
default:
|
2023-11-22 20:21:18 +03:00
|
|
|
|
break;
|
2023-09-14 19:43:13 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& st : toDelete)
|
|
|
|
|
|
st->extractStmt();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& use : useStats)
|
|
|
|
|
|
{
|
|
|
|
|
|
string currUse = use->unparse();
|
|
|
|
|
|
if (useStatsInFunc.find(currUse) == useStatsInFunc.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
useStatsInFunc.insert(currUse);
|
|
|
|
|
|
currentFunc->insertStmtAfter(*use, *currentFunc);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
checkSymbols(currentFunc->getFileId(), newSymbols);
|
|
|
|
|
|
for (auto& symb : newSymbols)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (symb->variant() == CONSTRUCT_NAME)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
newSymbsToDeclare[currentFunc].insert(symb);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return isInlined;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static vector<pair<SgStatement*, SgStatement*>> getNextBounds(SgStatement* point)
|
|
|
|
|
|
{
|
|
|
|
|
|
vector<pair<SgStatement*, SgStatement*>> parts;
|
|
|
|
|
|
pair<SgStatement*, SgStatement*> newPart;
|
|
|
|
|
|
bool sectionStarted = false;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto st = point; st != point->lastNodeOfStmt(); st = st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->variant() == CONTAINS_STMT)
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
if (st->variant() == GLOBAL)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!sectionStarted)
|
|
|
|
|
|
{
|
|
|
|
|
|
newPart.first = st;
|
|
|
|
|
|
sectionStarted = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (sectionStarted)
|
|
|
|
|
|
{
|
|
|
|
|
|
newPart.second = st;
|
|
|
|
|
|
parts.push_back(newPart);
|
|
|
|
|
|
sectionStarted = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (sectionStarted)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
return parts;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool dontInlineByAttribute(SgStatement* st)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool dontInline = false;
|
|
|
|
|
|
for (int k = 0; k < st->numberOfAttributes(); ++k)
|
|
|
|
|
|
if (st->getAttribute(k)->getAttributeType() == BOOL_VAL)
|
|
|
|
|
|
dontInline = true;
|
|
|
|
|
|
|
|
|
|
|
|
if (dontInline)
|
|
|
|
|
|
__spf_print(1, " skip call in statement with line %d by attribute\n", st->lineNumber());
|
|
|
|
|
|
return dontInline;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void fillNewFunctions(SgExpression* ex, SgStatement* main,
|
|
|
|
|
|
map<FuncInfo*, set<SgStatement*>>& nextInfo,
|
|
|
|
|
|
const map<string, FuncInfo*>& funcMap)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex->variant() == FUNC_CALL)
|
|
|
|
|
|
if (funcMap.find(ex->symbol()->identifier()) != funcMap.end())
|
|
|
|
|
|
if (!dontInlineByAttribute(main))
|
|
|
|
|
|
nextInfo[funcMap.at(ex->symbol()->identifier())].insert(main);
|
|
|
|
|
|
|
|
|
|
|
|
fillNewFunctions(ex->lhs(), main, nextInfo, funcMap);
|
|
|
|
|
|
fillNewFunctions(ex->rhs(), main, nextInfo, funcMap);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void fillNewFunctions(SgStatement* begin, SgStatement* end,
|
|
|
|
|
|
map<FuncInfo*, set<SgStatement*>>& nextInfo,
|
|
|
|
|
|
const map<string, FuncInfo*>& funcMap)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto st = begin; st != end; st = st->lexNext())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (st->variant() == PROC_STAT)
|
|
|
|
|
|
if (funcMap.find(st->symbol()->identifier()) != funcMap.end())
|
|
|
|
|
|
if (!dontInlineByAttribute(st))
|
|
|
|
|
|
nextInfo[funcMap.at(st->symbol()->identifier())].insert(st);
|
|
|
|
|
|
|
|
|
|
|
|
for (int z = 0; z < 3; ++z)
|
|
|
|
|
|
fillNewFunctions(st->expr(z), st, nextInfo, funcMap);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static map<FuncInfo*, set<SgStatement*>> fillNextDeep(const set<SgStatement*>& insertedIn, const map<string, FuncInfo*>& funcMap)
|
|
|
|
|
|
{
|
|
|
|
|
|
map<FuncInfo*, set<SgStatement*>> nextInfo;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& point : insertedIn)
|
|
|
|
|
|
for (auto& part : getNextBounds(point))
|
|
|
|
|
|
fillNewFunctions(part.first, part.second, nextInfo, funcMap);
|
|
|
|
|
|
|
|
|
|
|
|
return nextInfo;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-30 20:24:34 +03:00
|
|
|
|
static void addMessage(bool status, map<string, vector<Messages>>& SPF_messages, const string& fileName, const int line)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (status == true)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
wstring messageE, messageR;
|
|
|
|
|
|
__spf_printToLongBuf(messageE, L"Function inlining failed with an error.");
|
|
|
|
|
|
__spf_printToLongBuf(messageR, R193);
|
|
|
|
|
|
|
|
|
|
|
|
getObjectForFileFromMap(fileName.c_str(), SPF_messages).push_back(Messages(ERROR, line, messageR, messageE, 2020));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-26 18:57:05 +03:00
|
|
|
|
static bool inliner(const string& fileName_in, const string& funcName, const int lineNumber,
|
|
|
|
|
|
const map<string, vector<FuncInfo*>>& allFuncInfo, map<string, vector<Messages>>& SPF_messages,
|
|
|
|
|
|
map<SgStatement*, set<SgSymbol*>>& newSymbsToDeclare, const map<string, CommonBlock*>& commonBlocks,
|
|
|
|
|
|
int deepLvl = 0)
|
2023-11-28 12:58:22 +03:00
|
|
|
|
{
|
2023-09-14 19:43:13 +03:00
|
|
|
|
map<string, FuncInfo*> funcMap;
|
|
|
|
|
|
createMapOfFunc(allFuncInfo, funcMap);
|
|
|
|
|
|
|
|
|
|
|
|
auto func = getFuncInfo(funcMap, funcName);
|
|
|
|
|
|
const string& fileName = (fileName_in == "") ? func->fileName : fileName_in;
|
|
|
|
|
|
|
|
|
|
|
|
if (func && !func->doNotInline)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SgFile::switchToFile(fileName) == -1)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
//TODO:
|
|
|
|
|
|
// now function is expected to be declared in the target file
|
|
|
|
|
|
set<SgStatement*> toInsert;
|
|
|
|
|
|
if (lineNumber > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgStatement* callSt = SgStatement::getStatementByFileAndLine(fileName, lineNumber);
|
|
|
|
|
|
if (callSt)
|
|
|
|
|
|
toInsert.insert(callSt);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& callTo : func->callsTo)
|
|
|
|
|
|
{
|
2023-11-05 13:08:57 +03:00
|
|
|
|
for (auto& callInfo : callTo->callsFromDetailed)
|
2023-09-14 19:43:13 +03:00
|
|
|
|
{
|
2023-11-05 13:08:57 +03:00
|
|
|
|
auto& callFrom = callInfo.detailCallsFrom;
|
2023-09-14 19:43:13 +03:00
|
|
|
|
if (callFrom.first == funcName)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgStatement* callSt = SgStatement::getStatementByFileAndLine(fileName, callFrom.second);
|
|
|
|
|
|
if (callSt)
|
|
|
|
|
|
toInsert.insert(callSt);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
set<SgStatement*> insertedIn;
|
|
|
|
|
|
set<SgStatement*> markers;
|
|
|
|
|
|
for (auto& elem : toInsert)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool dontInline = dontInlineByAttribute(elem);
|
|
|
|
|
|
|
|
|
|
|
|
if (dontInline)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
insertedIn.insert(getFuncStat(elem));
|
|
|
|
|
|
//insert bounds
|
|
|
|
|
|
auto cp = elem->controlParent();
|
|
|
|
|
|
auto boundAfter = new SgStatement(GLOBAL);
|
|
|
|
|
|
auto boundBefore = new SgStatement(GLOBAL);
|
|
|
|
|
|
|
|
|
|
|
|
elem->insertStmtBefore(*boundAfter, *cp);
|
|
|
|
|
|
elem->insertStmtAfter(*boundBefore, *cp);
|
|
|
|
|
|
|
|
|
|
|
|
markers.insert(boundAfter);
|
|
|
|
|
|
markers.insert(boundBefore);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (markers.size() == 0)
|
2023-11-22 20:21:18 +03:00
|
|
|
|
return false;
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
PointCall point;
|
|
|
|
|
|
point.mainPoint.first = fileName;
|
|
|
|
|
|
point.mainPoint.second = lineNumber;
|
|
|
|
|
|
|
|
|
|
|
|
point.func = func;
|
|
|
|
|
|
point.currLvl = 0;
|
|
|
|
|
|
point.currCall = func->funcName;
|
|
|
|
|
|
|
2024-02-25 11:16:56 +03:00
|
|
|
|
__spf_print(1, " INLINE %s - ", func->funcName.c_str());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(func->funcName.begin(), func->funcName.end()) + L"'");
|
|
|
|
|
|
#else
|
|
|
|
|
|
sendMessage_2lvl(wstring(L"inlinig of function '") + wstring(func->funcName.begin(), func->funcName.end()) + L"'");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
//1 level
|
|
|
|
|
|
bool isInlined = run_inliner(funcMap, toInsert, SPF_messages, fileName, func, newSymbsToDeclare, point, commonBlocks);
|
2024-02-25 11:16:56 +03:00
|
|
|
|
__spf_print(1, "%s\n", isInlined ? "done" : "fault");
|
2024-09-30 20:24:34 +03:00
|
|
|
|
addMessage(isInlined, SPF_messages, fileName, lineNumber);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
2023-11-22 20:21:18 +03:00
|
|
|
|
if (isInlined == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
__spf_print(1, " missing ...\n");
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
if (deepLvl >= 0 && isInlined)
|
|
|
|
|
|
{
|
|
|
|
|
|
int currDeep = 0;
|
|
|
|
|
|
bool changed = true;
|
|
|
|
|
|
while (changed)
|
|
|
|
|
|
{
|
|
|
|
|
|
changed = false;
|
|
|
|
|
|
currDeep++;
|
|
|
|
|
|
if (deepLvl > 0 && deepLvl <= currDeep)
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& next : fillNextDeep(insertedIn, funcMap))
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int p = 0; p < currDeep; ++p)
|
|
|
|
|
|
__spf_print(1, " ");
|
|
|
|
|
|
|
|
|
|
|
|
if (next.first->doNotInline)
|
|
|
|
|
|
{
|
|
|
|
|
|
__spf_print(1, "skip %s by flag\n", next.first->funcName.c_str());
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
point.currLvl = currDeep;
|
|
|
|
|
|
point.currCall = next.first->funcName;
|
2024-02-25 11:16:56 +03:00
|
|
|
|
__spf_print(1, " INLINE %s - ", next.first->funcName.c_str());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
bool isInlined = run_inliner(funcMap, next.second, SPF_messages, fileName, next.first, newSymbsToDeclare, point, commonBlocks);
|
2024-02-25 11:16:56 +03:00
|
|
|
|
__spf_print(1, "%s\n", isInlined ? "done" : "fault");
|
2024-09-30 20:24:34 +03:00
|
|
|
|
addMessage(isInlined, SPF_messages, fileName, lineNumber);
|
|
|
|
|
|
|
2023-09-14 19:43:13 +03:00
|
|
|
|
changed |= isInlined;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& marker : markers)
|
|
|
|
|
|
marker->extractStmt();
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-26 18:57:05 +03:00
|
|
|
|
static bool inliner(const string& allInFunc, const map<string, vector<FuncInfo*>>& allFuncInfo,
|
|
|
|
|
|
map<string, vector<Messages>>& SPF_messages,
|
|
|
|
|
|
map<SgStatement*, set<SgSymbol*>>& newSymbsToDeclare, const map<string, CommonBlock*>& commonBlocks,
|
|
|
|
|
|
int deepLvl = 0)
|
2023-09-14 19:43:13 +03:00
|
|
|
|
{
|
|
|
|
|
|
bool result = true;
|
|
|
|
|
|
map<string, FuncInfo*> funcMap;
|
|
|
|
|
|
createMapOfFunc(allFuncInfo, funcMap);
|
|
|
|
|
|
|
|
|
|
|
|
auto func = getFuncInfo(funcMap, allInFunc);
|
|
|
|
|
|
if (func && !func->doNotInline)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SgFile::switchToFile(func->fileName) == -1)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
2023-11-05 13:08:57 +03:00
|
|
|
|
for (auto& callInfo : func->callsFromDetailed)
|
2023-09-14 19:43:13 +03:00
|
|
|
|
{
|
2023-11-05 13:08:57 +03:00
|
|
|
|
auto& callFrom = callInfo.detailCallsFrom;
|
2023-09-14 19:43:13 +03:00
|
|
|
|
bool res = inliner(func->fileName, callFrom.first, callFrom.second, allFuncInfo, SPF_messages, newSymbsToDeclare, commonBlocks, deepLvl);
|
|
|
|
|
|
result = result && res;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static vector<SgSymbol*> sortConstRefs(const map<string, SgSymbol*>& constRefs)
|
|
|
|
|
|
{
|
|
|
|
|
|
map<SgSymbol*, set<string>> deps;
|
|
|
|
|
|
map<SgSymbol*, pair<string, int>> constRefByFunc; // value is <funcName, fileId>
|
|
|
|
|
|
for (auto& byF : replacedConstRef)
|
|
|
|
|
|
for (auto& s : byF.second)
|
|
|
|
|
|
constRefByFunc[s.second.first] = byF.first;
|
|
|
|
|
|
|
|
|
|
|
|
bool printInternal = false;
|
|
|
|
|
|
for (auto& elem : constRefs)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgSymbol* s = elem.second;
|
|
|
|
|
|
|
|
|
|
|
|
if (constRefByFunc.find(s) == constRefByFunc.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
__spf_print(1, " const not found '%s' with id %d\n", s->identifier(), s->id());
|
|
|
|
|
|
printInternal = true;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
auto& inFunc = constRefByFunc[s];
|
|
|
|
|
|
map<string, pair<SgSymbol*, string>>& byFuncRefpl = replacedConstRef[inFunc];
|
|
|
|
|
|
|
|
|
|
|
|
deps[s] = set<string>();
|
|
|
|
|
|
set<SgSymbol*> tmp;
|
|
|
|
|
|
findAllConstRef(isSgConstantSymb(elem.second)->constantValue(), tmp);
|
|
|
|
|
|
for (auto& ref : tmp)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto itS = byFuncRefpl.find(ref->identifier());
|
|
|
|
|
|
if (itS != byFuncRefpl.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto newName = itS->second.second.c_str();
|
|
|
|
|
|
ref->changeName(newName);
|
|
|
|
|
|
deps[elem.second].insert(newName);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
deps[s].insert(ref->identifier());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (printInternal)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
set<string> added;
|
|
|
|
|
|
vector<SgSymbol*> result;
|
|
|
|
|
|
for (auto& elem : deps)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool existInRef = false;
|
|
|
|
|
|
for (auto& dep : elem.second)
|
|
|
|
|
|
if (constRefs.find(dep) != constRefs.end())
|
|
|
|
|
|
existInRef = true;
|
|
|
|
|
|
|
|
|
|
|
|
if (!existInRef)
|
|
|
|
|
|
{
|
|
|
|
|
|
result.push_back(elem.first);
|
|
|
|
|
|
added.insert(elem.first->identifier());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while (result.size() != constRefs.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& elem : deps)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (added.find(elem.first->identifier()) != added.end())
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
bool needToAdd = true;
|
|
|
|
|
|
for (auto& dep : elem.second)
|
|
|
|
|
|
if (added.find(dep) == added.end() && (dep != elem.first->identifier()))
|
|
|
|
|
|
needToAdd = false;
|
|
|
|
|
|
if (needToAdd)
|
|
|
|
|
|
{
|
|
|
|
|
|
result.push_back(elem.first);
|
|
|
|
|
|
added.insert(elem.first->identifier());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static pair<string, int> getCommonInfo(SgSymbol* toDec)
|
|
|
|
|
|
{
|
|
|
|
|
|
pair<string, int> info = make_pair("NULL", -1);
|
|
|
|
|
|
|
|
|
|
|
|
auto attrsC = getAttributes<SgSymbol*, char*>(toDec, set<int> { COMM_STAT });
|
|
|
|
|
|
if (attrsC.size() && attrsC.size() != 1)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
if (attrsC.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto attrsPos = getAttributes<SgSymbol*, int*>(toDec, set<int> { COMM_LIST });
|
|
|
|
|
|
if (attrsPos.size() && attrsPos.size() != 1)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
info.first = attrsC[0];
|
|
|
|
|
|
info.second = *attrsPos[0];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return info;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool addNewCommonDecl(SgSymbol* toDec, const int posNum, const string& commName,
|
|
|
|
|
|
map<string, vector<SgExpression*>>& commonBlocksRef,
|
|
|
|
|
|
const map<string, CommonBlock*>& commonBlocks,
|
|
|
|
|
|
map<string, map<int, SgSymbol*>>& commons,
|
|
|
|
|
|
const string& needToRename)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (posNum != -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (needToRename != "")
|
|
|
|
|
|
toDec->changeName(needToRename.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
auto itCommRef = commonBlocksRef.find(commName);
|
|
|
|
|
|
if (itCommRef == commonBlocksRef.end())
|
|
|
|
|
|
commons[commName][posNum] = toDec; // sort by position
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
auto it = commonBlocks.find(commName);
|
|
|
|
|
|
if (it == commonBlocks.end())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
auto groupedByPos = it->second->getGroupedVars();
|
|
|
|
|
|
auto itG = groupedByPos.find(posNum);
|
|
|
|
|
|
|
|
|
|
|
|
if (itG == groupedByPos.end() || itG != groupedByPos.end() && itG->second.size() == 1)
|
|
|
|
|
|
commons[commName][posNum] = toDec; // sort by position
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
int idx = 0;
|
|
|
|
|
|
SgExpression* ex = NULL;
|
|
|
|
|
|
for (auto& elem : itCommRef->second)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto list = elem->lhs(); list && !ex; list = list->rhs(), ++idx)
|
|
|
|
|
|
if (idx == posNum)
|
|
|
|
|
|
ex = list->lhs();
|
|
|
|
|
|
|
|
|
|
|
|
if (ex)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ex == NULL)
|
|
|
|
|
|
commons[commName][posNum] = toDec; // sort by position
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex->symbol() == NULL)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
if (ex->symbol()->identifier() != string(toDec->identifier()))
|
|
|
|
|
|
{
|
|
|
|
|
|
toDec->changeName(ex->symbol()->identifier());
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
commons[commName][posNum] = toDec; // sort by position
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-26 18:57:05 +03:00
|
|
|
|
static void createDeclarations(const map<SgStatement*, set<SgSymbol*>>& newSymbsToDeclare, const map<string, CommonBlock*>& commonBlocks)
|
2023-09-14 19:43:13 +03:00
|
|
|
|
{
|
|
|
|
|
|
map<pair<string, int>, map<string, string>> preprocDataByFunc; // key is <funcName, int>
|
|
|
|
|
|
map<pair<string, int>, map<string, SgExpression*>> initValue;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& dataByF : dataDeclsByFunc)
|
|
|
|
|
|
preprocDataByFunc[dataByF.first] = splitData(dataByF.second);
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& dataByF : dataDeclsByFuncS)
|
|
|
|
|
|
{
|
|
|
|
|
|
initValue[dataByF.first] = dataByF.second;
|
|
|
|
|
|
for (auto& elem : dataByF.second)
|
|
|
|
|
|
preprocDataByFunc[dataByF.first][elem.first] = "---";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
map<SgSymbol*, pair<pair<string, int>, string>> originalInfo; // value is <<funcName, int>, sName>
|
|
|
|
|
|
for (auto& elem : createdByFunc)
|
|
|
|
|
|
for (auto& s : elem.second)
|
|
|
|
|
|
originalInfo[s.second] = make_pair(elem.first, s.first);
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& byFunc : newSymbsToDeclare)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!byFunc.first->switchToFile())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
__spf_print(1, "symbols checking for function '%s'\n", byFunc.first->symbol()->identifier());
|
|
|
|
|
|
int currFileId = byFunc.first->getFileId();
|
|
|
|
|
|
checkSymbols(currFileId, byFunc.second);
|
|
|
|
|
|
|
|
|
|
|
|
map<string, vector<SgExpression*>> commonBlocksRef;
|
|
|
|
|
|
getCommonBlocksRef(commonBlocksRef, byFunc.first, byFunc.first ? byFunc.first->lastNodeOfStmt() : NULL);
|
|
|
|
|
|
|
|
|
|
|
|
map<string, map<string, vector<SgSymbol*>>> groups;
|
|
|
|
|
|
map<string, map<string, vector<SgSymbol*>>> groupsConstRefs;
|
|
|
|
|
|
map<string, map<int, SgSymbol*>> commons;
|
|
|
|
|
|
map<string, SgSymbol*> constRefs;
|
|
|
|
|
|
map<string, SgSymbol*> saveRefs;
|
|
|
|
|
|
map<SgSymbol*, string> declRefs;
|
|
|
|
|
|
map<SgSymbol*, SgExpression*> declInitInfo;
|
|
|
|
|
|
set<SgSymbol*> allocatable;
|
|
|
|
|
|
map<string, int> commonRenames;
|
|
|
|
|
|
|
|
|
|
|
|
SgStatement* place = byFunc.first;
|
|
|
|
|
|
while (isSgProgHedrStmt(place) == NULL && place->variant() != MODULE_STMT)
|
|
|
|
|
|
place = place->controlParent();
|
|
|
|
|
|
SgStatement* scope = place;
|
|
|
|
|
|
|
|
|
|
|
|
set<string> declared, undeclared;
|
|
|
|
|
|
map<string, set<string>> commonsInCurrFunc;
|
|
|
|
|
|
while (isSgExecutableStatement(place) == NULL && place != scope->lastNodeOfStmt())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (place->variant() == VAR_DECL ||
|
|
|
|
|
|
place->variant() == VAR_DECL_90 ||
|
|
|
|
|
|
place->variant() == DIM_STAT)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto list = place->expr(0); list; list = list->rhs())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto elem = list->lhs();
|
|
|
|
|
|
if (elem && elem->symbol())
|
|
|
|
|
|
declared.insert(elem->symbol()->identifier());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (place->variant() == COMM_STAT)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (SgExpression* exp = place->expr(0); exp; exp = exp->rhs())
|
|
|
|
|
|
{
|
|
|
|
|
|
string commonName = "spf_unnamed";
|
|
|
|
|
|
if (exp->symbol())
|
|
|
|
|
|
commonName = string(exp->symbol()->identifier());
|
|
|
|
|
|
|
|
|
|
|
|
for (auto list = exp->lhs(); list; list = list->rhs())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto elem = list->lhs();
|
|
|
|
|
|
if (elem && elem->symbol())
|
|
|
|
|
|
{
|
|
|
|
|
|
declared.insert(elem->symbol()->identifier());
|
|
|
|
|
|
commonsInCurrFunc[commonName].insert(elem->symbol()->identifier());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (place->variant() == PARAM_DECL)
|
|
|
|
|
|
{
|
|
|
|
|
|
SgParameterStmt* param = (SgParameterStmt*)place;
|
|
|
|
|
|
for (int z = 0; z < param->numberOfConstants(); ++z)
|
|
|
|
|
|
declared.insert(param->constant(z)->identifier());
|
|
|
|
|
|
}
|
|
|
|
|
|
place = place->lexNext();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//find undeclared
|
|
|
|
|
|
auto usedVars = usedByFunc.find(byFunc.first);
|
|
|
|
|
|
if (usedVars != usedByFunc.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& var : usedVars->second)
|
|
|
|
|
|
if (declared.find(var) == declared.end())
|
|
|
|
|
|
undeclared.insert(var);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<SgSymbol*> toDeclV;
|
|
|
|
|
|
// firstly - not in common
|
|
|
|
|
|
for (auto& toDec : byFunc.second)
|
|
|
|
|
|
{
|
|
|
|
|
|
const auto commInfo = getCommonInfo(toDec);
|
|
|
|
|
|
const int posNum = commInfo.second;
|
|
|
|
|
|
if (posNum == -1)
|
|
|
|
|
|
toDeclV.push_back(toDec);
|
|
|
|
|
|
}
|
|
|
|
|
|
// secondly - in common
|
|
|
|
|
|
for (auto& toDec : byFunc.second)
|
|
|
|
|
|
{
|
|
|
|
|
|
const auto commInfo = getCommonInfo(toDec);
|
|
|
|
|
|
const int posNum = commInfo.second;
|
|
|
|
|
|
if (posNum != -1)
|
|
|
|
|
|
toDeclV.push_back(toDec);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (toDeclV.size() != byFunc.second.size())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
map<string, map<int, set<SgSymbol*>>> alreadyCommonDecl;
|
|
|
|
|
|
for (auto& toDec : toDeclV)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool isVarFromAnotherCommon = false;
|
|
|
|
|
|
string needToRename = "";
|
|
|
|
|
|
int globalType = -1;
|
|
|
|
|
|
|
|
|
|
|
|
if (declared.find(toDec->identifier()) != declared.end() || undeclared.find(toDec->identifier()) != undeclared.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
const auto commInfo = getCommonInfo(toDec);
|
|
|
|
|
|
const int posNum = commInfo.second;
|
|
|
|
|
|
|
|
|
|
|
|
if (posNum == -1)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
bool wasUnDeclared = undeclared.find(toDec->identifier()) != undeclared.end();
|
|
|
|
|
|
globalType = 1;
|
|
|
|
|
|
|
|
|
|
|
|
bool already = false;
|
|
|
|
|
|
if (alreadyCommonDecl.find(commInfo.first) != alreadyCommonDecl.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (alreadyCommonDecl[commInfo.first].find(posNum) != alreadyCommonDecl[commInfo.first].end())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto curr = string(toDec->identifier());
|
|
|
|
|
|
for (auto& s : alreadyCommonDecl[commInfo.first][posNum])
|
|
|
|
|
|
if (s->identifier() == curr)
|
|
|
|
|
|
already = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!already)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto itC = commonsInCurrFunc.find(commInfo.first);
|
|
|
|
|
|
if (itC == commonsInCurrFunc.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& currC : commonBlocks)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (currC.first == commInfo.first && !wasUnDeclared)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& var : currC.second->getVariables())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (var->getName() == toDec->identifier())
|
|
|
|
|
|
{
|
|
|
|
|
|
const string name = var->getName();
|
|
|
|
|
|
if (commonRenames.find(name) == commonRenames.end())
|
|
|
|
|
|
commonRenames[name] = 0;
|
|
|
|
|
|
needToRename = name + "_cr" + to_string(commonRenames[name]);
|
|
|
|
|
|
commonRenames[name]++;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (needToRename != "")
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (itC != commonsInCurrFunc.end())
|
|
|
|
|
|
if (itC->second.find(toDec->identifier()) != itC->second.end())
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
isVarFromAnotherCommon = true;
|
|
|
|
|
|
alreadyCommonDecl[commInfo.first][posNum].insert(toDec);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
declared.insert(toDec->identifier());
|
|
|
|
|
|
|
|
|
|
|
|
const auto commInfo = getCommonInfo(toDec);
|
|
|
|
|
|
const int posNum = commInfo.second;
|
|
|
|
|
|
|
|
|
|
|
|
if (posNum != -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
alreadyCommonDecl[commInfo.first][posNum].insert(toDec);
|
|
|
|
|
|
globalType = 1;
|
|
|
|
|
|
isVarFromAnotherCommon = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isSgConstantSymb(toDec))
|
|
|
|
|
|
constRefs[toDec->identifier()] = toDec;
|
|
|
|
|
|
|
|
|
|
|
|
if (toDec->attributes())
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((toDec->attributes() & SAVE_BIT) || (toDec->attributes() & DATA_BIT))
|
|
|
|
|
|
if (globalType != 1) // not in COMMON
|
|
|
|
|
|
saveRefs[toDec->identifier()] = toDec;
|
|
|
|
|
|
|
2024-01-23 13:04:46 +03:00
|
|
|
|
if (isAllocated(toDec))
|
2023-09-14 19:43:13 +03:00
|
|
|
|
allocatable.insert(toDec);
|
|
|
|
|
|
|
|
|
|
|
|
if (toDec->attributes() & DATA_BIT)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto itD = originalInfo.find(toDec);
|
|
|
|
|
|
if (itD == originalInfo.end())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
auto itDF = preprocDataByFunc.find(itD->second.first);
|
|
|
|
|
|
if (itDF == preprocDataByFunc.end())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
if (initValue.find(itD->second.first) == initValue.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
auto info = itDF->second.find(itD->second.second);
|
|
|
|
|
|
if (info == itDF->second.end())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
declRefs[toDec] = info->second;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
auto itDF = initValue[itD->second.first];
|
|
|
|
|
|
auto info = itDF.find(itD->second.second);
|
|
|
|
|
|
if (info == itDF.end())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
declInitInfo[toDec] = info->second;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
globalType = (globalType == -1) ? isGlobal(byFunc.first, toDec) : globalType;
|
|
|
|
|
|
if (globalType != 0 && !isVarFromAnotherCommon)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
const auto commInfo = getCommonInfo(toDec);
|
|
|
|
|
|
const int posNum = commInfo.second;
|
|
|
|
|
|
const string commName = commInfo.first;
|
|
|
|
|
|
|
|
|
|
|
|
bool needContinue = addNewCommonDecl(toDec, posNum, commName, commonBlocksRef, commonBlocks, commons, needToRename);
|
|
|
|
|
|
if (needContinue)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
auto attrsM = getAttributes<SgSymbol*, char*>(toDec, set<int> { MODULE_STMT });
|
|
|
|
|
|
if (attrsM.size())
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string newDecl = makeDeclaration(NULL, { toDec })->unparse();
|
|
|
|
|
|
auto it = newDecl.find("::");
|
|
|
|
|
|
if (it == string::npos)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
if (isSgConstantSymb(toDec))
|
|
|
|
|
|
groupsConstRefs[newDecl.substr(0, it)][toDec->identifier()].push_back(toDec);
|
|
|
|
|
|
else
|
|
|
|
|
|
groups[newDecl.substr(0, it)][toDec->identifier()].push_back(toDec);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//insert PARAMETER
|
|
|
|
|
|
if (constRefs.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& toDecls : groupsConstRefs)
|
|
|
|
|
|
{
|
|
|
|
|
|
vector<SgSymbol*> unitedList;
|
|
|
|
|
|
for (auto& elem : toDecls.second)
|
|
|
|
|
|
unitedList.push_back(elem.second[0]);
|
|
|
|
|
|
makeDeclaration(byFunc.first, unitedList);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SgParameterStmt* param = new SgParameterStmt();
|
|
|
|
|
|
for (auto& elem : sortConstRefs(constRefs))
|
|
|
|
|
|
param->addConstant(elem);
|
|
|
|
|
|
|
2024-07-19 21:10:43 +03:00
|
|
|
|
param->setlineNumber(place->lineNumber());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
place->insertStmtBefore(*param, *scope);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& toDecls : groups)
|
|
|
|
|
|
{
|
|
|
|
|
|
vector<SgSymbol*> unitedList;
|
|
|
|
|
|
vector<SgExpression*> inits;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& elem : toDecls.second)
|
|
|
|
|
|
{
|
|
|
|
|
|
unitedList.push_back(elem.second[0]);
|
|
|
|
|
|
auto initI = declInitInfo.find(elem.second[0]);
|
|
|
|
|
|
if (initI != declInitInfo.end())
|
|
|
|
|
|
inits.push_back(initI->second);
|
|
|
|
|
|
else
|
|
|
|
|
|
inits.push_back(NULL);
|
|
|
|
|
|
}
|
|
|
|
|
|
auto inserted = makeDeclaration(byFunc.first, unitedList, &inits);
|
|
|
|
|
|
|
|
|
|
|
|
SgExpression* list = inserted->expr(0);
|
|
|
|
|
|
bool typeConverted = false;
|
|
|
|
|
|
while (list)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (list->lhs())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!typeConverted)
|
|
|
|
|
|
{
|
|
|
|
|
|
typeConverted = true;
|
|
|
|
|
|
SgType* t = list->lhs()->symbol()->type();
|
|
|
|
|
|
|
|
|
|
|
|
if (t->selector())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (t->selector()->variant() == CONST_REF)
|
2024-04-09 11:51:21 +03:00
|
|
|
|
t->setSelector(CalculateInteger(t->selector()->copyPtr()));
|
2023-09-14 19:43:13 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (t->length())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (t->length()->variant() == CONST_REF)
|
|
|
|
|
|
{
|
2024-04-09 11:51:21 +03:00
|
|
|
|
auto result = CalculateInteger(t->length()->copyPtr());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
if (result->variant() == INT_VAL)
|
|
|
|
|
|
t->setLength(result);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-04-09 11:51:21 +03:00
|
|
|
|
auto result = CalculateInteger(list->lhs()->copyPtr());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
list->setLhs(result);
|
|
|
|
|
|
}
|
|
|
|
|
|
list = list->rhs();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vector<SgStatement*> newCommons;
|
|
|
|
|
|
for (auto& byCommon : commons)
|
|
|
|
|
|
{
|
|
|
|
|
|
vector<SgExpression*> refs;
|
|
|
|
|
|
for (auto& s : byCommon.second)
|
|
|
|
|
|
refs.push_back(new SgVarRefExp(s.second));
|
|
|
|
|
|
std::reverse(refs.begin(), refs.end());
|
|
|
|
|
|
|
|
|
|
|
|
SgStatement* common = new SgStatement(COMM_STAT);
|
|
|
|
|
|
common->setExpression(0, new SgExpression(COMM_LIST, makeExprList(refs, false), NULL, new SgSymbol(COMMON_NAME, byCommon.first.c_str())));
|
|
|
|
|
|
|
|
|
|
|
|
newCommons.push_back(common);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (newCommons.size())
|
2024-07-19 21:10:43 +03:00
|
|
|
|
{
|
2023-09-14 19:43:13 +03:00
|
|
|
|
for (auto& elem : newCommons)
|
2024-07-19 21:10:43 +03:00
|
|
|
|
{
|
|
|
|
|
|
elem->setlineNumber(place->lineNumber());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
place->insertStmtBefore(*elem, *scope);
|
2024-07-19 21:10:43 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-09-14 19:43:13 +03:00
|
|
|
|
|
|
|
|
|
|
//insert SAVE
|
|
|
|
|
|
if (saveRefs.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
SgStatement* save = new SgStatement(SAVE_DECL);
|
|
|
|
|
|
vector<SgExpression*> refs;
|
|
|
|
|
|
for (auto& s : saveRefs)
|
|
|
|
|
|
refs.push_back(new SgVarRefExp(s.second));
|
|
|
|
|
|
save->setExpression(0, makeExprList(refs));
|
2024-07-19 21:10:43 +03:00
|
|
|
|
|
|
|
|
|
|
save->setlineNumber(place->lineNumber());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
place->insertStmtBefore(*save, *scope);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (declRefs.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
SgStatement* decl = new SgStatement(DATA_DECL);
|
|
|
|
|
|
SgExpression* value = new SgExpression(STMT_STR);
|
|
|
|
|
|
|
|
|
|
|
|
string dataS = "data ";
|
|
|
|
|
|
int z = 0;
|
|
|
|
|
|
for (auto& elem : declRefs)
|
|
|
|
|
|
{
|
|
|
|
|
|
dataS += elem.first->identifier() + string("/") + elem.second + "/";
|
|
|
|
|
|
if (z != declRefs.size() - 1)
|
|
|
|
|
|
dataS += ",";
|
|
|
|
|
|
++z;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
value->thellnd->entry.string_val = new char[dataS.size() + 1];
|
|
|
|
|
|
strcpy(value->thellnd->entry.string_val, dataS.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
decl->setExpression(0, value);
|
2024-07-19 21:10:43 +03:00
|
|
|
|
decl->setlineNumber(place->lineNumber());
|
2023-09-14 19:43:13 +03:00
|
|
|
|
place->insertStmtBefore(*decl, *scope);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//insert ALLOCATABLE
|
|
|
|
|
|
if (allocatable.size())
|
|
|
|
|
|
{
|
2024-07-19 21:10:43 +03:00
|
|
|
|
SgStatement* alloc_stat = new SgStatement(ALLOCATABLE_STMT);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
vector<SgExpression*> refs;
|
|
|
|
|
|
for (auto& s : allocatable)
|
|
|
|
|
|
refs.push_back(new SgVarRefExp(s));
|
2024-07-19 21:10:43 +03:00
|
|
|
|
alloc_stat->setExpression(0, makeExprList(refs));
|
|
|
|
|
|
|
|
|
|
|
|
alloc_stat->setlineNumber(place->lineNumber());
|
|
|
|
|
|
place->insertStmtBefore(*alloc_stat, *scope);
|
2023-09-14 19:43:13 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-11-26 18:57:05 +03:00
|
|
|
|
|
|
|
|
|
|
static void convertLinesToAbsolute(const map<string, vector<FuncInfo*>>& allFuncInfo,
|
|
|
|
|
|
vector<tuple<string, string, int>>& inDataProc)
|
|
|
|
|
|
{
|
2023-11-28 12:58:22 +03:00
|
|
|
|
set<tuple<string, string, int>> added;
|
2023-11-26 18:57:05 +03:00
|
|
|
|
for (int z = 0; z < inDataProc.size(); ++z)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (std::get<2>(inDataProc[z]) > 0)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
auto funcToInl = std::get<0>(inDataProc[z]);
|
|
|
|
|
|
auto file = std::get<1>(inDataProc[z]);
|
|
|
|
|
|
int absoluteLine = 0;
|
|
|
|
|
|
int shilftLine = -std::get<2>(inDataProc[z]);
|
2023-11-28 12:58:22 +03:00
|
|
|
|
|
2023-11-26 18:57:05 +03:00
|
|
|
|
for (auto& funcByFile : allFuncInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (funcByFile.first != file)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& func : funcByFile.second)
|
|
|
|
|
|
{
|
|
|
|
|
|
int targetLine = func->linesNum.first + shilftLine;
|
2023-11-28 12:58:22 +03:00
|
|
|
|
//__spf_print(1, "%s target %d + %d = %d\n", func->funcName.c_str(), func->linesNum.first, shilftLine, targetLine);
|
2023-11-26 18:57:05 +03:00
|
|
|
|
for (auto& detCall : func->callsFromDetailed)
|
|
|
|
|
|
{
|
2023-11-28 12:58:22 +03:00
|
|
|
|
if (detCall.detailCallsFrom == make_pair(funcToInl, targetLine) &&
|
|
|
|
|
|
added.find(make_tuple(file, funcToInl, targetLine)) == added.end())
|
2023-11-26 18:57:05 +03:00
|
|
|
|
{
|
2023-12-11 20:53:33 +03:00
|
|
|
|
__spf_print(1, "%s %d (was %d) %s\n", funcToInl.c_str(), targetLine, std::get<2>(inDataProc[z]), funcByFile.first.c_str());
|
2023-11-28 12:58:22 +03:00
|
|
|
|
added.insert(make_tuple(file, funcToInl, targetLine));
|
2023-11-26 18:57:05 +03:00
|
|
|
|
absoluteLine = targetLine;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (absoluteLine)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2023-11-28 12:58:22 +03:00
|
|
|
|
if (absoluteLine)
|
|
|
|
|
|
break;
|
2023-11-26 18:57:05 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (absoluteLine == 0)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
std::get<2>(inDataProc[z]) = absoluteLine;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void callInliner(const map<string, vector<FuncInfo*>>& allFuncInfo,
|
|
|
|
|
|
vector<tuple<string, string, int>>& inDataProc,
|
|
|
|
|
|
map<string, set<pair<string, int>>>& inDataChains,
|
|
|
|
|
|
const set<string>& inDataChainsStart,
|
|
|
|
|
|
map<string, vector<Messages>>& SPF_messages,
|
|
|
|
|
|
const map<string, CommonBlock*>& commonBlocks)
|
|
|
|
|
|
{
|
|
|
|
|
|
map<SgStatement*, set<SgSymbol*>> newSymbsToDeclare;
|
|
|
|
|
|
map<string, FuncInfo*> tmpM;
|
|
|
|
|
|
createMapOfFunc(allFuncInfo, tmpM);
|
|
|
|
|
|
FuncInfo* mainF = NULL;
|
|
|
|
|
|
for (auto& elem : tmpM)
|
|
|
|
|
|
if (elem.second->isMain)
|
|
|
|
|
|
mainF = elem.second;
|
|
|
|
|
|
checkNull(mainF, convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
//inliner(mainF->funcName, allFuncInfo, SPF_messages, newSymbsToDeclare);
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
|
|
if (inDataProc.size())
|
|
|
|
|
|
{
|
2023-11-28 12:58:22 +03:00
|
|
|
|
__spf_print(1, "count of inline data %ld\n", inDataProc.size());
|
2023-11-26 18:57:05 +03:00
|
|
|
|
convertLinesToAbsolute(allFuncInfo, inDataProc);
|
|
|
|
|
|
|
|
|
|
|
|
map<int, vector<int>> sortByLvl;
|
|
|
|
|
|
int maxLvlCall = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (int z = 0; z < inDataProc.size(); ++z)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (std::get<2>(inDataProc[z]) != -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
int lvl = getLvlCall(mainF, 0, std::get<0>(inDataProc[z]), std::get<1>(inDataProc[z]), std::get<2>(inDataProc[z]));
|
|
|
|
|
|
if (lvl == -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool found = false;
|
|
|
|
|
|
for (auto& func : tmpM)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (func.second->isMain)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
int lvlTmp = getLvlCall(func.second, 0, std::get<0>(inDataProc[z]), std::get<1>(inDataProc[z]), std::get<2>(inDataProc[z]));
|
|
|
|
|
|
if (lvlTmp != -1)
|
|
|
|
|
|
lvl = std::max(lvl, lvlTmp);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (lvl == -1)
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
maxLvlCall = std::max(maxLvlCall, lvl);
|
|
|
|
|
|
sortByLvl[lvl].push_back(z);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int z = 0; z < inDataProc.size(); ++z)
|
|
|
|
|
|
if (std::get<2>(inDataProc[z]) == -1)
|
|
|
|
|
|
sortByLvl[maxLvlCall + 1].push_back(z);
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& byLvl : sortByLvl)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& idx : byLvl.second)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto& tup = inDataProc[idx];
|
|
|
|
|
|
|
|
|
|
|
|
if (std::get<2>(tup) != -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
__spf_print(1, " call inliner with [%s %s %d]\n", std::get<1>(tup).c_str(), std::get<0>(tup).c_str(), std::get<2>(tup));
|
|
|
|
|
|
bool isInlined = inliner(std::get<1>(tup), std::get<0>(tup), std::get<2>(tup), allFuncInfo, SPF_messages, newSymbsToDeclare, commonBlocks);
|
|
|
|
|
|
if (!isInlined)
|
|
|
|
|
|
{
|
|
|
|
|
|
__spf_print(1, " missing ...\n");
|
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (inDataChains.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
setInlineAttributeToCalls(tmpM, inDataChains, hiddenData);
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& startPoint : inDataChainsStart)
|
|
|
|
|
|
{
|
|
|
|
|
|
__spf_print(1, "call inliner from '%s'\n", startPoint.c_str());
|
|
|
|
|
|
inliner(startPoint, allFuncInfo, SPF_messages, newSymbsToDeclare, commonBlocks);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
createDeclarations(newSymbsToDeclare, commonBlocks);
|
|
|
|
|
|
}
|