4 Commits

Author SHA1 Message Date
ALEXks
51f97e2be9 improved private arrays analysis 2026-05-01 12:56:32 +03:00
ALEXks
e1bcaeba5c refactored private arrays analysis 2026-05-01 12:23:51 +03:00
ALEXks
357f961d68 refactored arrays propagation pass 2026-05-01 12:03:41 +03:00
8b282ebc21 Merge pull request 'add restore pass' (#83) from private_arrays2 into master 2026-04-27 16:40:01 +03:00
10 changed files with 236 additions and 207 deletions

View File

@@ -20,14 +20,11 @@
using namespace std; using namespace std;
extern std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays;
extern map<string, vector<Messages>> SPF_messages;
static set<Region*> collapsed; static set<Region*> collapsed;
static void RemoveEmptyPoints(ArrayAccessingIndexes& container) static void removeEmptyPoints(arrayAccessingIndexes& container)
{ {
ArrayAccessingIndexes resultContainer; arrayAccessingIndexes resultContainer;
set<string> toRemove; set<string> toRemove;
for (auto& [arrayName, accessingSet] : container) for (auto& [arrayName, accessingSet] : container)
@@ -52,7 +49,7 @@ static void RemoveEmptyPoints(ArrayAccessingIndexes& container)
container[arrayName] = accessingSet; container[arrayName] = accessingSet;
} }
static void Collapse(Region* region) static void collapse(Region* region)
{ {
if (region->getBasickBlocks().empty()) if (region->getBasickBlocks().empty())
return; return;
@@ -90,7 +87,7 @@ static void Collapse(Region* region)
RegionInstruction instruction; RegionInstruction instruction;
instruction.def = move(region->array_def); instruction.def = move(region->array_def);
ArrayAccessingIndexes recursivePriv; arrayAccessingIndexes recursivePriv;
for (auto& byBlock : region->getBasickBlocks()) for (auto& byBlock : region->getBasickBlocks())
{ {
if (!byBlock->array_priv.empty()) if (!byBlock->array_priv.empty())
@@ -107,7 +104,7 @@ static void Collapse(Region* region)
} }
} }
ArrayAccessingIndexes useUnionB; arrayAccessingIndexes useUnionB;
for (auto& byBlock : region->getBasickBlocks()) for (auto& byBlock : region->getBasickBlocks())
for (auto& instruction : byBlock->instructions) for (auto& instruction : byBlock->instructions)
for (auto& [arrayName, _] : instruction.use) for (auto& [arrayName, _] : instruction.use)
@@ -134,9 +131,9 @@ static void Collapse(Region* region)
region->array_priv = move(recursivePriv); region->array_priv = move(recursivePriv);
} }
static void SolveForBasickBlock(Region* block) static void solveForBasickBlock(Region* block)
{ {
ArrayAccessingIndexes newIn; arrayAccessingIndexes newIn;
bool flagFirst = true; bool flagFirst = true;
for (Region* prevBlock : block->getPrevRegions()) for (Region* prevBlock : block->getPrevRegions())
{ {
@@ -175,7 +172,7 @@ static void SolveForBasickBlock(Region* block)
if (i > 0) if (i > 0)
instruction.in = block->instructions[i - 1].out; instruction.in = block->instructions[i - 1].out;
ArrayAccessingIndexes newOut; arrayAccessingIndexes newOut;
if (instruction.def.empty()) if (instruction.def.empty())
newOut = instruction.in; newOut = instruction.in;
else if (instruction.in.empty()) else if (instruction.in.empty())
@@ -192,11 +189,9 @@ static void SolveForBasickBlock(Region* block)
for (auto& [arrayName, accessSet] : instruction.in) for (auto& [arrayName, accessSet] : instruction.in)
{ {
if (newOut.find(arrayName) == newOut.end()) if (newOut.find(arrayName) == newOut.end())
{
newOut[arrayName] = accessSet; newOut[arrayName] = accessSet;
} }
} }
}
instruction.out = move(newOut); instruction.out = move(newOut);
} }
@@ -204,30 +199,31 @@ static void SolveForBasickBlock(Region* block)
block->array_out = block->instructions.back().out; block->array_out = block->instructions.back().out;
} }
static void SolveDataFlowTopologically(Region* DFG) static void solveDataFlowTopologically(Region* DFG)
{ {
for (Region* b : DFG->getBasickBlocks()) for (Region* b : DFG->getBasickBlocks())
{ {
collapsed.insert(b); collapsed.insert(b);
SolveForBasickBlock(b); solveForBasickBlock(b);
} }
} }
static void SolveDataFlow(Region* DFG) static void solveDataFlow(Region* DFG)
{ {
if (!DFG) if (!DFG)
return; return;
for (Region* subRegion : DFG->getSubRegions()) for (Region* subRegion : DFG->getSubRegions())
{ {
SolveDataFlow(subRegion); solveDataFlow(subRegion);
DFG->addBasickBlocks(subRegion); DFG->addBasickBlocks(subRegion);
} }
vector<Region*>& blocks = DFG->getBasickBlocks(); vector<Region*>& blocks = DFG->getBasickBlocks();
auto pos = remove_if(blocks.begin(), blocks.end(), [](Region* r) { return collapsed.find(r) != collapsed.end(); }); auto pos = remove_if(blocks.begin(), blocks.end(), [](Region* r) { return collapsed.find(r) != collapsed.end(); });
blocks.erase(pos, blocks.end()); blocks.erase(pos, blocks.end());
TopologySort(DFG->getBasickBlocks(), DFG->getHeader()); topologySort(DFG->getBasickBlocks(), DFG->getHeader());
SolveDataFlowTopologically(DFG); solveDataFlowTopologically(DFG);
Collapse(DFG); collapse(DFG);
} }
static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>& declaredDims) static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>& declaredDims)
@@ -247,9 +243,7 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>
else if (constValSymb) else if (constValSymb)
dimLength = stol(constValSymb->constantValue()->unparse()); dimLength = stol(constValSymb->constantValue()->unparse());
else if (subscriptExpr) else if (subscriptExpr)
{
dimLength = stol(subscriptExpr->rhs()->unparse()) - stol(subscriptExpr->lhs()->unparse()); dimLength = stol(subscriptExpr->rhs()->unparse()) - stol(subscriptExpr->lhs()->unparse());
}
else else
return false; return false;
@@ -260,7 +254,7 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>
return true; return true;
} }
static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym) static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym, const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
{ {
if (!arrSym) if (!arrSym)
return nullptr; return nullptr;
@@ -268,10 +262,10 @@ static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym)
{ {
DIST::Array* distArr = val.first; DIST::Array* distArr = val.first;
if (!distArr) if (!distArr)
continue; printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
Symbol* declSym = distArr->GetDeclSymbol(); Symbol* declSym = distArr->GetDeclSymbol();
if (!declSym) if (!declSym)
continue; printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgSymbol* sgDecl = declSym->GetOriginal(); SgSymbol* sgDecl = declSym->GetOriginal();
if (sgDecl && isEqSymbols(sgDecl, arrSym)) if (sgDecl && isEqSymbols(sgDecl, arrSym))
return distArr; return distArr;
@@ -279,7 +273,7 @@ static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym)
return nullptr; return nullptr;
} }
static bool CheckDimensionLength(const AccessingSet& array) static bool checkDimensionLength(const AccessingSet& array, const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
{ {
if (array.GetElements().empty()) if (array.GetElements().empty())
return false; return false;
@@ -291,7 +285,7 @@ static bool CheckDimensionLength(const AccessingSet& array)
vector<uint64_t> declaredDims; vector<uint64_t> declaredDims;
declaredDims.reserve(dimCount); declaredDims.reserve(dimCount);
DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol()); DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol(), declaredArrays);
if (distArr && distArr->GetDimSize() == (int)dimCount) if (distArr && distArr->GetDimSize() == (int)dimCount)
{ {
const auto& sizes = distArr->GetSizes(); const auto& sizes = distArr->GetSizes();
@@ -317,7 +311,9 @@ static bool CheckDimensionLength(const AccessingSet& array)
return false; return false;
} }
static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set<SgStatement*>& insertedPrivates) static int addPrivateArraysToLoop(LoopGraph* loop, const arrayAccessingIndexes& privates, set<SgStatement*>& insertedPrivates,
map<string, vector<Messages>>& SPF_messages,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
{ {
SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR); SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR);
spfStat->setlineNumber(loop->loop->lineNumber()); spfStat->setlineNumber(loop->loop->lineNumber());
@@ -328,19 +324,12 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes&
{ {
int idx = arrayName.find('%'); int idx = arrayName.find('%');
string name = (idx != -1 ? arrayName.substr(idx+1) : arrayName); string name = (idx != -1 ? arrayName.substr(idx+1) : arrayName);
if (!CheckDimensionLength(accessingSet)) if (!checkDimensionLength(accessingSet, declaredArrays))
{ {
wstring messageE, messageR; wstring messageE, messageR;
__spf_printToLongBuf( __spf_printToLongBuf(messageE, L"Private array '%s' was skipped because dimension lengths are inconsistent", to_wstring(name).c_str());
messageE, __spf_printToLongBuf(messageR, R159, to_wstring("array " + name + " has inconsistent dimension lengths").c_str());
L"Private array '%s' was skipped because dimension lengths are inconsistent", SPF_messages[loop->loop->fileName()].push_back(Messages(WARR, loop->loop->lineNumber(), messageR, messageE, 1029));
to_wstring(name).c_str());
__spf_printToLongBuf(
messageR,
R159,
to_wstring("array " + name + " has inconsistent dimension lengths").c_str());
SPF_messages[loop->loop->fileName()].push_back(
Messages(WARR, loop->loop->lineNumber(), messageR, messageE, 1029));
continue; continue;
} }
@@ -378,12 +367,18 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes&
} }
} }
void findPrivateArrays(map<string, vector<LoopGraph*>>& loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR, set<SgStatement*>& insertedPrivates) int findPrivateArrays(map<string, vector<LoopGraph*>>& loopGraph, map<FuncInfo*,
vector<SAPFOR::BasicBlock*>>& FullIR,
set<SgStatement*>& insertedPrivates,
map<string, vector<Messages>>& SPF_messages,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
{ {
map<LoopGraph*, ArrayAccessingIndexes> result; map<LoopGraph*, arrayAccessingIndexes> result;
for (const auto& [fileName, loops] : loopGraph) for (const auto& [fileName, loops] : loopGraph)
{ {
SgFile::switchToFile(fileName); if (SgFile::switchToFile(fileName) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (const auto& loop : loops) for (const auto& loop : loops)
{ {
if (!loop->isFor()) if (!loop->isFor())
@@ -397,28 +392,53 @@ void findPrivateArrays(map<string, vector<LoopGraph*>>& loopGraph, map<FuncInfo*
{ {
if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func) if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func)
{ {
Region* loopRegion; Region* loopRegion = nullptr;
try try
{ {
loopRegion = new Region(loop, blocks); loopRegion = new Region(loop, blocks);
} }
catch (...) catch (...)
{ {
continue; printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
} }
if (loopRegion->getBasickBlocks().size() <= 1) if (loopRegion->getBasickBlocks().size() <= 1)
{ {
delete(loopRegion); delete loopRegion;
continue; continue;
} }
SolveDataFlow(loopRegion);
RemoveEmptyPoints(loopRegion->array_priv); solveDataFlow(loopRegion);
removeEmptyPoints(loopRegion->array_priv);
result[loop] = loopRegion->array_priv; result[loop] = loopRegion->array_priv;
delete(loopRegion); delete loopRegion;
} }
} }
if (result.find(loop) != result.end() && !result[loop].empty()) if (result.find(loop) != result.end() && !result[loop].empty())
AddPrivateArraysToLoop(loop, result[loop], insertedPrivates); addPrivateArraysToLoop(loop, result[loop], insertedPrivates, SPF_messages, declaredArrays);
} }
} }
for (const auto& [loop, accesing] : result)
{
if (accesing.size())
{
__spf_print(1, "found for loop on line %d in file %s\n", loop->lineNum, loop->fileName.c_str());
for (const auto& [name, accesingSet] : accesing)
{
const auto& byDimention = accesingSet.GetElements();
__spf_print(1, " for array %s with dimention %d\n", name.c_str(), byDimention.size());
for (int z = 0; z < byDimention.size(); ++z)
{
__spf_print(1, " dim %d (start, step, tripCount):\n", z);
for (auto& elem : byDimention[z])
__spf_print(1, " [%ld %ld %ld]\n", elem.start, elem.step, elem.tripCount);
}
}
}
}
return insertedPrivates.size();
} }

View File

@@ -3,10 +3,12 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <set> #include <set>
#include <set>
#include "range_structures.h" #include "range_structures.h"
#include "graph_loops.h" #include "graph_loops.h"
#include "CFGraph/CFGraph.h" #include "CFGraph/CFGraph.h"
void findPrivateArrays(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR, std::set<SgStatement*>& insertedPrivates); int findPrivateArrays(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*,
std::vector<SAPFOR::BasicBlock*>>& FullIR, std::set<SgStatement*>& insertedPrivates,
std::map<std::string, std::vector<Messages>>& SPF_messages,
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);

View File

@@ -8,7 +8,7 @@
using namespace std; using namespace std;
static vector<uint64_t> FindParticularSolution(const ArrayDimension& dim1, const ArrayDimension& dim2) static vector<uint64_t> findParticularSolution(const ArrayDimension& dim1, const ArrayDimension& dim2)
{ {
for (uint64_t i = 0; i < dim1.tripCount; i++) for (uint64_t i = 0; i < dim1.tripCount; i++)
{ {
@@ -24,9 +24,9 @@ static vector<uint64_t> FindParticularSolution(const ArrayDimension& dim1, const
} }
/* dim1 /\ dim2 */ /* dim1 /\ dim2 */
static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const ArrayDimension& dim2) static ArrayDimension* dimensionIntersection(const ArrayDimension& dim1, const ArrayDimension& dim2)
{ {
vector<uint64_t> partSolution = FindParticularSolution(dim1, dim2); vector<uint64_t> partSolution = findParticularSolution(dim1, dim2);
if (partSolution.empty()) if (partSolution.empty())
return NULL; return NULL;
@@ -52,9 +52,9 @@ static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const A
} }
/* dim1 / dim2 */ /* dim1 / dim2 */
static vector<ArrayDimension> DimensionDifference(const ArrayDimension& dim1, const ArrayDimension& dim2) static vector<ArrayDimension> dimensionDifference(const ArrayDimension& dim1, const ArrayDimension& dim2)
{ {
ArrayDimension* intersection = DimensionIntersection(dim1, dim2); ArrayDimension* intersection = dimensionIntersection(dim1, dim2);
if (!intersection) if (!intersection)
return { dim1 }; return { dim1 };
@@ -87,10 +87,10 @@ static vector<ArrayDimension> DimensionDifference(const ArrayDimension& dim1, co
} }
static vector<ArrayDimension> DimensionUnion(const ArrayDimension& dim1, const ArrayDimension& dim2) static vector<ArrayDimension> dimensionUnion(const ArrayDimension& dim1, const ArrayDimension& dim2)
{ {
vector<ArrayDimension> res; vector<ArrayDimension> res;
ArrayDimension* inter = DimensionIntersection(dim1, dim2); ArrayDimension* inter = dimensionIntersection(dim1, dim2);
if (!inter) if (!inter)
return { dim1, dim2 }; return { dim1, dim2 };
@@ -98,14 +98,14 @@ static vector<ArrayDimension> DimensionUnion(const ArrayDimension& dim1, const A
delete(inter); delete(inter);
vector<ArrayDimension> diff1, diff2; vector<ArrayDimension> diff1, diff2;
diff1 = DimensionDifference(dim1, dim2); diff1 = dimensionDifference(dim1, dim2);
diff2 = DimensionDifference(dim2, dim1); diff2 = dimensionDifference(dim2, dim1);
res.insert(res.end(), diff1.begin(), diff1.end()); res.insert(res.end(), diff1.begin(), diff1.end());
res.insert(res.end(), diff2.begin(), diff2.end()); res.insert(res.end(), diff2.begin(), diff2.end());
return res; return res;
} }
static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>& firstElement, const vector<ArrayDimension>& secondElement) static vector<ArrayDimension> elementsIntersection(const vector<ArrayDimension>& firstElement, const vector<ArrayDimension>& secondElement)
{ {
if (firstElement.empty() || secondElement.empty()) if (firstElement.empty() || secondElement.empty())
return {}; return {};
@@ -113,13 +113,13 @@ static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>&
size_t dimAmount = firstElement.size(); size_t dimAmount = firstElement.size();
/* check if there is no intersecction */ /* check if there is no intersecction */
for (size_t i = 0; i < dimAmount; i++) for (size_t i = 0; i < dimAmount; i++)
if (FindParticularSolution(firstElement[i], secondElement[i]).empty()) if (findParticularSolution(firstElement[i], secondElement[i]).empty())
return {}; return {};
vector<ArrayDimension> result(dimAmount); vector<ArrayDimension> result(dimAmount);
for (size_t i = 0; i < dimAmount; i++) for (size_t i = 0; i < dimAmount; i++)
{ {
ArrayDimension* resPtr = DimensionIntersection(firstElement[i], secondElement[i]); ArrayDimension* resPtr = dimensionIntersection(firstElement[i], secondElement[i]);
if (resPtr) if (resPtr)
result[i] = *resPtr; result[i] = *resPtr;
else else
@@ -129,7 +129,7 @@ static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>&
return result; return result;
} }
static vector<vector<ArrayDimension>> ElementsDifference(const vector<ArrayDimension>& firstElement, static vector<vector<ArrayDimension>> elementsDifference(const vector<ArrayDimension>& firstElement,
const vector<ArrayDimension>& secondElement) const vector<ArrayDimension>& secondElement)
{ {
if (firstElement.empty()) if (firstElement.empty())
@@ -137,14 +137,14 @@ static vector<vector<ArrayDimension>> ElementsDifference(const vector<ArrayDimen
if (secondElement.empty()) if (secondElement.empty())
return { firstElement }; return { firstElement };
vector<ArrayDimension> intersection = ElementsIntersection(firstElement, secondElement); vector<ArrayDimension> intersection = elementsIntersection(firstElement, secondElement);
vector<vector<ArrayDimension>> result; vector<vector<ArrayDimension>> result;
if (intersection.empty()) if (intersection.empty())
return { firstElement }; return { firstElement };
for (int i = 0; i < firstElement.size(); i++) for (int i = 0; i < firstElement.size(); i++)
{ {
auto dimDiff = DimensionDifference(firstElement[i], secondElement[i]); auto dimDiff = dimensionDifference(firstElement[i], secondElement[i]);
if (!dimDiff.empty()) if (!dimDiff.empty())
{ {
vector<ArrayDimension> firstCopy = firstElement; vector<ArrayDimension> firstCopy = firstElement;
@@ -158,14 +158,14 @@ static vector<vector<ArrayDimension>> ElementsDifference(const vector<ArrayDimen
return result; return result;
} }
static void ElementsUnion(const vector<ArrayDimension>& firstElement, const vector<ArrayDimension>& secondElement, static void elementsUnion(const vector<ArrayDimension>& firstElement, const vector<ArrayDimension>& secondElement,
vector<vector<ArrayDimension>>& lc, vector<vector<ArrayDimension>>& rc, vector<vector<ArrayDimension>>& lc, vector<vector<ArrayDimension>>& rc,
vector<ArrayDimension>& intersection) vector<ArrayDimension>& intersection)
{ {
/* lc(rc) is a set of ranges, which only exist in first(second) element*/ /* lc(rc) is a set of ranges, which only exist in first(second) element*/
intersection = ElementsIntersection(firstElement, secondElement); intersection = elementsIntersection(firstElement, secondElement);
lc = ElementsDifference(firstElement, intersection); lc = elementsDifference(firstElement, intersection);
rc = ElementsDifference(secondElement, intersection); rc = elementsDifference(secondElement, intersection);
} }
void AccessingSet::FindUncovered(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const { void AccessingSet::FindUncovered(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const {
@@ -175,8 +175,8 @@ void AccessingSet::FindUncovered(const vector<ArrayDimension>& element, vector<v
{ {
for (const auto& tailLoc : result) for (const auto& tailLoc : result)
{ {
auto intersection = ElementsIntersection(tailLoc, currentElement); auto intersection = elementsIntersection(tailLoc, currentElement);
auto diff = ElementsDifference(tailLoc, intersection); auto diff = elementsDifference(tailLoc, intersection);
if (!diff.empty()) { if (!diff.empty()) {
newTails.insert(newTails.end(), diff.begin(), diff.end()); newTails.insert(newTails.end(), diff.begin(), diff.end());
} }
@@ -197,13 +197,13 @@ void AccessingSet::FindCoveredBy(const vector<ArrayDimension>& element, vector<v
{ {
for (const auto& currentElement : allElements) for (const auto& currentElement : allElements)
{ {
auto intersection = ElementsIntersection(element, currentElement); auto intersection = elementsIntersection(element, currentElement);
if (!intersection.empty()) if (!intersection.empty())
result.push_back(intersection); result.push_back(intersection);
} }
} }
vector<vector<ArrayDimension>> AccessingSet::GetElements() const { return allElements; } const vector<vector<ArrayDimension>>& AccessingSet::GetElements() const { return allElements; }
void AccessingSet::Insert(const vector<ArrayDimension>& element) void AccessingSet::Insert(const vector<ArrayDimension>& element)
{ {
@@ -283,7 +283,7 @@ bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs)
return false; return false;
} }
bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs) bool operator!=(const arrayAccessingIndexes& lhs, const arrayAccessingIndexes& rhs)
{ {
if (lhs.size() != rhs.size()) if (lhs.size() != rhs.size())
return true; return true;

View File

@@ -22,7 +22,7 @@ public:
AccessingSet(std::vector<std::vector<ArrayDimension>> input) : allElements(input) {}; AccessingSet(std::vector<std::vector<ArrayDimension>> input) : allElements(input) {};
AccessingSet() {}; AccessingSet() {};
AccessingSet(const AccessingSet& a) { allElements = a.GetElements(); }; AccessingSet(const AccessingSet& a) { allElements = a.GetElements(); };
std::vector<std::vector<ArrayDimension>> GetElements() const; const std::vector<std::vector<ArrayDimension>>& GetElements() const;
void Insert(const std::vector<ArrayDimension>& element); void Insert(const std::vector<ArrayDimension>& element);
AccessingSet Union(const AccessingSet& source); AccessingSet Union(const AccessingSet& source);
AccessingSet Intersect(const AccessingSet& secondSet) const; AccessingSet Intersect(const AccessingSet& secondSet) const;
@@ -33,8 +33,8 @@ public:
friend bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs); friend bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs);
}; };
using ArrayAccessingIndexes = std::map<std::string, AccessingSet>; using arrayAccessingIndexes = std::map<std::string, AccessingSet>;
bool operator!=(const ArrayDimension& lhs, const ArrayDimension& rhs); bool operator!=(const ArrayDimension& lhs, const ArrayDimension& rhs);
bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs); bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs);
bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs); bool operator!=(const arrayAccessingIndexes& lhs, const arrayAccessingIndexes& rhs);

View File

@@ -23,7 +23,7 @@ static bool isParentStmt(SgStatement* stmt, SgStatement* parent)
} }
/*returns head block and loop*/ /*returns head block and loop*/
pair<SAPFOR::BasicBlock*, set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const vector<SAPFOR::BasicBlock*> blocks) pair<SAPFOR::BasicBlock*, set<SAPFOR::BasicBlock*>> getBasicBlocksForLoop(const LoopGraph* loop, const vector<SAPFOR::BasicBlock*> blocks)
{ {
set<SAPFOR::BasicBlock*> block_loop; set<SAPFOR::BasicBlock*> block_loop;
SAPFOR::BasicBlock* head_block = nullptr; SAPFOR::BasicBlock* head_block = nullptr;
@@ -51,15 +51,15 @@ pair<SAPFOR::BasicBlock*, set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const
return { head_block, block_loop }; return { head_block, block_loop };
} }
static void BuildLoopIndex(map<SgStatement*, LoopGraph*>& loopForIndex, LoopGraph* loop) { static void buildLoopIndex(map<SgStatement*, LoopGraph*>& loopForIndex, LoopGraph* loop) {
string index = loop->loopSymbol(); string index = loop->loopSymbol();
loopForIndex[loop->loop->GetOriginal()] = loop; loopForIndex[loop->loop->GetOriginal()] = loop;
for (const auto& childLoop : loop->children) for (const auto& childLoop : loop->children)
BuildLoopIndex(loopForIndex, childLoop); buildLoopIndex(loopForIndex, childLoop);
} }
static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, LoopGraph*>& loopForIndex) { static string findIndexName(int pos, SAPFOR::BasicBlock* block, map<string, LoopGraph*>& loopForIndex) {
set<SAPFOR::Argument*> args = { block->getInstructions()[pos]->getInstruction()->getArg1() }; set<SAPFOR::Argument*> args = { block->getInstructions()[pos]->getInstruction()->getArg1() };
for (int i = pos - 1; i >= 0; i--) for (int i = pos - 1; i >= 0; i--)
@@ -93,10 +93,10 @@ static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, Loop
return ""; return "";
} }
static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use, Region* region) { static int getDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, arrayAccessingIndexes& def, arrayAccessingIndexes& use, Region* region) {
auto instructions = block->getInstructions(); auto instructions = block->getInstructions();
map<SgStatement*, LoopGraph*> loopForIndex; map<SgStatement*, LoopGraph*> loopForIndex;
BuildLoopIndex(loopForIndex, loop); buildLoopIndex(loopForIndex, loop);
for (int i = 0; i < instructions.size(); i++) for (int i = 0; i < instructions.size(); i++)
{ {
auto instruction = instructions[i]; auto instruction = instructions[i];
@@ -233,7 +233,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
} }
static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const set<SAPFOR::BasicBlock*>& blockSet, map<SAPFOR::BasicBlock*, Region*>& bbToRegion) static void removeHeaderConnection(SAPFOR::BasicBlock* header, const set<SAPFOR::BasicBlock*>& blockSet, map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
{ {
for (SAPFOR::BasicBlock* block : blockSet) for (SAPFOR::BasicBlock* block : blockSet)
{ {
@@ -249,10 +249,7 @@ static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const set<SAPFOR:
} }
} }
static bool DFS(Region* block, static bool DFS(Region* block, vector<Region*>& result, const set<Region*>& cycleBlocks, map<Region*, int>& color)
vector<Region*>& result,
const set<Region*>& cycleBlocks,
map<Region*, int>& color)
{ {
auto it = color.find(block); auto it = color.find(block);
if (it != color.end()) if (it != color.end())
@@ -275,7 +272,7 @@ static bool DFS(Region* block,
return true; return true;
} }
bool HasCycle(Region* block, const std::set<Region*>& cycleBlocks, std::set<Region*>& visitedBlocks) bool hasCycle(Region* block, const std::set<Region*>& cycleBlocks, std::set<Region*>& visitedBlocks)
{ {
return false; return false;
if (visitedBlocks.find(block) != visitedBlocks.end()) if (visitedBlocks.find(block) != visitedBlocks.end())
@@ -283,13 +280,13 @@ bool HasCycle(Region* block, const std::set<Region*>& cycleBlocks, std::set<Regi
visitedBlocks.insert(block); visitedBlocks.insert(block);
for (Region* nextBlock : block->getNextRegions()) for (Region* nextBlock : block->getNextRegions())
{ {
if (cycleBlocks.find(nextBlock) != cycleBlocks.end() && HasCycle(nextBlock, cycleBlocks, visitedBlocks)) if (cycleBlocks.find(nextBlock) != cycleBlocks.end() && hasCycle(nextBlock, cycleBlocks, visitedBlocks))
return true; return true;
} }
return false; return false;
} }
bool TopologySort(std::vector<Region*>& basikBlocks, Region* header) bool topologySort(std::vector<Region*>& basikBlocks, Region* header)
{ {
set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end()); set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end());
vector<Region*> result; vector<Region*> result;
@@ -301,7 +298,7 @@ bool TopologySort(std::vector<Region*>& basikBlocks, Region* header)
return true; return true;
} }
static void SetConnections(map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const set<SAPFOR::BasicBlock*>& blockSet) static void setConnections(map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const set<SAPFOR::BasicBlock*>& blockSet)
{ {
for (SAPFOR::BasicBlock* block : blockSet) for (SAPFOR::BasicBlock* block : blockSet)
{ {
@@ -315,11 +312,11 @@ static void SetConnections(map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const
} }
} }
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, map<SAPFOR::BasicBlock*, Region*>& bbToRegion) static Region* createSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
{ {
Region* region = new Region; Region* region = new Region;
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); auto [header, blockSet] = getBasicBlocksForLoop(loop, Blocks);
RemoveHeaderConnection(header, blockSet, bbToRegion); removeHeaderConnection(header, blockSet, bbToRegion);
if (bbToRegion.find(header) != bbToRegion.end()) if (bbToRegion.find(header) != bbToRegion.end())
region->setHeader(bbToRegion.at(header)); region->setHeader(bbToRegion.at(header));
else else
@@ -336,34 +333,34 @@ static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*
{ {
if (!childLoop->isFor()) if (!childLoop->isFor())
continue; continue;
region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); region->addSubRegions(createSubRegion(childLoop, Blocks, bbToRegion));
} }
if (!TopologySort(region->getBasickBlocks(), region->getHeader())) if (!topologySort(region->getBasickBlocks(), region->getHeader()))
throw std::runtime_error("Unnoticed cycle"); throw std::runtime_error("Unnoticed cycle");
return region; return region;
} }
Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks) Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks)
{ {
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks); auto [header, blockSet] = getBasicBlocksForLoop(loop, Blocks);
map<SAPFOR::BasicBlock*, Region*> bbToRegion; map<SAPFOR::BasicBlock*, Region*> bbToRegion;
for (auto poiner : blockSet) for (auto poiner : blockSet)
{ {
bbToRegion[poiner] = new Region(*poiner); bbToRegion[poiner] = new Region(*poiner);
this->basickBlocks.push_back(bbToRegion[poiner]); this->basickBlocks.push_back(bbToRegion[poiner]);
GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use, bbToRegion[poiner]); getDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use, bbToRegion[poiner]);
} }
this->header = bbToRegion[header]; this->header = bbToRegion[header];
SetConnections(bbToRegion, blockSet); setConnections(bbToRegion, blockSet);
RemoveHeaderConnection(header, blockSet, bbToRegion); removeHeaderConnection(header, blockSet, bbToRegion);
//create subRegions //create subRegions
for (LoopGraph* childLoop : loop->children) for (LoopGraph* childLoop : loop->children)
{ {
if (!childLoop->isFor()) if (!childLoop->isFor())
continue; continue;
subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); subRegions.insert(createSubRegion(childLoop, Blocks, bbToRegion));
} }
if (!TopologySort(basickBlocks, this->header)) if (!topologySort(basickBlocks, this->header))
throw std::runtime_error("Unnoticed cycle"); throw std::runtime_error("Unnoticed cycle");
} }

View File

@@ -10,7 +10,7 @@
struct RegionInstruction struct RegionInstruction
{ {
ArrayAccessingIndexes def, use, in, out; arrayAccessingIndexes def, use, in, out;
}; };
class Region : public SAPFOR::BasicBlock { class Region : public SAPFOR::BasicBlock {
@@ -67,7 +67,7 @@ public:
std::vector<RegionInstruction> instructions; std::vector<RegionInstruction> instructions;
ArrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv; arrayAccessingIndexes array_def, array_use, array_out, array_in, array_priv;
private: private:
std::vector<Region*> basickBlocks; std::vector<Region*> basickBlocks;
@@ -79,6 +79,6 @@ private:
Region* header; Region* header;
}; };
bool HasCycle(Region* block, const std::set<Region*>& cycleBlocks, std::set<Region*>& visitedBlocks); bool hasCycle(Region* block, const std::set<Region*>& cycleBlocks, std::set<Region*>& visitedBlocks);
bool TopologySort(std::vector<Region*>& basikBlocks, Region* header); bool topologySort(std::vector<Region*>& basikBlocks, Region* header);

View File

@@ -1036,24 +1036,6 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
if (internalExit < 0) if (internalExit < 0)
throw -1; throw -1;
set<int> applyFor = { LOOPS_SPLITTER,
LOOPS_COMBINER,
PRIVATE_REMOVING,
PRIVATE_ARRAYS_EXPANSION,
PRIVATE_ARRAYS_SHRINKING,
REMOVE_DEAD_CODE,
MOVE_OPERATORS };
if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end())
{
SgStatement* mainUnit = findMainUnit(&project, SPF_messages);
checkNull(mainUnit, convertFileName(__FILE__).c_str(), __LINE__);
getObjectForFileFromMap(mainUnit->fileName(), SPF_messages).push_back(Messages(ERROR, mainUnit->lineNumber(), R197, L"Transformation cannot be performed - nothing to change", 2023));
__spf_print(1, "%d Transformation cannot be performed - nothing to change, count of transform %d, err %d\n", mainUnit->lineNumber(), countOfTransform, internalExit);
throw -11;
}
sendMessage_2lvl(2); sendMessage_2lvl(2);
// ********************************** /// // ********************************** ///
/// SECOND AGGREGATION STEP /// /// SECOND AGGREGATION STEP ///
@@ -1905,13 +1887,13 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS) else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS)
transformAssumedSizeParameters(allFuncInfo); transformAssumedSizeParameters(allFuncInfo);
else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS) else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS)
findPrivateArrays(loopGraph, fullIR, insertedPrivates); countOfTransform = findPrivateArrays(loopGraph, fullIR, insertedPrivates, SPF_messages, declaredArrays);
else if (curr_regime == MERGE_REGIONS) else if (curr_regime == MERGE_REGIONS)
mergeRegions(parallelRegions, allFuncInfo); mergeRegions(parallelRegions, allFuncInfo);
else if (curr_regime == ARRAY_PROPAGATION) else if (curr_regime == ARRAY_PROPAGATION)
arrayConstantPropagation(project); arrayConstantPropagation(project);
else if (curr_regime == ARRAY_PROPAGATION_RESTORE) else if (curr_regime == ARRAY_PROPAGATION_RESTORE)
restoreArrays(); arrayConstantPropagationRrestore();
const float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - timeForPass).count() / 1000.; const float elapsed = duration_cast<milliseconds>(high_resolution_clock::now() - timeForPass).count() / 1000.;
const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.; const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.;
@@ -1921,6 +1903,25 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
if (internalExit != 0) if (internalExit != 0)
throw -1; throw -1;
set<int> applyFor = { LOOPS_SPLITTER,
LOOPS_COMBINER,
PRIVATE_REMOVING,
PRIVATE_ARRAYS_EXPANSION,
PRIVATE_ARRAYS_SHRINKING,
REMOVE_DEAD_CODE,
MOVE_OPERATORS,
FIND_PRIVATE_ARRAYS_ANALYSIS };
if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end())
{
SgStatement* mainUnit = findMainUnit(&project, SPF_messages);
checkNull(mainUnit, convertFileName(__FILE__).c_str(), __LINE__);
getObjectForFileFromMap(mainUnit->fileName(), SPF_messages).push_back(Messages(ERROR, mainUnit->lineNumber(), R197, L"Transformation cannot be performed - nothing to change", 2023));
__spf_print(1, "%d Transformation cannot be performed - nothing to change, count of transform %d, err %d\n", mainUnit->lineNumber(), countOfTransform, internalExit);
throw - 11;
}
return true; return true;
} }

