Compare commits
111 Commits
a7764847c4
...
analyze_lo
| Author | SHA1 | Date | |
|---|---|---|---|
| 37ebeee97a | |||
| 2d47b8533b | |||
|
|
b8f429256f | ||
| 2fd08e79f1 | |||
|
|
2f53d6ae2e | ||
|
|
65237e4d63 | ||
| 2af6d9c140 | |||
| 375070f959 | |||
| 31715a46d0 | |||
|
|
7533739488 | ||
| c1d31b809b | |||
| 537f3eb6e9 | |||
| f5f99f6e8a | |||
|
|
fc47a1685c | ||
| 383d8df826 | |||
| ebc5a1cbc1 | |||
|
|
0eee799867 | ||
|
|
50dd54cec1 | ||
|
|
6a59bc0e09 | ||
|
|
9e777ceeab | ||
|
|
10636427ed | ||
|
|
a0704038db | ||
| 623f6c0d73 | |||
|
|
622159cba6 | ||
|
|
db26a2c332 | ||
|
|
8ad19cbfa5 | ||
|
|
1895a4b02a | ||
|
|
623898d913 | ||
|
|
a96a4bcaa6 | ||
| ae9cc2bf3b | |||
| c6a0c73287 | |||
|
|
ef6d7fb70f | ||
|
|
c7c46cd159 | ||
|
|
c842630ec2 | ||
|
|
2969f92013 | ||
|
|
b13b0a0f57 | ||
|
|
06dd8848be | ||
| bed098b345 | |||
| f322306344 | |||
| f7c66f537d | |||
| b454858647 | |||
|
|
ad99446b12 | ||
|
|
d3e8c481d2 | ||
| 4e16638c36 | |||
| 6742932862 | |||
| 8b2e59356a | |||
| f9d52c0c3e | |||
| 537d60222f | |||
| 4eb057731f | |||
| 267f85ae27 | |||
| b137ea5ef3 | |||
| 6a84171382 | |||
| cd209a587a | |||
|
|
0b0d7d373b | ||
|
|
781a892497 | ||
|
|
a55440c071 | ||
|
|
996f7ead1b | ||
|
|
5231eeacd8 | ||
|
|
7460cf6e59 | ||
|
|
5596b57021 | ||
| 3ad972c188 | |||
| dde0bcdee5 | |||
| 65cdbef201 | |||
| 2ad239d1e3 | |||
| 12f311077b | |||
|
|
a2e0a99891 | ||
| 27a350dac0 | |||
| 3c1032bfd0 | |||
| 189374274e | |||
| de4690513b | |||
| 86ab34e7f3 | |||
| 06cfe83666 | |||
| a3c1e1e5d1 | |||
| 75e89ab868 | |||
| d4fb323f86 | |||
|
|
0c9f0664fd | ||
|
|
90a608230c | ||
|
|
d6df2f6b5f | ||
|
|
90894a4723 | ||
|
|
26fe1d3f61 | ||
|
|
68d2f3253c | ||
|
|
09401376c7 | ||
|
|
a0c8f78868 | ||
|
|
2aa9e569f4 | ||
|
|
9e5ee78b80 | ||
|
|
d5d5514e17 | ||
|
|
68c779790d | ||
|
|
c6b09ad285 | ||
|
|
fd402b6ab0 | ||
|
|
b76753c285 | ||
|
|
44600a50c1 | ||
|
|
d2f5e5fcc1 | ||
|
|
18ac0ae47c | ||
|
|
00b6026761 | ||
|
|
2036fab86f | ||
|
|
da4e992926 | ||
|
|
8e4a4c78ad | ||
| b4038b532f | |||
| dec1a853db | |||
| 7df02737c7 | |||
| d267dc047a | |||
| 12a810ad35 | |||
| 1522dc7f27 | |||
| bd52d5c6ec | |||
| 4ba2bb4c94 | |||
| 60544ea4d6 | |||
|
|
b40e969d02 | ||
| d062e52dd6 | |||
| 392ad97738 | |||
| c2c111586c | |||
| 172eedfef1 |
@@ -228,6 +228,8 @@ set(TRANSFORMS
|
|||||||
|
|
||||||
set(CFG src/CFGraph/IR.cpp
|
set(CFG src/CFGraph/IR.cpp
|
||||||
src/CFGraph/IR.h
|
src/CFGraph/IR.h
|
||||||
|
src/CFGraph/IR_domTree.cpp
|
||||||
|
src/CFGraph/IR_domTree.h
|
||||||
src/CFGraph/CFGraph.cpp
|
src/CFGraph/CFGraph.cpp
|
||||||
src/CFGraph/CFGraph.h
|
src/CFGraph/CFGraph.h
|
||||||
src/CFGraph/RD_subst.cpp
|
src/CFGraph/RD_subst.cpp
|
||||||
@@ -236,14 +238,14 @@ set(CFG src/CFGraph/IR.cpp
|
|||||||
src/CFGraph/live_variable_analysis.h
|
src/CFGraph/live_variable_analysis.h
|
||||||
src/CFGraph/private_variables_analysis.cpp
|
src/CFGraph/private_variables_analysis.cpp
|
||||||
src/CFGraph/private_variables_analysis.h
|
src/CFGraph/private_variables_analysis.h
|
||||||
)
|
src/CFGraph/IR_SSAForm.cpp
|
||||||
|
src/CFGraph/IR_SSAForm.h)
|
||||||
|
|
||||||
set(DATA_FLOW
|
set(DATA_FLOW
|
||||||
src/CFGraph/DataFlow/data_flow.h
|
src/CFGraph/DataFlow/data_flow.h
|
||||||
src/CFGraph/DataFlow/data_flow_impl.h
|
src/CFGraph/DataFlow/data_flow_impl.h
|
||||||
src/CFGraph/DataFlow/backward_data_flow.h
|
src/CFGraph/DataFlow/backward_data_flow.h
|
||||||
src/CFGraph/DataFlow/backward_data_flow_impl.h
|
src/CFGraph/DataFlow/backward_data_flow_impl.h)
|
||||||
)
|
|
||||||
|
|
||||||
set(CREATE_INTER_T src/CreateInterTree/CreateInterTree.cpp
|
set(CREATE_INTER_T src/CreateInterTree/CreateInterTree.cpp
|
||||||
src/CreateInterTree/CreateInterTree.h)
|
src/CreateInterTree/CreateInterTree.h)
|
||||||
@@ -319,7 +321,9 @@ set(GR_LOOP src/GraphLoop/graph_loops_base.cpp
|
|||||||
set(LOOP_ANALYZER src/LoopAnalyzer/allocations_prepoc.cpp
|
set(LOOP_ANALYZER src/LoopAnalyzer/allocations_prepoc.cpp
|
||||||
src/LoopAnalyzer/dep_analyzer.cpp
|
src/LoopAnalyzer/dep_analyzer.cpp
|
||||||
src/LoopAnalyzer/loop_analyzer.cpp
|
src/LoopAnalyzer/loop_analyzer.cpp
|
||||||
src/LoopAnalyzer/loop_analyzer.h)
|
src/LoopAnalyzer/loop_analyzer.h
|
||||||
|
src/LoopAnalyzer/implicit_loops_analyzer.cpp
|
||||||
|
src/LoopAnalyzer/implicit_loops_analyzer.h)
|
||||||
|
|
||||||
set(MAIN src/Sapfor.cpp
|
set(MAIN src/Sapfor.cpp
|
||||||
src/Sapfor.h
|
src/Sapfor.h
|
||||||
|
|||||||
Submodule projects/dvm updated: 3a567d7582...c550423b8e
@@ -50,12 +50,30 @@ BBlock::BasicBlock(const BBlock& copyFrom)
|
|||||||
prev = copyFrom.prev;
|
prev = copyFrom.prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BBlock::addInstruction(IR_Block* item)
|
void BBlock::addInstruction(IR_Block* item, bool pushFront)
|
||||||
{
|
{
|
||||||
|
if (pushFront)
|
||||||
|
instructions.insert(instructions.begin(), item);
|
||||||
|
else
|
||||||
instructions.push_back(item);
|
instructions.push_back(item);
|
||||||
item->setBasicBlock(this);
|
item->setBasicBlock(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BBlock::addInstructionBefore(IR_Block* item, Instruction* before)
|
||||||
|
{
|
||||||
|
checkNull(before, convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
checkNull(item, convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
|
for (auto it = instructions.begin(); it != instructions.end(); ++it) {
|
||||||
|
if ((*it)->getInstruction() == before) {
|
||||||
|
instructions.insert(it, item);
|
||||||
|
item->setBasicBlock(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
int BBlock::removePrev(BBlock* removed)
|
int BBlock::removePrev(BBlock* removed)
|
||||||
{
|
{
|
||||||
auto it = std::remove(prev.begin(), prev.end(), removed);
|
auto it = std::remove(prev.begin(), prev.end(), removed);
|
||||||
@@ -512,7 +530,7 @@ static int buildReachingDefs(const vector<BBlock*>& CFG, const FuncInfo* currF,
|
|||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Kosaraju<EFBFBD>Sharir algorithm
|
//Kosaraju-Sharir algorithm
|
||||||
static vector<int> getStronglyConnectedComps(vector<vector<int>>& g) {
|
static vector<int> getStronglyConnectedComps(vector<vector<int>>& g) {
|
||||||
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
// 1. For each vertex u of the graph, mark u as unvisited. Let l be empty.
|
||||||
auto size = g.size();
|
auto size = g.size();
|
||||||
@@ -1149,9 +1167,22 @@ map<FuncInfo*, vector<BBlock*>> buildCFG(const map<string, CommonBlock*>& common
|
|||||||
if (settings.withRD)
|
if (settings.withRD)
|
||||||
buildReachingDefs(result, settings);
|
buildReachingDefs(result, settings);
|
||||||
|
|
||||||
|
if (settings.withDominators)
|
||||||
|
{
|
||||||
|
auto t = high_resolution_clock::now();
|
||||||
|
for (auto& [func, bblocks] : result)
|
||||||
|
SAPFOR::buildDominatorTree(bblocks);
|
||||||
|
|
||||||
|
auto msec = duration_cast<milliseconds>(high_resolution_clock::now() - t).count();
|
||||||
|
__spf_print(1, " dominator build time is %.3f sec\n", msec / 1000.);
|
||||||
|
}
|
||||||
|
|
||||||
if (SgFile::switchToFile(oldFile) == -1)
|
if (SgFile::switchToFile(oldFile) == -1)
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
|
for (auto& [func, blocks] : result)
|
||||||
|
removedUnreachableBlocks(blocks);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1227,3 +1258,48 @@ map<FuncInfo*, vector<SAPFOR::BasicBlock*>>
|
|||||||
|
|
||||||
return buildCFG(commonBlocks, fileFuncInfoMap, settings);
|
return buildCFG(commonBlocks, fileFuncInfoMap, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void removedUnreachableBlocks(vector<SAPFOR::BasicBlock*>& blocks)
|
||||||
|
{
|
||||||
|
set<SAPFOR::BasicBlock*> reachable;
|
||||||
|
|
||||||
|
for (auto& b : blocks)
|
||||||
|
if (b->getInstructions().front()->isHeader() ||
|
||||||
|
b->getInstructions().front()->getInstruction()->getOperation() == SAPFOR::CFG_OP::ENTRY)
|
||||||
|
reachable.insert(b);
|
||||||
|
|
||||||
|
set<SAPFOR::BasicBlock*> worklist = reachable;
|
||||||
|
while (worklist.size() != 0)
|
||||||
|
{
|
||||||
|
set<SAPFOR::BasicBlock*> to_insert;
|
||||||
|
|
||||||
|
for (auto& b : worklist)
|
||||||
|
for (auto& next : b->getNext())
|
||||||
|
if (reachable.insert(next).second)
|
||||||
|
to_insert.insert(next);
|
||||||
|
|
||||||
|
worklist = to_insert;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto remove_unreachable_it = remove_if(blocks.begin(), blocks.end(),
|
||||||
|
[&reachable](SAPFOR::BasicBlock* b)
|
||||||
|
{
|
||||||
|
if (reachable.find(b) == reachable.end())
|
||||||
|
{
|
||||||
|
for (auto& next : b->getNext())
|
||||||
|
if (reachable.find(next) != reachable.end())
|
||||||
|
next->removePrev(b);
|
||||||
|
|
||||||
|
delete b;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
reachable.clear();
|
||||||
|
|
||||||
|
blocks.erase(remove_unreachable_it, blocks.end());
|
||||||
|
}
|
||||||
@@ -6,6 +6,11 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "IR.h"
|
#include "IR.h"
|
||||||
|
#include "../Utils/errors.h"
|
||||||
|
#include "../Utils/utils.h"
|
||||||
|
#include "../Utils/CommonBlock.h"
|
||||||
|
#include "../GraphCall/graph_calls.h"
|
||||||
|
#include "IR_domTree.h"
|
||||||
|
|
||||||
namespace SAPFOR
|
namespace SAPFOR
|
||||||
{
|
{
|
||||||
@@ -24,7 +29,7 @@ namespace SAPFOR
|
|||||||
|
|
||||||
std::vector<BasicBlock*> next;
|
std::vector<BasicBlock*> next;
|
||||||
std::vector<BasicBlock*> prev;
|
std::vector<BasicBlock*> prev;
|
||||||
|
BasicBlock* directDominator = NULL;
|
||||||
//reaching definition
|
//reaching definition
|
||||||
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
|
std::map<SAPFOR::Argument*, std::set<int>> RD_in, RD_out;
|
||||||
|
|
||||||
@@ -34,14 +39,17 @@ namespace SAPFOR
|
|||||||
bool addLive(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add, bool in);
|
bool addLive(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add, bool in);
|
||||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLive(bool in) const;
|
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLive(bool in) const;
|
||||||
bool removeLive(SAPFOR::Argument* to_remove, bool in);
|
bool removeLive(SAPFOR::Argument* to_remove, bool in);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BasicBlock() { num = lastNumBlock++; }
|
BasicBlock() { num = lastNumBlock++; }
|
||||||
BasicBlock(IR_Block* item);
|
BasicBlock(IR_Block* item);
|
||||||
BasicBlock(const BasicBlock& copyFrom);
|
BasicBlock(const BasicBlock& copyFrom);
|
||||||
|
|
||||||
void addInstruction(IR_Block* item);
|
void addInstructionBefore(IR_Block* item, Instruction* istruction);
|
||||||
|
void addInstruction(IR_Block* item, bool pushFront = false);
|
||||||
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
||||||
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
||||||
|
void setDom(BasicBlock* dom) { directDominator = dom; }
|
||||||
|
|
||||||
int removePrev(BasicBlock* removed);
|
int removePrev(BasicBlock* removed);
|
||||||
int removeNext(BasicBlock* removed);
|
int removeNext(BasicBlock* removed);
|
||||||
@@ -69,6 +77,10 @@ namespace SAPFOR
|
|||||||
const std::vector<IR_Block*>& getInstructions() const { return instructions; }
|
const std::vector<IR_Block*>& getInstructions() const { return instructions; }
|
||||||
const std::vector<BasicBlock*>& getNext() const { return next; }
|
const std::vector<BasicBlock*>& getNext() const { return next; }
|
||||||
const std::vector<BasicBlock*>& getPrev() const { return prev; }
|
const std::vector<BasicBlock*>& getPrev() const { return prev; }
|
||||||
|
BasicBlock* getDom() const
|
||||||
|
{
|
||||||
|
return directDominator;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FOR LIVE ANALYSIS
|
* FOR LIVE ANALYSIS
|
||||||
@@ -105,13 +117,15 @@ namespace SAPFOR
|
|||||||
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 = true;
|
bool withCallFrom = true;
|
||||||
|
bool withDominators = true;
|
||||||
|
|
||||||
explicit CFG_Settings(int) { }
|
explicit CFG_Settings(int) { }
|
||||||
|
|
||||||
explicit CFG_Settings(bool atLeastOneIterInLoop = false, bool withRD = true, bool withRegisters = false,
|
explicit CFG_Settings(bool atLeastOneIterInLoop = false, bool withRD = true, bool withRegisters = false,
|
||||||
bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false, bool withCallFrom = true) :
|
bool withDVM = false, bool withSPF = false, bool withCallsInBlocks = false,
|
||||||
|
bool withCallFrom = true, bool withDominators = true) :
|
||||||
atLeastOneIterInLoop(atLeastOneIterInLoop), withRD(withRD), withRegisters(withRegisters), withDVM(withDVM), withSPF(withSPF),
|
atLeastOneIterInLoop(atLeastOneIterInLoop), withRD(withRD), withRegisters(withRegisters), withDVM(withDVM), withSPF(withSPF),
|
||||||
withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom)
|
withCallsInBlocks(withCallsInBlocks), withCallFrom(withCallFrom), withDominators(withDominators)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -147,3 +161,5 @@ static inline void deleteCFG(std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*
|
|||||||
}
|
}
|
||||||
cfg.clear();
|
cfg.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removedUnreachableBlocks(std::vector<SAPFOR::BasicBlock*>& blocks);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ namespace SAPFOR
|
|||||||
Argument() : number(lastNumArg++), type(CFG_ARG_TYPE::NONE), value(""), mType(CFG_MEM_TYPE::NONE_) { }
|
Argument() : number(lastNumArg++), type(CFG_ARG_TYPE::NONE), value(""), mType(CFG_MEM_TYPE::NONE_) { }
|
||||||
Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType) : number(lastNumArg++), type(type), mType(mType), value("") { }
|
Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType) : number(lastNumArg++), type(type), mType(mType), value("") { }
|
||||||
Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType, const std::string& value) : number(lastNumArg++), type(type), mType(mType), value(value) { }
|
Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType, const std::string& value) : number(lastNumArg++), type(type), mType(mType), value(value) { }
|
||||||
|
Argument(CFG_ARG_TYPE type, CFG_MEM_TYPE mType, const std::string& value, int num) : number(num), type(type), mType(mType), value(value) { }
|
||||||
Argument(CFG_ARG_TYPE type, const std::string& value) : number(lastNumArg++), type(type), mType(CFG_MEM_TYPE::NONE_), value(value)
|
Argument(CFG_ARG_TYPE type, const std::string& value) : number(lastNumArg++), type(type), mType(CFG_MEM_TYPE::NONE_), value(value)
|
||||||
{
|
{
|
||||||
if (type != CFG_ARG_TYPE::INSTR && type == CFG_ARG_TYPE::LAB &&
|
if (type != CFG_ARG_TYPE::INSTR && type == CFG_ARG_TYPE::LAB &&
|
||||||
@@ -50,6 +51,9 @@ namespace SAPFOR
|
|||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Argument(const Argument& other)
|
||||||
|
: number(other.number), type(other.type), mType(other.mType), value(other.value)
|
||||||
|
{ }
|
||||||
|
|
||||||
void setType(CFG_ARG_TYPE newType) { type = newType; }
|
void setType(CFG_ARG_TYPE newType) { type = newType; }
|
||||||
CFG_ARG_TYPE getType() const { return type; }
|
CFG_ARG_TYPE getType() const { return type; }
|
||||||
|
|||||||
386
src/CFGraph/IR_SSAForm.cpp
Normal file
386
src/CFGraph/IR_SSAForm.cpp
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "../Utils/SgUtils.h"
|
||||||
|
#include "../Utils/CommonBlock.h"
|
||||||
|
#include "../GraphCall/graph_calls.h"
|
||||||
|
|
||||||
|
#include "dvm.h"
|
||||||
|
#include "IR.h"
|
||||||
|
#include "CFGraph.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace SAPFOR;
|
||||||
|
|
||||||
|
static const SAPFOR::Argument CONST_UNDEFINED_ARG(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1");
|
||||||
|
|
||||||
|
template <typename T> static bool compareVectors(const vector<T>* vec1, const vector<T>* vec2)
|
||||||
|
{
|
||||||
|
if (vec1 == vec2)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!vec1 || !vec2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
vector<T> sortedVec1 = *vec1;
|
||||||
|
vector<T> sortedVec2 = *vec2;
|
||||||
|
|
||||||
|
sort(sortedVec1.begin(), sortedVec1.end());
|
||||||
|
sort(sortedVec2.begin(), sortedVec2.end());
|
||||||
|
|
||||||
|
return sortedVec1 == sortedVec2;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> static vector<T>* getCommonElements(const vector<vector<T>>* vectors)
|
||||||
|
{
|
||||||
|
if (!vectors || vectors->empty())
|
||||||
|
return new vector<T>();
|
||||||
|
|
||||||
|
vector<T>* commonElements = new vector<T>((*vectors)[0]);
|
||||||
|
|
||||||
|
for (size_t i = 1; i < vectors->size(); ++i)
|
||||||
|
{
|
||||||
|
vector<T> tempCommon;
|
||||||
|
|
||||||
|
vector<T> sortedVec = (*vectors)[i];
|
||||||
|
sort(commonElements->begin(), commonElements->end());
|
||||||
|
sort(sortedVec.begin(), sortedVec.end());
|
||||||
|
|
||||||
|
set_intersection(
|
||||||
|
commonElements->begin(), commonElements->end(),
|
||||||
|
sortedVec.begin(), sortedVec.end(),
|
||||||
|
back_inserter(tempCommon)
|
||||||
|
);
|
||||||
|
|
||||||
|
*commonElements = tempCommon;
|
||||||
|
|
||||||
|
if (commonElements->empty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return commonElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>> findDominators(const vector<SAPFOR::BasicBlock*>& blocks)
|
||||||
|
{
|
||||||
|
map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>> result;
|
||||||
|
|
||||||
|
bool changed = true;
|
||||||
|
while (changed)
|
||||||
|
{
|
||||||
|
changed = false;
|
||||||
|
|
||||||
|
for (auto& currentBlock : blocks)
|
||||||
|
{
|
||||||
|
auto pred = currentBlock->getPrev();
|
||||||
|
auto prevDominators = new vector<vector<SAPFOR::BasicBlock*>>();
|
||||||
|
|
||||||
|
for (auto predBlock : pred)
|
||||||
|
prevDominators->push_back(result.find(predBlock) != result.end() ? result[predBlock] : blocks);
|
||||||
|
|
||||||
|
auto currentBlockResult = getCommonElements(prevDominators);
|
||||||
|
currentBlockResult->push_back(currentBlock);
|
||||||
|
|
||||||
|
if (result.find(currentBlock) == result.end() || !compareVectors(currentBlockResult, &result[currentBlock]))
|
||||||
|
{
|
||||||
|
result[currentBlock] = *currentBlockResult;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>> findDominatorBorders(const vector<SAPFOR::BasicBlock*>& blocks)
|
||||||
|
{
|
||||||
|
map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>> result;
|
||||||
|
|
||||||
|
for (auto& block : blocks)
|
||||||
|
result[block] = *(new vector<SAPFOR::BasicBlock*>());
|
||||||
|
|
||||||
|
for (auto& block : blocks)
|
||||||
|
{
|
||||||
|
if (block->getPrev().size() > 1)
|
||||||
|
{
|
||||||
|
for (auto prev : block->getPrev())
|
||||||
|
{
|
||||||
|
auto tmpBlock = prev;
|
||||||
|
|
||||||
|
while (tmpBlock != block->getDom())
|
||||||
|
{
|
||||||
|
result[tmpBlock].push_back(block);
|
||||||
|
tmpBlock = tmpBlock->getDom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pair<set<SAPFOR::Argument*>, map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>>> getGlobalsAndVarBlocks(const vector<SAPFOR::BasicBlock*>& blocks)
|
||||||
|
{
|
||||||
|
set<SAPFOR::Argument*> globals;
|
||||||
|
map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>> varBlocks;
|
||||||
|
|
||||||
|
for (auto& block : blocks)
|
||||||
|
{
|
||||||
|
set<SAPFOR::Argument*> def;
|
||||||
|
const auto& instructions = block->getInstructions();
|
||||||
|
|
||||||
|
for (const auto& irBlock : instructions)
|
||||||
|
{
|
||||||
|
if (irBlock)
|
||||||
|
{
|
||||||
|
Instruction* instr = irBlock->getInstruction();
|
||||||
|
|
||||||
|
if (instr)
|
||||||
|
{
|
||||||
|
auto arg1 = instr->getArg1();
|
||||||
|
auto arg2 = instr->getArg2();
|
||||||
|
auto res = instr->getResult();
|
||||||
|
|
||||||
|
if (arg1 && arg1->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg1) == def.end())
|
||||||
|
globals.insert(arg1);
|
||||||
|
|
||||||
|
if (arg2 && arg2->getType() == CFG_ARG_TYPE::VAR && find(def.begin(), def.end(), arg2) == def.end())
|
||||||
|
globals.insert(arg2);
|
||||||
|
|
||||||
|
if (res && res->getType() == CFG_ARG_TYPE::VAR)
|
||||||
|
{
|
||||||
|
def.insert(res);
|
||||||
|
varBlocks[res].insert(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_pair(globals, varBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getBlocksWithFiFunctions(const vector<SAPFOR::BasicBlock*> blocks, set<SAPFOR::Argument*>& globals,
|
||||||
|
map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>>& varBlocks,
|
||||||
|
map<SAPFOR::BasicBlock*, vector<SAPFOR::BasicBlock*>>& dominatorBorders)
|
||||||
|
{
|
||||||
|
vector<SAPFOR::BasicBlock*> blocksWithFiFunctions;
|
||||||
|
auto fiFunc = new SAPFOR::Argument(CFG_ARG_TYPE::FUNC, CFG_MEM_TYPE::NONE_, "FI_FUNCTION");
|
||||||
|
auto paramCount = new SAPFOR::Argument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::LOCAL_, "0");
|
||||||
|
|
||||||
|
for (auto& var : globals)
|
||||||
|
{
|
||||||
|
auto worklist = varBlocks[var];
|
||||||
|
set<SAPFOR::BasicBlock*> hasFiFunction;
|
||||||
|
|
||||||
|
while (!worklist.empty())
|
||||||
|
{
|
||||||
|
auto block = *worklist.begin();
|
||||||
|
worklist.erase(block);
|
||||||
|
|
||||||
|
for (auto& dfBlock : dominatorBorders[block])
|
||||||
|
{
|
||||||
|
if (hasFiFunction.find(dfBlock) == hasFiFunction.end())
|
||||||
|
{
|
||||||
|
hasFiFunction.insert(dfBlock);
|
||||||
|
Instruction* phiInstruction = new Instruction(CFG_OP::F_CALL, new SAPFOR::Argument(*fiFunc), new SAPFOR::Argument(*paramCount), var, dfBlock->getInstructions()[0]->getInstruction()->getOperator());
|
||||||
|
|
||||||
|
IR_Block* phiBlock = new IR_Block(phiInstruction);
|
||||||
|
dfBlock->addInstruction(phiBlock, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void restoreConnections(const vector<SAPFOR::BasicBlock*>& originalBlocks, vector<SAPFOR::BasicBlock*>& copiedBlocks)
|
||||||
|
{
|
||||||
|
map<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*> blockMapping;
|
||||||
|
for (size_t i = 0; i < originalBlocks.size(); ++i)
|
||||||
|
blockMapping[originalBlocks[i]] = copiedBlocks[i];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < originalBlocks.size(); ++i)
|
||||||
|
{
|
||||||
|
SAPFOR::BasicBlock* originalBlock = originalBlocks[i];
|
||||||
|
SAPFOR::BasicBlock* copiedBlock = copiedBlocks[i];
|
||||||
|
|
||||||
|
auto prevCopy = copiedBlock->getPrev();
|
||||||
|
for (auto j : prevCopy)
|
||||||
|
copiedBlock->removePrev(j);
|
||||||
|
|
||||||
|
auto nextCopy = copiedBlock->getNext();
|
||||||
|
for (auto j : nextCopy)
|
||||||
|
copiedBlock->removeNext(j);
|
||||||
|
|
||||||
|
for (auto* succ : originalBlock->getNext())
|
||||||
|
copiedBlock->addNext(blockMapping[succ]);
|
||||||
|
|
||||||
|
for (auto* prev : originalBlock->getPrev())
|
||||||
|
copiedBlock->addPrev(blockMapping[prev]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static SAPFOR::Argument* newName(SAPFOR::Argument* var, map<string, int>& counter, map<string, stack<SAPFOR::Argument*>>& stack, int number) {
|
||||||
|
counter[var->getValue()]++;
|
||||||
|
|
||||||
|
SAPFOR::Argument* newName = new SAPFOR::Argument(var->getType(), var->getMemType(), var->getValue(), number);
|
||||||
|
stack[var->getValue()].push(newName);
|
||||||
|
return newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void renameFiFunctionResultVar(SAPFOR::BasicBlock* block, map<string, int>& counter, map<string, stack<SAPFOR::Argument*>>& stack) {
|
||||||
|
for (auto& irBlock : block->getInstructions())
|
||||||
|
{
|
||||||
|
auto instruction = irBlock->getInstruction();
|
||||||
|
if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != NULL &&
|
||||||
|
instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL)
|
||||||
|
{
|
||||||
|
instruction->setResult(newName(instruction->getResult(), counter, stack, instruction->getNumber()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void renameInstructionVars(SAPFOR::BasicBlock* block, map<string, int>& counter, map<string, stack<SAPFOR::Argument*>>& stack)
|
||||||
|
{
|
||||||
|
for (auto& irBlock : block->getInstructions())
|
||||||
|
{
|
||||||
|
auto instruction = irBlock->getInstruction();
|
||||||
|
|
||||||
|
if (instruction->getArg1() != NULL && instruction->getArg1()->getType() == CFG_ARG_TYPE::VAR)
|
||||||
|
instruction->setArg1(stack[instruction->getArg1()->getValue()].top());
|
||||||
|
|
||||||
|
if (instruction->getArg2() != NULL && instruction->getArg2()->getType() == CFG_ARG_TYPE::VAR)
|
||||||
|
instruction->setArg2(stack[instruction->getArg2()->getValue()].top());
|
||||||
|
|
||||||
|
if (instruction->getResult() != NULL && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR)
|
||||||
|
instruction->setResult(newName(instruction->getResult(), counter, stack, instruction->getNumber()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void renameFiFunctionArgsVar(SAPFOR::BasicBlock* block, map<string, stack<SAPFOR::Argument*>>& stack)
|
||||||
|
{
|
||||||
|
auto size = block->getInstructions().size();
|
||||||
|
auto& instructions = block->getInstructions();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
auto irBlock = instructions[i];
|
||||||
|
auto instruction = irBlock->getInstruction();
|
||||||
|
if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != NULL &&
|
||||||
|
instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL &&
|
||||||
|
instruction->getArg2() != NULL)
|
||||||
|
{
|
||||||
|
Instruction* paramInstruction;
|
||||||
|
|
||||||
|
if (stack[instruction->getResult()->getValue()].size() > 0)
|
||||||
|
{
|
||||||
|
SAPFOR::Argument* tmp = new SAPFOR::Argument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, to_string(stack[instruction->getResult()->getValue()].top()->getNumber()));
|
||||||
|
paramInstruction = new Instruction(CFG_OP::PARAM, tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SAPFOR::Argument* tmp = new SAPFOR::Argument(CFG_ARG_TYPE::CONST, CFG_MEM_TYPE::COMMON_, "-1");
|
||||||
|
paramInstruction = new Instruction(CFG_OP::PARAM, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
paramInstruction->setOperator(block->getInstructions()[0]->getInstruction()->getOperator());
|
||||||
|
block->addInstructionBefore(new IR_Block(paramInstruction), instruction);
|
||||||
|
|
||||||
|
instruction->getArg2()->setValue(to_string(stoi(instruction->getArg2()->getValue()) + 1));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static vector<SAPFOR::BasicBlock*> findBlocksWithValue(vector<SAPFOR::BasicBlock*>& blocks, SAPFOR::BasicBlock* x)
|
||||||
|
{
|
||||||
|
vector<SAPFOR::BasicBlock*> result;
|
||||||
|
|
||||||
|
for (auto& block : blocks)
|
||||||
|
if (block->getDom() == x)
|
||||||
|
result.push_back(block);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void renameIR(SAPFOR::BasicBlock* block, vector<SAPFOR::BasicBlock*>& blocks, map<string, int>& counter, map<string, stack<SAPFOR::Argument*>>& stack)
|
||||||
|
{
|
||||||
|
renameFiFunctionResultVar(block, counter, stack);
|
||||||
|
renameInstructionVars(block, counter, stack);
|
||||||
|
|
||||||
|
for (auto& successor : block->getNext())
|
||||||
|
renameFiFunctionArgsVar(successor, stack);
|
||||||
|
|
||||||
|
for (auto& child : findBlocksWithValue(blocks, block))
|
||||||
|
renameIR(child, blocks, counter, stack);
|
||||||
|
|
||||||
|
for (auto& irBlock : block->getInstructions())
|
||||||
|
{
|
||||||
|
auto instruction = irBlock->getInstruction();
|
||||||
|
if (instruction->getResult() != NULL && instruction->getResult()->getType() == CFG_ARG_TYPE::VAR)
|
||||||
|
{
|
||||||
|
string varName = instruction->getResult()->getValue();
|
||||||
|
stack[varName].pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& irBlock : block->getInstructions())
|
||||||
|
{
|
||||||
|
auto instruction = irBlock->getInstruction();
|
||||||
|
if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != NULL &&
|
||||||
|
instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != NULL)
|
||||||
|
{
|
||||||
|
string varName = instruction->getResult()->getValue();
|
||||||
|
stack[varName].pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildFuncIRSSAForm(FuncInfo* funcInfo, const std::vector<SAPFOR::BasicBlock*>& funcIRConst, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& result)
|
||||||
|
{
|
||||||
|
vector<SAPFOR::BasicBlock*> funcIR;
|
||||||
|
|
||||||
|
for (auto& i : funcIRConst)
|
||||||
|
funcIR.push_back(new SAPFOR::BasicBlock(*i));
|
||||||
|
|
||||||
|
restoreConnections(funcIRConst, funcIR);
|
||||||
|
|
||||||
|
SAPFOR::buildDominatorTree(funcIR);
|
||||||
|
|
||||||
|
auto dominatorBorders = findDominatorBorders(funcIR);
|
||||||
|
|
||||||
|
auto globalsAndVarBlocks = getGlobalsAndVarBlocks(funcIR);
|
||||||
|
auto globals = globalsAndVarBlocks.first;
|
||||||
|
auto varBlocks = globalsAndVarBlocks.second;
|
||||||
|
|
||||||
|
getBlocksWithFiFunctions(funcIR, globals, varBlocks, dominatorBorders);
|
||||||
|
|
||||||
|
map<string, int> count;
|
||||||
|
map<string, stack<SAPFOR::Argument*>> varStack;
|
||||||
|
|
||||||
|
for (auto& var : globals)
|
||||||
|
{
|
||||||
|
count[var->getValue()] = 0;
|
||||||
|
|
||||||
|
stack<SAPFOR::Argument*> tmp;
|
||||||
|
tmp.push(new SAPFOR::Argument(CONST_UNDEFINED_ARG));
|
||||||
|
varStack[var->getValue()] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
renameIR(funcIR[0], funcIR, count, varStack);
|
||||||
|
|
||||||
|
result[funcInfo] = funcIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
FuncInfo* getIRByFilename(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR, const char* filename)
|
||||||
|
{
|
||||||
|
for (auto ir : fullIR)
|
||||||
|
if (ir.first->fileName == filename)
|
||||||
|
return ir.first;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
8
src/CFGraph/IR_SSAForm.h
Normal file
8
src/CFGraph/IR_SSAForm.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CFGraph.h"
|
||||||
|
#include "IR.h"
|
||||||
|
|
||||||
|
void buildFuncIRSSAForm(FuncInfo* funcInfo, const std::vector<SAPFOR::BasicBlock*>& fullIR, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& result);
|
||||||
|
|
||||||
|
FuncInfo* getIRByFilename(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR, const char* filename);
|
||||||
102
src/CFGraph/IR_domTree.cpp
Normal file
102
src/CFGraph/IR_domTree.cpp
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#include "dvm.h"
|
||||||
|
#include "IR_domTree.h"
|
||||||
|
|
||||||
|
namespace SAPFOR {
|
||||||
|
void DominatorFinder::DFS(BasicBlock* v, int parent_num) {
|
||||||
|
dfs_num[v] = n;
|
||||||
|
vertex[n] = n;
|
||||||
|
semi[n] = n;
|
||||||
|
label[n] = n;
|
||||||
|
ancestor[n] = -1;
|
||||||
|
parent[n] = parent_num;
|
||||||
|
vertices[n++] = v;
|
||||||
|
|
||||||
|
for (const auto& w : v->getNext()) {
|
||||||
|
if (dfs_num[w] == -1)
|
||||||
|
DFS(w, dfs_num[v]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DominatorFinder::Compress(int v) {
|
||||||
|
if (ancestor[ancestor[v]] != -1) {
|
||||||
|
Compress(ancestor[v]);
|
||||||
|
|
||||||
|
if (semi[label[ancestor[v]]] < semi[label[v]])
|
||||||
|
label[v] = label[ancestor[v]];
|
||||||
|
ancestor[v] = ancestor[ancestor[v]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DominatorFinder::Eval(int v) {
|
||||||
|
if (ancestor[v] == -1)
|
||||||
|
return v;
|
||||||
|
|
||||||
|
Compress(v);
|
||||||
|
return label[v];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DominatorFinder::Link(int v, int w) {
|
||||||
|
ancestor[w] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
DominatorFinder::DominatorFinder(std::vector<BasicBlock*>& blocks) {
|
||||||
|
if (blocks.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
entry = blocks[0];
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for (auto block : blocks)
|
||||||
|
dfs_num[block] = -1;
|
||||||
|
|
||||||
|
int max_size = blocks.size();
|
||||||
|
vertices.resize(max_size);
|
||||||
|
parent.assign(max_size, -1);
|
||||||
|
semi.assign(max_size, -1);
|
||||||
|
vertex.assign(max_size, -1);
|
||||||
|
ancestor.assign(max_size, -1);
|
||||||
|
label.assign(max_size, -1);
|
||||||
|
bucket.resize(max_size);
|
||||||
|
|
||||||
|
DFS(entry, -1);
|
||||||
|
|
||||||
|
for (int i = n - 1; i > 0; --i) {
|
||||||
|
int w = vertex[i];
|
||||||
|
|
||||||
|
for (BasicBlock* v : vertices[w]->getPrev()) {
|
||||||
|
if (dfs_num[v] == -1)
|
||||||
|
continue;
|
||||||
|
int u = Eval(dfs_num[v]);
|
||||||
|
|
||||||
|
if (semi[u] < semi[w])
|
||||||
|
semi[w] = semi[u];
|
||||||
|
}
|
||||||
|
|
||||||
|
bucket[vertex[semi[w]]].push_back(w);
|
||||||
|
Link(parent[w], w);
|
||||||
|
|
||||||
|
for (int v : bucket[parent[w]])
|
||||||
|
{
|
||||||
|
int u = Eval(v);
|
||||||
|
if (semi[u] < semi[v])
|
||||||
|
vertices[v]->setDom(vertices[u]);
|
||||||
|
else
|
||||||
|
vertices[v]->setDom(vertices[parent[w]]);
|
||||||
|
}
|
||||||
|
bucket[parent[w]].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < n; ++i) {
|
||||||
|
int w = vertex[i];
|
||||||
|
|
||||||
|
if (vertices[w]->getDom() != vertices[vertex[semi[w]]])
|
||||||
|
vertices[w]->setDom(vertices[w]->getDom()->getDom());
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->setDom(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildDominatorTree(std::vector<BasicBlock*>& blocks) {
|
||||||
|
DominatorFinder finder(blocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/CFGraph/IR_domTree.h
Normal file
35
src/CFGraph/IR_domTree.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "CFGraph.h"
|
||||||
|
|
||||||
|
// Lengauer, Thomas. A fast algorithm for finding dominators in a flowgraph / Thomas Lengauer, Robert Endre Tarjan
|
||||||
|
// ACM Transactions on Programming Languages and Systems (TOPLAS). <20> 1979. <20> Vol. 1, no. 1. <20> Pp. 121<32>141.
|
||||||
|
|
||||||
|
namespace SAPFOR {
|
||||||
|
|
||||||
|
class BasicBlock;
|
||||||
|
|
||||||
|
class DominatorFinder {
|
||||||
|
private:
|
||||||
|
BasicBlock* entry;
|
||||||
|
std::vector<BasicBlock*> vertices;
|
||||||
|
std::unordered_map<BasicBlock*, int> dfs_num;
|
||||||
|
std::vector<int> parent, semi, vertex, ancestor, label;
|
||||||
|
std::vector<std::vector<int>> bucket;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
void DFS(BasicBlock* v, int parent_num);
|
||||||
|
void Compress(int v);
|
||||||
|
int Eval(int v);
|
||||||
|
void Link(int v, int w);
|
||||||
|
|
||||||
|
public:
|
||||||
|
DominatorFinder(std::vector<BasicBlock*>& blocks);
|
||||||
|
};
|
||||||
|
|
||||||
|
void buildDominatorTree(std::vector<BasicBlock*>& blocks);
|
||||||
|
}
|
||||||
@@ -250,7 +250,7 @@ static set<SAPFOR::BasicBlock*> analyzeLoop(LoopGraph* loop, const set<SAPFOR::B
|
|||||||
const map<string, SgSymbol*>& commonArgs, FuncInfo* func,
|
const map<string, SgSymbol*>& commonArgs, FuncInfo* func,
|
||||||
map<string, vector<Messages>>& messages)
|
map<string, vector<Messages>>& messages)
|
||||||
{
|
{
|
||||||
if (!loop->isFor)
|
if (!loop->isFor())
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //should be called only with FOR loops
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //should be called only with FOR loops
|
||||||
|
|
||||||
SgStatement* loop_operator = loop->loop->GetOriginal();
|
SgStatement* loop_operator = loop->loop->GetOriginal();
|
||||||
@@ -450,7 +450,7 @@ static void recAnalyzeLoop(LoopGraph* loop, const set<SAPFOR::BasicBlock*>& bloc
|
|||||||
const map<string, SgSymbol*>& commonArgs,
|
const map<string, SgSymbol*>& commonArgs,
|
||||||
FuncInfo* func, map<string, vector<Messages>>& messages)
|
FuncInfo* func, map<string, vector<Messages>>& messages)
|
||||||
{
|
{
|
||||||
const auto& loop_body = loop->isFor ? analyzeLoop(loop, blocks, commonVars, commonArgs, func, messages) : blocks;
|
const auto& loop_body = loop->isFor() ? analyzeLoop(loop, blocks, commonVars, commonArgs, func, messages) : blocks;
|
||||||
|
|
||||||
for (const auto& inner_loop : loop->children)
|
for (const auto& inner_loop : loop->children)
|
||||||
recAnalyzeLoop(inner_loop, loop_body, commonVars, commonArgs, func, messages);
|
recAnalyzeLoop(inner_loop, loop_body, commonVars, commonArgs, func, messages);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
directive->parallel.push_back(currentLoop->loopSymbol);
|
directive->parallel.push_back(currentLoop->loopSymbol());
|
||||||
directive->arrayRef = mainArray.arrayRef;
|
directive->arrayRef = mainArray.arrayRef;
|
||||||
|
|
||||||
DIST::Array *tmp = mainArray.arrayRef;
|
DIST::Array *tmp = mainArray.arrayRef;
|
||||||
@@ -84,7 +84,7 @@ static LoopGraph* createDirectiveForLoop(LoopGraph *currentLoop, MapToArray &mai
|
|||||||
for (int i = 0; i < tmp->GetDimSize(); ++i)
|
for (int i = 0; i < tmp->GetDimSize(); ++i)
|
||||||
{
|
{
|
||||||
if (i == pos)
|
if (i == pos)
|
||||||
directive->on.push_back(make_pair(currentLoop->loopSymbol, mainAccess));
|
directive->on.push_back(make_pair(currentLoop->loopSymbol(), mainAccess));
|
||||||
else
|
else
|
||||||
directive->on.push_back(make_pair("*", make_pair(0, 0)));
|
directive->on.push_back(make_pair("*", make_pair(0, 0)));
|
||||||
}
|
}
|
||||||
@@ -808,7 +808,7 @@ void createParallelDirectives(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*
|
|||||||
for (int i = 0; i < mainArrayOfLoop->GetDimSize(); ++i)
|
for (int i = 0; i < mainArrayOfLoop->GetDimSize(); ++i)
|
||||||
{
|
{
|
||||||
if (i == dimPos)
|
if (i == dimPos)
|
||||||
parDir->on2.push_back(make_pair(currLoop->loopSymbol, mainAccess));
|
parDir->on2.push_back(make_pair(currLoop->loopSymbol(), mainAccess));
|
||||||
else
|
else
|
||||||
parDir->on2.push_back(make_pair("*", make_pair(0, 0)));
|
parDir->on2.push_back(make_pair("*", make_pair(0, 0)));
|
||||||
}
|
}
|
||||||
@@ -1100,7 +1100,7 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
|
|||||||
LoopGraph* tmpL = loop;
|
LoopGraph* tmpL = loop;
|
||||||
for (int z = 0; z < nested; ++z)
|
for (int z = 0; z < nested; ++z)
|
||||||
{
|
{
|
||||||
deprecateToMatch.insert(tmpL->loopSymbol);
|
deprecateToMatch.insert(tmpL->loopSymbol());
|
||||||
if (tmpL->children.size())
|
if (tmpL->children.size())
|
||||||
tmpL = tmpL->children[0];
|
tmpL = tmpL->children[0];
|
||||||
else if (z != nested - 1)
|
else if (z != nested - 1)
|
||||||
@@ -1113,7 +1113,7 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
|
|||||||
tmpL = loop->parent;
|
tmpL = loop->parent;
|
||||||
while (tmpL)
|
while (tmpL)
|
||||||
{
|
{
|
||||||
if (!tmpL->isFor) // TODO: need to add all inductive variables!
|
if (tmpL->isWhile()) // TODO: need to add all inductive variables!
|
||||||
{
|
{
|
||||||
SgWhileStmt* dow = isSgWhileStmt(tmpL->loop->GetOriginal());
|
SgWhileStmt* dow = isSgWhileStmt(tmpL->loop->GetOriginal());
|
||||||
if (dow->conditional())
|
if (dow->conditional())
|
||||||
@@ -1124,7 +1124,7 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
deprecateToMatch.insert(tmpL->loopSymbol);
|
deprecateToMatch.insert(tmpL->loopSymbol());
|
||||||
tmpL = tmpL->parent;
|
tmpL = tmpL->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -455,15 +455,7 @@ namespace Distribution
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needPrint)
|
if (needPrint)
|
||||||
{
|
sendMessage_2lvl(4, k, (int)AllCycles.size());
|
||||||
#if _WIN32
|
|
||||||
wstring treeM = L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring(k + 1) + L"/" + std::to_wstring(AllCycles.size());
|
|
||||||
#else
|
|
||||||
wstring treeM = L"conflict resolution, processing group " + std::to_wstring(k + 1) + L"/" + std::to_wstring(AllCycles.size());
|
|
||||||
#endif
|
|
||||||
sendMessage_2lvl(treeM);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
auto timeR = steady_clock::now();
|
auto timeR = steady_clock::now();
|
||||||
if (countConflicts != 0)
|
if (countConflicts != 0)
|
||||||
@@ -516,7 +508,7 @@ namespace Distribution
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needPrint)
|
if (needPrint)
|
||||||
sendMessage_2lvl(L"");
|
sendMessage_2lvl(2);
|
||||||
|
|
||||||
return make_pair(allOnlySecondType, globalSum);
|
return make_pair(allOnlySecondType, globalSum);
|
||||||
}
|
}
|
||||||
@@ -572,13 +564,7 @@ namespace Distribution
|
|||||||
for (int z = 0; z < arraysV.size(); ++z)
|
for (int z = 0; z < arraysV.size(); ++z)
|
||||||
{
|
{
|
||||||
const DIST::Array *array = arraysV[z];
|
const DIST::Array *array = arraysV[z];
|
||||||
|
sendMessage_2lvl(5, z, (int)arrays.size());
|
||||||
#ifdef _WIN32
|
|
||||||
wstring treeM = L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring(z + 1) + L"/" + std::to_wstring(arrays.size());
|
|
||||||
#else
|
|
||||||
wstring treeM = L"conflict resolution, processing array " + std::to_wstring(z + 1) + L"/" + std::to_wstring(arrays.size());
|
|
||||||
#endif
|
|
||||||
sendMessage_2lvl(treeM);
|
|
||||||
|
|
||||||
vector<vType> verts;
|
vector<vType> verts;
|
||||||
|
|
||||||
@@ -605,7 +591,7 @@ namespace Distribution
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendMessage_2lvl(L"");
|
sendMessage_2lvl(2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ static vector<SgExpression*>
|
|||||||
{
|
{
|
||||||
needToAdd = true;
|
needToAdd = true;
|
||||||
dim_found = true;
|
dim_found = true;
|
||||||
subs[i] = new SgVarRefExp(findSymbolOrCreate(file, currLoop->loopSymbol));
|
subs[i] = new SgVarRefExp(findSymbolOrCreate(file, currLoop->loopSymbol()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -830,13 +830,13 @@ namespace Distribution
|
|||||||
color[k] = WHITE;
|
color[k] = WHITE;
|
||||||
|
|
||||||
findFrom = currentV;
|
findFrom = currentV;
|
||||||
#ifdef _WIN32
|
/*#ifdef _WIN32
|
||||||
if (needPrint)
|
if (needPrint)
|
||||||
{
|
{
|
||||||
wstring vertexM = std::to_wstring(k + 1) + L"/" + std::to_wstring(vertByTrees[t].size());
|
wstring vertexM = std::to_wstring(k + 1) + L"/" + std::to_wstring(vertByTrees[t].size());
|
||||||
sendMessage_2lvl(wstring(L"<22><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ") + wstring(treeM.begin(), treeM.end()) + L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + wstring(vertexM.begin(), vertexM.end()));
|
sendMessage_2lvl(wstring(L"<22><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ") + wstring(treeM.begin(), treeM.end()) + L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + wstring(vertexM.begin(), vertexM.end()));
|
||||||
}
|
}
|
||||||
#endif
|
#endif*/
|
||||||
__spf_print(PRINT_TIMES && needPrint, "v (tree %d) = %d (with neighb %d) ", t, i, neighbors[i + 1] - neighbors[i]);
|
__spf_print(PRINT_TIMES && needPrint, "v (tree %d) = %d (with neighb %d) ", t, i, neighbors[i + 1] - neighbors[i]);
|
||||||
activeV[activeCounter++] = currentV;
|
activeV[activeCounter++] = currentV;
|
||||||
FindLoop(cyclesTmp[t], currentV, currentV, numbers);
|
FindLoop(cyclesTmp[t], currentV, currentV, numbers);
|
||||||
@@ -847,8 +847,8 @@ namespace Distribution
|
|||||||
maxLoopDim = wasMaxLoopDim;
|
maxLoopDim = wasMaxLoopDim;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needPrint)
|
/*if (needPrint)
|
||||||
sendMessage_2lvl(L"");
|
sendMessage_2lvl(2);*/
|
||||||
}
|
}
|
||||||
catch (int code)
|
catch (int code)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ static void findArrayRef(SgExpression *exp, bool isWirte, set<DIST::Array*>& use
|
|||||||
{
|
{
|
||||||
if (exp)
|
if (exp)
|
||||||
{
|
{
|
||||||
if (exp->variant() == ARRAY_REF)
|
if (isArrayRef(exp))
|
||||||
{
|
{
|
||||||
DIST::Array *arrayRef = NULL;
|
DIST::Array *arrayRef = NULL;
|
||||||
SgSymbol *symbS = OriginalSymbol(exp->symbol());
|
SgSymbol *symbS = OriginalSymbol(exp->symbol());
|
||||||
@@ -699,7 +699,12 @@ void loopGraphAnalyzer(SgFile *file, vector<LoopGraph*> &loopGraph, const vector
|
|||||||
newLoop->hasPrints = hasThisIds(st, newLoop->linesOfIO, { WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT, PRINT_STAT } ); // FORMAT_STAT
|
newLoop->hasPrints = hasThisIds(st, newLoop->linesOfIO, { WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT, PRINT_STAT } ); // FORMAT_STAT
|
||||||
newLoop->hasStops = hasThisIds(st, newLoop->linesOfStop, { STOP_STAT, PAUSE_NODE });
|
newLoop->hasStops = hasThisIds(st, newLoop->linesOfStop, { STOP_STAT, PAUSE_NODE });
|
||||||
newLoop->hasDvmIntervals = hasThisIds(st, tmpLines, { DVM_INTERVAL_DIR, DVM_ENDINTERVAL_DIR, DVM_EXIT_INTERVAL_DIR });
|
newLoop->hasDvmIntervals = hasThisIds(st, tmpLines, { DVM_INTERVAL_DIR, DVM_ENDINTERVAL_DIR, DVM_EXIT_INTERVAL_DIR });
|
||||||
newLoop->isFor = isSgForStmt(st) ? true : false;
|
if (isSgForStmt(st))
|
||||||
|
newLoop->loopType = LoopType::FOR;
|
||||||
|
else if (isSgWhileStmt(st))
|
||||||
|
newLoop->loopType = LoopType::WHILE;
|
||||||
|
else
|
||||||
|
newLoop->loopType = LoopType::NONE;
|
||||||
newLoop->inCanonicalFrom = isSgForStmt(st) ? true : false;
|
newLoop->inCanonicalFrom = isSgForStmt(st) ? true : false;
|
||||||
newLoop->hasSubstringRefs = hasSubstringRef(st);
|
newLoop->hasSubstringRefs = hasSubstringRef(st);
|
||||||
|
|
||||||
@@ -777,7 +782,7 @@ void loopGraphAnalyzer(SgFile *file, vector<LoopGraph*> &loopGraph, const vector
|
|||||||
newLoop->startEndExpr = std::make_pair((Expression*)NULL, (Expression*)NULL);
|
newLoop->startEndExpr = std::make_pair((Expression*)NULL, (Expression*)NULL);
|
||||||
|
|
||||||
newLoop->loop = new Statement(st);
|
newLoop->loop = new Statement(st);
|
||||||
newLoop->loopSymbol = st->symbol() ? st->symbol()->identifier() : "unknown";
|
newLoop->loopSymbols.addMainVar(st->symbol() ? st->symbol()->identifier() : "unknown");
|
||||||
findArrayRefs(newLoop);
|
findArrayRefs(newLoop);
|
||||||
|
|
||||||
SgStatement *lexPrev = st->lexPrev();
|
SgStatement *lexPrev = st->lexPrev();
|
||||||
|
|||||||
@@ -25,6 +25,33 @@ namespace DIST = Distribution;
|
|||||||
void getRealArrayRefs(DIST::Array* addTo, DIST::Array* curr, std::set<DIST::Array*>& realArrayRefs, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
|
void getRealArrayRefs(DIST::Array* addTo, DIST::Array* curr, std::set<DIST::Array*>& realArrayRefs, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
|
||||||
void getAllArrayRefs(DIST::Array* addTo, DIST::Array* curr, std::set<DIST::Array*>& realArrayRefs, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
|
void getAllArrayRefs(DIST::Array* addTo, DIST::Array* curr, std::set<DIST::Array*>& realArrayRefs, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
|
||||||
|
|
||||||
|
enum class LoopType { NONE, FOR, WHILE, IMPLICIT };
|
||||||
|
|
||||||
|
struct InductiveVariables
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string mainVar;
|
||||||
|
std::set<std::string> allVars;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InductiveVariables() { }
|
||||||
|
|
||||||
|
explicit InductiveVariables(const std::string& mainVar, const std::set<std::string>& allVars) : mainVar(mainVar), allVars(allVars) { };
|
||||||
|
|
||||||
|
std::string getMainVar() const { return mainVar; }
|
||||||
|
std::set<std::string> getAllVars() const { return allVars; }
|
||||||
|
|
||||||
|
void addVar(const std::string& var) { allVars.insert(var); }
|
||||||
|
void addMainVar(const std::string& var) { mainVar = var; allVars.insert(var); }
|
||||||
|
|
||||||
|
void replaceMainVar(const std::string& var)
|
||||||
|
{
|
||||||
|
allVars.erase(mainVar);
|
||||||
|
|
||||||
|
addMainVar(var);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct LoopGraph
|
struct LoopGraph
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -70,7 +97,7 @@ public:
|
|||||||
calculatedCountOfIters = 0;
|
calculatedCountOfIters = 0;
|
||||||
executionTimeInSec = -1.0;
|
executionTimeInSec = -1.0;
|
||||||
inDvmhRegion = 0;
|
inDvmhRegion = 0;
|
||||||
isFor = false;
|
loopType = LoopType::NONE;
|
||||||
inCanonicalFrom = false;
|
inCanonicalFrom = false;
|
||||||
hasAccessToSubArray = false;
|
hasAccessToSubArray = false;
|
||||||
hasSubstringRefs = false;
|
hasSubstringRefs = false;
|
||||||
@@ -113,21 +140,24 @@ public:
|
|||||||
{
|
{
|
||||||
return hasUnknownArrayDep || hasUnknownScalarDep || hasGoto || hasPrints || (hasConflicts.size() != 0) || hasStops || hasNonPureProcedures ||
|
return hasUnknownArrayDep || hasUnknownScalarDep || hasGoto || hasPrints || (hasConflicts.size() != 0) || hasStops || hasNonPureProcedures ||
|
||||||
hasUnknownArrayAssigns || hasNonRectangularBounds || hasIndirectAccess || hasWritesToNonDistribute || hasDifferentAlignRules || hasDvmIntervals ||
|
hasUnknownArrayAssigns || hasNonRectangularBounds || hasIndirectAccess || hasWritesToNonDistribute || hasDifferentAlignRules || hasDvmIntervals ||
|
||||||
!isFor || lastprivateScalars.size() || hasAccessToSubArray || hasSubstringRefs;
|
!isFor() || lastprivateScalars.size() || hasAccessToSubArray || hasSubstringRefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasLimitsToSplit() const
|
bool hasLimitsToSplit() const
|
||||||
{
|
{
|
||||||
return hasGoto || hasStops || !isFor || hasPrints;
|
return hasGoto || hasStops || !isFor() || hasPrints;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasLimitsToCombine() const
|
bool hasLimitsToCombine() const
|
||||||
{
|
{
|
||||||
return hasGoto || hasStops || !isFor || hasPrints || linesOfCycle.size();
|
return hasGoto || hasStops || !isFor() || hasPrints || linesOfCycle.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addConflictMessages(std::vector<Messages> *messages)
|
void addConflictMessages(std::vector<Messages> *messages)
|
||||||
{
|
{
|
||||||
|
if (messages == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
const int line = altLineNum > 0 ? altLineNum : lineNum;
|
const int line = altLineNum > 0 ? altLineNum : lineNum;
|
||||||
if (hasUnknownArrayDep)
|
if (hasUnknownArrayDep)
|
||||||
messages->push_back(Messages(NOTE, line, R113, L"unknown array dependency prevents parallelization of this loop", 3006));
|
messages->push_back(Messages(NOTE, line, R113, L"unknown array dependency prevents parallelization of this loop", 3006));
|
||||||
@@ -168,7 +198,7 @@ public:
|
|||||||
if (hasDvmIntervals)
|
if (hasDvmIntervals)
|
||||||
messages->push_back(Messages(NOTE, line, R145, L"DVM intervals prevent parallelization of this loop", 3006));
|
messages->push_back(Messages(NOTE, line, R145, L"DVM intervals prevent parallelization of this loop", 3006));
|
||||||
|
|
||||||
if (!isFor || !inCanonicalFrom)
|
if (!isFor() || !inCanonicalFrom)
|
||||||
messages->push_back(Messages(NOTE, line, R178, L"This type of loop is not supported by the system", 3006));
|
messages->push_back(Messages(NOTE, line, R178, L"This type of loop is not supported by the system", 3006));
|
||||||
|
|
||||||
if (lastprivateScalars.size())
|
if (lastprivateScalars.size())
|
||||||
@@ -393,6 +423,14 @@ public:
|
|||||||
|
|
||||||
void* getRealStat(const char* file) const;
|
void* getRealStat(const char* file) const;
|
||||||
|
|
||||||
|
bool isFor() const { return loopType == LoopType::FOR; }
|
||||||
|
|
||||||
|
bool isWhile() const { return loopType == LoopType::WHILE; }
|
||||||
|
|
||||||
|
bool isImplicit() const { return loopType == LoopType::IMPLICIT; }
|
||||||
|
|
||||||
|
std::string loopSymbol() const { return loopSymbols.getMainVar(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int lineNum;
|
int lineNum;
|
||||||
int altLineNum;
|
int altLineNum;
|
||||||
@@ -407,7 +445,7 @@ public:
|
|||||||
int startVal, endVal, stepVal;
|
int startVal, endVal, stepVal;
|
||||||
std::tuple<Expression*, Expression*, Expression*> startEndStepVals;
|
std::tuple<Expression*, Expression*, Expression*> startEndStepVals;
|
||||||
|
|
||||||
std::string loopSymbol;
|
InductiveVariables loopSymbols;
|
||||||
std::pair<Expression*, Expression*> startEndExpr;
|
std::pair<Expression*, Expression*> startEndExpr;
|
||||||
|
|
||||||
bool hasGoto;
|
bool hasGoto;
|
||||||
@@ -448,7 +486,7 @@ public:
|
|||||||
|
|
||||||
bool hasSubstringRefs;
|
bool hasSubstringRefs;
|
||||||
|
|
||||||
bool isFor;
|
LoopType loopType;
|
||||||
|
|
||||||
bool inCanonicalFrom;
|
bool inCanonicalFrom;
|
||||||
|
|
||||||
|
|||||||
@@ -551,7 +551,7 @@ void addToDistributionGraph(const map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loopAccess.first->isFor)
|
if (!loopAccess.first->isFor())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DIST::GraphCSR<int, double, attrType>& G = currReg->GetGraphToModify();
|
DIST::GraphCSR<int, double, attrType>& G = currReg->GetGraphToModify();
|
||||||
@@ -775,7 +775,7 @@ static void isAllOk(const vector<LoopGraph*> &loops, vector<Messages> &currMessa
|
|||||||
{
|
{
|
||||||
if (loops[i]->region)
|
if (loops[i]->region)
|
||||||
{
|
{
|
||||||
if (loops[i]->countOfIters == 0 && loops[i]->region && loops[i]->isFor)
|
if (loops[i]->countOfIters == 0 && loops[i]->region && loops[i]->isFor())
|
||||||
{
|
{
|
||||||
wstring bufE, bufR;
|
wstring bufE, bufR;
|
||||||
__spf_printToLongBuf(bufE, L" Can not calculate count of iterations for this loop, information about iterations in all loops in parallel regions '%s' will be ignored",
|
__spf_printToLongBuf(bufE, L" Can not calculate count of iterations for this loop, information about iterations in all loops in parallel regions '%s' will be ignored",
|
||||||
|
|||||||
281
src/LoopAnalyzer/implicit_loops_analyzer.cpp
Normal file
281
src/LoopAnalyzer/implicit_loops_analyzer.cpp
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
#include "../CFGraph/IR.h"
|
||||||
|
#include "GraphCall/graph_calls.h"
|
||||||
|
#include "implicit_loops_analyzer.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace SAPFOR;
|
||||||
|
|
||||||
|
using std::map;
|
||||||
|
using std::set;
|
||||||
|
using std::vector;
|
||||||
|
using std::pair;
|
||||||
|
using std::string;
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
|
using std::make_pair;
|
||||||
|
using std::to_string;
|
||||||
|
|
||||||
|
enum VisitState { UNVISITED = 0, VISITING = 1, VISITED = 2 };
|
||||||
|
|
||||||
|
void dfs(SAPFOR::BasicBlock* block,
|
||||||
|
std::map<int, int>& visit,
|
||||||
|
std::vector<std::pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>>& startAndEnd,
|
||||||
|
SAPFOR::BasicBlock* prev)
|
||||||
|
{
|
||||||
|
if (!block)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int id = block->getNumber();
|
||||||
|
|
||||||
|
if (visit[id] == VISITING) {
|
||||||
|
startAndEnd.emplace_back(prev, block);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visit[id] == VISITED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
visit[id] = VISITING;
|
||||||
|
|
||||||
|
for (auto next : block->getNext())
|
||||||
|
dfs(next, visit, startAndEnd, block);
|
||||||
|
|
||||||
|
visit[id] = VISITED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getLoopBody(SAPFOR::BasicBlock* loopHeader, const std::set<SAPFOR::BasicBlock*>& loopExits, std::vector<SAPFOR::BasicBlock*>& loopBody)
|
||||||
|
{
|
||||||
|
std::set<SAPFOR::BasicBlock*> visited;
|
||||||
|
std::stack<SAPFOR::BasicBlock*> stack;
|
||||||
|
|
||||||
|
stack.push(loopHeader);
|
||||||
|
|
||||||
|
while (!stack.empty())
|
||||||
|
{
|
||||||
|
auto block = stack.top();
|
||||||
|
stack.pop();
|
||||||
|
|
||||||
|
if (visited.count(block))
|
||||||
|
continue;
|
||||||
|
visited.insert(block);
|
||||||
|
|
||||||
|
for (auto succ : block->getNext())
|
||||||
|
{
|
||||||
|
if (loopExits.count(succ))
|
||||||
|
continue;
|
||||||
|
if (!visited.count(succ))
|
||||||
|
stack.push(succ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<SAPFOR::BasicBlock*> backReachable;
|
||||||
|
std::stack<SAPFOR::BasicBlock*> reverseStack;
|
||||||
|
reverseStack.push(loopHeader);
|
||||||
|
|
||||||
|
while (!reverseStack.empty())
|
||||||
|
{
|
||||||
|
auto block = reverseStack.top();
|
||||||
|
reverseStack.pop();
|
||||||
|
|
||||||
|
if (backReachable.count(block))
|
||||||
|
continue;
|
||||||
|
backReachable.insert(block);
|
||||||
|
|
||||||
|
for (auto pred : block->getPrev())
|
||||||
|
if (visited.count(pred) && !backReachable.count(pred))
|
||||||
|
reverseStack.push(pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto block : visited)
|
||||||
|
if (backReachable.count(block))
|
||||||
|
loopBody.push_back(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
SAPFOR::Instruction* findDef(const SAPFOR::Argument* arg,
|
||||||
|
const std::vector<SAPFOR::BasicBlock*>& blocks)
|
||||||
|
{
|
||||||
|
if (!arg)
|
||||||
|
return nullptr;
|
||||||
|
std::string argName = arg->getValue();
|
||||||
|
|
||||||
|
for (auto block : blocks) {
|
||||||
|
for (auto instrWrapper : block->getInstructions()) {
|
||||||
|
auto instr = instrWrapper->getInstruction();
|
||||||
|
if (!instr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto res = instr->getResult();
|
||||||
|
if (!res)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (res->getValue() == argName)
|
||||||
|
return instr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SAPFOR::Argument* getBaseSource(const SAPFOR::Argument* arg, const std::vector<SAPFOR::BasicBlock*>& blocks)
|
||||||
|
{
|
||||||
|
while (arg && arg->getType() == CFG_ARG_TYPE::REG)
|
||||||
|
{
|
||||||
|
auto defInstr = findDef(arg, blocks);
|
||||||
|
if (!defInstr)
|
||||||
|
break;
|
||||||
|
auto defOp = defInstr->getOperation();
|
||||||
|
|
||||||
|
if (defOp == CFG_OP::ASSIGN)
|
||||||
|
arg = defInstr->getArg1();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void findInductiveVars(const std::vector<SAPFOR::BasicBlock*>& Loopblocks, const std::vector<SAPFOR::BasicBlock*>& blocks)
|
||||||
|
{
|
||||||
|
std::set<std::string> inductiveVars;
|
||||||
|
|
||||||
|
for (auto block : Loopblocks)
|
||||||
|
{
|
||||||
|
for (auto instrWrapper : block->getInstructions())
|
||||||
|
{
|
||||||
|
auto instr = instrWrapper->getInstruction();
|
||||||
|
if (!instr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto res = instr->getResult();
|
||||||
|
if (!res || res->getType() != SAPFOR::CFG_ARG_TYPE::VAR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
while (instr && instr->getOperation() == CFG_OP::ASSIGN)
|
||||||
|
instr = findDef(instr->getArg1(), blocks);
|
||||||
|
|
||||||
|
if (!instr || instr->getOperation() != CFG_OP::ADD && instr->getOperation() != CFG_OP::SUBT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto arg1 = getBaseSource(instr->getArg1(), blocks);
|
||||||
|
auto arg2 = getBaseSource(instr->getArg2(), blocks);
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
if (res->getValue() == arg1->getValue() && arg2->getType() == CFG_ARG_TYPE::CONST)
|
||||||
|
ok = true;
|
||||||
|
else if (res->getValue() == arg2->getValue() && arg1->getType() == CFG_ARG_TYPE::CONST)
|
||||||
|
ok = true;
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
inductiveVars.insert(res->getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inductiveVars.empty())
|
||||||
|
std::cout << "No inductive variables found." << std::endl;
|
||||||
|
else
|
||||||
|
for (const auto& var : inductiveVars)
|
||||||
|
std::cout << "Inductive variable: " << var << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instruction* findInstructionAfterLoop(const std::vector<SAPFOR::BasicBlock*>& loopBody)
|
||||||
|
{
|
||||||
|
std::set<SAPFOR::BasicBlock*> loopSet(loopBody.begin(), loopBody.end());
|
||||||
|
|
||||||
|
for (auto block : loopBody)
|
||||||
|
{
|
||||||
|
for (auto succ : block->getNext())
|
||||||
|
{
|
||||||
|
if (!loopSet.count(succ))
|
||||||
|
{
|
||||||
|
auto instructions = succ->getInstructions();
|
||||||
|
if (instructions.empty())
|
||||||
|
std::cout << "Exit block has no instructions." << std::endl;
|
||||||
|
|
||||||
|
for (auto wrapper : instructions)
|
||||||
|
if (auto instr = wrapper->getInstruction())
|
||||||
|
return instr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void findImplicitLoops(const std::vector<SAPFOR::BasicBlock*>& irSSA, const std::vector<LoopGraph*> loopGraph)
|
||||||
|
{
|
||||||
|
map<int, int> visited;
|
||||||
|
for (auto i : irSSA)
|
||||||
|
visited[i->getNumber()] = UNVISITED;
|
||||||
|
|
||||||
|
vector<pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>> startAndEnd;
|
||||||
|
dfs(irSSA[0], visited, startAndEnd, NULL);
|
||||||
|
|
||||||
|
vector<LoopGraph*> loops;
|
||||||
|
|
||||||
|
for (auto& [tail, header] : startAndEnd)
|
||||||
|
{
|
||||||
|
set<SAPFOR::BasicBlock*> loopExits;
|
||||||
|
|
||||||
|
for (auto succ : tail->getNext())
|
||||||
|
if (succ != header)
|
||||||
|
loopExits.insert(succ);
|
||||||
|
|
||||||
|
vector<SAPFOR::BasicBlock*> loopBody;
|
||||||
|
getLoopBody(header, loopExits, loopBody);
|
||||||
|
|
||||||
|
findInductiveVars(loopBody, irSSA);
|
||||||
|
|
||||||
|
Instruction* instructionAfterLoop = findInstructionAfterLoop(loopBody);
|
||||||
|
|
||||||
|
if (instructionAfterLoop == NULL)
|
||||||
|
{
|
||||||
|
cout << "Warning: instruction after loop not found!" << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto firstInstruction = header->getInstructions()[0]->getInstruction();
|
||||||
|
auto lastInstruction = tail->getInstructions().back()->getInstruction();
|
||||||
|
auto tmpLoop = new LoopGraph();
|
||||||
|
tmpLoop->lineNum = firstInstruction->getOperator()->lineNumber();
|
||||||
|
tmpLoop->lineNumAfterLoop = instructionAfterLoop->getOperator()->lineNumber();
|
||||||
|
|
||||||
|
|
||||||
|
if (firstInstruction->getOperator()->variant() == FOR_NODE)
|
||||||
|
{
|
||||||
|
SgForStmt* stmt = isSgForStmt(firstInstruction->getOperator());
|
||||||
|
|
||||||
|
cout << "for loop" << endl;
|
||||||
|
}
|
||||||
|
else if (firstInstruction->getOperator()->variant() == WHILE_NODE)
|
||||||
|
{
|
||||||
|
SgWhileStmt* stmt = isSgWhileStmt(firstInstruction->getOperator());
|
||||||
|
|
||||||
|
cout << (stmt->conditional() == NULL ? "infinit" : "") << "while loop" << endl;
|
||||||
|
}
|
||||||
|
else if (firstInstruction->getOperator()->variant() == DO_WHILE_NODE)
|
||||||
|
{
|
||||||
|
SgWhileStmt* stmt = isSgDoWhileStmt(firstInstruction->getOperator());
|
||||||
|
|
||||||
|
cout << "do while loop" << endl;
|
||||||
|
}
|
||||||
|
else if (firstInstruction->getOperator()->variant() == LOOP_NODE)
|
||||||
|
{
|
||||||
|
cout << "not known loop" << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cout << "goto loop" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "loop start line " << tmpLoop->lineNum << endl;
|
||||||
|
cout << "after loop line " << tmpLoop->lineNumAfterLoop << endl << endl;
|
||||||
|
|
||||||
|
loops.push_back(tmpLoop);
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/LoopAnalyzer/implicit_loops_analyzer.h
Normal file
7
src/LoopAnalyzer/implicit_loops_analyzer.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
#include "../GraphCall/graph_calls.h"
|
||||||
|
|
||||||
|
void findImplicitLoops(const std::vector<SAPFOR::BasicBlock*>& fullIR_SSA, const std::vector<LoopGraph*> loopGraph);
|
||||||
@@ -1633,17 +1633,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> ®ions, map<tuple<int,
|
|||||||
createNeededException();
|
createNeededException();
|
||||||
|
|
||||||
string fName = file->functions(i)->symbol()->identifier();
|
string fName = file->functions(i)->symbol()->identifier();
|
||||||
#if _WIN32
|
sendMessage_2lvl(0, (file->functions(i)->variant() != MODULE_STMT), fName);
|
||||||
if (file->functions(i)->variant() != MODULE_STMT)
|
|
||||||
sendMessage_2lvl(wstring(L"обработка функции '") + wstring(fName.begin(), fName.end()) + L"'");
|
|
||||||
else
|
|
||||||
sendMessage_2lvl(wstring(L"обработка модуля '") + wstring(fName.begin(), fName.end()) + L"'");
|
|
||||||
#else
|
|
||||||
if (file->functions(i)->variant() != MODULE_STMT)
|
|
||||||
sendMessage_2lvl(wstring(L"processing function '") + wstring(fName.begin(), fName.end()) + L"'");
|
|
||||||
else
|
|
||||||
sendMessage_2lvl(wstring(L"processing module '") + wstring(fName.begin(), fName.end()) + L"'");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
set<SgSymbol*> delcsSymbViewed;
|
set<SgSymbol*> delcsSymbViewed;
|
||||||
set<SgStatement*> delcsStatViewed;
|
set<SgStatement*> delcsStatViewed;
|
||||||
@@ -2188,11 +2178,8 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> ®ions, map<tuple<int,
|
|||||||
if (!skipDeps)
|
if (!skipDeps)
|
||||||
{
|
{
|
||||||
string fName = file->functions(i)->symbol()->identifier();
|
string fName = file->functions(i)->symbol()->identifier();
|
||||||
#ifdef _WIN32
|
sendMessage_2lvl(1, idx, (int)convertedLoopInfo.size());
|
||||||
sendMessage_2lvl(wstring(L"обработка цикла ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
|
|
||||||
#else
|
|
||||||
sendMessage_2lvl(wstring(L"processing loop ") + std::to_wstring(idx) + L"/" + std::to_wstring(convertedLoopInfo.size()));
|
|
||||||
#endif
|
|
||||||
tryToFindDependencies(loop.first, allLoops, funcWasInit, file, regions, currMessages, collection, funcByName, defUseByPlace);
|
tryToFindDependencies(loop.first, allLoops, funcWasInit, file, regions, currMessages, collection, funcByName, defUseByPlace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2212,7 +2199,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> ®ions, map<tuple<int,
|
|||||||
LoopGraph *tmpLoop = new LoopGraph();
|
LoopGraph *tmpLoop = new LoopGraph();
|
||||||
|
|
||||||
tmpLoop->region = reg;
|
tmpLoop->region = reg;
|
||||||
tmpLoop->isFor = true;
|
tmpLoop->loopType = LoopType::FOR;
|
||||||
|
|
||||||
tmpLoops.push_back(tmpLoop);
|
tmpLoops.push_back(tmpLoop);
|
||||||
|
|
||||||
@@ -2340,7 +2327,7 @@ void loopAnalyzer(SgFile *file, vector<ParallelRegion*> ®ions, map<tuple<int,
|
|||||||
if (parallizeFreeLoops)
|
if (parallizeFreeLoops)
|
||||||
selectFreeLoopsForParallelization(loopsForFunction, funcName, (regime == DATA_DISTR), regions, messagesForFile);
|
selectFreeLoopsForParallelization(loopsForFunction, funcName, (regime == DATA_DISTR), regions, messagesForFile);
|
||||||
}
|
}
|
||||||
sendMessage_2lvl(L"");
|
sendMessage_2lvl(2);
|
||||||
}
|
}
|
||||||
else if (regime == COMP_DISTR)
|
else if (regime == COMP_DISTR)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ static void SolveDataFlow(Region* DFG)
|
|||||||
Collapse(DFG);
|
Collapse(DFG);
|
||||||
}
|
}
|
||||||
|
|
||||||
map<LoopGraph*, ArrayAccessingIndexes> FindPrivateArrays(map<string, vector<LoopGraph*>> &loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
|
map<LoopGraph*, ArrayAccessingIndexes> findPrivateArrays(map<string, vector<LoopGraph*>> &loopGraph, map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR)
|
||||||
{
|
{
|
||||||
map<LoopGraph*, ArrayAccessingIndexes> result;
|
map<LoopGraph*, ArrayAccessingIndexes> result;
|
||||||
for (const auto& [loopName, loops] : loopGraph)
|
for (const auto& [loopName, loops] : loopGraph)
|
||||||
|
|||||||
@@ -10,5 +10,5 @@
|
|||||||
#include "../CFGraph/CFGraph.h"
|
#include "../CFGraph/CFGraph.h"
|
||||||
|
|
||||||
void Collapse(Region* region);
|
void Collapse(Region* region);
|
||||||
std::map<LoopGraph*, ArrayAccessingIndexes> FindPrivateArrays(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR);
|
std::map<LoopGraph*, ArrayAccessingIndexes> findPrivateArrays(std::map<std::string, std::vector<LoopGraph*>>& loopGraph, std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& FullIR);
|
||||||
std::pair<SAPFOR::BasicBlock*, std::unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const std::vector<SAPFOR::BasicBlock*> blocks);
|
std::pair<SAPFOR::BasicBlock*, std::unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForLoop(const LoopGraph* loop, const std::vector<SAPFOR::BasicBlock*> blocks);
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
#include "range_structures.h"
|
#include "range_structures.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pair<SAPFOR::BasicBlock*, unordered_set<SAPFOR::BasicBlock*>> GetBasicBlocksForL
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void BuildLoopIndex(map<string, LoopGraph*>& loopForIndex, LoopGraph* loop) {
|
static void BuildLoopIndex(map<string, LoopGraph*>& loopForIndex, LoopGraph* loop) {
|
||||||
string index = loop->loopSymbol;
|
string index = loop->loopSymbol();
|
||||||
loopForIndex[index] = loop;
|
loopForIndex[index] = loop;
|
||||||
|
|
||||||
for (const auto& childLoop : loop->children)
|
for (const auto& childLoop : loop->children)
|
||||||
@@ -146,7 +146,7 @@ static int GetDefUseArray(SAPFOR::BasicBlock* block, LoopGraph* loop, ArrayAcces
|
|||||||
{
|
{
|
||||||
auto var = index_vars.back();
|
auto var = index_vars.back();
|
||||||
int currentVarPos = refPos.back();
|
int currentVarPos = refPos.back();
|
||||||
pair currentCoefs = coefsForDims.back();
|
pair<int, int> currentCoefs = coefsForDims.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 };
|
current_dim = { stoul(var->getValue()), 1, 1 };
|
||||||
|
|||||||
@@ -294,11 +294,8 @@ static vector<string> parseList(vector<FileInfo>& listOfProject,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
sendMessage_2lvl(3, file);
|
||||||
sendMessage_2lvl(L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> '" + to_wstring(file) + L"'");
|
|
||||||
#else
|
|
||||||
sendMessage_2lvl(L" processing file '" + to_wstring(file) + L"'");
|
|
||||||
#endif
|
|
||||||
StdCapture::Init();
|
StdCapture::Init();
|
||||||
string errorMessage = "";
|
string errorMessage = "";
|
||||||
try
|
try
|
||||||
@@ -444,20 +441,12 @@ static int dumpErrors(const vector<FileInfo>& listOfProject, const vector<string
|
|||||||
if (errors[z] == "")
|
if (errors[z] == "")
|
||||||
{
|
{
|
||||||
FILE* ferr = fopen(file.errPath.c_str(), "w");
|
FILE* ferr = fopen(file.errPath.c_str(), "w");
|
||||||
if (!ferr)
|
if (ferr)
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
fclose(ferr);
|
fclose(ferr);
|
||||||
++z;
|
++z;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* ferr = fopen(file.errPath.c_str(), "w");
|
|
||||||
FILE* fout = fopen(file.outPath.c_str(), "w");
|
|
||||||
if (!ferr)
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
if (!fout)
|
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
||||||
|
|
||||||
string errS = "", outS = "";
|
string errS = "", outS = "";
|
||||||
vector<string> splited;
|
vector<string> splited;
|
||||||
splitString(errors[z], '\n', splited);
|
splitString(errors[z], '\n', splited);
|
||||||
@@ -476,13 +465,22 @@ static int dumpErrors(const vector<FileInfo>& listOfProject, const vector<string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fout, "%s", outS.c_str());
|
|
||||||
|
FILE* ferr = fopen(file.errPath.c_str(), "w");
|
||||||
|
FILE* fout = fopen(file.outPath.c_str(), "w");
|
||||||
|
if (ferr)
|
||||||
|
{
|
||||||
fprintf(ferr, "%s", errS.c_str());
|
fprintf(ferr, "%s", errS.c_str());
|
||||||
|
fclose(ferr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fout)
|
||||||
|
{
|
||||||
|
fprintf(fout, "%s", outS.c_str());
|
||||||
|
fclose(fout);
|
||||||
|
}
|
||||||
|
|
||||||
fflush(NULL);
|
fflush(NULL);
|
||||||
|
|
||||||
fclose(fout);
|
|
||||||
fclose(ferr);
|
|
||||||
++z;
|
++z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,11 +575,8 @@ static void parseFiles(int& iters, vector<string>& errors, vector<FileInfo>& lis
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
sendMessage_1lvl(0, iters + 1);
|
||||||
sendMessage_1lvl(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring((iters + 1)) + L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
||||||
#else
|
|
||||||
sendMessage_1lvl(L"running " + std::to_wstring((iters + 1)) + L" iteration of syntax analisys");
|
|
||||||
#endif
|
|
||||||
errors = parseList(listOfProject, iters != 0, parseForInlining, mapModuleDeps, moduleDelc, modDirectOrder, isFromConsole);
|
errors = parseList(listOfProject, iters != 0, parseForInlining, mapModuleDeps, moduleDelc, modDirectOrder, isFromConsole);
|
||||||
changed = createMapOfUse(errors, listOfProject, mapModuleDeps);
|
changed = createMapOfUse(errors, listOfProject, mapModuleDeps);
|
||||||
if (iters != 0)
|
if (iters != 0)
|
||||||
@@ -810,6 +805,8 @@ void parseFiles(int argc, char** argv)
|
|||||||
printf(" run parsing for inlining\n");
|
printf(" run parsing for inlining\n");
|
||||||
|
|
||||||
int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, isInline, true);
|
int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, isInline, true);
|
||||||
|
int errCount = dumpErrors(listOfProject, errors, messages);
|
||||||
|
|
||||||
if (rethrow == 0)
|
if (rethrow == 0)
|
||||||
{
|
{
|
||||||
for (auto& err : errors)
|
for (auto& err : errors)
|
||||||
@@ -839,5 +836,7 @@ void parseFiles(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
printf("Parsing was completed with errors, throw code %d, errors count %d\n", rethrow, code);
|
printf("Parsing was completed with errors, throw code %d, errors count %d\n", rethrow, code);
|
||||||
|
|
||||||
|
dumpMessages(false, messages, VISUALIZER_DATA_PATH);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,20 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
#include "CFGraph/CFGraph.h"
|
||||||
|
#include "CFGraph/IR.h"
|
||||||
|
#include "Distribution/Array.h"
|
||||||
#include "dvm.h"
|
#include "dvm.h"
|
||||||
|
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "SgUtils.h"
|
#include "SgUtils.h"
|
||||||
#include "graph_calls.h"
|
#include "graph_calls.h"
|
||||||
@@ -19,15 +23,421 @@
|
|||||||
|
|
||||||
#include "projectParameters.h"
|
#include "projectParameters.h"
|
||||||
|
|
||||||
using namespace std;
|
using std::set;
|
||||||
|
using std::map;
|
||||||
|
using std::string;
|
||||||
|
using std::vector;
|
||||||
|
using std::tuple;
|
||||||
|
using std::pair;
|
||||||
|
using std::make_tuple;
|
||||||
|
using std::find_if;
|
||||||
|
|
||||||
map< pair<string, int>, set<string>>
|
static map<FuncInfo*, vector<SAPFOR::Instruction*>> call_sites;
|
||||||
findParameters(const map<string, vector<DefUseList>> &defUseByFunctions,
|
|
||||||
const map<string, CommonBlock*> &commonBlocks,
|
enum class MODE
|
||||||
const map<string, vector<FuncInfo*>> &allFuncInfo)
|
|
||||||
{
|
{
|
||||||
map< pair<string, int>, set<string>> foundParameters;
|
BEFORE,
|
||||||
|
AFTER
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
static void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist, SAPFOR::Argument* reg, Iterator instr, Iterator first_instr);
|
||||||
|
|
||||||
return foundParameters;
|
static tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*>
|
||||||
|
stmtToIR(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, SgStatement* stmt)
|
||||||
|
{
|
||||||
|
SgStatement* cur = stmt;
|
||||||
|
cur->switchToFile();
|
||||||
|
while (cur->variant() != PROC_HEDR && cur->variant() != PROG_HEDR && cur->variant() != FUNC_HEDR)
|
||||||
|
cur = cur->controlParent();
|
||||||
|
|
||||||
|
string funcName = ((SgProcHedrStmt*)cur)->nameWithContains();
|
||||||
|
|
||||||
|
int stmtID = stmt->id();
|
||||||
|
for (const auto& [func, bblocks] : CFGraph)
|
||||||
|
{
|
||||||
|
if (func->funcName != funcName)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto basicBlock : bblocks)
|
||||||
|
for (auto ins : basicBlock->getInstructions())
|
||||||
|
if (stmtID == ins->getInstruction()->getOperator()->id())
|
||||||
|
return make_tuple(func, ins->getInstruction(), basicBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
return { NULL, NULL, NULL };
|
||||||
|
}
|
||||||
|
|
||||||
|
static tuple<FuncInfo*, SAPFOR::Instruction*, SAPFOR::BasicBlock*>
|
||||||
|
IRByNumber(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph, int num)
|
||||||
|
{
|
||||||
|
if (num < 0)
|
||||||
|
return { NULL, NULL, NULL };
|
||||||
|
|
||||||
|
for (const auto& [func, bblocks] : CFGraph)
|
||||||
|
for (auto byBB : bblocks)
|
||||||
|
if (byBB->getInstructions().front()->getNumber() <= num && byBB->getInstructions().back()->getNumber() >= num)
|
||||||
|
return make_tuple(func, getInstructionByNumber(byBB->getInstructions(), num), byBB);
|
||||||
|
|
||||||
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
return { NULL, NULL, NULL };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
static void processArgument(set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Argument* arg,
|
||||||
|
Iterator instr, Iterator first_instr)
|
||||||
|
{
|
||||||
|
if (arg == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (arg->getType() == SAPFOR::CFG_ARG_TYPE::REG)
|
||||||
|
extract_vars_from_reg(worklist, arg, instr, first_instr);
|
||||||
|
else if (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||||
|
worklist.insert(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
static void extract_vars_from_reg(set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Argument* reg,
|
||||||
|
Iterator instr, Iterator first_instr)
|
||||||
|
{
|
||||||
|
for (; instr >= first_instr; instr--)
|
||||||
|
{
|
||||||
|
if ((*instr)->getInstruction()->getResult() == reg)
|
||||||
|
{
|
||||||
|
processArgument(worklist, (*instr)->getInstruction()->getArg1(), instr, first_instr);
|
||||||
|
processArgument(worklist, (*instr)->getInstruction()->getArg2(), instr, first_instr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lookup_for_vars(set<tuple<SgStatement*, string, MODE>>& where_to_add,
|
||||||
|
set<SAPFOR::Argument*>& worklist,
|
||||||
|
SAPFOR::Instruction* instr,
|
||||||
|
SAPFOR::BasicBlock* bblock,
|
||||||
|
FuncInfo* cur_func,
|
||||||
|
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||||
|
{
|
||||||
|
while (bblock)
|
||||||
|
{
|
||||||
|
auto first_instr = bblock->getInstructions().begin();
|
||||||
|
auto cur_instr = find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
|
||||||
|
return i->getInstruction() == instr;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (; cur_instr >= bblock->getInstructions().begin(); --cur_instr)
|
||||||
|
{
|
||||||
|
auto instr = (*cur_instr)->getInstruction();
|
||||||
|
auto result_arg = instr->getResult();
|
||||||
|
auto arg1 = instr->getArg1();
|
||||||
|
auto arg2 = instr->getArg2();
|
||||||
|
|
||||||
|
if (worklist.count(result_arg))
|
||||||
|
{
|
||||||
|
worklist.erase(result_arg);
|
||||||
|
processArgument(worklist, arg1, cur_instr, first_instr);
|
||||||
|
processArgument(worklist, arg2, cur_instr, first_instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instr->getOperation() == SAPFOR::CFG_OP::PARAM && worklist.count(arg1))
|
||||||
|
{
|
||||||
|
// skip to F_CALL
|
||||||
|
auto f_call_instr = cur_instr;
|
||||||
|
while ((*f_call_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL)
|
||||||
|
f_call_instr++;
|
||||||
|
|
||||||
|
if ((*f_call_instr)->getInstruction()->getArg1()->getValue() == "_READ")
|
||||||
|
{
|
||||||
|
auto stmt_before = (*f_call_instr)->getInstruction()->getOperator();
|
||||||
|
auto filename = stmt_before->fileName();
|
||||||
|
auto line = stmt_before->lineNumber();
|
||||||
|
auto var_name = arg1->getValue().substr(arg1->getValue().find('%') + 1);
|
||||||
|
__spf_print(1, "Please specify value of variable %s on line %d of file %s\n", arg1->getValue().c_str(), line, filename);
|
||||||
|
auto toAdd = make_tuple(stmt_before, var_name, MODE::AFTER);
|
||||||
|
where_to_add.insert(toAdd);
|
||||||
|
worklist.erase(arg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& RD = bblock->getRD_In();
|
||||||
|
map<SAPFOR::BasicBlock*, SAPFOR::Instruction*> group_by_block;
|
||||||
|
|
||||||
|
set<SAPFOR::Argument*> to_erase;
|
||||||
|
for (auto& arg : worklist)
|
||||||
|
{
|
||||||
|
if (RD.count(arg))
|
||||||
|
{
|
||||||
|
if (RD.at(arg).size() == 1 && *RD.at(arg).begin() == SAPFOR::CFG_VAL::UNINIT)
|
||||||
|
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
|
||||||
|
else if (RD.at(arg).size() > 1)
|
||||||
|
{
|
||||||
|
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
|
||||||
|
auto filename = stmt_after->fileName();
|
||||||
|
auto line = stmt_after->lineNumber();
|
||||||
|
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
|
||||||
|
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
|
||||||
|
__spf_print(1, "Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
|
||||||
|
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
|
||||||
|
where_to_add.insert(toAdd);
|
||||||
|
to_erase.insert(arg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto instr_num = *RD.at(arg).begin();
|
||||||
|
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
|
||||||
|
if (cur_func == func && (group_by_block[bblock] == NULL || group_by_block[bblock]->getNumber() < instr_num))
|
||||||
|
group_by_block[bblock] = instr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto& arg : to_erase)
|
||||||
|
worklist.erase(arg);
|
||||||
|
|
||||||
|
while (bblock && group_by_block.find(bblock) == group_by_block.end())
|
||||||
|
bblock = bblock->getDom();
|
||||||
|
|
||||||
|
if (bblock)
|
||||||
|
instr = group_by_block[bblock];
|
||||||
|
}
|
||||||
|
|
||||||
|
// other variables are from global scope
|
||||||
|
const auto& RD = fullIR.at(cur_func).front()->getRD_In();
|
||||||
|
for (auto& arg : worklist)
|
||||||
|
{
|
||||||
|
if (arg->isMemGlobal())
|
||||||
|
{
|
||||||
|
set<int> found_rd;
|
||||||
|
if (RD.count(arg))
|
||||||
|
found_rd = RD.at(arg);
|
||||||
|
|
||||||
|
if (found_rd.size() == 0)
|
||||||
|
{
|
||||||
|
auto call_instr = call_sites[cur_func].size() ? call_sites[cur_func].front() : NULL;
|
||||||
|
while (call_instr && found_rd.size() == 0)
|
||||||
|
{
|
||||||
|
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
|
||||||
|
if (call_bblock->getRD_Out().count(arg))
|
||||||
|
found_rd = call_bblock->getRD_Out().at(arg);
|
||||||
|
|
||||||
|
|
||||||
|
call_instr = call_sites[call_func].size() ? call_sites[call_func].front() : NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_rd.size() == 1 && *found_rd.begin() == SAPFOR::CFG_VAL::UNINIT)
|
||||||
|
__spf_print(1, "variable %s has no definition\n", arg->getValue().c_str());
|
||||||
|
else if (found_rd.size() > 1)
|
||||||
|
{
|
||||||
|
auto first_instr = fullIR.at(cur_func).front()->getInstructions().begin();
|
||||||
|
auto stmt_after = (*first_instr)->getInstruction()->getOperator();
|
||||||
|
auto filename = stmt_after->fileName();
|
||||||
|
auto line = stmt_after->lineNumber();
|
||||||
|
auto var_name = arg->getValue().substr(arg->getValue().find('%') + 1);
|
||||||
|
__spf_print(1, "variable %s has multiple reaching definitions, further analysis is impossible\n", arg->getValue().c_str());
|
||||||
|
__spf_print(1, "Please specify value of variable %s on line %d of file %s\n", arg->getValue().c_str(), line, filename);
|
||||||
|
auto toAdd = make_tuple(stmt_after, var_name, MODE::BEFORE);
|
||||||
|
where_to_add.insert(toAdd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto instr_num = *found_rd.begin();
|
||||||
|
auto [func, instr, bblock] = IRByNumber(fullIR, instr_num);
|
||||||
|
set<SAPFOR::Argument*> new_worklist = { arg };
|
||||||
|
|
||||||
|
lookup_for_vars(where_to_add, new_worklist, instr, bblock, func, fullIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (const auto& call_instr : call_sites[cur_func])
|
||||||
|
{
|
||||||
|
set<SAPFOR::Argument*> new_worklist;
|
||||||
|
auto params_num = cur_func->funcParams.countOfPars;
|
||||||
|
|
||||||
|
auto [call_func, _, call_bblock] = IRByNumber(fullIR, call_instr->getNumber());
|
||||||
|
auto first_instr = call_bblock->getInstructions().begin();
|
||||||
|
auto cur_instr = find_if(first_instr, call_bblock->getInstructions().end(), [call_instr](SAPFOR::IR_Block* i) {
|
||||||
|
return i->getInstruction() == call_instr;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto& arg : worklist)
|
||||||
|
{
|
||||||
|
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
|
||||||
|
{
|
||||||
|
auto param_num = stoi(arg->getValue().substr(arg->getValue().find('%', arg->getValue().find('%') + 1) + 1));
|
||||||
|
auto param_instr = (cur_instr - (params_num - param_num));
|
||||||
|
auto param_arg = (*param_instr)->getInstruction()->getArg1();
|
||||||
|
processArgument(new_worklist, param_arg, param_instr, first_instr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lookup_for_vars(where_to_add, new_worklist, call_instr, call_bblock, call_func, fullIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_single_allocate(set<tuple<SgStatement*, string, MODE>>& where_to_add,
|
||||||
|
SgStatement* alloc_statement,
|
||||||
|
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||||
|
{
|
||||||
|
auto [func, instr, bblock] = stmtToIR(fullIR, alloc_statement);
|
||||||
|
|
||||||
|
auto first_instr = bblock->getInstructions().begin();
|
||||||
|
auto cur_instr = find_if(first_instr, bblock->getInstructions().end(), [instr](SAPFOR::IR_Block* i) {
|
||||||
|
return i->getInstruction() == instr;
|
||||||
|
});
|
||||||
|
auto alloc_instr = cur_instr;
|
||||||
|
|
||||||
|
// skip to F_CALL _ALLOC n
|
||||||
|
while ((*alloc_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::F_CALL ||
|
||||||
|
(*alloc_instr)->getInstruction()->getArg1()->getValue() != "_ALLOC")
|
||||||
|
alloc_instr++;
|
||||||
|
|
||||||
|
auto arrays_num = stoi((*alloc_instr)->getInstruction()->getArg2()->getValue());
|
||||||
|
|
||||||
|
set<SAPFOR::Argument*> worklist;
|
||||||
|
for (int i = 0; i < arrays_num; i++)
|
||||||
|
{
|
||||||
|
auto param_instr = --alloc_instr;
|
||||||
|
auto param_reg = (*param_instr)->getInstruction()->getArg1();
|
||||||
|
|
||||||
|
while ((*param_instr)->getInstruction()->getOperation() != SAPFOR::CFG_OP::LOAD ||
|
||||||
|
(*param_instr)->getInstruction()->getResult() != param_reg)
|
||||||
|
param_instr--;
|
||||||
|
|
||||||
|
|
||||||
|
auto dimensions_num = stoi((*param_instr)->getInstruction()->getArg2()->getValue());
|
||||||
|
|
||||||
|
for (int j = 0; j < dimensions_num; j++)
|
||||||
|
{
|
||||||
|
auto ref_instr = --param_instr;
|
||||||
|
if ((*ref_instr)->getInstruction()->getOperation() == SAPFOR::CFG_OP::RANGE)
|
||||||
|
{
|
||||||
|
vector<SAPFOR::Argument*> range_args = { (*ref_instr)->getInstruction()->getArg1(),
|
||||||
|
(*ref_instr)->getInstruction()->getArg2(),
|
||||||
|
(*ref_instr)->getInstruction()->getResult() };
|
||||||
|
for (auto& arg : range_args)
|
||||||
|
processArgument(worklist, arg, ref_instr, first_instr);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto arg = (*ref_instr)->getInstruction()->getArg1();
|
||||||
|
processArgument(worklist, arg, ref_instr, first_instr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lookup_for_vars(where_to_add, worklist, instr, bblock, func, fullIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handle_single_loop(set<tuple<SgStatement*, string, MODE>>& where_to_add,
|
||||||
|
SgStatement* loop_stmt,
|
||||||
|
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& fullIR)
|
||||||
|
{
|
||||||
|
auto [func, instr, bblock] = stmtToIR(fullIR, loop_stmt);
|
||||||
|
auto cur_instr = bblock->getInstructions().end() - 1;
|
||||||
|
|
||||||
|
set<SAPFOR::Argument*> worklist;
|
||||||
|
extract_vars_from_reg(worklist, (*cur_instr)->getInstruction()->getResult(), cur_instr, bblock->getInstructions().begin());
|
||||||
|
|
||||||
|
lookup_for_vars(where_to_add, worklist, (*cur_instr)->getInstruction(), bblock, func, fullIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void findParameters(ResultSet& foundParameters,
|
||||||
|
map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& fullIR,
|
||||||
|
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays)
|
||||||
|
{
|
||||||
|
set<tuple<SgStatement*, string, MODE>> where_to_add;
|
||||||
|
|
||||||
|
map<string, FuncInfo*> name_to_func;
|
||||||
|
for (const auto& [func, _] : fullIR)
|
||||||
|
name_to_func[func->funcName] = func;
|
||||||
|
|
||||||
|
for (auto& [func, bblocks] : fullIR)
|
||||||
|
{
|
||||||
|
for (const auto& block : bblocks)
|
||||||
|
{
|
||||||
|
for (const auto& ir_block : block->getInstructions())
|
||||||
|
{
|
||||||
|
auto instr = ir_block->getInstruction();
|
||||||
|
if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
|
||||||
|
{
|
||||||
|
auto func_name = instr->getArg1()->getValue();
|
||||||
|
auto func_info = name_to_func.find(func_name);
|
||||||
|
|
||||||
|
if (func_info != name_to_func.end())
|
||||||
|
call_sites[func_info->second].push_back(instr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set<SgStatement*> alloc_statements;
|
||||||
|
for (const auto& [func, bblocks] : fullIR)
|
||||||
|
{
|
||||||
|
for (const auto& block : bblocks)
|
||||||
|
{
|
||||||
|
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
|
||||||
|
{
|
||||||
|
auto op = (*instr)->getInstruction()->getOperator();
|
||||||
|
if (op && op->variant() == ALLOCATE_STMT)
|
||||||
|
alloc_statements.insert(op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set<SgStatement*> for_statements;
|
||||||
|
// Find all FOR statements in the program
|
||||||
|
for (const auto& [func, bblocks] : fullIR)
|
||||||
|
{
|
||||||
|
for (const auto& block : bblocks)
|
||||||
|
{
|
||||||
|
for (auto instr = block->getInstructions().begin(); instr != block->getInstructions().end(); ++instr)
|
||||||
|
{
|
||||||
|
auto op = (*instr)->getInstruction()->getOperator();
|
||||||
|
if (op && op->variant() == FOR_NODE)
|
||||||
|
for_statements.insert(op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& alloc_statement : alloc_statements)
|
||||||
|
handle_single_allocate(where_to_add, alloc_statement, fullIR);
|
||||||
|
|
||||||
|
for (const auto& stmt : for_statements)
|
||||||
|
handle_single_loop(where_to_add, stmt, fullIR);
|
||||||
|
|
||||||
|
for (const auto& [stmt_before, var_name, mode] : where_to_add)
|
||||||
|
{
|
||||||
|
stmt_before->switchToFile();
|
||||||
|
|
||||||
|
SgVariableSymb* var_symb = new SgVariableSymb(var_name.c_str());
|
||||||
|
SgVarRefExp* var = new SgVarRefExp(var_symb);
|
||||||
|
SgExprListExp* ex = new SgExprListExp();
|
||||||
|
auto assgn_op = new SgExpression(ASSGN_OP, var, NULL);
|
||||||
|
ex->setLhs(assgn_op);
|
||||||
|
|
||||||
|
SgExpression* parameter_op = new SgExpression(SPF_PARAMETER_OP, ex);
|
||||||
|
auto dir_list = new SgExprListExp();
|
||||||
|
dir_list->setLhs(parameter_op);
|
||||||
|
SgStatement* toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, dir_list, NULL, NULL);
|
||||||
|
|
||||||
|
toAdd->setlineNumber(stmt_before->lineNumber());
|
||||||
|
toAdd->setLocalLineNumber(stmt_before->lineNumber());
|
||||||
|
toAdd->setFileId(stmt_before->getFileId());
|
||||||
|
toAdd->setProject(stmt_before->getProject());
|
||||||
|
|
||||||
|
//NOTE: only for debbuging, results will be transferred to the visualizer
|
||||||
|
/*if (mode == MODE::AFTER)
|
||||||
|
stmt_before->insertStmtAfter(*toAdd, *stmt_before->controlParent());
|
||||||
|
else
|
||||||
|
stmt_before->insertStmtBefore(*toAdd, *stmt_before->controlParent());*/
|
||||||
|
|
||||||
|
foundParameters.insert(make_tuple(stmt_before->fileName(), stmt_before->lineNumber(), var_name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
std::map< std::pair<std::string, int>, std::set<std::string>> findParameters(const std::map<std::string, std::vector<DefUseList>> &defUseByFunctions, const std::map<std::string, CommonBlock*> &commonBlocks, const std::map<std::string, std::vector<FuncInfo*>> &allFuncInfo);
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../GraphCall/graph_calls.h"
|
||||||
|
|
||||||
|
using ResultSet = std::set<std::tuple<std::string, int, std::string>>;
|
||||||
|
|
||||||
|
void findParameters(ResultSet& foundParameters,
|
||||||
|
std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& fullIR,
|
||||||
|
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "ProjectManipulation/ConvertFiles.h"
|
#include "ProjectManipulation/ConvertFiles.h"
|
||||||
|
|
||||||
#include "LoopAnalyzer/loop_analyzer.h"
|
#include "LoopAnalyzer/loop_analyzer.h"
|
||||||
|
#include "LoopAnalyzer/implicit_loops_analyzer.h"
|
||||||
|
|
||||||
#include "GraphCall/graph_calls_func.h"
|
#include "GraphCall/graph_calls_func.h"
|
||||||
#include "GraphLoop/graph_loops_func.h"
|
#include "GraphLoop/graph_loops_func.h"
|
||||||
@@ -95,6 +96,7 @@
|
|||||||
#include "CFGraph/IR.h"
|
#include "CFGraph/IR.h"
|
||||||
#include "CFGraph/RD_subst.h"
|
#include "CFGraph/RD_subst.h"
|
||||||
#include "CFGraph/CFGraph.h"
|
#include "CFGraph/CFGraph.h"
|
||||||
|
#include "CFGraph/IR_SSAForm.h"
|
||||||
|
|
||||||
#include "CFGraph/live_variable_analysis.h"
|
#include "CFGraph/live_variable_analysis.h"
|
||||||
#include "CFGraph/private_variables_analysis.h"
|
#include "CFGraph/private_variables_analysis.h"
|
||||||
@@ -398,11 +400,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
__spf_print(DEBUG_LVL1, "RUN PASS with name %s\n", passNames[curr_regime]);
|
__spf_print(DEBUG_LVL1, "RUN PASS with name %s\n", passNames[curr_regime]);
|
||||||
|
|
||||||
auto toSendStrMessage = string(passNames[curr_regime]);
|
auto toSendStrMessage = string(passNames[curr_regime]);
|
||||||
#ifdef _WIN32
|
sendMessage_1lvl(1, toSendStrMessage);
|
||||||
sendMessage_1lvl(wstring(L"выполняется проход '") + wstring(toSendStrMessage.begin(), toSendStrMessage.end()) + L"'");
|
|
||||||
#else
|
|
||||||
sendMessage_1lvl(wstring(L"running pass '") + wstring(toSendStrMessage.begin(), toSendStrMessage.end()) + L"'");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const int n = project.numberOfFiles();
|
const int n = project.numberOfFiles();
|
||||||
bool verifyOK = true;
|
bool verifyOK = true;
|
||||||
@@ -450,11 +448,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
SgFile *file = &(project.file(i));
|
SgFile *file = &(project.file(i));
|
||||||
|
|
||||||
toSendStrMessage = file->filename();
|
toSendStrMessage = file->filename();
|
||||||
#ifdef _WIN32
|
sendMessage_2lvl(3, toSendStrMessage);
|
||||||
sendMessage_2lvl(wstring(L"обработка файла '") + wstring(toSendStrMessage.begin(), toSendStrMessage.end()) + L"'");
|
|
||||||
#else
|
|
||||||
sendMessage_2lvl(wstring(L"processing file '") + wstring(toSendStrMessage.begin(), toSendStrMessage.end()) + L"'");
|
|
||||||
#endif
|
|
||||||
sendMessage_progress(std::to_wstring((int)(((double)(n - i) / n) * 100)));
|
sendMessage_progress(std::to_wstring((int)(((double)(n - i) / n) * 100)));
|
||||||
|
|
||||||
const char *file_name = file->filename();
|
const char *file_name = file->filename();
|
||||||
@@ -1027,8 +1021,19 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
if(func->funcPointer->variant() != ENTRY_STAT)
|
if(func->funcPointer->variant() != ENTRY_STAT)
|
||||||
countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
|
countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
|
||||||
}
|
}
|
||||||
|
else if (curr_regime == BUILD_IR_SSA_FORM)
|
||||||
|
{
|
||||||
|
auto irFound = getIRByFilename(fullIR, file_name);
|
||||||
|
buildFuncIRSSAForm(irFound, fullIR[irFound], fullIR_SSA);
|
||||||
|
}
|
||||||
|
else if (curr_regime == FIND_IMPLICIT_LOOPS)
|
||||||
|
{
|
||||||
|
auto itFound = loopGraph.find(file_name);
|
||||||
|
auto irFound = getIRByFilename(fullIR_SSA, file_name);
|
||||||
|
findImplicitLoops(fullIR_SSA[irFound], itFound->second);
|
||||||
|
}
|
||||||
else if (curr_regime == FIND_PRIVATE_ARRAYS)
|
else if (curr_regime == FIND_PRIVATE_ARRAYS)
|
||||||
FindPrivateArrays(loopGraph, fullIR);
|
findPrivateArrays(loopGraph, fullIR);
|
||||||
else if (curr_regime == TEST_PASS)
|
else if (curr_regime == TEST_PASS)
|
||||||
{
|
{
|
||||||
//test pass
|
//test pass
|
||||||
@@ -1057,7 +1062,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
throw -11;
|
throw -11;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage_2lvl(wstring(L""));
|
sendMessage_2lvl(2);
|
||||||
// ********************************** ///
|
// ********************************** ///
|
||||||
/// SECOND AGGREGATION STEP ///
|
/// SECOND AGGREGATION STEP ///
|
||||||
// ********************************** ///
|
// ********************************** ///
|
||||||
@@ -1895,7 +1900,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
else if (curr_regime == RENAME_SYMBOLS)
|
else if (curr_regime == RENAME_SYMBOLS)
|
||||||
runRenameSymbols(&project, commonBlocks);
|
runRenameSymbols(&project, commonBlocks);
|
||||||
else if (curr_regime == FIND_PARAMETERS)
|
else if (curr_regime == FIND_PARAMETERS)
|
||||||
parametersOfProject = findParameters(defUseByFunctions, commonBlocks, allFuncInfo);
|
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(0));
|
auto CFG_forFile = buildCFG(commonBlocks, allFuncInfo_IR, SAPFOR::CFG_Settings(0));
|
||||||
@@ -1928,7 +1933,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
|||||||
const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.;
|
const float elapsedGlobal = duration_cast<milliseconds>(high_resolution_clock::now() - globalTime).count() / 1000.;
|
||||||
__spf_print(1, "PROFILE: time for this pass = %f sec (total %f sec)\n", elapsed, elapsedGlobal);
|
__spf_print(1, "PROFILE: time for this pass = %f sec (total %f sec)\n", elapsed, elapsedGlobal);
|
||||||
|
|
||||||
sendMessage_2lvl(wstring(L""));
|
sendMessage_2lvl(2);
|
||||||
if (internalExit != 0)
|
if (internalExit != 0)
|
||||||
throw -1;
|
throw -1;
|
||||||
|
|
||||||
@@ -2662,35 +2667,12 @@ int main(int argc, char **argv)
|
|||||||
printStackTrace();
|
printStackTrace();
|
||||||
printf("exception occurred\n");
|
printf("exception occurred\n");
|
||||||
|
|
||||||
FILE* outF = fopen((string(VISUALIZER_DATA_PATH) + "/error_messages.json").c_str(), "w");
|
dumpMessages(true, SPF_messages, VISUALIZER_DATA_PATH);
|
||||||
if (outF)
|
|
||||||
{
|
|
||||||
json byFileArray = json::array();
|
|
||||||
for (auto& byFile : SPF_messages)
|
|
||||||
{
|
|
||||||
json inFile;
|
|
||||||
inFile["file"] = byFile.first;
|
|
||||||
|
|
||||||
json messages = json::array();
|
|
||||||
for (auto& message : byFile.second)
|
|
||||||
{
|
|
||||||
message.print(byFile.first);
|
|
||||||
messages.push_back(message.toJson());
|
|
||||||
}
|
|
||||||
inFile["messages"] = messages;
|
|
||||||
byFileArray.push_back(inFile);
|
|
||||||
}
|
|
||||||
json allMessages;
|
|
||||||
allMessages["allMessages"] = byFileArray;
|
|
||||||
|
|
||||||
fprintf(outF, "%s", allMessages.dump().c_str());
|
|
||||||
fclose(outF);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
dumpMessages(false, SPF_messages, VISUALIZER_DATA_PATH);
|
||||||
|
|
||||||
deleteAllAllocatedData(withDel);
|
deleteAllAllocatedData(withDel);
|
||||||
|
|
||||||
|
|
||||||
#if _WIN32 && _DEBUG
|
#if _WIN32 && _DEBUG
|
||||||
if (leakMemDump)
|
if (leakMemDump)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -182,6 +182,8 @@ enum passes {
|
|||||||
|
|
||||||
SET_IMPLICIT_NONE,
|
SET_IMPLICIT_NONE,
|
||||||
RENAME_INLCUDES,
|
RENAME_INLCUDES,
|
||||||
|
FIND_IMPLICIT_LOOPS,
|
||||||
|
BUILD_IR_SSA_FORM,
|
||||||
|
|
||||||
FIND_PRIVATE_ARRAYS,
|
FIND_PRIVATE_ARRAYS,
|
||||||
|
|
||||||
@@ -369,6 +371,8 @@ static void setPassValues()
|
|||||||
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
|
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
|
||||||
passNames[RENAME_INLCUDES] = "RENAME_INLCUDES";
|
passNames[RENAME_INLCUDES] = "RENAME_INLCUDES";
|
||||||
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
|
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
|
||||||
|
passNames[FIND_IMPLICIT_LOOPS] = "FIND_IMPLICIT_LOOPS";
|
||||||
|
passNames[BUILD_IR_SSA_FORM] = "BUILD_IR_SSA_FORM";
|
||||||
passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS";
|
passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS";
|
||||||
|
|
||||||
passNames[TEST_PASS] = "TEST_PASS";
|
passNames[TEST_PASS] = "TEST_PASS";
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ std::map<int, UserFiles> filesInfo; // information about open,close,write and re
|
|||||||
//
|
//
|
||||||
|
|
||||||
//for FIND_PARAMETERS
|
//for FIND_PARAMETERS
|
||||||
std::map< std::pair<std::string, int>, std::set<std::string>> parametersOfProject; // [file, line] -> set[vars]
|
std::set<std::tuple<std::string, int, std::string>> parametersOfProject; // [file, line, varname]
|
||||||
//
|
//
|
||||||
|
|
||||||
//for GET_MIN_MAX_BLOCK_DIST
|
//for GET_MIN_MAX_BLOCK_DIST
|
||||||
@@ -181,3 +181,7 @@ bool passNamesWasInit = false;
|
|||||||
|
|
||||||
std::map<PTR_BFND, std::pair<std::string, int>> sgStats;
|
std::map<PTR_BFND, std::pair<std::string, int>> sgStats;
|
||||||
std::map<PTR_LLND, std::pair<std::string, int>> sgExprs;
|
std::map<PTR_LLND, std::pair<std::string, int>> sgExprs;
|
||||||
|
|
||||||
|
//for FIND_IMPLICIT_LOOPS and BUILD_IR_SSA_FORM
|
||||||
|
map<FuncInfo*, vector<SAPFOR::BasicBlock*>> fullIR_SSA;
|
||||||
|
//
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "../../CFGraph/CFGraph.h"
|
||||||
|
|
||||||
using std::map;
|
using std::map;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
@@ -88,13 +90,13 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
|
|||||||
instr_operation == SAPFOR::CFG_OP::STORE)
|
instr_operation == SAPFOR::CFG_OP::STORE)
|
||||||
last_stack_op_useful = true;
|
last_stack_op_useful = true;
|
||||||
|
|
||||||
for (auto e : res)
|
for (auto& e : res)
|
||||||
{
|
{
|
||||||
def.insert(e);
|
def.insert(e);
|
||||||
use.erase(e);
|
use.erase(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto e : args)
|
for (auto& e : args)
|
||||||
{
|
{
|
||||||
use.insert(e);
|
use.insert(e);
|
||||||
def.erase(e);
|
def.erase(e);
|
||||||
@@ -164,7 +166,7 @@ public:
|
|||||||
{
|
{
|
||||||
const auto& example = dynamic_cast<DeadCodeAnalysisNode*>(*prev.begin())->next_notempty_out;
|
const auto& example = dynamic_cast<DeadCodeAnalysisNode*>(*prev.begin())->next_notempty_out;
|
||||||
|
|
||||||
for (auto p : prev)
|
for (auto& p : prev)
|
||||||
{
|
{
|
||||||
DeadCodeAnalysisNode* next = dynamic_cast<DeadCodeAnalysisNode*>(p);
|
DeadCodeAnalysisNode* next = dynamic_cast<DeadCodeAnalysisNode*>(p);
|
||||||
|
|
||||||
@@ -188,7 +190,7 @@ public:
|
|||||||
{
|
{
|
||||||
set<DeadCodeAnalysisNode*> current = {};
|
set<DeadCodeAnalysisNode*> current = {};
|
||||||
|
|
||||||
for (auto nextP : getPrevBlocks())
|
for (auto& nextP : getPrevBlocks())
|
||||||
{
|
{
|
||||||
DeadCodeAnalysisNode* next = dynamic_cast<DeadCodeAnalysisNode*>(nextP);
|
DeadCodeAnalysisNode* next = dynamic_cast<DeadCodeAnalysisNode*>(nextP);
|
||||||
|
|
||||||
@@ -428,49 +430,7 @@ int removeDeadCode(SgStatement* func,
|
|||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
|
|
||||||
auto& cfg_pair = *(cfg.begin());
|
auto& cfg_pair = *(cfg.begin());
|
||||||
|
removedUnreachableBlocks(cfg_pair.second);
|
||||||
// delete unreachable blocks
|
|
||||||
|
|
||||||
set<SAPFOR::BasicBlock*> reachable;
|
|
||||||
|
|
||||||
for (auto b : cfg_pair.second)
|
|
||||||
if(b->getInstructions().front()->isHeader() ||
|
|
||||||
b->getInstructions().front()->getInstruction()->getOperation() == SAPFOR::CFG_OP::ENTRY)
|
|
||||||
reachable.insert(b);
|
|
||||||
|
|
||||||
set<SAPFOR::BasicBlock*> worklist = reachable;
|
|
||||||
while (worklist.size() != 0)
|
|
||||||
{
|
|
||||||
set<SAPFOR::BasicBlock*> to_insert;
|
|
||||||
|
|
||||||
for(auto b : worklist)
|
|
||||||
for(auto next: b->getNext())
|
|
||||||
if(reachable.insert(next).second)
|
|
||||||
to_insert.insert(next);
|
|
||||||
|
|
||||||
worklist = to_insert;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto remove_unreachable_it = remove_if(cfg_pair.second.begin(), cfg_pair.second.end(),
|
|
||||||
[&reachable](SAPFOR::BasicBlock* b)
|
|
||||||
{
|
|
||||||
if (reachable.find(b) == reachable.end())
|
|
||||||
{
|
|
||||||
for(auto next: b->getNext())
|
|
||||||
if(reachable.find(next) != reachable.end())
|
|
||||||
next->removePrev(b);
|
|
||||||
|
|
||||||
delete b;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
reachable.clear();
|
|
||||||
|
|
||||||
cfg_pair.second.erase(remove_unreachable_it, cfg_pair.second.end());
|
|
||||||
|
|
||||||
#if DEBUG_IR
|
#if DEBUG_IR
|
||||||
dumpCFG({ cfg_pair }, false);
|
dumpCFG({ cfg_pair }, false);
|
||||||
@@ -481,7 +441,7 @@ int removeDeadCode(SgStatement* func,
|
|||||||
map<string, FuncInfo*> funcByName;
|
map<string, FuncInfo*> funcByName;
|
||||||
|
|
||||||
for (auto& byFile : allFuncs)
|
for (auto& byFile : allFuncs)
|
||||||
for (auto byFunc : byFile.second)
|
for (auto& byFunc : byFile.second)
|
||||||
funcByName[byFunc->funcName] = byFunc;
|
funcByName[byFunc->funcName] = byFunc;
|
||||||
|
|
||||||
DeadCodeAnalysis analysis_object(func_parameters, funcByName);
|
DeadCodeAnalysis analysis_object(func_parameters, funcByName);
|
||||||
|
|||||||
@@ -1776,11 +1776,8 @@ static bool inliner(const string& fileName_in, const string& funcName, const int
|
|||||||
point.currCall = func->funcName;
|
point.currCall = func->funcName;
|
||||||
|
|
||||||
__spf_print(1, " INLINE %s - ", func->funcName.c_str());
|
__spf_print(1, " INLINE %s - ", func->funcName.c_str());
|
||||||
#ifdef _WIN32
|
sendMessage_2lvl(6, func->funcName);
|
||||||
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(func->funcName.begin(), func->funcName.end()) + L"'");
|
|
||||||
#else
|
|
||||||
sendMessage_2lvl(wstring(L"inlinig of function '") + wstring(func->funcName.begin(), func->funcName.end()) + L"'");
|
|
||||||
#endif
|
|
||||||
//1 level
|
//1 level
|
||||||
bool isInlined = run_inliner(funcMap, toInsert, SPF_messages, fileName, func, newSymbsToDeclare, point, commonBlocks);
|
bool isInlined = run_inliner(funcMap, toInsert, SPF_messages, fileName, func, newSymbsToDeclare, point, commonBlocks);
|
||||||
__spf_print(1, "%s\n", isInlined ? "done" : "fault");
|
__spf_print(1, "%s\n", isInlined ? "done" : "fault");
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "expr_transform.h"
|
#include "expr_transform.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "SgUtils.h"
|
#include "SgUtils.h"
|
||||||
|
#include "utils.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@@ -17,22 +18,9 @@ using std::make_pair;
|
|||||||
using std::queue;
|
using std::queue;
|
||||||
using std::wstring;
|
using std::wstring;
|
||||||
|
|
||||||
static int gcd(int a, int b)
|
|
||||||
{
|
|
||||||
while (a != b)
|
|
||||||
{
|
|
||||||
if (a > b)
|
|
||||||
a = a - b;
|
|
||||||
else
|
|
||||||
b = b - a;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SgSymbol* getLoopSymbol(const LoopGraph* loop)
|
static SgSymbol* getLoopSymbol(const LoopGraph* loop)
|
||||||
{
|
{
|
||||||
if (!loop || !loop->isFor)
|
if (!loop || !loop->isFor())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
SgForStmt* stmt = (SgForStmt*)loop->loop->GetOriginal();
|
SgForStmt* stmt = (SgForStmt*)loop->loop->GetOriginal();
|
||||||
@@ -679,12 +667,12 @@ static void renameIterationVariables(LoopGraph* loop, const map<SgSymbol*, SgSym
|
|||||||
{
|
{
|
||||||
if (loop)
|
if (loop)
|
||||||
{
|
{
|
||||||
string& loopName = loop->loopSymbol;
|
const string& loopName = loop->loopSymbol();
|
||||||
for (auto& pair : symbols)
|
for (auto& [from, to] : symbols)
|
||||||
{
|
{
|
||||||
if (pair.first->identifier() == loopName)
|
if (from->identifier() == loopName)
|
||||||
{
|
{
|
||||||
loop->loopSymbol = (string)pair.second->identifier();
|
loop->loopSymbols.replaceMainVar(to->identifier());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -703,9 +691,9 @@ static void renameVariablesInLoop(LoopGraph* loop, const map<SgSymbol*, SgSymbol
|
|||||||
if (st->variant() == FOR_NODE)
|
if (st->variant() == FOR_NODE)
|
||||||
{
|
{
|
||||||
SgForStmt* for_st = (SgForStmt*)st;
|
SgForStmt* for_st = (SgForStmt*)st;
|
||||||
for (auto& pair : symbols)
|
for (auto& [from, to] : symbols)
|
||||||
if (isEqSymbols(pair.first, for_st->symbol()))
|
if (isEqSymbols(from, for_st->symbol()))
|
||||||
for_st->setDoName(*pair.second);
|
for_st->setDoName(*to);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
@@ -722,12 +710,12 @@ static void renamePrivatesInMap(LoopGraph* loop, const map<SgSymbol*, SgSymbol*>
|
|||||||
for (auto& priv : privates->second)
|
for (auto& priv : privates->second)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto& pair : symbols)
|
for (auto& [from, to] : symbols)
|
||||||
{
|
{
|
||||||
if (isEqSymbols(priv, pair.first))
|
if (isEqSymbols(priv, from))
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
newList.insert(pair.second);
|
newList.insert(to);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1385,7 +1373,6 @@ static int getNewStep(SgForStmt* firstLoopStmt, SgForStmt* loopStmt)
|
|||||||
step2Val = step2->valueInteger();
|
step2Val = step2->valueInteger();
|
||||||
|
|
||||||
int stepGcd = gcd(std::abs(step1Val), std::abs(step2Val));
|
int stepGcd = gcd(std::abs(step1Val), std::abs(step2Val));
|
||||||
|
|
||||||
int newStep = stepGcd;
|
int newStep = stepGcd;
|
||||||
|
|
||||||
int startDifference = 0;
|
int startDifference = 0;
|
||||||
@@ -1603,7 +1590,7 @@ static bool combine(LoopGraph* firstLoop, const vector<LoopGraph*>& nextLoops, s
|
|||||||
bool wasCombine = false;
|
bool wasCombine = false;
|
||||||
for (LoopGraph* loop : nextLoops)
|
for (LoopGraph* loop : nextLoops)
|
||||||
{
|
{
|
||||||
if (!loop->isFor)
|
if (!loop->isFor())
|
||||||
return wasCombine;
|
return wasCombine;
|
||||||
|
|
||||||
int perfectLoop = std::min(firstLoop->perfectLoop, loop->perfectLoop);
|
int perfectLoop = std::min(firstLoop->perfectLoop, loop->perfectLoop);
|
||||||
@@ -1736,7 +1723,7 @@ static bool tryToCombine(vector<LoopGraph*>& loopGraphs, map<LoopGraph*, set<SgS
|
|||||||
{
|
{
|
||||||
LoopGraph* loop = loops[z];
|
LoopGraph* loop = loops[z];
|
||||||
newloopGraphs.push_back(loop);
|
newloopGraphs.push_back(loop);
|
||||||
if (!loop->isFor)
|
if (!loop->isFor())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vector<LoopGraph*> nextLoops = getNextLoops(loop, loopGraphs, -1);
|
vector<LoopGraph*> nextLoops = getNextLoops(loop, loopGraphs, -1);
|
||||||
|
|||||||
@@ -1035,7 +1035,7 @@ int splitLoops(SgFile *file, vector<LoopGraph*> &loopGraphs, vector<Messages> &m
|
|||||||
|
|
||||||
for (auto &loopPair : mapLoopGraph)
|
for (auto &loopPair : mapLoopGraph)
|
||||||
{
|
{
|
||||||
if (!loopPair.second->isFor)
|
if (!loopPair.second->isFor())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LoopGraph *loop = loopPair.second;
|
LoopGraph *loop = loopPair.second;
|
||||||
|
|||||||
@@ -2257,7 +2257,7 @@ void removePrivatesAnalysis(string filename,
|
|||||||
{
|
{
|
||||||
for (LoopGraph* loop : loopGraphs)
|
for (LoopGraph* loop : loopGraphs)
|
||||||
{
|
{
|
||||||
if (!loop->isFor)
|
if (!loop->isFor())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SgForStmt* loopStmt = (SgForStmt*)loop->loop->GetOriginal();
|
SgForStmt* loopStmt = (SgForStmt*)loop->loop->GetOriginal();
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ static void fillIterationVariables(const LoopGraph* loop, set<string>& vars, int
|
|||||||
{
|
{
|
||||||
if (dimensions == -1)
|
if (dimensions == -1)
|
||||||
{
|
{
|
||||||
vars.insert(loop->loopSymbol);
|
vars.insert(loop->loopSymbol());
|
||||||
for (LoopGraph* child : loop->children)
|
for (LoopGraph* child : loop->children)
|
||||||
fillIterationVariables(child, vars);
|
fillIterationVariables(child, vars);
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ static void fillIterationVariables(const LoopGraph* loop, set<string>& vars, int
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < dimensions; ++i)
|
for (int i = 0; i < dimensions; ++i)
|
||||||
{
|
{
|
||||||
vars.insert(loop->loopSymbol);
|
vars.insert(loop->loopSymbol());
|
||||||
if (i != dimensions - 1)
|
if (i != dimensions - 1)
|
||||||
loop = loop->children[0];
|
loop = loop->children[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,25 +88,37 @@ static void populateDistributedIoArrays(map<SgSymbol*, set<SgStatement*>>& array
|
|||||||
case READ_STAT:
|
case READ_STAT:
|
||||||
case WRITE_STAT:
|
case WRITE_STAT:
|
||||||
{
|
{
|
||||||
|
|
||||||
SgExpression* spec = stat->expr(1);
|
SgExpression* spec = stat->expr(1);
|
||||||
__spf_print(DEBUG_TRACE, "[%d: %s (%d)]\n", 2000, spec->rhs()->unparse(), spec->rhs()->variant());
|
|
||||||
if (!spec || spec->variant() != EXPR_LIST ||
|
if (spec->variant() == SPEC_PAIR)
|
||||||
spec->lhs()->variant() != SPEC_PAIR ||
|
{
|
||||||
!spec->rhs() || !spec->rhs()->lhs() || spec->rhs()->lhs()->variant() != SPEC_PAIR)
|
if (spec->rhs()->variant() != KEYWORD_VAL || spec->rhs()->sunparse() != "*")
|
||||||
|
{
|
||||||
|
need_replace = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (spec)
|
||||||
|
{
|
||||||
|
auto *kv = spec->lhs();
|
||||||
|
if (!kv || kv->variant() != SPEC_PAIR || !kv->rhs())
|
||||||
{
|
{
|
||||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SgExpression* unit_val = spec->lhs()->rhs(), * fmt_val = spec->rhs()->lhs()->rhs();
|
if (kv->rhs()->variant() != KEYWORD_VAL || kv->rhs()->sunparse() != "*")
|
||||||
|
{
|
||||||
if (unit_val->variant() != KEYWORD_VAL || unit_val->sunparse() != "*" ||
|
|
||||||
fmt_val->variant() != KEYWORD_VAL || fmt_val->sunparse() != "*")
|
|
||||||
need_replace = true;
|
need_replace = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spec = spec->rhs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -136,7 +148,8 @@ static void replaceArrayRec(SgSymbol* arr, SgSymbol* replace_by, SgExpression* e
|
|||||||
if (!exp)
|
if (!exp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (exp->symbol() && exp->symbol()->identifier() && strcmp(exp->symbol()->identifier(), arr->identifier()) == 0)
|
if (isArrayRef(exp) &&
|
||||||
|
strcmp(exp->symbol()->identifier(), arr->identifier()) == 0)
|
||||||
{
|
{
|
||||||
has_read |= from_read;
|
has_read |= from_read;
|
||||||
has_write |= from_write;
|
has_write |= from_write;
|
||||||
@@ -202,11 +215,9 @@ static void copyArrayBetweenStatements(SgSymbol* replace_symb, SgSymbol* replace
|
|||||||
while (start->lexNext() && !isSgExecutableStatement(start->lexNext()))
|
while (start->lexNext() && !isSgExecutableStatement(start->lexNext()))
|
||||||
start = start->lexNext();
|
start = start->lexNext();
|
||||||
|
|
||||||
auto* stop = last->lexNext();
|
|
||||||
|
|
||||||
bool has_read = false, has_write = false;
|
bool has_read = false, has_write = false;
|
||||||
|
|
||||||
for (auto* st = start->lexNext(); st && st != stop->lexPrev(); st = st->lexNext())
|
for (auto* st = start->lexNext(); st && st != last; st = st->lexNext())
|
||||||
replaceArrayRec(replace_symb, replace_by, st, has_read, has_write);
|
replaceArrayRec(replace_symb, replace_by, st, has_read, has_write);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2215,6 +2215,7 @@ void restoreAssignsFromLoop(SgFile* file, const map<DIST::Array*, set<DIST::Arra
|
|||||||
if (secondConv && notDeletedVectorAssign(move.first))
|
if (secondConv && notDeletedVectorAssign(move.first))
|
||||||
{
|
{
|
||||||
move.first->setVariant(-abs(move.first->variant()));
|
move.first->setVariant(-abs(move.first->variant()));
|
||||||
|
__spf_print(1, " save assign\n");
|
||||||
|
|
||||||
if (needDecl) // declare loops symbol
|
if (needDecl) // declare loops symbol
|
||||||
{
|
{
|
||||||
@@ -2237,8 +2238,10 @@ void restoreAssignsFromLoop(SgFile* file, const map<DIST::Array*, set<DIST::Arra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
move.second->setVariant(-abs(move.second->variant()));
|
move.second->setVariant(-abs(move.second->variant()));
|
||||||
|
__spf_print(1, " restored assign\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Distribution/Array.h"
|
||||||
|
|
||||||
enum varType { SCALAR, ARRAY, CONST, ANOTHER };
|
enum varType { SCALAR, ARRAY, CONST, ANOTHER };
|
||||||
|
|
||||||
struct CommonVariableUse
|
struct CommonVariableUse
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
|
|||||||
|
|
||||||
list({ REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN }) <= Pass(RESOLVE_PAR_REGIONS);
|
list({ REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN }) <= Pass(RESOLVE_PAR_REGIONS);
|
||||||
|
|
||||||
list({ REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN, FILL_PAR_REGIONS}) <= Pass(REMOVE_DIST_ARRAYS_FROM_IO);
|
list({ FILL_PAR_REGIONS, REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN }) <= Pass(REMOVE_DIST_ARRAYS_FROM_IO);
|
||||||
|
|
||||||
Pass(REVERT_SUBST_EXPR_RD) <= Pass(EXPAND_EXTRACT_PAR_REGION);
|
Pass(REVERT_SUBST_EXPR_RD) <= Pass(EXPAND_EXTRACT_PAR_REGION);
|
||||||
|
|
||||||
@@ -316,7 +316,9 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
|
|||||||
|
|
||||||
list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE);
|
list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE);
|
||||||
|
|
||||||
list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS);
|
list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2, BUILD_IR }) <= Pass(BUILD_IR_SSA_FORM) <= Pass(FIND_IMPLICIT_LOOPS);
|
||||||
|
|
||||||
|
list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2, BUILD_IR, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS);
|
||||||
|
|
||||||
passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS,
|
passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS,
|
||||||
EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,
|
EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,
|
||||||
|
|||||||
@@ -3219,6 +3219,7 @@ bool isArrayRef(SgExpression* ex)
|
|||||||
{
|
{
|
||||||
SgArrayRefExp* arrayRef = isSgArrayRefExp(ex);
|
SgArrayRefExp* arrayRef = isSgArrayRefExp(ex);
|
||||||
if (arrayRef)
|
if (arrayRef)
|
||||||
|
{
|
||||||
if (isArrayType(ex->symbol()->type()))
|
if (isArrayType(ex->symbol()->type()))
|
||||||
{
|
{
|
||||||
auto type = isSgArrayType(ex->symbol()->type());
|
auto type = isSgArrayType(ex->symbol()->type());
|
||||||
@@ -3226,6 +3227,7 @@ bool isArrayRef(SgExpression* ex)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,15 +14,13 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <string>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "utils.h"
|
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
|
#include "utils.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include "graph_loops.h"
|
#include "graph_loops.h"
|
||||||
@@ -1738,3 +1736,37 @@ void copyStringToShort(short*& result, const string& resVal, bool withEnd)
|
|||||||
if (withEnd)
|
if (withEnd)
|
||||||
result[resVal.size()] = (short)'\0';
|
result[resVal.size()] = (short)'\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dumpMessages(bool inCatch, const map<string, vector<Messages>>& messages, const char *vis_path)
|
||||||
|
{
|
||||||
|
json byFileArray = json::array();
|
||||||
|
for (auto& byFile : messages)
|
||||||
|
{
|
||||||
|
json inFile;
|
||||||
|
inFile["file"] = byFile.first;
|
||||||
|
|
||||||
|
json messages = json::array();
|
||||||
|
for (auto& message : byFile.second)
|
||||||
|
{
|
||||||
|
if (inCatch)
|
||||||
|
message.print(byFile.first);
|
||||||
|
messages.push_back(message.toJson());
|
||||||
|
}
|
||||||
|
inFile["messages"] = messages;
|
||||||
|
byFileArray.push_back(inFile);
|
||||||
|
}
|
||||||
|
json allMessages;
|
||||||
|
allMessages["allMessages"] = byFileArray;
|
||||||
|
|
||||||
|
const string dump = allMessages.dump().c_str();
|
||||||
|
|
||||||
|
if (dump.size())
|
||||||
|
{
|
||||||
|
FILE* outF = fopen((string(vis_path) + "/error_messages.json").c_str(), "w");
|
||||||
|
if (outF)
|
||||||
|
{
|
||||||
|
fprintf(outF, "%s", dump.c_str());
|
||||||
|
fclose(outF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
struct Messages;
|
||||||
struct DataDirective;
|
struct DataDirective;
|
||||||
|
|
||||||
namespace Distribution
|
namespace Distribution
|
||||||
{
|
{
|
||||||
class Array;
|
class Array;
|
||||||
@@ -98,3 +100,17 @@ std::set<DIST::Array*> fillDistributedArraysD(const DataDirective& dataDirective
|
|||||||
std::set<std::string> fillDistributedArrays(const DataDirective& dataDirectives, const std::map<DIST::Array*, std::tuple<int, std::string, std::string>>& tableOfUniqNamesByArray, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, bool onlyCommon = false, bool shortName = false);
|
std::set<std::string> fillDistributedArrays(const DataDirective& dataDirectives, const std::map<DIST::Array*, std::tuple<int, std::string, std::string>>& tableOfUniqNamesByArray, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, bool onlyCommon = false, bool shortName = false);
|
||||||
|
|
||||||
void copyStringToShort(short*& result, const std::string& resVal, bool withEnd = true);
|
void copyStringToShort(short*& result, const std::string& resVal, bool withEnd = true);
|
||||||
|
void dumpMessages(bool inCatch, const std::map<std::string, std::vector<Messages>>& messages, const char* vis_path);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline T gcd(T a, T b)
|
||||||
|
{
|
||||||
|
while (a != b)
|
||||||
|
{
|
||||||
|
if (a > b)
|
||||||
|
a = a - b;
|
||||||
|
else
|
||||||
|
b = b - a;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION_SPF "2423"
|
#define VERSION_SPF "2432"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
#include "SendMessage.h"
|
#include "SendMessage.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@@ -144,10 +145,116 @@ static int decodeMessage(const string& message, vector<string>& pars, int &winH,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendMessage_1lvl(const wstring& toSend) { MessageManager::sendFirstLvl (toSend); }
|
static void sendMessage_1lvl(const wstring& toSend) { MessageManager::sendFirstLvl (toSend); }
|
||||||
void sendMessage_2lvl(const wstring& toSend) { MessageManager::sendSecondLvl(toSend); }
|
static void sendMessage_2lvl(const wstring& toSend) { MessageManager::sendSecondLvl(toSend); }
|
||||||
void sendMessage_progress(const wstring& toSend) { MessageManager::sendProgress (toSend); }
|
void sendMessage_progress(const wstring& toSend) { MessageManager::sendProgress (toSend); }
|
||||||
|
|
||||||
|
void sendMessage_1lvl(int kind, ...)
|
||||||
|
{
|
||||||
|
va_list list;
|
||||||
|
va_start(list, kind);
|
||||||
|
|
||||||
|
if (kind == 0)
|
||||||
|
{
|
||||||
|
int iters = va_arg(list, int);
|
||||||
|
#ifdef _WIN32
|
||||||
|
sendMessage_1lvl(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring(iters) + L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||||
|
#else
|
||||||
|
sendMessage_1lvl(L"running " + std::to_wstring(iters) + L" iteration of syntax analisys");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (kind == 1)
|
||||||
|
{
|
||||||
|
string str = va_arg(list, string);
|
||||||
|
#ifdef _WIN32
|
||||||
|
sendMessage_1lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + wstring(str.begin(), str.end()) + L"'");
|
||||||
|
#else
|
||||||
|
sendMessage_1lvl(wstring(L"running pass '") + wstring(str.begin(), str.end()) + L"'");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendMessage_2lvl(int kind, ...)
|
||||||
|
{
|
||||||
|
va_list list;
|
||||||
|
va_start(list, kind);
|
||||||
|
|
||||||
|
if (kind == 0)
|
||||||
|
{
|
||||||
|
bool isFunction = va_arg(list, int);
|
||||||
|
string fName = va_arg(list, string);
|
||||||
|
#if _WIN32
|
||||||
|
if (isFunction)
|
||||||
|
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + to_wstring(fName) + L"'");
|
||||||
|
else
|
||||||
|
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + to_wstring(fName) + L"'");
|
||||||
|
#else
|
||||||
|
if (isFunction)
|
||||||
|
sendMessage_2lvl(wstring(L"processing function '") + wstring(fName.begin(), fName.end()) + L"'");
|
||||||
|
else
|
||||||
|
sendMessage_2lvl(wstring(L"processing module '") + wstring(fName.begin(), fName.end()) + L"'");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (kind == 1)
|
||||||
|
{
|
||||||
|
int idx = va_arg(list, int);
|
||||||
|
int all = va_arg(list, int);
|
||||||
|
#ifdef _WIN32
|
||||||
|
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> ") + std::to_wstring(idx) + L"/" + std::to_wstring(all));
|
||||||
|
#else
|
||||||
|
sendMessage_2lvl(wstring(L"processing loop ") + std::to_wstring(idx) + L"/" + std::to_wstring(all));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (kind == 2)
|
||||||
|
{
|
||||||
|
sendMessage_2lvl(L"");
|
||||||
|
}
|
||||||
|
else if (kind == 3)
|
||||||
|
{
|
||||||
|
string file = va_arg(list, string);
|
||||||
|
#ifdef _WIN32
|
||||||
|
sendMessage_2lvl(L" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> '" + to_wstring(file) + L"'");
|
||||||
|
#else
|
||||||
|
sendMessage_2lvl(L" processing file '" + to_wstring(file) + L"'");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (kind == 4)
|
||||||
|
{
|
||||||
|
int k = va_arg(list, int);
|
||||||
|
int all = va_arg(list, int);
|
||||||
|
#if _WIN32
|
||||||
|
wstring treeM = L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring(k + 1) + L"/" + std::to_wstring(all);
|
||||||
|
#else
|
||||||
|
wstring treeM = L"conflict resolution, processing group " + std::to_wstring(k + 1) + L"/" + std::to_wstring(all);
|
||||||
|
#endif
|
||||||
|
sendMessage_2lvl(treeM);
|
||||||
|
}
|
||||||
|
else if (kind == 5)
|
||||||
|
{
|
||||||
|
int z = va_arg(list, int);
|
||||||
|
int all = va_arg(list, int);
|
||||||
|
#ifdef _WIN32
|
||||||
|
wstring treeM = L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " + std::to_wstring(z + 1) + L"/" + std::to_wstring(all);
|
||||||
|
#else
|
||||||
|
wstring treeM = L"conflict resolution, processing array " + std::to_wstring(z + 1) + L"/" + std::to_wstring(all);
|
||||||
|
#endif
|
||||||
|
sendMessage_2lvl(treeM);
|
||||||
|
}
|
||||||
|
else if (kind == 6)
|
||||||
|
{
|
||||||
|
string funcName = va_arg(list, string);
|
||||||
|
#ifdef _WIN32
|
||||||
|
sendMessage_2lvl(wstring(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '") + to_wstring(funcName) + L"'");
|
||||||
|
#else
|
||||||
|
sendMessage_2lvl(wstring(L"inlinig of function '") + to_wstring(funcName) + L"'");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(list);
|
||||||
|
}
|
||||||
|
|
||||||
static string utf8_encode(const wstring& wstr)
|
static string utf8_encode(const wstring& wstr)
|
||||||
{
|
{
|
||||||
if (wstr.empty())
|
if (wstr.empty())
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ public:
|
|||||||
static int init();
|
static int init();
|
||||||
};
|
};
|
||||||
|
|
||||||
void sendMessage_1lvl(const std::wstring& toSend);
|
void sendMessage_1lvl(int kind, ...);
|
||||||
void sendMessage_2lvl(const std::wstring& toSend);
|
void sendMessage_2lvl(int kind, ...);
|
||||||
void sendMessage_progress(const std::wstring& toSend);
|
void sendMessage_progress(const std::wstring& toSend);
|
||||||
|
|
||||||
unsigned int GetPid();
|
unsigned int GetPid();
|
||||||
|
|||||||
52
tests/sapfor/parameter/dynamic_array_maximum.f90
Normal file
52
tests/sapfor/parameter/dynamic_array_maximum.f90
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
program dynamic_array_maximum_3d
|
||||||
|
implicit none
|
||||||
|
integer :: n1, n2, n3, n4 , k, i, j, l, a
|
||||||
|
integer :: sum3
|
||||||
|
real :: max_element
|
||||||
|
real, allocatable :: array(:,:,:), array2(:,:,:), array3(:,:,:)
|
||||||
|
|
||||||
|
write(*, *) "Enter 3 integers"
|
||||||
|
read(*, *) n, m, k
|
||||||
|
m = 100
|
||||||
|
|
||||||
|
if (1 .eq. 1) then
|
||||||
|
a = 3
|
||||||
|
else if (2 .eq. 1) then
|
||||||
|
a = 4
|
||||||
|
endif
|
||||||
|
|
||||||
|
m = m + 1
|
||||||
|
k = m * 1000 + n * 10
|
||||||
|
|
||||||
|
allocate(array(n, m + n, k + m + n), &
|
||||||
|
&array2(k, m + n, k), &
|
||||||
|
&array3(k, m, k + n))
|
||||||
|
|
||||||
|
call random_seed()
|
||||||
|
do i = 1, n1
|
||||||
|
do j = 1, m * n1
|
||||||
|
do l = 1, k * m * n1
|
||||||
|
call random_number(array(i,j,l))
|
||||||
|
array(i,j,l) = int(array(i,j,l) * 100)
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
|
||||||
|
max_element = array(1,1,1)
|
||||||
|
do i = 1, n1
|
||||||
|
do j = 1, m
|
||||||
|
do l = 1, k
|
||||||
|
max_element = MAX(array(i,j,l), max_element)
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
deallocate(array, array2, array3)
|
||||||
|
write(*, *) max_element
|
||||||
|
end program dynamic_array_maximum_3d
|
||||||
|
|
||||||
|
! function sum3(x, y, z)
|
||||||
|
! implicit none
|
||||||
|
! integer :: x, y, z
|
||||||
|
! integer :: sum3
|
||||||
|
! sum3 = x + y + z
|
||||||
|
! end function sum3
|
||||||
Reference in New Issue
Block a user