7 Commits

10 changed files with 463 additions and 183 deletions

View File

@@ -321,6 +321,12 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
} }
} }
if (currentLoop.empty()) // can't find loop IR - loop unreachable!
{
__spf_print(1, "Unreachable loop on %s:%d\n", current_file->filename(), loop_operator->lineNumber());
return currentLoop;
}
if (!head_block) if (!head_block)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);

View File

@@ -1,3 +1,4 @@
#include <algorithm>
#include <map> #include <map>
#include <unordered_set> #include <unordered_set>
#include <unordered_map> #include <unordered_map>
@@ -16,6 +17,8 @@
using namespace std; using namespace std;
static unordered_set<Region*> collapsed;
static void RemoveEmptyPoints(ArrayAccessingIndexes& container) static void RemoveEmptyPoints(ArrayAccessingIndexes& container)
{ {
ArrayAccessingIndexes resultContainer; ArrayAccessingIndexes resultContainer;
@@ -49,41 +52,81 @@ static void Collapse(Region* region)
if (region->getBasickBlocks().empty()) if (region->getBasickBlocks().empty())
return; return;
for (auto& [arrayName, arrayRanges] : region->getHeader()->array_out) bool firstRegion = true;
for (Region* basickBlock : region->getBasickBlocks())
{ {
for (Region* byBlock : region->getBasickBlocks()) if (basickBlock->getNextRegions().empty())
{ {
AccessingSet intersection = byBlock->array_def[arrayName].Intersect(arrayRanges); if (firstRegion)
region->array_def[arrayName] = region->array_def[arrayName].Union(intersection); {
region->array_def = basickBlock->array_out;
firstRegion = false;
}
else
{
unordered_set<string> toErease;
for (auto& [arrayName, arrayRanges] : region->array_def)
{
if (basickBlock->array_out.find(arrayName) != basickBlock->array_out.end())
arrayRanges = arrayRanges.Intersect(basickBlock->array_out[arrayName]);
else
{
arrayRanges = AccessingSet();
toErease.insert(arrayName);
}
}
for (string arrayName : toErease)
region->array_def.erase(arrayName);
}
} }
} }
RegionInstruction instruction;
instruction.def = move(region->array_def);
for (auto& byBlock : region->getBasickBlocks()) for (auto& byBlock : region->getBasickBlocks())
{ {
for (auto& [arrayName, arrayRanges] : byBlock->array_use) for (auto& instruction : byBlock->instructions)
{ {
AccessingSet diff = byBlock->array_use[arrayName].Diff(byBlock->array_in[arrayName]); for (auto& [arrayName, _] : instruction.use)
region->array_use[arrayName] = region->array_use[arrayName].Union(diff); {
AccessingSet diff = instruction.use[arrayName].Diff(instruction.in[arrayName]);
region->array_use[arrayName] = region->array_use[arrayName].Union(diff);
}
} }
} }
ArrayAccessingIndexes useUnion; ArrayAccessingIndexes useUnionB;
for (auto& byBlock : region->getBasickBlocks()) for (auto& byBlock : region->getBasickBlocks())
for (auto& [arrayName, arrayRanges] : byBlock->array_use) for (auto& instruction : byBlock->instructions)
useUnion[arrayName] = useUnion[arrayName].Union(byBlock->array_use[arrayName]); for (auto& [arrayName, _] : instruction.use)
useUnionB[arrayName] = useUnionB[arrayName].Union(instruction.use[arrayName]);
region->array_priv = region->array_use; for (auto& [arrayName, _] : useUnionB)
region->array_priv[arrayName] = useUnionB[arrayName].Diff(region->array_use[arrayName]);
instruction.use = move(region->array_use);
for (Region* prevBlock : region->getHeader()->getPrevRegions()) for (Region* prevBlock : region->getHeader()->getPrevRegions())
{
prevBlock->replaceInNextRegions(region, region->getHeader()); prevBlock->replaceInNextRegions(region, region->getHeader());
region->addPrevRegion(prevBlock);
}
for (Region* nextBlock : region->getHeader()->getNextRegions()) for (Region* nextBlock : region->getHeader()->getNextRegions())
{
nextBlock->replaceInPrevRegions(region, region->getHeader()); nextBlock->replaceInPrevRegions(region, region->getHeader());
region->addNextRegion(nextBlock);
}
region->instructions.push_back(instruction);
} }
static void SolveDataFlowIteratively(Region* DFG) static void SolveDataFlowIteratively(Region* DFG)
{ {
unordered_set<Region*> worklist(DFG->getBasickBlocks()); auto blocks = DFG->getBasickBlocks();
std::unordered_set<Region*> worklist(blocks.begin(), blocks.end());
do do
{ {
Region* b = *worklist.begin(); Region* b = *worklist.begin();
@@ -101,7 +144,7 @@ static void SolveDataFlowIteratively(Region* DFG)
if (prevBlock->array_out.empty()) if (prevBlock->array_out.empty())
{ {
newIn.clear(); newIn.clear();
continue; break;
} }
for (const auto& [arrayName, accessSet] : prevBlock->array_out) for (const auto& [arrayName, accessSet] : prevBlock->array_out)
@@ -137,21 +180,153 @@ static void SolveDataFlowIteratively(Region* DFG)
b->array_out = newOut; b->array_out = newOut;
else else
worklist.erase(b); worklist.erase(b);
} while (!worklist.empty());
}
static void SolveForBasickBlock(Region* block)
{
ArrayAccessingIndexes newIn;
bool flagFirst = true;
for (Region* prevBlock : block->getPrevRegions())
{
if (flagFirst)
{
newIn = prevBlock->array_out;
flagFirst = false;
}
else
{
if (prevBlock->array_out.empty())
{
newIn.clear();
break;
}
for (const auto& [arrayName, accessSet] : prevBlock->array_out)
{
if (newIn.find(arrayName) != newIn.end())
newIn[arrayName] = newIn[arrayName].Intersect(accessSet);
else
newIn[arrayName] = AccessingSet();
}
}
}
if (block->instructions.empty())
block->instructions.push_back(RegionInstruction());
block->instructions[0].in = move(newIn);
for (int i = 0; i < block->instructions.size(); i++)
{
auto& instruction = block->instructions[i];
if (i > 0)
instruction.in = block->instructions[i - 1].out;
ArrayAccessingIndexes newOut;
if (instruction.def.empty())
newOut = instruction.in;
else if (instruction.in.empty())
newOut = instruction.def;
else
{
for (auto& [arrayName, accessSet] : instruction.def)
{
if (instruction.in.find(arrayName) != instruction.in.end())
newOut[arrayName] = instruction.def[arrayName].Union(instruction.in[arrayName]);
else
newOut[arrayName] = accessSet;
}
for (auto& [arrayName, accessSet] : instruction.in)
{
if (newOut.find(arrayName) == newOut.end())
{
newOut[arrayName] = accessSet;
}
}
}
instruction.out = move(newOut);
}
if (!block->instructions.empty())
block->array_out = block->instructions.back().out;
}
static void SolveDataFlowTopologically(Region* DFG)
{
for (Region* b : DFG->getBasickBlocks())
{
collapsed.insert(b);
SolveForBasickBlock(b);
} }
while (!worklist.empty());
} }
static void SolveDataFlow(Region* DFG) static void SolveDataFlow(Region* DFG)
{ {
if (!DFG) if (!DFG)
return; return;
SolveDataFlowIteratively(DFG);
for (Region* subRegion : DFG->getSubRegions()) 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); Collapse(DFG);
} }
static bool getArrayDeclaredDimensions(SgArrayRefExp* arrayRef, vector<uint64_t>& declaredDims)
{
declaredDims.clear();
if (!arrayRef || !arrayRef->symbol() || !isSgArrayType(arrayRef->symbol()->type()))
return false;
SgArrayType* arrayType = (SgArrayType*)arrayRef->symbol()->type();
int dimCount = arrayType->dimension();
for (int i = 0; i < dimCount; i++)
{
SgExpression* sizeExpr = arrayType->sizeInDim(i);
SgConstantSymb* constValSymb = isSgConstantSymb(sizeExpr->symbol());
string strDimLength;
if (sizeExpr && sizeExpr->variant() == INT_VAL)
strDimLength = sizeExpr->unparse();
else if (constValSymb)
strDimLength = constValSymb->constantValue()->unparse();
else
return false;
if (strDimLength == "0")
return false;
declaredDims.push_back((uint64_t)stoi(strDimLength));
}
return true;
}
static bool CheckDimensionLength(const AccessingSet& array)
{
if (array.GetElements().empty())
return false;
size_t dimCount = array.GetElements()[0].size();
SgArrayRefExp* arrayRef = array.GetElements()[0][0].array;
if (!arrayRef)
return false;
vector<uint64_t> declaredDims(dimCount);
if (!getArrayDeclaredDimensions(arrayRef, declaredDims))
return false;
vector<ArrayDimension> testArray(dimCount);
for (size_t i = 0; i < dimCount; i++)
{
testArray[i] = { 1, 1, declaredDims[i], nullptr };
}
AccessingSet diff = AccessingSet({ testArray }).Diff(array);
return diff.GetElements().empty();
}
static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set<SgStatement*>& insertedPrivates) static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes& privates, set<SgStatement*>& insertedPrivates)
{ {
SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR); SgStatement* spfStat = new SgStatement(SPF_ANALYSIS_DIR);
@@ -161,6 +336,8 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes&
set<SgSymbol*> arraysToInsert; set<SgSymbol*> arraysToInsert;
for (const auto& [_, accessingSet] : privates) for (const auto& [_, accessingSet] : privates)
{ {
if (!CheckDimensionLength(accessingSet))
continue;
for (const auto& arrayElement : accessingSet.GetElements()) for (const auto& arrayElement : accessingSet.GetElements())
{ {
if (arrayElement.empty()) if (arrayElement.empty())
@@ -188,14 +365,14 @@ static void AddPrivateArraysToLoop(LoopGraph* loop, const ArrayAccessingIndexes&
toAdd->setLhs(new SgVarRefExp(elem)); toAdd->setLhs(new SgVarRefExp(elem));
} }
if (arraysToInsert.size() == 0) if (arraysToInsert.size() != 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); {
loop->loop->insertStmtBefore(*spfStat, *loop->loop->controlParent());
loop->loop->insertStmtBefore(*spfStat, *loop->loop->controlParent()); insertedPrivates.insert(spfStat);
insertedPrivates.insert(spfStat); }
} }
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<LoopGraph*, ArrayAccessingIndexes> result; map<LoopGraph*, ArrayAccessingIndexes> result;
for (const auto& [fileName, loops] : loopGraph) for (const auto& [fileName, loops] : loopGraph)
@@ -210,7 +387,7 @@ void FindPrivateArrays(map<string, vector<LoopGraph*>> &loopGraph, map<FuncInfo*
while (search_func && (!isSgProgHedrStmt(search_func))) while (search_func && (!isSgProgHedrStmt(search_func)))
search_func = search_func->controlParent(); search_func = search_func->controlParent();
for (const auto& [funcInfo, blocks]: FullIR) for (const auto& [funcInfo, blocks] : FullIR)
{ {
if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func) if (funcInfo->fileName == fileName && funcInfo->funcPointer->GetOriginal() == search_func)
{ {

View File

@@ -47,7 +47,7 @@ static ArrayDimension* DimensionIntersection(const ArrayDimension& dim1, const A
uint64_t start3 = dim1.start + x0 * dim1.step; uint64_t start3 = dim1.start + x0 * dim1.step;
uint64_t step3 = c * dim1.step; uint64_t step3 = c * dim1.step;
ArrayDimension* result = new(ArrayDimension){ start3, step3, tMax + 1 , dim1.array}; ArrayDimension* result = new(ArrayDimension){ start3, step3, tMax + 1 , dim1.array };
return result; return result;
} }
@@ -61,7 +61,7 @@ static vector<ArrayDimension> DimensionDifference(const ArrayDimension& dim1, co
vector<ArrayDimension> result; vector<ArrayDimension> result;
/* add the part before intersection */ /* add the part before intersection */
if (dim1.start < intersection->start) if (dim1.start < intersection->start)
result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step, dim1.array}); result.push_back({ dim1.start, dim1.step, (intersection->start - dim1.start) / dim1.step, dim1.array });
/* add the parts between intersection steps */ /* add the parts between intersection steps */
if (intersection->step > dim1.step) if (intersection->step > dim1.step)
@@ -70,7 +70,7 @@ static vector<ArrayDimension> DimensionDifference(const ArrayDimension& dim1, co
uint64_t interValue = intersection->start; uint64_t interValue = intersection->start;
for (int64_t i = start; interValue <= intersection->start + intersection->step * (intersection->tripCount - 1); i++) for (int64_t i = start; interValue <= intersection->start + intersection->step * (intersection->tripCount - 1); i++)
{ {
result.push_back({interValue + dim1.step, dim1.step, intersection->step / dim1.step, dim1.array}); result.push_back({ interValue + dim1.step, dim1.step, intersection->step / dim1.step, dim1.array });
interValue += intersection->step; interValue += intersection->step;
} }
} }
@@ -132,8 +132,10 @@ static vector<ArrayDimension> ElementsIntersection(const vector<ArrayDimension>&
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() || secondElement.empty()) if (firstElement.empty())
return {}; return {};
if (secondElement.empty())
return { firstElement };
vector<ArrayDimension> intersection = ElementsIntersection(firstElement, secondElement); vector<ArrayDimension> intersection = ElementsIntersection(firstElement, secondElement);
vector<vector<ArrayDimension>> result; vector<vector<ArrayDimension>> result;
@@ -188,7 +190,7 @@ bool AccessingSet::ContainsElement(const vector<ArrayDimension>& element) const
{ {
vector<vector<ArrayDimension>> tails; vector<vector<ArrayDimension>> tails;
FindUncovered(element, tails); FindUncovered(element, tails);
return !tails.empty(); return tails.empty();
} }
void AccessingSet::FindCoveredBy(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const void AccessingSet::FindCoveredBy(const vector<ArrayDimension>& element, vector<vector<ArrayDimension>>& result) const
@@ -252,13 +254,15 @@ AccessingSet AccessingSet::Diff(const AccessingSet& secondSet) const
return *this; return *this;
AccessingSet intersection = this->Intersect(secondSet); AccessingSet intersection = this->Intersect(secondSet);
AccessingSet uncovered = *this; vector<vector<ArrayDimension>> uncovered;
vector<vector<ArrayDimension>> result; for (const auto& element : allElements)
for (const auto& element : intersection.GetElements())
{ {
vector<vector<ArrayDimension>> current_uncovered; vector<vector<ArrayDimension>> current_uncovered;
uncovered.FindUncovered(element, current_uncovered); intersection.FindUncovered(element, current_uncovered);
uncovered = AccessingSet(current_uncovered); uncovered.insert(uncovered.end(),
std::move_iterator(current_uncovered.begin()),
std::move_iterator(current_uncovered.end())
);
} }
return uncovered; return uncovered;
} }

View File

@@ -1,14 +1,16 @@
#include<vector> #include <algorithm>
#include<map> #include <vector>
#include<unordered_set> #include <map>
#include<unordered_map> #include <unordered_set>
#include<string> #include <unordered_map>
#include <string>
#include <numeric> #include <numeric>
#include <iostream> #include <iostream>
#include "range_structures.h" #include "range_structures.h"
#include "region.h" #include "region.h"
#include "..\Transformations\ExpressionSubstitution\expr_transform.h"
#include "SgUtils.h" #include "SgUtils.h"
using namespace std; using namespace std;
@@ -93,7 +95,7 @@ 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) { static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use, Region* region) {
auto instructions = block->getInstructions(); auto instructions = block->getInstructions();
map<string, LoopGraph*> loopForIndex; map<string, LoopGraph*> loopForIndex;
BuildLoopIndex(loopForIndex, loop); BuildLoopIndex(loopForIndex, loop);
@@ -123,7 +125,11 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
} }
if (point.size() == dimCount) if (point.size() == dimCount)
def[instruction->getInstruction()->getResult()->getValue()] = AccessingSet({point}); {
def[instruction->getInstruction()->getResult()->getValue()] = AccessingSet({ point });
RegionInstruction regionInstruction;
regionInstruction.def[instruction->getInstruction()->getResult()->getValue()] = AccessingSet({ point });
}
} }
} }
} }
@@ -148,13 +154,27 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression()); auto* ref = isSgArrayRefExp(instruction->getInstruction()->getExpression());
int fillCount = 0; int fillCount = 0;
while (!index_vars.empty() && !refPos.empty()) vector<pair<int, int>> coeffsForDims;
int subs = ref->numberOfSubscripts();
for (int i = 0; ref && i < ref->numberOfSubscripts(); ++i)
{
const vector<int*>& coeffs = getAttributes<SgExpression*, int*>(ref->subscript(i), set<int>{ INT_VAL });
if (coeffs.size() == 1)
{
const pair<int, int> coef(coeffs[0][0], coeffs[0][1]);
coeffsForDims.push_back(coef);
}
}
coeffsForDims = { coeffsForDims.rbegin(), coeffsForDims.rend() };
while (!index_vars.empty() && !refPos.empty() && !coeffsForDims.empty())
{ {
auto var = index_vars.back(); auto var = index_vars.back();
int currentVarPos = refPos.back(); int currentVarPos = refPos.back();
ArrayDimension current_dim; ArrayDimension current_dim;
if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST) if (var->getType() == SAPFOR::CFG_ARG_TYPE::CONST)
current_dim = { stoul(var->getValue()), 1, 1, ref}; current_dim = { stoul(var->getValue()), 1, 1, ref };
else else
{ {
string name, full_name = var->getValue(); string name, full_name = var->getValue();
@@ -180,7 +200,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
return -1; return -1;
} }
uint64_t start = currentLoop->startVal; uint64_t start = coeffsForDims.back().second * currentLoop->startVal + coeffsForDims.back().first;
uint64_t step = currentLoop->stepVal; uint64_t step = currentLoop->stepVal;
uint64_t iters = currentLoop->calculatedCountOfIters; uint64_t iters = currentLoop->calculatedCountOfIters;
current_dim = { start, step, iters, ref }; current_dim = { start, step, iters, ref };
@@ -193,14 +213,29 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
} }
index_vars.pop_back(); index_vars.pop_back();
refPos.pop_back(); refPos.pop_back();
coeffsForDims.pop_back();
} }
if (fillCount == accessPoint.size()) if (fillCount == accessPoint.size())
{ {
RegionInstruction instruction;
if (operation == SAPFOR::CFG_OP::STORE) if (operation == SAPFOR::CFG_OP::STORE)
{
def[array_name].Insert(accessPoint); def[array_name].Insert(accessPoint);
instruction.def[array_name] = { { accessPoint } };
}
else else
use[array_name].Insert(accessPoint); {
instruction.use[array_name] = { { accessPoint } };
if (def.find(array_name) == def.end())
use[array_name].Insert(accessPoint);
else
{
AccessingSet element({ accessPoint });
use[array_name] = use[array_name].Union(element.Diff(def[array_name]));
}
}
region->instructions.push_back(instruction);
} }
} }
} }
@@ -208,6 +243,41 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
} }
static void RemoveHeaderConnection(SAPFOR::BasicBlock* header, const unordered_set<SAPFOR::BasicBlock*>& blockSet, unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion)
{
for (SAPFOR::BasicBlock* block : blockSet)
{
bool isCycleBlock = false;
for (SAPFOR::BasicBlock* prevBlock : block->getPrev())
isCycleBlock = isCycleBlock || (blockSet.find(prevBlock) != blockSet.end());
if (isCycleBlock)
{
bbToRegion[block]->removeNextRegion(bbToRegion[header]);
bbToRegion[header]->removePrevRegion(bbToRegion[block]);
}
}
}
static void DFS(Region* block, vector<Region*>& result, unordered_set<Region*> cycleBlocks)
{
for (Region* nextBlock : block->getNextRegions())
{
if (cycleBlocks.find(nextBlock) != cycleBlocks.end())
DFS(nextBlock, result, cycleBlocks);
}
result.push_back(block);
}
void TopologySort(std::vector<Region*>& basikBlocks, Region* header)
{
vector<Region*> result;
unordered_set<Region*> cycleBlocks(basikBlocks.begin(), basikBlocks.end());
DFS(header, result, cycleBlocks);
reverse(result.begin(), result.end());
basikBlocks = result;
}
static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet) static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion, const unordered_set<SAPFOR::BasicBlock*>& blockSet)
{ {
for (SAPFOR::BasicBlock* block : blockSet) for (SAPFOR::BasicBlock* block : blockSet)
@@ -222,10 +292,11 @@ static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegi
} }
} }
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, const unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion) static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, unordered_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);
if (bbToRegion.find(header) != bbToRegion.end()) if (bbToRegion.find(header) != bbToRegion.end())
region->setHeader(bbToRegion.at(header)); region->setHeader(bbToRegion.at(header));
else else
@@ -244,6 +315,7 @@ static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*
continue; continue;
region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion)); region->addSubRegions(CreateSubRegion(childLoop, Blocks, bbToRegion));
} }
TopologySort(region->getBasickBlocks(), region->getHeader());
return region; return region;
} }
@@ -254,12 +326,13 @@ Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks)
for (auto poiner : blockSet) for (auto poiner : blockSet)
{ {
bbToRegion[poiner] = new Region(*poiner); bbToRegion[poiner] = new Region(*poiner);
this->basickBlocks.insert(bbToRegion[poiner]); this->basickBlocks.push_back(bbToRegion[poiner]);
GetDefUseArray(poiner, loop, bbToRegion[poiner]->array_def, bbToRegion[poiner]->array_use); 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);
//create subRegions //create subRegions
for (LoopGraph* childLoop : loop->children) for (LoopGraph* childLoop : loop->children)
{ {
@@ -267,4 +340,5 @@ Region::Region(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks)
continue; continue;
subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion)); subRegions.insert(CreateSubRegion(childLoop, Blocks, bbToRegion));
} }
TopologySort(basickBlocks, this->header);
} }

