Files
SAPFOR/src/Distribution/Array.h

872 lines
30 KiB
C
Raw Normal View History

2023-09-14 19:43:13 +03:00
#pragma once
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <climits>
#include "DvmhDirectiveBase.h"
#include "../Utils/utils.h"
#include "../Utils/errors.h"
#include "../Utils/json.hpp"
2023-09-14 19:43:13 +03:00
class Symbol;
class Expression;
struct FuncInfo;
#define STRING std::string
#define VECTOR std::vector
#define PAIR std::pair
#define MAP std::map
#define SET std::set
#define TO_STR std::to_string
#define JSON nlohmann::json
2023-09-14 19:43:13 +03:00
#if __SPF
extern int sharedMemoryParallelization;
2023-09-14 19:43:13 +03:00
#endif
namespace Distribution
{
typedef enum distFlag : int { DISTR = 0, NO_DISTR, SPF_PRIV, IO_PRIV } distFlagType;
typedef enum arrayLocation : int { l_LOCAL = 0, l_COMMON, l_MODULE, l_PARAMETER, l_STRUCT, l_LOCAL_SAVE } arrayLocType;
class Array;
class TemplateLink
{
private:
VECTOR<int> linkWithTemplate;
VECTOR<PAIR<int, int>> alignRuleWithTemplate;
Array *templateArray;
public:
TemplateLink(const int dimSize)
{
linkWithTemplate.resize(dimSize);
alignRuleWithTemplate.resize(dimSize);
for (int i = 0; i < dimSize; ++i)
linkWithTemplate[i] = -1;
templateArray = NULL;
}
TemplateLink(const TemplateLink &copy)
{
linkWithTemplate = copy.linkWithTemplate;
alignRuleWithTemplate = copy.alignRuleWithTemplate;
templateArray = copy.templateArray;
}
Array* GetTemplateArray() const { return templateArray; }
VECTOR<PAIR<int, int>> GetAlignRules() const;
VECTOR<int> GetLinks() const;
void AddRule(const int dimNum, int value, const PAIR<int, int> &rule, Array *templateArray_);
STRING toString() const;
};
class Array
{
private:
unsigned id;
STRING name;
STRING shortName;
int dimSize;
int typeSize; // size of one element of array
// calculated sizes
VECTOR<PAIR<int, int>> sizes;
// original sizes + shifts
VECTOR<PAIR<PAIR<Expression*, PAIR<int, int>>, PAIR<Expression*, PAIR<int, int>>>> sizesExpr;
VECTOR<PAIR<int, int>> orderedSizes;
VECTOR<PAIR<PAIR<Expression*, PAIR<int, int>>, PAIR<Expression*, PAIR<int, int>>>> orderedSizesExpr;
// template info by region
MAP<uint64_t, TemplateLink*> templateInfo;
bool isTemplFlag;
bool isLoopArrayFlag;
distFlag isNonDistribute;
Symbol *declSymbol;
STRING uniqKey;
// PAIR<FILE, LINE>
SET<PAIR<STRING, int>> declPlaces;
MAP<PAIR<STRING, int>, Symbol*> declPlacesSymbol;
//file-> map[incFile, line] -> symbol
MAP<STRING, MAP<PAIR<STRING, int>, Symbol*>> declPlacesSymbolByFile;
//TYPE: 0 - local, 1 - common, 2 - module, 3 - function parameter
// PAIR<TYPE, NAME>
PAIR<arrayLocation, STRING> locationPos;
VECTOR<VECTOR<PAIR<int, int>>> allShadowSpecs;
SET<STRING> containsInRegions;
// file -> lines
MAP<STRING, SET<int>> usagePlaces;
VECTOR<bool> mappedDims;
VECTOR<bool> depracateToDistribute;
bool ompThreadPrivate;
bool privateInLoop;
bool inEquivalence;
private:
TemplateLink* getTemlateInfo(const uint64_t regionId, bool withCheck = false)
{
auto it = templateInfo.find(regionId);
TemplateLink *currLink = NULL;
if (it == templateInfo.end())
{
#if __SPF
if (withCheck && sharedMemoryParallelization != 0)
2023-09-14 19:43:13 +03:00
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
#endif
currLink = new TemplateLink(dimSize);
templateInfo[regionId] = currLink;
}
else
currLink = it->second;
return currLink;
}
void GenUniqKey()
{
uniqKey = shortName + locationPos.second + TO_STR(dimSize);
for (auto &place : declPlaces)
uniqKey += place.first + TO_STR(place.second);
}
//clones of template for realignes
MAP<VECTOR<dist>, STRING> templateClones;
VECTOR<int> templateDimsOrder;
public:
Array()
{
isTemplFlag = false;
isLoopArrayFlag = false;
isNonDistribute = NO_DISTR;
typeSize = 0;
uniqKey = "";
dimSize = 0;
id = -1;
declSymbol = NULL;
ompThreadPrivate = false;
privateInLoop = false;
inEquivalence = false;
}
Array(const STRING &name, const STRING &shortName, const int dimSize, const unsigned id,
const STRING &declFile, const int declLine, const PAIR<arrayLocation, STRING> &locationPos,
Symbol *declSymbol, bool inOmpThreadPriv, bool privateInLoop, bool inEquivalence,
2024-05-11 15:38:41 +03:00
const VECTOR<STRING> &regions, const int typeSize, const distFlag flag = DISTR) :
2023-09-14 19:43:13 +03:00
name(name), dimSize(dimSize), id(id), shortName(shortName),
2024-05-11 15:38:41 +03:00
isTemplFlag(false), isNonDistribute(flag), isLoopArrayFlag(false),
2023-09-14 19:43:13 +03:00
locationPos(locationPos), declSymbol(declSymbol), typeSize(typeSize),
ompThreadPrivate(inOmpThreadPriv), privateInLoop(privateInLoop), inEquivalence(inEquivalence)
{
declPlaces.insert(std::make_pair(declFile, declLine));
sizes.resize(dimSize);
sizesExpr.resize(dimSize);
mappedDims.resize(dimSize);
depracateToDistribute.resize(dimSize);
for (int z = 0; z < dimSize; ++z)
{
sizes[z] = std::make_pair((int)INT_MAX, (int)INT_MIN);
PAIR<int, int> initVal = std::make_pair(0, 0);
sizesExpr[z] = std::make_pair(std::make_pair((Expression*)NULL, initVal), std::make_pair((Expression*)NULL, initVal));
mappedDims[z] = false;
depracateToDistribute[z] = false;
}
GenUniqKey();
for (auto &reg : regions)
containsInRegions.insert(reg);
}
Array(const Array &copy)
{
id = copy.id;
name = copy.name;
shortName = copy.shortName;
dimSize = copy.dimSize;
typeSize = copy.typeSize;
sizes = copy.sizes;
sizesExpr = copy.sizesExpr;
isTemplFlag = copy.isTemplFlag;
isNonDistribute = copy.isNonDistribute;
isLoopArrayFlag = copy.isLoopArrayFlag;
declPlaces = copy.declPlaces;
locationPos = copy.locationPos;
allShadowSpecs = copy.allShadowSpecs;
for (auto &elem : copy.templateInfo)
templateInfo[elem.first] = new TemplateLink(*elem.second);
declSymbol = copy.declSymbol;
uniqKey = copy.uniqKey;
containsInRegions = copy.containsInRegions;
mappedDims = copy.mappedDims;
depracateToDistribute = copy.depracateToDistribute;
ompThreadPrivate = copy.ompThreadPrivate;
privateInLoop = copy.privateInLoop;
inEquivalence = copy.inEquivalence;
}
bool RemoveUnpammedDims()
{
bool needToRemove = false;
int countToRem = 0;
for (int z = 0; z < dimSize; ++z)
{
if (!mappedDims[z] || depracateToDistribute[z])
{
needToRemove = true;
countToRem++;
//break;
}
}
if (needToRemove == false)
return false;
if (countToRem == dimSize)
return true;
VECTOR<PAIR<int, int>> newSizes;
VECTOR<PAIR<PAIR<Expression*, PAIR<int, int>>, PAIR<Expression*, PAIR<int, int>>>> newSizesExpr;
VECTOR<bool> newMappedDims;
VECTOR<bool> newDepr;
for (int z = 0; z < dimSize; ++z)
{
if (mappedDims[z] && !depracateToDistribute[z])
{
newSizes.push_back(sizes[z]);
newSizesExpr.push_back(sizesExpr[z]);
newMappedDims.push_back(mappedDims[z]);
newDepr.push_back(depracateToDistribute[z]);
}
}
sizes = newSizes;
sizesExpr = newSizesExpr;
mappedDims = newMappedDims;
depracateToDistribute = newDepr;
dimSize = (int)sizes.size();
return false;
}
int GetDimSize() const { return dimSize; }
const STRING GetName() const { return name; }
const STRING GetShortName() const { return shortName; }
2025-02-18 13:45:20 +03:00
const STRING GetNameInLocation(void* location) const;
void* GetNameInLocationS(void* location) const;
2023-09-14 19:43:13 +03:00
unsigned GetId() const { return id; }
void SetSizes(VECTOR<PAIR<int, int>> &_sizes, bool notCopyToExpr = false)
{
sizes = _sizes;
if (!notCopyToExpr)
{
for (int i = 0; i < sizesExpr.size(); ++i)
{
sizesExpr[i].first.second.first = sizes[i].first;
sizesExpr[i].second.second.first = sizes[i].second;
}
}
}
const VECTOR<PAIR<int, int>>& GetSizes();
const VECTOR<PAIR<PAIR<Expression*, PAIR<int, int>>, PAIR<Expression*, PAIR<int, int>>>>& GetSizesExpr();
void SetTemplateFlag(const bool templFlag) { isTemplFlag = templFlag; }
bool IsTemplate() const { return isTemplFlag; }
bool IsLoopArray() const { return isLoopArrayFlag; }
bool IsArray() const { return !isTemplFlag && !isLoopArrayFlag; }
void SetLoopArray(const bool flag) { isLoopArrayFlag = flag; }
void SetSizesExpr(const VECTOR<PAIR<Expression*, Expression*>> &_sizesExpr)
{
for (int i = 0; i < _sizesExpr.size(); ++i)
{
sizesExpr[i].first.first = _sizesExpr[i].first;
sizesExpr[i].second.first = _sizesExpr[i].second;
}
}
int AddLinkWithTemplate(const int dimNum, const int dimTempl, Array *templateArray_, const PAIR<int, int> &rule, const uint64_t regionId)
{
int err = 0;
if (dimNum >= dimSize)
err = -1;
else
{
TemplateLink *currLink = getTemlateInfo(regionId, templateArray_ == NULL);
currLink->AddRule(dimNum, dimTempl, rule, templateArray_);
}
return err;
}
VECTOR<int> GetLinksWithTemplate(const uint64_t regionId)
{
TemplateLink *currLink = getTemlateInfo(regionId, true);
return currLink->GetLinks();
}
VECTOR<PAIR<int, int>> GetAlignRulesWithTemplate(const uint64_t regionId)
{
TemplateLink *currLink = getTemlateInfo(regionId, true);
return currLink->GetAlignRules();
}
bool HasTemplateInfo(const uint64_t regionId) const
{
auto it = templateInfo.find(regionId);
return (it != templateInfo.end());
}
void ChangeName(const STRING &newName)
{
auto pos = name.find(shortName);
if (pos != STRING::npos)
{
name.erase(pos, shortName.size());
shortName = newName;
name += newName;
}
GenUniqKey();
}
void ExtendDimSize(const int dim, const PAIR<int, int> &size)
{
/*if (size.first == size.second)
return;*/
sizes[dim].first = std::min(sizes[dim].first, size.first);
sizes[dim].second = std::max(sizes[dim].second, size.second);
PAIR<int, int> &left = sizesExpr[dim].first.second;
PAIR<int, int> &right = sizesExpr[dim].second.second;
left.second = std::min(left.second, sizes[dim].first - left.first);
right.second = std::max(right.second, sizes[dim].second - right.first);
}
void SetId(const unsigned newId) { id = newId; }
const SET<PAIR<STRING, int>>& GetDeclInfo() const { return declPlaces; }
const MAP<PAIR<STRING, int>, Symbol*>& GetDeclInfoWithSymb() const { return declPlacesSymbol; }
void AddDeclInfo(const PAIR<STRING, int> &declInfo, const SET<STRING>& allFilesInProj,
const STRING& currFile, Symbol* symb = NULL)
{
declPlaces.insert(declInfo);
if (symb)
{
declPlacesSymbol[declInfo] = symb;
if (allFilesInProj.find(declInfo.first) == allFilesInProj.end()) // from include
declPlacesSymbolByFile[currFile][declInfo] = symb;
}
GenUniqKey();
}
//save request of shadow spec
void ExtendShadowSpec(const VECTOR<PAIR<int, int>> &newSpec)
{
if (allShadowSpecs.size() == 0)
allShadowSpecs.resize(dimSize);
const PAIR<int, int> zeroPair(0, 0);
for (int i = 0; i < newSpec.size(); ++i)
if (newSpec[i] != zeroPair)
allShadowSpecs[i].push_back(newSpec[i]);
}
//remove last requst of shadow spec
void RemoveShadowSpec(const VECTOR<PAIR<int, int>> &delSpec)
{
int dimN = 0;
for (auto &group : allShadowSpecs)
{
for (int i = 0; i < group.size(); ++i)
{
if (group[i] == delSpec[dimN])
{
group.erase(group.begin() + i);
break;
}
}
++dimN;
}
}
//construct shadow spec from all requests
const VECTOR<PAIR<int, int>> GetShadowSpec() const
{
VECTOR<PAIR<int, int>> shadowSpec;
shadowSpec.resize(dimSize);
for (int i = 0; i < dimSize; ++i)
shadowSpec[i] = std::make_pair(0, 0);
int dimN = 0;
for (auto &group : allShadowSpecs)
{
for (auto &elem : group)
{
shadowSpec[dimN].first = std::max(shadowSpec[dimN].first, elem.first);
shadowSpec[dimN].second = std::max(shadowSpec[dimN].second, elem.second);
}
++dimN;
}
return shadowSpec;
}
void ClearShadowSpecs() { allShadowSpecs.clear(); }
//TODO: to remove
2023-09-14 19:43:13 +03:00
STRING toString()
{
STRING retVal = "";
retVal += TO_STR(id);
retVal += "#" + name;
retVal += "#" + shortName;
retVal += "#" + TO_STR(dimSize);
retVal += "#" + TO_STR(typeSize);
retVal += "#" + TO_STR(isNonDistribute);
retVal += "#" + TO_STR(locationPos.first);
retVal += "#" + locationPos.second;
retVal += "#" + TO_STR(sizes.size());
for (int i = 0; i < sizes.size(); ++i)
retVal += "#" + TO_STR(sizes[i].first) + "#" + TO_STR(sizes[i].second);
retVal += "#" + TO_STR(depracateToDistribute.size());
for (int i = 0; i < depracateToDistribute.size(); ++i)
retVal += "#" + TO_STR((int)depracateToDistribute[i]);
retVal += "#" + TO_STR(mappedDims.size());
for (int i = 0; i < mappedDims.size(); ++i)
retVal += "#" + TO_STR((int)mappedDims[i]);
retVal += "#" + TO_STR(templateInfo.size());
for (auto it = templateInfo.begin(); it != templateInfo.end(); ++it)
retVal += "#" + TO_STR(it->first) + it->second->toString();
retVal += "#" + TO_STR((int)isTemplFlag);
retVal += "|" + TO_STR((int)isLoopArrayFlag);
retVal += "|" + TO_STR(declPlaces.size());
for (auto &place : declPlaces)
retVal += "|" + place.first + "|" + TO_STR(place.second);
retVal += "|" + TO_STR(containsInRegions.size());
for (auto &reg : containsInRegions)
retVal += "|" + reg;
return retVal;
}
JSON toJson()
{
JSON retVal;
retVal["id"] = (int64_t)id;
retVal["name"] = name;
retVal["shortName"] = shortName;
retVal["dimSize"] = dimSize;
retVal["typeSize"] = typeSize;
retVal["state"] = (int)isNonDistribute;
retVal["location"] = (int)locationPos.first;
retVal["locName"] = locationPos.second;
retVal["isTemplFlag"] = (int)isTemplFlag;
retVal["isLoopArrayFlag"] = (int)isLoopArrayFlag;
JSON deprToDist = nlohmann::json::array();
for (int i = 0; i < depracateToDistribute.size(); ++i)
deprToDist.push_back((int)depracateToDistribute[i]);
retVal["depracateToDist"] = deprToDist;
JSON mappedDimsJ = nlohmann::json::array();
for (int i = 0; i < mappedDims.size(); ++i)
mappedDimsJ.push_back((int)mappedDims[i]);
retVal["mappedDims"] = mappedDimsJ;
JSON sizesJ = nlohmann::json::array();
for (int i = 0; i < sizes.size(); ++i)
{
JSON pair;
pair["key"] = sizes[i].first;
pair["value"] = sizes[i].second;
sizesJ.push_back(pair);
}
retVal["sizes"] = sizesJ;
JSON regions = nlohmann::json::array();
for (auto& reg : containsInRegions)
regions.push_back(reg);
retVal["regions"] = regions;
JSON declPlacesJ = nlohmann::json::array();
for (auto& place : declPlaces)
{
JSON elem;
elem["array_name"] = place.first;
elem["array_loc"] = place.second;
declPlacesJ.push_back(elem);
}
retVal["declPlaces"] = declPlacesJ;
return retVal;
}
2023-09-14 19:43:13 +03:00
Array* GetTemplateArray(const uint64_t regionId, bool withCheck = true)
{
TemplateLink *currLink = getTemlateInfo(regionId, withCheck);
return currLink->GetTemplateArray();
}
void SetDistributeFlag(const distFlag isNonDistribute_) { isNonDistribute = isNonDistribute_; }
bool IsNotDistribute() const { return (isNonDistribute == DISTR) ? false : true; }
distFlag GetDistributeFlagVal() const { return isNonDistribute; }
void ChangeLocation(arrayLocation loc, const STRING &name)
{
locationPos = std::make_pair(loc, name);
}
void SetLocation(arrayLocation loc, const STRING &name)
{
ChangeLocation(loc, name);
GenUniqKey();
}
PAIR<arrayLocation, STRING> GetLocation() const { return locationPos; }
Symbol* GetDeclSymbol(const STRING& file, const PAIR<int, int>& range, const SET<STRING>& allFilesInProj) const
{
if (!IsArray() || locationPos.first != l_COMMON)
return declSymbol;
for (auto& pos : declPlacesSymbol)
{
if (pos.first.first == file)
{
const int line = pos.first.second;
if (range.first <= line && line <= range.second)
return pos.second;
} // may be in include?
else if (allFilesInProj.find(pos.first.first) == allFilesInProj.end() && allFilesInProj.size())
{
auto it = declPlacesSymbolByFile.find(file);
if (it != declPlacesSymbolByFile.end() && it->second.find(pos.first) != it->second.end())
{
auto s = it->second.find(pos.first);
return s->second;
}
else
#if __SPF
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
#else
return NULL;
#endif
return NULL;
}
}
#if __SPF
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
#endif
return NULL;
}
Symbol* GetDeclSymbol() const { return declSymbol; }
void SetDeclSymbol(Symbol *s) { declSymbol = s; }
const STRING& GetArrayUniqKey() const { return uniqKey; }
STRING GetIndepUniqName() const { return shortName + locationPos.second + TO_STR(dimSize); }
const SET<STRING>& GetRegionsName() const { return containsInRegions; }
void SetRegionPlace(const STRING &regName) { if (regName != "") containsInRegions.insert(regName); }
const MAP<STRING, SET<int>>& GetUsagePlaces() const { return usagePlaces; }
const SET<int> GetUsagePlaces(const STRING& fileName, const PAIR<int, int>* filter = NULL) const
{
auto it = usagePlaces.find(fileName);
if (it == usagePlaces.end())
return SET<int>();
if (!filter)
return it->second;
else
{
SET<int> ret;
int first = filter->first;
int last = filter->second;
for (auto& elem : it->second)
if (first <= elem && elem <= last)
ret.insert(elem);
return ret;
}
}
void AddUsagePlace(const STRING &fileName, int lineNumber)
{
auto it = usagePlaces.find(fileName);
if (it == usagePlaces.end())
it = usagePlaces.insert(it, make_pair(fileName, SET<int>()));
it->second.insert(lineNumber);
}
void SetMappedDim(const int dim)
{
if (dim >= dimSize)
return;
mappedDims[dim] = true;
}
bool IsDimMapped(const int dim) const
{
if (dim >= dimSize)
return false;
else
{
if (templateDimsOrder.size() == 0)
return mappedDims[dim];
else
return mappedDims[templateDimsOrder[dim]];
}
}
void DeprecateDimension(const int dim, bool value = true)
{
if (dim >= dimSize)
return;
depracateToDistribute[dim] = value;
}
void DeprecateAllDims()
{
for (int dim = 0; dim < dimSize; ++dim)
depracateToDistribute[dim] = true;
}
bool IsDimDepracated(const int dim) const
{
if (dim >= dimSize)
return false;
else
{
if (templateDimsOrder.size() == 0)
return depracateToDistribute[dim];
else
return depracateToDistribute[templateDimsOrder[dim]];
}
}
bool IsAllDeprecated() const
{
bool ret = true;
for (int z = 0; z < dimSize; ++z)
ret = ret && depracateToDistribute[z];
return ret;
}
const VECTOR<bool>& GetDeprecetedDims() const { return depracateToDistribute; }
int GetTypeSize() const { return typeSize; }
STRING AddTemplateClone(const VECTOR<dist> &newDist)
{
auto it = templateClones.find(newDist);
if (it == templateClones.end())
it = templateClones.insert(it, std::make_pair(newDist, shortName + STRING("_r") + TO_STR(templateClones.size())));
return it->second;
}
void ClearTemplateClones()
{
templateClones.clear();
templateDimsOrder.clear();
orderedSizes.clear();
orderedSizesExpr.clear();
}
const MAP<VECTOR<dist>, STRING>& GetAllClones() const { return templateClones; }
void AddNewTemplateDimsOrder(const VECTOR<int> &newOrder) { templateDimsOrder = newOrder; }
VECTOR<int> GetNewTemplateDimsOrder() const { return templateDimsOrder; }
void SetDimSizesToMaxMin(bool notCopyToExpr = false)
{
for (int i = 0; i < dimSize; ++i)
sizes[i] = std::make_pair((int)INT_MAX, (int)INT_MIN);
if (!notCopyToExpr)
{
for (int i = 0; i < sizesExpr.size(); ++i)
{
sizesExpr[i].first.second.first = sizes[i].first;
sizesExpr[i].second.second.first = sizes[i].second;
}
}
}
bool IsOmpThreadPrivate() const { return ompThreadPrivate; }
bool IsSpfPrivate() const { return ((isNonDistribute == SPF_PRIV) || (isNonDistribute == IO_PRIV)); }
bool IsInEquvalence() const { return inEquivalence; }
void SetEquvalence(bool value) { inEquivalence = value; }
bool IsPrivateInLoop() const { return privateInLoop; }
void SetPrivateInLoopStatus(bool value) { privateInLoop = value; }
bool IsModuleSymbol() const { return locationPos.first == l_MODULE; }
~Array()
{
for (auto &templ : templateInfo)
delete templ.second;
}
};
struct ArrayComparator
{
bool operator()(const Array* left, const Array* right) const
{
return (left->GetArrayUniqKey() > right->GetArrayUniqKey());
}
};
struct UnaryAccess
{
UnaryAccess()
{
line = -1;
type = -1;
underFunctionPar = -1;
fName = "";
count = 0;
}
UnaryAccess(const PAIR<int, char>& info)
{
line = info.first;
type = info.second;
underFunctionPar = -1;
fName = "";
count = 1;
}
UnaryAccess(const PAIR<int, char>& info, const STRING &f, const int parN)
{
line = info.first;
type = info.second;
underFunctionPar = parN;
fName = f;
count = 1;
}
STRING PrintInfo() const
{
STRING out = "#" + std::to_string(count) + " of ";
if (type == 0)
out += "READ ";
else if(type == 1)
out += "WRITE ";
else
out += "UNKN ";
out += "on line " + std::to_string(line);
if (underFunctionPar != -1)
out += " in '#" + std::to_string(underFunctionPar + 1) + "' par of function call '" + fName + "'";
return out;
}
bool operator==(const UnaryAccess &left) const
{
return (line == left.line && type == left.type &&
underFunctionPar == left.underFunctionPar && fName == left.fName);
}
bool operator!=(const UnaryAccess& left) const
{
return !(*this == left);
}
int line;
int type; // R/W -> 0, 1
int underFunctionPar;
STRING fName;
int count;
};
class ArrayAccessInfo
{
private:
MAP<STRING, MAP<int, VECTOR<UnaryAccess>>> accessPatterns; // file -> MAP<LINE, info>
public:
void AddAccessInfo(const STRING& file, const PAIR<int, char> &info, const STRING fName = "", int underParN = -1)
{
auto it = accessPatterns.find(file);
if (it == accessPatterns.end())
it = accessPatterns.insert(it, std::make_pair(file, MAP<int, VECTOR<UnaryAccess>>()));
bool found = false;
UnaryAccess toAdd;
if (underParN == -1)
toAdd = UnaryAccess(info);
else
toAdd = UnaryAccess(info, fName, underParN);
auto itMap = it->second.find(info.first);
if (itMap == it->second.end())
it->second[info.first].push_back(toAdd);
else
{
for (int z = 0; z < itMap->second.size(); ++z)
{
if (itMap->second[z] == toAdd)
{
found = true;
itMap->second[z].count++;
break;
}
}
if (found == false)
{
if (underParN == -1)
itMap->second.push_back(toAdd);
else
itMap->second.push_back(toAdd);
}
}
}
void checkAndUpdate(const MAP<STRING, FuncInfo*>& allFuncs);
const MAP<STRING, MAP<int, VECTOR<UnaryAccess>>>& GetAllAccessInfo() const { return accessPatterns; }
const MAP<int, VECTOR<UnaryAccess>>* GetAccessInfoByFile(const STRING &file) const
{
auto it = accessPatterns.find(file);
if (it == accessPatterns.end())
return NULL;
else
return &(it->second);
}
};
void printArrayInfo(const STRING &file, const MAP<std::tuple<int, STRING, STRING>, PAIR<Array*, ArrayAccessInfo*>> &declaredArrays);
void fixTypeOfArrayInfoWithCallGraph(MAP<std::tuple<int, STRING, STRING>, PAIR<Array*, ArrayAccessInfo*>>& declaredArrays, const MAP<STRING, FuncInfo*>& allFuncs);
}
#undef VECTOR
#undef STRING
#undef PAIR
#undef MAP
#undef SET
#undef TO_STR