29 Commits

Author SHA1 Message Date
Egor Mayorov
37389b486a Analyze program block by block & reorder operators only in basic blocks 2026-02-26 00:57:50 +03:00
Egor Mayorov
136850a081 use rd 2026-02-25 23:24:32 +03:00
ALEXks
7c0e97e0aa refactored, added pass to Visualizer calls 2026-02-25 23:24:32 +03:00
ALEXks
52028f86e4 refactored 2026-02-25 23:24:32 +03:00
Egor Mayorov
0d8a9e8a98 fixes & improvements 2026-02-25 23:24:32 +03:00
Egor Mayorov
2b3cd51668 Adding handing of nested loops and conditional statements 2026-02-25 23:24:32 +03:00
Egor Mayorov
d401daa9f4 Make pass correct 2026-02-25 23:24:32 +03:00
Egor Mayorov
b8f04dbb92 attempt to build new ast 2026-02-25 23:24:32 +03:00
332252a79e moved to transformations 2026-02-25 23:24:32 +03:00
Egor Mayorov
f95be3ebc8 swap operators in AST 2026-02-25 23:24:32 +03:00
Egor Mayorov
f84e6ca6b3 Use more complex algorythm for building new order of statements 2026-02-25 23:24:32 +03:00
Egor Mayorov
58c1f8d6ca update in new order 2026-02-25 23:24:32 +03:00
Egor Mayorov
65e2f4febf biulding new order 2026-02-25 23:24:32 +03:00
Egor Mayorov
96118e4980 some loop analysis done 2026-02-25 23:24:32 +03:00
Egor Mayorov
b5ab467bf8 Add _bin to gitignore 2026-02-25 23:24:32 +03:00
Egor Mayorov
9618e6ce00 Some actions simplify analyzing IR 2026-02-25 23:24:32 +03:00
Egor Mayorov
3605665c88 Pass with output file added 2026-02-25 23:24:32 +03:00
Egor Mayorov
47304c4e16 change pass deps 2026-02-25 23:24:32 +03:00
Egor Mayorov
6f61917ee6 New pass 2026-02-25 23:24:32 +03:00
ALEXks
dcf40201a6 corrected style, updated version 2026-02-25 23:24:32 +03:00
4362fb6fb8 small fix 2026-02-25 23:24:32 +03:00
c5a44c4899 add whole array assign 2026-02-25 23:24:32 +03:00
928cfbdfb2 fix 2026-02-25 23:24:32 +03:00
ALEXks
96338799bc updated version, fixed code style 2026-02-25 23:24:32 +03:00
a75012b6b6 fix FIND_PRIVATE_ARRAYS 2026-02-25 23:24:32 +03:00
ALEXks
d94cb3c062 finalyze first version of private arrays search 2026-02-25 23:24:32 +03:00
13e4b6dff6 add directives 2026-02-25 23:24:32 +03:00
ALEXks
24f261961d added new function for visualizer 2026-02-25 23:24:32 +03:00
ALEXks
46a4eec33e version updated 2026-02-25 23:24:32 +03:00
27 changed files with 1160 additions and 1341 deletions

View File