View File

@@ -8,6 +8,11 @@
#include "graph_loops.h" #include "graph_loops.h"
#include "CFGraph/CFGraph.h" #include "CFGraph/CFGraph.h"
struct RegionInstruction
{
ArrayAccessingIndexes def, use, in, out;
};
class Region : public SAPFOR::BasicBlock { class Region : public SAPFOR::BasicBlock {
public: public:
Region() { header = nullptr; } Region() { header = nullptr; }
@@ -20,13 +25,25 @@ public:
void setHeader(Region* region) { header = region; } void setHeader(Region* region) { header = region; }
std::unordered_set<Region*>& getBasickBlocks() { return basickBlocks; } std::vector<Region*>& getBasickBlocks() { return basickBlocks; }
void addBasickBlocks(Region* region) { basickBlocks.insert(region); } void addBasickBlocks(Region* region) { basickBlocks.push_back(region); }
const std::unordered_set<Region*>& getPrevRegions() { return prevRegions; } const std::unordered_set<Region*>& getPrevRegions() { return prevRegions; }
std::unordered_set<Region*> getNextRegions() { return nextRegions; } std::unordered_set<Region*>& getNextRegions() { return nextRegions; }
void removeNextRegion(Region* region)
{
if (nextRegions.find(region) != nextRegions.end())
nextRegions.erase(region);
}
void removePrevRegion(Region* region)
{
if (prevRegions.find(region) != prevRegions.end())
prevRegions.erase(region);
}
void addPrevRegion(Region* region) { prevRegions.insert(region); } void addPrevRegion(Region* region) { prevRegions.insert(region); }
@@ -48,13 +65,18 @@ public:
void addSubRegions(Region* region) { subRegions.insert(region); } void addSubRegions(Region* region) { subRegions.insert(region); }
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::unordered_set<Region*> subRegions, basickBlocks; std::vector<Region*> basickBlocks;
std::unordered_set<Region*> subRegions;
/*next Region which is BB for current BB Region*/ /*next Region which is BB for current BB Region*/
std::unordered_set<Region*> nextRegions; std::unordered_set<Region*> nextRegions;
/*prev Regions which is BBs for current BB Region*/ /*prev Regions which is BBs for current BB Region*/
std::unordered_set<Region*> prevRegions; std::unordered_set<Region*> prevRegions;
Region* header; Region* header;
}; };
void TopologySort(std::vector<Region*>& basikBlocks, Region* header);

