Compare commits
28 Commits
fd18e95fa2
...
bb50340b2b
| Author | SHA1 | Date | |
|---|---|---|---|
| bb50340b2b | |||
| 2a83078944 | |||
| fc1663013d | |||
| 7a2d18b39f | |||
| 0d8ba256ae | |||
| 81d7d3803b | |||
|
|
8f55c13a0c | ||
|
|
7ee9d839a1 | ||
|
|
78e9b63331 | ||
|
|
879094a6b7 | ||
|
|
6c16cc5432 | ||
|
|
b1eeac0b10 | ||
|
|
4bcf83f551 | ||
|
|
c548f4ab4c | ||
| 2338156a28 | |||
|
|
718b1738a1 | ||
|
|
0fe97ceb24 | ||
|
|
81725651b1 | ||
|
|
4614e166b4 | ||
|
|
bcecd5460b | ||
|
|
719e3723ae | ||
|
|
12d3c2c8e5 | ||
|
|
a719dea05f | ||
|
|
5f98eaf872 | ||
|
|
e3d77f51f1 | ||
|
|
0a4b795900 | ||
|
|
8efd632325 | ||
|
|
5a7d7269cd |
Submodule projects/dvm updated: a711f8ebfd...3a567d7582
@@ -24,7 +24,7 @@ namespace SAPFOR
|
||||
|
||||
std::vector<BasicBlock*> next;
|
||||
std::vector<BasicBlock*> prev;
|
||||
|
||||
BasicBlock* idom{};
|
||||
//reaching definition
|
||||
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace SAPFOR
|
||||
void addInstruction(IR_Block* item);
|
||||
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
||||
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
||||
void setIdom(BasicBlock* idom_) { idom = idom_; }
|
||||
|
||||
int removePrev(BasicBlock* removed);
|
||||
int removeNext(BasicBlock* removed);
|
||||
@@ -69,7 +70,8 @@ namespace SAPFOR
|
||||
const std::vector<IR_Block*>& getInstructions() const { return instructions; }
|
||||
const std::vector<BasicBlock*>& getNext() const { return next; }
|
||||
const std::vector<BasicBlock*>& getPrev() const { return prev; }
|
||||
|
||||
BasicBlock* getIdom() const { return idom; }
|
||||
|
||||
/*
|
||||
* FOR LIVE ANALYSIS
|
||||
*/
|
||||
@@ -146,4 +148,4 @@ static inline void deleteCFG(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*
|
||||
byFunc.second.clear();
|
||||
}
|
||||
cfg.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1601,7 +1601,7 @@ static bool matchParallelAndDist(const pair<DIST::Array*, const DistrVariant*>&
|
||||
parallelOn = NULL;
|
||||
for (auto& refOn : realRefs)
|
||||
{
|
||||
linkWithTempl = parallelOn->GetLinksWithTemplate(regionId);
|
||||
linkWithTempl = refOn->GetLinksWithTemplate(regionId);
|
||||
int z = 0;
|
||||
for (int k = 0; k < linkWithTempl.size(); ++k)
|
||||
if (linkWithTempl[k] != -1)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "DvmhDirectiveBase.h"
|
||||
#include "../Utils/utils.h"
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Utils/json.hpp"
|
||||
|
||||
class Symbol;
|
||||
class Expression;
|
||||
@@ -20,6 +21,7 @@ struct FuncInfo;
|
||||
#define MAP std::map
|
||||
#define SET std::set
|
||||
#define TO_STR std::to_string
|
||||
#define JSON nlohmann::json
|
||||
|
||||
#if __SPF
|
||||
extern int sharedMemoryParallelization;
|
||||
@@ -104,7 +106,7 @@ namespace Distribution
|
||||
MAP<STRING, SET<int>> usagePlaces;
|
||||
|
||||
VECTOR<bool> mappedDims;
|
||||
VECTOR<bool> depracateToDistribute;
|
||||
VECTOR<bool> deprecateToDistribute;
|
||||
|
||||
bool ompThreadPrivate;
|
||||
bool privateInLoop;
|
||||
@@ -169,7 +171,7 @@ namespace Distribution
|
||||
sizes.resize(dimSize);
|
||||
sizesExpr.resize(dimSize);
|
||||
mappedDims.resize(dimSize);
|
||||
depracateToDistribute.resize(dimSize);
|
||||
deprecateToDistribute.resize(dimSize);
|
||||
|
||||
for (int z = 0; z < dimSize; ++z)
|
||||
{
|
||||
@@ -177,7 +179,7 @@ namespace Distribution
|
||||
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;
|
||||
deprecateToDistribute[z] = false;
|
||||
}
|
||||
|
||||
GenUniqKey();
|
||||
@@ -212,7 +214,7 @@ namespace Distribution
|
||||
uniqKey = copy.uniqKey;
|
||||
containsInRegions = copy.containsInRegions;
|
||||
mappedDims = copy.mappedDims;
|
||||
depracateToDistribute = copy.depracateToDistribute;
|
||||
deprecateToDistribute = copy.deprecateToDistribute;
|
||||
ompThreadPrivate = copy.ompThreadPrivate;
|
||||
privateInLoop = copy.privateInLoop;
|
||||
inEquivalence = copy.inEquivalence;
|
||||
@@ -224,7 +226,7 @@ namespace Distribution
|
||||
int countToRem = 0;
|
||||
for (int z = 0; z < dimSize; ++z)
|
||||
{
|
||||
if (!mappedDims[z] || depracateToDistribute[z])
|
||||
if (!mappedDims[z] || deprecateToDistribute[z])
|
||||
{
|
||||
needToRemove = true;
|
||||
countToRem++;
|
||||
@@ -244,19 +246,19 @@ namespace Distribution
|
||||
|
||||
for (int z = 0; z < dimSize; ++z)
|
||||
{
|
||||
if (mappedDims[z] && !depracateToDistribute[z])
|
||||
if (mappedDims[z] && !deprecateToDistribute[z])
|
||||
{
|
||||
newSizes.push_back(sizes[z]);
|
||||
newSizesExpr.push_back(sizesExpr[z]);
|
||||
newMappedDims.push_back(mappedDims[z]);
|
||||
newDepr.push_back(depracateToDistribute[z]);
|
||||
newDepr.push_back(deprecateToDistribute[z]);
|
||||
}
|
||||
}
|
||||
|
||||
sizes = newSizes;
|
||||
sizesExpr = newSizesExpr;
|
||||
mappedDims = newMappedDims;
|
||||
depracateToDistribute = newDepr;
|
||||
deprecateToDistribute = newDepr;
|
||||
dimSize = (int)sizes.size();
|
||||
|
||||
return false;
|
||||
@@ -424,48 +426,64 @@ namespace Distribution
|
||||
|
||||
void ClearShadowSpecs() { allShadowSpecs.clear(); }
|
||||
|
||||
STRING toString()
|
||||
JSON toJson()
|
||||
{
|
||||
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;
|
||||
JSON retVal;
|
||||
|
||||
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["id"] = (int64_t)id;
|
||||
retVal["name"] = name;
|
||||
retVal["shortName"] = shortName;
|
||||
retVal["packedAddress"] = std::to_string((long long)this);
|
||||
|
||||
retVal += "#" + TO_STR(depracateToDistribute.size());
|
||||
for (int i = 0; i < depracateToDistribute.size(); ++i)
|
||||
retVal += "#" + TO_STR((int)depracateToDistribute[i]);
|
||||
retVal["dimSize"] = dimSize;
|
||||
retVal["typeSize"] = typeSize;
|
||||
retVal["state"] = (int)isNonDistribute;
|
||||
retVal["location"] = (int)locationPos.first;
|
||||
retVal["locName"] = locationPos.second;
|
||||
|
||||
retVal += "#" + TO_STR(mappedDims.size());
|
||||
retVal["isTemplFlag"] = (int)isTemplFlag;
|
||||
retVal["isLoopArrayFlag"] = (int)isLoopArrayFlag;
|
||||
|
||||
JSON deprToDist = nlohmann::json::array();
|
||||
for (int i = 0; i < deprecateToDistribute.size(); ++i)
|
||||
deprToDist.push_back((int)deprecateToDistribute[i]);
|
||||
retVal["deprecateToDist"] = deprToDist;
|
||||
|
||||
JSON mappedDimsJ = nlohmann::json::array();
|
||||
for (int i = 0; i < mappedDims.size(); ++i)
|
||||
retVal += "#" + TO_STR((int)mappedDims[i]);
|
||||
mappedDimsJ.push_back((int)mappedDims[i]);
|
||||
retVal["mappedDims"] = mappedDimsJ;
|
||||
|
||||
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());
|
||||
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;
|
||||
|
||||
for (auto &place : declPlaces)
|
||||
retVal += "|" + place.first + "|" + TO_STR(place.second);
|
||||
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["file"] = place.first;
|
||||
elem["line"] = place.second;
|
||||
|
||||
declPlacesJ.push_back(elem);
|
||||
}
|
||||
retVal["declPlaces"] = declPlacesJ;
|
||||
|
||||
retVal += "|" + TO_STR(containsInRegions.size());
|
||||
for (auto ® : containsInRegions)
|
||||
retVal += "|" + reg;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
Array* GetTemplateArray(const uint64_t regionId, bool withCheck = true)
|
||||
{
|
||||
TemplateLink *currLink = getTemlateInfo(regionId, withCheck);
|
||||
@@ -587,13 +605,13 @@ namespace Distribution
|
||||
{
|
||||
if (dim >= dimSize)
|
||||
return;
|
||||
depracateToDistribute[dim] = value;
|
||||
deprecateToDistribute[dim] = value;
|
||||
}
|
||||
|
||||
void DeprecateAllDims()
|
||||
{
|
||||
for (int dim = 0; dim < dimSize; ++dim)
|
||||
depracateToDistribute[dim] = true;
|
||||
deprecateToDistribute[dim] = true;
|
||||
}
|
||||
|
||||
bool IsDimDepracated(const int dim) const
|
||||
@@ -603,9 +621,9 @@ namespace Distribution
|
||||
else
|
||||
{
|
||||
if (templateDimsOrder.size() == 0)
|
||||
return depracateToDistribute[dim];
|
||||
return deprecateToDistribute[dim];
|
||||
else
|
||||
return depracateToDistribute[templateDimsOrder[dim]];
|
||||
return deprecateToDistribute[templateDimsOrder[dim]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,11 +631,11 @@ namespace Distribution
|
||||
{
|
||||
bool ret = true;
|
||||
for (int z = 0; z < dimSize; ++z)
|
||||
ret = ret && depracateToDistribute[z];
|
||||
ret = ret && deprecateToDistribute[z];
|
||||
return ret;
|
||||
}
|
||||
|
||||
const VECTOR<bool>& GetDeprecetedDims() const { return depracateToDistribute; }
|
||||
const VECTOR<bool>& GetDeprecetedDims() const { return deprecateToDistribute; }
|
||||
|
||||
int GetTypeSize() const { return typeSize; }
|
||||
|
||||
|
||||
@@ -199,15 +199,6 @@ static set<string> fillUsedSymbols(SgStatement *loop)
|
||||
return usedS;
|
||||
}
|
||||
|
||||
static string correctSymbolModuleName(const string& origFull)
|
||||
{
|
||||
auto it = origFull.find("::");
|
||||
if (it == string::npos)
|
||||
return origFull;
|
||||
else
|
||||
return origFull.substr(it + 2);
|
||||
}
|
||||
|
||||
static SgStatement* getModuleScope(const string& origFull, vector<SgStatement*>& moduleList, SgStatement *local)
|
||||
{
|
||||
auto it = origFull.find("::");
|
||||
@@ -959,7 +950,7 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
|
||||
SgSymbol* redS;
|
||||
string clearName = correctSymbolModuleName(red);
|
||||
if (clearName != red)
|
||||
redS = getNameInLocation(parentFunc, clearName, getModuleScope(red, moduleList, parentFunc)->symbol()->identifier());
|
||||
redS = getNameInLocation(parentFunc, red, getModuleScope(red, moduleList, parentFunc)->symbol()->identifier());
|
||||
else
|
||||
redS = findSymbolOrCreate(file, clearName, NULL, parentFunc);
|
||||
|
||||
@@ -1017,12 +1008,12 @@ ParallelDirective::genDirective(File* file, const vector<pair<DIST::Array*, cons
|
||||
string clearName2 = correctSymbolModuleName(get<1>(list));
|
||||
|
||||
if (clearName1 != get<0>(list))
|
||||
redS1 = getNameInLocation(parentFunc, clearName1, getModuleScope(get<0>(list), moduleList, parentFunc)->symbol()->identifier());
|
||||
redS1 = getNameInLocation(parentFunc, get<0>(list), getModuleScope(get<0>(list), moduleList, parentFunc)->symbol()->identifier());
|
||||
else
|
||||
redS1 = findSymbolOrCreate(file, clearName1, NULL, parentFunc);
|
||||
|
||||
if (clearName2 != get<1>(list))
|
||||
redS2 = getNameInLocation(parentFunc, clearName2, getModuleScope(get<1>(list), moduleList, parentFunc)->symbol()->identifier());
|
||||
redS2 = getNameInLocation(parentFunc, get<1>(list), getModuleScope(get<1>(list), moduleList, parentFunc)->symbol()->identifier());
|
||||
else
|
||||
redS2 = findSymbolOrCreate(file, clearName2, NULL, parentFunc);
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "../Distribution/GraphCSR.h"
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Utils/utils.h"
|
||||
#include "../Utils/json.hpp"
|
||||
|
||||
#include "../GraphCall/graph_calls_func.h"
|
||||
|
||||
using std::vector;
|
||||
@@ -27,6 +29,8 @@ using std::make_pair;
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
template<typename setT>
|
||||
static void uniteSets(const set<setT> &first, const set<setT> &second, set<setT> &result)
|
||||
{
|
||||
@@ -732,30 +736,34 @@ string AlignRuleBase::GenRuleBase() const
|
||||
return retVal;
|
||||
}
|
||||
|
||||
string AlignRuleBase::toString()
|
||||
json AlignRuleBase::toJson()
|
||||
{
|
||||
string retVal = "";
|
||||
json retVal;
|
||||
|
||||
if (alignArray)
|
||||
retVal += "#" + std::to_string((long long)alignArray);
|
||||
else
|
||||
retVal += "#-1";
|
||||
retVal["packedAlignArrayAddress"] = alignArray ? std::to_string((long long)alignArray) : std::to_string((long long)-1);
|
||||
retVal["packedAlignWithAddress"] = alignWith ? std::to_string((long long)alignWith) : std::to_string((long long)-1);
|
||||
|
||||
if (alignWith)
|
||||
retVal += "#" + std::to_string((long long)alignWith);
|
||||
else
|
||||
retVal += "#-1";
|
||||
json alignRules = json::array();
|
||||
for (auto& rule : alignRule)
|
||||
{
|
||||
json pair;
|
||||
pair["key"] = rule.first;
|
||||
pair["value"] = rule.second;
|
||||
alignRules.push_back(pair);
|
||||
}
|
||||
retVal["alignRule"] = alignRules;
|
||||
|
||||
retVal += "#" + std::to_string(alignRule.size());
|
||||
for (int i = 0; i < alignRule.size(); ++i)
|
||||
retVal += "#" + std::to_string(alignRule[i].first) + "#" + std::to_string(alignRule[i].second);
|
||||
|
||||
retVal += "#" + std::to_string(alignRuleWith.size());
|
||||
for (int i = 0; i < alignRuleWith.size(); ++i)
|
||||
retVal += "#" + std::to_string(alignRuleWith[i].first)
|
||||
+ "#" + std::to_string(alignRuleWith[i].second.first)
|
||||
+ "#" + std::to_string(alignRuleWith[i].second.second);
|
||||
json alignRuleWithJ = json::array();
|
||||
for (auto& [dimNum, AB] : alignRuleWith)
|
||||
{
|
||||
json tuple;
|
||||
tuple["dimNum"] = dimNum;
|
||||
tuple["a"] = AB.first;
|
||||
tuple["b"] = AB.second;
|
||||
|
||||
alignRuleWithJ.push_back(tuple);
|
||||
}
|
||||
retVal["alignRuleWith"] = alignRuleWithJ;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "../Utils/json.hpp"
|
||||
|
||||
typedef enum lang : int { LANG_C, LANG_F } language;
|
||||
typedef enum dist : int { BLOCK, NONE } distType;
|
||||
typedef std::pair<std::pair<int, int>, std::pair<int, int>> attrType;
|
||||
@@ -48,7 +50,7 @@ public:
|
||||
|
||||
public:
|
||||
std::string GenRuleBase() const;
|
||||
std::string toString();
|
||||
nlohmann::json toJson();
|
||||
|
||||
public:
|
||||
DIST::Array *alignArray;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "../Distribution/Distribution.h"
|
||||
#include "../Utils/AstWrapper.h"
|
||||
|
||||
#include "../Utils/json.hpp"
|
||||
|
||||
#if __SPF
|
||||
#include "../Utils/SgUtils.h"
|
||||
#endif
|
||||
@@ -235,35 +237,42 @@ public:
|
||||
return retVal;
|
||||
}
|
||||
|
||||
std::string toString()
|
||||
nlohmann::json toJson()
|
||||
{
|
||||
std::string retVal = "";
|
||||
nlohmann::json retVal;
|
||||
|
||||
retVal += "#" + std::to_string(regionId);
|
||||
retVal += "#" + originalName;
|
||||
retVal += "#" + std::to_string(lines.size());
|
||||
retVal["packedRegionId"] = std::to_string(regionId);
|
||||
retVal["originalName"] = originalName;
|
||||
|
||||
for (auto it = lines.begin(); it != lines.end(); ++it)
|
||||
nlohmann::json arrays = nlohmann::json::array();
|
||||
for (auto& array : allArrays.GetArrays())
|
||||
arrays.push_back(array->toJson());
|
||||
retVal["packedArrays"] = arrays;
|
||||
|
||||
nlohmann::json linesInfo = nlohmann::json::array();
|
||||
for (auto& [file, linesByFile] : lines)
|
||||
{
|
||||
retVal += "|" + it->first + "|";
|
||||
retVal += std::to_string(it->second.size());
|
||||
for (int i = 0; i < it->second.size(); ++i)
|
||||
retVal += "#" + std::to_string(it->second[i].lines.first) + "#" + std::to_string(it->second[i].lines.second);
|
||||
nlohmann::json linesRegs;
|
||||
nlohmann::json lines = nlohmann::json::array();
|
||||
|
||||
for (auto& elem : linesByFile)
|
||||
{
|
||||
JSON pair;
|
||||
pair["key"] = elem.lines.first;
|
||||
pair["value"] = elem.lines.second;
|
||||
lines.push_back(pair);
|
||||
}
|
||||
linesRegs["file"] = file;
|
||||
linesRegs["lines"] = lines;
|
||||
|
||||
linesInfo.push_back(linesRegs);
|
||||
}
|
||||
retVal["regionsLines"] = linesInfo;
|
||||
|
||||
const std::set<DIST::Array*> &arrays = allArrays.GetArrays();
|
||||
retVal += "#" + std::to_string(arrays.size());
|
||||
|
||||
//create map<array_address, DIST::Array_toString()>
|
||||
for (auto it = arrays.begin(); it != arrays.end(); ++it)
|
||||
{
|
||||
retVal += "#" + std::to_string((long long)(*it));
|
||||
retVal += "#" + (*it)->toString();
|
||||
}
|
||||
|
||||
retVal += "#" + std::to_string(dataDirectives.alignRules.size());
|
||||
for (int i = 0; i < dataDirectives.alignRules.size(); ++i)
|
||||
retVal += dataDirectives.alignRules[i].toString();
|
||||
nlohmann::json alignRules = nlohmann::json::array();
|
||||
for (auto& rule : dataDirectives.alignRules)
|
||||
alignRules.push_back(rule.toJson());
|
||||
retVal["alignRules"] = alignRules;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <vector>
|
||||
#include "dvm.h"
|
||||
#include "../GraphCall/graph_calls.h"
|
||||
#include "../Utils/json.hpp"
|
||||
|
||||
class ParallelStats
|
||||
{
|
||||
@@ -11,10 +12,10 @@ public:
|
||||
RemoteCount = ShadowCount = ReductionCount = AcrossCount = 0;
|
||||
}
|
||||
|
||||
int RemoteCount;
|
||||
int ShadowCount;
|
||||
int ReductionCount;
|
||||
int AcrossCount;
|
||||
int RemoteCount = 0;
|
||||
int ShadowCount = 0;
|
||||
int ReductionCount = 0;
|
||||
int AcrossCount = 0;
|
||||
};
|
||||
|
||||
class PredictorStats
|
||||
@@ -27,28 +28,32 @@ public:
|
||||
}
|
||||
|
||||
ParallelStats ParallelStat;
|
||||
int ParallelCount;
|
||||
int RemoteCount;
|
||||
int RedistributeCount;
|
||||
int IntervalCount;
|
||||
int TotalScoreComm;
|
||||
int TotalScorePar;
|
||||
int TotalScoreDist;
|
||||
int ParallelCount = 0;
|
||||
int RemoteCount = 0;
|
||||
int RedistributeCount = 0;
|
||||
int IntervalCount = 0;
|
||||
int TotalScoreComm = 0;
|
||||
int TotalScorePar = 0;
|
||||
int TotalScoreDist = 0;
|
||||
|
||||
std::string to_string()
|
||||
nlohmann::json toJson()
|
||||
{
|
||||
std::string res = "";
|
||||
res += std::to_string(ParallelCount) + "|";
|
||||
res += std::to_string(RemoteCount) + "|";
|
||||
res += std::to_string(RedistributeCount) + "|";
|
||||
res += std::to_string(IntervalCount) + "|";
|
||||
nlohmann::json stat;
|
||||
|
||||
res += std::to_string(ParallelStat.RemoteCount) + "|";
|
||||
res += std::to_string(ParallelStat.ShadowCount) + "|";
|
||||
res += std::to_string(ParallelStat.ReductionCount) + "|";
|
||||
res += std::to_string(ParallelStat.AcrossCount);
|
||||
stat["ParallelCount"] = ParallelCount;
|
||||
stat["RemoteCount"] = RemoteCount;
|
||||
stat["RedistributeCount"] = RedistributeCount;
|
||||
stat["IntervalCount"] = IntervalCount;
|
||||
|
||||
return res;
|
||||
stat["PS_RemoteCount"] = ParallelStat.RemoteCount;
|
||||
stat["PS_ShadowCount"] = ParallelStat.ShadowCount;
|
||||
stat["PS_ReductionCount"] = ParallelStat.ReductionCount;
|
||||
stat["PS_AcrossCount"] = ParallelStat.AcrossCount;
|
||||
|
||||
//TODO: need to improve
|
||||
// (summed.TotalScoreComm != 0 ? 1.0 / summed.TotalScoreComm : 0.0) + (double)summed.TotalScorePar * 1000 + (countOfDist == 0 ? -5000 : countOfDist);
|
||||
stat["TotalScore"] = -1 * (ParallelStat.RemoteCount + ParallelStat.ShadowCount + ParallelStat.ReductionCount + ParallelStat.AcrossCount);
|
||||
return stat;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -387,7 +387,50 @@ static string shiftLines(const string &in, const map<string, const FileInfo*> &m
|
||||
return newStr;
|
||||
}
|
||||
|
||||
static int dumpErrors(const vector<FileInfo>& listOfProject, const vector<string>& errors)
|
||||
static void addMessage(const string& in, const map<string, const FileInfo*>& mapOfFiles,
|
||||
const FileInfo* currF, map<string, vector<Messages>>& messages, typeMessage type)
|
||||
{
|
||||
int byNum = 0;
|
||||
|
||||
auto it = in.find("on line ");
|
||||
if (it != string::npos)
|
||||
it += strlen("on line ");
|
||||
|
||||
int line = 0;
|
||||
sscanf(in.c_str() + it, "%d", &line);
|
||||
|
||||
auto it1 = in.find("of", it + 1);
|
||||
if (it1 == string::npos)
|
||||
return;
|
||||
it1 += 3;
|
||||
|
||||
string fileN = in.substr(it1, in.find(':', it1) - it1);
|
||||
auto itF = mapOfFiles.find(fileN);
|
||||
if (itF != mapOfFiles.end() && itF->second != currF)
|
||||
{
|
||||
byNum = itF->second->includesAdded;
|
||||
if (byNum != 0)
|
||||
{
|
||||
if (line - byNum <= 0)
|
||||
{
|
||||
//return in;
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
else
|
||||
line -= byNum;
|
||||
}
|
||||
}
|
||||
|
||||
const string newStr = in.substr(0, it) + std::to_string(line) + in.substr(in.find(' ', it + 1));
|
||||
|
||||
wstring messageE, messageR;
|
||||
__spf_printToLongBuf(messageE, L"%s", to_wstring(newStr).c_str());
|
||||
__spf_printToLongBuf(messageR, L"%s", to_wstring(newStr).c_str());
|
||||
|
||||
messages[fileN].push_back(Messages(type, line, messageR, messageE, 6000));
|
||||
}
|
||||
|
||||
static int dumpErrors(const vector<FileInfo>& listOfProject, const vector<string>& errors, map<string, vector<Messages>>& messages)
|
||||
{
|
||||
int errorsCount = 0;
|
||||
map<string, const FileInfo*> mapOfFiles;
|
||||
@@ -420,9 +463,13 @@ static int dumpErrors(const vector<FileInfo>& listOfProject, const vector<string
|
||||
for (auto& elem : splited)
|
||||
{
|
||||
if (elem.find("Warning 308") != string::npos)
|
||||
{
|
||||
addMessage(elem, mapOfFiles, &file, messages, WARR);
|
||||
outS += shiftLines(elem, mapOfFiles, &file) + "\n";
|
||||
}
|
||||
else if (elem.find("Error") != string::npos)
|
||||
{
|
||||
addMessage(elem, mapOfFiles, &file, messages, ERROR);
|
||||
errS += shiftLines(elem, mapOfFiles, &file) + "\n";
|
||||
errorsCount++;
|
||||
}
|
||||
@@ -652,7 +699,7 @@ static int parseFiles(vector<string>& errors, vector<FileInfo>& listOfProject, v
|
||||
return rethrow;
|
||||
}
|
||||
|
||||
int parseFiles(const char* proj, vector<string>& filesCompilationOrder, int parseForInlining)
|
||||
int parseFiles(const char* proj, vector<string>& filesCompilationOrder, int parseForInlining, map<string, vector<Messages>>& messages)
|
||||
{
|
||||
FILE* list = fopen(proj, "r");
|
||||
if (!list)
|
||||
@@ -723,7 +770,7 @@ int parseFiles(const char* proj, vector<string>& filesCompilationOrder, int pars
|
||||
vector<string> errors;
|
||||
|
||||
int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, parseForInlining);
|
||||
int errCount = dumpErrors(listOfProject, errors);
|
||||
int errCount = dumpErrors(listOfProject, errors, messages);
|
||||
|
||||
if (rethrow != 0)
|
||||
throw rethrow;
|
||||
@@ -732,6 +779,8 @@ int parseFiles(const char* proj, vector<string>& filesCompilationOrder, int pars
|
||||
|
||||
void parseFiles(int argc, char** argv)
|
||||
{
|
||||
map<string, vector<Messages>> messages;
|
||||
|
||||
bool isInline = false;
|
||||
auto result = splitCommandLineForParse(argv, argc, isInline);
|
||||
if (result.second.size() == 0)
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
int parseFiles(const char* proj, std::vector<std::string>& filesCompilationOrder, int parseForInlining);
|
||||
int parseFiles(const char* proj, std::vector<std::string>& filesCompilationOrder, int parseForInlining, std::map<std::string, std::vector<Messages>>& messages);
|
||||
void parseFiles(int argc, char** argv);
|
||||
|
||||
111
src/ProjectParameters/domTree.h
Normal file
111
src/ProjectParameters/domTree.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#pragma once
|
||||
|
||||
#include "vector"
|
||||
#include "map"
|
||||
|
||||
#include "../CFGraph/CFGraph.h"
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace SAPFOR {
|
||||
class DominatorFinder {
|
||||
private:
|
||||
BasicBlock* entry;
|
||||
std::vector<BasicBlock*> vertices;
|
||||
std::unordered_map<BasicBlock*, int> dfs_num;
|
||||
std::vector<int> parent, semi, vertex, ancestor, label;
|
||||
std::vector<std::vector<int>> bucket;
|
||||
int n;
|
||||
|
||||
void DFS(BasicBlock* v, int parent_num) {
|
||||
dfs_num[v] = n;
|
||||
vertex[n] = n;
|
||||
semi[n] = n;
|
||||
label[n] = n;
|
||||
ancestor[n] = -1;
|
||||
parent[n] = parent_num;
|
||||
vertices[n++] = v;
|
||||
|
||||
for (const auto& w : v->getNext()) {
|
||||
if (dfs_num[w] == -1) {
|
||||
DFS(w, dfs_num[v]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Compress(int v) {
|
||||
if (ancestor[ancestor[v]] != -1) {
|
||||
Compress(ancestor[v]);
|
||||
if (semi[label[ancestor[v]]] < semi[label[v]])
|
||||
label[v] = label[ancestor[v]];
|
||||
ancestor[v] = ancestor[ancestor[v]];
|
||||
}
|
||||
}
|
||||
|
||||
int Eval(int v) {
|
||||
if (ancestor[v] == -1) return v;
|
||||
Compress(v);
|
||||
return label[v];
|
||||
}
|
||||
|
||||
void Link(int v, int w) {
|
||||
ancestor[w] = v;
|
||||
}
|
||||
|
||||
public:
|
||||
DominatorFinder(std::vector<BasicBlock*>& blocks) {
|
||||
if (blocks.empty()) return;
|
||||
entry = blocks[0];
|
||||
n = 0;
|
||||
|
||||
for (auto block : blocks) dfs_num[block] = -1;
|
||||
|
||||
int max_size = blocks.size();
|
||||
vertices.resize(max_size);
|
||||
parent.assign(max_size, -1);
|
||||
semi.assign(max_size, -1);
|
||||
vertex.assign(max_size, -1);
|
||||
ancestor.assign(max_size, -1);
|
||||
label.assign(max_size, -1);
|
||||
bucket.resize(max_size);
|
||||
|
||||
DFS(entry, -1);
|
||||
|
||||
for (int i = n - 1; i > 0; --i) {
|
||||
int w = vertex[i];
|
||||
|
||||
for (BasicBlock* v : vertices[w]->getPrev()) {
|
||||
int u = Eval(dfs_num[v]);
|
||||
if (semi[u] < semi[w])
|
||||
semi[w] = semi[u];
|
||||
}
|
||||
bucket[vertex[semi[w]]].push_back(w);
|
||||
Link(parent[w], w);
|
||||
|
||||
for (int v : bucket[parent[w]])
|
||||
{
|
||||
int u = Eval(v);
|
||||
if (semi[u] < semi[v])
|
||||
vertices[v]->setIdom(vertices[u]);
|
||||
else
|
||||
vertices[v]->setIdom(vertices[parent[w]]);
|
||||
}
|
||||
bucket[parent[w]].clear();
|
||||
}
|
||||
|
||||
for (int i = 1; i < n; ++i) {
|
||||
int w = vertex[i];
|
||||
if (vertices[w]->getIdom() != vertices[vertex[semi[w]]])
|
||||
vertices[w]->setIdom(vertices[w]->getIdom()->getIdom());
|
||||
}
|
||||
|
||||
entry->setIdom(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
void buildDominatorTreeLT(std::vector<BasicBlock*>& blocks) {
|
||||
DominatorFinder finder(blocks);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +1,413 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <tuple>
|
||||
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../CFGraph/CFGraph.h"
|
||||
#include "CFGraph/IR.h"
|
||||
#include "Distribution/Array.h"
|
||||
#include "dvm.h"
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../GraphCall/graph_calls.h"
|
||||
#include "../GraphCall/graph_calls_func.h"
|
||||
|
||||
#include "libSage++.h"
|
||||
#include "projectParameters.h"
|
||||
#include "domTree.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
map< pair<string, int>, set<string>>
|
||||
findParameters(const map<string, vector<DefUseList>> &defUseByFunctions,
|
||||
const map<string, CommonBlock*> &commonBlocks,
|
||||
const map<string, vector<FuncInfo*>> &allFuncInfo)
|
||||
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> stmtToIR(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt)
|
||||
{
|
||||
map< pair<string, int>, set<string>> foundParameters;
|
||||
|
||||
|
||||
return foundParameters;
|
||||
}
|
||||
SgStatement* cur = stmt;
|
||||
cur->switchToFile();
|
||||
while (cur->variant() != PROC_HEDR && cur->variant() != PROG_HEDR && cur->variant() != FUNC_HEDR)
|
||||
cur = cur->controlParent();
|
||||
|
||||
string funcName = ((SgProcHedrStmt*)cur)->nameWithContains();
|
||||
|
||||
int stmtID = stmt->id();
|
||||
for (const auto& [func, bblocks] : CFGraph)
|
||||
{
|
||||
if (func->funcName != funcName)
|
||||
continue;
|
||||
|
||||
for (auto basicBlock : bblocks)
|
||||
for (auto ins : basicBlock->getInstructions())
|
||||
if (stmtID == ins->getInstruction()->getOperator()->id())
|
||||
return make_tuple(func, ins->getInstruction(), basicBlock);
|
||||
}
|
||||
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
return { NULL, NULL, NULL };
|
||||
}
|
||||
|
||||
tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*> IRByNumber(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, int num)
|
||||
{
|
||||
if (num < 0)
|
||||
return { NULL, NULL, NULL };
|
||||
|
||||
for (const auto& [func, bblocks] : CFGraph)
|
||||
for (auto byBB : bblocks)
|
||||
if (byBB->getInstructions().front()->getNumber() <= num && byBB->getInstructions().back()->getNumber() >= num)
|
||||
return make_tuple(func, getInstructionByNumber(byBB->getInstructions(), num), byBB);
|
||||
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
return { NULL, NULL, NULL};
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
void processArgument(set<SAPFOR::Argument*>& worklist,
|
||||
SAPFOR::Argument* arg,
|
||||
Iterator instr,
|
||||
Iterator first_instr)
|
||||
{
|
||||
if (arg == NULL)
|
||||
return;
|
||||
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
|
||||
extract_vars_from_reg(worklist, arg, instr, first_instr);
|
||||
else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||
{
|
||||
worklist.insert(arg);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist,
|
||||
SAPFOR::Argument* reg,
|
||||
Iterator instr,
|
||||
Iterator first_instr)
|
||||
{
|
||||
for (; instr >= first_instr; instr--)
|
||||
{
|
||||
if ((*instr)->getInstruction()->getResult() == reg)
|
||||
{
|
||||
processArgument(worklist, (*instr)->getInstruction()->getArg1(), instr, first_instr);
|
||||
processArgument(worklist, (*instr)->getInstruction()->getArg2(), instr, first_instr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
||||
set<SAPFOR::Argument*>& worklist,
|
||||
SAPFOR::Instruction* instr,
|
||||
SAPFOR::BasicBlock* bblock,
|
||||
FuncInfo* cur_func,
|
||||
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||
{
|
||||
while (bblock)
|
||||
{
|
||||
auto first_instr = bblock->getInstructions().begin();
|
||||
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
|
||||
return i->getInstruction() == instr;
|
||||
});
|
||||
|
||||
for (; cur_instr >= bblock->getInstructions().begin(); cur_instr--)
|
||||
{
|
||||
auto instr = (*cur_instr)->getInstruction();
|
||||
auto result_arg = instr->getResult();
|
||||
auto arg1 = instr->getArg1();
|
||||
auto arg2 = instr->getArg2();
|
||||
|
||||
if (worklist.count(result_arg))
|
||||
{
|
||||
processArgument(worklist, arg1, cur_instr, first_instr);
|
||||
processArgument(worklist, arg2, cur_instr, first_instr);
|
||||
worklist.erase(result_arg);
|
||||
}
|
||||
if (instr->getOperation() == SAPFOR::CFG_OP::PARAM && worklist.count(arg1))
|
||||
{
|
||||
// skip to F_CALL
|
||||
auto f_call_instr = cur_instr;
|
||||
while ((*f_call_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL)
|
||||
f_call_instr++;
|
||||
|
||||
if ((*f_call_instr)->getInstruction()->getArg1()->getValue() == "_READ")
|
||||
{
|
||||
auto stmt_before = (*f_call_instr)->getInstruction()->getOperator();
|
||||
auto filename = stmt_before->fileName();
|
||||
auto line = stmt_before->lineNumber();
|
||||
auto var_name = arg1->getValue().substr(arg1->getValue().find('%') + 1);
|
||||
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg1->getValue().c_str(), line, filename);
|
||||
auto toAdd = make_tuple(stmt_before, var_name, MODE::AFTER);
|
||||
where_to_add.insert(toAdd);
|
||||
worklist.erase(arg1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto& RD = bblock->getRD_In();
|
||||
map<SAPFOR::BasicBlock*, SAPFOR::Instruction*> group_by_block;
|
||||
for (auto& arg : worklist)
|
||||
{
|
||||
if (RD.count(arg))
|
||||
{
|
||||
if (RD.at(arg).size() == 1 && *RD.at(arg).begin() == SAPFOR::CFG_VAL::UNINIT)
|
||||
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
|
||||
else if (RD.at(arg).size() > 1)
|
||||
{
|
||||
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
|
||||
auto filename = stmt_after->fileName();
|
||||
auto line = stmt_after->lineNumber();
|
||||
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
|
||||
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
|
||||
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
|
||||
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
|
||||
where_to_add.insert(toAdd);
|
||||
worklist.erase(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto instr_num = *RD.at(arg).begin();
|
||||
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
|
||||
if (cur_func == func && (group_by_block[bblock] == NULL || group_by_block[bblock]->getNumber() < instr_num))
|
||||
group_by_block[bblock] = instr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (bblock && group_by_block.find(bblock) == group_by_block.end())
|
||||
bblock = bblock->getIdom();
|
||||
if (bblock)
|
||||
instr = group_by_block[bblock];
|
||||
}
|
||||
|
||||
// other variables are from global scope
|
||||
const auto& RD = fullIR.at(cur_func).front()->getRD_In();
|
||||
for (auto& arg : worklist)
|
||||
{
|
||||
if (arg->isMemGlobal())
|
||||
{
|
||||
set<int> found_rd;
|
||||
if (RD.count(arg))
|
||||
found_rd = RD.at(arg);
|
||||
if (found_rd.size() == 0)
|
||||
{
|
||||
auto call_instr = call_sites[cur_func].size() ? call_sites[cur_func].front() : NULL;
|
||||
while (call_instr && found_rd.size() == 0)
|
||||
{
|
||||
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
|
||||
if (call_bblock->getRD_Out().count(arg))
|
||||
found_rd = call_bblock->getRD_Out().at(arg);
|
||||
|
||||
|
||||
call_instr = call_sites[call_func].size() ? call_sites[call_func].front() : NULL;
|
||||
}
|
||||
}
|
||||
if (found_rd.size() == 1 && *found_rd.begin() == SAPFOR::CFG_VAL::UNINIT)
|
||||
{
|
||||
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
|
||||
} else if (found_rd.size() > 1)
|
||||
{
|
||||
auto first_instr = fullIR.at(cur_func).front()->getInstructions().begin();
|
||||
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
|
||||
auto filename = stmt_after->fileName();
|
||||
auto line = stmt_after->lineNumber();
|
||||
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
|
||||
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
|
||||
__spf_print(1,"Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
|
||||
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
|
||||
where_to_add.insert(toAdd);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto instr_num = *found_rd.begin();
|
||||
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
|
||||
set<SAPFOR::Argument*> new_worklist = {arg};
|
||||
|
||||
lookup_for_vars(where_to_add, new_worklist, instr, bblock, func, fullIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (const auto& call_instr : call_sites[cur_func])
|
||||
{
|
||||
set<SAPFOR::Argument*> new_worklist;
|
||||
auto params_num = cur_func->funcParams.countOfPars;
|
||||
|
||||
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
|
||||
auto first_instr = call_bblock->getInstructions().begin();
|
||||
auto cur_instr = std::find_if(first_instr, call_bblock->getInstructions().end(), [call_instr](SAPFOR::IR_Block* i) {
|
||||
return i->getInstruction() == call_instr;
|
||||
});
|
||||
for (auto& arg : worklist)
|
||||
{
|
||||
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
|
||||
{
|
||||
auto param_num= stoi(arg->getValue().substr(arg->getValue().find('%', arg->getValue().find('%') + 1) + 1));
|
||||
auto param_instr = (cur_instr - (params_num - param_num));
|
||||
auto param_arg = (*param_instr)->getInstruction()->getArg1();
|
||||
processArgument(new_worklist, param_arg, param_instr, first_instr);
|
||||
}
|
||||
}
|
||||
lookup_for_vars(where_to_add, new_worklist, call_instr, call_bblock, call_func, fullIR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handle_single_allocate(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
||||
SgStatement* alloc_statement,
|
||||
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||
{
|
||||
auto [func, instr, bblock] = stmtToIR(fullIR, alloc_statement);
|
||||
|
||||
auto first_instr = bblock->getInstructions().begin();
|
||||
auto cur_instr = std::find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
|
||||
return i->getInstruction() == instr;
|
||||
});
|
||||
auto alloc_instr = cur_instr;
|
||||
|
||||
// skip to F_CALL _ALLOC n
|
||||
while ((*alloc_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL ||
|
||||
(*alloc_instr)->getInstruction()->getArg1()->getValue() != "_ALLOC")
|
||||
alloc_instr++;
|
||||
|
||||
|
||||
auto arrays_num = stoi((*alloc_instr)->getInstruction()->getArg2()->getValue());
|
||||
|
||||
set<SAPFOR::Argument*> worklist;
|
||||
for (int i = 0; i < arrays_num; i++)
|
||||
{
|
||||
auto param_instr = --alloc_instr;
|
||||
auto param_reg = (*param_instr)->getInstruction()->getArg1();
|
||||
|
||||
while ((*param_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::LOAD ||
|
||||
(*param_instr)->getInstruction()->getResult() != param_reg)
|
||||
param_instr--;
|
||||
|
||||
|
||||
auto dimensions_num = stoi((*param_instr)->getInstruction()->getArg2()->getValue());
|
||||
|
||||
for (int j = 0; j < dimensions_num; j++)
|
||||
{
|
||||
auto ref_instr = --param_instr;
|
||||
if ((*ref_instr)->getInstruction()->getOperation() == SAPFOR::CFG_OP::RANGE)
|
||||
{
|
||||
vector<SAPFOR::Argument*> range_args = {(*ref_instr)->getInstruction()->getArg1(),
|
||||
(*ref_instr)->getInstruction()->getArg2(),
|
||||
(*ref_instr)->getInstruction()->getResult()};
|
||||
for (auto& arg : range_args)
|
||||
processArgument(worklist, arg, ref_instr, first_instr);
|
||||
|
||||
} else
|
||||
{
|
||||
auto arg = (*ref_instr)->getInstruction()->getArg1();
|
||||
processArgument(worklist, arg, ref_instr, first_instr);
|
||||
}
|
||||
}
|
||||
}
|
||||
lookup_for_vars(where_to_add,worklist, instr, bblock, func, fullIR);
|
||||
}
|
||||
|
||||
|
||||
void handle_single_loop(std::set<tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
||||
SgStatement* loop_stmt,
|
||||
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||
{
|
||||
auto [func, instr, bblock] = stmtToIR(fullIR, loop_stmt);
|
||||
|
||||
auto cur_instr = bblock->getInstructions().end() - 1;
|
||||
|
||||
set<SAPFOR::Argument*> worklist;
|
||||
extract_vars_from_reg(worklist, (*cur_instr)->getInstruction()->getResult(), cur_instr, bblock->getInstructions().begin());
|
||||
|
||||
lookup_for_vars(where_to_add, worklist, (*cur_instr)->getInstruction(), bblock, func, fullIR);
|
||||
}
|
||||
|
||||
void
|
||||
findParameters(ResultSet& foundParameters,
|
||||
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
|
||||
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
|
||||
{
|
||||
set<tuple<SgStatement*, string, MODE>> where_to_add;
|
||||
|
||||
map<string, FuncInfo*> name_to_func;
|
||||
for (const auto& [func, _] : fullIR)
|
||||
name_to_func[func->funcName] = func;
|
||||
|
||||
for (auto& [func, bblocks] : fullIR)
|
||||
{
|
||||
for (const auto& block : bblocks)
|
||||
for (const auto& ir_block : block->getInstructions())
|
||||
{
|
||||
auto instr = ir_block->getInstruction();
|
||||
if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
|
||||
{
|
||||
auto func_name = instr->getArg1()->getValue();
|
||||
auto func_info = name_to_func.find(func_name);
|
||||
|
||||
if (func_info != name_to_func.end())
|
||||
call_sites[func_info->second].push_back(instr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SAPFOR::buildDominatorTreeLT(bblocks);
|
||||
}
|
||||
|
||||
std::set<SgStatement*> alloc_statements;
|
||||
for (const auto& [func, bblocks] : fullIR)
|
||||
for (const auto& block : bblocks)
|
||||
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
|
||||
{
|
||||
auto op = (*instr)->getInstruction()->getOperator();
|
||||
if (op && op->variant() == ALLOCATE_STMT) {
|
||||
alloc_statements.insert(op);
|
||||
}
|
||||
}
|
||||
|
||||
set<SgStatement*> for_statements;
|
||||
// Find all FOR statements in the program
|
||||
for (const auto& [func, bblocks] : fullIR)
|
||||
for (const auto& block : bblocks)
|
||||
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
|
||||
{
|
||||
auto op = (*instr)->getInstruction()->getOperator();
|
||||
if (op && op->variant() == FOR_NODE)
|
||||
for_statements.insert(op);
|
||||
}
|
||||
|
||||
for (const auto& alloc_statement : alloc_statements)
|
||||
handle_single_allocate(where_to_add, alloc_statement, fullIR);
|
||||
|
||||
for (const auto& stmt : for_statements)
|
||||
handle_single_loop(where_to_add, stmt, fullIR);
|
||||
|
||||
for (const auto& [stmt_before, var_name, mode] : where_to_add)
|
||||
{
|
||||
stmt_before->switchToFile();
|
||||
|
||||
SgVariableSymb* var_symb = new SgVariableSymb(var_name.c_str());
|
||||
SgVarRefExp* var = new SgVarRefExp(var_symb);
|
||||
SgValueExp* zero = new SgValueExp(1337);
|
||||
SgExprListExp* ex = new SgExprListExp();
|
||||
auto assgn_op = new SgExpression(ASSGN_OP, var, zero);
|
||||
ex->setLhs(assgn_op);
|
||||
|
||||
SgExpression* parameter_op = new SgExpression(SPF_PARAMETER_OP, ex);
|
||||
auto dir_list = new SgExprListExp();
|
||||
dir_list->setLhs(parameter_op);
|
||||
SgStatement* toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, dir_list, NULL, NULL);
|
||||
|
||||
toAdd->setlineNumber(stmt_before->lineNumber());
|
||||
toAdd->setLocalLineNumber(stmt_before->lineNumber());
|
||||
toAdd->setFileId(stmt_before->getFileId());
|
||||
toAdd->setProject(stmt_before->getProject());
|
||||
|
||||
if (mode == MODE::AFTER)
|
||||
stmt_before->insertStmtAfter(*toAdd, *stmt_before->controlParent());
|
||||
else
|
||||
stmt_before->insertStmtBefore(*toAdd, *stmt_before->controlParent());
|
||||
|
||||
foundParameters.insert(make_tuple(stmt_before->fileName(), stmt_before->lineNumber(), var_name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
std::map< std::pair<std::string, int>, std::set<std::string>> findParameters(const std::map<std::string, std::vector<DefUseList>> &defUseByFunctions, const std::map<std::string, CommonBlock*> &commonBlocks, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo);
|
||||
#include "libSage++.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
using ResultSet = std::set<std::tuple<std::string, int, std::string>>;
|
||||
|
||||
enum class MODE
|
||||
{
|
||||
BEFORE,
|
||||
AFTER
|
||||
};
|
||||
|
||||
static std::map<FuncInfo*, std::vector<SAPFOR::Instruction*>> call_sites;
|
||||
|
||||
template<typename Iterator>
|
||||
void extract_vars_from_reg(std::set<SAPFOR::Argument*>& worklist,
|
||||
SAPFOR::Argument* reg,
|
||||
Iterator instr,
|
||||
Iterator first_instr);
|
||||
|
||||
|
||||
template<typename Iterator>
|
||||
void processArgument(std::set<SAPFOR::Argument*>& worklist,
|
||||
SAPFOR::Argument* arg,
|
||||
Iterator instr,
|
||||
Iterator first_instr);
|
||||
|
||||
void lookup_for_vars(std::set<std::tuple<SgStatement*, std::string, MODE>>& where_to_add,
|
||||
std::set<SAPFOR::Argument*>& worklist,
|
||||
SAPFOR::Instruction* instr,
|
||||
SAPFOR::BasicBlock* bblock,
|
||||
FuncInfo* cur_func,
|
||||
const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR);
|
||||
|
||||
void
|
||||
findParameters(ResultSet& foundParameters,
|
||||
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
|
||||
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#include "DvmhRegions/LoopChecker.h"
|
||||
#include "DvmhRegions/ReadWriteAnalyzer.h"
|
||||
#include "Utils/utils.h"
|
||||
#include "Utils/json.hpp"
|
||||
#include "Distribution/Array.h"
|
||||
|
||||
#include "VisualizerCalls/get_information.h"
|
||||
@@ -107,6 +108,7 @@ using namespace std;
|
||||
using std::chrono::high_resolution_clock;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::milliseconds;
|
||||
using json = nlohmann::json;
|
||||
|
||||
int PASSES_DONE[EMPTY_PASS];
|
||||
bool PASSES_DONE_INIT = false;
|
||||
@@ -331,9 +333,10 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
|
||||
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile,
|
||||
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, false, true);
|
||||
auto itI = filesToInclude.find(file_name);
|
||||
for (auto& [_, incl] : itI->second)
|
||||
if (allIncludeFiles.find(incl) != allIncludeFiles.end())
|
||||
allIncludeFiles.erase(incl);
|
||||
for (auto& [_, incls] : itI->second)
|
||||
for (auto& incl : incls)
|
||||
if (allIncludeFiles.find(incl) != allIncludeFiles.end())
|
||||
allIncludeFiles.erase(incl);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -827,7 +830,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
{
|
||||
auto fileIt = includeDependencies.find(file_name);
|
||||
if (fileIt == includeDependencies.end())
|
||||
fileIt = includeDependencies.insert(fileIt, make_pair(file_name, vector<pair<int, string>>()));
|
||||
fileIt = includeDependencies.insert(fileIt, make_pair(file_name, map<int, set<string>>()));
|
||||
|
||||
set<string> modFiles;
|
||||
for (auto& elem : moduleDecls)
|
||||
@@ -844,7 +847,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
{
|
||||
if (lastFromFile == NULL)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
fileIt->second.push_back(make_pair(lastFromFile->lineNumber(), st->fileName()));
|
||||
fileIt->second[lastFromFile->lineNumber()].insert(st->fileName());
|
||||
}
|
||||
else
|
||||
lastFromFile = st;
|
||||
@@ -1603,12 +1606,15 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
set<string> includedToThisFile;
|
||||
if (itDep != includeDependencies.end())
|
||||
{
|
||||
for (auto& [_, incl] : itDep->second)
|
||||
for (auto& [_, incls] : itDep->second)
|
||||
{
|
||||
auto comm = commentsToInclude.find(incl);
|
||||
if (comm != commentsToInclude.end())
|
||||
for (auto &allComm : comm->second)
|
||||
includedToThisFile.insert(allComm.second.begin(), allComm.second.end());
|
||||
for (auto& incl : incls)
|
||||
{
|
||||
auto comm = commentsToInclude.find(incl);
|
||||
if (comm != commentsToInclude.end())
|
||||
for (auto& allComm : comm->second)
|
||||
includedToThisFile.insert(allComm.second.begin(), allComm.second.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1888,7 +1894,9 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
else if (curr_regime == RENAME_SYMBOLS)
|
||||
runRenameSymbols(&project, commonBlocks);
|
||||
else if (curr_regime == FIND_PARAMETERS)
|
||||
parametersOfProject = findParameters(defUseByFunctions, commonBlocks, allFuncInfo);
|
||||
{
|
||||
findParameters(parametersOfProject, fullIR, declaredArrays);
|
||||
}
|
||||
else if (curr_regime == BUILD_IR)
|
||||
{
|
||||
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
|
||||
@@ -2042,7 +2050,7 @@ static void findFunctionsToInclude(bool needToAddErrors)
|
||||
SPF_messages[byFile.first].push_back(message);
|
||||
else
|
||||
{
|
||||
if (message.type != ERROR)
|
||||
if (message.getType() != ERROR)
|
||||
SPF_messages[byFile.first].push_back(message);
|
||||
else
|
||||
lastErrors[byFile.first].push_back(message);
|
||||
@@ -2217,8 +2225,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
|
||||
runPass(GROUP_ACTUAL_AND_REMOTE, proj_name, folderName);
|
||||
|
||||
runAnalysis(*project, CALCULATE_STATS_SCHEME, false);
|
||||
for (auto& elem : allPredictorStats)
|
||||
__spf_print(1, " stat for file %s: %s\n", elem.first.c_str(), elem.second.to_string().c_str());
|
||||
|
||||
//TODO: need to rewrite this to new algo
|
||||
/*if (!folderName && !consoleMode || predictOn)
|
||||
runAnalysis(*project, PREDICT_SCHEME, false); */
|
||||
@@ -2367,6 +2374,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
|
||||
case LOOPS_COMBINER:
|
||||
case FIX_COMMON_BLOCKS:
|
||||
case TEST_PASS:
|
||||
case FIND_PARAMETERS:
|
||||
case SET_IMPLICIT_NONE:
|
||||
runAnalysis(*project, curr_regime, false);
|
||||
case SUBST_EXPR_RD_AND_UNPARSE:
|
||||
@@ -2386,7 +2394,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
|
||||
break;
|
||||
case PARSE_FILES:
|
||||
{
|
||||
int err = parseFiles(proj_name, filesCompilationOrder, parseForInlining);
|
||||
int err = parseFiles(proj_name, filesCompilationOrder, parseForInlining, SPF_messages);
|
||||
if (err != 0)
|
||||
throw err;
|
||||
}
|
||||
@@ -2655,26 +2663,28 @@ int main(int argc, char **argv)
|
||||
{
|
||||
printStackTrace();
|
||||
printf("exception occurred\n");
|
||||
|
||||
json byFileArray = json::array();
|
||||
for (auto& byFile : SPF_messages)
|
||||
{
|
||||
json inFile;
|
||||
inFile["file"] = byFile.first;
|
||||
|
||||
json messages = json::array();
|
||||
for (auto& message : byFile.second)
|
||||
{
|
||||
string toPrint = "";
|
||||
for (int z = 0; z < message.engMessage.size(); ++z)
|
||||
toPrint += message.engMessage[z];
|
||||
string type;
|
||||
if (message.type == WARR)
|
||||
type = "WARR";
|
||||
else if (message.type == ERROR)
|
||||
type = "ERROR";
|
||||
else if (message.type == NOTE)
|
||||
type = "NOTE";
|
||||
else
|
||||
type = "UNKN";
|
||||
|
||||
printf("%s - [#%d: %s: line %d]: %s\n", type.c_str(), message.group, byFile.first.c_str(), message.line, toPrint.c_str());
|
||||
message.print(byFile.first);
|
||||
messages.push_back(message.toJson());
|
||||
}
|
||||
inFile["messages"] = messages;
|
||||
byFileArray.push_back(inFile);
|
||||
}
|
||||
json allMessages;
|
||||
allMessages["allMessage"] = byFileArray;
|
||||
|
||||
FILE* outF = fopen("dump_messages.json", "w");
|
||||
fprintf(outF, "%s", allMessages.dump().c_str());
|
||||
fclose(outF);
|
||||
}
|
||||
|
||||
deleteAllAllocatedData(withDel);
|
||||
|
||||
@@ -85,7 +85,7 @@ std::map<std::string, std::map<int, std::set<std::string>>> commentsToInclude;
|
||||
//
|
||||
|
||||
//for INSERT_INCLUDES
|
||||
std::map<std::string, std::vector<std::pair<int, std::string>>> filesToInclude; // file -> includes [nearest line, include]
|
||||
std::map<std::string, std::map<int, std::set<std::string>>> filesToInclude; // file -> includes [nearest line, include]
|
||||
//
|
||||
|
||||
//for PASSES DEPENDENSIES
|
||||
@@ -96,7 +96,7 @@ std::set<passes> passesIgnoreStateDone;
|
||||
//for files info
|
||||
std::map<std::string, int> lineInfo; // file -> lines count
|
||||
std::map<std::string, std::pair<std::set<int>, std::set<int>>> dirsInfo; // file -> dirs <lines SPF, lines DVM> count
|
||||
std::map<std::string, std::vector<std::pair<int, std::string>>> includeDependencies; // file -> includes [nearest line, include]
|
||||
std::map<std::string, std::map<int, std::set<std::string>>> includeDependencies; // file -> includes [nearest line, include]
|
||||
std::vector<std::string> filesCompilationOrder; // order of files for unite to one file
|
||||
std::map<std::string, std::map<SgStatement*, std::vector<SgStatement*>>> exctactedModuleStats; // file -> hided excluded modules
|
||||
//
|
||||
@@ -168,7 +168,7 @@ std::map<int, UserFiles> filesInfo; // information about open,close,write and re
|
||||
//
|
||||
|
||||
//for FIND_PARAMETERS
|
||||
std::map< std::pair<std::string, int>, std::set<std::string>> parametersOfProject; // [file, line] -> set[vars]
|
||||
std::set<std::tuple<std::string, int, std::string>> parametersOfProject; // [file, line, varname]
|
||||
//
|
||||
|
||||
//for GET_MIN_MAX_BLOCK_DIST
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "json.hpp"
|
||||
|
||||
#ifdef __SPF
|
||||
#include "dvm.h"
|
||||
#endif
|
||||
@@ -143,6 +145,9 @@ enum typeMessage { WARR, ERROR, NOTE };
|
||||
// 06 "%s clause can be used only once."
|
||||
// 07 "Variable '%s' can't be used in FILES and EXCEPT clauses at the same time."
|
||||
|
||||
// 6000 PARSER GROUP
|
||||
//
|
||||
|
||||
extern int langOfMessages;
|
||||
struct Messages
|
||||
{
|
||||
@@ -164,18 +169,41 @@ public:
|
||||
engMessage.erase(engMessage.begin() + engMessage.size() - 1);
|
||||
}
|
||||
|
||||
std::wstring toString() const
|
||||
nlohmann::json toJson() const
|
||||
{
|
||||
std::wstring retVal = L"|";
|
||||
retVal += std::to_wstring((int)type) + L" ";
|
||||
retVal += std::to_wstring(line) + L" ";
|
||||
retVal += std::to_wstring(group);
|
||||
retVal += L"|" + value;
|
||||
return retVal;
|
||||
nlohmann::json resVal;
|
||||
|
||||
resVal["line"] = line;
|
||||
resVal["group"] = group;
|
||||
resVal["value"] = std::string(value.begin(), value.end());
|
||||
resVal["type"] = (int)type;
|
||||
return resVal;
|
||||
}
|
||||
|
||||
std::string getString() const { return std::string(engMessage.begin(), engMessage.end()); }
|
||||
public:
|
||||
typeMessage getType() const { return type; }
|
||||
int getLine() const { return line; }
|
||||
|
||||
void print(const std::string& file) const
|
||||
{
|
||||
std::string toPrint = "";
|
||||
for (int z = 0; z < engMessage.size(); ++z)
|
||||
toPrint += engMessage[z];
|
||||
|
||||
std::string typeStr;
|
||||
if (type == WARR)
|
||||
typeStr = "WARR";
|
||||
else if (type == ERROR)
|
||||
typeStr = "ERROR";
|
||||
else if (type == NOTE)
|
||||
typeStr = "NOTE";
|
||||
else
|
||||
typeStr = "UNKN";
|
||||
|
||||
printf("%s - [#%d: %s: line %d]: %s\n", typeStr.c_str(), group, file.c_str(), line, toPrint.c_str());
|
||||
}
|
||||
|
||||
auto getUniqKey() const { return std::make_tuple(type, group, line, value); }
|
||||
private:
|
||||
typeMessage type;
|
||||
int group;
|
||||
int line;
|
||||
|
||||
@@ -310,8 +310,17 @@ static void getModuleSymbols(SgStatement* func, set<SgSymbol*>& symbs)
|
||||
SgSymbol* s = func->symbol()->next();
|
||||
while (s)
|
||||
{
|
||||
if (IS_BY_USE(s) && s->scope() && s->scope()->symbol()->identifier() == currScope)
|
||||
symbs.insert(s);
|
||||
if (func->variant() == MODULE_STMT)
|
||||
{
|
||||
if (s->scope() && s->scope()->symbol() && s->scope()->symbol()->identifier())
|
||||
if (s->scope()->symbol()->identifier() == currScope)
|
||||
symbs.insert(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IS_BY_USE(s) && s->scope() && s->scope()->symbol()->identifier() == currScope)
|
||||
symbs.insert(s);
|
||||
}
|
||||
s = s->next();
|
||||
}
|
||||
}
|
||||
@@ -325,18 +334,18 @@ const set<SgSymbol*>& getModuleSymbols(SgStatement *func)
|
||||
set<SgSymbol*> symbs;
|
||||
getModuleSymbols(func, symbs);
|
||||
|
||||
//if function in contains
|
||||
//if function or module in contains
|
||||
auto cp = func->controlParent();
|
||||
if (isSgProgHedrStmt(cp))
|
||||
if (isSgProgHedrStmt(cp) || cp->variant() == MODULE_STMT)
|
||||
getModuleSymbols(cp, symbs);
|
||||
|
||||
symbolsForFunc[func->symbol()->identifier()] = symbs;
|
||||
return symbs;
|
||||
}
|
||||
|
||||
SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const string& locName)
|
||||
static void findSymbol(SgStatement* func, const string& varName, const string& locName,
|
||||
map<string, SgSymbol*>& altNames)
|
||||
{
|
||||
map<string, SgSymbol*> altNames;
|
||||
for (const auto& s : getModuleSymbols(func))
|
||||
{
|
||||
SgSymbol* orig = OriginalSymbol(s);
|
||||
@@ -344,11 +353,22 @@ SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const stri
|
||||
if (orig->identifier() == varName && orig->scope()->symbol()->identifier() == locName)
|
||||
altNames[s->identifier()] = s;
|
||||
}
|
||||
}
|
||||
|
||||
SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const string& locName)
|
||||
{
|
||||
const string clearName = correctSymbolModuleName(varName);
|
||||
|
||||
map<string, SgSymbol*> altNames;
|
||||
findSymbol(func, varName, locName, altNames);
|
||||
|
||||
if (altNames.size() == 0 && clearName != varName)
|
||||
findSymbol(func, clearName, locName, altNames);
|
||||
|
||||
if (altNames.size() > 0)
|
||||
return altNames.begin()->second;
|
||||
else {
|
||||
__spf_print(1, "%s %s %s\n", func->symbol()->identifier(), varName.c_str(), locName.c_str());
|
||||
__spf_print(1, "%s (%s %s) %s\n", func->symbol()->identifier(), clearName.c_str(), varName.c_str(), locName.c_str());
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
|
||||
@@ -384,6 +404,15 @@ SgSymbol* getNameInLocation(SgSymbol* curr, SgStatement* location)
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
string correctSymbolModuleName(const string& origFull)
|
||||
{
|
||||
auto it = origFull.find("::");
|
||||
if (it == string::npos)
|
||||
return origFull;
|
||||
else
|
||||
return origFull.substr(it + 2);
|
||||
}
|
||||
|
||||
namespace Distribution
|
||||
{
|
||||
const string Array::GetNameInLocation(void* location_p) const
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
std::string correctSymbolModuleName(const std::string& origFull);
|
||||
const std::set<SgSymbol*>& getModuleSymbols(SgStatement* func);
|
||||
void getModulesAndFunctions(SgFile* file, std::vector<SgStatement*>& modulesAndFunctions);
|
||||
void findModulesInFile(SgFile* file, std::vector<SgStatement*>& modules);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "../Distribution/Arrays.h"
|
||||
#include "../DynamicAnalysis/gcov_info.h"
|
||||
#include "../ParallelizationRegions/ParRegions.h"
|
||||
#include "json.hpp"
|
||||
|
||||
#if __SPF
|
||||
#include "acc_analyzer.h"
|
||||
@@ -42,6 +43,7 @@ using std::set;
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using json = nlohmann::json;
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#include <filesystem>
|
||||
@@ -427,7 +429,7 @@ static map<string, vector<Messages>> removeCopies(map<string, vector<Messages>>
|
||||
map<tuple<typeMessage, int, int, wstring>, const Messages*> uniq;
|
||||
for (auto& message : byFile.second)
|
||||
{
|
||||
auto key = make_tuple(message.type, message.group, message.line, message.value);
|
||||
auto key = message.getUniqKey();
|
||||
/*string tmp = "";
|
||||
for (auto& s : message.toString())
|
||||
tmp += (char)s;
|
||||
@@ -460,7 +462,7 @@ static void convertGlobalMessagesBuffer(short *&result, int *&resultSize)
|
||||
bool waschanged = false;
|
||||
for (auto &message : byFile.second)
|
||||
{
|
||||
if (message.line > 0)
|
||||
if (message.getLine() > 0)
|
||||
newVal.push_back(message);
|
||||
else
|
||||
waschanged = true;
|
||||
@@ -470,22 +472,30 @@ static void convertGlobalMessagesBuffer(short *&result, int *&resultSize)
|
||||
byFile.second = newVal;
|
||||
}
|
||||
|
||||
wstring val = L"";
|
||||
val += std::to_wstring(copySPF_messages.size());
|
||||
for (auto it = copySPF_messages.begin(); it != copySPF_messages.end(); ++it)
|
||||
json allMessages = json::array();
|
||||
for (auto& byFile : copySPF_messages)
|
||||
{
|
||||
val += L"|" + to_wstring(it->first.c_str()) + L"|" + std::to_wstring(it->second.size());
|
||||
for (int k = 0; k < it->second.size(); ++k)
|
||||
val += it->second[k].toString();
|
||||
json inFile;
|
||||
inFile["file"] = byFile.first;
|
||||
|
||||
json array = json::array();
|
||||
for (auto& message : byFile.second)
|
||||
{
|
||||
json msg = message.toJson();
|
||||
array.push_back(msg);
|
||||
}
|
||||
inFile["messages"] = array;
|
||||
allMessages.push_back(inFile);
|
||||
}
|
||||
|
||||
const unsigned len = (unsigned)val.size();
|
||||
result = new short[len + 1];
|
||||
allocated.insert(result);
|
||||
json all;
|
||||
all["allMessages"] = allMessages;
|
||||
|
||||
result[len] = '\0';
|
||||
for (unsigned i = 0; i < len; ++i)
|
||||
result[i] = val[i];
|
||||
const string str = all.dump();
|
||||
const unsigned len = (unsigned)str.size();
|
||||
|
||||
copyStringToShort(result, str);
|
||||
allocated.insert(result);
|
||||
|
||||
resultSize = new int[1];
|
||||
resultSize[0] = (int)len;
|
||||
@@ -1686,4 +1696,16 @@ set<string> fillDistributedArrays(const DataDirective& dataDirectives,
|
||||
for (auto& elem : ret)
|
||||
distrArrays.insert(shortName ? elem->GetShortName() : elem->GetName());
|
||||
return distrArrays;
|
||||
}
|
||||
|
||||
void copyStringToShort(short*& result, const string& resVal, bool withEnd)
|
||||
{
|
||||
result = new short[resVal.size() + 1];
|
||||
allocated.insert(result);
|
||||
|
||||
for (int i = 0; i < resVal.size(); ++i)
|
||||
result[i] = resVal[i];
|
||||
|
||||
if (withEnd)
|
||||
result[resVal.size()] = (short)'\0';
|
||||
}
|
||||
@@ -96,3 +96,5 @@ std::vector<std::string> splitAndArgvCreate(const std::string& options);
|
||||
|
||||
std::set<DIST::Array*> fillDistributedArraysD(const DataDirective& dataDirectives, const std::map<DIST::Array*, std::tuple<int, std::string, std::string>>& tableOfUniqNamesByArray, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, bool onlyCommon = false);
|
||||
std::set<std::string> fillDistributedArrays(const DataDirective& dataDirectives, const std::map<DIST::Array*, std::tuple<int, std::string, std::string>>& tableOfUniqNamesByArray, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, bool onlyCommon = false, bool shortName = false);
|
||||
|
||||
void copyStringToShort(short*& result, const std::string& resVal, bool withEnd = true);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_SPF "2414"
|
||||
#define VERSION_SPF "2422"
|
||||
|
||||
@@ -218,18 +218,6 @@ static bool tryOpenProjectFile(const char *project)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void copyStringToShort(short *&result, const string &resVal, bool withEnd = true)
|
||||
{
|
||||
result = new short[resVal.size() + 1];
|
||||
allocated.insert(result);
|
||||
|
||||
for (int i = 0; i < resVal.size(); ++i)
|
||||
result[i] = resVal[i];
|
||||
|
||||
if (withEnd)
|
||||
result[resVal.size()] = (short)'\0';
|
||||
}
|
||||
|
||||
volatile int passDone = 0;
|
||||
static volatile int rethrow = 0;
|
||||
static void runPassesLoop(const vector<passes> &passesToRun, const char *prName, const char *folderNameChar)
|
||||
@@ -465,14 +453,15 @@ int SPF_ParseFilesWithOrder(void*& context, int winHandler, short* options, shor
|
||||
{
|
||||
runPassesForVisualizer(projName, { PARSE_FILES });
|
||||
|
||||
string resVal = "";
|
||||
for (auto& elem : filesCompilationOrder)
|
||||
{
|
||||
if (resVal == "")
|
||||
resVal += elem;
|
||||
else
|
||||
resVal += "|" + elem;
|
||||
}
|
||||
json filesArray = json::array();
|
||||
|
||||
for (auto& file : filesCompilationOrder)
|
||||
filesArray.push_back(file);
|
||||
|
||||
json filesOrder;
|
||||
filesOrder["allFiles"] = filesArray;
|
||||
|
||||
string resVal = filesOrder.dump();
|
||||
copyStringToShort(result, resVal);
|
||||
retSize = 0;
|
||||
}
|
||||
@@ -766,15 +755,17 @@ int SPF_GetArrayDistribution(void*& context, int winHandler, short *options, sho
|
||||
else
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
string resVal = "";
|
||||
resVal += to_string(parallelRegions.size());
|
||||
for (int i = 0; i < parallelRegions.size(); ++i)
|
||||
resVal += parallelRegions[i]->toString();
|
||||
json regions = json::array();
|
||||
for (auto& reg : parallelRegions)
|
||||
{
|
||||
json currReg = reg->toJson();
|
||||
regions.push_back(currReg);
|
||||
}
|
||||
|
||||
//__spf_print(1, "==============\n");
|
||||
//__spf_print(1, "%s\n", resVal.c_str());
|
||||
//__spf_print(1, "==============\n");
|
||||
json allRegions;
|
||||
allRegions["allRegions"] = regions;
|
||||
|
||||
string resVal = allRegions.dump();
|
||||
copyStringToShort(result, resVal);
|
||||
retSize = (int)resVal.size() + 1;
|
||||
}
|
||||
@@ -1063,7 +1054,6 @@ int SPF_CreateParallelVariant(void*& context, int winHandler, short *options, sh
|
||||
printf("SAPFOR: set all info done\n");
|
||||
runPassesForVisualizer(projName, { INSERT_PARALLEL_DIRS }, folderName);
|
||||
|
||||
string predictRes = "";
|
||||
PredictorStats summed;
|
||||
for (auto &predFile : allPredictorStats)
|
||||
{
|
||||
@@ -1079,44 +1069,11 @@ int SPF_CreateParallelVariant(void*& context, int winHandler, short *options, sh
|
||||
summed.TotalScoreComm += predFile.second.TotalScoreComm;
|
||||
summed.TotalScoreDist += predFile.second.TotalScoreDist;
|
||||
summed.TotalScorePar += predFile.second.TotalScorePar;
|
||||
}
|
||||
predictRes += summed.to_string();
|
||||
//predictRes += "|" + to_string((summed.TotalScoreComm != 0 ? 1.0 / summed.TotalScoreComm : 0.0 )+ (double)summed.TotalScorePar * 1000 + (countOfDist == 0 ? -5000 : countOfDist));
|
||||
if (countOfDist == 0)
|
||||
predictRes += "|x";
|
||||
else
|
||||
predictRes += "|" + to_string(-1 * (summed.ParallelStat.AcrossCount + summed.ParallelStat.RemoteCount + summed.RedistributeCount + summed.RemoteCount));
|
||||
//predictRes += "|0";
|
||||
|
||||
//TODO: need to rewrite to new algo
|
||||
/*if (folderName == NULL)
|
||||
{
|
||||
SpfInterval *mainIterval = getMainInterval(project, intervals);
|
||||
const int idxBest = mainIterval->getBestTimeIdx();
|
||||
double speedUpBest = 1;
|
||||
int procCount = 1;
|
||||
string topo = "";
|
||||
if (idxBest != -1 && mainIterval->exec_time != 0)
|
||||
{
|
||||
speedUpBest = mainIterval->exec_time / mainIterval->predictedTimes[idxBest];
|
||||
topo += "[";
|
||||
for (int z = 0; z < topologies[idxBest].size(); ++z)
|
||||
{
|
||||
topo += to_string(topologies[idxBest][z]);
|
||||
procCount *= topologies[idxBest][z];
|
||||
if (z != topologies[idxBest].size() - 1)
|
||||
topo += "x";
|
||||
}
|
||||
topo += "]";
|
||||
}
|
||||
char buf[256];
|
||||
sprintf(buf, "%.2f", speedUpBest / procCount * 100.0);
|
||||
predictRes += "|" + string(buf) + topo;
|
||||
}
|
||||
else
|
||||
predictRes += "|0";*/
|
||||
|
||||
string predictRes = summed.toJson().dump();
|
||||
copyStringToShort(predictorStats, predictRes);
|
||||
|
||||
__spf_print(1, " statistic to send: %s\n", predictRes.c_str());
|
||||
retSize = (int)predictRes.size();
|
||||
}
|
||||
@@ -1156,8 +1113,6 @@ int SPF_GetArrayLinks(void*& context, int winHandler, short *options, short *pro
|
||||
{
|
||||
runPassesForVisualizer(projName, { CALL_GRAPH2 } );
|
||||
|
||||
string resVal = "";
|
||||
|
||||
map<DIST::Array*, set<DIST::Array*>> linkedArrays;
|
||||
for (auto& inMap : arrayLinksByFuncCalls)
|
||||
{
|
||||
@@ -1171,17 +1126,24 @@ int SPF_GetArrayLinks(void*& context, int winHandler, short *options, short *pro
|
||||
linkedArrays[ref].insert(toAdd);
|
||||
}
|
||||
|
||||
|
||||
json allLinks = json::array();
|
||||
for (auto& array : linkedArrays)
|
||||
{
|
||||
resVal += to_string(array.first->GetId()) + "|" + to_string(array.second.size()) + "|";
|
||||
json currLink;
|
||||
currLink["id"] = array.first->GetId();
|
||||
|
||||
json links = json::array();
|
||||
for (auto& link : array.second)
|
||||
resVal += to_string(link->GetId()) + "|";
|
||||
links.push_back(link->GetId());
|
||||
currLink["links"] = links;
|
||||
|
||||
allLinks.push_back(currLink);
|
||||
}
|
||||
|
||||
if (resVal[resVal.size() - 1] == '|')
|
||||
resVal.erase(resVal.size() - 1);
|
||||
json links;
|
||||
links["allLinks"] = allLinks;
|
||||
|
||||
string resVal = links.dump();
|
||||
copyStringToShort(result, resVal);
|
||||
retSize = (int)resVal.size() + 1;
|
||||
}
|
||||
@@ -1308,7 +1270,7 @@ int SPF_GetIntrinsics(void*& context, short *&result)
|
||||
return (int)resVal.size() + 1;
|
||||
}
|
||||
|
||||
extern map<string, vector<pair<int, string>>> includeDependencies;
|
||||
extern map<string, map<int, set<string>>> includeDependencies;
|
||||
int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, short *projName, short *&result, short*& output, int*& outputSize,
|
||||
short*& outputMessage, int*& outputMessageSize)
|
||||
{
|
||||
@@ -1328,12 +1290,15 @@ int SPF_GetIncludeDependencies(void*& context, int winHandler, short *options, s
|
||||
includes["file"] = deps.first;
|
||||
|
||||
json array = json::array();
|
||||
for (const auto& [line, incl] : deps.second)
|
||||
for (const auto& [line, incls] : deps.second)
|
||||
{
|
||||
json elem;
|
||||
elem["line"] = line;
|
||||
elem["dependencyFileName"] = incl;
|
||||
array.push_back(elem);
|
||||
for (auto& incl : incls)
|
||||
{
|
||||
json elem;
|
||||
elem["line"] = line;
|
||||
elem["dependencyFileName"] = incl;
|
||||
array.push_back(elem);
|
||||
}
|
||||
}
|
||||
includes["includes"] = array;
|
||||
inc_array.push_back(includes);
|
||||
@@ -1416,14 +1381,17 @@ int SPF_GetAllDeclaratedArrays(void*& context, int winHandler, short *options, s
|
||||
{
|
||||
runPassesForVisualizer(projName, { GET_ALL_ARRAY_DECL });
|
||||
|
||||
string resVal = "";
|
||||
for (auto f = declaredArrays.begin(); f != declaredArrays.end(); ++f)
|
||||
json arrays = json::array();
|
||||
for (const auto& [_, array] : declaredArrays)
|
||||
{
|
||||
if (f != declaredArrays.begin())
|
||||
resVal += "@";
|
||||
resVal += f->second.first->toString();
|
||||
json jArray = array.first->toJson();
|
||||
arrays.push_back(jArray);
|
||||
}
|
||||
|
||||
json allArrays;
|
||||
allArrays["allArrays"] = arrays;
|
||||
string resVal = allArrays.dump();
|
||||
|
||||
copyStringToShort(result, resVal);
|
||||
retSize = (int)resVal.size() + 1;
|
||||
}
|
||||
@@ -2189,7 +2157,7 @@ int SPF_InlineProcedures(void*& context, int winHandler, short* options, short*
|
||||
}
|
||||
|
||||
|
||||
extern map<string, vector<pair<int, string>>> filesToInclude;
|
||||
extern map<string, map<int, set<string>>> filesToInclude;
|
||||
int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short *projName, short *folderName, char *visFilesToInclude,
|
||||
short *&output, int *&outputSize, short *&outputMessage, int *&outputMessageSize)
|
||||
{
|
||||
@@ -2222,9 +2190,8 @@ int SPF_InsertIncludesPass(void*& context, int winHandler, short *options, short
|
||||
if (sscanf(splited[k].c_str(), "%d", &line) == -1)
|
||||
return -5;
|
||||
|
||||
auto pair = make_pair(line, splited[k + 1]);
|
||||
filesToInclude[file].push_back(pair);
|
||||
__spf_print(1, " include = [%d %s]\n", pair.first, pair.second.c_str());
|
||||
filesToInclude[file][line].insert(splited[k + 1]);
|
||||
__spf_print(1, " include = [%d %s]\n", line, splited[k + 1].c_str());
|
||||
}
|
||||
i += 2 * num;
|
||||
}
|
||||
@@ -2253,18 +2220,30 @@ int SPF_GetGCovInfo(void*& context, int winHandler, short *options, short *projN
|
||||
{
|
||||
runPassesForVisualizer(projName, { GCOV_PARSER });
|
||||
|
||||
string resVal = "";
|
||||
bool first = true;
|
||||
for (auto &byFile : gCovInfo)
|
||||
json gcov_array = json::array();
|
||||
for (auto& byFile : gCovInfo)
|
||||
{
|
||||
if (!first)
|
||||
resVal += "@";
|
||||
resVal += byFile.first + "@";
|
||||
for (auto &elem : byFile.second)
|
||||
resVal += to_string(elem.first) + " " + to_string(elem.second.getExecutedCount()) + " ";
|
||||
first = false;
|
||||
json fileGCov;
|
||||
fileGCov["file"] = byFile.first;
|
||||
|
||||
json info_array = json::array();
|
||||
for (auto& elem : byFile.second)
|
||||
{
|
||||
json item;
|
||||
item["line"] = elem.first;
|
||||
item["execution"] = elem.second.getExecutedCount();
|
||||
|
||||
info_array.push_back(item);
|
||||
}
|
||||
fileGCov["lines"] = info_array;
|
||||
|
||||
gcov_array.push_back(fileGCov);
|
||||
}
|
||||
|
||||
json allGCov;
|
||||
allGCov["allGCov"] = gcov_array;
|
||||
string resVal = allGCov.dump();
|
||||
|
||||
copyStringToShort(result, resVal);
|
||||
retSize = (int)resVal.size();
|
||||
}
|
||||
|
||||
52
tests/sapfor/parameter/dynamic_array_maximum.f90
Normal file
52
tests/sapfor/parameter/dynamic_array_maximum.f90
Normal file
@@ -0,0 +1,52 @@
|
||||
program dynamic_array_maximum_3d
|
||||
implicit none
|
||||
integer :: n1, n2, n3, n4 , k, i, j, l, a
|
||||
integer :: sum3
|
||||
real :: max_element
|
||||
real, allocatable :: array(:,:,:), array2(:,:,:), array3(:,:,:)
|
||||
|
||||
write(*, *) "Enter 3 integers"
|
||||
read(*, *) n, m, k
|
||||
m = 100
|
||||
|
||||
if (1 .eq. 1) then
|
||||
a = 3
|
||||
else if (2 .eq. 1) then
|
||||
a = 4
|
||||
endif
|
||||
|
||||
m = m + 1
|
||||
k = m * 1000 + n * 10
|
||||
|
||||
allocate(array(n, m + n, k + m + n), &
|
||||
&array2(k, m + n, k), &
|
||||
&array3(k, m, k + n))
|
||||
|
||||
call random_seed()
|
||||
do i = 1, n1
|
||||
do j = 1, m * n1
|
||||
do l = 1, k * m * n1
|
||||
call random_number(array(i,j,l))
|
||||
array(i,j,l) = int(array(i,j,l) * 100)
|
||||
end do
|
||||
end do
|
||||
end do
|
||||
|
||||
max_element = array(1,1,1)
|
||||
do i = 1, n1
|
||||
do j = 1, m
|
||||
do l = 1, k
|
||||
max_element = MAX(array(i,j,l), max_element)
|
||||
end do
|
||||
end do
|
||||
end do
|
||||
deallocate(array, array2, array3)
|
||||
write(*, *) max_element
|
||||
end program dynamic_array_maximum_3d
|
||||
|
||||
! function sum3(x, y, z)
|
||||
! implicit none
|
||||
! integer :: x, y, z
|
||||
! integer :: sum3
|
||||
! sum3 = x + y + z
|
||||
! end function sum3
|
||||
Reference in New Issue
Block a user