@@ -1162,7 +1162,6 @@ map<FuncInfo*, vector<BBlock*>> buildCFG(const map<string, CommonBlock*>& common
if (SgFile::switchToFile(oldFile) == -1) if (SgFile::switchToFile(oldFile) == -1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (!settings.withUnreachable)
for (auto& [func, blocks] : result) for (auto& [func, blocks] : result)
removedUnreachableBlocks(blocks); removedUnreachableBlocks(blocks);

View File

@@ -105,52 +105,23 @@ namespace SAPFOR
struct CFG_Settings struct CFG_Settings
{ {
enum setting { CFG_atLeastOneIterInLoop = 1,
CFG_withRD = 2,
CFG_withRegisters = 3,
CFG_withSPF = 4,
CFG_withDVM = 5,
CFG_withCallsInBlocks = 6,
CFG_withCallFrom = 7,
CFG_withDominators = 8,
CFG_withUnreachable = 9 };
bool atLeastOneIterInLoop = false; bool atLeastOneIterInLoop = false;
bool withRD = false; bool withRD = true;
bool withRegisters = false; bool withRegisters = false;
bool withSPF = false; bool withSPF = false;
bool withDVM = false; bool withDVM = false;
bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock bool withCallsInBlocks = false; // separate each F_CALL to own BasicBlock
bool withCallFrom = false; bool withCallFrom = true;
bool withDominators = false; bool withDominators = true;
bool withUnreachable = false;
explicit CFG_Settings(const std::set<setting> &settings = { CFG_withRD, CFG_withCallFrom, CFG_withDominators }) explicit CFG_Settings(int) { }
{
for (auto& set : settings) explicit CFG_Settings(bool atLeastOneIterInLoop = false, bool withRD = true, bool withRegisters = false,
{ bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false,
if (set == CFG_atLeastOneIterInLoop) bool withCallFrom = true, bool withDominators = true) :
atLeastOneIterInLoop = true; atLeastOneIterInLoop(atLeastOneIterInLoop), withRD(withRD), withRegisters(withRegisters), withDVM(withDVM), withSPF(withSPF),
else if (set == CFG_withRD) withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom), withDominators(withDominators)
withRD = true; { }
else if (set == CFG_withRegisters)
withRegisters = true;
else if (set == CFG_withSPF)
withSPF = true;
else if (set == CFG_withDVM)
withDVM = true;
else if (set == CFG_withCallsInBlocks)
withCallsInBlocks = true;
else if (set == CFG_withCallFrom)
withCallFrom = true;
else if (set == CFG_withDominators)
withDominators = true;
else if (set == CFG_withUnreachable)
withUnreachable = true;
else
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
}; };
} }

View File

@@ -200,41 +200,15 @@ static void fillOutForFunc(const FuncInfo* func, const vector<SAPFOR::BasicBlock
outForFunc[func->funcName] = { defined, common_defined }; outForFunc[func->funcName] = { defined, common_defined };
} }
static bool isInstructionSpfParameter(SAPFOR::Instruction* instr)
{
SgStatement* st = instr->getOperator();
// check if this operator is SPF(ANALYSIS(PARAMETER( )))
if (st && st->variant() == ASSIGN_STAT)
{
if (st->lineNumber() < 0 && st->numberOfAttributes())
{
for (int i = 0; i < st->numberOfAttributes(); ++i)
{
SgAttribute* attr = st->getAttribute(i);
SgStatement* attributeStatement = (SgStatement*)(attr->getAttributeData());
int type = st->attributeType(i);
if (type == SPF_PARAMETER_OP)
return true;
}
}
}
return false;
}
static void getDefsFromBlock(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& res, static void getDefsFromBlock(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& res,
const vector<pair<const Variable*, CommonBlock*>>& commonVars, const vector<pair<const Variable*, CommonBlock*>>& commonVars,
const FuncInfo* func) const FuncInfo* func)
{ {
vector<SAPFOR::Argument*> lastParamRef; vector<SAPFOR::Argument*> lastParamRef;
for (const auto &ir_block : block->getInstructions()) for (auto ir_block : block->getInstructions())
{ {
SAPFOR::Instruction* instr = ir_block->getInstruction(); SAPFOR::Instruction* instr = ir_block->getInstruction();
if (isInstructionSpfParameter(instr))
continue;
SAPFOR::CFG_OP instr_operation = instr->getOperation(); SAPFOR::CFG_OP instr_operation = instr->getOperation();
if (instr_operation == SAPFOR::CFG_OP::PARAM) if (instr_operation == SAPFOR::CFG_OP::PARAM)
{ {
@@ -262,19 +236,11 @@ static void getDefsFromBlock(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>&
int last_instr_num = block->getInstructions().back()->getNumber(); int last_instr_num = block->getInstructions().back()->getNumber();
for (const auto& def : block->getRD_Out()) for (const auto& def : block->getRD_Out())
{
for (int place : def.second) for (int place : def.second)
{
if (place >= first_instr_num && place <= last_instr_num && def.first->getType() == SAPFOR::CFG_ARG_TYPE::VAR) if (place >= first_instr_num && place <= last_instr_num && def.first->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
{ {
SAPFOR::Instruction* instr = block->getInstructions()[place - first_instr_num]->getInstruction();
if (isInstructionSpfParameter(instr))
continue;
res.insert(def.first); res.insert(def.first);
addPlaceWithDef(commonVars, func, def.first, instr); addPlaceWithDef(commonVars, func, def.first, block->getInstructions()[place - first_instr_num]->getInstruction());
}
}
} }
} }
@@ -300,7 +266,7 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
SAPFOR::BasicBlock* head_block = NULL; SAPFOR::BasicBlock* head_block = NULL;
int loop_start = loop->lineNum, loop_end = loop->lineNumAfterLoop; int loop_start = loop->lineNum, loop_end = loop->lineNumAfterLoop;
for (const auto &bb : blocks) for (auto bb : blocks)
{ {
if (!bb || (bb->getInstructions().size() == 0)) if (!bb || (bb->getInstructions().size() == 0))
continue; continue;
@@ -321,12 +287,6 @@ 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__);
@@ -388,7 +348,7 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
getDefsFromBlock(*loop_it, changeValueOnExit, commonVars, func); getDefsFromBlock(*loop_it, changeValueOnExit, commonVars, func);
for (const auto &bb : currentLoop) for (auto bb : currentLoop)
{ {
//fill LiveWhenLoopEnds //fill LiveWhenLoopEnds
bool has_next_outside_body = false; bool has_next_outside_body = false;

View File

@@ -853,21 +853,12 @@ static pair<string, string> getModuleRename(const set<SgStatement*>& allocatable
return make_pair("", ""); return make_pair("", "");
} }
static void doRename(string& str, const pair<string, string>& renamePair)
{
auto it = str.find(renamePair.first);
if (it != string::npos)
if (str[it + renamePair.first.size()] == '(' && str[it - 1] == ' ')
str = str.replace(it, renamePair.first.size(), renamePair.second);
}
static pair<DIST::Array*, string> static pair<DIST::Array*, string>
getNewDirective(const string &fullArrayName, getNewDirective(const string &fullArrayName,
const vector<string> &distrRules, const vector<string> &distrRules,
const vector<string> &alignRules, const vector<string> &alignRules,
const DataDirective &dataDir, const DataDirective &dataDir,
const set<SgStatement*>& allocatableStmts, const set<SgStatement*>& allocatableStmts)
const pair<string, int>& position_decl)
{ {
string out = ""; string out = "";
DIST::Array* outA = NULL; DIST::Array* outA = NULL;
@@ -886,8 +877,7 @@ getNewDirective(const string &fullArrayName,
for (int i = 0; i < dataDir.alignRules.size(); ++i) for (int i = 0; i < dataDir.alignRules.size(); ++i)
{ {
auto alignArray = dataDir.alignRules[i].alignArray; if (dataDir.alignRules[i].alignArray->GetName() == fullArrayName)
if (alignArray->GetName() == fullArrayName)
{ {
string rule = alignRules[i]; string rule = alignRules[i];
if (allocatableStmts.size()) if (allocatableStmts.size())
@@ -899,21 +889,21 @@ getNewDirective(const string &fullArrayName,
it = rule.find("ALIGN", it + 7); it = rule.find("ALIGN", it + 7);
} }
auto renamePair = getModuleRename(allocatableStmts, alignArray); auto renamePair = getModuleRename(allocatableStmts, dataDir.alignRules[i].alignArray);
doRename(rule, renamePair); if (renamePair.first != "")
}
else if (alignArray->GetLocation().first == DIST::l_COMMON)
{ {
auto symb = alignArray->GetDeclSymbol(position_decl); it = rule.find(renamePair.first);
if (symb->identifier() != alignArray->GetShortName()) if (it != string::npos)
doRename(rule, make_pair(alignArray->GetShortName(), symb->identifier())); if (rule[it + renamePair.first.size()] == '(' && rule[it - 1] == ' ')
rule = rule.replace(it, renamePair.first.size(), renamePair.second);
}
} }
out += "!DVM$ " + rule + "\n"; out += "!DVM$ " + rule + "\n";
if (!out_free_form) if (!out_free_form)
out = splitDirective(out); out = splitDirective(out);
return make_pair(alignArray, out); return make_pair(dataDir.alignRules[i].alignArray, out);
} }
} }
@@ -1753,7 +1743,7 @@ void insertDistributionToFile(SgFile *file, const char *fin_name, const DataDire
if (allocatableStmtsCopy.size()) if (allocatableStmtsCopy.size())
allocatableStmts = filterAllocateStats(file, allocatableStmtsCopy, currSymb->identifier()); allocatableStmts = filterAllocateStats(file, allocatableStmtsCopy, currSymb->identifier());
pair<DIST::Array*, string> dirWithArray = getNewDirective(fullArrayName, distrRules, alignRules, dataDir, allocatableStmts, make_pair(st->fileName(), st->lineNumber())); pair<DIST::Array*, string> dirWithArray = getNewDirective(fullArrayName, distrRules, alignRules, dataDir, allocatableStmts);
string toInsert = dirWithArray.second; string toInsert = dirWithArray.second;
if (toInsert != "") if (toInsert != "")
@@ -1985,27 +1975,20 @@ void insertDistributionToFile(SgFile *file, const char *fin_name, const DataDire
set<string> toInsertArrays; set<string> toInsertArrays;
for (auto &array : dynamicArraysLocal) for (auto &array : dynamicArraysLocal)
{ {
string name = array->GetShortName();
if (array->GetLocation().first == DIST::l_COMMON)
{
auto symb = array->GetDeclSymbol(make_pair(st->fileName(), st->lineNumber()));
name = symb->identifier();
}
if (extractDir) if (extractDir)
{ {
if (dynamicArraysAdded.find(name) != dynamicArraysAdded.end()) if (dynamicArraysAdded.find(array->GetShortName()) != dynamicArraysAdded.end())
{ {
dynamicArraysAdded.erase(name); dynamicArraysAdded.erase(array->GetShortName());
toInsertArrays.insert(name); toInsertArrays.insert(array->GetShortName());
} }
} }
else else
{ {
if (dynamicArraysAdded.find(name) == dynamicArraysAdded.end()) if (dynamicArraysAdded.find(array->GetShortName()) == dynamicArraysAdded.end())
{ {
dynamicArraysAdded.insert(name); dynamicArraysAdded.insert(array->GetShortName());
toInsertArrays.insert(name); toInsertArrays.insert(array->GetShortName());
} }
} }
} }
@@ -2162,14 +2145,7 @@ void insertShadowSpecToFile(SgFile *file, const char *fin_name, const set<string
if (needToGen) if (needToGen)
{ {
string name = array->GetShortName(); string shadowSpecInsert = "!DVM$ SHADOW " + array->GetShortName() + "(";
if (array->GetLocation().first == DIST::l_COMMON)
{
auto symb = array->GetDeclSymbol(make_pair(st->fileName(), st->lineNumber()));
name = symb->identifier();
}
string shadowSpecInsert = "!DVM$ SHADOW " + name + "(";
for (int k = 0; k < currSpec.size(); ++k) for (int k = 0; k < currSpec.size(); ++k)
{ {
char buf[256]; char buf[256];
@@ -2181,7 +2157,7 @@ void insertShadowSpecToFile(SgFile *file, const char *fin_name, const set<string
shadowSpecInsert += ")\n"; shadowSpecInsert += ")\n";
shadowsSpecsString.push_back(shadowSpecInsert); shadowsSpecsString.push_back(shadowSpecInsert);
pair<SgExpression*, SgExpression*> newSpec = genShadowSpec(file, make_pair(name, currSpec)); pair<SgExpression*, SgExpression*> newSpec = genShadowSpec(file, make_pair(array->GetShortName(), currSpec));
if (newSpec.first == NULL || newSpec.second == NULL) if (newSpec.first == NULL || newSpec.second == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
shadowsSpecs.push_back(newSpec); shadowsSpecs.push_back(newSpec);

View File

@@ -26,7 +26,6 @@ using std::string;
using std::vector; using std::vector;
using std::pair; using std::pair;
using std::make_pair; using std::make_pair;
using SAPFOR::CFG_Settings;
extern int debSh; extern int debSh;
@@ -1673,12 +1672,9 @@ void GroupShadow(const map<string, vector<FuncInfo*>>& allFuncs,
SgStatement* func = currF->funcPointer->GetOriginal(); SgStatement* func = currF->funcPointer->GetOriginal();
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop, CFG_Settings::CFG_withDVM, auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, true, false, true, false), commonBlocks, allFuncs);
CFG_Settings::CFG_withCallsInBlocks, CFG_Settings::CFG_withUnreachable });
auto cfg = buildCFGforCurrentFunc(func, settings, commonBlocks, allFuncs);
if (cfg.size() != 1) if (cfg.size() != 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto& blocks = cfg.begin()->second; auto& blocks = cfg.begin()->second;
//create reaching blocks //create reaching blocks

View File

@@ -336,24 +336,9 @@ namespace Distribution
if (pos != STRING::npos) if (pos != STRING::npos)
{ {
name.erase(pos, shortName.size()); name.erase(pos, shortName.size());
name += newName;
}
else if (locationPos.first == l_COMMON) // name of array in common may be different
{
pos = name.rfind("_");
if (pos != STRING::npos)
{
name.erase(pos + 1, shortName.size());
name += newName;
}
else
{
#if __SPF
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
#endif
}
}
shortName = newName; shortName = newName;
name += newName;
}
GenUniqKey(); GenUniqKey();
} }
@@ -557,44 +542,6 @@ namespace Distribution
return NULL; return NULL;
} }
Symbol* GetDeclSymbol(const PAIR<STRING, int>& position_decl) const
{
if (!IsArray() || locationPos.first != l_COMMON)
return declSymbol;
auto it = declPlacesSymbol.find(position_decl);
if (it != declPlacesSymbol.end())
return it->second;
else // find nearest
{
MAP<PAIR<STRING, int>, Symbol*> currFile;
for (auto& [position, symb] : declPlacesSymbol)
{
if (position.first == position_decl.first)
currFile[position] = symb;
}
PAIR<int, Symbol*> nearest = { (int)0, NULL };
const int needed_pos = position_decl.second;
for (auto& [position, symb] : currFile)
{
if (nearest.second == NULL)
nearest = { abs(position.second - needed_pos), symb };
if (abs(position.second - needed_pos) < nearest.first)
nearest = { abs(position.second - needed_pos), symb };
}
if (nearest.second)
return nearest.second;
#if __SPF
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
#endif
}
return NULL;
}
Symbol* GetDeclSymbol() const { return declSymbol; } Symbol* GetDeclSymbol() const { return declSymbol; }
void SetDeclSymbol(Symbol *s) { declSymbol = s; } void SetDeclSymbol(Symbol *s) { declSymbol = s; }

View File

@@ -33,7 +33,6 @@ using std::set;
using std::ofstream; using std::ofstream;
using std::pair; using std::pair;
using std::tuple; using std::tuple;
using SAPFOR::CFG_Settings;
using json = nlohmann::json; using json = nlohmann::json;
@@ -508,8 +507,7 @@ static void parallelDir(const map<DIST::Array*, int>& byPos, SgExpression* spec,
if (currF == NULL) if (currF == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop, CFG_Settings::CFG_withSPF, CFG_Settings::CFG_withDominators }); auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, true, false, false, true), commonBlocks, allFuncInfo);
auto cfg = buildCFGforCurrentFunc(func, settings, commonBlocks, allFuncInfo);
//TODO IP analysis //TODO IP analysis
unsigned countOfAccess = 0; unsigned countOfAccess = 0;

View File

@@ -1,4 +1,3 @@
#include <algorithm>
#include <map> #include <map>
#include <unordered_set> #include <unordered_set>
#include <unordered_map> #include <unordered_map>
@@ -17,8 +16,6 @@
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;
@@ -52,81 +49,41 @@ static void Collapse(Region* region)
if (region->getBasickBlocks().empty()) if (region->getBasickBlocks().empty())
return; return;
bool firstRegion = true; for (auto& [arrayName, arrayRanges] : region->getHeader()->array_out)
for (Region* basickBlock : region->getBasickBlocks())
{ {
if (basickBlock->getNextRegions().empty()) for (Region* byBlock : region->getBasickBlocks())
{ {
if (firstRegion) AccessingSet intersection = byBlock->array_def[arrayName].Intersect(arrayRanges);
{ 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& instruction : byBlock->instructions) for (auto& [arrayName, arrayRanges] : byBlock->array_use)
{ {
for (auto& [arrayName, _] : instruction.use) AccessingSet diff = byBlock->array_use[arrayName].Diff(byBlock->array_in[arrayName]);
{
AccessingSet diff = instruction.use[arrayName].Diff(instruction.in[arrayName]);
region->array_use[arrayName] = region->array_use[arrayName].Union(diff); region->array_use[arrayName] = region->array_use[arrayName].Union(diff);
} }
} }
}
ArrayAccessingIndexes useUnionB; ArrayAccessingIndexes useUnion;
for (auto& byBlock : region->getBasickBlocks()) for (auto& byBlock : region->getBasickBlocks())
for (auto& instruction : byBlock->instructions) for (auto& [arrayName, arrayRanges] : byBlock->array_use)
for (auto& [arrayName, _] : instruction.use) useUnion[arrayName] = useUnion[arrayName].Union(byBlock->array_use[arrayName]);
useUnionB[arrayName] = useUnionB[arrayName].Union(instruction.use[arrayName]);
for (auto& [arrayName, _] : useUnionB) region->array_priv = region->array_use;
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)
{ {
auto blocks = DFG->getBasickBlocks(); unordered_set<Region*> worklist(DFG->getBasickBlocks());
std::unordered_set<Region*> worklist(blocks.begin(), blocks.end());
do do
{ {
Region* b = *worklist.begin(); Region* b = *worklist.begin();
@@ -144,7 +101,7 @@ static void SolveDataFlowIteratively(Region* DFG)
if (prevBlock->array_out.empty()) if (prevBlock->array_out.empty())
{ {
newIn.clear(); newIn.clear();
break; continue;
} }
for (const auto& [arrayName, accessSet] : prevBlock->array_out) for (const auto& [arrayName, accessSet] : prevBlock->array_out)
@@ -180,153 +137,21 @@ 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);
@@ -336,8 +161,6 @@ 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())
@@ -365,12 +188,12 @@ 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)
{ {

View File

@@ -132,10 +132,8 @@ 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()) if (firstElement.empty() || secondElement.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;
@@ -190,7 +188,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
@@ -254,15 +252,13 @@ AccessingSet AccessingSet::Diff(const AccessingSet& secondSet) const
return *this; return *this;
AccessingSet intersection = this->Intersect(secondSet); AccessingSet intersection = this->Intersect(secondSet);
vector<vector<ArrayDimension>> uncovered; AccessingSet uncovered = *this;
for (const auto& element : allElements) vector<vector<ArrayDimension>> result;
for (const auto& element : intersection.GetElements())
{ {
vector<vector<ArrayDimension>> current_uncovered; vector<vector<ArrayDimension>> current_uncovered;
intersection.FindUncovered(element, current_uncovered); uncovered.FindUncovered(element, current_uncovered);
uncovered.insert(uncovered.end(), uncovered = AccessingSet(current_uncovered);
std::move_iterator(current_uncovered.begin()),
std::move_iterator(current_uncovered.end())
);
} }
return uncovered; return uncovered;
} }

View File

@@ -1,4 +1,3 @@
#include <algorithm>
#include<vector> #include<vector>
#include<map> #include<map>
#include<unordered_set> #include<unordered_set>
@@ -10,7 +9,6 @@
#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;
@@ -95,7 +93,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, Region* region) { static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAccessingIndexes& def, ArrayAccessingIndexes& use) {
auto instructions = block->getInstructions(); auto instructions = block->getInstructions();
map<string, LoopGraph*> loopForIndex; map<string, LoopGraph*> loopForIndex;
BuildLoopIndex(loopForIndex, loop); BuildLoopIndex(loopForIndex, loop);
@@ -125,11 +123,7 @@ 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 });
}
} }
} }
} }
@@ -154,21 +148,7 @@ 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;
vector<pair<int, int>> coeffsForDims; while (!index_vars.empty() && !refPos.empty())
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();
@@ -200,7 +180,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
return -1; return -1;
} }
uint64_t start = coeffsForDims.back().second * currentLoop->startVal + coeffsForDims.back().first; uint64_t start = currentLoop->startVal;
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 };
@@ -213,29 +193,14 @@ 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
{
instruction.use[array_name] = { { accessPoint } };
if (def.find(array_name) == def.end())
use[array_name].Insert(accessPoint); 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);
} }
} }
} }
@@ -243,41 +208,6 @@ 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)
@@ -292,11 +222,10 @@ static void SetConnections(unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegi
} }
} }
static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, unordered_map<SAPFOR::BasicBlock*, Region*>& bbToRegion) static Region* CreateSubRegion(LoopGraph* loop, const vector<SAPFOR::BasicBlock*>& Blocks, const 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
@@ -315,7 +244,6 @@ 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;
} }
@@ -326,13 +254,12 @@ 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.push_back(bbToRegion[poiner]); this->basickBlocks.insert(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);
} }
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)
{ {
@@ -340,5 +267,4 @@ 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,11 +8,6 @@
#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; }
@@ -25,25 +20,13 @@ public:
void setHeader(Region* region) { header = region; } void setHeader(Region* region) { header = region; }
std::vector<Region*>& getBasickBlocks() { return basickBlocks; } std::unordered_set<Region*>& getBasickBlocks() { return basickBlocks; }
void addBasickBlocks(Region* region) { basickBlocks.push_back(region); } void addBasickBlocks(Region* region) { basickBlocks.insert(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); }
@@ -65,18 +48,13 @@ 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::vector<Region*> basickBlocks; std::unordered_set<Region*> subRegions, 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

@@ -1893,7 +1893,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
findParameters(parametersOfProject, fullIR, declaredArrays); findParameters(parametersOfProject, fullIR, declaredArrays);
else if (curr_regime == BUILD_IR) else if (curr_regime == BUILD_IR)
{ {
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings()); auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
for (auto& byFunc : CFG_forFile) for (auto& byFunc : CFG_forFile)
fullIR[byFunc.first].insert(fullIR[byFunc.first].end(), byFunc.second.begin(), byFunc.second.end()); fullIR[byFunc.first].insert(fullIR[byFunc.first].end(), byFunc.second.begin(), byFunc.second.end());
@@ -2524,8 +2524,8 @@ int main(int argc, char **argv)
out_free_form = 1; out_free_form = 1;
out_line_unlimit = 1; out_line_unlimit = 1;
} }
/*else if (string(curr_arg) == "-sh") else if (string(curr_arg) == "-sh")
staticShadowAnalysis = 1;*/ staticShadowAnalysis = 1;
else if (string(curr_arg) == "-shWidth") else if (string(curr_arg) == "-shWidth")
{ {
i++; i++;

View File

@@ -19,7 +19,7 @@
extern std::map<std::string, std::string> shortFileNames; extern std::map<std::string, std::string> shortFileNames;
static int activeState = 0; static int activeState = 0;
int staticShadowAnalysis = 1; int staticShadowAnalysis = 0;
int staticPrivateAnalysis = 0; int staticPrivateAnalysis = 0;
int keepDvmDirectives = 0; int keepDvmDirectives = 0;
int keepFiles = 0; int keepFiles = 0;

View File

@@ -12,7 +12,6 @@ using std::map;
using std::string; using std::string;
using std::vector; using std::vector;
using std::set; using std::set;
using SAPFOR::CFG_Settings;
using std::remove_if; using std::remove_if;
@@ -425,8 +424,7 @@ int removeDeadCode(SgStatement* func,
if (intervalDelEnd->lineNumber() < prog->lineNumber() || intervalDelEnd->lineNumber() > prog->lastNodeOfStmt()->lineNumber()) if (intervalDelEnd->lineNumber() < prog->lineNumber() || intervalDelEnd->lineNumber() > prog->lastNodeOfStmt()->lineNumber())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop }); auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, false, false, false, false), commonBlocks, allFuncs);
auto cfg = buildCFGforCurrentFunc(func, settings, commonBlocks, allFuncs);
if(cfg.size() != 1) if(cfg.size() != 1)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);