View File

@@ -18,69 +18,66 @@ using std::tuple;
/// main function: /// main function:
// renew unions for all common blocks in the file // renew unions for all common blocks in the file
static void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBlocks, //void BuildNewCommDecls
map<string, deque<CommConstraint>>& newCommonDecls, map<string, map<string, deque<CommConstraint>>>& commDecls,
set<string>& badCommon, map<string, set<string>>& notUsedVars, vector<SgStatement*>& programUnits);
// get names of variables and array elements, which were referenced in programm unit // get names of variables and array elements, which were referenced in programm unit
static set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNames); //set<string> getUses
static void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarNames, set<string>& used); //void getUsesFromExpr
// splits arrays into elements and replaces not used vars with empty constraints // splits arrays into elements and replaces not used vars with empty constraints
static bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& namesOfUsedVars); //bool splitType
// create constraits set // create constraits set
static deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints, const set<string>& namesOfUsedVars, set<string>& notUsedVars); //deque<CommConstraint> makeConstraints
// build union // build union
static bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B, const set<string>& namesOfUsedVars, pair<CommConstraint, CommConstraint>& problemConstraints); //bool buildConstraintsUnion
static bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>& B, deque<CommConstraint>& newU, pair<CommConstraint, CommConstraint>& problemConstraints); //bool docheckUnequalConstraints
static bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommConstraint, CommConstraint>& problemConstraints); //bool check
/// small help functions: /// small help functions:
static string getParentName(const string& name); //string getParentName
static bool equalDims(const CommConstraint& a, const CommConstraint& b); //bool equalDims
static bool equalConstraints(const CommConstraint& a, const CommConstraint& b); //bool equalConstraints
static void addElem(deque<CommConstraint>& comm, const CommConstraint& elem); //void addElem
//////
// change names of variables in 'constraints' // change names of variables in 'constraints'
static void fixNames(deque<CommConstraint>& constraints, const string& commName); //void fixNames
////// step2: transformation ////// step2: transformation
/// main function /// main function
// peform transformation on every program unit in the file // peform transformation on every program unit in the file
static void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, deque<CommConstraint>>& newCommonDecls, //void fixFunctions
map<string, map<string, deque<CommConstraint>>>& commDecls, const set<string>& badCommon, map<string, set<string>>& notUsedVars);
// get pairs of names (namesOldToNew) for renaming // get pairs of names (namesOldToNew) for renaming
static bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDecl, map<string, string>& namesOldToNew); //bool getNamesOldToNew
// create new symbols for new variables in new common declaration (constraints) // create new symbols for new variables in new common declaration (constraints)
static void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* file, SgStatement* func, string commName, //void makeCommVarSymbs
map<string, SgSymbol*>& symbs, vector<SgSymbol*>& needNewDecl);
// delete from program unit all references to names in commVarNames // delete from program unit all references to names in commVarNames
static void deleteOldVars(SgStatement* firstSt, const set<string>& commVarNames); //void deleteOldVars
// calls fixExpression for each statement, replaces names in data statement // calls fixExpression for each statement, replaces names in data statement
static void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>& newVarSymbs, const map<string, string>& namesOldToNew); //void renameVariables
// replacing variables or array elements in expression expr if their names are in namesOldToNew // replacing variables or array elements in expression expr if their names are in namesOldToNew
static SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbol*>& newSymbs, const map<string, string>& namesOldToNew); //SgExpression* fixExpression
// make new exprList exprssion for new declaration decl with symbols from newSymbs // make new exprList exprssion for new declaration decl with symbols from newSymbs
static SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, const map<string, SgSymbol*>& newSymbs, //SgExpression* makeExprListForCommon
SgFile* file, SgStatement* firstSt);
// replace old common declarations with new ones // replace old common declarations with new ones
static void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& commListExprs); //void rewriteCommon
/// help functions: /// help functions:
static SgExpression* makeIdxFromStr(const string& str); //SgExpression* makeIdxFromStr(const string& str);
// make new expression of array element // make new expression of array element
static SgExpression* newArrElemExpr(const string& newName, const map<string, SgSymbol*>& newSymbs); //SgExpression* newArrElemExpr
static bool variablePositionComp(const Variable* lhs, const Variable* rhs); //bool variablePositionComp
////// //////
CommConstraint::CommConstraint(const Variable* var, bool u, const string& funcName, const string& fileName) CommConstraint::CommConstraint(const Variable* var, bool u, const string& funcName, const string& fileName)
{ {
used = u; used = u;
@@ -125,7 +122,6 @@ CommConstraint::CommConstraint(const Variable* var, bool u, const string& funcNa
} }
} }
CommConstraint::CommConstraint(const string& name, SgType* t, bool u) : used(u), type(t), identifier(name) CommConstraint::CommConstraint(const string& name, SgType* t, bool u) : used(u), type(t), identifier(name)
{ {
typeVariant = type->variant(); typeVariant = type->variant();
@@ -139,8 +135,7 @@ CommConstraint::CommConstraint(const string& name, SgType* t, bool u, vector<Dec
size = getSizeOfType(type); size = getSizeOfType(type);
} }
static string getParentName(const string& name)
string getParentName(const string& name)
{ {
size_t len = name.find("%"); size_t len = name.find("%");
size_t posB = name.find("("); size_t posB = name.find("(");
@@ -154,8 +149,7 @@ string getParentName(const string& name)
return name.substr(0, len); return name.substr(0, len);
} }
static void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarNames, set<string>& used)
void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarNames, set<string>& used)
{ {
if (expr == NULL) if (expr == NULL)
return; return;
@@ -194,8 +188,7 @@ void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarNames, set<
getUsesFromExpr(expr->rhs(), commonVarNames, used); getUsesFromExpr(expr->rhs(), commonVarNames, used);
} }
static set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNames)
set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNames)
{ {
set<string> used; set<string> used;
SgStatement* lastSt = firstSt->lastNodeOfStmt(); SgStatement* lastSt = firstSt->lastNodeOfStmt();
@@ -212,8 +205,7 @@ set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNames)
return used; return used;
} }
static bool equalDims(const CommConstraint& a, const CommConstraint& b)
bool equalDims(const CommConstraint& a, const CommConstraint& b)
{ {
const vector<pair<int, int>>& adim = a.arrayInfo->GetSizes(); const vector<pair<int, int>>& adim = a.arrayInfo->GetSizes();
const vector<pair<int, int>>& bdim = b.arrayInfo->GetSizes(); const vector<pair<int, int>>& bdim = b.arrayInfo->GetSizes();
@@ -228,9 +220,8 @@ bool equalDims(const CommConstraint& a, const CommConstraint& b)
return true; return true;
} }
// TODO: add attributes to CommConstraints, check if a and b have equal attributes // TODO: add attributes to CommConstraints, check if a and b have equal attributes
bool equalConstraints(const CommConstraint& a, const CommConstraint& b) static bool equalConstraints(const CommConstraint& a, const CommConstraint& b)
{ {
if ((a.arrayInfo != NULL && b.arrayInfo == NULL) || ((a.arrayInfo == NULL && b.arrayInfo != NULL))) if ((a.arrayInfo != NULL && b.arrayInfo == NULL) || ((a.arrayInfo == NULL && b.arrayInfo != NULL)))
return false; return false;
@@ -241,8 +232,7 @@ bool equalConstraints(const CommConstraint& a, const CommConstraint& b)
return true; return true;
} }
static void addElem(deque<CommConstraint>& comm, const CommConstraint& elem)
void addElem(deque<CommConstraint>& comm, const CommConstraint& elem)
{ {
if (elem.typeVariant == 0 && !comm.empty() && comm.back().typeVariant == 0) if (elem.typeVariant == 0 && !comm.empty() && comm.back().typeVariant == 0)
comm.back().size += elem.size; comm.back().size += elem.size;
@@ -250,9 +240,8 @@ void addElem(deque<CommConstraint>& comm, const CommConstraint& elem)
comm.push_back(elem); comm.push_back(elem);
} }
// TODO: check attributes: do not split arrays with pointer or target attributes if check_use == true // TODO: check attributes: do not split arrays with pointer or target attributes if check_use == true
bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& namesOfUsedVars = {}) static bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& namesOfUsedVars = {})
{ {
CommConstraint var = d.front(); CommConstraint var = d.front();
string name = var.identifier; string name = var.identifier;
@@ -300,8 +289,7 @@ bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& name
} }
} }
static deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints, const set<string>& namesOfUsedVars, set<string>& notUsedVars)
deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints, const set<string>& namesOfUsedVars, set<string>& notUsedVars)
{ {
deque<CommConstraint> res; deque<CommConstraint> res;
while (!constraints.empty()) while (!constraints.empty())
@@ -318,8 +306,7 @@ deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints, const
return res; return res;
} }
static bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommConstraint, CommConstraint>& problemConstraints)
bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommConstraint, CommConstraint>& problemConstraints)
{ {
while (!A.empty() && !B.empty()) while (!A.empty() && !B.empty())
{ {
@@ -358,8 +345,8 @@ bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommConstrai
return true; return true;
} }
static bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>& B, deque<CommConstraint>& newU,
bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>& B, deque<CommConstraint>& newU, pair<CommConstraint, CommConstraint>& problemConstraints) pair<CommConstraint, CommConstraint>& problemConstraints)
{ {
if (U.front().typeVariant == 0) if (U.front().typeVariant == 0)
{ {
@@ -382,8 +369,8 @@ bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>&
return true; return true;
} }
static bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B,
bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B, const set<string>& namesOfUsedVars, pair<CommConstraint, CommConstraint>& problemConstraints) const set<string>& namesOfUsedVars, pair<CommConstraint, CommConstraint>& problemConstraints)
{ {
deque<CommConstraint> newU; deque<CommConstraint> newU;
while (!U.empty() && !B.empty()) while (!U.empty() && !B.empty())
@@ -438,8 +425,8 @@ bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B, co
return true; return true;
} }
//TODO: check this: newDecl and oldDecl => do these variables need references?
bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDecl, map<string, string>& namesOldToNew) static bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDecl, map<string, string>& namesOldToNew)
{ {
bool needChange = false; bool needChange = false;
map<string, string> rename; map<string, string> rename;
@@ -504,16 +491,18 @@ bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDe
newDecl.pop_front(); newDecl.pop_front();
} }
} }
if (!oldDecl.empty() || !newDecl.empty()) if (!oldDecl.empty() || !newDecl.empty())
needChange = true; needChange = true;
if (needChange) if (needChange)
namesOldToNew.insert(rename.begin(), rename.end()); namesOldToNew.insert(rename.begin(), rename.end());
return needChange; return needChange;
} }
static void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* file, SgStatement* func, const string& commName,
void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* file, SgStatement* func, string commName, map<string, SgSymbol*>& symbs, vector<SgSymbol*>& needNewDecl)
map<string, SgSymbol*>& symbs, vector<SgSymbol*>& needNewDecl)
{ {
for (const CommConstraint& var : constraints) for (const CommConstraint& var : constraints)
{ {
@@ -526,8 +515,7 @@ void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* file, Sg
} }
} }
static void deleteOldVars(SgStatement* firstSt, const set<string>& commVarNames)
void deleteOldVars(SgStatement* firstSt, const set<string>& commVarNames)
{ {
SgStatement* lastSt = firstSt->lastNodeOfStmt(); SgStatement* lastSt = firstSt->lastNodeOfStmt();
vector<SgStatement*> stmtsToDelete; vector<SgStatement*> stmtsToDelete;
@@ -573,12 +561,12 @@ void deleteOldVars(SgStatement* firstSt, const set<string>& commVarNames)
} }
// TODO: delete common variables form attributes statements (like DIM_STAT) // TODO: delete common variables form attributes statements (like DIM_STAT)
} }
for (SgStatement* st : stmtsToDelete) for (SgStatement* st : stmtsToDelete)
st->deleteStmt(); st->deleteStmt();
} }
static SgExpression* makeIdxFromStr(const string& str)
SgExpression* makeIdxFromStr(const string& str)
{ {
vector<SgExpression*> items; vector<SgExpression*> items;
int num = 0; int num = 0;
@@ -593,13 +581,13 @@ SgExpression* makeIdxFromStr(const string& str)
num = 0; num = 0;
} }
} }
reverse(items.begin(), items.end()); reverse(items.begin(), items.end());
SgExpression* exprList = makeExprList(items, false); SgExpression* exprList = makeExprList(items, false);
return exprList; return exprList;
} }
static SgExpression* newArrElemExpr(const string& newName, const map<string, SgSymbol*>& newSymbs)
SgExpression* newArrElemExpr(const string& newName, const map<string, SgSymbol*>& newSymbs)
{ {
size_t pos = newName.find('('); size_t pos = newName.find('(');
SgExpression* newExpr = new SgArrayRefExp(*newSymbs.at(newName.substr(0, pos))); SgExpression* newExpr = new SgArrayRefExp(*newSymbs.at(newName.substr(0, pos)));
@@ -607,11 +595,11 @@ SgExpression* newArrElemExpr(const string& newName, const map<string, SgSymbol*>
return newExpr; return newExpr;
} }
static SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbol*>& newSymbs, const map<string, string>& namesOldToNew)
SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbol*>& newSymbs, const map<string, string>& namesOldToNew)
{ {
if (expr == NULL) if (expr == NULL)
return NULL; return NULL;
if (expr->variant() == VAR_REF || expr->variant() == ARRAY_REF) if (expr->variant() == VAR_REF || expr->variant() == ARRAY_REF)
{ {
string name = expr->symbol()->identifier(); string name = expr->symbol()->identifier();
@@ -647,17 +635,18 @@ SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbol*>& ne
} }
} }
} }
SgExpression* lhs = fixExpression(expr->lhs(), newSymbs, namesOldToNew); SgExpression* lhs = fixExpression(expr->lhs(), newSymbs, namesOldToNew);
if (lhs != NULL) if (lhs != NULL)
expr->setLhs(lhs); expr->setLhs(lhs);
SgExpression* rhs = fixExpression(expr->rhs(), newSymbs, namesOldToNew); SgExpression* rhs = fixExpression(expr->rhs(), newSymbs, namesOldToNew);
if (rhs != NULL) if (rhs != NULL)
expr->setRhs(rhs); expr->setRhs(rhs);
return NULL; return NULL;
} }
static void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>& newVarSymbs, const map<string, string>& namesOldToNew)
void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>& newVarSymbs, const map<string, string>& namesOldToNew)
{ {
SgStatement* lastSt = firstSt->lastNodeOfStmt(); SgStatement* lastSt = firstSt->lastNodeOfStmt();
for (SgStatement* curSt = firstSt; curSt != NULL && curSt != lastSt; curSt = curSt->lexNext()) for (SgStatement* curSt = firstSt; curSt != NULL && curSt != lastSt; curSt = curSt->lexNext())
@@ -705,8 +694,7 @@ void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>& newVarS
} }
} }
static SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, const map<string, SgSymbol*>& newSymbs,
SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, const map<string, SgSymbol*>& newSymbs,
SgFile* file, SgStatement* firstSt) SgFile* file, SgStatement* firstSt)
{ {
vector<SgExpression*> items; vector<SgExpression*> items;
@@ -740,8 +728,7 @@ SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, const map
return exprList; return exprList;
} }
static void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& commListExprs)
void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& commListExprs)
{ {
vector<SgStatement*> commonStmtsToDelete; vector<SgStatement*> commonStmtsToDelete;
for (SgStatement* st = firstSt; st != firstSt->lastDeclaration()->lexNext(); st = st->lexNext()) for (SgStatement* st = firstSt; st != firstSt->lastDeclaration()->lexNext(); st = st->lexNext())
@@ -792,12 +779,12 @@ void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& commListExp
commonStmtsToDelete.push_back(st); commonStmtsToDelete.push_back(st);
} }
} }
for (SgStatement* st : commonStmtsToDelete) for (SgStatement* st : commonStmtsToDelete)
st->deleteStmt(); st->deleteStmt();
} }
static void fixNames(deque<CommConstraint>& constraints, const string& commName)
void fixNames(deque<CommConstraint>& constraints, const string& commName)
{ {
for (auto& var : constraints) for (auto& var : constraints)
{ {
@@ -812,26 +799,26 @@ void fixNames(deque<CommConstraint>& constraints, const string& commName)
} }
} }
static bool variablePositionComp(const Variable* lhs, const Variable* rhs)
bool variablePositionComp(const Variable* lhs, const Variable* rhs)
{ {
return lhs->getPosition() < rhs->getPosition(); return lhs->getPosition() < rhs->getPosition();
} }
static void fixFunctions(SgFile* file, const vector<SgStatement*>& programUnits, map<string, deque<CommConstraint>>& newCommonDecls,
void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, deque<CommConstraint>>& newCommonDecls, map<string, map<string, deque<CommConstraint>>>& commDecls, const set<string>& badCommon, map<string, set<string>>& notUsedVars)
map<string, map<string, deque<CommConstraint>>>& commDecls, const set<string>& badCommon, map<string, set<string>>& notUsedVars)
{ {
for (SgStatement* unitSt : programUnits) for (SgStatement* unitSt : programUnits)
{ {
string funcName = unitSt->symbol()->identifier(); string funcName = unitSt->symbol()->identifier();
if (commDecls.find(funcName) == commDecls.end()) if (commDecls.find(funcName) == commDecls.end())
continue; continue;
SgStatement* firstSt = unitSt; SgStatement* firstSt = unitSt;
map<string, SgExpression*> commListExprs; map<string, SgExpression*> commListExprs;
map<string, SgSymbol*> newVarSymbs; // new symbols for new variables map<string, SgSymbol*> newVarSymbs; // new symbols for new variables
map<string, string> namesOldToNew; // for ranaming: old name -> new name map<string, string> namesOldToNew; // for ranaming: old name -> new name
vector<SgSymbol*> needNewDecl; vector<SgSymbol*> needNewDecl;
for (auto& common : commDecls[funcName]) for (auto& common : commDecls[funcName])
{ {
string commName = common.first; string commName = common.first;
@@ -842,9 +829,11 @@ void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, d
bool needChange = getNamesOldToNew(newDecl, common.second, namesOldToNew); bool needChange = getNamesOldToNew(newDecl, common.second, namesOldToNew);
if (!needChange) if (!needChange)
continue; continue;
makeCommVarSymbs(newDecl, file, firstSt, commName, newVarSymbs, needNewDecl); makeCommVarSymbs(newDecl, file, firstSt, commName, newVarSymbs, needNewDecl);
commListExprs[commName] = makeExprListForCommon(newDecl, newVarSymbs, file, firstSt); commListExprs[commName] = makeExprListForCommon(newDecl, newVarSymbs, file, firstSt);
} }
if (!commListExprs.empty()) if (!commListExprs.empty())
{ {
for (const auto& item : commListExprs) for (const auto& item : commListExprs)
@@ -858,10 +847,9 @@ void fixFunctions(SgFile* file, vector<SgStatement*> programUnits, map<string, d
} }
} }
static void buildNewCommDecls(SgFile* file, const map<string, CommonBlock*>& allCommonBlocks,
void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBlocks, map<string, deque<CommConstraint>>& newCommonDecls, map<string, map<string, deque<CommConstraint>>>& commDecls,
map<string, deque<CommConstraint>>& newCommonDecls, map<string, map<string, deque<CommConstraint>>>& commDecls, set<string>& badCommon, map<string, set<string>>& notUsedVars, vector<SgStatement*>& programUnits)
set<string>& badCommon, map<string, set<string>>& notUsedVars, vector<SgStatement*>& programUnits)
{ {
string fileName = file->filename(); string fileName = file->filename();
SgStatement* curSt = file->firstStatement(); SgStatement* curSt = file->firstStatement();
@@ -900,7 +888,8 @@ void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBl
constraints.push_back(newConstr); constraints.push_back(newConstr);
} }
if (hasChar && hasNotChar) // TDOO: make proper warning message or separate such common blocks if (hasChar && hasNotChar) // TDOO: make proper warning message or separate such common blocks
__spf_print(1, "common block '%s' ('%s':%d) contains variables of symbolic and numeric types. It is required to divide\n", commName.c_str(), fileName.c_str(), constraints.back().uses.back().lineNum); __spf_print(1, "common block '%s' ('%s':%d) contains variables of symbolic and numeric types. It is required to divide\n",
commName.c_str(), fileName.c_str(), constraints.back().uses.back().getLineNum());
if (hasChar) if (hasChar)
{ {
badCommon.insert(commName); badCommon.insert(commName);
@@ -917,7 +906,7 @@ void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBl
for (auto x : problemConstraints.first.uses) // TODO: make proper warning message for (auto x : problemConstraints.first.uses) // TODO: make proper warning message
for (auto y : problemConstraints.second.uses) for (auto y : problemConstraints.second.uses)
__spf_print(1, "variables '%s' and '%s' in one storage association (common block '%s') have different types (files - %s:%d and %s:%d)\n", __spf_print(1, "variables '%s' and '%s' in one storage association (common block '%s') have different types (files - %s:%d and %s:%d)\n",
x.varName.c_str(), y.varName.c_str(), commName.c_str(), x.fileName.c_str(), x.lineNum, y.fileName.c_str(), y.lineNum); x.getVarName(), y.getVarName(), commName.c_str(), x.getFileName(), x.getLineNum(), y.getFileName(), y.getLineNum());
} }
} }
curSt = curSt->lastNodeOfStmt(); curSt = curSt->lastNodeOfStmt();
@@ -929,7 +918,7 @@ void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBl
// main function // main function
void fixCommonBlocks(const map<string, vector<FuncInfo*>> allFuncInfo, const map<string, CommonBlock*> allCommonBlocks, SgProject* project) // TODO: separate into 2 steps? void fixCommonBlocks(const map<string, vector<FuncInfo*>>& allFuncInfo, const map<string, CommonBlock*>& allCommonBlocks, SgProject* project) // TODO: separate into 2 steps?
{ {
int filesNum = project->numberOfFiles(); int filesNum = project->numberOfFiles();
map<string, map<string, map<string, deque<CommConstraint>>>> commDecls; // file_name -> function_name -> common block name -> old declaration of common block map<string, map<string, map<string, deque<CommConstraint>>>> commDecls; // file_name -> function_name -> common block name -> old declaration of common block
@@ -943,10 +932,12 @@ void fixCommonBlocks(const map<string, vector<FuncInfo*>> allFuncInfo, const map
SgFile* file = &project->file(i); SgFile* file = &project->file(i);
string fileName = file->filename(); string fileName = file->filename();
file->switchToFile(fileName); file->switchToFile(fileName);
BuildNewCommDecls(file, allCommonBlocks, newCommonDecls, commDecls[fileName], badCommon, notUsedVars, programUnitsInFile[fileName]); buildNewCommDecls(file, allCommonBlocks, newCommonDecls, commDecls[fileName], badCommon, notUsedVars, programUnitsInFile[fileName]);
} }
for (auto& elem : newCommonDecls) for (auto& elem : newCommonDecls)
fixNames(elem.second, elem.first); fixNames(elem.second, elem.first);
for (int i = 0; i < filesNum; i++) // second step for (int i = 0; i < filesNum; i++) // second step
{ {
SgFile* file = &project->file(i); SgFile* file = &project->file(i);

View File

@@ -16,12 +16,18 @@
struct DeclInfo // for error messages struct DeclInfo // for error messages
{ {
private:
std::string varName; std::string varName;
std::string fileName; std::string fileName;
int lineNum; int lineNum;
public:
DeclInfo() : varName(""), fileName(""), lineNum(0) {}; DeclInfo() : varName(""), fileName(""), lineNum(0) {};
DeclInfo(const std::string& vn, const std::string& fn, int ln) : varName(vn), fileName(fn), lineNum(ln) {}; DeclInfo(const std::string& vn, const std::string& fn, int ln) : varName(vn), fileName(fn), lineNum(ln) {};
const char* getVarName() const { return varName.c_str(); }
const char* getFileName() const { return fileName.c_str(); }
int getLineNum() const { return lineNum; }
}; };
struct CommConstraint // TODO: add variable attributes struct CommConstraint // TODO: add variable attributes
@@ -42,4 +48,4 @@ struct CommConstraint // TODO: add variable attributes
}; };
void fixCommonBlocks(const std::map<std::string, std::vector<FuncInfo*>> allFuncInfo, const std::map<std::string, CommonBlock*> allCommonBlocks, SgProject* project); void fixCommonBlocks(const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo, const std::map<std::string, CommonBlock*>& allCommonBlocks, SgProject* project);

View File

@@ -325,7 +325,7 @@ static void getModuleSymbols(SgStatement* func, set<SgSymbol*>& symbs)
} }
} }
set<SgSymbol*> getModuleSymbols(SgStatement *func) const set<SgSymbol*>& getModuleSymbols(SgStatement *func)
{ {
auto it = symbolsForFunc.find(func->symbol()->identifier()); auto it = symbolsForFunc.find(func->symbol()->identifier());
if (it != symbolsForFunc.end()) if (it != symbolsForFunc.end())
@@ -345,7 +345,7 @@ set<SgSymbol*> getModuleSymbols(SgStatement *func)
} }
symbolsForFunc[func->symbol()->identifier()] = symbs; symbolsForFunc[func->symbol()->identifier()] = symbs;
return symbs; return symbolsForFunc[func->symbol()->identifier()];
} }
static void findSymbol(SgStatement* func, const string& varName, const string& locName, static void findSymbol(SgStatement* func, const string& varName, const string& locName,

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
std::string correctSymbolModuleName(const std::string& origFull); std::string correctSymbolModuleName(const std::string& origFull);
std::set<SgSymbol*> getModuleSymbols(SgStatement* func); const std::set<SgSymbol*>& getModuleSymbols(SgStatement* func);
void getModulesAndFunctions(SgFile* file, std::vector<SgStatement*>& modulesAndFunctions); void getModulesAndFunctions(SgFile* file, std::vector<SgStatement*>& modulesAndFunctions);
void findModulesInFile(SgFile* file, std::vector<SgStatement*>& modules); void findModulesInFile(SgFile* file, std::vector<SgStatement*>& modules);
std::map<std::string, std::set<std::string>> createMapOfModuleUses(SgFile* file); std::map<std::string, std::set<std::string>> createMapOfModuleUses(SgFile* file);

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_SPF "2464" #define VERSION_SPF "2465"