View File

@@ -15,10 +15,11 @@ static set<SgStatement*> changed;
static map<string, SgSymbol*> variablesToAdd; static map<string, SgSymbol*> variablesToAdd;
static map<string, set<SgStatement*>> positionsToAdd; static map<string, set<SgStatement*>> positionsToAdd;
static map<string, string> arrayToName; static map<string, string> arrayToName;
static set<SgStatement*> statementsToRemove; static map<string, set<SgStatement*>> statementsToRemove;
static map<string, map<SgStatement*, SgStatement*>> expToChange; static map<string, map<SgStatement*, SgStatement*>> expToChange;
static int variableNumber = 0;
static bool CheckConstIndexes(SgExpression* exp) static bool checkConstIndexes(SgExpression* exp)
{ {
if (!exp) if (!exp)
{ {
@@ -41,7 +42,7 @@ static bool CheckConstIndexes(SgExpression* exp)
return true; return true;
} }
static SgExpression* CreateVar(int& variableNumber, SgType* type) static SgExpression* createVar(SgType* type)
{ {
string varName = "tmp_prop_var"; string varName = "tmp_prop_var";
string name = varName + std::to_string(variableNumber) + "__"; string name = varName + std::to_string(variableNumber) + "__";
@@ -56,10 +57,11 @@ static SgExpression* CreateVar(int& variableNumber, SgType* type)
return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr()); return new SgExpression(VAR_REF, NULL, NULL, varSymbol, type->copyPtr());
} }
static SgStatement* FindLastDeclStatement(SgStatement* funcStart) static SgStatement* findLastDeclStatement(SgStatement* funcStart)
{ {
if (!funcStart) if (!funcStart)
return NULL; return NULL;
SgStatement* endSt = funcStart->lastNodeOfStmt(); SgStatement* endSt = funcStart->lastNodeOfStmt();
SgStatement* cur = funcStart->lexNext(); SgStatement* cur = funcStart->lexNext();
SgStatement* lastDecl = funcStart; SgStatement* lastDecl = funcStart;
@@ -82,7 +84,7 @@ static SgStatement* FindLastDeclStatement(SgStatement* funcStart)
return lastDecl; return lastDecl;
} }
static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map<string, SgSymbol*>& symbols) static void insertCommonAndDeclsForFunction(SgStatement* funcStart, const map<string, SgSymbol*>& symbols)
{ {
if (symbols.empty()) if (symbols.empty())
return; return;
@@ -90,7 +92,7 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map<st
if (!funcStart) if (!funcStart)
return; return;
const string commonBlockName = "propagation_common__"; const string commonBlockName = "__propagation_common__";
SgStatement* funcEnd = funcStart->lastNodeOfStmt(); SgStatement* funcEnd = funcStart->lastNodeOfStmt();
SgStatement* commonStat = NULL; SgStatement* commonStat = NULL;
@@ -130,7 +132,7 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map<st
} }
SgExpression* varList = makeExprList(varRefs, false); SgExpression* varList = makeExprList(varRefs, false);
SgStatement* insertAfter = FindLastDeclStatement(funcStart); SgStatement* insertAfter = findLastDeclStatement(funcStart);
for (const auto& [name, sym] : symbols) for (const auto& [name, sym] : symbols)
{ {
if (!sym) if (!sym)
@@ -149,7 +151,7 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map<st
insertAfter->insertStmtAfter(*declStmt, *funcStart); insertAfter->insertStmtAfter(*declStmt, *funcStart);
insertAfter = declStmt; insertAfter = declStmt;
statementsToRemove.insert(declStmt); statementsToRemove[declStmt->fileName()].insert(declStmt);
} }
if (!commonList) if (!commonList)
@@ -164,14 +166,12 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map<st
commonStat->setlineNumber(getNextNegativeLineNumber()); commonStat->setlineNumber(getNextNegativeLineNumber());
commonStat->setExpression(0, commonList); commonStat->setExpression(0, commonList);
SgStatement* lastDecl = FindLastDeclStatement(funcStart); SgStatement* lastDecl = findLastDeclStatement(funcStart);
lastDecl->insertStmtAfter(*commonStat, *funcStart); lastDecl->insertStmtAfter(*commonStat, *funcStart);
statementsToRemove.insert(commonStat); statementsToRemove[commonStat->fileName()].insert(commonStat);
} }
else else
{
commonList->setLhs(varList); commonList->setLhs(varList);
}
} }
@@ -179,6 +179,7 @@ static void copyStatement(SgStatement* st)
{ {
if (!st) if (!st)
return; return;
if (expToChange[st->fileName()].find(st) == expToChange[st->fileName()].end()) if (expToChange[st->fileName()].find(st) == expToChange[st->fileName()].end())
{ {
SgStatement* boundCopy = st->copyPtr(); SgStatement* boundCopy = st->copyPtr();
@@ -195,7 +196,7 @@ static void copyStatement(SgStatement* st)
} }
} }
static bool TransformRightPart(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable, int& variableNumber) static bool transformRightPart(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable)
{ {
if (!exp) if (!exp)
return false; return false;
@@ -204,13 +205,13 @@ static bool TransformRightPart(SgStatement* st, SgExpression* exp, map<string, S
string expUnparsed; string expUnparsed;
SgExpression* toAdd = NULL; SgExpression* toAdd = NULL;
if (isArrayRef(exp) && CheckConstIndexes(exp->lhs())) if (isArrayRef(exp) && checkConstIndexes(exp->lhs()))
{ {
expUnparsed = exp->unparse(); expUnparsed = exp->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp && exp->symbol() && if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp && exp->symbol() &&
exp->symbol()->type() && exp->symbol()->type()->baseType()) exp->symbol()->type() && exp->symbol()->type()->baseType())
{ {
arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); arrayToVariable[expUnparsed] = createVar(exp->symbol()->type()->baseType());
arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse();
} }
positionsToAdd[string(declPlace->fileName())].insert(declPlace); positionsToAdd[string(declPlace->fileName())].insert(declPlace);
@@ -220,16 +221,17 @@ static bool TransformRightPart(SgStatement* st, SgExpression* exp, map<string, S
st->setExpression(1, newVarExp); st->setExpression(1, newVarExp);
return true; return true;
} }
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
if (subnodes[i] && isArrayRef(subnodes[i]) && subnodes[i]->symbol() && subnodes[i]->symbol()->type() && if (subnodes[i] && isArrayRef(subnodes[i]) && subnodes[i]->symbol() && subnodes[i]->symbol()->type() &&
subnodes[i]->symbol()->type()->baseType() && CheckConstIndexes(subnodes[i]->lhs())) subnodes[i]->symbol()->type()->baseType() && checkConstIndexes(subnodes[i]->lhs()))
{ {
isChanged = true; isChanged = true;
expUnparsed = subnodes[i]->unparse(); expUnparsed = subnodes[i]->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end()) if (arrayToVariable.find(expUnparsed) == arrayToVariable.end())
{ {
arrayToVariable[expUnparsed] = CreateVar(variableNumber, subnodes[i]->symbol()->type()->baseType()); arrayToVariable[expUnparsed] = createVar(subnodes[i]->symbol()->type()->baseType());
arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse();
} }
positionsToAdd[string(declPlace->fileName())].insert(declPlace); positionsToAdd[string(declPlace->fileName())].insert(declPlace);
@@ -246,13 +248,13 @@ static bool TransformRightPart(SgStatement* st, SgExpression* exp, map<string, S
} }
} }
else else
isChanged = isChanged || TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber); isChanged = isChanged || transformRightPart(st, subnodes[i], arrayToVariable);
} }
return isChanged; return isChanged;
} }
static void TransformLeftPart(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable, int& variableNumber) static void transformLeftPart(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable)
{ {
if (!st || !st->expr(1)) if (!st || !st->expr(1))
return; return;
@@ -262,10 +264,11 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, map<string, Sg
return; return;
if (changed.find(st) != changed.end()) if (changed.find(st) != changed.end())
return; return;
string expUnparsed = exp->unparse(); string expUnparsed = exp->unparse();
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType()) if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp->symbol()->type()->baseType())
{ {
arrayToVariable[expUnparsed] = CreateVar(variableNumber, exp->symbol()->type()->baseType()); arrayToVariable[expUnparsed] = createVar(exp->symbol()->type()->baseType());
arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse(); arrayToName[expUnparsed] = arrayToVariable[expUnparsed]->unparse();
} }
positionsToAdd[string(declPlace->fileName())].insert(declPlace); positionsToAdd[string(declPlace->fileName())].insert(declPlace);
@@ -282,16 +285,16 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, map<string, Sg
newStatement->setLocalLineNumber(st->lineNumber()); newStatement->setLocalLineNumber(st->lineNumber());
changed.insert(st); changed.insert(st);
statementsToRemove.insert(newStatement); statementsToRemove[newStatement->fileName()].insert(newStatement);
} }
static void TransformBorder(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable, int& variableNumber) static void transformBorder(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable)
{ {
if (!st || !exp) if (!st || !exp)
return; return;
SgStatement* firstStatement = declPlace->lexPrev(); SgStatement* firstStatement = declPlace->lexPrev();
positionsToAdd[string(declPlace->fileName())].insert(declPlace); positionsToAdd[string(declPlace->fileName())].insert(declPlace);
TransformRightPart(st, exp, arrayToVariable, variableNumber); transformRightPart(st, exp, arrayToVariable);
st = st->lexPrev(); st = st->lexPrev();
while (st &&st != firstStatement) while (st &&st != firstStatement)
{ {
@@ -299,16 +302,16 @@ static void TransformBorder(SgStatement* st, SgExpression* exp, map<string, SgEx
{ {
if (st->expr(1)) if (st->expr(1))
{ {
TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber); transformRightPart(st, st->expr(1), arrayToVariable);
} }
if (st->expr(0) && isArrayRef(st->expr(0)) && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) if (st->expr(0) && isArrayRef(st->expr(0)) && checkConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); transformLeftPart(st, st->expr(0), arrayToVariable);
} }
st = st->lexPrev(); st = st->lexPrev();
} }
} }
static void CheckVariable(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable, int& variableNumber) static void checkVariable(SgStatement* st, SgExpression* exp, map<string, SgExpression*>& arrayToVariable)
{ {
SgStatement* firstStatement = declPlace->lexPrev(); SgStatement* firstStatement = declPlace->lexPrev();
st = st->lexPrev(); st = st->lexPrev();
@@ -316,23 +319,24 @@ static void CheckVariable(SgStatement* st, SgExpression* exp, map<string, SgExpr
{ {
if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol()) if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol() == exp->symbol())
{ {
if (TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber)) if (transformRightPart(st, st->expr(1), arrayToVariable))
{ {
positionsToAdd[string(declPlace->fileName())].insert(declPlace); positionsToAdd[string(declPlace->fileName())].insert(declPlace);
} }
} }
if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{ {
if (st->expr(1)) if (st->expr(1))
{ {
if(TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber)) if(transformRightPart(st, st->expr(1), arrayToVariable))
{ {
positionsToAdd[string(declPlace->fileName())].insert(declPlace); positionsToAdd[string(declPlace->fileName())].insert(declPlace);
} }
} }
if (st->expr(0) && isArrayRef(st->expr(0)) && CheckConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end()) if (st->expr(0) && isArrayRef(st->expr(0)) && checkConstIndexes(st->expr(0)->lhs()) && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
{ {
TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber); transformLeftPart(st, st->expr(0), arrayToVariable);
positionsToAdd[string(declPlace->fileName())].insert(declPlace); positionsToAdd[string(declPlace->fileName())].insert(declPlace);
} }
} }
@@ -340,8 +344,7 @@ static void CheckVariable(SgStatement* st, SgExpression* exp, map<string, SgExpr
} }
} }
static void findConstValues( static void findConstValues(SgProject& project,
SgProject& project,
const map<string, map<string, SgStatement*>>& borderVars, const map<string, map<string, SgStatement*>>& borderVars,
const map<string, SgExpression*>& arrayToVariable, const map<string, SgExpression*>& arrayToVariable,
map<string, int>& hitCount, map<string, int>& hitCount,
@@ -422,14 +425,14 @@ static void insertDefinition(map<string, map<SgStatement*, vector<pair<string, s
if (insertBefore && insertBefore->controlParent()) if (insertBefore && insertBefore->controlParent())
{ {
insertBefore->insertStmtBefore(*asg, *insertBefore->controlParent()); insertBefore->insertStmtBefore(*asg, *insertBefore->controlParent());
statementsToRemove.insert(asg); statementsToRemove[asg->fileName()].insert(asg);
} }
} }
} }
} }
} }
static void applyLeftPartForUnchangedAssignments(SgProject& project, map<string, SgExpression*>& arrayToVariable, int& variableNumber) static void applyLeftPartForUnchangedAssignments(SgProject& project, map<string, SgExpression*>& arrayToVariable)
{ {
for (int fi = 0; fi < project.numberOfFiles(); ++fi) for (int fi = 0; fi < project.numberOfFiles(); ++fi)
{ {
@@ -468,28 +471,28 @@ static void applyLeftPartForUnchangedAssignments(SgProject& project, map<string,
continue; continue;
if (!lhs->symbol()->type()->baseType()) if (!lhs->symbol()->type()->baseType())
continue; continue;
if (!CheckConstIndexes(lhs->lhs())) if (!checkConstIndexes(lhs->lhs()))
continue; continue;
const string lhsUnparsed = lhs->unparse(); const string lhsUnparsed = lhs->unparse();
if (arrayToVariable.find(lhsUnparsed) == arrayToVariable.end()) if (arrayToVariable.find(lhsUnparsed) == arrayToVariable.end())
continue; continue;
TransformLeftPart(st, lhs, arrayToVariable, variableNumber); transformLeftPart(st, lhs, arrayToVariable);
} }
} }
} }
} }
static bool ContainsArrayRefRecursive(SgExpression* exp) static bool containsArrayRefRecursive(SgExpression* exp)
{ {
if (!exp) if (!exp)
return false; return false;
if (isArrayRef(exp) && CheckConstIndexes(exp->lhs())) if (isArrayRef(exp) && checkConstIndexes(exp->lhs()))
return true; return true;
return ContainsArrayRefRecursive(exp->lhs()) || ContainsArrayRefRecursive(exp->rhs()); return containsArrayRefRecursive(exp->lhs()) || containsArrayRefRecursive(exp->rhs());
} }
static void getBorderVars(SgExpression* exp, const string& filename, map<string, map<string, SgStatement*>>& borderVars) static void getBorderVars(SgExpression* exp, const string& filename, map<string, map<string, SgStatement*>>& borderVars)
@@ -497,21 +500,19 @@ static void getBorderVars(SgExpression* exp, const string& filename, map<string,
if (!exp) if (!exp)
return; return;
if ((isArrayRef(exp) && CheckConstIndexes(exp->lhs())) || exp->variant() == VAR_REF) if ((isArrayRef(exp) && checkConstIndexes(exp->lhs())) || exp->variant() == VAR_REF)
borderVars[filename][string(exp->unparse())] = declPlace; borderVars[filename][string(exp->unparse())] = declPlace;
getBorderVars(exp->lhs(), filename, borderVars); getBorderVars(exp->lhs(), filename, borderVars);
getBorderVars(exp->rhs(), filename, borderVars); getBorderVars(exp->rhs(), filename, borderVars);
} }
static void processLoopBound( static void processLoopBound(SgStatement* st,
SgStatement* st,
SgExpression* bound, SgExpression* bound,
const string& boundUnparsed, const string& boundUnparsed,
bool isUpperBound, bool isUpperBound,
map<string, SgExpression*>& arrayToVariable, map<string, SgExpression*>& arrayToVariable,
map<string, map<string, SgStatement*>>& borderVars, map<string, map<string, SgStatement*>>& borderVars)
int& variableNumber)
{ {
if (!bound || !st) if (!bound || !st)
return; return;
@@ -520,36 +521,40 @@ static void processLoopBound(
getBorderVars(exp, st->fileName(), borderVars); getBorderVars(exp, st->fileName(), borderVars);
if (ContainsArrayRefRecursive(exp), borderVars, st->fileName()) if (containsArrayRefRecursive(exp), borderVars, st->fileName())
{ {
copyStatement(st); copyStatement(st);
TransformBorder(st, bound, arrayToVariable, variableNumber); transformBorder(st, bound, arrayToVariable);
positionsToAdd[string(declPlace->fileName())].insert(declPlace); positionsToAdd[string(declPlace->fileName())].insert(declPlace);
} }
else if (bound->variant() == VAR_REF) else if (bound->variant() == VAR_REF)
CheckVariable(st, bound, arrayToVariable, variableNumber); checkVariable(st, bound, arrayToVariable);
} }
void arrayConstantPropagation(SgProject& project) void arrayConstantPropagation(SgProject& project)
{ {
map<string, SgExpression*> arrayToVariable; map<string, SgExpression*> arrayToVariable;
map<string, map<string, SgStatement*>> borderVars; map<string, map<string, SgStatement*>> borderVars;
int variableNumber = 0;
for (int i = 0; i < project.numberOfFiles(); i++) for (int i = 0; i < project.numberOfFiles(); i++)
{ {
SgFile* file = &(project.file(i)); SgFile *file = &(project.file(i));
if (!file) if (!file)
continue; printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgFile::switchToFile(file->filename());
if (SgFile::switchToFile(file->filename()) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const int funcNum = file->numberOfFunctions(); const int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i) for (int i = 0; i < funcNum; ++i)
{ {
SgStatement* st = file->functions(i); SgStatement* st = file->functions(i);
if (!st) if (!st)
continue; printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
declPlace = st; declPlace = st;
SgStatement* lastNode = st->lastNodeOfStmt(); SgStatement* lastNode = st->lastNodeOfStmt();
@@ -568,20 +573,22 @@ void arrayConstantPropagation(SgProject& project)
string lowerBoundUnparsed = lowerBound->unparse(); string lowerBoundUnparsed = lowerBound->unparse();
string upperBoundUnparsed = upperBound->unparse(); string upperBoundUnparsed = upperBound->unparse();
processLoopBound(st, st->expr(0), upperBoundUnparsed, true, arrayToVariable, borderVars, variableNumber); processLoopBound(st, st->expr(0), upperBoundUnparsed, true, arrayToVariable, borderVars);
processLoopBound(st, st->expr(0), lowerBoundUnparsed, false, arrayToVariable, borderVars, variableNumber); processLoopBound(st, st->expr(0), lowerBoundUnparsed, false, arrayToVariable, borderVars);
} }
} }
} }
} }
applyLeftPartForUnchangedAssignments(project, arrayToVariable, variableNumber);
applyLeftPartForUnchangedAssignments(project, arrayToVariable);
map<string, set<SgStatement*>> funcStarts; map<string, set<SgStatement*>> funcStarts;
for (const auto& [fileName, statements] : positionsToAdd) for (const auto& [fileName, statements] : positionsToAdd)
{ {
int res = SgFile::switchToFile(fileName); int res = SgFile::switchToFile(fileName);
if (res == -1) if (res == -1)
continue; printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (SgStatement* st : statements) for (SgStatement* st : statements)
{ {
SgStatement* scope = isSgProgHedrStmt(st) ? st : st->controlParent(); SgStatement* scope = isSgProgHedrStmt(st) ? st : st->controlParent();
@@ -589,42 +596,44 @@ void arrayConstantPropagation(SgProject& project)
funcStarts[fileName].insert(scope); funcStarts[fileName].insert(scope);
} }
} }
for (const auto& [fileName, statements] : funcStarts) for (const auto& [fileName, statements] : funcStarts)
{ {
SgFile::switchToFile(fileName); SgFile::switchToFile(fileName);
for (SgStatement* st : statements) for (SgStatement* st : statements)
{ {
InsertCommonAndDeclsForFunction(st, variablesToAdd); insertCommonAndDeclsForFunction(st, variablesToAdd);
} }
} }
map<string, map<SgStatement*, vector<pair<string, string>>>> result; map<string, map<SgStatement*, vector<pair<string, string>>>> result;
map<string, int> hitCount; map<string, int> hitCount;
findConstValues(project, borderVars, arrayToVariable, hitCount, result); findConstValues(project, borderVars, arrayToVariable, hitCount, result);
insertDefinition(result, hitCount); insertDefinition(result, hitCount);
} }
void restoreArrays() void arrayConstantPropagationRrestore()
{ {
for (auto& [filename, statements] : expToChange) for (auto& [filename, statements] : expToChange)
{ {
if (SgFile::switchToFile(filename) == -1) if (SgFile::switchToFile(filename) == -1)
continue; printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& [statement, statementCopy] : statements) for (auto& [statement, statementCopy] : statements)
{ {
if (statement && statementCopy) if (statement && statementCopy)
{
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{
statement->setExpression(i, statementCopy->expr(i)); statement->setExpression(i, statementCopy->expr(i));
} }
}
}
} }
for (SgStatement* st : statementsToRemove) for (auto& [filename, statements] : statementsToRemove)
{ {
SgFile::switchToFile(st->fileName()); if (SgFile::switchToFile(filename) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (auto& st : statements)
st->deleteStmt(); st->deleteStmt();
} }
} }

View File

@@ -8,4 +8,4 @@ using namespace std;
void arrayConstantPropagation(SgProject& project); void arrayConstantPropagation(SgProject& project);
void restoreArrays(); void arrayConstantPropagationRrestore();

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_SPF "2483" #define VERSION_SPF "2485"