View File

@@ -18,66 +18,69 @@ 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
//void BuildNewCommDecls static void BuildNewCommDecls(SgFile* file, const map<string, CommonBlock*> allCommonBlocks,
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
//set<string> getUses static set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNames);
//void getUsesFromExpr static void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarNames, set<string>& used);
// splits arrays into elements and replaces not used vars with empty constraints // splits arrays into elements and replaces not used vars with empty constraints
//bool splitType static bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& namesOfUsedVars);
// create constraits set // create constraits set
//deque<CommConstraint> makeConstraints static deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints, const set<string>& namesOfUsedVars, set<string>& notUsedVars);
// build union // build union
//bool buildConstraintsUnion static bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B, const set<string>& namesOfUsedVars, pair<CommConstraint, CommConstraint>& problemConstraints);
//bool docheckUnequalConstraints static bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>& B, deque<CommConstraint>& newU, pair<CommConstraint, CommConstraint>& problemConstraints);
//bool check static bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommConstraint, CommConstraint>& problemConstraints);
/// small help functions: /// small help functions:
//string getParentName static string getParentName(const string& name);
//bool equalDims static bool equalDims(const CommConstraint& a, const CommConstraint& b);
//bool equalConstraints static bool equalConstraints(const CommConstraint& a, const CommConstraint& b);
//void addElem static void addElem(deque<CommConstraint>& comm, const CommConstraint& elem);
//////
// change names of variables in 'constraints' // change names of variables in 'constraints'
//void fixNames static void fixNames(deque<CommConstraint>& constraints, const string& commName);
////// 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
//void fixFunctions static 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);
// get pairs of names (namesOldToNew) for renaming // get pairs of names (namesOldToNew) for renaming
//bool getNamesOldToNew static bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDecl, map<string, string>& namesOldToNew);
// create new symbols for new variables in new common declaration (constraints) // create new symbols for new variables in new common declaration (constraints)
//void makeCommVarSymbs static void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* file, SgStatement* func, string commName,
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
//void deleteOldVars static void deleteOldVars(SgStatement* firstSt, const set<string>& commVarNames);
// calls fixExpression for each statement, replaces names in data statement // calls fixExpression for each statement, replaces names in data statement
//void renameVariables static void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>& newVarSymbs, const map<string, string>& namesOldToNew);
// 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
//SgExpression* fixExpression static SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbol*>& newSymbs, const map<string, string>& namesOldToNew);
// make new exprList exprssion for new declaration decl with symbols from newSymbs // make new exprList exprssion for new declaration decl with symbols from newSymbs
//SgExpression* makeExprListForCommon static SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, const map<string, SgSymbol*>& newSymbs,
SgFile* file, SgStatement* firstSt);
// replace old common declarations with new ones // replace old common declarations with new ones
//void rewriteCommon static void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& commListExprs);
/// help functions: /// help functions:
//SgExpression* makeIdxFromStr(const string& str); static SgExpression* makeIdxFromStr(const string& str);
// make new expression of array element // make new expression of array element
//SgExpression* newArrElemExpr static SgExpression* newArrElemExpr(const string& newName, const map<string, SgSymbol*>& newSymbs);
//bool variablePositionComp static bool variablePositionComp(const Variable* lhs, const Variable* rhs);
////// //////
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;
@@ -122,6 +125,7 @@ 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();
@@ -135,7 +139,8 @@ 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("(");
@@ -149,7 +154,8 @@ static 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;
@@ -188,7 +194,8 @@ static void getUsesFromExpr(SgExpression* expr, const set<string>& commonVarName
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();
@@ -205,7 +212,8 @@ static set<string> getUses(SgStatement* firstSt, const set<string>& commonVarNam
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();
@@ -216,12 +224,11 @@ static bool equalDims(const CommConstraint& a, const CommConstraint& b)
if (adim[i].second - adim[i].first != bdim[i].second - bdim[i].first) if (adim[i].second - adim[i].first != bdim[i].second - bdim[i].first)
return false; return false;
} }
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
static bool equalConstraints(const CommConstraint& a, const CommConstraint& b) 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;
@@ -232,7 +239,8 @@ static 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;
@@ -240,8 +248,9 @@ static 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
static bool splitType(deque<CommConstraint>& d, bool check_use, const set<string>& namesOfUsedVars = {}) 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;
@@ -289,7 +298,8 @@ static bool splitType(deque<CommConstraint>& d, bool check_use, const set<string
} }
} }
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())
@@ -306,7 +316,8 @@ static deque<CommConstraint> makeConstraints(deque<CommConstraint>& constraints,
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())
{ {
@@ -345,8 +356,8 @@ static bool check(deque<CommConstraint>& A, deque<CommConstraint>& B, pair<CommC
return true; return true;
} }
static bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>& B, deque<CommConstraint>& newU,
pair<CommConstraint, CommConstraint>& problemConstraints) bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstraint>& B, deque<CommConstraint>& newU, pair<CommConstraint, CommConstraint>& problemConstraints)
{ {
if (U.front().typeVariant == 0) if (U.front().typeVariant == 0)
{ {
@@ -369,8 +380,8 @@ static bool docheckUnequalConstraints(deque<CommConstraint>& U, deque<CommConstr
return true; return true;
} }
static bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B,
const set<string>& namesOfUsedVars, pair<CommConstraint, CommConstraint>& problemConstraints) bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint> B, const set<string>& namesOfUsedVars, pair<CommConstraint, CommConstraint>& problemConstraints)
{ {
deque<CommConstraint> newU; deque<CommConstraint> newU;
while (!U.empty() && !B.empty()) while (!U.empty() && !B.empty())
@@ -425,8 +436,8 @@ static bool buildConstraintsUnion(deque<CommConstraint>& U, deque<CommConstraint
return true; return true;
} }
//TODO: check this: newDecl and oldDecl => do these variables need references?
static bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint> oldDecl, map<string, string>& namesOldToNew) 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;
@@ -491,17 +502,15 @@ static bool getNamesOldToNew(deque<CommConstraint> newDecl, deque<CommConstraint
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)
@@ -515,7 +524,8 @@ static void makeCommVarSymbs(const deque<CommConstraint>& constraints, SgFile* f
} }
} }
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;
@@ -561,12 +571,12 @@ static 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;
@@ -581,13 +591,13 @@ static 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)));
@@ -595,11 +605,11 @@ static SgExpression* newArrElemExpr(const string& newName, const map<string, SgS
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();
@@ -635,18 +645,17 @@ static SgExpression* fixExpression(SgExpression* expr, const map<string, SgSymbo
} }
} }
} }
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())
@@ -694,7 +703,8 @@ static void renameVariables(SgStatement* firstSt, const map<string, SgSymbol*>&
} }
} }
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;
@@ -728,7 +738,8 @@ static SgExpression* makeExprListForCommon(const deque<CommConstraint>& decl, co
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())
@@ -779,12 +790,12 @@ static void rewriteCommon(SgStatement* firstSt, map<string, SgExpression*>& comm
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)
{ {
@@ -799,12 +810,14 @@ static 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)
@@ -812,13 +825,11 @@ static void fixFunctions(SgFile* file, const vector<SgStatement*>& 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;
@@ -829,11 +840,9 @@ static void fixFunctions(SgFile* file, const vector<SgStatement*>& programUnits,
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)
@@ -847,7 +856,8 @@ static void fixFunctions(SgFile* file, const vector<SgStatement*>& programUnits,
} }
} }
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)
{ {
@@ -888,8 +898,7 @@ static void buildNewCommDecls(SgFile* file, const map<string, CommonBlock*>& all
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", __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);
commName.c_str(), fileName.c_str(), constraints.back().uses.back().getLineNum());
if (hasChar) if (hasChar)
{ {
badCommon.insert(commName); badCommon.insert(commName);
@@ -906,7 +915,7 @@ static void buildNewCommDecls(SgFile* file, const map<string, CommonBlock*>& all
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.getVarName(), y.getVarName(), commName.c_str(), x.getFileName(), x.getLineNum(), y.getFileName(), y.getLineNum()); x.varName.c_str(), y.varName.c_str(), commName.c_str(), x.fileName.c_str(), x.lineNum, y.fileName.c_str(), y.lineNum);
} }
} }
curSt = curSt->lastNodeOfStmt(); curSt = curSt->lastNodeOfStmt();
@@ -918,7 +927,7 @@ static void buildNewCommDecls(SgFile* file, const map<string, CommonBlock*>& all
// 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
@@ -932,12 +941,10 @@ void fixCommonBlocks(const map<string, vector<FuncInfo*>>& allFuncInfo, const ma
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,18 +16,12 @@
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
@@ -48,4 +42,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

@@ -19,7 +19,6 @@ using std::pair;
using std::make_pair; using std::make_pair;
using std::wstring; using std::wstring;
using std::stack; using std::stack;
using SAPFOR::CFG_Settings;
#define PRINT_SPLITTED_FRAGMENTS 0 #define PRINT_SPLITTED_FRAGMENTS 0
@@ -316,7 +315,7 @@ static map<SgStatement*, pair<set<SgStatement*>, set<SgStatement*>>>
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
map<SAPFOR::Argument*, set<int>> outForCurr; map<SAPFOR::Argument*, set<int>> outForCurr;
buildGenKillForCFG(itCFG->second, funcByName, outForFunc, gen, kill, &genForIR, &killForIR, notInitedGlobals, SAPFOR::CFG_Settings()); buildGenKillForCFG(itCFG->second, funcByName, outForFunc, gen, kill, &genForIR, &killForIR, notInitedGlobals, SAPFOR::CFG_Settings(0));
if (outForFunc.count(byFunc)) if (outForFunc.count(byFunc))
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1052,8 +1051,7 @@ int splitLoops(SgFile *file, vector<LoopGraph*> &loopGraphs, vector<Messages> &m
checkNull(listExp, convertFileName(__FILE__).c_str(), __LINE__); checkNull(listExp, convertFileName(__FILE__).c_str(), __LINE__);
int deep = listExp->length(); int deep = listExp->length();
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop, CFG_Settings::CFG_withRD, CFG_Settings::CFG_withCallFrom, CFG_Settings::CFG_withDominators }); currIR = buildCFGforCurrentFunc(loop->loop, SAPFOR::CFG_Settings(true, true), commonBlocks, allFuncInfo);
currIR = buildCFGforCurrentFunc(loop->loop, settings, commonBlocks, allFuncInfo);
totalErr = splitLoop(loop, messages, deep, depInfoForLoopGraph); totalErr = splitLoop(loop, messages, deep, depInfoForLoopGraph);
if (totalErr > 0) if (totalErr > 0)

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,6 @@ using std::set;
using std::string; using std::string;
using std::vector; using std::vector;
using std::wstring; using std::wstring;
using SAPFOR::CFG_Settings;
using CFG_Type = map<FuncInfo*, vector<SAPFOR::BasicBlock*>>; using CFG_Type = map<FuncInfo*, vector<SAPFOR::BasicBlock*>>;
using UsersDirectives = map<pair<string, int>, set<SgStatement*>>; using UsersDirectives = map<pair<string, int>, set<SgStatement*>>;
@@ -2208,8 +2207,8 @@ static void removePrivateAnalyze(Context *ctx)
makeDeclaration(ctx->loopStmt, vector<SgSymbol*> {receiverVar}, nullptr) makeDeclaration(ctx->loopStmt, vector<SgSymbol*> {receiverVar}, nullptr)
)); ));
const auto settings = CFG_Settings({ CFG_Settings::CFG_atLeastOneIterInLoop, CFG_Settings::CFG_withRD, CFG_Settings::CFG_withCallFrom, CFG_Settings::CFG_withDominators }); CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(ctx->loopStmt,
CFG_Type CFG_ForFunc = buildCFGforCurrentFunc(ctx->loopStmt, settings, SAPFOR::CFG_Settings(true, true),
ctx->commonBlocks, ctx->allFuncInfo); ctx->commonBlocks, ctx->allFuncInfo);
if (CFG_ForFunc.empty()) if (CFG_ForFunc.empty())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);

