Compare commits
3 Commits
5f25567a14
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1bcaeba5c | ||
|
|
357f961d68 | ||
| 8b282ebc21 |
@@ -20,14 +20,11 @@
|
||||
|
||||
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 void RemoveEmptyPoints(ArrayAccessingIndexes& container)
|
||||
static void removeEmptyPoints(arrayAccessingIndexes& container)
|
||||
{
|
||||
ArrayAccessingIndexes resultContainer;
|
||||
arrayAccessingIndexes resultContainer;
|
||||
set<string> toRemove;
|
||||
|
||||
for (auto& [arrayName, accessingSet] : container)
|
||||
@@ -52,7 +49,7 @@ static void RemoveEmptyPoints(ArrayAccessingIndexes& container)
|
||||
container[arrayName] = accessingSet;
|
||||
}
|
||||
|
||||
static void Collapse(Region* region)
|
||||
static void collapse(Region* region)
|
||||
{
|
||||
if (region->getBasickBlocks().empty())
|
||||
return;
|
||||
@@ -90,7 +87,7 @@ static void Collapse(Region* region)
|
||||
RegionInstruction instruction;
|
||||
instruction.def = move(region->array_def);
|
||||
|
||||
ArrayAccessingIndexes recursivePriv;
|
||||
arrayAccessingIndexes recursivePriv;
|
||||
for (auto& byBlock : region->getBasickBlocks())
|
||||
{
|
||||
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& instruction : byBlock->instructions)
|
||||
for (auto& [arrayName, _] : instruction.use)
|
||||
@@ -134,9 +131,9 @@ static void Collapse(Region* region)
|
||||
region->array_priv = move(recursivePriv);
|
||||
}
|
||||
|
||||
static void SolveForBasickBlock(Region* block)
|
||||
static void solveForBasickBlock(Region* block)
|
||||
{
|
||||
ArrayAccessingIndexes newIn;
|
||||
arrayAccessingIndexes newIn;
|
||||
bool flagFirst = true;
|
||||
for (Region* prevBlock : block->getPrevRegions())
|
||||
{
|
||||
@@ -175,7 +172,7 @@ static void SolveForBasickBlock(Region* block)
|
||||
if (i > 0)
|
||||
instruction.in = block->instructions[i - 1].out;
|
||||
|
||||
ArrayAccessingIndexes newOut;
|
||||
arrayAccessingIndexes newOut;
|
||||
if (instruction.def.empty())
|
||||
newOut = instruction.in;
|
||||
else if (instruction.in.empty())
|
||||
@@ -192,11 +189,9 @@ static void SolveForBasickBlock(Region* block)
|
||||
for (auto& [arrayName, accessSet] : instruction.in)
|
||||
{
|
||||
if (newOut.find(arrayName) == newOut.end())
|
||||
{
|
||||
newOut[arrayName] = accessSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
instruction.out = move(newOut);
|
||||
}
|
||||
@@ -204,30 +199,31 @@ static void SolveForBasickBlock(Region* block)
|
||||
block->array_out = block->instructions.back().out;
|
||||
}
|
||||
|
||||
static void SolveDataFlowTopologically(Region* DFG)
|
||||
static void solveDataFlowTopologically(Region* DFG)
|
||||
{
|
||||
for (Region* b : DFG->getBasickBlocks())
|
||||
{
|
||||
collapsed.insert(b);
|
||||
SolveForBasickBlock(b);
|
||||
solveForBasickBlock(b);
|
||||
}
|
||||
}
|
||||
|
||||
static void SolveDataFlow(Region* DFG)
|
||||
static void solveDataFlow(Region* DFG)
|
||||
{
|
||||
if (!DFG)
|
||||
return;
|
||||
|
||||
for (Region* subRegion : DFG->getSubRegions())
|
||||
{
|
||||
SolveDataFlow(subRegion);
|
||||
solveDataFlow(subRegion);
|
||||
DFG->addBasickBlocks(subRegion);
|
||||
}
|
||||
vector<Region*>& blocks = DFG->getBasickBlocks();
|
||||
auto pos = remove_if(blocks.begin(), blocks.end(), [](Region* r) { return collapsed.find(r) != collapsed.end(); });
|
||||
blocks.erase(pos, blocks.end());
|
||||
TopologySort(DFG->getBasickBlocks(), DFG->getHeader());
|
||||
SolveDataFlowTopologically(DFG);
|
||||
Collapse(DFG);
|
||||
topologySort(DFG->getBasickBlocks(), DFG->getHeader());
|
||||
solveDataFlowTopologically(DFG);
|
||||
collapse(DFG);
|
||||
}
|
||||
|
||||
static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>& declaredDims)
|
||||
@@ -247,9 +243,7 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>
|
||||
else if (constValSymb)
|
||||
dimLength = stol(constValSymb->constantValue()->unparse());
|
||||
else if (subscriptExpr)
|
||||
{
|
||||
dimLength = stol(subscriptExpr->rhs()->unparse()) - stol(subscriptExpr->lhs()->unparse());
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
@@ -260,7 +254,7 @@ static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>
|
||||
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)
|
||||
return nullptr;
|
||||
@@ -268,10 +262,10 @@ static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym)
|
||||
{
|
||||
DIST::Array* distArr = val.first;
|
||||
if (!distArr)
|
||||
continue;
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
Symbol* declSym = distArr->GetDeclSymbol();
|
||||
if (!declSym)
|
||||
continue;
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
SgSymbol* sgDecl = declSym->GetOriginal();
|
||||
if (sgDecl && isEqSymbols(sgDecl, arrSym))
|
||||
return distArr;
|
||||
@@ -279,7 +273,7 @@ static DIST::Array* getDistArrayBySymbol(SgSymbol* arrSym)
|
||||
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())
|
||||
return false;
|
||||
@@ -291,7 +285,7 @@ static bool CheckDimensionLength(const AccessingSet& array)
|
||||
vector<uint64_t> declaredDims;
|
||||
declaredDims.reserve(dimCount);
|
||||
|
||||
DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol());
|
||||
DIST::Array* distArr = getDistArrayBySymbol(arrayRef->symbol(), declaredArrays);
|
||||
if (distArr && distArr->GetDimSize() == (int)dimCount)
|
||||
{
|
||||
const auto& sizes = distArr->GetSizes();
|
||||
@@ -317,7 +311,9 @@ static bool CheckDimensionLength(const AccessingSet& array)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set<SgStatement*>& insertedPrivates)
|
||||
static void 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);
|
||||
spfStat->setlineNumber(loop->loop->lineNumber());
|
||||
@@ -328,19 +324,12 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes&
|
||||
{
|
||||
int idx = arrayName.find('%');
|
||||
string name = (idx != -1 ? arrayName.substr(idx+1) : arrayName);
|
||||
if (!CheckDimensionLength(accessingSet))
|
||||
if (!checkDimensionLength(accessingSet, declaredArrays))
|
||||
{
|
||||
wstring messageE, messageR;
|
||||
__spf_printToLongBuf(
|
||||
messageE,
|
||||
L"Private array '%s' was skipped because dimension lengths are inconsistent",
|
||||
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));
|
||||
__spf_printToLongBuf(messageE, L"Private array '%s' was skipped because dimension lengths are inconsistent", 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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
void 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)
|
||||
{
|
||||
SgFile::switchToFile(fileName);
|
||||
if (SgFile::switchToFile(fileName) == -1)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
for (const auto& loop : loops)
|
||||
{
|
||||
if (!loop->isFor())
|
||||
@@ -397,28 +392,31 @@ void findPrivateArrays(map<string, vector<LoopGraph*>>& loopGraph, map<FuncInfo*
|
||||
{
|
||||
if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func)
|
||||
{
|
||||
Region* loopRegion;
|
||||
Region* loopRegion = nullptr;
|
||||
try
|
||||
{
|
||||
loopRegion = new Region(loop, blocks);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
continue;
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
|
||||
if (loopRegion->getBasickBlocks().size() <= 1)
|
||||
{
|
||||
delete(loopRegion);
|
||||
delete loopRegion;
|
||||
continue;
|
||||
}
|
||||
SolveDataFlow(loopRegion);
|
||||
RemoveEmptyPoints(loopRegion->array_priv);
|
||||
|
||||
solveDataFlow(loopRegion);
|
||||
removeEmptyPoints(loopRegion->array_priv);
|
||||
result[loop] = loopRegion->array_priv;
|
||||
delete(loopRegion);
|
||||
delete loopRegion;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.find(loop) != result.end() && !result[loop].empty())
|
||||
AddPrivateArraysToLoop(loop, result[loop], insertedPrivates);
|
||||
addPrivateArraysToLoop(loop, result[loop], insertedPrivates, SPF_messages, declaredArrays);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,12 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <set>
|
||||
|
||||
#include "range_structures.h"
|
||||
#include "graph_loops.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);
|
||||
void 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);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
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++)
|
||||
{
|
||||
@@ -24,9 +24,9 @@ static vector<uint64_t> FindParticularSolution(const ArrayDimension& dim1, const
|
||||
}
|
||||
|
||||
/* 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())
|
||||
return NULL;
|
||||
|
||||
@@ -52,9 +52,9 @@ static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const A
|
||||
}
|
||||
|
||||
/* 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)
|
||||
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;
|
||||
ArrayDimension* inter = DimensionIntersection(dim1, dim2);
|
||||
ArrayDimension* inter = dimensionIntersection(dim1, dim2);
|
||||
if (!inter)
|
||||
return { dim1, dim2 };
|
||||
|
||||
@@ -98,14 +98,14 @@ static vector<ArrayDimension> DimensionUnion(const ArrayDimension& dim1, const A
|
||||
delete(inter);
|
||||
|
||||
vector<ArrayDimension> diff1, diff2;
|
||||
diff1 = DimensionDifference(dim1, dim2);
|
||||
diff2 = DimensionDifference(dim2, dim1);
|
||||
diff1 = dimensionDifference(dim1, dim2);
|
||||
diff2 = dimensionDifference(dim2, dim1);
|
||||
res.insert(res.end(), diff1.begin(), diff1.end());
|
||||
res.insert(res.end(), diff2.begin(), diff2.end());
|
||||
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())
|
||||
return {};
|
||||
@@ -113,13 +113,13 @@ static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>&
|
||||
size_t dimAmount = firstElement.size();
|
||||
/* check if there is no intersecction */
|
||||
for (size_t i = 0; i < dimAmount; i++)
|
||||
if (FindParticularSolution(firstElement[i], secondElement[i]).empty())
|
||||
if (findParticularSolution(firstElement[i], secondElement[i]).empty())
|
||||
return {};
|
||||
|
||||
vector<ArrayDimension> result(dimAmount);
|
||||
for (size_t i = 0; i < dimAmount; i++)
|
||||
{
|
||||
ArrayDimension* resPtr = DimensionIntersection(firstElement[i], secondElement[i]);
|
||||
ArrayDimension* resPtr = dimensionIntersection(firstElement[i], secondElement[i]);
|
||||
if (resPtr)
|
||||
result[i] = *resPtr;
|
||||
else
|
||||
@@ -129,7 +129,7 @@ static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>&
|
||||
return result;
|
||||
}
|
||||
|
||||
static vector<vector<ArrayDimension>> ElementsDifference(const vector<ArrayDimension>& firstElement,
|
||||
static vector<vector<ArrayDimension>> elementsDifference(const vector<ArrayDimension>& firstElement,
|
||||
const vector<ArrayDimension>& secondElement)
|
||||
{
|
||||
if (firstElement.empty())
|
||||
@@ -137,14 +137,14 @@ static vector<vector<ArrayDimension>> ElementsDifference(const vector<ArrayDimen
|
||||
if (secondElement.empty())
|
||||
return { firstElement };
|
||||
|
||||
vector<ArrayDimension> intersection = ElementsIntersection(firstElement, secondElement);
|
||||
vector<ArrayDimension> intersection = elementsIntersection(firstElement, secondElement);
|
||||
vector<vector<ArrayDimension>> result;
|
||||
if (intersection.empty())
|
||||
return { firstElement };
|
||||
|
||||
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())
|
||||
{
|
||||
vector<ArrayDimension> firstCopy = firstElement;
|
||||
@@ -158,14 +158,14 @@ static vector<vector<ArrayDimension>> ElementsDifference(const vector<ArrayDimen
|
||||
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<ArrayDimension>& intersection)
|
||||
{
|
||||
/* lc(rc) is a set of ranges, which only exist in first(second) element*/
|
||||
intersection = ElementsIntersection(firstElement, secondElement);
|
||||
lc = ElementsDifference(firstElement, intersection);
|
||||
rc = ElementsDifference(secondElement, intersection);
|
||||
intersection = elementsIntersection(firstElement, secondElement);
|
||||
lc = elementsDifference(firstElement, intersection);
|
||||
rc = elementsDifference(secondElement, intersection);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
auto intersection = ElementsIntersection(tailLoc, currentElement);
|
||||
auto diff = ElementsDifference(tailLoc, intersection);
|
||||
auto intersection = elementsIntersection(tailLoc, currentElement);
|
||||
auto diff = elementsDifference(tailLoc, intersection);
|
||||
if (!diff.empty()) {
|
||||
newTails.insert(newTails.end(), diff.begin(), diff.end());
|
||||
}
|
||||
@@ -197,7 +197,7 @@ void AccessingSet::FindCoveredBy(const vector<ArrayDimension>& element, vector<v
|
||||
{
|
||||
for (const auto& currentElement : allElements)
|
||||
{
|
||||
auto intersection = ElementsIntersection(element, currentElement);
|
||||
auto intersection = elementsIntersection(element, currentElement);
|
||||
if (!intersection.empty())
|
||||
result.push_back(intersection);
|
||||
}
|
||||
@@ -283,7 +283,7 @@ bool operator!=(const AccessingSet& lhs, const AccessingSet& rhs)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs)
|
||||
bool operator!=(const arrayAccessingIndexes& lhs, const arrayAccessingIndexes& rhs)
|
||||
{
|
||||
if (lhs.size() != rhs.size())
|
||||
return true;
|
||||
|
||||
@@ -33,8 +33,8 @@ public:
|
||||
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 AccessingSet& lhs, const AccessingSet& rhs);
|
||||
bool operator!=(const ArrayAccessingIndexes& lhs, const ArrayAccessingIndexes& rhs);
|
||||
bool operator!=(const arrayAccessingIndexes& lhs, const arrayAccessingIndexes& rhs);
|
||||
@@ -23,7 +23,7 @@ static bool isParentStmt(SgStatement* stmt, SgStatement* parent)
|
||||
}
|
||||
|
||||
/*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;
|
||||
SAPFOR::BasicBlock* head_block = nullptr;
|
||||
@@ -51,15 +51,15 @@ pair<SAPFOR::BasicBlock*, set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const
|
||||
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();
|
||||
loopForIndex[loop->loop->GetOriginal()] = loop;
|
||||
|
||||
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() };
|
||||
|
||||
for (int i = pos - 1; i >= 0; i--)
|
||||
@@ -93,10 +93,10 @@ static string FindIndexName(int pos, SAPFOR::BasicBlock* block, map<string, Loop
|
||||
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();
|
||||
map<SgStatement*, LoopGraph*> loopForIndex;
|
||||
BuildLoopIndex(loopForIndex, loop);
|
||||
buildLoopIndex(loopForIndex, loop);
|
||||
for (int i = 0; i < instructions.size(); 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)
|
||||
{
|
||||
@@ -249,10 +249,7 @@ static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const set<SAPFOR:
|
||||
}
|
||||
}
|
||||
|
||||
static bool DFS(Region* block,
|
||||
vector<Region*>& result,
|
||||
const set<Region*>& cycleBlocks,
|
||||
map<Region*, int>& color)
|
||||
static bool DFS(Region* block, vector<Region*>& result, const set<Region*>& cycleBlocks, map<Region*, int>& color)
|
||||
{
|
||||
auto it = color.find(block);
|
||||
if (it != color.end())
|
||||
@@ -275,7 +272,7 @@ static bool DFS(Region* block,
|
||||
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;
|
||||
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);
|
||||
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 false;
|
||||
}
|
||||
|
||||
bool TopologySort(std::vector<Region*>& basikBlocks, Region* header)
|
||||
bool topologySort(std::vector<Region*>& basikBlocks, Region* header)
|
||||
{
|
||||
set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end());
|
||||
vector<Region*> result;
|
||||
@@ -301,7 +298,7 @@ bool TopologySort(std::vector<Region*>& basikBlocks, Region* header)
|
||||
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)
|
||||
{
|
||||
@@ -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;
|
||||
auto [header, blockSet] = GetBasicBlocksForLoop(loop, Blocks);
|
||||
RemoveHeaderConnection(header, blockSet, bbToRegion);
|
||||
auto [header, blockSet] = getBasicBlocksForLoop(loop, Blocks);
|
||||
removeHeaderConnection(header, blockSet, bbToRegion);
|
||||
if (bbToRegion.find(header) != bbToRegion.end())
|
||||
region->setHeader(bbToRegion.at(header));
|
||||
else
|
||||
@@ -336,34 +333,34 @@ static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*
|
||||
{
|
||||
if (!childLoop->isFor())
|
||||
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");
|
||||
return region;
|
||||
}
|
||||
|
||||
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;
|
||||
for (auto poiner : blockSet)
|
||||
{
|
||||
bbToRegion[poiner] = new Region(*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];
|
||||
SetConnections(bbToRegion, blockSet);
|
||||
RemoveHeaderConnection(header, blockSet, bbToRegion);
|
||||
setConnections(bbToRegion, blockSet);
|
||||
removeHeaderConnection(header, blockSet, bbToRegion);
|
||||
//create subRegions
|
||||
for (LoopGraph* childLoop : loop->children)
|
||||
{
|
||||
if (!childLoop->isFor())
|
||||
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");
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
struct RegionInstruction
|
||||
{
|
||||
ArrayAccessingIndexes def, use, in, out;
|
||||
arrayAccessingIndexes def, use, in, out;
|
||||
};
|
||||
|
||||
class Region : public SAPFOR::BasicBlock {
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
|
||||
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:
|
||||
std::vector<Region*> basickBlocks;
|
||||
@@ -79,6 +79,6 @@ private:
|
||||
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);
|
||||
@@ -1905,13 +1905,13 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
else if (curr_regime == TRANSFORM_ASSUMED_SIZE_PARAMETERS)
|
||||
transformAssumedSizeParameters(allFuncInfo);
|
||||
else if (curr_regime == FIND_PRIVATE_ARRAYS_ANALYSIS)
|
||||
findPrivateArrays(loopGraph, fullIR, insertedPrivates);
|
||||
findPrivateArrays(loopGraph, fullIR, insertedPrivates, SPF_messages, declaredArrays);
|
||||
else if (curr_regime == MERGE_REGIONS)
|
||||
mergeRegions(parallelRegions, allFuncInfo);
|
||||
else if (curr_regime == ARRAY_PROPAGATION)
|
||||
arrayConstantPropagation(project);
|
||||
else if (curr_regime == ARRAY_PROPAGATION_RESTORE)
|
||||
restoreArrays();
|
||||
arrayConstantPropagationRrestore();
|
||||
|
||||
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.;
|
||||
|
||||
@@ -15,10 +15,11 @@ static set<SgStatement*> changed;
|
||||
static map<string, SgSymbol*> variablesToAdd;
|
||||
static map<string, set<SgStatement*>> positionsToAdd;
|
||||
static map<string, string> arrayToName;
|
||||
static set<SgStatement*> statementsToRemove;
|
||||
static map<string, set<SgStatement*>> statementsToRemove;
|
||||
static map<string, map<SgStatement*, SgStatement*>> expToChange;
|
||||
static int variableNumber = 0;
|
||||
|
||||
static bool CheckConstIndexes(SgExpression* exp)
|
||||
static bool checkConstIndexes(SgExpression* exp)
|
||||
{
|
||||
if (!exp)
|
||||
{
|
||||
@@ -41,7 +42,7 @@ static bool CheckConstIndexes(SgExpression* exp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static SgExpression* CreateVar(int& variableNumber, SgType* type)
|
||||
static SgExpression* createVar(SgType* type)
|
||||
{
|
||||
string varName = "tmp_prop_var";
|
||||
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());
|
||||
}
|
||||
|
||||
static SgStatement* FindLastDeclStatement(SgStatement* funcStart)
|
||||
static SgStatement* findLastDeclStatement(SgStatement* funcStart)
|
||||
{
|
||||
if (!funcStart)
|
||||
return NULL;
|
||||
|
||||
SgStatement* endSt = funcStart->lastNodeOfStmt();
|
||||
SgStatement* cur = funcStart->lexNext();
|
||||
SgStatement* lastDecl = funcStart;
|
||||
@@ -82,7 +84,7 @@ static SgStatement* FindLastDeclStatement(SgStatement* funcStart)
|
||||
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())
|
||||
return;
|
||||
@@ -90,7 +92,7 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map<st
|
||||
if (!funcStart)
|
||||
return;
|
||||
|
||||
const string commonBlockName = "propagation_common__";
|
||||
const string commonBlockName = "__propagation_common__";
|
||||
|
||||
SgStatement* funcEnd = funcStart->lastNodeOfStmt();
|
||||
SgStatement* commonStat = NULL;
|
||||
@@ -130,7 +132,7 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map<st
|
||||
}
|
||||
SgExpression* varList = makeExprList(varRefs, false);
|
||||
|
||||
SgStatement* insertAfter = FindLastDeclStatement(funcStart);
|
||||
SgStatement* insertAfter = findLastDeclStatement(funcStart);
|
||||
for (const auto& [name, sym] : symbols)
|
||||
{
|
||||
if (!sym)
|
||||
@@ -149,7 +151,7 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map<st
|
||||
|
||||
insertAfter->insertStmtAfter(*declStmt, *funcStart);
|
||||
insertAfter = declStmt;
|
||||
statementsToRemove.insert(declStmt);
|
||||
statementsToRemove[declStmt->fileName()].insert(declStmt);
|
||||
}
|
||||
|
||||
if (!commonList)
|
||||
@@ -164,14 +166,12 @@ static void InsertCommonAndDeclsForFunction(SgStatement* funcStart, const map<st
|
||||
commonStat->setlineNumber(getNextNegativeLineNumber());
|
||||
commonStat->setExpression(0, commonList);
|
||||
|
||||
SgStatement* lastDecl = FindLastDeclStatement(funcStart);
|
||||
SgStatement* lastDecl = findLastDeclStatement(funcStart);
|
||||
lastDecl->insertStmtAfter(*commonStat, *funcStart);
|
||||
statementsToRemove.insert(commonStat);
|
||||
statementsToRemove[commonStat->fileName()].insert(commonStat);
|
||||
}
|
||||
else
|
||||
{
|
||||
commonList->setLhs(varList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -179,6 +179,7 @@ static void copyStatement(SgStatement* st)
|
||||
{
|
||||
if (!st)
|
||||
return;
|
||||
|
||||
if (expToChange[st->fileName()].find(st) == expToChange[st->fileName()].end())
|
||||
{
|
||||
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)
|
||||
return false;
|
||||
@@ -204,13 +205,13 @@ static bool TransformRightPart(SgStatement* st, SgExpression* exp, map<string, S
|
||||
|
||||
string expUnparsed;
|
||||
SgExpression* toAdd = NULL;
|
||||
if (isArrayRef(exp) && CheckConstIndexes(exp->lhs()))
|
||||
if (isArrayRef(exp) && checkConstIndexes(exp->lhs()))
|
||||
{
|
||||
expUnparsed = exp->unparse();
|
||||
if (arrayToVariable.find(expUnparsed) == arrayToVariable.end() && exp && exp->symbol() &&
|
||||
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();
|
||||
}
|
||||
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
|
||||
@@ -220,16 +221,17 @@ static bool TransformRightPart(SgStatement* st, SgExpression* exp, map<string, S
|
||||
st->setExpression(1, newVarExp);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
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;
|
||||
expUnparsed = subnodes[i]->unparse();
|
||||
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();
|
||||
}
|
||||
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
|
||||
@@ -246,13 +248,13 @@ static bool TransformRightPart(SgStatement* st, SgExpression* exp, map<string, S
|
||||
}
|
||||
}
|
||||
else
|
||||
isChanged = isChanged || TransformRightPart(st, subnodes[i], arrayToVariable, variableNumber);
|
||||
isChanged = isChanged || transformRightPart(st, subnodes[i], arrayToVariable);
|
||||
|
||||
}
|
||||
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))
|
||||
return;
|
||||
@@ -262,10 +264,11 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, map<string, Sg
|
||||
return;
|
||||
if (changed.find(st) != changed.end())
|
||||
return;
|
||||
|
||||
string expUnparsed = exp->unparse();
|
||||
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();
|
||||
}
|
||||
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
|
||||
@@ -282,16 +285,16 @@ static void TransformLeftPart(SgStatement* st, SgExpression* exp, map<string, Sg
|
||||
newStatement->setLocalLineNumber(st->lineNumber());
|
||||
|
||||
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)
|
||||
return;
|
||||
SgStatement* firstStatement = declPlace->lexPrev();
|
||||
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
|
||||
TransformRightPart(st, exp, arrayToVariable, variableNumber);
|
||||
transformRightPart(st, exp, arrayToVariable);
|
||||
st = st->lexPrev();
|
||||
while (st &&st != firstStatement)
|
||||
{
|
||||
@@ -299,16 +302,16 @@ static void TransformBorder(SgStatement* st, SgExpression* exp, map<string, SgEx
|
||||
{
|
||||
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())
|
||||
TransformLeftPart(st, st->expr(0), arrayToVariable, variableNumber);
|
||||
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);
|
||||
}
|
||||
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();
|
||||
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 (TransformRightPart(st, st->expr(1), arrayToVariable, variableNumber))
|
||||
if (transformRightPart(st, st->expr(1), arrayToVariable))
|
||||
{
|
||||
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
|
||||
}
|
||||
}
|
||||
|
||||
if (st->variant() == ASSIGN_STAT && arrayToVariable.find(st->expr(0)->unparse()) != arrayToVariable.end())
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -340,8 +344,7 @@ static void CheckVariable(SgStatement* st, SgExpression* exp, map<string, SgExpr
|
||||
}
|
||||
}
|
||||
|
||||
static void findConstValues(
|
||||
SgProject& project,
|
||||
static void findConstValues(SgProject& project,
|
||||
const map<string, map<string, SgStatement*>>& borderVars,
|
||||
const map<string, SgExpression*>& arrayToVariable,
|
||||
map<string, int>& hitCount,
|
||||
@@ -422,14 +425,14 @@ static void insertDefinition(map<string, map<SgStatement*, vector<pair<string, s
|
||||
if (insertBefore && 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)
|
||||
{
|
||||
@@ -468,28 +471,28 @@ static void applyLeftPartForUnchangedAssignments(SgProject& project, map<string,
|
||||
continue;
|
||||
if (!lhs->symbol()->type()->baseType())
|
||||
continue;
|
||||
if (!CheckConstIndexes(lhs->lhs()))
|
||||
if (!checkConstIndexes(lhs->lhs()))
|
||||
continue;
|
||||
|
||||
const string lhsUnparsed = lhs->unparse();
|
||||
if (arrayToVariable.find(lhsUnparsed) == arrayToVariable.end())
|
||||
continue;
|
||||
|
||||
TransformLeftPart(st, lhs, arrayToVariable, variableNumber);
|
||||
transformLeftPart(st, lhs, arrayToVariable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool ContainsArrayRefRecursive(SgExpression* exp)
|
||||
static bool containsArrayRefRecursive(SgExpression* exp)
|
||||
{
|
||||
if (!exp)
|
||||
return false;
|
||||
|
||||
if (isArrayRef(exp) && CheckConstIndexes(exp->lhs()))
|
||||
if (isArrayRef(exp) && checkConstIndexes(exp->lhs()))
|
||||
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)
|
||||
@@ -497,21 +500,19 @@ static void getBorderVars(SgExpression* exp, const string& filename, map<string,
|
||||
if (!exp)
|
||||
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;
|
||||
|
||||
getBorderVars(exp->lhs(), filename, borderVars);
|
||||
getBorderVars(exp->rhs(), filename, borderVars);
|
||||
}
|
||||
|
||||
static void processLoopBound(
|
||||
SgStatement* st,
|
||||
static void processLoopBound(SgStatement* st,
|
||||
SgExpression* bound,
|
||||
const string& boundUnparsed,
|
||||
bool isUpperBound,
|
||||
map<string, SgExpression*>& arrayToVariable,
|
||||
map<string, map<string, SgStatement*>>& borderVars,
|
||||
int& variableNumber)
|
||||
map<string, map<string, SgStatement*>>& borderVars)
|
||||
{
|
||||
if (!bound || !st)
|
||||
return;
|
||||
@@ -520,36 +521,40 @@ static void processLoopBound(
|
||||
|
||||
getBorderVars(exp, st->fileName(), borderVars);
|
||||
|
||||
if (ContainsArrayRefRecursive(exp), borderVars, st->fileName())
|
||||
if (containsArrayRefRecursive(exp), borderVars, st->fileName())
|
||||
{
|
||||
copyStatement(st);
|
||||
|
||||
TransformBorder(st, bound, arrayToVariable, variableNumber);
|
||||
transformBorder(st, bound, arrayToVariable);
|
||||
|
||||
positionsToAdd[string(declPlace->fileName())].insert(declPlace);
|
||||
}
|
||||
else if (bound->variant() == VAR_REF)
|
||||
CheckVariable(st, bound, arrayToVariable, variableNumber);
|
||||
checkVariable(st, bound, arrayToVariable);
|
||||
}
|
||||
|
||||
void arrayConstantPropagation(SgProject& project)
|
||||
{
|
||||
map<string, SgExpression*> arrayToVariable;
|
||||
map<string, map<string, SgStatement*>> borderVars;
|
||||
int variableNumber = 0;
|
||||
|
||||
for (int i = 0; i < project.numberOfFiles(); i++)
|
||||
{
|
||||
SgFile *file = &(project.file(i));
|
||||
|
||||
if (!file)
|
||||
continue;
|
||||
SgFile::switchToFile(file->filename());
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
if (SgFile::switchToFile(file->filename()) == -1)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
const int funcNum = file->numberOfFunctions();
|
||||
for (int i = 0; i < funcNum; ++i)
|
||||
{
|
||||
SgStatement* st = file->functions(i);
|
||||
if (!st)
|
||||
continue;
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
declPlace = st;
|
||||
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||
|
||||
@@ -568,20 +573,22 @@ void arrayConstantPropagation(SgProject& project)
|
||||
string lowerBoundUnparsed = lowerBound->unparse();
|
||||
string upperBoundUnparsed = upperBound->unparse();
|
||||
|
||||
processLoopBound(st, st->expr(0), upperBoundUnparsed, true, arrayToVariable, borderVars, variableNumber);
|
||||
processLoopBound(st, st->expr(0), lowerBoundUnparsed, false, arrayToVariable, borderVars, variableNumber);
|
||||
processLoopBound(st, st->expr(0), upperBoundUnparsed, true, arrayToVariable, borderVars);
|
||||
processLoopBound(st, st->expr(0), lowerBoundUnparsed, false, arrayToVariable, borderVars);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
applyLeftPartForUnchangedAssignments(project, arrayToVariable, variableNumber);
|
||||
|
||||
applyLeftPartForUnchangedAssignments(project, arrayToVariable);
|
||||
map<string, set<SgStatement*>> funcStarts;
|
||||
for (const auto& [fileName, statements] : positionsToAdd)
|
||||
{
|
||||
int res = SgFile::switchToFile(fileName);
|
||||
if (res == -1)
|
||||
continue;
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
for (SgStatement* st : statements)
|
||||
{
|
||||
SgStatement* scope = isSgProgHedrStmt(st) ? st : st->controlParent();
|
||||
@@ -589,42 +596,44 @@ void arrayConstantPropagation(SgProject& project)
|
||||
funcStarts[fileName].insert(scope);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [fileName, statements] : funcStarts)
|
||||
{
|
||||
SgFile::switchToFile(fileName);
|
||||
for (SgStatement* st : statements)
|
||||
{
|
||||
InsertCommonAndDeclsForFunction(st, variablesToAdd);
|
||||
insertCommonAndDeclsForFunction(st, variablesToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
map<string, map<SgStatement*, vector<pair<string, string>>>> result;
|
||||
map<string, int> hitCount;
|
||||
|
||||
findConstValues(project, borderVars, arrayToVariable, hitCount, result);
|
||||
insertDefinition(result, hitCount);
|
||||
}
|
||||
|
||||
void restoreArrays()
|
||||
void arrayConstantPropagationRrestore()
|
||||
{
|
||||
for (auto& [filename, statements] : expToChange)
|
||||
{
|
||||
if (SgFile::switchToFile(filename) == -1)
|
||||
continue;
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
for (auto& [statement, statementCopy] : statements)
|
||||
{
|
||||
if (statement && statementCopy)
|
||||
{
|
||||
for (int i = 0; i < 3; 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,4 @@ using namespace std;
|
||||
|
||||
|
||||
void arrayConstantPropagation(SgProject& project);
|
||||
void restoreArrays();
|
||||
void arrayConstantPropagationRrestore();
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_SPF "2483"
|
||||
#define VERSION_SPF "2484"
|
||||
|
||||
Reference in New Issue
Block a user