View File

@@ -206,9 +206,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
Pass(DEF_USE_STAGE1) <= Pass(DEF_USE_STAGE2); Pass(DEF_USE_STAGE1) <= Pass(DEF_USE_STAGE2);
list({ VERIFY_DVM_DIRS, VERIFY_COMMON, FILL_COMMON_BLOCKS, PRIVATE_CALL_GRAPH_STAGE1, PRIVATE_CALL_GRAPH_STAGE2, MACRO_EXPANSION, CONVERT_ASSIGN_TO_LOOP, DEF_USE_STAGE1, DEF_USE_STAGE2, FILL_PARALLEL_REG_IR, CALL_GRAPH_IR }) <= list({ SUBST_EXPR, SUBST_EXPR_RD, BUILD_IR }); list({ VERIFY_DVM_DIRS, PRIVATE_CALL_GRAPH_STAGE1, PRIVATE_CALL_GRAPH_STAGE2, MACRO_EXPANSION, CONVERT_ASSIGN_TO_LOOP, DEF_USE_STAGE1, DEF_USE_STAGE2, FILL_PARALLEL_REG_IR, VERIFY_COMMON, FILL_COMMON_BLOCKS, CALL_GRAPH_IR }) <= list({ SUBST_EXPR, SUBST_EXPR_RD, BUILD_IR });
Pass(VERIFY_COMMON) <= Pass(FILL_COMMON_BLOCKS);
Pass(BUILD_IR) <= Pass(SUBST_EXPR) <= Pass(SUBST_EXPR_AND_UNPARSE); Pass(BUILD_IR) <= Pass(SUBST_EXPR) <= Pass(SUBST_EXPR_AND_UNPARSE);
@@ -219,7 +217,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
Pass(RESTORE_LOOP_FROM_ASSIGN) <= list({ SUBST_EXPR_AND_UNPARSE, SUBST_EXPR_RD_AND_UNPARSE }); Pass(RESTORE_LOOP_FROM_ASSIGN) <= list({ SUBST_EXPR_AND_UNPARSE, SUBST_EXPR_RD_AND_UNPARSE });
Pass(FILL_COMMON_BLOCKS) <= Pass(GET_ALL_ARRAY_DECL) <= list({ CALL_GRAPH_IR, INSERT_NO_DISTR_FLAGS_FROM_GUI }); Pass(GET_ALL_ARRAY_DECL) <= list({ CALL_GRAPH_IR, INSERT_NO_DISTR_FLAGS_FROM_GUI });
Pass(LOOP_GRAPH) <= Pass(PRIVATE_CALL_GRAPH_STAGE3) <= list(FIND_FUNC_TO_INCLUDE, PRIVATE_ANALYSIS_IR) <= list({ LOOP_ANALYZER_DATA_DIST_S0, LOOP_ANALYZER_DATA_DIST_S1, ONLY_ARRAY_GRAPH, LOOP_ANALYZER_ALIGNS }); Pass(LOOP_GRAPH) <= Pass(PRIVATE_CALL_GRAPH_STAGE3) <= list(FIND_FUNC_TO_INCLUDE, PRIVATE_ANALYSIS_IR) <= list({ LOOP_ANALYZER_DATA_DIST_S0, LOOP_ANALYZER_DATA_DIST_S1, ONLY_ARRAY_GRAPH, LOOP_ANALYZER_ALIGNS });
@@ -229,7 +227,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_SPF, PREPROC_ALLOCATES, GET_ALL_ARRAY_DECL, GCOV_PARSER }) <= list({ CALL_GRAPH, MACRO_EXPANSION, DEF_USE_STAGE1 }); list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_SPF, PREPROC_ALLOCATES, GET_ALL_ARRAY_DECL, GCOV_PARSER }) <= list({ CALL_GRAPH, MACRO_EXPANSION, DEF_USE_STAGE1 });
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ FILL_COMMON_BLOCKS, GET_ALL_ARRAY_DECL, PARSE_OMP_DIRS }) <= Pass(PREPROC_SPF); list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ GET_ALL_ARRAY_DECL, FILL_COMMON_BLOCKS, PARSE_OMP_DIRS }) <= Pass(PREPROC_SPF);
Pass(CHECK_PAR_REG_DIR) <= Pass(FILL_PARALLEL_REG_IR); Pass(CHECK_PAR_REG_DIR) <= Pass(FILL_PARALLEL_REG_IR);

View File

@@ -934,14 +934,8 @@ void fillNonDistrArraysAsPrivate(SgStatement *st,
{ {
auto itD = declaredArrays.find(*itSet); auto itD = declaredArrays.find(*itSet);
if (itD != declaredArrays.end()) if (itD != declaredArrays.end())
{ if (itD->second.first->IsNotDistribute())
const auto array = itD->second.first; privatesVars.insert(itD->second.first->GetShortName());
if (array->IsNotDistribute())
{
auto symb = array->GetDeclSymbol(make_pair(st->fileName(), st->lineNumber()));
privatesVars.insert(symb->identifier());
}
}
} }
} }
} }
@@ -960,20 +954,8 @@ DIST::Array* getArrayFromDeclarated(SgStatement *st, const string &arrayName)
{ {
auto itD = declaredArrays.find(*itSet); auto itD = declaredArrays.find(*itSet);
if (itD != declaredArrays.end()) if (itD != declaredArrays.end())
{ if (itD->second.first->GetShortName() == arrayName)
DIST::Array* array = itD->second.first; found = itD->second.first;
if (array->GetLocation().first == DIST::l_COMMON)
{
auto symb = array->GetDeclSymbol(make_pair(st->fileName(), st->lineNumber()));
if (symb && symb->identifier() == arrayName)
found = array;
}
else
{
if (array->GetShortName() == arrayName)
found = array;
}
}
} }
} }
return found; return found;
@@ -1282,32 +1264,6 @@ static SgExpression* isInCommon(const vector<SgExpression*> &commonBlocks, const
return NULL; return NULL;
} }
//all common block in project
extern map<string, CommonBlock*> commonBlocks;
static string getCommonNameOnPos(const string& name, const int commonPos)
{
if (commonBlocks.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto it = commonBlocks.find(name);
if (it == commonBlocks.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto inPos = it->second->getGroupedVars().find(commonPos);
if (inPos == it->second->getGroupedVars().end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
set<string> namesOnPos;
for (auto& var : inPos->second)
namesOnPos.insert(var->getName());
if (namesOnPos.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return *namesOnPos.begin();
}
static map<tuple<string, string, int>, tuple<int, string, string>> tableOfUniqNames; static map<tuple<string, string, int>, tuple<int, string, string>> tableOfUniqNames;
tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>> &commonBlocks, SgStatement *decl, SgSymbol *symb) tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>> &commonBlocks, SgStatement *decl, SgSymbol *symb)
{ {
@@ -1316,7 +1272,6 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
int commonPos = 0; int commonPos = 0;
SgExpression *foundCommon = NULL; SgExpression *foundCommon = NULL;
string symbCommn = "";
SgStatement *declCP = decl->controlParent(); SgStatement *declCP = decl->controlParent();
// find symbol in parameter list of functions // find symbol in parameter list of functions
@@ -1352,7 +1307,6 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
if (foundCommon) if (foundCommon)
{ {
inCommon = true; inCommon = true;
symbCommn = getCommonNameOnPos(common.first, commonPos);
break; break;
} }
} }
@@ -1360,7 +1314,7 @@ tuple<int, string, string> getUniqName(const map<string, vector<SgExpression*>>
tuple<int, string, string> retVal; tuple<int, string, string> retVal;
if (inCommon) if (inCommon)
retVal = make_tuple(commonPos, string("common_") + getCommonName(foundCommon), symbCommn); retVal = make_tuple(commonPos, string("common_") + getCommonName(foundCommon), string(symb->identifier()));
else else
retVal = make_tuple(decl->lineNumber(), string(decl->fileName()), string(symb->identifier())); retVal = make_tuple(decl->lineNumber(), string(decl->fileName()), string(symb->identifier()));

View File

@@ -337,15 +337,10 @@ const set<SgSymbol*>& getModuleSymbols(SgStatement *func)
//if function or module in contains //if function or module in contains
auto cp = func->controlParent(); auto cp = func->controlParent();
if (isSgProgHedrStmt(cp) || cp->variant() == MODULE_STMT) if (isSgProgHedrStmt(cp) || cp->variant() == MODULE_STMT)
{
getModuleSymbols(cp, symbs); getModuleSymbols(cp, symbs);
if (func->variant() == FUNC_HEDR)
symbs.insert(func->symbol());
}
symbolsForFunc[func->symbol()->identifier()] = symbs; symbolsForFunc[func->symbol()->identifier()] = symbs;
return symbolsForFunc[func->symbol()->identifier()]; return symbs;
} }
static void findSymbol(SgStatement* func, const string& varName, const string& locName, static void findSymbol(SgStatement* func, const string& varName, const string& locName,
@@ -354,21 +349,11 @@ static void findSymbol(SgStatement* func, const string& varName, const string& l
for (const auto& s : getModuleSymbols(func)) for (const auto& s : getModuleSymbols(func))
{ {
SgSymbol* orig = OriginalSymbol(s); SgSymbol* orig = OriginalSymbol(s);
printf("%s == %s\n", orig->identifier(), s->identifier());
//any suitable symbol can be used //any suitable symbol can be used
if (orig->variant() == FUNCTION_NAME)
{
if (orig->identifier() == varName)
altNames[s->identifier()] = s;
}
else
{
if (orig->identifier() == varName && orig->scope()->symbol()->identifier() == locName) if (orig->identifier() == varName && orig->scope()->symbol()->identifier() == locName)
altNames[s->identifier()] = s; altNames[s->identifier()] = s;
} }
} }
}
SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const string& locName) SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const string& locName)
{ {
@@ -384,7 +369,6 @@ SgSymbol* getNameInLocation(SgStatement* func, const string& varName, const stri
return altNames.begin()->second; return altNames.begin()->second;
else { else {
__spf_print(1, "%s (%s %s) %s\n", func->symbol()->identifier(), clearName.c_str(), varName.c_str(), locName.c_str()); __spf_print(1, "%s (%s %s) %s\n", func->symbol()->identifier(), clearName.c_str(), varName.c_str(), locName.c_str());
findSymbol(func, varName, locName, altNames);
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
} }

View File

@@ -569,8 +569,8 @@ void copyIncludes(const set<string> &allIncludeFiles, const map<string, map<int,
while (!feof(oldFile)) while (!feof(oldFile))
{ {
char buf[16384]; char buf[8192];
char *res = fgets(buf, sizeof(buf), oldFile); char *res = fgets(buf, 16384, oldFile);
if (res == NULL) if (res == NULL)
break; break;

View File

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

View File

@@ -152,7 +152,7 @@ static void setOptions(const short* options, bool isBuildParallel = false, const
intOptions[z] = -1; intOptions[z] = -1;
} }
//staticShadowAnalysis = intOptions[STATIC_SHADOW_ANALYSIS]; staticShadowAnalysis = intOptions[STATIC_SHADOW_ANALYSIS];
staticPrivateAnalysis = intOptions[STATIC_PRIVATE_ANALYSIS]; staticPrivateAnalysis = intOptions[STATIC_PRIVATE_ANALYSIS];
out_free_form = intOptions[FREE_FORM]; out_free_form = intOptions[FREE_FORM];
if (out_free_form == 1) if (out_free_form == 1)