merge to master
This commit is contained in:
@@ -160,7 +160,9 @@ set(PARALLEL_REG _src/ParallelizationRegions/ParRegions.cpp
|
||||
_src/ParallelizationRegions/expand_extract_reg.h
|
||||
_src/ParallelizationRegions/resolve_par_reg_conflicts.cpp
|
||||
_src/ParallelizationRegions/resolve_par_reg_conflicts.h)
|
||||
|
||||
|
||||
set(TR_DEAD_CODE _src/Transformations/dead_code.cpp
|
||||
_src/Transformations/dead_code.h)
|
||||
set(TR_CP _src/Transformations/checkpoints.cpp
|
||||
_src/Transformations/checkpoints.h)
|
||||
set(TR_VECTOR _src/Transformations/array_assign_to_loop.cpp
|
||||
@@ -194,7 +196,7 @@ set(TR_IMPLICIT_NONE _src/Transformations/set_implicit_none.cpp
|
||||
_src/Transformations/set_implicit_none.h)
|
||||
|
||||
set(TRANSFORMS
|
||||
${TR_CP}
|
||||
${TR_DEAD_CODE}
|
||||
${TR_VECTOR}
|
||||
${TR_ENDDO_LOOP}
|
||||
${TR_LOOP_NEST}
|
||||
@@ -223,6 +225,13 @@ set(CFG _src/CFGraph/IR.cpp
|
||||
_src/CFGraph/private_variables_analysis.h
|
||||
)
|
||||
|
||||
set(DATA_FLOW
|
||||
_src/CFGraph/DataFlow/data_flow.h
|
||||
_src/CFGraph/DataFlow/data_flow_impl.h
|
||||
_src/CFGraph/DataFlow/backward_data_flow.h
|
||||
_src/CFGraph/DataFlow/backward_data_flow_impl.h
|
||||
)
|
||||
|
||||
set(CREATE_INTER_T _src/CreateInterTree/CreateInterTree.cpp
|
||||
_src/CreateInterTree/CreateInterTree.h)
|
||||
|
||||
@@ -326,6 +335,16 @@ set(MAIN _src/Sapfor.cpp
|
||||
set(PREDICTOR _src/Predictor/PredictScheme.cpp
|
||||
_src/Predictor/PredictScheme.h)
|
||||
|
||||
set(PROJ_MAN _src/ProjectManipulation/ParseFiles.cpp
|
||||
_src/ProjectManipulation/ParseFiles.h
|
||||
_src/ProjectManipulation/StdCapture.h
|
||||
_src/ProjectManipulation/PerfAnalyzer.cpp
|
||||
_src/ProjectManipulation/PerfAnalyzer.h
|
||||
_src/ProjectManipulation/FileInfo.cpp
|
||||
_src/ProjectManipulation/FileInfo.h
|
||||
_src/ProjectManipulation/ConvertFiles.cpp
|
||||
_src/ProjectManipulation/ConvertFiles.h)
|
||||
|
||||
set(PARSER ${parser_sources}/cftn.c
|
||||
${parser_sources}/errors.c
|
||||
${parser_sources}/gram1.tab.c
|
||||
@@ -382,6 +401,7 @@ set(ZLIB ${zlib_sources}/src/adler32.c
|
||||
|
||||
set(SOURCE_EXE
|
||||
${CFG}
|
||||
${DATA_FLOW}
|
||||
${CREATE_INTER_T}
|
||||
${DIRA}
|
||||
${DISTR}
|
||||
@@ -407,11 +427,14 @@ set(SOURCE_EXE
|
||||
${PPPA}
|
||||
${ZLIB}
|
||||
${GR_LAYOUT}
|
||||
${PR_PARAM})
|
||||
${PR_PARAM}
|
||||
${PROJ_MAN})
|
||||
|
||||
add_executable(Sapfor_F ${SOURCE_EXE})
|
||||
source_group (CFGraph FILES ${CFG})
|
||||
source_group (CFGraph\\DataFlow FILES ${DATA_FLOW})
|
||||
|
||||
source_group (Transformations\\DeadCodeRemoving FILES ${TR_DEAD_CODE})
|
||||
source_group (Transformations\\ExpressionSubstitution FILES ${EXPR_TRANSFORM})
|
||||
source_group (Transformations\\CheckPoints FILES ${TR_CP})
|
||||
source_group (Transformations\\LoopEndDoConverter FILES ${TR_ENDDO_LOOP})
|
||||
@@ -447,6 +470,7 @@ source_group (SageExtension FILES ${OMEGA})
|
||||
source_group (Utils FILES ${UTILS})
|
||||
source_group (VerificationCode FILES ${VERIF})
|
||||
source_group (ProjectParameters FILES ${PR_PARAM})
|
||||
source_group (ProjectManipulation FILES ${PROJ_MAN})
|
||||
|
||||
source_group (VisualizerCalls FILES ${VS_CALLS})
|
||||
source_group (VisualizerCalls\\GraphLayout FILES ${GR_LAYOUT})
|
||||
|
||||
@@ -56,6 +56,22 @@ void BBlock::addInstruction(IR_Block* item)
|
||||
item->setBasicBlock(this);
|
||||
}
|
||||
|
||||
int BBlock::removePrev(BBlock* removed)
|
||||
{
|
||||
auto it = std::remove(prev.begin(), prev.end(), removed);
|
||||
auto r = prev.end() - it;
|
||||
prev.erase(it, prev.end());
|
||||
return r;
|
||||
}
|
||||
|
||||
int BBlock::removeNext(BBlock* removed)
|
||||
{
|
||||
auto it = std::remove(next.begin(), next.end(), removed);
|
||||
auto r = next.end() - it;
|
||||
next.erase(it, next.end());
|
||||
return r;
|
||||
}
|
||||
|
||||
BBlock::~BasicBlock()
|
||||
{
|
||||
for (auto& instr : instructions)
|
||||
|
||||
@@ -31,8 +31,9 @@ namespace SAPFOR
|
||||
//live variables [arg -> blocks with usages]
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> live_in, live_out, live_inout;
|
||||
|
||||
bool addLive(const std::map<SAPFOR::Argument*, std::set<SAPFOR::BasicBlock*>>& to_add, bool in);
|
||||
std::map<SAPFOR::Argument*, std::set<SAPFOR::BasicBlock*>> getLive(bool in) const;
|
||||
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;
|
||||
bool removeLive(SAPFOR::Argument* to_remove, bool in);
|
||||
public:
|
||||
BasicBlock() { num = lastNumBlock++; }
|
||||
BasicBlock(IR_Block* item);
|
||||
@@ -41,6 +42,9 @@ namespace SAPFOR
|
||||
void addInstruction(IR_Block* item);
|
||||
void addPrev(BasicBlock* prev_) { prev.push_back(prev_); }
|
||||
void addNext(BasicBlock* next_) { next.push_back(next_); }
|
||||
|
||||
int removePrev(BasicBlock* removed);
|
||||
int removeNext(BasicBlock* removed);
|
||||
|
||||
void replacePrevNext(const std::map<BasicBlock*, BasicBlock*>& oldToNew)
|
||||
{
|
||||
@@ -69,11 +73,14 @@ namespace SAPFOR
|
||||
/*
|
||||
* FOR LIVE ANALYSIS
|
||||
*/
|
||||
bool addLiveIn(const std::map<SAPFOR::Argument*, std::set<SAPFOR::BasicBlock*>>& to_add) { return addLive(to_add, true); };
|
||||
bool addLiveOut(const std::map<SAPFOR::Argument*, std::set<SAPFOR::BasicBlock*>>& to_add) { return addLive(to_add, false); };
|
||||
bool addLiveIn(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add) { return addLive(to_add, true); };
|
||||
bool addLiveOut(const std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& to_add) { return addLive(to_add, false); };
|
||||
|
||||
bool removeLiveIn(SAPFOR::Argument* to_remove) { return removeLive(to_remove, true); };
|
||||
bool removeLiveOut(SAPFOR::Argument* to_remove) { return removeLive(to_remove, false); };
|
||||
|
||||
std::map<SAPFOR::Argument*, std::set<SAPFOR::BasicBlock*>> getLiveIn() const { return getLive(true); };
|
||||
std::map<SAPFOR::Argument*, std::set<SAPFOR::BasicBlock*>> getLiveOut() const { return getLive(false); };
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLiveIn() const { return getLive(true); };
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>> getLiveOut() const { return getLive(false); };
|
||||
void compressLives();
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "data_flow.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
|
||||
template <class NodeType>
|
||||
class BackwardDataFlowAnalysis : public DataFlowAnalysis<NodeType> {
|
||||
std::vector<SAPFOR::BasicBlock*> reorderSequence(const std::vector<SAPFOR::BasicBlock*>& blocks,
|
||||
const std::set<SAPFOR::BasicBlock*> back_edge_sources);
|
||||
public:
|
||||
void fit(const std::vector<SAPFOR::BasicBlock*>& blocks);
|
||||
};
|
||||
|
||||
#include "backward_data_flow_impl.h"
|
||||
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
#include "backward_data_flow.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
#include "../RD_subst.h"
|
||||
|
||||
/* Note: this file should be included in backward_data_flow.h to provide template definitions */
|
||||
|
||||
// minimizes the number of blocks beween the ends of back edges
|
||||
template <class NodeType>
|
||||
std::vector<SAPFOR::BasicBlock*>
|
||||
BackwardDataFlowAnalysis<NodeType>::reorderSequence(const std::vector<SAPFOR::BasicBlock*>& blocks,
|
||||
const std::set<SAPFOR::BasicBlock*> back_edge_sources)
|
||||
{
|
||||
std::vector<SAPFOR::BasicBlock*> res = { };
|
||||
|
||||
auto blocks_end = blocks.rend();
|
||||
for (auto it = blocks.rbegin(); it < blocks_end; it++)
|
||||
{
|
||||
SAPFOR::BasicBlock* curr = *it;
|
||||
auto res_end = res.end();
|
||||
auto inserter = res.begin();
|
||||
if (back_edge_sources.count(curr) == 0)
|
||||
{
|
||||
auto curr_next_begin = curr->getNext().begin();
|
||||
auto curr_next_end = curr->getNext().end();
|
||||
while (inserter < res_end && std::find(curr_next_begin, curr_next_end, *inserter) == curr_next_end)
|
||||
inserter++;
|
||||
}
|
||||
|
||||
res.insert(inserter, curr);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class NodeType>
|
||||
void BackwardDataFlowAnalysis<NodeType>::fit(const std::vector<SAPFOR::BasicBlock*>& blocks)
|
||||
{
|
||||
std::set<std::pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>> back_edges = {};
|
||||
|
||||
bool returned = false;
|
||||
std::map<SAPFOR::BasicBlock*, std::set<SAPFOR::BasicBlock*>> back_edges_by_src;
|
||||
|
||||
auto blocks_sorted = sortCfgNodes(blocks, &back_edges);
|
||||
|
||||
std::set<SAPFOR::BasicBlock*> back_edge_sources;
|
||||
|
||||
for (auto& edge : back_edges)
|
||||
{
|
||||
back_edges_by_src[edge.first].insert(edge.second);
|
||||
back_edge_sources.insert(edge.first);
|
||||
}
|
||||
|
||||
back_edges.clear();
|
||||
|
||||
blocks_sorted = reorderSequence(blocks_sorted, back_edge_sources);
|
||||
back_edge_sources.clear();
|
||||
|
||||
std::reverse(blocks_sorted.begin(), blocks_sorted.end());
|
||||
|
||||
this->nodes.clear();
|
||||
std::map<SAPFOR::BasicBlock*, NodeType*> node_by_block;
|
||||
|
||||
for (auto block : blocks_sorted)
|
||||
{
|
||||
NodeType* node = this->createNode(block);
|
||||
this->nodes.push_back(node);
|
||||
node_by_block[block] = node;
|
||||
}
|
||||
|
||||
int nodes_size = this->nodes.size();
|
||||
|
||||
for (int i = 0; i < nodes_size; i++)
|
||||
{
|
||||
NodeType* node = this->nodes[i];
|
||||
|
||||
auto back_edges_by_src_it = back_edges_by_src.find(node->getBlock());
|
||||
if (back_edges_by_src_it != back_edges_by_src.end())
|
||||
{
|
||||
// This node is a source for back edge
|
||||
for (auto dest : back_edges_by_src_it->second)
|
||||
{
|
||||
auto node_by_block_it = node_by_block.find(dest);
|
||||
if (node_by_block_it != node_by_block.end())
|
||||
node_by_block_it->second->getRollback().insert(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto next : node->getBlock()->getNext())
|
||||
{
|
||||
auto node_by_block_it = node_by_block.find(next);
|
||||
if (node_by_block_it != node_by_block.end())
|
||||
node->getPrevBlocks().insert(node_by_block_it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h
Normal file
67
sapfor/experts/Sapfor_2017/_src/CFGraph/DataFlow/data_flow.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
#include<vector>
|
||||
#include<set>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
|
||||
template <class DataType>
|
||||
class DataFlowAnalysisNode {
|
||||
static const int CNT_NOTINIT = 0;
|
||||
|
||||
int in_cnt = CNT_NOTINIT, out_cnt = CNT_NOTINIT;
|
||||
|
||||
std::set<int> rollback;
|
||||
std::set<int> ignore_rollback;
|
||||
|
||||
std::set<DataFlowAnalysisNode<DataType>*> prev_blocks;
|
||||
|
||||
SAPFOR::BasicBlock* bb;
|
||||
public:
|
||||
DataFlowAnalysisNode();
|
||||
|
||||
void doStep();
|
||||
|
||||
virtual DataType getIn() = 0;
|
||||
virtual DataType getOut() = 0;
|
||||
|
||||
virtual bool addIn(const DataType& data) = 0;
|
||||
virtual bool addOut(const DataType& data) = 0;
|
||||
|
||||
virtual bool forwardData(const DataType& data) = 0;
|
||||
|
||||
bool newerThan(const DataFlowAnalysisNode<DataType>* block) const { return out_cnt > block->in_cnt; }
|
||||
|
||||
int getInCnt() { return in_cnt; }
|
||||
int getOutCnt() { return out_cnt; }
|
||||
|
||||
void setInCnt(int cnt) { in_cnt = cnt; }
|
||||
void setOutCnt(int cnt) { out_cnt = cnt; }
|
||||
static int getStartCounter() { return CNT_NOTINIT; }
|
||||
|
||||
std::set<int>& getRollback() { return rollback; }
|
||||
std::set<int>& getIgnoreRollback() { return ignore_rollback; }
|
||||
|
||||
std::set<DataFlowAnalysisNode<DataType>*>& getPrevBlocks() { return prev_blocks; }
|
||||
|
||||
SAPFOR::BasicBlock* getBlock() { return bb; }
|
||||
void setBlock(SAPFOR::BasicBlock* b) { bb = b; }
|
||||
};
|
||||
|
||||
template <class NodeType>
|
||||
class DataFlowAnalysis {
|
||||
protected:
|
||||
std::vector<NodeType*> nodes;
|
||||
|
||||
virtual NodeType* createNode(SAPFOR::BasicBlock* block) = 0;
|
||||
public:
|
||||
virtual void fit(const std::vector<SAPFOR::BasicBlock*>& blocks) = 0;
|
||||
void analyze();
|
||||
|
||||
const std::vector<NodeType*>& getNodes() { return nodes; }
|
||||
|
||||
~DataFlowAnalysis();
|
||||
};
|
||||
|
||||
#include "data_flow_impl.h"
|
||||
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
#include "data_flow.h"
|
||||
|
||||
#include<vector>
|
||||
#include<set>
|
||||
|
||||
#include "../../Utils/SgUtils.h"
|
||||
#include "../CFGraph.h"
|
||||
#include "../IR.h"
|
||||
|
||||
/* Note: this file should be included in data_flow.h to provide template definitions */
|
||||
|
||||
/* definitions for DataFlowAnalysisNode class */
|
||||
|
||||
template <class DataType>
|
||||
const int DataFlowAnalysisNode<DataType>::CNT_NOTINIT;
|
||||
|
||||
template <class DataType>
|
||||
DataFlowAnalysisNode<DataType>::DataFlowAnalysisNode()
|
||||
{
|
||||
getRollback() = {};
|
||||
getIgnoreRollback() = {};
|
||||
prev_blocks = {};
|
||||
}
|
||||
|
||||
template <class DataType>
|
||||
void DataFlowAnalysisNode<DataType>::doStep()
|
||||
{
|
||||
int in_max_cnt = CNT_NOTINIT, out_max_cnt = CNT_NOTINIT;
|
||||
for (auto next : prev_blocks)
|
||||
{
|
||||
if (in_cnt < next->out_cnt)
|
||||
{
|
||||
for (const auto& byOut : next->getOut())
|
||||
{
|
||||
bool inserted = addIn({ byOut });
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
if (next->out_cnt > in_max_cnt)
|
||||
in_max_cnt = next->out_cnt;
|
||||
|
||||
inserted = forwardData({ byOut });
|
||||
|
||||
if (inserted && next->out_cnt > out_max_cnt)
|
||||
out_max_cnt = next->out_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool was_notinit = (out_cnt == CNT_NOTINIT);
|
||||
|
||||
if (out_max_cnt != CNT_NOTINIT)
|
||||
out_cnt = out_max_cnt;
|
||||
|
||||
if (in_max_cnt != CNT_NOTINIT)
|
||||
in_cnt = in_max_cnt;
|
||||
|
||||
// TODO: fix counter overflow
|
||||
if (was_notinit)
|
||||
{
|
||||
out_cnt++;
|
||||
in_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
/* definitions for DataFlowAnalysis class */
|
||||
|
||||
template <class NodeType>
|
||||
void DataFlowAnalysis<NodeType>::analyze() {
|
||||
auto curr = 0;
|
||||
auto stop = nodes.size();
|
||||
|
||||
while (curr != stop)
|
||||
{
|
||||
auto curr_bb = nodes[curr];
|
||||
curr_bb->doStep();
|
||||
|
||||
const auto& jumps = curr_bb->getRollback();
|
||||
if (jumps.size() != 0)
|
||||
{
|
||||
auto& ignored_jumps = curr_bb->getIgnoreRollback();
|
||||
|
||||
bool jump = false;
|
||||
for (const auto& jump_to : jumps)
|
||||
{
|
||||
if (ignored_jumps.insert(jump_to).second && curr_bb->newerThan(nodes[jump_to]))
|
||||
{
|
||||
jump = true;
|
||||
curr = jump_to;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!jump)
|
||||
curr_bb->getIgnoreRollback().clear();
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
curr++;
|
||||
}
|
||||
}
|
||||
|
||||
template <class NodeType>
|
||||
DataFlowAnalysis<NodeType>::~DataFlowAnalysis()
|
||||
{
|
||||
for (NodeType* node : nodes)
|
||||
delete node;
|
||||
|
||||
nodes.clear();
|
||||
}
|
||||
@@ -321,38 +321,6 @@ static bool getDependencies(SAPFOR::Argument* var, SAPFOR::Instruction* instr, c
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ifVariableValid(SAPFOR::Argument* var, const set<pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*>>& defs,
|
||||
SAPFOR::Argument* processed_var, const pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*>& def_of_processed_var)
|
||||
{
|
||||
const auto& BB_of_def_of_processed_var = def_of_processed_var.second;
|
||||
|
||||
if (defs.size() == 1)
|
||||
{
|
||||
const auto& def = *defs.begin();
|
||||
if (def.second == BB_of_def_of_processed_var && def.first->getNumber() < def_of_processed_var.first->getNumber())
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto& RD_In_BB_of_def_of_processed_var = BB_of_def_of_processed_var->getRD_In();
|
||||
auto RD_of_var_from_BB_with_processed_var = RD_In_BB_of_def_of_processed_var.find(var);
|
||||
|
||||
if (RD_of_var_from_BB_with_processed_var != RD_In_BB_of_def_of_processed_var.end()
|
||||
&& RD_of_var_from_BB_with_processed_var->second.size() == defs.size())
|
||||
{
|
||||
for (const auto& def : defs)
|
||||
{
|
||||
int number_of_istruction_with_decl = def.first ? def.first->getNumber() : CFG_VAL::UNINIT;
|
||||
|
||||
if (RD_of_var_from_BB_with_processed_var->second.count(number_of_istruction_with_decl) == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const set<SAPFOR::Argument*>& func_affects(const FuncInfo* func, const vector<SAPFOR::BasicBlock*>& blocks)
|
||||
{
|
||||
static map<const FuncInfo*, set<SAPFOR::Argument*>> affects;
|
||||
@@ -1150,7 +1118,7 @@ vector<SAPFOR::BasicBlock*> sortCfgNodes(const vector<SAPFOR::BasicBlock*>& bloc
|
||||
if (!nodes_added && processing_stack.size() != 0) {
|
||||
//there is some blocks in the stack but no one can be processed
|
||||
//this code should be unreachable
|
||||
#ifdef DEBUG_CHECKS
|
||||
#if DEBUG_CHECKS
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
#endif // DEBUG_CHECKS
|
||||
auto block = processing_stack.back();
|
||||
@@ -1167,7 +1135,7 @@ vector<SAPFOR::BasicBlock*> sortCfgNodes(const vector<SAPFOR::BasicBlock*>& bloc
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CHECKS
|
||||
#if DEBUG_CHECKS
|
||||
set<SAPFOR::BasicBlock*> verify_unique;
|
||||
verify_unique.insert(result.begin(), result.end());
|
||||
|
||||
@@ -1176,7 +1144,7 @@ vector<SAPFOR::BasicBlock*> sortCfgNodes(const vector<SAPFOR::BasicBlock*>& bloc
|
||||
verify_unique.clear();
|
||||
#endif // DEBUG_CHECKS
|
||||
|
||||
#ifdef DEBUG_CHECKS
|
||||
#if DEBUG_CHECKS
|
||||
set<SAPFOR::BasicBlock*> all_blocks, res_blocks;
|
||||
|
||||
all_blocks.insert(blocks.begin(), blocks.end());
|
||||
@@ -1267,7 +1235,7 @@ bool isArgReaches(int decl_instr, SAPFOR::BasicBlock* decl_bb,
|
||||
if (RDs_for_arg.size() == 1)
|
||||
{
|
||||
const int rd = *RDs_for_arg.begin();
|
||||
if (rd >= decl_bb->getInstructions().front()->getNumber() && rd <= decl_instr)
|
||||
if (rd >= decl_bb->getInstructions().front()->getNumber() && rd < decl_instr)
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1275,7 +1243,67 @@ bool isArgReaches(int decl_instr, SAPFOR::BasicBlock* decl_bb,
|
||||
if (arg_in_from_decl_it == decl_bb->getRD_In().end())
|
||||
return false;
|
||||
|
||||
return arg_in_from_decl_it->second == RDs_for_arg;
|
||||
if(arg_in_from_decl_it->second != RDs_for_arg)
|
||||
return false;
|
||||
|
||||
set<SAPFOR::BasicBlock*> reachable = { decl_bb };
|
||||
set<int> banned_instructions;
|
||||
for (int instr_def : arg_in_from_decl_it->second)
|
||||
if (instr_def >= decl_instr || instr_def < decl_bb->getInstructions().front()->getNumber())
|
||||
//try to find way [decl_bb] -> [dest_bb] with redefining of var (that means that var value from decl_bb could be overwrited)
|
||||
banned_instructions.insert(instr_def);
|
||||
|
||||
set<SAPFOR::BasicBlock*> worklist = reachable, banned_blocks;
|
||||
bool way_found = false;
|
||||
while (worklist.size() != 0 && banned_instructions.size() != 0)
|
||||
{
|
||||
for (SAPFOR::BasicBlock* wl : worklist)
|
||||
{
|
||||
int start = wl->getInstructions().front()->getNumber(), end = wl->getInstructions().back()->getNumber();
|
||||
|
||||
for (auto banned_it = banned_instructions.begin(); banned_it != banned_instructions.end();)
|
||||
{
|
||||
if(start <= *banned_it && *banned_it <= end)
|
||||
{
|
||||
banned_it = banned_instructions.erase(banned_it);
|
||||
banned_blocks.insert(wl);
|
||||
}
|
||||
else
|
||||
{
|
||||
banned_it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
reachable = banned_blocks;
|
||||
worklist = reachable;
|
||||
while (worklist.size() != 0 && banned_instructions.size() != 0)
|
||||
{
|
||||
if(worklist.find(dest_bb) != worklist.end())
|
||||
return false;
|
||||
|
||||
set<SAPFOR::BasicBlock*> to_insert;
|
||||
|
||||
for (auto b : worklist)
|
||||
for (auto next : b->getNext())
|
||||
if(next != decl_bb)
|
||||
if (reachable.insert(next).second)
|
||||
to_insert.insert(next);
|
||||
|
||||
worklist = to_insert;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// return arg's definition if it really reaches dest_bb
|
||||
@@ -1597,28 +1625,7 @@ void buildSubstitutions(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGra
|
||||
|
||||
for (SAPFOR::Argument* dep : dependencies_of_var->second)
|
||||
{
|
||||
if (dep->getType() != CFG_ARG_TYPE::VAR)
|
||||
{
|
||||
can_use = false;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto& RD_In_of_curr_BB = cur_BB->getRD_In();
|
||||
auto dep_from_curr_RD_In = RD_In_of_curr_BB.find(dep);
|
||||
|
||||
if (dep_from_curr_RD_In == RD_In_of_curr_BB.end())
|
||||
{
|
||||
can_use = false;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto& RDs_for_dep = dep_from_curr_RD_In->second;
|
||||
|
||||
set<pair<SAPFOR::Instruction*, SAPFOR::BasicBlock*>> defs_of_dep;
|
||||
for (int def_instruction_num : RDs_for_dep)
|
||||
defs_of_dep.insert(getInstructionAndBlockByNumber(CFGraph_for_project, def_instruction_num));
|
||||
|
||||
if (!ifVariableValid(dep, defs_of_dep, in_val.first, instr_and_bb))
|
||||
if (!isArgReaches(instr_num, instr_and_bb.second, dep, cur_BB))
|
||||
{
|
||||
can_use = false;
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "live_variable_analysis.h"
|
||||
#include "RD_subst.h"
|
||||
#include "DataFlow/backward_data_flow.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -16,18 +17,20 @@ using std::set;
|
||||
using std::unordered_map;
|
||||
using std::list;
|
||||
|
||||
using LIVE_VARIABLES::LiveDeadVarsForCall;
|
||||
|
||||
namespace SAPFOR
|
||||
{
|
||||
bool BasicBlock::addLive(const map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>>& to_add, bool in) {
|
||||
bool BasicBlock::addLive(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& to_add, bool in) {
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& current_set = (in ? live_in : live_out);
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& opposite_set = (!in ? live_in : live_out);
|
||||
|
||||
bool inserted = false;
|
||||
for (const auto& byNew : to_add)
|
||||
{
|
||||
const set<SAPFOR::BasicBlock*>& add_in_live = byNew.second;
|
||||
set<SAPFOR::BasicBlock*> new_in_live = {};
|
||||
|
||||
const vector<SAPFOR::BasicBlock*>& add_in_live = byNew.second;
|
||||
vector<SAPFOR::BasicBlock*> new_in_live = {};
|
||||
|
||||
auto current_set_iter = current_set.find(byNew.first);
|
||||
|
||||
if (current_set_iter == current_set.end())
|
||||
@@ -92,20 +95,56 @@ namespace SAPFOR
|
||||
}
|
||||
|
||||
return inserted;
|
||||
};
|
||||
}
|
||||
|
||||
map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>> BasicBlock::getLive(bool in) const {
|
||||
bool BasicBlock::removeLive(SAPFOR::Argument* to_remove, bool in)
|
||||
{
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& current_set = (in ? live_in : live_out);
|
||||
std::map<SAPFOR::Argument*, std::vector<SAPFOR::BasicBlock*>>& opposite_set = (!in ? live_in : live_out);
|
||||
|
||||
bool removed = false;
|
||||
|
||||
removed |= (current_set.erase(to_remove) != 0);
|
||||
|
||||
if (!removed)
|
||||
{
|
||||
auto it = live_inout.find(to_remove);
|
||||
|
||||
if (it != live_inout.end())
|
||||
{
|
||||
auto& dest = opposite_set[to_remove];
|
||||
for (SAPFOR::BasicBlock* bb : it->second)
|
||||
{
|
||||
auto find_bb_from_dest = std::lower_bound(dest.begin(), dest.end(), bb);
|
||||
|
||||
if (find_bb_from_dest == dest.end() || *find_bb_from_dest != bb)
|
||||
dest.insert(find_bb_from_dest, bb);
|
||||
}
|
||||
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> BasicBlock::getLive(bool in) const {
|
||||
auto& current_set = in ? live_in : live_out;
|
||||
|
||||
map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>> res;
|
||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> res;
|
||||
|
||||
for (auto& by_source : { current_set, live_inout })
|
||||
{
|
||||
for (auto& by_pair : by_source)
|
||||
res[by_pair.first].insert(by_pair.second.begin(), by_pair.second.end());
|
||||
{
|
||||
auto& dest = res[by_pair.first];
|
||||
dest.insert(dest.end(), by_pair.second.begin(), by_pair.second.end());
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void BasicBlock::compressLives() {
|
||||
for (auto& bySrc : { &live_in, &live_out, &live_inout })
|
||||
for (auto& byArg : *bySrc)
|
||||
@@ -113,403 +152,297 @@ namespace SAPFOR
|
||||
}
|
||||
}
|
||||
|
||||
struct fcall
|
||||
bool LiveDeadVarsForCall::tryInsert(set<SAPFOR::BasicBlock*>& dest, SAPFOR::BasicBlock* b)
|
||||
{
|
||||
private:
|
||||
bool tryInsert(set<SAPFOR::BasicBlock*>& dest, SAPFOR::BasicBlock* b)
|
||||
if (b == block || dest.find(block) == dest.end())
|
||||
{
|
||||
if (b == block || dest.find(block) == dest.end())
|
||||
{
|
||||
dest.insert(b);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
dest.insert(b);
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
FuncInfo* func;
|
||||
|
||||
map<int, set<SAPFOR::BasicBlock*>> live_after;
|
||||
set<int> dead_after;
|
||||
return false;
|
||||
}
|
||||
|
||||
map<SAPFOR::Argument*, set<SAPFOR::BasicBlock*>> commons_live_after;
|
||||
set<SAPFOR::Argument*> commons_dead_after;
|
||||
LiveDeadVarsForCall::LiveDeadVarsForCall(FuncInfo* f, SAPFOR::BasicBlock* b, const vector<SAPFOR::Argument*>& p)
|
||||
{
|
||||
block = b;
|
||||
func = f;
|
||||
|
||||
vector<SAPFOR::Argument*> params;
|
||||
SAPFOR::BasicBlock* block;
|
||||
int param_size = p.size();
|
||||
params = vector<SAPFOR::Argument*>(param_size, NULL);
|
||||
|
||||
fcall(FuncInfo* f, SAPFOR::BasicBlock* b, const vector<SAPFOR::Argument*>& p)
|
||||
{
|
||||
block = b;
|
||||
func = f;
|
||||
|
||||
int param_size = p.size();
|
||||
params = vector<SAPFOR::Argument*>(param_size, NULL);
|
||||
for (int i = 0; i < param_size; i++)
|
||||
if (f->funcParams.isArgOut(i))
|
||||
params[i] = p[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < param_size; i++)
|
||||
if (f->funcParams.isArgOut(i))
|
||||
params[i] = p[i];
|
||||
void LiveDeadVarsForCall::make_live(SAPFOR::Argument* arg, SAPFOR::BasicBlock* b)
|
||||
{
|
||||
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::COMMON_ || arg->getMemType() == SAPFOR::CFG_MEM_TYPE::MODULE_)
|
||||
{
|
||||
if (commons_dead_after.find(arg) == commons_dead_after.end())
|
||||
tryInsert(commons_live_after[arg], b);
|
||||
}
|
||||
|
||||
void make_live(SAPFOR::Argument* arg, SAPFOR::BasicBlock* b)
|
||||
auto it = find(params.begin(), params.end(), arg);
|
||||
if (it != params.end())
|
||||
{
|
||||
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::COMMON_ || arg->getMemType() == SAPFOR::CFG_MEM_TYPE::MODULE_)
|
||||
{
|
||||
if (commons_dead_after.find(arg) == commons_dead_after.end())
|
||||
tryInsert(commons_live_after[arg], b);
|
||||
}
|
||||
|
||||
auto it = find(params.begin(), params.end(), arg);
|
||||
if (it != params.end())
|
||||
{
|
||||
int idx = it - params.begin();
|
||||
if (dead_after.find(idx) == dead_after.end())
|
||||
tryInsert(live_after[idx], b);
|
||||
}
|
||||
int idx = it - params.begin();
|
||||
if (dead_after.find(idx) == dead_after.end())
|
||||
tryInsert(live_after[idx], b);
|
||||
}
|
||||
}
|
||||
|
||||
void make_dead(SAPFOR::Argument* arg)
|
||||
void LiveDeadVarsForCall::make_dead(SAPFOR::Argument* arg)
|
||||
{
|
||||
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::COMMON_ || arg->getMemType() == SAPFOR::CFG_MEM_TYPE::MODULE_)
|
||||
{
|
||||
if (arg->getMemType() == SAPFOR::CFG_MEM_TYPE::COMMON_ || arg->getMemType() == SAPFOR::CFG_MEM_TYPE::MODULE_)
|
||||
if (commons_live_after.find(arg) == commons_live_after.end())
|
||||
commons_dead_after.insert(arg);
|
||||
|
||||
auto it = find(params.begin(), params.end(), arg);
|
||||
if (it != params.end())
|
||||
{
|
||||
int idx = it - params.begin();
|
||||
dead_after.insert(idx);
|
||||
}
|
||||
}
|
||||
|
||||
void updateFromOut()
|
||||
auto it = find(params.begin(), params.end(), arg);
|
||||
if (it != params.end())
|
||||
{
|
||||
for (const auto& p : block->getLiveOut())
|
||||
for (auto b : p.second)
|
||||
make_live(p.first, b);
|
||||
int idx = it - params.begin();
|
||||
if (live_after.find(idx) == live_after.end())
|
||||
dead_after.insert(idx);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void LiveDeadVarsForCall::updateFromOut()
|
||||
{
|
||||
for (const auto& p : block->getLiveOut())
|
||||
for (auto b : p.second)
|
||||
make_live(p.first, b);
|
||||
}
|
||||
|
||||
static bool getLiveDead(const vector<SAPFOR::Argument*>& params, const string& func_name,
|
||||
set<SAPFOR::Argument*>& live, set<SAPFOR::Argument*>& dead);
|
||||
|
||||
static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||
vector<SAPFOR::Argument*>& formal_parameters, vector<fcall>& fcalls,
|
||||
const map<string, FuncInfo*>& funcByName);
|
||||
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
||||
const map<string, FuncInfo*>& funcByName, bool interprocedural);
|
||||
|
||||
enum
|
||||
{
|
||||
CNT_NOTINIT = 0
|
||||
};
|
||||
|
||||
struct BasicBlockNode
|
||||
{
|
||||
SAPFOR::BasicBlock* bb;
|
||||
class LiveVarAnalysisNode : public DataFlowAnalysisNode<map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>> {
|
||||
private:
|
||||
set<SAPFOR::Argument*> live, dead;
|
||||
int in_cnt, out_cnt;
|
||||
set<BasicBlockNode*> next_blocks;
|
||||
|
||||
set<vector<BasicBlockNode*>::reverse_iterator> rollback;
|
||||
set<vector<BasicBlockNode*>::reverse_iterator> ignore_rollback;
|
||||
|
||||
BasicBlockNode(SAPFOR::BasicBlock* block, vector<SAPFOR::Argument*>& formal_parameters,
|
||||
vector<fcall>& fcalls, const map<string, FuncInfo*>& funcByName)
|
||||
public:
|
||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getIn()
|
||||
{
|
||||
bb = block;
|
||||
out_cnt = in_cnt = CNT_NOTINIT;
|
||||
|
||||
buildUseDef(bb, live, dead, formal_parameters, fcalls, funcByName);
|
||||
for (SAPFOR::Argument* arg : live)
|
||||
bb->addLiveIn({ { arg, { bb } } });
|
||||
|
||||
rollback = {};
|
||||
ignore_rollback = {};
|
||||
next_blocks = {};
|
||||
return getBlock()->getLiveOut();
|
||||
}
|
||||
|
||||
void updateLive()
|
||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getOut()
|
||||
{
|
||||
bool in_changed = false, out_changed = false;
|
||||
int in_max_cnt = CNT_NOTINIT, out_max_cnt = CNT_NOTINIT;
|
||||
for (auto next : next_blocks)
|
||||
return getBlock()->getLiveIn();
|
||||
}
|
||||
|
||||
bool addIn(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
|
||||
{
|
||||
return getBlock()->addLiveOut(data);
|
||||
}
|
||||
|
||||
bool addOut(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
|
||||
{
|
||||
return getBlock()->addLiveIn(data);
|
||||
}
|
||||
|
||||
bool forwardData(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
|
||||
{
|
||||
bool inserted = false;
|
||||
|
||||
for (const auto& byArg : data)
|
||||
if (live.find(byArg.first) == live.end() && dead.find(byArg.first) == dead.end())
|
||||
inserted |= getBlock()->addLiveIn({ byArg });
|
||||
|
||||
return inserted;
|
||||
}
|
||||
|
||||
LiveVarAnalysisNode(SAPFOR::BasicBlock* block, vector<SAPFOR::Argument*>& formal_parameters,
|
||||
vector<LiveDeadVarsForCall>& fcalls, const map<string, FuncInfo*>& funcByName)
|
||||
{
|
||||
setBlock(block);
|
||||
|
||||
buildUseDef(getBlock(), live, dead, formal_parameters, fcalls, funcByName, true);
|
||||
|
||||
for (SAPFOR::Argument* arg : live)
|
||||
getBlock()->addLiveIn({ { arg, { getBlock() } } });
|
||||
}
|
||||
};
|
||||
|
||||
class LiveVarAnalysis : public BackwardDataFlowAnalysis<LiveVarAnalysisNode> {
|
||||
protected:
|
||||
vector<SAPFOR::Argument*>& formal_parameters;
|
||||
vector<LiveDeadVarsForCall>& fcalls;
|
||||
const map<string, FuncInfo*>& funcByName;
|
||||
|
||||
LiveVarAnalysisNode* createNode(SAPFOR::BasicBlock* block) override {
|
||||
return new LiveVarAnalysisNode(block, formal_parameters, fcalls, funcByName);
|
||||
}
|
||||
public:
|
||||
LiveVarAnalysis(vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
||||
const map<string, FuncInfo*>& funcByName) : formal_parameters(formal_parameters), fcalls(fcalls), funcByName(funcByName)
|
||||
{ }
|
||||
};
|
||||
|
||||
void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
||||
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
||||
vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
||||
string& fName, const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
||||
{
|
||||
for (auto arg : { instr->getArg1(), instr->getArg2(), instr->getResult() })
|
||||
if (arg && arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
|
||||
formal_parameters[getParamIndex(arg, formal_parameters.size())] = arg;
|
||||
|
||||
SAPFOR::Argument* res_arg = NULL;
|
||||
|
||||
static const set<SAPFOR::CFG_OP> skip = { SAPFOR::CFG_OP::ENTRY };
|
||||
SAPFOR::CFG_OP instr_operation = instr->getOperation();
|
||||
if (hasStoreStructure(instr_operation))
|
||||
{
|
||||
res_arg = instr->getArg1();
|
||||
set<SAPFOR::Argument*> instr_args = { instr->getResult(), instr->getArg2() };
|
||||
use.insert(instr_args.begin(), instr_args.end());
|
||||
}
|
||||
else if (instr_operation == SAPFOR::CFG_OP::PARAM)
|
||||
{
|
||||
lastParamRef[last_param_ref_index--] = instr->getArg1();
|
||||
}
|
||||
else if (instr_operation == SAPFOR::CFG_OP::F_CALL)
|
||||
{
|
||||
res_arg = instr->getResult();
|
||||
|
||||
last_param_ref_size = stoi(instr->getArg2()->getValue());
|
||||
|
||||
lastParamRef.clear();
|
||||
lastParamRef.resize(last_param_ref_size);
|
||||
|
||||
last_param_ref_index = last_param_ref_size - 1;
|
||||
|
||||
fName = instr->getArg1()->getValue();
|
||||
}
|
||||
else if (skip.find(instr_operation) == skip.end())
|
||||
{
|
||||
//default
|
||||
res_arg = instr->getResult();
|
||||
std::set<SAPFOR::Argument*> intr_args = { instr->getArg1(), instr->getArg2() };
|
||||
use.insert(intr_args.begin(), intr_args.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
//skip
|
||||
return;
|
||||
}
|
||||
|
||||
if ((instr_operation == SAPFOR::CFG_OP::F_CALL || instr_operation == SAPFOR::CFG_OP::PARAM) && last_param_ref_index < 0) {
|
||||
auto func_it = funcByName.find(fName);
|
||||
if (interprocedural && func_it != funcByName.end())
|
||||
{
|
||||
if (out_cnt < next->in_cnt)
|
||||
fcalls.push_back(LiveDeadVarsForCall(func_it->second, block, lastParamRef));
|
||||
|
||||
auto r_it = fcalls.rbegin();
|
||||
auto r_end = fcalls.rend();
|
||||
|
||||
for (auto e : def)
|
||||
r_it->make_dead(e);
|
||||
|
||||
for (auto e : use)
|
||||
r_it->make_live(e, block);
|
||||
}
|
||||
|
||||
set<SAPFOR::Argument*> make_live, make_dead;
|
||||
if (fName == "_READ")
|
||||
def.insert(lastParamRef.begin(), lastParamRef.end());
|
||||
else if (interprocedural && getLiveDead(lastParamRef, fName, make_live, make_dead))
|
||||
{
|
||||
use.insert(make_live.begin(), make_live.end());
|
||||
def.insert(make_dead.begin(), make_dead.end());
|
||||
}
|
||||
else if (func_it != funcByName.end())
|
||||
{
|
||||
int arg_num = lastParamRef.size();
|
||||
for (int i = 0; i < arg_num; i++)
|
||||
{
|
||||
for (const auto& byArg : next->bb->getLiveIn())
|
||||
{
|
||||
bool inserted = bb->addLiveOut({ byArg });
|
||||
out_changed |= inserted;
|
||||
if(func_it->second->funcParams.isArgOut(i))
|
||||
def.insert(lastParamRef[i]);
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
if (next->in_cnt > out_max_cnt)
|
||||
out_max_cnt = next->in_cnt;
|
||||
|
||||
if (live.find(byArg.first) == live.end() && dead.find(byArg.first) == dead.end())
|
||||
{
|
||||
inserted = bb->addLiveIn({ byArg });
|
||||
if (inserted && next->in_cnt > in_max_cnt)
|
||||
{
|
||||
in_max_cnt = next->in_cnt;
|
||||
in_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (func_it->second->funcParams.isArgIn(i))
|
||||
use.insert(lastParamRef[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
use.insert(lastParamRef.begin(), lastParamRef.end());
|
||||
|
||||
bool was_notinit = (in_cnt == CNT_NOTINIT);
|
||||
|
||||
if (in_max_cnt != CNT_NOTINIT)
|
||||
in_cnt = in_max_cnt;
|
||||
last_param_ref_index = 0;
|
||||
last_param_ref_size = 0;
|
||||
|
||||
if (out_max_cnt != CNT_NOTINIT)
|
||||
out_cnt = out_max_cnt;
|
||||
lastParamRef.clear();
|
||||
fName = "";
|
||||
}
|
||||
|
||||
// TODO: fix counter overflow
|
||||
if (was_notinit)
|
||||
if (res_arg)
|
||||
def.insert(res_arg);
|
||||
}
|
||||
|
||||
static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
||||
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
||||
vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
||||
string& fName, const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
||||
{
|
||||
set<SAPFOR::Argument*> res, args;
|
||||
|
||||
getUseDefForInstruction(block, instr,
|
||||
args, res,
|
||||
formal_parameters, fcalls,
|
||||
lastParamRef, last_param_ref_index, last_param_ref_size,
|
||||
fName, funcByName,
|
||||
interprocedural
|
||||
);
|
||||
|
||||
for (auto e : res)
|
||||
{
|
||||
if (e && e->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||
{
|
||||
out_cnt++;
|
||||
in_cnt++;
|
||||
def.insert(e);
|
||||
use.erase(e);
|
||||
}
|
||||
}
|
||||
|
||||
bool newerThan(const BasicBlockNode* block) const { return in_cnt > block->out_cnt; }
|
||||
};
|
||||
|
||||
for (auto e : args)
|
||||
{
|
||||
if (e && e->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||
{
|
||||
use.insert(e);
|
||||
def.erase(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Build use and def sets of block. Result are stored in use and def
|
||||
static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||
vector<SAPFOR::Argument*>& formal_parameters, vector<fcall>& fcalls,
|
||||
const map<string, FuncInfo*>& funcByName)
|
||||
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
|
||||
const map<string, FuncInfo*>& funcByName, bool interprocedural)
|
||||
{
|
||||
set<SAPFOR::Argument*> tmp_use, tmp_def;
|
||||
|
||||
vector<SAPFOR::Argument*> lastParamRef;
|
||||
bool fcall_added;
|
||||
int last_param_ref_index = 0, last_param_ref_size = 0;
|
||||
string fName;
|
||||
|
||||
for (auto ir_block : block->getInstructions())
|
||||
const auto& instructions = block->getInstructions();
|
||||
auto ir_block_it = instructions.rbegin(), ir_block_end = instructions.rend();
|
||||
|
||||
for (; ir_block_it != ir_block_end; ir_block_it++)
|
||||
{
|
||||
fcall_added = false;
|
||||
SAPFOR::Instruction* instr = ir_block->getInstruction();
|
||||
for (auto arg : { instr->getArg1(), instr->getArg2(), instr->getResult() })
|
||||
if (arg && arg->getMemType() == SAPFOR::CFG_MEM_TYPE::FUNC_PARAM_)
|
||||
formal_parameters[getParamIndex(arg, formal_parameters.size())] = arg;
|
||||
|
||||
set<SAPFOR::Argument*> res = {}, args = {};
|
||||
SAPFOR::Argument* res_arg = NULL;
|
||||
|
||||
static const set<SAPFOR::CFG_OP> skip = { SAPFOR::CFG_OP::ENTRY };
|
||||
SAPFOR::CFG_OP instr_operation = instr->getOperation();
|
||||
if (hasStoreStructure(instr_operation)) {
|
||||
res_arg = instr->getArg1();
|
||||
std::set<SAPFOR::Argument*> instr_args = { instr->getResult(), instr->getArg2()};
|
||||
insertIfVar(instr_args.begin(), instr_args.end(), args);
|
||||
}
|
||||
else if (instr_operation == SAPFOR::CFG_OP::PARAM)
|
||||
lastParamRef.push_back(instr->getArg1());
|
||||
else if (instr_operation == SAPFOR::CFG_OP::F_CALL)
|
||||
{
|
||||
res_arg = instr->getResult();
|
||||
|
||||
int count = stoi(instr->getArg2()->getValue());
|
||||
if (lastParamRef.size() != count)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
const string& fName = instr->getArg1()->getValue();
|
||||
auto func_it = funcByName.find(fName);
|
||||
if (func_it != funcByName.end())
|
||||
{
|
||||
fcalls.push_back(fcall(func_it->second, block, lastParamRef));
|
||||
fcall_added = true;
|
||||
}
|
||||
|
||||
set<SAPFOR::Argument*> make_live, make_dead;
|
||||
if (fName == "_READ")
|
||||
res.insert(lastParamRef.begin(), lastParamRef.end());
|
||||
else if (getLiveDead(lastParamRef, fName, make_live, make_dead))
|
||||
{
|
||||
insertIfVar(make_live.begin(), make_live.end(), args);
|
||||
insertIfVar(make_dead.begin(), make_dead.end(), res);
|
||||
}
|
||||
else
|
||||
insertIfVar(lastParamRef.begin(), lastParamRef.end(), args);
|
||||
|
||||
lastParamRef.clear();
|
||||
}
|
||||
else if(skip.find(instr_operation) == skip.end())
|
||||
{
|
||||
//default
|
||||
res_arg = instr->getResult();
|
||||
std::set<SAPFOR::Argument*> intr_args = { instr->getArg1(), instr->getArg2() };
|
||||
insertIfVar(intr_args.begin(), intr_args.end(), args);
|
||||
}
|
||||
else {
|
||||
//skip
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res_arg && res_arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||
res.insert(res_arg);
|
||||
|
||||
for (auto e : args)
|
||||
if (!tmp_def.count(e))
|
||||
tmp_use.insert(e);
|
||||
|
||||
for(auto e : res)
|
||||
if (!tmp_use.count(e))
|
||||
tmp_def.insert(e);
|
||||
|
||||
auto r_it = fcalls.rbegin();
|
||||
auto r_end = fcalls.rend();
|
||||
if (fcall_added && r_it != r_end)
|
||||
r_it++;
|
||||
|
||||
while (r_it != r_end && r_it->block == block)
|
||||
{
|
||||
for (auto e : args)
|
||||
r_it->make_live(e, block);
|
||||
|
||||
for (auto e : res)
|
||||
r_it->make_dead(e);
|
||||
|
||||
r_it++;
|
||||
}
|
||||
updateUseDefForInstruction(block, (*ir_block_it)->getInstruction(),
|
||||
use, def,
|
||||
formal_parameters, fcalls,
|
||||
lastParamRef, last_param_ref_index, last_param_ref_size,
|
||||
fName, funcByName,
|
||||
interprocedural
|
||||
);
|
||||
}
|
||||
|
||||
use = tmp_use;
|
||||
def = tmp_def;
|
||||
}
|
||||
|
||||
// minimizes the number of blocks beween the ends of back edges
|
||||
static vector<SAPFOR::BasicBlock*> reorderSequence(const vector<SAPFOR::BasicBlock*>& blocks,
|
||||
const set<SAPFOR::BasicBlock*> back_edge_sources)
|
||||
{
|
||||
vector<SAPFOR::BasicBlock*> res = { };
|
||||
|
||||
auto blocks_end = blocks.rend();
|
||||
for (auto it = blocks.rbegin(); it < blocks_end; it++)
|
||||
{
|
||||
SAPFOR::BasicBlock* curr = *it;
|
||||
auto res_end = res.end();
|
||||
auto inserter = res.begin();
|
||||
if (back_edge_sources.count(curr) == 0)
|
||||
{
|
||||
auto curr_next_begin = curr->getNext().begin();
|
||||
auto curr_next_end = curr->getNext().end();
|
||||
while (inserter < res_end && std::find(curr_next_begin, curr_next_end, *inserter) == curr_next_end)
|
||||
inserter++;
|
||||
}
|
||||
|
||||
res.insert(inserter, curr);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// finds back edges, reorders and converts blocks into vector of BasicBlockNode*
|
||||
// fills vector of formal parameters for given function
|
||||
// fills info about arguments which becomes live after calls of functions
|
||||
static vector<BasicBlockNode*> toBlocksWithCnt(const vector<SAPFOR::BasicBlock*>& blocks,
|
||||
vector<SAPFOR::Argument*>& formal_parameters,
|
||||
vector<fcall>& fcalls, const map<string, FuncInfo*>& funcByName)
|
||||
{
|
||||
set<pair<SAPFOR::BasicBlock*, SAPFOR::BasicBlock*>> back_edges = {};
|
||||
|
||||
bool returned = false;
|
||||
map<SAPFOR::BasicBlock*, set<SAPFOR::BasicBlock*>> back_edges_by_src;
|
||||
|
||||
auto blocks_sorted = sortCfgNodes(blocks, &back_edges);
|
||||
|
||||
set<SAPFOR::BasicBlock*> back_edge_sources;
|
||||
|
||||
for (auto& edge : back_edges)
|
||||
{
|
||||
back_edges_by_src[edge.first].insert(edge.second);
|
||||
back_edge_sources.insert(edge.first);
|
||||
}
|
||||
|
||||
back_edges.clear();
|
||||
|
||||
blocks_sorted = reorderSequence(blocks_sorted, back_edge_sources);
|
||||
back_edge_sources.clear();
|
||||
|
||||
vector<BasicBlockNode*> blocks_with_counters;
|
||||
map<SAPFOR::BasicBlock*, BasicBlockNode*> node_by_block;
|
||||
for (auto block : blocks_sorted)
|
||||
{
|
||||
BasicBlockNode* node = new BasicBlockNode(block, formal_parameters, fcalls, funcByName);
|
||||
blocks_with_counters.push_back(node);
|
||||
node_by_block[block] = node;
|
||||
}
|
||||
|
||||
for (auto r_it = blocks_with_counters.rbegin(); r_it != blocks_with_counters.rend(); r_it++)
|
||||
{
|
||||
auto back_edges_by_src_it = back_edges_by_src.find((*r_it)->bb);
|
||||
if (back_edges_by_src_it != back_edges_by_src.end())
|
||||
{
|
||||
// This node is a source for back edge
|
||||
for (auto dest : back_edges_by_src_it->second)
|
||||
{
|
||||
auto node_by_block_it = node_by_block.find(dest);
|
||||
if (node_by_block_it != node_by_block.end())
|
||||
node_by_block_it->second->rollback.insert(r_it);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto next : (*r_it)->bb->getNext())
|
||||
{
|
||||
auto node_by_block_it = node_by_block.find(next);
|
||||
if (node_by_block_it != node_by_block.end())
|
||||
(*r_it)->next_blocks.insert(node_by_block_it->second);
|
||||
}
|
||||
}
|
||||
|
||||
return blocks_with_counters;
|
||||
}
|
||||
|
||||
// iterate over separated subset of blocks
|
||||
static void analyzeSequence(const vector<BasicBlockNode*>& blocks_with_counters)
|
||||
{
|
||||
auto curr = blocks_with_counters.rbegin();
|
||||
auto stop = blocks_with_counters.rend();
|
||||
|
||||
while (curr != stop)
|
||||
{
|
||||
auto curr_bb = *curr;
|
||||
curr_bb->updateLive();
|
||||
|
||||
const auto& jumps = curr_bb->rollback;
|
||||
if (jumps.size() != 0)
|
||||
{
|
||||
auto& ignored_jumps = curr_bb->ignore_rollback;
|
||||
|
||||
bool jump = false;
|
||||
for (const auto& jump_to : jumps)
|
||||
{
|
||||
if (ignored_jumps.insert(jump_to).second && curr_bb->newerThan(*jump_to))
|
||||
{
|
||||
jump = true;
|
||||
curr = jump_to;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!jump)
|
||||
curr_bb->ignore_rollback.clear();
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
curr++;
|
||||
}
|
||||
}
|
||||
|
||||
// delete all nodes from vector
|
||||
static void freeBlocksWithCnt(const vector<BasicBlockNode*>& blocks_with_counters)
|
||||
{
|
||||
for (auto to_free : blocks_with_counters)
|
||||
delete to_free;
|
||||
}
|
||||
|
||||
// prints info about live variables
|
||||
@@ -527,7 +460,7 @@ void doDumpLive(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& CFGraph_for_p
|
||||
for (const auto& live : byBB->getLiveIn())
|
||||
{
|
||||
__spf_print(1, " %s:", live.first->getValue().c_str());
|
||||
for(auto use : live.second)
|
||||
for (auto use : live.second)
|
||||
__spf_print(1, " %d", use->getNumber());
|
||||
__spf_print(1, "\n");
|
||||
}
|
||||
@@ -630,8 +563,8 @@ static void fillLiveDeadArgs(const FuncInfo* func, const vector<SAPFOR::BasicBlo
|
||||
// unite global arguments and actual parameters with given indexes for function
|
||||
// stores the result in the last argument
|
||||
bool joinGlobalsWithParameters(const vector<SAPFOR::Argument*>& params,
|
||||
const map<string, pair<set<int>, set<SAPFOR::Argument*>>>& params_and_globals,
|
||||
const string& func_name, set<SAPFOR::Argument*>& result)
|
||||
const map<string, pair<set<int>, set<SAPFOR::Argument*>>>& params_and_globals,
|
||||
const string& func_name, set<SAPFOR::Argument*>& result)
|
||||
{
|
||||
auto globals_it = params_and_globals.find(func_name);
|
||||
|
||||
@@ -646,7 +579,7 @@ bool joinGlobalsWithParameters(const vector<SAPFOR::Argument*>& params,
|
||||
for (int idx : param_indexes)
|
||||
{
|
||||
if (idx < params_size) {
|
||||
if(params[idx] && params[idx]->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||
if (params[idx] && params[idx]->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||
result.insert(params[idx]);
|
||||
}
|
||||
else
|
||||
@@ -658,11 +591,11 @@ bool joinGlobalsWithParameters(const vector<SAPFOR::Argument*>& params,
|
||||
}
|
||||
|
||||
// fill sets of arguments wich becomes live or dead after call with parameters params
|
||||
static bool getLiveDead(const vector<SAPFOR::Argument*>& params, const string& func_name,
|
||||
set<SAPFOR::Argument*>& live, set<SAPFOR::Argument*>& dead)
|
||||
static bool getLiveDead(const vector<SAPFOR::Argument*>& params, const string& func_name,
|
||||
set<SAPFOR::Argument*>& live, set<SAPFOR::Argument*>& dead)
|
||||
{
|
||||
return joinGlobalsWithParameters(params, live_by_func, func_name, live) &&
|
||||
joinGlobalsWithParameters(params, dead_by_func, func_name, dead);
|
||||
joinGlobalsWithParameters(params, dead_by_func, func_name, dead);
|
||||
}
|
||||
|
||||
// entrypoint for live variable analysis pass
|
||||
@@ -682,14 +615,14 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
||||
callDeps[byFunc.first].insert(byFunc.first->callsFromV.begin(), byFunc.first->callsFromV.end());
|
||||
funcByName[byFunc.first->funcName] = byFunc.first;
|
||||
}
|
||||
|
||||
|
||||
vector<set<FuncInfo*>> scc;
|
||||
vector<set<FuncInfo*>> callLvls = groupByCallDependencies(callDeps, scc);
|
||||
|
||||
map<string, vector<BasicBlockNode*>> func_to_blocks_with_cnt;
|
||||
map<string, LiveVarAnalysis*> func_to_analysis_object;
|
||||
map<string, vector<SAPFOR::Argument*>> func_to_parameters;
|
||||
|
||||
list<vector<fcall>> live_for_fcalls;
|
||||
list<vector<LiveDeadVarsForCall>> live_for_fcalls;
|
||||
|
||||
//TODO: take into account ssc structure
|
||||
// main stage
|
||||
@@ -707,8 +640,9 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
||||
|
||||
auto& params = func_to_parameters[byFunc->funcName] = vector<SAPFOR::Argument*>(byFunc->funcParams.countOfPars, NULL);
|
||||
|
||||
auto& blocks_with_cnt = (func_to_blocks_with_cnt[byFunc->funcName] = toBlocksWithCnt(itCFG->second, params, curr_fcalls, funcByName));
|
||||
analyzeSequence(blocks_with_cnt);
|
||||
LiveVarAnalysis* analysis_object = (func_to_analysis_object[byFunc->funcName] = new LiveVarAnalysis(params, curr_fcalls, funcByName));
|
||||
analysis_object->fit(itCFG->second);
|
||||
analysis_object->analyze();
|
||||
|
||||
fillLiveDeadArgs(byFunc, itCFG->second);
|
||||
}
|
||||
@@ -717,7 +651,7 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
||||
// interprocedural analysis
|
||||
for (auto& calls_vector : live_for_fcalls)
|
||||
{
|
||||
map<FuncInfo*, fcall> assembled_fcalls;
|
||||
map<FuncInfo*, LiveDeadVarsForCall> assembled_fcalls;
|
||||
for (auto& call : calls_vector)
|
||||
{
|
||||
call.updateFromOut();
|
||||
@@ -727,8 +661,8 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
||||
|
||||
auto it = assembled_fcalls.find(call.func);
|
||||
if (it == assembled_fcalls.end())
|
||||
it = assembled_fcalls.insert({ call.func, fcall(call.func, call.block, {}) }).first;
|
||||
|
||||
it = assembled_fcalls.insert({ call.func, LiveDeadVarsForCall(call.func, call.block, {}) }).first;
|
||||
|
||||
for (const auto& p : call.live_after)
|
||||
it->second.live_after[p.first].insert(p.second.begin(), p.second.end());
|
||||
|
||||
@@ -738,12 +672,12 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
||||
|
||||
for (const auto& func : assembled_fcalls)
|
||||
{
|
||||
auto func_it = func_to_blocks_with_cnt.find(func.first->funcName);
|
||||
if (func_it == func_to_blocks_with_cnt.end())
|
||||
auto func_it = func_to_analysis_object.find(func.first->funcName);
|
||||
if (func_it == func_to_analysis_object.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
auto param_it = func_to_parameters.find(func.first->funcName);
|
||||
if(param_it == func_to_parameters.end())
|
||||
if (param_it == func_to_parameters.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
const vector<SAPFOR::Argument*>& params = param_it->second;
|
||||
@@ -761,14 +695,14 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
||||
}
|
||||
}
|
||||
|
||||
set<BasicBlockNode*> exits;
|
||||
int max_cnt = CNT_NOTINIT;
|
||||
for (auto block : func_it->second)
|
||||
set<LiveVarAnalysisNode*> exits;
|
||||
int max_cnt = LiveVarAnalysisNode::getStartCounter();
|
||||
for (auto block : func_it->second->getNodes())
|
||||
{
|
||||
if (block->bb->getNext().size() == 0)
|
||||
if (block->getBlock()->getNext().size() == 0)
|
||||
exits.insert(block);
|
||||
if (block->out_cnt > max_cnt)
|
||||
max_cnt = block->out_cnt;
|
||||
if (block->getInCnt() > max_cnt)
|
||||
max_cnt = block->getInCnt();
|
||||
}
|
||||
|
||||
max_cnt++;
|
||||
@@ -777,23 +711,25 @@ void runLiveVariableAnalysis(const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>&
|
||||
{
|
||||
for (const auto& byArg : live_after)
|
||||
{
|
||||
if (exit->bb->addLiveOut({ byArg }))
|
||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> converted;
|
||||
converted[byArg.first] = vector<SAPFOR::BasicBlock*>(byArg.second.begin(), byArg.second.end());
|
||||
|
||||
if (exit->addIn(converted))
|
||||
{
|
||||
exit->out_cnt = max_cnt;
|
||||
if (exit->live.find(byArg.first) == exit->live.end() && exit->dead.find(byArg.first) == exit->dead.end())
|
||||
if (exit->bb->addLiveIn({ byArg }))
|
||||
exit->in_cnt = max_cnt;
|
||||
exit->setInCnt(max_cnt);
|
||||
if (exit->forwardData(converted))
|
||||
exit->setOutCnt(max_cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now we can update live sets in all blocks
|
||||
analyzeSequence(func_it->second);
|
||||
func_it->second->analyze();
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& nodeByFunc : func_to_blocks_with_cnt)
|
||||
freeBlocksWithCnt(nodeByFunc.second);
|
||||
for (const auto& byFunc : func_to_analysis_object)
|
||||
delete byFunc.second;
|
||||
|
||||
for (auto& byFunc : CFGraph_for_project)
|
||||
for (auto& byBlock : byFunc.second)
|
||||
|
||||
@@ -1,12 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "CFGraph.h"
|
||||
|
||||
namespace LIVE_VARIABLES
|
||||
{
|
||||
/* Store information about live and dead variables after call operator */
|
||||
/* (needed for interprocedural part of live variable analysis) */
|
||||
class LiveDeadVarsForCall
|
||||
{
|
||||
private:
|
||||
bool tryInsert(std::set<SAPFOR::BasicBlock*>& dest, SAPFOR::BasicBlock* b);
|
||||
public:
|
||||
FuncInfo* func;
|
||||
|
||||
std::map<int, std::set<SAPFOR::BasicBlock*>> live_after;
|
||||
std::set<int> dead_after;
|
||||
|
||||
std::map<SAPFOR::Argument*, std::set<SAPFOR::BasicBlock*>> commons_live_after;
|
||||
std::set<SAPFOR::Argument*> commons_dead_after;
|
||||
|
||||
std::vector<SAPFOR::Argument*> params;
|
||||
SAPFOR::BasicBlock* block;
|
||||
|
||||
LiveDeadVarsForCall(FuncInfo* f, SAPFOR::BasicBlock* b, const std::vector<SAPFOR::Argument*>& p);
|
||||
|
||||
void make_live(SAPFOR::Argument* arg, SAPFOR::BasicBlock* b);
|
||||
void make_dead(SAPFOR::Argument* arg);
|
||||
|
||||
void updateFromOut();
|
||||
};
|
||||
}
|
||||
|
||||
template <class IT, class DEST>
|
||||
void insertIfVar(IT begin, IT end, DEST& to) {
|
||||
for (auto it = begin; it != end; it++)
|
||||
if (*it && (*it)->getType() == SAPFOR::CFG_ARG_TYPE::VAR)
|
||||
to.insert(*it);
|
||||
};
|
||||
}
|
||||
|
||||
void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
||||
std::set<SAPFOR::Argument*>& use, std::set<SAPFOR::Argument*>& def,
|
||||
std::vector<SAPFOR::Argument*>& formal_parameters, std::vector<LIVE_VARIABLES::LiveDeadVarsForCall>& fcalls,
|
||||
std::vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
||||
std::string& fName, const std::map<std::string, FuncInfo*>& funcByName, bool interprocedural);
|
||||
|
||||
void runLiveVariableAnalysis(const std::map<FuncInfo*, std::vector<SAPFOR::BasicBlock*>>& CFGraph_for_project);
|
||||
|
||||
|
||||
@@ -1095,9 +1095,16 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
|
||||
tmpL = loop->parent;
|
||||
while (tmpL)
|
||||
{
|
||||
|
||||
if (!tmpL->isFor) // TODO: need to add all inductive variables!
|
||||
;// return false;
|
||||
{
|
||||
SgWhileStmt* dow = isSgWhileStmt(tmpL->loop->GetOriginal());
|
||||
if (dow->conditional())
|
||||
{
|
||||
SgExpression* cond = dow->conditional();
|
||||
if (cond->lhs() && cond->lhs()->variant() == VAR_REF)
|
||||
deprecateToMatch.insert(cond->lhs()->symbol()->identifier());
|
||||
}
|
||||
}
|
||||
else
|
||||
deprecateToMatch.insert(tmpL->loopSymbol);
|
||||
tmpL = tmpL->parent;
|
||||
@@ -1802,14 +1809,6 @@ static bool addRedistributionDirs(File* file, const vector<pair<DIST::Array*, co
|
||||
return needToSkip;
|
||||
}
|
||||
|
||||
uint64_t getTrueRegId(const uint64_t regId, const uint64_t loopRegId)
|
||||
{
|
||||
if (mpiProgram)
|
||||
return loopRegId;
|
||||
else
|
||||
return regId;
|
||||
}
|
||||
|
||||
void selectParallelDirectiveForVariant(File* file, ParallelRegion* currParReg,
|
||||
DIST::GraphCSR<int, double, attrType>& reducedG,
|
||||
DIST::Arrays<int>& allArrays,
|
||||
@@ -1826,13 +1825,12 @@ void selectParallelDirectiveForVariant(File* file, ParallelRegion* currParReg,
|
||||
for (int i = 0; i < loopGraph.size(); ++i)
|
||||
{
|
||||
LoopGraph* loop = loopGraph[i];
|
||||
const uint64_t loopRegId = (uint64_t)loop;
|
||||
const bool hasDirective = loop->directive;
|
||||
const bool noLimits = loop->hasLimitsToParallel() == false;
|
||||
const bool isMyRegion = loop->region == currParReg;
|
||||
const bool noUserDir = loop->userDvmDirective == NULL;
|
||||
DIST::Array* sameAlignTemplate = NULL;
|
||||
const bool sameAligns = loop->isArrayTemplatesTheSame(sameAlignTemplate, getTrueRegId(regionId, loopRegId), arrayLinksByFuncCalls);
|
||||
const bool sameAligns = loop->isArrayTemplatesTheSame(sameAlignTemplate, regionId, arrayLinksByFuncCalls);
|
||||
|
||||
bool freeLoopDistr = true;
|
||||
if (hasDirective && loop->directive->arrayRef2->IsLoopArray())
|
||||
@@ -1871,18 +1869,18 @@ void selectParallelDirectiveForVariant(File* file, ParallelRegion* currParReg,
|
||||
bool topCheck = isOnlyTopPerfect(loop, distribution);
|
||||
|
||||
bool needToContinue = false;
|
||||
if (topCheck && mpiProgram == 0)
|
||||
if (topCheck)
|
||||
{
|
||||
//<Array, linksWithTempl> -> dims not mached
|
||||
map<DIST::Array*, vector<bool>> dimsNotMatch;
|
||||
if (!checkCorrectness(*parDirective, distribution, reducedG, allArrays, arrayLinksByFuncCalls, loop->getAllArraysInLoop(), messages, loop->lineNum, dimsNotMatch, getTrueRegId(regionId, loopRegId)))
|
||||
if (!checkCorrectness(*parDirective, distribution, reducedG, allArrays, arrayLinksByFuncCalls, loop->getAllArraysInLoop(), messages, loop->lineNum, dimsNotMatch, regionId))
|
||||
{
|
||||
if (!tryToResolveUnmatchedDims(dimsNotMatch, loop, getTrueRegId(regionId, loopRegId), parDirective, reducedG, allArrays, arrayLinksByFuncCalls, distribution, mapFuncInfo))
|
||||
needToContinue = addRedistributionDirs(file, distribution, toInsert, loop, mapLoopsInFile, parDirective, getTrueRegId(regionId, loopRegId), messages, arrayLinksByFuncCalls, sameAlignTemplate);
|
||||
if (!tryToResolveUnmatchedDims(dimsNotMatch, loop, regionId, parDirective, reducedG, allArrays, arrayLinksByFuncCalls, distribution, mapFuncInfo))
|
||||
needToContinue = addRedistributionDirs(file, distribution, toInsert, loop, mapLoopsInFile, parDirective, regionId, messages, arrayLinksByFuncCalls, sameAlignTemplate);
|
||||
}
|
||||
}
|
||||
else if (mpiProgram == 0)
|
||||
needToContinue = addRedistributionDirs(file, distribution, toInsert, loop, mapLoopsInFile, parDirective, getTrueRegId(regionId, loopRegId), messages, arrayLinksByFuncCalls, sameAlignTemplate);
|
||||
else
|
||||
needToContinue = addRedistributionDirs(file, distribution, toInsert, loop, mapLoopsInFile, parDirective, regionId, messages, arrayLinksByFuncCalls, sameAlignTemplate);
|
||||
|
||||
if (needToContinue)
|
||||
continue;
|
||||
@@ -1890,7 +1888,7 @@ void selectParallelDirectiveForVariant(File* file, ParallelRegion* currParReg,
|
||||
vector<pair<DIST::Array*, const DistrVariant*>> newRules;
|
||||
constructRules(newRules, distribution, loop);
|
||||
|
||||
Directive* dirImpl = parDirective->genDirective(file, newRules, loop, reducedG, allArrays, getTrueRegId(regionId, loopRegId), arrayLinksByFuncCalls);
|
||||
Directive* dirImpl = parDirective->genDirective(file, newRules, loop, reducedG, allArrays, regionId, arrayLinksByFuncCalls);
|
||||
|
||||
#if __SPF
|
||||
//move label before loop
|
||||
|
||||
@@ -102,20 +102,18 @@ void createParallelDirectivesNoDist(const map<LoopGraph*, map<DIST::Array*, Arra
|
||||
|
||||
|
||||
void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currParReg,
|
||||
DIST::Arrays<int>& allArrays,
|
||||
const vector<LoopGraph*>& loopGraph,
|
||||
const map<int, LoopGraph*>& mapLoopsInFile,
|
||||
const map<string, FuncInfo*>& mapFuncInfo,
|
||||
vector<Directive*>& toInsert,
|
||||
const uint64_t regionId,
|
||||
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
|
||||
const map<LoopGraph*, void*>& depInfoForLoopGraph,
|
||||
vector<Messages>& messages)
|
||||
DIST::Arrays<int>& allArrays,
|
||||
const vector<LoopGraph*>& loopGraph,
|
||||
const map<int, LoopGraph*>& mapLoopsInFile,
|
||||
const map<string, FuncInfo*>& mapFuncInfo,
|
||||
vector<Directive*>& toInsert,
|
||||
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
|
||||
const map<LoopGraph*, void*>& depInfoForLoopGraph,
|
||||
vector<Messages>& messages)
|
||||
{
|
||||
for (int i = 0; i < loopGraph.size(); ++i)
|
||||
{
|
||||
LoopGraph* loop = loopGraph[i];
|
||||
const uint64_t loopRegId = (uint64_t)loop;
|
||||
const bool hasDirective = loop->directive;
|
||||
const bool noLimits = loop->hasLimitsToParallel() == false;
|
||||
const bool isMyRegion = loop->region == currParReg;
|
||||
@@ -133,7 +131,7 @@ void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currPar
|
||||
parDirective = loop->recalculateParallelDirective();
|
||||
// rewrite bool topCheck = isOnlyTopPerfect(loop, distribution);
|
||||
|
||||
Directive* dirImpl = parDirective->genDirectiveNoDist(file, loop, allArrays, getTrueRegId(regionId, loopRegId), arrayLinksByFuncCalls);
|
||||
Directive* dirImpl = parDirective->genDirectiveNoDist(file, loop, allArrays, arrayLinksByFuncCalls);
|
||||
|
||||
#if __SPF
|
||||
//move label before loop
|
||||
@@ -167,7 +165,7 @@ void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currPar
|
||||
{
|
||||
if (loopGraph[i]->children.size() != 0)
|
||||
selectParallelDirectiveForVariantNoDist(file, currParReg, allArrays, loopGraph[i]->children, mapLoopsInFile, mapFuncInfo,
|
||||
toInsert, regionId, arrayLinksByFuncCalls,depInfoForLoopGraph, messages);
|
||||
toInsert, arrayLinksByFuncCalls,depInfoForLoopGraph, messages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
|
||||
void addShadowFromAnalysis(ParallelDirective* dir, const std::map<DIST::Array*, ArrayInfo*>& currAccesses);
|
||||
|
||||
bool checkForConflict(const std::map<DIST::Array*, ArrayInfo*>& currAccesses,
|
||||
const LoopGraph* currentLoop,
|
||||
std::map<DIST::Array*, std::pair<int, std::pair<int, int>>, DIST::ArrayComparator>& arrayWriteAcc,
|
||||
const std::vector<std::pair<std::pair<std::string, std::string>, std::vector<std::pair<int, int>>>>& acrossInfo,
|
||||
std::set<DIST::Array*>& acrossOutArrays);
|
||||
|
||||
uint64_t getTrueRegId(const uint64_t regId, const uint64_t loopRegId);
|
||||
|
||||
bool checkForConflict(const std::map<DIST::Array*, ArrayInfo*>& currAccesses,
|
||||
const LoopGraph* currentLoop,
|
||||
std::map<DIST::Array*, std::pair<int, std::pair<int, int>>, DIST::ArrayComparator>& arrayWriteAcc,
|
||||
const std::vector<std::pair<std::pair<std::string, std::string>, std::vector<std::pair<int, int>>>>& acrossInfo,
|
||||
std::set<DIST::Array*>& acrossOutArrays);
|
||||
|
||||
@@ -21,7 +21,6 @@ void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currPar
|
||||
const std::map<int, LoopGraph*>& mapLoopsInFile,
|
||||
const std::map<std::string, FuncInfo*>& mapFuncInfo,
|
||||
std::vector<Directive*>& toInsert,
|
||||
const uint64_t regionId,
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
|
||||
const std::map<LoopGraph*, void*>& depInfoForLoopGraph,
|
||||
std::vector<Messages>& messages);
|
||||
@@ -721,6 +721,27 @@ static inline void addToAttribute(SgStatement* st, int var, vector<SgExpression*
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_private_in_do(SgStatement* st, const string& var)
|
||||
{
|
||||
checkNull(st, convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
if (st->variant() != FOR_NODE)
|
||||
return false;
|
||||
|
||||
SgStatement* lastNode = st->lastNodeOfStmt();
|
||||
for (SgStatement* op = st->lexNext(); st != lastNode; st = st->lexNext())
|
||||
{
|
||||
if (st->variant() == ASSIGN_STAT)
|
||||
{
|
||||
SgExpression* ex = st->expr(0);
|
||||
if (ex->variant() == ARRAY_REF || ex->variant() == VAR_REF)
|
||||
if (var == ex->symbol()->identifier())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<OmpDir> parseOmpDirs(void* stIn, const set<string> &globalPriv, bool forDo)
|
||||
{
|
||||
SgStatement* st = (SgStatement*)stIn;
|
||||
@@ -825,8 +846,11 @@ vector<OmpDir> parseOmpDirs(void* stIn, const set<string> &globalPriv, bool forD
|
||||
{
|
||||
vector<SgExpression*> list;
|
||||
for (auto& var : globalPriv)
|
||||
list.push_back(new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st))));
|
||||
addToAttribute(st, ACC_PRIVATE_OP, list);
|
||||
if (is_private_in_do(st, var))
|
||||
list.push_back(new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st))));
|
||||
|
||||
if (list.size())
|
||||
addToAttribute(st, ACC_PRIVATE_OP, list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -144,9 +144,8 @@ public:
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls);
|
||||
|
||||
Directive*
|
||||
genDirectiveNoDist(File* file, LoopGraph* currLoop,
|
||||
DIST::Arrays<int>& allArrays, const uint64_t regionId,
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
|
||||
genDirectiveNoDist(File* file, LoopGraph* currLoop, DIST::Arrays<int>& allArrays,
|
||||
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
|
||||
|
||||
friend ParallelDirective* operator+(const ParallelDirective &first, const ParallelDirective &second);
|
||||
|
||||
|
||||
@@ -91,9 +91,8 @@ compliteTieListNoDist(const LoopGraph* currLoop, const vector<LoopGraph*>& loops
|
||||
}
|
||||
|
||||
Directive*
|
||||
ParallelDirective::genDirectiveNoDist(File* file, LoopGraph* currLoop,
|
||||
DIST::Arrays<int>& allArrays, const uint64_t regionId,
|
||||
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
|
||||
ParallelDirective::genDirectiveNoDist(File* file, LoopGraph* currLoop, DIST::Arrays<int>& allArrays,
|
||||
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
|
||||
{
|
||||
const set<DIST::Array*>& acrossOutAttribute = currLoop->acrossOutAttribute;
|
||||
const map<DIST::Array*, pair<vector<ArrayOp>, vector<bool>>>& readOps = currLoop->readOps;
|
||||
|
||||
@@ -382,7 +382,17 @@ ArraySet DvmhRegionInserter::excludeRemotes(const ArraySet& block, SgStatement*
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
SgStatement* next = remoteDir->lexNext();
|
||||
const string leftS = next->variant() == ASSIGN_STAT ? OriginalSymbol(next->expr(0)->symbol())->identifier() : "";
|
||||
const string leftS = "";
|
||||
|
||||
//TODO: record ref!
|
||||
if (next->variant() == ASSIGN_STAT)
|
||||
{
|
||||
auto ex = next->expr(0);
|
||||
if (ex->variant() == ARRAY_REF)
|
||||
OriginalSymbol(ex->symbol())->identifier();
|
||||
else if (ex->variant() == RECORD_REF && ex->rhs()->variant() == ARRAY_REF)
|
||||
OriginalSymbol(ex->rhs()->symbol())->identifier();
|
||||
}
|
||||
|
||||
set<DIST::Array*> raArrays;
|
||||
|
||||
|
||||
@@ -911,7 +911,9 @@ static void fillFunctionPureStatus(SgStatement *header, FuncInfo *currInfo, vect
|
||||
if (currInfo->commonBlocks.size() == 0)
|
||||
{
|
||||
lines.clear();
|
||||
bool has = hasThisIds(header, lines, { DATA_DECL, SAVE_DECL, USE_STMT });
|
||||
bool has = hasThisIds(header, lines, { DATA_DECL, SAVE_DECL, USE_STMT,
|
||||
WRITE_STAT, READ_STAT, OPEN_STAT, CLOSE_STAT,
|
||||
PRINT_STAT, STOP_STAT, PAUSE_NODE });
|
||||
if (!has || declaratedAsPure)
|
||||
currInfo->isPure = true;
|
||||
else
|
||||
|
||||
@@ -222,6 +222,9 @@ struct FuncInfo
|
||||
|
||||
std::string getCallName(const std::pair<void*, int>& call_info, const std::string& name, int line)
|
||||
{
|
||||
if (line <= 0)
|
||||
return name;
|
||||
|
||||
std::set<std::string> names;
|
||||
|
||||
for (auto& call : callsFromDetailed)
|
||||
|
||||
@@ -137,6 +137,11 @@ static map<string, SgExpression*> createMapOfArgs(SgStatement* tempHedr, SgExpre
|
||||
return vars;
|
||||
}
|
||||
|
||||
static bool isAllocated(SgSymbol* s)
|
||||
{
|
||||
return (s->attributes() & ALLOCATABLE_BIT) || (s->attributes() & POINTER_BIT);
|
||||
}
|
||||
|
||||
static inline SgSymbol* createSymbAndDecl(const string& funcName, const string& varName, SgSymbol* newS, set<SgSymbol*>& newSymbols, SgType* type = NULL)
|
||||
{
|
||||
SgSymbol* original = newS;
|
||||
@@ -208,7 +213,7 @@ static inline SgSymbol* createSymbAndDecl(const string& funcName, const string&
|
||||
{
|
||||
createdByFunc[key][varName] = newS;
|
||||
count[0] = nextCount;
|
||||
if (original && (original->attributes() & ALLOCATABLE_BIT))
|
||||
if (original && isAllocated(original))
|
||||
linkToOrig[newS] = original;
|
||||
}
|
||||
else
|
||||
@@ -259,14 +264,12 @@ static SgValueExp* zeroExpr = NULL;
|
||||
|
||||
static vector<SgExpression*> getLowBounds(SgSymbol* arrayS)
|
||||
{
|
||||
|
||||
if (oneExpr == NULL)
|
||||
oneExpr = new SgValueExp(1);
|
||||
|
||||
SgExpression* list = NULL;
|
||||
|
||||
|
||||
if (arrayS->attributes() & ALLOCATABLE_BIT)
|
||||
if (isAllocated(arrayS))
|
||||
{
|
||||
SgSymbol* copyFrom = NULL;
|
||||
if (linkToOrig.find(arrayS) == linkToOrig.end())
|
||||
@@ -280,7 +283,27 @@ static vector<SgExpression*> getLowBounds(SgSymbol* arrayS)
|
||||
int consistInAllocates = 0;
|
||||
const string origName = OriginalSymbol(copyFrom)->identifier();
|
||||
|
||||
for (auto data : getAttributes<SgStatement*, SgStatement*>(decl, set<int>{ ALLOCATE_STMT }))
|
||||
auto allocData = getAttributes<SgStatement*, SgStatement*>(decl, set<int>{ ALLOCATE_STMT });
|
||||
if (allocData.size() == 0) // try to find statements in original file
|
||||
{
|
||||
string declFile(decl->fileName());
|
||||
int line = decl->lineNumber();
|
||||
string file_name = current_file->filename();
|
||||
|
||||
if (current_file->filename() != declFile)
|
||||
{
|
||||
auto trueDecl = SgStatement::getStatementByFileAndLine(declFile, line);
|
||||
if (trueDecl)
|
||||
{
|
||||
auto trueData = getAttributes<SgStatement*, SgStatement*>(trueDecl, set<int>{ ALLOCATE_STMT });
|
||||
if (trueData.size())
|
||||
allocData = trueData;
|
||||
}
|
||||
}
|
||||
SgFile::switchToFile(file_name);
|
||||
}
|
||||
|
||||
for (auto data : allocData)
|
||||
{
|
||||
if (data->variant() != ALLOCATE_STMT)
|
||||
continue;
|
||||
@@ -309,6 +332,8 @@ static vector<SgExpression*> getLowBounds(SgSymbol* arrayS)
|
||||
if (consistInAllocates != 1)
|
||||
list = NULL;
|
||||
|
||||
if (list == NULL)
|
||||
__spf_print(1, "find for %s, consistInAllocates = %d\n", arrayS->identifier(), consistInAllocates);
|
||||
checkNull(list, convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
else
|
||||
@@ -332,7 +357,7 @@ static vector<SgExpression*> getLowBounds(SgSymbol* arrayS)
|
||||
|
||||
static vector<SgExpression*> getBoundsExpression(SgSymbol* arrayS)
|
||||
{
|
||||
if (arrayS->attributes() & ALLOCATABLE_BIT)
|
||||
if (isAllocated(arrayS))
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
auto type = isSgArrayType(arrayS->type());
|
||||
@@ -360,10 +385,20 @@ static SgArrayRefExp* addressPass(SgArrayRefExp* result, SgArrayRefExp* arrayExp
|
||||
{
|
||||
checkNull(boundsOld[z], convertFileName(__FILE__).c_str(), __LINE__);
|
||||
checkNull(boundsNew[z], convertFileName(__FILE__).c_str(), __LINE__);
|
||||
SgExpression* shift = NULL;
|
||||
SgExpression& baseShift = (boundsNew[z]->copy() - boundsOld[z]->copy());
|
||||
|
||||
if (arrayExpNew->subscript(z) &&
|
||||
!isEqExpressions(arrayExpNew->subscript(z), boundsNew[z], collection))
|
||||
{
|
||||
shift = &(arrayExpNew->subscript(z)->copy() - boundsNew[z]->copy());
|
||||
}
|
||||
|
||||
SgExpression& oldSub = arrayExpOld->subscript(z)->copy();
|
||||
if (isEqExpressions(boundsOld[z], boundsNew[z], collection))
|
||||
result->addSubscript(arrayExpOld->subscript(z)->copy());
|
||||
result->addSubscript(shift ? (oldSub + *shift) : oldSub);
|
||||
else
|
||||
result->addSubscript(arrayExpOld->subscript(z)->copy() + (boundsNew[z]->copy() - boundsOld[z]->copy()));
|
||||
result->addSubscript(shift ? (oldSub + baseShift + *shift) : (oldSub + baseShift));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -449,12 +484,19 @@ static SgExpression* doReplace(SgExpression* oldExp, SgExpression* newExp, map<S
|
||||
SgArrayRefExp* arrayExpOld = isSgArrayRefExp(oldExp);
|
||||
SgArrayRefExp* arrayExpNew = isSgArrayRefExp(newExp);
|
||||
|
||||
//arrayExpOld->unparsestdout();
|
||||
//arrayExpNew->unparsestdout();
|
||||
//printf("\n");
|
||||
/*arrayExpOld->unparsestdout();
|
||||
arrayExpNew->unparsestdout();
|
||||
printf("\n");*/
|
||||
|
||||
auto boundsOld = getLowBounds(oldExp->symbol());
|
||||
auto boundsNew = getLowBounds(newExp->symbol());
|
||||
|
||||
/*for (auto& elem : boundsOld)
|
||||
elem->unparsestdout();
|
||||
printf("--\n");
|
||||
for (auto& elem : boundsNew)
|
||||
elem->unparsestdout();
|
||||
printf("--\n");*/
|
||||
|
||||
const int numOldSubs = arrayExpOld->numberOfSubscripts();
|
||||
const int numNewSubs = arrayExpNew->numberOfSubscripts();
|
||||
@@ -503,7 +545,6 @@ static SgExpression* doReplace(SgExpression* oldExp, SgExpression* newExp, map<S
|
||||
result = addressPass(result, arrayExpOld, arrayExpNew, boundsOld, boundsNew, collection);
|
||||
for (int z = 0; z < boundsNew.size() - boundsOld.size(); ++z)
|
||||
result->addSubscript(arrayExpNew->subscript(boundsOld.size() + z)->copy());
|
||||
|
||||
retVal = result;
|
||||
}
|
||||
else
|
||||
@@ -939,10 +980,14 @@ static void insert(SgStatement* callSt, SgStatement* tempHedr, SgStatement* begi
|
||||
auto next = prev->lexNext();
|
||||
if (callSt->comments())
|
||||
{
|
||||
if (next->comments())
|
||||
next->setComments((string(callSt->comments()) + next->comments()).c_str());
|
||||
string callCom(callSt->comments());
|
||||
if (next->comments()) {
|
||||
string newCom = callCom + next->comments();
|
||||
next->setComments(newCom.c_str());
|
||||
}
|
||||
else
|
||||
next->addComment(callSt->comments());
|
||||
next->addComment(callCom.c_str());
|
||||
callSt->delComments();
|
||||
}
|
||||
|
||||
auto ident = string(tempHedr->symbol()->identifier());
|
||||
@@ -1715,7 +1760,7 @@ static bool inliner(const string& fileName_in, const string& funcName, const int
|
||||
point.currLvl = 0;
|
||||
point.currCall = func->funcName;
|
||||
|
||||
__spf_print(1, " INLINE %s\n", func->funcName.c_str());
|
||||
__spf_print(1, " INLINE %s - ", func->funcName.c_str());
|
||||
#ifdef _WIN32
|
||||
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
|
||||
@@ -1723,6 +1768,7 @@ static bool inliner(const string& fileName_in, const string& funcName, const int
|
||||
#endif
|
||||
//1 level
|
||||
bool isInlined = run_inliner(funcMap, toInsert, SPF_messages, fileName, func, newSymbsToDeclare, point, commonBlocks);
|
||||
__spf_print(1, "%s\n", isInlined ? "done" : "fault");
|
||||
|
||||
if (isInlined == false)
|
||||
{
|
||||
@@ -1754,8 +1800,9 @@ static bool inliner(const string& fileName_in, const string& funcName, const int
|
||||
|
||||
point.currLvl = currDeep;
|
||||
point.currCall = next.first->funcName;
|
||||
__spf_print(1, " INLINE %s\n", next.first->funcName.c_str());
|
||||
__spf_print(1, " INLINE %s - ", next.first->funcName.c_str());
|
||||
bool isInlined = run_inliner(funcMap, next.second, SPF_messages, fileName, next.first, newSymbsToDeclare, point, commonBlocks);
|
||||
__spf_print(1, "%s\n", isInlined ? "done" : "fault");
|
||||
changed |= isInlined;
|
||||
}
|
||||
}
|
||||
@@ -2163,7 +2210,7 @@ static void createDeclarations(const map<SgStatement*, set<SgSymbol*>>& newSymbs
|
||||
if (globalType != 1) // not in COMMON
|
||||
saveRefs[toDec->identifier()] = toDec;
|
||||
|
||||
if (toDec->attributes() & ALLOCATABLE_BIT)
|
||||
if (isAllocated(toDec))
|
||||
allocatable.insert(toDec);
|
||||
|
||||
if (toDec->attributes() & DATA_BIT)
|
||||
@@ -2386,7 +2433,7 @@ static void convertLinesToAbsolute(const map<string, vector<FuncInfo*>>& allFunc
|
||||
if (detCall.detailCallsFrom == make_pair(funcToInl, targetLine) &&
|
||||
added.find(make_tuple(file, funcToInl, targetLine)) == added.end())
|
||||
{
|
||||
__spf_print(1, "%s %d (was %d) %s\n", funcToInl, targetLine, std::get<2>(inDataProc[z]), funcByFile.first.c_str());
|
||||
__spf_print(1, "%s %d (was %d) %s\n", funcToInl.c_str(), targetLine, std::get<2>(inDataProc[z]), funcByFile.first.c_str());
|
||||
added.insert(make_tuple(file, funcToInl, targetLine));
|
||||
absoluteLine = targetLine;
|
||||
break;
|
||||
|
||||
@@ -2666,7 +2666,7 @@ static void findArrayRefs(SgExpression *ex, SgStatement *st, string fName, int p
|
||||
const vector<string> &inRegion,
|
||||
const set<string> &funcParNames,
|
||||
map<SgStatement*, set<string>>& ompThreadPrivate,
|
||||
const map<string, int>& keyValueFromGUI,
|
||||
const map<string, int>& distrStateFromGUI,
|
||||
const bool saveAllLocals,
|
||||
map<string, vector<Messages>>& currMessages,
|
||||
int& errorCount)
|
||||
@@ -2852,8 +2852,8 @@ static void findArrayRefs(SgExpression *ex, SgStatement *st, string fName, int p
|
||||
itNew->second.first->SetDistributeFlag(DIST::SPF_PRIV);
|
||||
else
|
||||
{
|
||||
auto it = keyValueFromGUI.find(itNew->second.first->GetIndepUniqName());
|
||||
if (it != keyValueFromGUI.end())
|
||||
auto it = distrStateFromGUI.find(itNew->second.first->GetIndepUniqName());
|
||||
if (it != distrStateFromGUI.end())
|
||||
{
|
||||
if (it->second != oldVal)
|
||||
{
|
||||
@@ -2910,7 +2910,7 @@ static void findArrayRefs(SgExpression *ex, SgStatement *st, string fName, int p
|
||||
//assume all arguments of function as OUT, except for inctrinsics
|
||||
bool isWriteN = intr ? false : true;
|
||||
//need to correct W/R usage with GraphCall map later
|
||||
findArrayRefs(funcExp->arg(z), st, fName, z, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, keyValueFromGUI, saveAllLocals, currMessages, errorCount);
|
||||
findArrayRefs(funcExp->arg(z), st, fName, z, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2920,8 +2920,8 @@ static void findArrayRefs(SgExpression *ex, SgStatement *st, string fName, int p
|
||||
queue.push(findInfo("", ex->lhs(), -1, isWriteN));
|
||||
if (ex->rhs())
|
||||
queue.push(findInfo("", ex->rhs(), -1, isWriteN));
|
||||
//findArrayRefs(ex->lhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, keyValueFromGUI, saveAllLocals, currMessages, errorCount);
|
||||
//findArrayRefs(ex->rhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, keyValueFromGUI, saveAllLocals, currMessages, errorCount);
|
||||
//findArrayRefs(ex->lhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount);
|
||||
//findArrayRefs(ex->rhs(), st, "", -1, isWriteN, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO, isExecutable, currFunctionName, inRegion, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals, currMessages, errorCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3036,7 +3036,7 @@ static void addPrivates(SgStatement *st, set<string>& privates, map<string, set<
|
||||
|
||||
int getAllDeclaredArrays(SgFile *file, map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays,
|
||||
map<SgStatement*, set<tuple<int, string, string>>> &declaratedArraysSt, map<string, vector<Messages>> &currMessages,
|
||||
const vector<ParallelRegion*> ®ions, const map<string, int>& keyValueFromGUI)
|
||||
const vector<ParallelRegion*> ®ions, const map<string, int>& distrStateFromGUI)
|
||||
{
|
||||
int countErrors = 0;
|
||||
|
||||
@@ -3243,7 +3243,7 @@ int getAllDeclaredArrays(SgFile *file, map<tuple<int, string, string>, pair<DIST
|
||||
findArrayRefs(funcExp->arg(z), st, fName, z, true,
|
||||
commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO,
|
||||
isSgExecutableStatement(st) ? true : false, currFunctionName,
|
||||
regNames, funcParNames, ompThreadPrivate, keyValueFromGUI, saveAllLocals,
|
||||
regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals,
|
||||
currMessages, countErrors);
|
||||
}
|
||||
}
|
||||
@@ -3253,7 +3253,7 @@ int getAllDeclaredArrays(SgFile *file, map<tuple<int, string, string>, pair<DIST
|
||||
findArrayRefs(st->expr(i), st, "", -1, (st->variant() == ASSIGN_STAT && i == 0) ? true : false,
|
||||
commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO,
|
||||
isSgExecutableStatement(st) ? true : false, currFunctionName,
|
||||
regNames, funcParNames, ompThreadPrivate, keyValueFromGUI, saveAllLocals,
|
||||
regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, saveAllLocals,
|
||||
currMessages, countErrors);
|
||||
}
|
||||
}
|
||||
@@ -3290,7 +3290,7 @@ int getAllDeclaredArrays(SgFile *file, map<tuple<int, string, string>, pair<DIST
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
findArrayRefs(st->expr(i), st, "", -1, false, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO,
|
||||
false, "NULL", regNames, funcParNames, ompThreadPrivate, keyValueFromGUI, false,
|
||||
false, "NULL", regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, false,
|
||||
currMessages, countErrors);
|
||||
}
|
||||
st = st->lexNext();
|
||||
@@ -3328,7 +3328,7 @@ int getAllDeclaredArrays(SgFile *file, map<tuple<int, string, string>, pair<DIST
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
findArrayRefs(curr->expr(i), curr, "", -1, false, commonBlocks, declaredArrays, declaratedArraysSt, privates, deprecatedByIO,
|
||||
false, blockName, regNames, funcParNames, ompThreadPrivate, keyValueFromGUI, false,
|
||||
false, blockName, regNames, funcParNames, ompThreadPrivate, distrStateFromGUI, false,
|
||||
currMessages, countErrors);
|
||||
curr = curr->lexNext();
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ std::string getShortName(const std::tuple<int, std::string, std::string> &uniqKe
|
||||
|
||||
int getAllDeclaredArrays(SgFile *file, std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>> &declaredArrays,
|
||||
std::map<SgStatement*, std::set<std::tuple<int, std::string, std::string>>> &declaratedArraysSt, std::map<std::string, std::vector<Messages>> &currMessages,
|
||||
const std::vector<ParallelRegion*> ®ions, const std::map<std::string, int>& keyValueFromGUI);
|
||||
const std::vector<ParallelRegion*> ®ions, const std::map<std::string, int>& distrStateFromGUI);
|
||||
void insertSpfAnalysisBeforeParalleLoops(const std::vector<LoopGraph*> &loops);
|
||||
void recalculateArraySizes(std::set<DIST::Array*> &arraysDone, const std::set<DIST::Array*> &allArrays, const std::map<DIST::Array*, std::set<DIST::Array*>> &arrayLinksByFuncCalls, const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo);
|
||||
int getSizeOfType(SgType* t);
|
||||
|
||||
@@ -0,0 +1,496 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../Utils/utils.h"
|
||||
|
||||
#include "../VerificationCode/verifications.h"
|
||||
|
||||
#include "ConvertFiles.h"
|
||||
#include "calls.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern int v_print;
|
||||
extern int warn_all;
|
||||
extern int unparse_functions;
|
||||
extern int opt_base;
|
||||
extern int opt_loop_range;
|
||||
|
||||
extern graph_node* cur_node;
|
||||
extern graph_node* node_list;
|
||||
|
||||
extern "C" int out_free_form;
|
||||
extern "C" int out_upper_case;
|
||||
extern "C" int out_line_unlimit;
|
||||
extern "C" int out_line_length;
|
||||
extern "C" PTR_SYMB last_file_symbol;
|
||||
|
||||
static int convertFile(int argc, char* argv[], const string& fileToConv,
|
||||
const set<string>& filesInProj, const set<string>& moduleDeclsInFiles)
|
||||
{
|
||||
FILE* fout = NULL;
|
||||
FILE* fout_cuf = NULL, * fout_C_cu = NULL, * fout_info = NULL; /*ACC*/
|
||||
const char* fout_name = "out.DVMH.f";
|
||||
char* fout_name_cuf; /*ACC*/
|
||||
char* fout_name_C_cu; /*ACC*/
|
||||
char* fout_name_info_C; /*ACC*/
|
||||
|
||||
char* source_name;
|
||||
int level, hpf, openmp, isz, dvm_type_size;
|
||||
int a_mode = 0;
|
||||
|
||||
initialize();
|
||||
|
||||
openmp = hpf = 0; dvm_type_size = 0;
|
||||
|
||||
argv++;
|
||||
while ((argc > 1) && (*argv)[0] == '-')
|
||||
{
|
||||
if ((*argv)[1] == 'o' && ((*argv)[2] == '\0')) {
|
||||
fout_name = argv[1];
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-dc"))
|
||||
check_regim = 1;
|
||||
else if (!strcmp(argv[0], "-dbif1"))
|
||||
dbg_if_regim = 1;
|
||||
else if (!strcmp(argv[0], "-dbif2"))
|
||||
dbg_if_regim = 2;
|
||||
else if (!strcmp(argv[0], "-speedL0")) /* for dedugging ACROSS-scheme */
|
||||
options.setOn(SPEED_TEST_L0); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-speedL1")) /* for dedugging ACROSS-scheme */
|
||||
options.setOn(SPEED_TEST_L1); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-dmpi"))
|
||||
deb_mpi = 1;
|
||||
else if (!strcmp(argv[0], "-dnoind"))
|
||||
d_no_index = 1;
|
||||
else if (!strcmp(argv[0], "-dperf")) {
|
||||
debug_regim = 1;
|
||||
omp_debug = DPERF;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-dvmLoopAnalysisEC")) /*ACC*/
|
||||
{
|
||||
options.setOn(LOOP_ANALYSIS);
|
||||
options.setOn(OPT_EXP_COMP);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-dvmIrregAnalysis")) /*ACC*/
|
||||
{
|
||||
options.setOn(LOOP_ANALYSIS);
|
||||
options.setOn(OPT_EXP_COMP);
|
||||
options.setOn(GPU_IRR_ACC);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-dvmLoopAnalysis")) /*ACC*/
|
||||
options.setOn(LOOP_ANALYSIS);
|
||||
else if (!strcmp(argv[0], "-dvmPrivateAnalysis")) /*ACC*/
|
||||
options.setOn(PRIVATE_ANALYSIS);
|
||||
else if ((*argv)[1] == 'd') {
|
||||
switch ((*argv)[2]) {
|
||||
case '0': level = 0; break;
|
||||
case '1': level = 1; omp_debug = D1; /*OMP*/ break;
|
||||
case '2': level = 2; omp_debug = D2; /*OMP*/ break;
|
||||
case '3': level = 3; omp_debug = D3; /*OMP*/ break;
|
||||
case '4': level = 4; omp_debug = D4; /*OMP*/ break;
|
||||
case '5': level = 5; omp_debug = D5; /*OMP*/ break;
|
||||
/* case '5': level = -1; many_files=1; break;*/
|
||||
default: level = -1;
|
||||
}
|
||||
if (level > 0)
|
||||
debug_regim = 1;
|
||||
if ((*argv)[3] == '\0')
|
||||
AddToFragmentList(0, 0, level, -1);
|
||||
else if ((*argv)[3] == ':')
|
||||
FragmentList(*argv + 4, level, -1);
|
||||
}
|
||||
else if ((*argv)[1] == 'e') {
|
||||
switch ((*argv)[2]) {
|
||||
case '0': level = 0; break;
|
||||
case '1': level = 1; break;
|
||||
case '2': level = 2; break;
|
||||
case '3': level = 3; break;
|
||||
case '4': level = 4; break;
|
||||
case 'm': omp_perf = 1; break;
|
||||
default: level = -1;
|
||||
}
|
||||
if ((*argv)[3] == '\0')
|
||||
AddToFragmentList(0, 0, -1, level);
|
||||
else if ((*argv)[3] == ':')
|
||||
FragmentList(*argv + 4, -1, level);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-spf"))
|
||||
{
|
||||
fprintf(stderr, "Illegal option -spf \n");
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-p")) {
|
||||
only_debug = 0; hpf = 0;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-s")) {
|
||||
only_debug = 1; hpf = 0;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-v"))
|
||||
v_print = 1;
|
||||
else if (!strcmp(argv[0], "-w"))
|
||||
warn_all = 1;
|
||||
else if (!strcmp(argv[0], "-bind0"))
|
||||
bind_ = 0;
|
||||
else if (!strcmp(argv[0], "-bind1"))
|
||||
bind_ = 1;
|
||||
else if (!strcmp(argv[0], "-t8"))
|
||||
dvm_type_size = 8;
|
||||
else if (!strcmp(argv[0], "-t4"))
|
||||
dvm_type_size = 4;
|
||||
else if (!strcmp(argv[0], "-r8"))
|
||||
default_real_size = 8;
|
||||
else if (!strcmp(argv[0], "-i8"))
|
||||
default_integer_size = 8;
|
||||
else if (!strcmp(argv[0], "-hpf") || !strcmp(argv[0], "-hpf1") || !strcmp(argv[0], "-hpf2"))
|
||||
hpf = 1;
|
||||
else if (!strcmp(argv[0], "-mp")) {
|
||||
OMP_program = 1; /*OMP*/
|
||||
openmp = 1;
|
||||
}
|
||||
//else if (!strcmp(argv[0],"-ta"))
|
||||
// ACC_program = 1;
|
||||
else if (!strcmp(argv[0], "-noH"))
|
||||
ACC_program = 0;
|
||||
else if (!strcmp(argv[0], "-noCudaType")) /*ACC*/
|
||||
undefined_Tcuda = 1;
|
||||
else if (!strcmp(argv[0], "-noCuda"))
|
||||
options.setOn(NO_CUDA); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-noPureFunc"))
|
||||
options.setOn(NO_PURE_FUNC); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-C_Cuda")) /*ACC*/
|
||||
options.setOn(C_CUDA);
|
||||
else if (!strcmp(argv[0], "-FTN_Cuda") || !strcmp(argv[0], "-F_Cuda")) /*ACC*/
|
||||
options.setOff(C_CUDA);
|
||||
else if (!strcmp(argv[0], "-no_blocks_info") || !strcmp(argv[0], "-noBI"))
|
||||
options.setOn(NO_BL_INFO); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-cacheIdx"))
|
||||
options.setOff(NO_BL_INFO); /*ACC*/
|
||||
else if (!strcmp(argv[0], "-Ohost")) /*ACC*/
|
||||
options.setOn(O_HOST);
|
||||
else if (!strcmp(argv[0], "-noOhost")) /*ACC*/
|
||||
options.setOff(O_HOST);
|
||||
else if (!strcmp(argv[0], "-Opl2")) /*ACC*/
|
||||
{
|
||||
parloop_by_handler = 2;
|
||||
options.setOn(O_HOST);
|
||||
options.setOn(O_PL2);
|
||||
// options.setOn(NO_CUDA);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-Opl")) /*ACC*/
|
||||
{
|
||||
parloop_by_handler = 1;
|
||||
options.setOn(O_PL);
|
||||
}
|
||||
else if (!strcmp(argv[0], "-oneThread")) /*ACC*/
|
||||
options.setOn(ONE_THREAD);
|
||||
else if (!strcmp(argv[0], "-noTfm")) /*ACC*/
|
||||
options.setOff(AUTO_TFM);
|
||||
else if (!strcmp(argv[0], "-autoTfm")) /*ACC*/
|
||||
options.setOn(AUTO_TFM);
|
||||
else if (!strcmp(argv[0], "-gpuO0")) /*ACC*/
|
||||
options.setOn(GPU_O0);
|
||||
else if (!strcmp(argv[0], "-gpuO1")) /*ACC*/
|
||||
options.setOn(GPU_O1);
|
||||
else if (!strcmp(argv[0], "-rtc")) /*ACC*/
|
||||
options.setOn(RTC); //for NVRTC compilation and execution
|
||||
else if (!strcmp(argv[0], "-ffo"))
|
||||
out_free_form = 1;
|
||||
else if (!strcmp(argv[0], "-upcase"))
|
||||
out_upper_case = 1;
|
||||
else if (!strcmp(argv[0], "-noLimitLine"))
|
||||
out_line_unlimit = 1;
|
||||
else if (!strcmp(argv[0], "-uniForm"))
|
||||
{
|
||||
out_free_form = 1;
|
||||
out_line_length = 72;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-noRemote"))
|
||||
options.setOn(NO_REMOTE);
|
||||
else if (!strcmp(argv[0], "-lgstd"))
|
||||
{
|
||||
(void)fprintf(stderr, "Illegal option -lgstd \n");
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-byFunUnparse"))
|
||||
unparse_functions = 1;
|
||||
else if (!strncmp(argv[0], "-bufio", 6)) {
|
||||
if ((*argv)[6] != '\0' && (isz = is_integer_value(*argv + 6)))
|
||||
IOBufSize = isz;
|
||||
}
|
||||
else if (!strncmp(argv[0], "-bufUnparser", 12)) {
|
||||
if ((*argv)[12] != '\0' && (isz = is_integer_value(*argv + 12)))
|
||||
UnparserBufSize = isz * 1024 * 1024;
|
||||
}
|
||||
else if (!strcmp(argv[0], "-ioRTS"))
|
||||
options.setOn(IO_RTS);
|
||||
else if (!strcmp(argv[0], "-read_all"))
|
||||
options.setOn(READ_ALL);
|
||||
else if (!strcmp(argv[0], "-Obase"))
|
||||
opt_base = 1;
|
||||
else if (!strcmp(argv[0], "-Oloop_range"))
|
||||
opt_loop_range = 1;
|
||||
else if ((*argv)[1] == 'H') {
|
||||
if ((*argv)[2] == 's' && (*argv)[3] == 'h' && (*argv)[4] == 'w') {
|
||||
if ((*argv)[5] != '\0' && (all_sh_width = is_integer_value(*argv + 5)))
|
||||
;
|
||||
}
|
||||
else if (!strcmp(*argv + 2, "nora"))
|
||||
no_rma = 1;
|
||||
else if (!strcmp(*argv + 2, "oneq"))
|
||||
one_inquiry = 1;
|
||||
else if (!strcmp(*argv + 2, "onlyl"))
|
||||
only_local = 1;
|
||||
}
|
||||
else if (!strncmp(argv[0], "-collapse", 9))
|
||||
if ((*argv)[9] != '\0' && (collapse_loop_count = is_integer_value(*argv + 9)));
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
// Check options combinations
|
||||
options.checkCombinations();
|
||||
|
||||
// definition of DvmType size: len_DvmType
|
||||
// len_DvmType==0, if DvmType-size == default_integer_size == 4
|
||||
if (bind_ == 1)
|
||||
len_DvmType = 8; //sizeof(long) == 8
|
||||
if (dvm_type_size)
|
||||
len_DvmType = dvm_type_size;
|
||||
if (len_DvmType == 0 && default_integer_size == 8)
|
||||
len_DvmType = 4;
|
||||
|
||||
if (ACC_program && debug_regim && !only_debug)
|
||||
{
|
||||
fprintf(stderr, "Warning: -noH option is set to debug mode\n");
|
||||
ACC_program = 0;
|
||||
}
|
||||
if (parloop_by_handler > 0 && debug_regim)
|
||||
{
|
||||
fprintf(stderr, "Warning: -Opl/Opl2 option is ignored in debug mode\n");
|
||||
parloop_by_handler = 0;
|
||||
options.setOff(O_PL);
|
||||
options.setOff(O_PL2);
|
||||
}
|
||||
|
||||
if (openmp && ACC_program)
|
||||
{
|
||||
fprintf(stderr, "Warning: -noH option is set to -mp mode\n");
|
||||
ACC_program = 0;
|
||||
}
|
||||
if (parloop_by_handler == 2 && !options.isOn(O_HOST))
|
||||
{
|
||||
fprintf(stderr, "Warning: -Ohost option is set to -Opl2 mode\n");
|
||||
options.setOn(O_HOST);
|
||||
}
|
||||
if (out_free_form == 1 && out_line_length == 72 && out_line_unlimit == 1)
|
||||
{
|
||||
fprintf(stderr, "Warning: -noLimitLine and -uniForm options are incompatible; -noLimitLine option is ignored\n");
|
||||
out_line_unlimit = 0;
|
||||
}
|
||||
|
||||
if (v_print)
|
||||
(void)fprintf(stderr, "<<<<< Translating >>>>>\n");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
string proj_name = "fdvm__";
|
||||
static int id = 0;
|
||||
|
||||
vector<char*> filesList;
|
||||
filesList.push_back((char*)fileToConv.c_str());
|
||||
|
||||
SgProject project((proj_name + to_string(id++)).c_str(), filesList.data(), filesList.size());
|
||||
|
||||
shiftLines(&project, false);
|
||||
for (int z = 0; z < project.numberOfFiles(); ++z) {
|
||||
vector<SgStatement*> tmp;
|
||||
removeExecutableFromModuleDeclaration(&(project.file(z)), filesInProj, tmp);
|
||||
}
|
||||
|
||||
SgFile* file;
|
||||
addNumberOfFileToAttribute(&project);
|
||||
|
||||
//----------------------------
|
||||
ProjectStructure(project);
|
||||
Private_Vars_Project_Analyzer();
|
||||
//----------------------------
|
||||
|
||||
initVariantNames(); //for project
|
||||
initIntrinsicFunctionNames(); //for project
|
||||
initSupportedVars(); // for project, acc_f2c.cpp
|
||||
initF2C_FunctionCalls(); // for project, acc_f2c.cpp
|
||||
for (int id = project.numberOfFiles() - 1; id >= 0; id--)
|
||||
{
|
||||
file = &(project.file(id)); //file->unparsestdout();
|
||||
fin_name = new char[strlen(project.fileName(id)) + 2];
|
||||
sprintf(fin_name, "%s%s", project.fileName(id), " ");
|
||||
fout_name = doOutFileName(file->filename()); //project.fileName(id);
|
||||
|
||||
if (fout_name && source_name && !strcmp(source_name, fout_name))
|
||||
{
|
||||
fprintf(stderr, "Output file has the same name as source file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fout_name_cuf = ChangeFtoCuf(fout_name); /*ACC*/
|
||||
fout_name_C_cu = ChangeFto_C_Cu(fout_name); /*ACC*/
|
||||
fout_name_info_C = ChangeFto_info_C(fout_name); /*ACC*/
|
||||
|
||||
//set the last symbol of file
|
||||
last_file_symbol = CUR_FILE_CUR_SYMB();
|
||||
initLibNames(); //for every file
|
||||
InitDVM(file); //for every file
|
||||
current_file = file; // global variable (used in SgTypeComplex)
|
||||
max_lab = getLastLabelId();
|
||||
|
||||
if (dbg_if_regim)
|
||||
GetLabel();
|
||||
|
||||
TranslateFileDVM(file);
|
||||
|
||||
if (err_cnt) {
|
||||
fprintf(stderr, "%d error(s)\n", err_cnt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!fout_name) {
|
||||
file->unparsestdout();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//writing result of converting into file
|
||||
if ((fout = fopen(fout_name, "w")) == NULL) {
|
||||
fprintf(stderr, "Can't open file %s for write\n", fout_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GeneratedForCuda()) /*ACC*/
|
||||
{
|
||||
if ((fout_C_cu = fopen(fout_name_C_cu, "w")) == NULL) {
|
||||
fprintf(stderr, "Can't open file %s for write\n", fout_name_C_cu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!options.isOn(C_CUDA)) {
|
||||
if ((fout_cuf = fopen(fout_name_cuf, "w")) == NULL) {
|
||||
fprintf(stderr, "Can't open file %s for write\n", fout_name_cuf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fout_info = fopen(fout_name_info_C, "w")) == NULL) {
|
||||
fprintf(stderr, "Can't open file %s for write\n", fout_name_info_C);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (v_print)
|
||||
fprintf(stderr, "<<<<< Unparsing %s >>>>>\n", fout_name);
|
||||
|
||||
if (mod_gpu) /*ACC*/
|
||||
UnparseTo_CufAndCu_Files(file, fout_cuf, fout_C_cu, fout_info);
|
||||
|
||||
const string fileN = file->filename();
|
||||
hideUnnecessary(file, fileN, moduleDeclsInFiles, true);
|
||||
|
||||
if (unparse_functions)
|
||||
UnparseFunctionsOfFile(file, fout);
|
||||
else if (UnparserBufSize)
|
||||
file->unparseS(fout, UnparserBufSize);
|
||||
else
|
||||
file->unparse(fout);
|
||||
|
||||
if ((fclose(fout)) < 0) {
|
||||
fprintf(stderr, "Could not close %s\n", fout_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GeneratedForCuda()) {
|
||||
if ((fclose(fout_C_cu)) < 0) {
|
||||
fprintf(stderr, "Could not close %s\n", fout_name_C_cu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!options.isOn(C_CUDA)) {
|
||||
if ((fclose(fout_cuf)) < 0) {
|
||||
fprintf(stderr, "Could not close %s\n", fout_name_cuf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fclose(fout_info)) < 0) {
|
||||
fprintf(stderr, "Could not close %s\n", fout_name_info_C);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (v_print)
|
||||
fprintf(stderr, "\n***** Done *****\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void preprocess(const vector<string>& files, map<string, set<string>>& moduleUsesByFile, map<string, string>& moduleDecls)
|
||||
{
|
||||
vector<char*> filesList;
|
||||
for (int z = 0; z < files.size(); ++z)
|
||||
filesList.push_back((char*)files[z].c_str());
|
||||
|
||||
SgProject tmpProj("preproc", filesList.data(), files.size());
|
||||
|
||||
for (int z = 0; z < tmpProj.numberOfFiles(); ++z)
|
||||
{
|
||||
SgFile* file = &(tmpProj.file(z));
|
||||
fillModuleUse(file, moduleUsesByFile, moduleDecls);
|
||||
}
|
||||
|
||||
InitializeTable();
|
||||
}
|
||||
|
||||
void convertFiles(int argc, char* argv[], const char* proj_name)
|
||||
{
|
||||
vector<char*> args_v;
|
||||
for (int z = 0; z < argc; ++z)
|
||||
args_v.push_back(argv[z]);
|
||||
|
||||
const string fileText = readFileToStr(proj_name);
|
||||
vector<string> files;
|
||||
set<string> filesinSet;
|
||||
splitString(fileText, '\n', files);
|
||||
|
||||
for (auto& file : files)
|
||||
filesinSet.insert(file);
|
||||
|
||||
map<string, set<string>> moduleUsesByFile;
|
||||
map<string, string> moduleDecls;
|
||||
set<string> moduleDeclsInFiles;
|
||||
|
||||
preprocess(files, moduleUsesByFile, moduleDecls);
|
||||
for (auto& elem : moduleDecls)
|
||||
moduleDeclsInFiles.insert(elem.second);
|
||||
|
||||
int codes = 0;
|
||||
for (auto& file : files)
|
||||
{
|
||||
codes += convertFile(args_v.size() - 1, args_v.data(), file, filesinSet, moduleDeclsInFiles);
|
||||
|
||||
cur_node = node_list = NULL;
|
||||
InitializeTable();
|
||||
}
|
||||
|
||||
if (codes == 0)
|
||||
printf("Convertation was completed successfully\n");
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void convertFiles(int argc, char* argv[], const char* proj_name = "dvm.proj");
|
||||
105
sapfor/experts/Sapfor_2017/_src/ProjectManipulation/FileInfo.cpp
Normal file
105
sapfor/experts/Sapfor_2017/_src/ProjectManipulation/FileInfo.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "FileInfo.h"
|
||||
#include "../Utils/utils.h"
|
||||
#include "../Utils/errors.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static int tmp_id = 0;
|
||||
static string tmp_name = "tmp_conv_";
|
||||
|
||||
extern "C" int out_free_form;
|
||||
extern "C" int out_line_length;
|
||||
|
||||
//convert through unparce
|
||||
void FileInfo::convertToUniform()
|
||||
{
|
||||
int old_free = out_free_form;
|
||||
int old_line = out_line_length;
|
||||
|
||||
out_free_form = 1;
|
||||
out_line_length = 72;
|
||||
|
||||
__spf_print(1, "covnert to uniform %s file\n", fileName.c_str());
|
||||
|
||||
if (error != 0)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
if (outDepPath == "")
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
vector<char*> filesList;
|
||||
filesList.push_back((char*)outDepPath.c_str());
|
||||
|
||||
const string name = tmp_name + to_string(tmp_id++);
|
||||
SgProject* tmpProj = new SgProject(name.c_str(), filesList.data(), 1);
|
||||
|
||||
if (tmpProj == NULL)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
SgFile* currF = &tmpProj->file(0);
|
||||
|
||||
string text = string(currF->firstStatement()->unparse());
|
||||
writeFileFromStr(fileName, text);
|
||||
|
||||
out_free_form = old_free;
|
||||
out_line_length = old_line;
|
||||
|
||||
InitializeTable();
|
||||
}
|
||||
|
||||
string FileInfo::convertStyle(bool needRewrite)
|
||||
{
|
||||
string tmp_text = text;
|
||||
|
||||
vector<string> splited;
|
||||
splitString(tmp_text, '\n', splited);
|
||||
|
||||
tmp_text = "";
|
||||
int z = 0;
|
||||
for (auto& line : splited)
|
||||
{
|
||||
if (line[0] == 'c' || line[0] == 'C' || line[0] == 'd' || line[0] == 'D' || line[0] == '*')
|
||||
line[0] = '!';
|
||||
|
||||
bool needContinuation = false;
|
||||
if (line[0] != '!' && line.size() > 6)
|
||||
{
|
||||
if (line[5] != ' ' && !(line[5] > '0' && line[5] < '9')) // not label
|
||||
{
|
||||
line[5] = ' ';
|
||||
needContinuation = true;// line[5] = '&';
|
||||
}
|
||||
|
||||
int p = 73;
|
||||
if (style == 1)
|
||||
p = 133;
|
||||
if (line.size() > p)
|
||||
{
|
||||
while (line[p] != '\0' && line[p] != '\n' && line[p] != '!')
|
||||
{
|
||||
line[p] = ' ';
|
||||
p++;
|
||||
if (p >= line.size())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needContinuation)
|
||||
tmp_text += "&";
|
||||
tmp_text += (z != 0 ? "\n" : "") + line;
|
||||
++z;
|
||||
}
|
||||
|
||||
if (needRewrite)
|
||||
writeFileFromStr(fileName, tmp_text);
|
||||
|
||||
return tmp_text;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
struct FileInfo
|
||||
{
|
||||
FileInfo()
|
||||
{
|
||||
fileName = "";
|
||||
options = "";
|
||||
errPath = "";
|
||||
outPath = "";
|
||||
outDepPath = "";
|
||||
text = "";
|
||||
error = -1;
|
||||
includesAdded = 0;
|
||||
style = -1;
|
||||
lvl = 0;
|
||||
}
|
||||
|
||||
FileInfo(const std::string& _fileName, const std::string& _options, const std::string& _errPath, const std::string& _outPath,
|
||||
const std::string& _outDepPath, const std::string& _text, int errorInit = -1)
|
||||
{
|
||||
fileName = _fileName;
|
||||
options = _options;
|
||||
errPath = _errPath;
|
||||
outPath = _outPath;
|
||||
outDepPath = _outDepPath;
|
||||
text = _text;
|
||||
error = errorInit;
|
||||
includesAdded = 0;
|
||||
style = -1;
|
||||
lvl = 0;
|
||||
}
|
||||
|
||||
int error;
|
||||
std::string fileName;
|
||||
std::string options;
|
||||
std::string errPath;
|
||||
std::string outPath;
|
||||
std::string outDepPath;
|
||||
std::string text;
|
||||
int style; // -1 unk, 0 fixed, 1 fixed ext, 2 free, 3 uniform
|
||||
int includesAdded;
|
||||
std::set<std::string> includes;
|
||||
int lvl;
|
||||
|
||||
std::string convertStyle(bool needRewrite = true);
|
||||
void convertToUniform();
|
||||
};
|
||||
@@ -0,0 +1,793 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
#include <locale>
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include <stack>
|
||||
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../VisualizerCalls/get_information.h"
|
||||
#include "../VisualizerCalls/SendMessage.h"
|
||||
|
||||
#include "ParseFiles.h"
|
||||
#include "StdCapture.h"
|
||||
#include "FileInfo.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" int parse_file(int argc, char* argv[], char* proj_name);
|
||||
|
||||
static void findModuleDeclInProject(const string& name, const vector<string>& files, map<string, string>& modDecls)
|
||||
{
|
||||
vector<char*> filesList;
|
||||
for (int z = 0; z < files.size(); ++z)
|
||||
filesList.push_back((char*)files[z].c_str());
|
||||
|
||||
SgProject* tmpProj = new SgProject(name.c_str(), filesList.data(), files.size());
|
||||
|
||||
int numF = tmpProj->numberOfFiles();
|
||||
for (int z = 0; z < numF; ++z)
|
||||
{
|
||||
vector<SgStatement*> modules;
|
||||
SgFile* currF = &tmpProj->file(z);
|
||||
string fileName = currF->filename();
|
||||
convertToLower(fileName);
|
||||
|
||||
findModulesInFile(currF, modules);
|
||||
for (auto& elem : modules)
|
||||
{
|
||||
if (string(elem->fileName()) == currF->filename())
|
||||
{
|
||||
const string name = elem->symbol()->identifier();
|
||||
auto it = modDecls.find(name);
|
||||
if (it != modDecls.end() && it->second != currF->filename())
|
||||
{
|
||||
__spf_print(1, "found several module declaration of '%s' in files '%s' and '%s'\n", name.c_str(), it->second.c_str(), currF->filename());
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
else
|
||||
modDecls.insert(it, make_pair(name, currF->filename()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InitializeTable();
|
||||
}
|
||||
|
||||
static void createIncludeOrder(vector<string> &toIncl,
|
||||
const map<string, string>& moduleDelc,
|
||||
const map<string, set<string>>& modDirectOrder,
|
||||
set<string> &done,
|
||||
const string &curr)
|
||||
{
|
||||
if (done.find(curr) == done.end())
|
||||
{
|
||||
for (auto& elem : modDirectOrder.find(curr)->second)
|
||||
createIncludeOrder(toIncl, moduleDelc, modDirectOrder, done, elem);
|
||||
|
||||
if (done.find(curr) == done.end())
|
||||
{
|
||||
toIncl.push_back(moduleDelc.find(curr)->second);
|
||||
done.insert(curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static set<FileInfo*> applyModuleDeclsForFile(FileInfo *forFile, const map<string, FileInfo*> &mapFiles,
|
||||
const map<string, string>& moduleDelc,
|
||||
const map<string, set<string>>& mapModuleDeps,
|
||||
const map<string, set<string>>& modDirectOrder,
|
||||
vector<string> &optSplited,
|
||||
bool includeForInline = false)
|
||||
{
|
||||
set<FileInfo*> retFilesMod;
|
||||
|
||||
auto itF = mapModuleDeps.find(forFile->fileName);
|
||||
if (itF == mapModuleDeps.end() && !includeForInline)
|
||||
return retFilesMod;
|
||||
|
||||
vector<string> toIncl;
|
||||
set<string> done;
|
||||
if (itF != mapModuleDeps.end())
|
||||
{
|
||||
for (auto& mod : itF->second)
|
||||
if (moduleDelc.find(mod) != moduleDelc.end())
|
||||
createIncludeOrder(toIncl, moduleDelc, modDirectOrder, done, mod);
|
||||
}
|
||||
|
||||
//rewrite files to the next iter of parse
|
||||
set<FileInfo*> allFiles;
|
||||
for (auto& incl : toIncl)
|
||||
{
|
||||
if (mapFiles.find(incl) == mapFiles.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
allFiles.insert(mapFiles.find(incl)->second);
|
||||
}
|
||||
allFiles.insert(forFile);
|
||||
|
||||
set<FileInfo*> toConvert;
|
||||
int mainStyle = forFile->style;
|
||||
for (auto& file : allFiles)
|
||||
if (mainStyle != file->style && file->style != 3)
|
||||
toConvert.insert(file);
|
||||
|
||||
const string mainText = forFile->text;
|
||||
for (auto& file : toConvert)
|
||||
file->convertToUniform();
|
||||
|
||||
string include = "";
|
||||
int includeCount = 0;
|
||||
set<string> included;
|
||||
for (auto& incl : toIncl)
|
||||
{
|
||||
if (included.find(incl) == included.end())
|
||||
{
|
||||
include += " include '" + incl + "'\n";
|
||||
includeCount++;
|
||||
}
|
||||
included.insert(incl);
|
||||
}
|
||||
|
||||
vector<string> toInclEnds;
|
||||
string includeLast = "";
|
||||
|
||||
if (includeForInline)
|
||||
{
|
||||
//find needed modules first
|
||||
vector<string> filesWithModules;
|
||||
for (auto& elem : moduleDelc)
|
||||
filesWithModules.push_back(elem.second);
|
||||
for (auto& file : filesWithModules)
|
||||
{
|
||||
if (file != forFile->fileName && included.find(file) == included.end())
|
||||
{
|
||||
toInclEnds.push_back(file);
|
||||
included.insert(file);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& file : mapFiles)
|
||||
if (file.second != forFile && included.find(file.second->fileName) == included.end())
|
||||
toInclEnds.push_back(file.second->fileName);
|
||||
|
||||
if (toInclEnds.size())
|
||||
includeLast += "!SPF SHADOW FILES\n";
|
||||
|
||||
for (auto& incl : toInclEnds)
|
||||
includeLast += " include '" + incl + "'\n";
|
||||
}
|
||||
|
||||
if (includeCount)
|
||||
include = "!SPF NUM FILES " + std::to_string(includeCount) + "\n" + include;
|
||||
|
||||
const string data = include + mainText + includeLast;
|
||||
__spf_print(1, "include to file %s before\n", forFile->fileName.c_str());
|
||||
__spf_print(1, "%s", include.c_str());
|
||||
__spf_print(1, "include to file %s after\n", forFile->fileName.c_str());
|
||||
__spf_print(1, "%s", includeLast.c_str());
|
||||
|
||||
writeFileFromStr(forFile->fileName, data);
|
||||
|
||||
/*static string tmp = "tmp__";
|
||||
static int id = 0;
|
||||
writeFileFromStr(tmp + to_string(id++) + ".ftn", data);*/
|
||||
|
||||
forFile->includesAdded = included.size();
|
||||
forFile->includes = included;
|
||||
|
||||
retFilesMod.insert(forFile);
|
||||
return retFilesMod;
|
||||
}
|
||||
|
||||
static void restoreOriginalText(const vector<FileInfo>& listOfProject)
|
||||
{
|
||||
for (auto& elem : listOfProject)
|
||||
writeFileFromStr(elem.fileName, elem.text);
|
||||
fflush(NULL);
|
||||
}
|
||||
|
||||
static inline void restoreOriginalText(const FileInfo& file)
|
||||
{
|
||||
writeFileFromStr(file.fileName, file.text);
|
||||
}
|
||||
|
||||
static void checkRetCode(FileInfo& info, const string& errorMessage)
|
||||
{
|
||||
if (info.error != 0)
|
||||
info.lvl++;
|
||||
|
||||
if (errorMessage.find("Warning 308") != string::npos)
|
||||
if (info.error == 0)
|
||||
info.error = 1;
|
||||
}
|
||||
|
||||
static vector<string> parseList(vector<FileInfo>& listOfProject,
|
||||
bool needToInclude, bool needToIncludeForInline,
|
||||
const map<string, set<string>> &mapModuleDeps,
|
||||
const map<string, string> &moduleDelc,
|
||||
const map<string, set<string>> &modDirectOrder, bool isFromConsole = false)
|
||||
{
|
||||
map<string, FileInfo*> mapFiles;
|
||||
for (auto& elem : listOfProject)
|
||||
mapFiles[elem.fileName] = &elem;
|
||||
|
||||
vector<string> errors;
|
||||
int i = 1;
|
||||
int N = listOfProject.size();
|
||||
for (auto& elem : listOfProject)
|
||||
{
|
||||
sendMessage_progress(std::to_wstring((int)(((double)(i++) / N) * 100)));
|
||||
|
||||
string file = elem.fileName;
|
||||
string options = elem.options;
|
||||
vector<string> optSplited = splitAndArgvCreate(options);
|
||||
|
||||
char** toParse = new char* [optSplited.size() + 1];
|
||||
for (int z = 0; z < optSplited.size(); ++z)
|
||||
{
|
||||
toParse[z] = new char[optSplited[z].size() + 1];
|
||||
strcpy(toParse[z], optSplited[z].c_str());
|
||||
}
|
||||
toParse[optSplited.size()] = new char[file.size() + 1];
|
||||
strcpy(toParse[optSplited.size()], file.c_str());
|
||||
|
||||
if (options.find("-FI") != string::npos)
|
||||
elem.style = 0;
|
||||
else if (options.find("-extend_source") != string::npos)
|
||||
elem.style = 1;
|
||||
else if (options.find("-FR") != string::npos || options.find("-f90") != string::npos)
|
||||
elem.style = 2;
|
||||
else
|
||||
{ //fdv|f|ftn|for|f90|f95|f03
|
||||
static set<string> fixed_exts = { "for", "f", "ftn" };
|
||||
static set<string> free_exts = { "f90", "f95", "f03" };
|
||||
string ext = OnlyExt(file.c_str());
|
||||
|
||||
if (fixed_exts.find(ext) != fixed_exts.end())
|
||||
elem.style = 0;
|
||||
else if (free_exts.find(ext) != free_exts.end())
|
||||
elem.style = 2;
|
||||
}
|
||||
|
||||
for (int z = 0; z < optSplited.size(); ++z)
|
||||
{
|
||||
if (optSplited[z] == "-o")
|
||||
{
|
||||
if (z + 1 == optSplited.size())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
elem.outDepPath = optSplited[z + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FILE* depPath = fopen(elem.outDepPath.c_str(), "r");
|
||||
if (depPath && !isFromConsole && !needToIncludeForInline)
|
||||
{
|
||||
fclose(depPath);
|
||||
if (elem.error <= 0)
|
||||
{
|
||||
elem.error = 0;
|
||||
errors.push_back("");
|
||||
for (int z = 0; z <= optSplited.size(); ++z)
|
||||
delete toParse[z];
|
||||
delete[] toParse;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
StdCapture::Init();
|
||||
string errorMessage = "";
|
||||
try
|
||||
{
|
||||
set<FileInfo*> filesModified;
|
||||
StdCapture::BeginCapture();
|
||||
if (needToInclude)
|
||||
filesModified = applyModuleDeclsForFile(&elem, mapFiles, moduleDelc, mapModuleDeps, modDirectOrder, optSplited, needToIncludeForInline);
|
||||
else if (needToIncludeForInline)
|
||||
filesModified = applyModuleDeclsForFile(&elem, mapFiles, moduleDelc, mapModuleDeps, modDirectOrder, optSplited, needToIncludeForInline);
|
||||
|
||||
int retCode = parse_file(optSplited.size(), toParse, "dvm.proj");
|
||||
if (needToInclude || needToIncludeForInline)
|
||||
{
|
||||
for (auto &elem : filesModified)
|
||||
restoreOriginalText(*elem);
|
||||
fflush(NULL);
|
||||
}
|
||||
|
||||
elem.error = retCode;
|
||||
StdCapture::EndCapture();
|
||||
errorMessage = StdCapture::GetCapture();
|
||||
checkRetCode(elem, errorMessage);
|
||||
}
|
||||
catch (int err)
|
||||
{
|
||||
StdCapture::EndCapture();
|
||||
errorMessage = StdCapture::GetCapture();
|
||||
|
||||
if (needToInclude || needToIncludeForInline)
|
||||
restoreOriginalText(listOfProject);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StdCapture::EndCapture();
|
||||
errorMessage = StdCapture::GetCapture();
|
||||
|
||||
if (needToInclude || needToIncludeForInline)
|
||||
restoreOriginalText(listOfProject);
|
||||
}
|
||||
errors.push_back(errorMessage);
|
||||
for (int z = 0; z <= optSplited.size(); ++z)
|
||||
delete toParse[z];
|
||||
delete[] toParse;
|
||||
|
||||
createNeededException();
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
static string shiftLines(const string &in, const map<string, const FileInfo*> &mapOfFiles, const FileInfo* currF)
|
||||
{
|
||||
int byNum = 0;
|
||||
|
||||
auto it = in.find("on line ");
|
||||
if (it != string::npos)
|
||||
it += strlen("on line ");
|
||||
|
||||
int d = 0;
|
||||
sscanf(in.c_str() + it, "%d", &d);
|
||||
|
||||
auto it1 = in.find("of", it + 1);
|
||||
if (it1 == string::npos)
|
||||
return in;
|
||||
it1 += 3;
|
||||
|
||||
string fileN = in.substr(it1, in.find(':', it1) - it1);
|
||||
auto itF = mapOfFiles.find(fileN);
|
||||
if (itF == mapOfFiles.end())
|
||||
return in;
|
||||
if (itF->second != currF)
|
||||
return in;
|
||||
|
||||
byNum = itF->second->includesAdded;
|
||||
if (byNum == 0)
|
||||
return in;
|
||||
|
||||
if (d - byNum <= 0)
|
||||
{
|
||||
//return in;
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
else
|
||||
d -= byNum;
|
||||
|
||||
string newStr = in.substr(0, it) + std::to_string(d) + in.substr(in.find(' ', it + 1));
|
||||
return newStr;
|
||||
}
|
||||
|
||||
static int dumpErrors(const vector<FileInfo>& listOfProject, const vector<string>& errors)
|
||||
{
|
||||
int errorsCount = 0;
|
||||
map<string, const FileInfo*> mapOfFiles;
|
||||
for (auto& elem : listOfProject)
|
||||
mapOfFiles[elem.fileName] = &elem;
|
||||
|
||||
int z = 0;
|
||||
for (auto& file : listOfProject)
|
||||
{
|
||||
if (errors[z] == "")
|
||||
{
|
||||
FILE* ferr = fopen(file.errPath.c_str(), "w");
|
||||
if (!ferr)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
fclose(ferr);
|
||||
++z;
|
||||
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 = "";
|
||||
vector<string> splited;
|
||||
splitString(errors[z], '\n', splited);
|
||||
for (auto& elem : splited)
|
||||
{
|
||||
if (elem.find("Warning 308") != string::npos)
|
||||
outS += shiftLines(elem, mapOfFiles, &file) + "\n";
|
||||
else if (elem.find("Error") != string::npos)
|
||||
{
|
||||
errS += shiftLines(elem, mapOfFiles, &file) + "\n";
|
||||
errorsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fout, "%s", outS.c_str());
|
||||
fprintf(ferr, "%s", errS.c_str());
|
||||
|
||||
fflush(NULL);
|
||||
|
||||
fclose(fout);
|
||||
fclose(ferr);
|
||||
++z;
|
||||
}
|
||||
|
||||
return errorsCount;
|
||||
}
|
||||
|
||||
static int createMapOfUse(const vector<string>& errors, const vector<FileInfo>& listOfProject, map<string, set<string>> &mapModuleDeps)
|
||||
{
|
||||
int changed = 0;
|
||||
for (int z = 0; z < listOfProject.size(); ++z)
|
||||
{
|
||||
if (listOfProject[z].error >= 0)
|
||||
{
|
||||
vector<string> splited;
|
||||
splitString(errors[z], '\n', splited);
|
||||
for (auto& err : splited)
|
||||
{
|
||||
if (err.find("Warning 308") != string::npos && err.find(listOfProject[z].fileName) != string::npos)
|
||||
{
|
||||
auto pos = err.find("Unknown module");
|
||||
if (pos != string::npos)
|
||||
{
|
||||
pos += strlen("Unknown module") + 1;
|
||||
string substr = "";
|
||||
while (err[pos] != ' ' && pos != err.size())
|
||||
substr += err[pos++];
|
||||
mapModuleDeps[listOfProject[z].fileName].insert(substr);
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static map<string, set<string>> createModuleOrder(const map<string, string> &moduleDelc, const map<string, set<string>> &mapModuleDeps)
|
||||
{
|
||||
map<string, set<string>> modDirectOrder;
|
||||
for (auto& elem : moduleDelc)
|
||||
modDirectOrder[elem.first] = set<string>();
|
||||
|
||||
for (auto& elem : moduleDelc)
|
||||
{
|
||||
auto itF = mapModuleDeps.find(elem.second);
|
||||
if (itF != mapModuleDeps.end())
|
||||
{
|
||||
for (auto& inFile : itF->second)
|
||||
{
|
||||
if (moduleDelc.find(inFile) != moduleDelc.end())
|
||||
modDirectOrder[elem.first].insert(inFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modDirectOrder;
|
||||
}
|
||||
|
||||
static void printDebug(const map<string, set<string>>& mapModuleDeps, const map<string, set<string>>& modDirectOrder,
|
||||
const vector<FileInfo>& listOfProject, bool console = false)
|
||||
{
|
||||
string toPrint = "MODULE DEPS:\n";
|
||||
for (auto& elem : mapModuleDeps)
|
||||
{
|
||||
toPrint += elem.first + '\n';
|
||||
for (auto& setEl : elem.second)
|
||||
toPrint += " " + setEl + '\n';
|
||||
}
|
||||
toPrint += "MODULE DIRECT ORDER:\n";
|
||||
for (auto& elem : modDirectOrder)
|
||||
{
|
||||
toPrint += elem.first + '\n';
|
||||
for (auto& setEl : elem.second)
|
||||
toPrint += " " + setEl + '\n';
|
||||
}
|
||||
toPrint += "FILES LVL:\n";
|
||||
for (auto& elem : listOfProject)
|
||||
toPrint += elem.fileName + " " + elem.outDepPath + " lvl = " + std::to_string(elem.lvl) + '\n';
|
||||
if (console)
|
||||
printf("%s\n", toPrint.c_str());
|
||||
__spf_print(1, "%s\n", toPrint.c_str());
|
||||
}
|
||||
|
||||
static void parseFiles(int& iters, vector<string>& errors, vector<FileInfo>& listOfProject,
|
||||
map<string, set<string>>& mapModuleDeps, map<string, string>& moduleDelc, map<string, set<string>>& modDirectOrder,
|
||||
int parseForInlining, bool isFromConsole)
|
||||
{
|
||||
int changed = 0;
|
||||
int lastChanged = 0;
|
||||
const string projName = (parseForInlining == 0) ? "tmp" : "tmp_inl";
|
||||
|
||||
do
|
||||
{
|
||||
#ifdef _WIN32
|
||||
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);
|
||||
changed = createMapOfUse(errors, listOfProject, mapModuleDeps);
|
||||
if (iters != 0)
|
||||
if (lastChanged <= changed)
|
||||
break;
|
||||
|
||||
createNeededException();
|
||||
|
||||
if (changed)
|
||||
{
|
||||
vector<string> files;
|
||||
for (auto& elem : listOfProject)
|
||||
if (elem.error == 0)
|
||||
files.push_back(elem.outDepPath);
|
||||
if (files.size() == 0)
|
||||
break;
|
||||
findModuleDeclInProject(projName + std::to_string(iters++), files, moduleDelc);
|
||||
modDirectOrder = createModuleOrder(moduleDelc, mapModuleDeps);
|
||||
}
|
||||
lastChanged = changed;
|
||||
//printDebug(mapModuleDeps, modDirectOrder, listOfProject);
|
||||
} while (changed);
|
||||
}
|
||||
|
||||
static vector<string> finalyzeParsing(const vector<FileInfo>& listOfProject,
|
||||
const map<string, set<string>> mapModuleDeps,
|
||||
const map<string, string> moduleDelc)
|
||||
{
|
||||
vector<string> filesCompilationOrder;
|
||||
int added = 0;
|
||||
int iter = 0;
|
||||
vector<string> files;
|
||||
|
||||
while (added != listOfProject.size())
|
||||
{
|
||||
for (auto& elem : listOfProject)
|
||||
{
|
||||
if (elem.lvl == iter)
|
||||
{
|
||||
files.push_back(elem.fileName);
|
||||
added++;
|
||||
}
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
map<string, set<string>> fileDeps;
|
||||
for (auto& file : files)
|
||||
{
|
||||
fileDeps[file] = set<string>();
|
||||
if (mapModuleDeps.find(file) == mapModuleDeps.end())
|
||||
continue;
|
||||
|
||||
for (auto& dep : mapModuleDeps.at(file))
|
||||
{
|
||||
if (moduleDelc.find(dep) == moduleDelc.end())
|
||||
continue;
|
||||
fileDeps[file].insert(moduleDelc.at(dep));
|
||||
}
|
||||
}
|
||||
|
||||
set<string> addedFiles;
|
||||
|
||||
added = 0;
|
||||
while (added != fileDeps.size())
|
||||
{
|
||||
for (auto& file : fileDeps)
|
||||
{
|
||||
bool depsAdded = true;
|
||||
for (auto& dep : file.second)
|
||||
if (addedFiles.find(dep) == addedFiles.end())
|
||||
depsAdded = false;
|
||||
|
||||
if (depsAdded && addedFiles.find(file.first) == addedFiles.end())
|
||||
{
|
||||
filesCompilationOrder.push_back(file.first);
|
||||
addedFiles.insert(file.first);
|
||||
added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__spf_print(1, "files compilation order:\n");
|
||||
for (auto& file : filesCompilationOrder)
|
||||
__spf_print(1, " %s\n", file.c_str());
|
||||
|
||||
return filesCompilationOrder;
|
||||
}
|
||||
|
||||
static int parseFiles(vector<string>& errors, vector<FileInfo>& listOfProject, vector<string>& filesCompilationOrder,
|
||||
int parseForInlining, bool isFromConsole = false)
|
||||
{
|
||||
int rethrow = 0;
|
||||
int iters = 0;
|
||||
|
||||
map<string, set<string>> mapModuleDeps;
|
||||
map<string, string> moduleDelc;
|
||||
map<string, set<string>> modDirectOrder;
|
||||
|
||||
try
|
||||
{
|
||||
parseFiles(iters, errors, listOfProject, mapModuleDeps, moduleDelc, modDirectOrder, false, isFromConsole);
|
||||
filesCompilationOrder = finalyzeParsing(listOfProject, mapModuleDeps, moduleDelc);
|
||||
|
||||
if (parseForInlining)
|
||||
parseFiles(iters, errors, listOfProject, mapModuleDeps, moduleDelc, modDirectOrder, true, isFromConsole);
|
||||
}
|
||||
catch (int err)
|
||||
{
|
||||
rethrow = err;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
rethrow = -1;
|
||||
}
|
||||
return rethrow;
|
||||
}
|
||||
|
||||
int parseFiles(const char* proj, vector<string>& filesCompilationOrder, int parseForInlining)
|
||||
{
|
||||
FILE* list = fopen(proj, "r");
|
||||
if (!list)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
vector<string> pathSplit;
|
||||
if (string(proj).find('\\') != string::npos)
|
||||
splitString(proj, '\\', pathSplit);
|
||||
else
|
||||
splitString(proj, '/', pathSplit);
|
||||
|
||||
if (pathSplit.size() < 2)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
if (pathSplit[pathSplit.size() - 2] != "visualiser_data")
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
string fullPath = "";
|
||||
for (int z = 0; z < pathSplit.size() - 2; ++z)
|
||||
fullPath += pathSplit[z] + "/";
|
||||
if (fullPath == "")
|
||||
fullPath = "./";
|
||||
else
|
||||
{
|
||||
//change dir
|
||||
if (chdir(fullPath.c_str()) != 0)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
|
||||
vector<FileInfo> listOfProject;
|
||||
while (!feof(list))
|
||||
{
|
||||
char buf[1024];
|
||||
if (fgets(buf, 1024, list) == NULL)
|
||||
continue;
|
||||
|
||||
string toAdd = buf;
|
||||
if (toAdd[toAdd.size() - 1] == '\n')
|
||||
toAdd = toAdd.erase(toAdd.size() - 1);
|
||||
|
||||
string fileNameFixed = "";
|
||||
auto idx = toAdd.find(fullPath);
|
||||
if (idx != string::npos)
|
||||
fileNameFixed = toAdd.substr(idx + fullPath.size());
|
||||
else
|
||||
fileNameFixed = (toAdd.substr(0, 2) == "./") ? toAdd.substr(2) : toAdd;
|
||||
|
||||
const string optPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".opt";
|
||||
const string errPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".err";
|
||||
const string outPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".out";
|
||||
|
||||
const string fileText = readFileToStr(toAdd);
|
||||
|
||||
FILE* opt = fopen(optPath.c_str(), "r");
|
||||
if (!opt)
|
||||
{
|
||||
__spf_print(1, "can not open path %s\n", optPath.c_str());
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
}
|
||||
fgets(buf, 1024, opt);
|
||||
string toAddOpt = buf;
|
||||
if (toAddOpt[toAddOpt.size() - 1] == '\n')
|
||||
toAddOpt = toAddOpt.erase(toAddOpt.size() - 1);
|
||||
|
||||
fclose(opt);
|
||||
listOfProject.push_back(FileInfo(fileNameFixed, toAddOpt, errPath, outPath, "", fileText));
|
||||
}
|
||||
|
||||
fclose(list);
|
||||
vector<string> errors;
|
||||
|
||||
int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, parseForInlining);
|
||||
int errCount = dumpErrors(listOfProject, errors);
|
||||
|
||||
if (rethrow != 0)
|
||||
throw rethrow;
|
||||
return -errCount;
|
||||
}
|
||||
|
||||
void parseFiles(int argc, char** argv)
|
||||
{
|
||||
bool isInline = false;
|
||||
auto result = splitCommandLineForParse(argv, argc, isInline);
|
||||
if (result.second.size() == 0)
|
||||
{
|
||||
printf("Nothing to parse\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int code = 0;
|
||||
|
||||
vector<string> errors;
|
||||
vector<FileInfo> listOfProject;
|
||||
|
||||
string toAddOpt = "";
|
||||
for (auto& opt : result.first)
|
||||
toAddOpt += opt + " ";
|
||||
|
||||
for (auto& file : result.second)
|
||||
{
|
||||
const string fileText = readFileToStr(file);
|
||||
listOfProject.push_back(FileInfo(file, toAddOpt + "-o " + file + ".dep", "", "", "", fileText, 0));
|
||||
}
|
||||
|
||||
vector<string> filesCompilationOrder;
|
||||
if (isInline)
|
||||
printf(" run parsing for inlining\n");
|
||||
|
||||
int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, isInline, true);
|
||||
if (rethrow == 0)
|
||||
{
|
||||
for (auto& err : errors)
|
||||
{
|
||||
vector<string> splited;
|
||||
splitString(err, '\n', splited);
|
||||
for (auto& elem : splited)
|
||||
{
|
||||
if (elem.find("Error") != string::npos)
|
||||
{
|
||||
printf("%s\n", elem.c_str());
|
||||
code++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (code == 0 && rethrow == 0)
|
||||
{
|
||||
FILE* proj = fopen("dvm.proj", "w");
|
||||
if (proj == NULL)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
for (auto& file : result.second)
|
||||
fprintf(proj, "%s.dep\n", file.c_str());
|
||||
printf("Parsing was completed successfully\n");
|
||||
}
|
||||
else
|
||||
printf("Parsing was completed with errors, throw code %d, errors count %d\n", rethrow, code);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
int parseFiles(const char* proj, std::vector<std::string>& filesCompilationOrder, int parseForInlining);
|
||||
void parseFiles(int argc, char** argv);
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "../Utils/leak_detector.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../Utils/errors.h"
|
||||
#include "../Utils/SgUtils.h"
|
||||
|
||||
#include "StdCapture.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern int pppa_analyzer(int argv, char** argc);
|
||||
|
||||
int pppaAnalyzer(const char* options)
|
||||
{
|
||||
string optionsS(options);
|
||||
vector<string> splited = splitAndArgvCreate(optionsS);
|
||||
|
||||
char** argv = new char* [splited.size()];
|
||||
for (int z = 0; z < splited.size(); ++z)
|
||||
argv[z] = (char*)splited[z].c_str();
|
||||
|
||||
StdCapture::Init();
|
||||
string errorMessage = "";
|
||||
int retCode = pppa_analyzer(splited.size(), argv);
|
||||
StdCapture::EndCapture();
|
||||
errorMessage = StdCapture::GetCapture();
|
||||
|
||||
delete []argv;
|
||||
return retCode;
|
||||
}
|
||||
|
||||
void pppaAnalyzer(int argc, char** argv)
|
||||
{
|
||||
int code = pppa_analyzer(argc, argv);
|
||||
if (code == 0)
|
||||
printf("PPPA was completed successfully\n");
|
||||
else
|
||||
printf("PPPA was completed with error code %d\n", code);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
int pppaAnalyzer(const char* options);
|
||||
void pppaAnalyzer(int argc, char** argv);
|
||||
191
sapfor/experts/Sapfor_2017/_src/ProjectManipulation/StdCapture.h
Normal file
191
sapfor/experts/Sapfor_2017/_src/ProjectManipulation/StdCapture.h
Normal file
@@ -0,0 +1,191 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
|
||||
#define popen _popen
|
||||
#define pclose _pclose
|
||||
#define stat _stat
|
||||
#define dup _dup
|
||||
#define dup2 _dup2
|
||||
#define fileno _fileno
|
||||
#define close _close
|
||||
#define pipe _pipe
|
||||
#define read _read
|
||||
#define eof _eof
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef STD_OUT_FD
|
||||
#define STD_OUT_FD (fileno(stdout))
|
||||
#endif
|
||||
|
||||
#ifndef STD_ERR_FD
|
||||
#define STD_ERR_FD (fileno(stderr))
|
||||
#endif
|
||||
|
||||
static int m_pipe[2];
|
||||
static int m_oldStdOut;
|
||||
static int m_oldStdErr;
|
||||
static bool m_capturing;
|
||||
static std::mutex m_mutex;
|
||||
static std::string m_captured;
|
||||
|
||||
class StdCapture
|
||||
{
|
||||
enum PIPES { READ, WRITE };
|
||||
|
||||
static int secure_dup(int src)
|
||||
{
|
||||
int ret = -1;
|
||||
bool fd_blocked = false;
|
||||
do
|
||||
{
|
||||
ret = dup(src);
|
||||
fd_blocked = (errno == EINTR || errno == EBUSY);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
} while (ret < 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void secure_pipe(int* pipes)
|
||||
{
|
||||
int ret = -1;
|
||||
bool fd_blocked = false;
|
||||
do
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ret = pipe(pipes, 1024 * 1024 * 20, O_BINARY); // 20 MB
|
||||
#else
|
||||
ret = pipe(pipes) == -1;
|
||||
fcntl(*pipes, F_SETPIPE_SZ, 1024 * 1024 * 20);
|
||||
#endif
|
||||
fd_blocked = (errno == EINTR || errno == EBUSY);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
} while (ret < 0);
|
||||
}
|
||||
|
||||
static void secure_dup2(int src, int dest)
|
||||
{
|
||||
int ret = -1;
|
||||
bool fd_blocked = false;
|
||||
do
|
||||
{
|
||||
ret = dup2(src, dest);
|
||||
fd_blocked = (errno == EINTR || errno == EBUSY);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
} while (ret < 0);
|
||||
}
|
||||
|
||||
static void secure_close(int& fd)
|
||||
{
|
||||
int ret = -1;
|
||||
bool fd_blocked = false;
|
||||
do
|
||||
{
|
||||
ret = close(fd);
|
||||
fd_blocked = (errno == EINTR);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
} while (ret < 0);
|
||||
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
public:
|
||||
static void Init()
|
||||
{
|
||||
// make stdout & stderr streams unbuffered
|
||||
// so that we don't need to flush the streams
|
||||
// before capture and after capture
|
||||
// (fflush can cause a deadlock if the stream is currently being
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
static void BeginCapture()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_capturing)
|
||||
return;
|
||||
|
||||
secure_pipe(m_pipe);
|
||||
m_oldStdOut = secure_dup(STD_OUT_FD);
|
||||
m_oldStdErr = secure_dup(STD_ERR_FD);
|
||||
secure_dup2(m_pipe[WRITE], STD_OUT_FD);
|
||||
secure_dup2(m_pipe[WRITE], STD_ERR_FD);
|
||||
m_capturing = true;
|
||||
#ifndef _WIN32
|
||||
secure_close(m_pipe[WRITE]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool IsCapturing()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_capturing;
|
||||
}
|
||||
|
||||
static void EndCapture()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (!m_capturing)
|
||||
return;
|
||||
|
||||
m_captured.clear();
|
||||
secure_dup2(m_oldStdOut, STD_OUT_FD);
|
||||
secure_dup2(m_oldStdErr, STD_ERR_FD);
|
||||
|
||||
const int bufSize = 1025;
|
||||
char buf[bufSize];
|
||||
int bytesRead = 0;
|
||||
bool fd_blocked(false);
|
||||
do
|
||||
{
|
||||
bytesRead = 0;
|
||||
fd_blocked = false;
|
||||
#ifdef _WIN32
|
||||
if (!eof(m_pipe[READ]))
|
||||
bytesRead = read(m_pipe[READ], buf, bufSize - 1);
|
||||
#else
|
||||
bytesRead = read(m_pipe[READ], buf, bufSize - 1);
|
||||
#endif
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
buf[bytesRead] = 0;
|
||||
m_captured += buf;
|
||||
}
|
||||
else if (bytesRead < 0)
|
||||
{
|
||||
fd_blocked = (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR);
|
||||
if (fd_blocked)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
} while (fd_blocked || bytesRead == (bufSize - 1));
|
||||
|
||||
secure_close(m_oldStdOut);
|
||||
secure_close(m_oldStdErr);
|
||||
secure_close(m_pipe[READ]);
|
||||
#ifdef _WIN32
|
||||
secure_close(m_pipe[WRITE]);
|
||||
#endif
|
||||
m_capturing = false;
|
||||
}
|
||||
|
||||
static std::string GetCapture()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_captured;
|
||||
}
|
||||
};
|
||||
@@ -33,6 +33,10 @@
|
||||
|
||||
#include "Utils/errors.h"
|
||||
#include "Utils/SgUtils.h"
|
||||
#include "ProjectManipulation/ParseFiles.h"
|
||||
#include "ProjectManipulation/PerfAnalyzer.h"
|
||||
#include "ProjectManipulation/ConvertFiles.h"
|
||||
|
||||
#include "LoopAnalyzer/loop_analyzer.h"
|
||||
#include "LoopAnalyzer/loop_analyzer_nodist.h"
|
||||
|
||||
@@ -79,7 +83,11 @@
|
||||
#include "Transformations/private_removing.h"
|
||||
#include "Transformations/fix_common_blocks.h"
|
||||
#include "Transformations/convert_to_c.h"
|
||||
<<<<<<< HEAD
|
||||
#include "Transformations/set_implicit_none.h"
|
||||
=======
|
||||
#include "Transformations/dead_code.h"
|
||||
>>>>>>> master
|
||||
|
||||
#include "RenameSymbols/rename_symbols.h"
|
||||
#include "ProjectParameters/projectParameters.h"
|
||||
@@ -322,7 +330,8 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
|
||||
//TODO: add freeForm for each file
|
||||
if (curr_regime == INSERT_INCLUDES && filesToInclude.find(file_name) != filesToInclude.end())
|
||||
{
|
||||
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile, moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, true); //,
|
||||
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile,
|
||||
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString, true);
|
||||
auto itI = filesToInclude.find(file_name);
|
||||
for (auto& incl : itI->second)
|
||||
if (allIncludeFiles.find(incl) != allIncludeFiles.end())
|
||||
@@ -330,7 +339,8 @@ static string unparseProjectIfNeed(SgFile* file, const int curr_regime, const bo
|
||||
}
|
||||
else
|
||||
{
|
||||
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile, moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString);
|
||||
unparseToBuf = removeIncludeStatsAndUnparse(file, file_name, fout_name.c_str(), allIncludeFiles, out_free_form == 1, moduleUsesByFile,
|
||||
moduleDecls, getObjectForFileFromMap(file_name, exctactedModuleStats), toString);
|
||||
|
||||
// copy includes that have not changed
|
||||
if (folderName != NULL)
|
||||
@@ -727,8 +737,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
depInfoForLoopGraphV[elem.first] = elem.second;
|
||||
|
||||
selectParallelDirectiveForVariantNoDist(new File(file), parallelRegions[z], allArrays, loopsInFile, mapLoopsInFile, mapFuncInfo,
|
||||
toInsert, parallelRegions[z]->GetId(), arrayLinksByFuncCalls,
|
||||
depInfoForLoopGraphV, getObjectForFileFromMap(file_name, SPF_messages));
|
||||
toInsert, arrayLinksByFuncCalls, depInfoForLoopGraphV, getObjectForFileFromMap(file_name, SPF_messages));
|
||||
|
||||
if (toInsert.size() > 0)
|
||||
{
|
||||
@@ -942,7 +951,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
}
|
||||
else if (curr_regime == GET_ALL_ARRAY_DECL)
|
||||
{
|
||||
int err = getAllDeclaredArrays(file, declaredArrays, declaratedArraysSt, SPF_messages, subs_parallelRegions, keyValueFromGUI);
|
||||
int err = getAllDeclaredArrays(file, declaredArrays, declaratedArraysSt, SPF_messages, subs_parallelRegions, distrStateFromGUI);
|
||||
if (err != 0)
|
||||
internalExit = -1;
|
||||
}
|
||||
@@ -996,6 +1005,10 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
fileIt->second.insert(first->fileName());
|
||||
}
|
||||
}
|
||||
|
||||
if (inlcudeAllFiles)
|
||||
if (fileIt->second.size())
|
||||
filesToInclude[file_name] = fileIt->second;
|
||||
}
|
||||
else if (curr_regime == REMOVE_AND_CALC_SHADOW)
|
||||
{
|
||||
@@ -1162,8 +1175,19 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
getMaxMinBlockDistribution(file, min_max_block);
|
||||
else if (curr_regime == CONVERT_TO_C)
|
||||
covertToC(file);
|
||||
<<<<<<< HEAD
|
||||
else if (curr_regime == SET_IMPLICIT_NONE)
|
||||
ImplicitCheck(file);
|
||||
=======
|
||||
else if (curr_regime == INSERT_NO_DISTR_FLAGS_FROM_GUI)
|
||||
addPrivatesToArraysFromGUI(file, declaredArrays, distrStateFromGUI);
|
||||
else if (curr_regime == REMOVE_DEAD_CODE)
|
||||
{
|
||||
auto funcsForFile = getObjectForFileFromMap(file_name, allFuncInfo);
|
||||
for (auto& func : funcsForFile)
|
||||
removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
|
||||
}
|
||||
>>>>>>> master
|
||||
else if (curr_regime == TEST_PASS)
|
||||
{
|
||||
//test pass
|
||||
@@ -2029,7 +2053,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
|
||||
swapLoopsForParallel(loopGraph, SPF_messages, 1);
|
||||
else if (curr_regime == RESTORE_SWAP_LOOPS)
|
||||
swapLoopsForParallel(loopGraph, SPF_messages, -1);
|
||||
else if (curr_regime == CREATE_PARALLEL_DIRS)
|
||||
else if (curr_regime == CREATE_PARALLEL_DIRS || curr_regime == INSERT_PARALLEL_DIRS_NODIST)
|
||||
filterParallelDirectives(loopGraph, createdDirectives);
|
||||
else if (curr_regime == INLINE_PROCEDURES)
|
||||
callInliner(allFuncInfo, inDataProc, inDataChains, inDataChainsStart, SPF_messages, commonBlocks);
|
||||
@@ -2482,6 +2506,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
|
||||
case PURE_INTENT_INSERT:
|
||||
case REMOVE_OMP_DIRS_TRANSFORM:
|
||||
case REMOVE_COMMENTS:
|
||||
case INSERT_NO_DISTR_FLAGS_FROM_GUI:
|
||||
runAnalysis(*project, curr_regime, true, "", folderName);
|
||||
break;
|
||||
case PRIVATE_REMOVING:
|
||||
@@ -2527,6 +2552,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
|
||||
runAnalysis(*project, curr_regime, false);
|
||||
case SUBST_EXPR_RD_AND_UNPARSE:
|
||||
case SUBST_EXPR_AND_UNPARSE:
|
||||
case REMOVE_DEAD_CODE_AND_UNPARSE:
|
||||
if (folderName)
|
||||
runAnalysis(*project, UNPARSE_FILE, true, "", folderName);
|
||||
else
|
||||
@@ -2552,11 +2578,6 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int parse_file(int argc, char* argv[], char* proj_name);
|
||||
extern int pppa_analyzer(int argv, char** argc);
|
||||
|
||||
bool runAsClient = false;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int leakMemDump = 0;
|
||||
@@ -2721,73 +2742,13 @@ int main(int argc, char **argv)
|
||||
else if (string(curr_arg) == "-autoArray")
|
||||
parallizeFreeLoops = 1;
|
||||
else if (string(curr_arg) == "-parse")
|
||||
{
|
||||
bool isInline = false;
|
||||
auto result = splitCommandLineForParse(argv + (i + 1), argc - (i + 1), isInline);
|
||||
if (result.second.size() == 0)
|
||||
{
|
||||
printf("Nothing to parse\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int code = 0;
|
||||
|
||||
vector<string> errors;
|
||||
vector<FileInfo> listOfProject;
|
||||
|
||||
string toAddOpt = "";
|
||||
for (auto& opt : result.first)
|
||||
toAddOpt += opt + " ";
|
||||
|
||||
for (auto& file : result.second)
|
||||
{
|
||||
const string fileText = readFileToStr(file);
|
||||
listOfProject.push_back(FileInfo(file, toAddOpt + "-o " + file + ".dep", "", "", "", fileText, 0));
|
||||
}
|
||||
|
||||
int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, isInline, true);
|
||||
if (rethrow == 0)
|
||||
{
|
||||
for (auto& err : errors)
|
||||
{
|
||||
vector<string> splited;
|
||||
splitString(err, '\n', splited);
|
||||
for (auto& elem : splited)
|
||||
{
|
||||
if (elem.find("Error") != string::npos)
|
||||
{
|
||||
printf("%s\n", elem.c_str());
|
||||
code++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (code == 0 && rethrow == 0)
|
||||
{
|
||||
FILE* proj = fopen("dvm.proj", "w");
|
||||
if (proj == NULL)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
for (auto& file : result.second)
|
||||
fprintf(proj, "%s.dep\n", file.c_str());
|
||||
printf("Parsing was completed successfully\n");
|
||||
}
|
||||
else
|
||||
printf("Parsing was completed with errors, throw code %d, errors count %d\n", rethrow, code);
|
||||
exit(0);
|
||||
}
|
||||
parseFiles(argc - (i + 1), argv + (i + 1));
|
||||
else if (string(curr_arg) == "-pppa")
|
||||
pppaAnalyzer(argc - i, argv + i);
|
||||
else if (string(curr_arg) == "-fdvm")
|
||||
convertFiles(argc - i, argv + i);
|
||||
else if (string(curr_arg) == "-mpi")
|
||||
mpiProgram = 1;
|
||||
else if (string(curr_arg) == "-pppa")
|
||||
{
|
||||
int code = pppa_analyzer(argc - i, argv + i);
|
||||
if (code == 0)
|
||||
printf("PPPA was completed successfully\n");
|
||||
else
|
||||
printf("PPPA was completed with error code %d\n", code);
|
||||
exit(0);
|
||||
}
|
||||
else if (string(curr_arg) == "-client")
|
||||
{
|
||||
runAsClient = true;
|
||||
@@ -2832,6 +2793,8 @@ int main(int argc, char **argv)
|
||||
debSh = 1;
|
||||
else if (string(curr_arg) == "-noLogo")
|
||||
noLogo = true;
|
||||
else if (string(curr_arg) == "-includeAll")
|
||||
inlcudeAllFiles = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -165,6 +165,8 @@ enum passes {
|
||||
BUILD_IR,
|
||||
LIVE_ANALYSIS_IR,
|
||||
PRIVATE_ANALYSIS_IR,
|
||||
REMOVE_DEAD_CODE,
|
||||
REMOVE_DEAD_CODE_AND_UNPARSE,
|
||||
|
||||
FIX_COMMON_BLOCKS,
|
||||
REMOVE_OMP_DIRS,
|
||||
@@ -172,6 +174,7 @@ enum passes {
|
||||
REMOVE_COMMENTS,
|
||||
GET_MIN_MAX_BLOCK_DIST,
|
||||
CONVERT_TO_C,
|
||||
INSERT_NO_DISTR_FLAGS_FROM_GUI,
|
||||
|
||||
SET_IMPLICIT_NONE,
|
||||
|
||||
@@ -344,6 +347,8 @@ static void setPassValues()
|
||||
passNames[CALL_GRAPH_IR] = "CALL_GRAPH_IR";
|
||||
passNames[LIVE_ANALYSIS_IR] = "LIVE_ANALYSIS_IR";
|
||||
passNames[PRIVATE_ANALYSIS_IR] = "PRIVATE_ANALYSIS_IR";
|
||||
passNames[REMOVE_DEAD_CODE] = "REMOVE_DEAD_CODE";
|
||||
passNames[REMOVE_DEAD_CODE_AND_UNPARSE] = "REMOVE_DEAD_CODE_AND_UNPARSE";
|
||||
|
||||
passNames[FIX_COMMON_BLOCKS] = "FIX_COMMON_BLOCKS";
|
||||
passNames[REMOVE_OMP_DIRS] = "REMOVE_OMP_DIRS";
|
||||
@@ -351,7 +356,11 @@ static void setPassValues()
|
||||
passNames[REMOVE_COMMENTS] = "REMOVE_COMMENTS";
|
||||
passNames[GET_MIN_MAX_BLOCK_DIST] = "GET_MIN_MAX_BLOCK_DIST";
|
||||
passNames[CONVERT_TO_C] = "CONVERT_TO_C";
|
||||
<<<<<<< HEAD
|
||||
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
|
||||
=======
|
||||
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
|
||||
>>>>>>> master
|
||||
|
||||
passNames[TEST_PASS] = "TEST_PASS";
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ bool ignoreArrayDistributeState = false;
|
||||
bool fullDepGraph = false;
|
||||
bool noLogo = false;
|
||||
bool withTemplateInfo = false;
|
||||
bool inlcudeAllFiles = false; // for pass INSERT_INLCUDES
|
||||
bool runAsClient = false; // run console project as client for Visualizer
|
||||
|
||||
uint64_t currentAvailMemory = 0;
|
||||
int QUALITY; // quality of conflicts search in graph
|
||||
@@ -82,7 +84,7 @@ std::map<std::string, std::map<int, std::set<std::string>>> commentsToInclude;
|
||||
//
|
||||
|
||||
//for INSERT_INCLUDES
|
||||
std::map<std::string, std::set<std::string>> filesToInclude;
|
||||
std::map<std::string, std::set<std::string>> filesToInclude; // file -> includes
|
||||
//
|
||||
|
||||
//for PASSES DEPENDENSIES
|
||||
@@ -157,7 +159,7 @@ std::pair<std::string, int> inOnlyForloopOnPlace;
|
||||
//
|
||||
|
||||
//cache for declaration arrays state switching
|
||||
std::map<std::string, int> keyValueFromGUI;
|
||||
std::map<std::string, int> distrStateFromGUI;
|
||||
//
|
||||
|
||||
//for PROCESS_IO
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
484
sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp
Normal file
484
sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.cpp
Normal file
@@ -0,0 +1,484 @@
|
||||
#include "dead_code.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::set;
|
||||
|
||||
using std::remove_if;
|
||||
|
||||
#define PRINT_USELESS_STATEMENTS 0
|
||||
|
||||
static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* instr,
|
||||
set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||
vector<SAPFOR::Argument*>& formal_parameters,
|
||||
vector<SAPFOR::Argument*>& lastParamRef, int& last_param_ref_index, int& last_param_ref_size,
|
||||
string& fName, const map<string, FuncInfo*>& funcByName,
|
||||
bool& useful, bool& last_fcall_useful,
|
||||
set<SAPFOR::Argument*>& usedByThisBlock)
|
||||
{
|
||||
set<SAPFOR::Argument*> res, args;
|
||||
|
||||
vector<LIVE_VARIABLES::LiveDeadVarsForCall> fcalls;
|
||||
|
||||
getUseDefForInstruction(block, instr,
|
||||
args, res,
|
||||
formal_parameters, fcalls,
|
||||
lastParamRef, last_param_ref_index, last_param_ref_size,
|
||||
fName, funcByName,
|
||||
false
|
||||
);
|
||||
|
||||
if (!useful)
|
||||
{
|
||||
for (SAPFOR::Argument* r : res)
|
||||
{
|
||||
if (use.find(r) != use.end() || r->getMemType() != SAPFOR::CFG_MEM_TYPE::LOCAL_)
|
||||
{
|
||||
useful = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!useful)
|
||||
{
|
||||
set<SAPFOR::CFG_OP> always_useful =
|
||||
{
|
||||
SAPFOR::CFG_OP::POINTER_ASS,
|
||||
SAPFOR::CFG_OP::STORE,
|
||||
SAPFOR::CFG_OP::REC_REF_STORE,
|
||||
SAPFOR::CFG_OP::RANGE,
|
||||
SAPFOR::CFG_OP::ENTRY,
|
||||
SAPFOR::CFG_OP::EXIT,
|
||||
SAPFOR::CFG_OP::DVM_DIR,
|
||||
SAPFOR::CFG_OP::SPF_DIR
|
||||
};
|
||||
|
||||
if (always_useful.find(instr->getOperation()) != always_useful.end())
|
||||
useful = true;
|
||||
else if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
|
||||
{
|
||||
auto func_it = funcByName.find(instr->getArg1()->getValue());
|
||||
useful |= func_it == funcByName.end() || !(func_it->second->isPure);
|
||||
}
|
||||
else if (instr->getOperation() == SAPFOR::CFG_OP::PARAM)
|
||||
useful |= last_fcall_useful;
|
||||
}
|
||||
|
||||
if (useful)
|
||||
{
|
||||
if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
|
||||
last_fcall_useful = true;
|
||||
|
||||
for (auto e : res)
|
||||
{
|
||||
def.insert(e);
|
||||
use.erase(e);
|
||||
}
|
||||
|
||||
for (auto e : args)
|
||||
{
|
||||
use.insert(e);
|
||||
def.erase(e);
|
||||
}
|
||||
|
||||
insertIfVar(args.begin(), args.end(), usedByThisBlock);
|
||||
}
|
||||
|
||||
if ((instr->getOperation() == SAPFOR::CFG_OP::F_CALL || instr->getOperation() == SAPFOR::CFG_OP::PARAM) && fName == "")
|
||||
last_fcall_useful = false;
|
||||
}
|
||||
|
||||
|
||||
//Build use and def sets of block. Result are stored in use and def
|
||||
static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use, set<SAPFOR::Argument*>& def,
|
||||
vector<SAPFOR::Argument*>& formal_parameters, vector<bool>& useful,
|
||||
set<SAPFOR::Argument*>& usedByThisBlock, const map<string, FuncInfo*>& funcByName)
|
||||
{
|
||||
set<SAPFOR::Argument*> use_with_regs = use, def_with_regs = def;
|
||||
|
||||
vector<SAPFOR::Argument*> lastParamRef;
|
||||
int last_param_ref_index = 0, last_param_ref_size = 0;
|
||||
string fName = "";
|
||||
bool last_fcall_useful = false;
|
||||
|
||||
const auto& instructions = block->getInstructions();
|
||||
int instr_size = instructions.size();
|
||||
|
||||
for (int i = instr_size - 1; i >= 0; i--)
|
||||
{
|
||||
bool u = useful[i];
|
||||
|
||||
updateUseDefForInstruction(block, instructions[i]->getInstruction(),
|
||||
use_with_regs, def_with_regs,
|
||||
formal_parameters,
|
||||
lastParamRef, last_param_ref_index, last_param_ref_size,
|
||||
fName, funcByName,
|
||||
u, last_fcall_useful,
|
||||
usedByThisBlock
|
||||
);
|
||||
|
||||
useful[i] = u;
|
||||
}
|
||||
|
||||
insertIfVar(use_with_regs.begin(), use_with_regs.end(), use);
|
||||
insertIfVar(def_with_regs.begin(), def_with_regs.end(), def);
|
||||
}
|
||||
|
||||
|
||||
class DeadCodeAnalysisNode : public DataFlowAnalysisNode<map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>> {
|
||||
private:
|
||||
vector<bool> useful;
|
||||
bool useful_block = false;
|
||||
set<DeadCodeAnalysisNode*> next_notempty_in, next_notempty_out;
|
||||
bool useful_jump = false;
|
||||
|
||||
vector<SAPFOR::Argument*>& formal_parameters;
|
||||
const map<string, FuncInfo*>& funcByName;
|
||||
public:
|
||||
bool updateJumpStatus()
|
||||
{
|
||||
bool res = false;
|
||||
const auto& prev = getPrevBlocks();
|
||||
if (prev.size() > 1 && !useful.back() &&
|
||||
getBlock()->getInstructions().back()->getInstruction()->getOperation() == SAPFOR::CFG_OP::JUMP_IF)
|
||||
{
|
||||
const auto& example = dynamic_cast<DeadCodeAnalysisNode*>(*prev.begin())->next_notempty_out;
|
||||
|
||||
for (auto p : prev)
|
||||
{
|
||||
DeadCodeAnalysisNode* next = dynamic_cast<DeadCodeAnalysisNode*>(p);
|
||||
|
||||
if (next->next_notempty_out != example)
|
||||
{
|
||||
useful.back() = true;
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool updateNextNotEmpty()
|
||||
{
|
||||
bool updated = false;
|
||||
|
||||
if(!useful_block)
|
||||
{
|
||||
set<DeadCodeAnalysisNode*> current = {};
|
||||
|
||||
for (auto nextP : getPrevBlocks())
|
||||
{
|
||||
DeadCodeAnalysisNode* next = dynamic_cast<DeadCodeAnalysisNode*>(nextP);
|
||||
|
||||
if(!next)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
current.insert(next->next_notempty_out.begin(), next->next_notempty_out.end());
|
||||
}
|
||||
|
||||
if (current != next_notempty_in)
|
||||
{
|
||||
next_notempty_in = current;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getIn() {
|
||||
return getBlock()->getLiveOut();
|
||||
}
|
||||
|
||||
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getOut() {
|
||||
return getBlock()->getLiveIn();
|
||||
}
|
||||
|
||||
bool addIn(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data) {
|
||||
bool inserted = getBlock()->addLiveOut(data);
|
||||
|
||||
if (!useful_block)
|
||||
inserted |= updateNextNotEmpty();
|
||||
|
||||
inserted |= updateJumpStatus();
|
||||
|
||||
return inserted;
|
||||
}
|
||||
|
||||
bool addOut(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data) {
|
||||
return getBlock()->addLiveIn(data);
|
||||
}
|
||||
|
||||
bool forwardData(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data) {
|
||||
bool inserted = false;
|
||||
SAPFOR::BasicBlock* bb= getBlock();
|
||||
|
||||
set<SAPFOR::Argument*> use, def;
|
||||
|
||||
for (const auto& byArg : data)
|
||||
use.insert(byArg.first);
|
||||
|
||||
set<SAPFOR::Argument*> usedByThisBlock;
|
||||
buildUseDef(bb, use, def, this->formal_parameters, useful, usedByThisBlock, funcByName);
|
||||
|
||||
auto in = bb->getLiveIn(), out = bb->getLiveOut();
|
||||
|
||||
for (SAPFOR::Argument* arg : use)
|
||||
{
|
||||
bool this_block = usedByThisBlock.find(arg) != usedByThisBlock.end();
|
||||
|
||||
if (!this_block)
|
||||
{
|
||||
auto data_it = data.find(arg);
|
||||
|
||||
if (data_it == data.end())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
inserted |= bb->addLiveIn({ *data_it });
|
||||
}
|
||||
else
|
||||
{
|
||||
auto in_it = in.find(arg);
|
||||
bool skip = false;
|
||||
if (in_it != in.end())
|
||||
{
|
||||
if (in_it->second.size() == 1 && *(in_it->second.begin()) == bb)
|
||||
skip = true; // nothing to do, inserted = false
|
||||
else
|
||||
bb->removeLiveIn(arg);
|
||||
}
|
||||
if(!skip)
|
||||
inserted |= bb->addLiveIn({ { arg, { bb } } });
|
||||
}
|
||||
}
|
||||
|
||||
if(!useful_block)
|
||||
{
|
||||
for(bool status : useful)
|
||||
{
|
||||
if (status)
|
||||
{
|
||||
useful_block = true;
|
||||
|
||||
inserted = true;
|
||||
next_notempty_out = { this };
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!useful_block)
|
||||
{
|
||||
if (next_notempty_in != next_notempty_out)
|
||||
{
|
||||
inserted = true;
|
||||
next_notempty_out = next_notempty_in;
|
||||
}
|
||||
}
|
||||
|
||||
return inserted;
|
||||
}
|
||||
|
||||
DeadCodeAnalysisNode(SAPFOR::BasicBlock* block,
|
||||
vector<SAPFOR::Argument*>& formal_parameters,
|
||||
const map<string, FuncInfo*>& funcByName)
|
||||
:
|
||||
formal_parameters(formal_parameters),
|
||||
funcByName(funcByName)
|
||||
{
|
||||
setBlock(block);
|
||||
useful.resize(block->getInstructions().size(), false);
|
||||
set<SAPFOR::Argument*> use, def;
|
||||
set<SAPFOR::Argument*> usedByThisBlock;
|
||||
|
||||
buildUseDef(getBlock(), use, def, this->formal_parameters, useful, usedByThisBlock, funcByName);
|
||||
|
||||
for (SAPFOR::Argument* arg : use)
|
||||
getBlock()->addLiveIn({ { arg, { getBlock() } } });
|
||||
}
|
||||
|
||||
const vector<bool>& getResult() { return useful; }
|
||||
};
|
||||
|
||||
class DeadCodeAnalysis : public BackwardDataFlowAnalysis<DeadCodeAnalysisNode> {
|
||||
protected:
|
||||
vector<SAPFOR::Argument*>& formal_parameters;
|
||||
const map<string, FuncInfo*>& funcByName;
|
||||
|
||||
DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override {
|
||||
return new DeadCodeAnalysisNode(block, formal_parameters, funcByName);
|
||||
}
|
||||
public:
|
||||
DeadCodeAnalysis(vector<SAPFOR::Argument*>& formal_parameters, const map<string, FuncInfo*>& funcByName)
|
||||
:
|
||||
formal_parameters(formal_parameters),
|
||||
funcByName(funcByName)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
void removeDeadCode(SgStatement* func,
|
||||
const map<string, vector<FuncInfo*>>& allFuncs,
|
||||
const map<string, CommonBlock*>& commonBlocks)
|
||||
{
|
||||
SgProgHedrStmt* prog = isSgProgHedrStmt(func);
|
||||
|
||||
auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, false, false, false, false), commonBlocks, allFuncs);
|
||||
|
||||
if(cfg.size() != 1)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
auto& cfg_pair = *(cfg.begin());
|
||||
|
||||
// delete unreachable blocks
|
||||
|
||||
set<SAPFOR::BasicBlock*> reachable;
|
||||
|
||||
for (auto b : cfg_pair.second)
|
||||
if(b->getInstructions().front()->isHeader())
|
||||
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());
|
||||
|
||||
// detect useless code
|
||||
|
||||
vector<SAPFOR::Argument*> func_parameters(cfg_pair.first->funcParams.countOfPars, NULL);
|
||||
|
||||
map<string, FuncInfo*> funcByName;
|
||||
|
||||
for (auto& byFile : allFuncs)
|
||||
for (auto byFunc : byFile.second)
|
||||
funcByName[byFunc->funcName] = byFunc;
|
||||
|
||||
DeadCodeAnalysis analysis_object(func_parameters, funcByName);
|
||||
|
||||
analysis_object.fit(cfg_pair.second);
|
||||
analysis_object.analyze();
|
||||
|
||||
// detect dead statements
|
||||
|
||||
set<SgStatement*> useful;
|
||||
|
||||
for (DeadCodeAnalysisNode* byNode : analysis_object.getNodes())
|
||||
{
|
||||
const auto& instructions = byNode->getBlock()->getInstructions();
|
||||
const auto& statuses = byNode->getResult();
|
||||
|
||||
int size = instructions.size();
|
||||
|
||||
if(size != statuses.size())
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if(statuses[i])
|
||||
{
|
||||
SgStatement* stmt = instructions[i]->getInstruction()->getOperator();
|
||||
|
||||
while(stmt && useful.insert(stmt).second)
|
||||
stmt = stmt->controlParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove dead statements
|
||||
|
||||
SgStatement* end = func->lastNodeOfStmt(), *st = func;
|
||||
|
||||
set<int> removable =
|
||||
{
|
||||
ASSIGN_STAT,
|
||||
PROC_STAT,
|
||||
WRITE_STAT,
|
||||
READ_STAT
|
||||
};
|
||||
|
||||
while (st != end)
|
||||
{
|
||||
SgStatement* next = st->lexNext();
|
||||
|
||||
if (removable.find(st->variant()) != removable.end() && useful.find(st) == useful.end())
|
||||
{
|
||||
__spf_print(PRINT_USELESS_STATEMENTS, "[Useless statement '%s' on line %d]\n", st->unparse(), st->lineNumber());
|
||||
|
||||
st->deleteStmt();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isSgControlEndStmt(st))
|
||||
{
|
||||
SgStatement* parent = st->controlParent();
|
||||
SgStatement* parent_end;
|
||||
|
||||
if (parent && (parent_end = parent->lastNodeOfStmt()) && parent_end == st)
|
||||
{
|
||||
bool empty_parent = false;
|
||||
|
||||
switch (parent->variant())
|
||||
{
|
||||
case IF_NODE:
|
||||
empty_parent =
|
||||
parent->lexNext() == parent_end || // IF THEN ENDIF
|
||||
isSgControlEndStmt(parent->lexNext()) &&
|
||||
parent->lexNext()->lexNext() == parent_end; // IF THEN ELSE ENDIF
|
||||
break;
|
||||
default:
|
||||
empty_parent = parent->lexNext() == parent_end; // DO, WHILE
|
||||
break;
|
||||
}
|
||||
|
||||
if (empty_parent)
|
||||
parent->deleteStmt();
|
||||
else if(isSgIfStmt(parent) && isSgControlEndStmt(parent_end->lexPrev())) // IF with empty ELSE branch
|
||||
parent_end->deleteStmt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
st = next;
|
||||
}
|
||||
|
||||
deleteCFG(cfg);
|
||||
}
|
||||
14
sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.h
Normal file
14
sapfor/experts/Sapfor_2017/_src/Transformations/dead_code.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include<string>
|
||||
#include<vector>
|
||||
|
||||
#include "../Utils/SgUtils.h"
|
||||
#include "../CFGraph/CFGraph.h"
|
||||
#include "../CFGraph/live_variable_analysis.h"
|
||||
#include "../CFGraph/DataFlow/data_flow.h"
|
||||
#include "../CFGraph/DataFlow/backward_data_flow.h"
|
||||
|
||||
void removeDeadCode(SgStatement* func,
|
||||
const std::map<std::string, std::vector<FuncInfo*>>&allFuncs,
|
||||
const std::map<std::string, CommonBlock*>& commonBlocks);
|
||||
@@ -216,7 +216,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
|
||||
|
||||
Pass(RESTORE_LOOP_FROM_ASSIGN) <= list({ SUBST_EXPR_AND_UNPARSE, SUBST_EXPR_RD_AND_UNPARSE });
|
||||
|
||||
Pass(GET_ALL_ARRAY_DECL) <= Pass(CALL_GRAPH_IR);
|
||||
Pass(GET_ALL_ARRAY_DECL) <= list({ CALL_GRAPH_IR, INSERT_NO_DISTR_FLAGS_FROM_GUI });
|
||||
|
||||
Pass(LOOP_GRAPH) <= Pass(PRIVATE_CALL_GRAPH_STAGE3) <= list(FIND_FUNC_TO_INCLUDE, PRIVATE_ANALYSIS_IR) <= list({ LOOP_ANALYZER_DATA_DIST_S0, LOOP_ANALYZER_DATA_DIST_S1, ONLY_ARRAY_GRAPH, LOOP_ANALYZER_ALIGNS });
|
||||
|
||||
@@ -306,6 +306,9 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
|
||||
|
||||
Pass(REMOVE_OMP_DIRS) <= Pass(REMOVE_OMP_DIRS_TRANSFORM);
|
||||
|
||||
Pass(CALL_GRAPH2) <= Pass(REMOVE_DEAD_CODE);
|
||||
list({ REMOVE_DEAD_CODE, REVERT_SUBST_EXPR, REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);
|
||||
|
||||
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,
|
||||
REVERSE_CREATED_NESTED_LOOPS, PREDICT_SCHEME, CALCULATE_STATS_SCHEME, REVERT_SPF_DIRS, CLEAR_SPF_DIRS, TRANSFORM_SHADOW_IF_FULL,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@ SgStatement* declaratedInStmt(SgSymbol *toFind, std::vector<SgStatement*> *allDe
|
||||
#include "DefUseList.h"
|
||||
#include "CommonBlock.h"
|
||||
|
||||
std::set<int> hideUnnecessary(SgFile* file, const std::string& fileN, const std::set<std::string>& moduleDeclsInFiles, const bool dontReplaceIncludes);
|
||||
std::string removeIncludeStatsAndUnparse(SgFile *file, const char *fileName, const char *fout, std::set<std::string> &allIncludeFiles, bool outFree, const std::map<std::string, std::set<std::string>> &moduleUsesByFile, const std::map<std::string, std::string>& moduleDelcs, const std::map<SgStatement*, std::vector<SgStatement*>>& exctactedModuleStats, bool toString, bool dontReplaceIncls = false);
|
||||
SgSymbol* findSymbolOrCreate(SgFile *file, const std::string toFind, SgType *type = NULL, SgStatement *scope = NULL);
|
||||
void recExpressionPrint(SgExpression *exp);
|
||||
@@ -74,11 +75,6 @@ std::string unparseProjectToString(SgFile* file, const int curr_regime);
|
||||
SgStatement* makeDeclaration(SgStatement* curr, const std::vector<SgSymbol*>& s, std::vector<SgExpression*>* inits = NULL);
|
||||
std::vector<SgStatement*> makeDeclaration(const std::vector<SgSymbol*>& symbolsToDeclare, SgStatement* where, std::vector<SgExpression*>* inits = NULL);
|
||||
|
||||
int parseFiles(const char* proj, std::vector<std::string>& filesCompilationOrder, int parseForInlining);
|
||||
int parseFiles(std::vector<std::string>& errors, std::vector<FileInfo>& listOfProject, std::vector<std::string>& filesCompilationOrder, int parseForInlining, bool isFromConsole = false);
|
||||
|
||||
int pppaAnalyzer(const char* options);
|
||||
|
||||
int getNextFreeLabel();
|
||||
|
||||
void fillUsedModulesInFunction(SgStatement *st, std::vector<SgStatement*> &useStats);
|
||||
@@ -109,4 +105,8 @@ std::set<std::string> getAllFilesInProject();
|
||||
void LogIftoIfThen(SgStatement* stmt);
|
||||
void removeSpecialCommentsFromProject(SgFile* file);
|
||||
|
||||
void getMaxMinBlockDistribution(SgFile* file, std::pair<int, int>& min_max);
|
||||
void getMaxMinBlockDistribution(SgFile* file, std::pair<int, int>& min_max);
|
||||
|
||||
void addPrivatesToArraysFromGUI(SgFile* file, const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays, const std::map<std::string, int>& distrStateFromGUI);
|
||||
|
||||
void shiftLines(SgProject* project, bool print = true);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -87,50 +87,6 @@ std::pair<std::vector<std::string>, std::vector<std::string>> splitCommandLineFo
|
||||
std::string getClearName(const std::string& in);
|
||||
std::wstring fixedLongFormat(const wchar_t* old);
|
||||
|
||||
struct FileInfo
|
||||
{
|
||||
FileInfo()
|
||||
{
|
||||
fileName = "";
|
||||
options = "";
|
||||
errPath = "";
|
||||
outPath = "";
|
||||
outDepPath = "";
|
||||
text = "";
|
||||
error = -1;
|
||||
includesAdded = 0;
|
||||
style = -1;
|
||||
lvl = 0;
|
||||
}
|
||||
|
||||
FileInfo(const std::string& _fileName, const std::string& _options, const std::string& _errPath, const std::string& _outPath,
|
||||
const std::string& _outDepPath, const std::string& _text, int errorInit = -1)
|
||||
{
|
||||
fileName = _fileName;
|
||||
options = _options;
|
||||
errPath = _errPath;
|
||||
outPath = _outPath;
|
||||
outDepPath = _outDepPath;
|
||||
text = _text;
|
||||
error = errorInit;
|
||||
includesAdded = 0;
|
||||
style = -1;
|
||||
lvl = 0;
|
||||
}
|
||||
|
||||
int error;
|
||||
std::string fileName;
|
||||
std::string options;
|
||||
std::string errPath;
|
||||
std::string outPath;
|
||||
std::string outDepPath;
|
||||
std::string text;
|
||||
int style; // -1 unk, 0 fixed, 1 fixed ext, 2 free
|
||||
int includesAdded;
|
||||
std::set<std::string> includes;
|
||||
int lvl;
|
||||
};
|
||||
|
||||
std::string convertStyle(const FileInfo* file, bool needRewrite = true);
|
||||
std::map<std::string, DIST::Array*> sortArraysByName(const std::set<DIST::Array*>& toSort);
|
||||
bool createDirectory(const std::string& name);
|
||||
bool createDirectory(const std::string& name);
|
||||
std::vector<std::string> splitAndArgvCreate(const std::string& options);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_SPF "2255"
|
||||
#pragma once
|
||||
|
||||
#define VERSION_SPF "2285"
|
||||
|
||||
@@ -150,6 +150,7 @@ void fillUseStatement(SgStatement *st, set<string> &useMod,
|
||||
{
|
||||
SgExpression *ex = st->expr(0);
|
||||
string modName = st->symbol()->identifier();
|
||||
convertToLower(modName);
|
||||
useMod.insert(modName);
|
||||
|
||||
if (ex)
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "../Distribution/CreateDistributionDirs.h"
|
||||
#include "../LoopAnalyzer/loop_analyzer.h"
|
||||
#include "../DirectiveProcessing/insert_directive.h"
|
||||
#include "../ProjectManipulation/PerfAnalyzer.h"
|
||||
|
||||
#include "BuildGraph.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -151,6 +153,9 @@ static void setOptions(const short* options, bool isBuildParallel = false, const
|
||||
staticShadowAnalysis = intOptions[STATIC_SHADOW_ANALYSIS];
|
||||
staticPrivateAnalysis = intOptions[STATIC_PRIVATE_ANALYSIS];
|
||||
out_free_form = intOptions[FREE_FORM];
|
||||
if (out_free_form == 1)
|
||||
out_line_unlimit = 1;
|
||||
|
||||
if (isBuildParallel)
|
||||
keepSpfDirs = intOptions[KEEP_SPF_DIRECTIVES];
|
||||
else
|
||||
@@ -180,7 +185,10 @@ static void setOptions(const short* options, bool isBuildParallel = false, const
|
||||
else if (elem == STATIC_PRIVATE_ANALYSIS)
|
||||
staticPrivateAnalysis = 0;
|
||||
else if (elem == FREE_FORM)
|
||||
{
|
||||
out_free_form = 0;
|
||||
out_line_unlimit = 0;
|
||||
}
|
||||
else if (elem == KEEP_DVM_DIRECTIVES)
|
||||
keepDvmDirectives = 0;
|
||||
else if (elem == KEEP_SPF_DIRECTIVES)
|
||||
@@ -1560,7 +1568,7 @@ int SPF_GetFileLineInfo(void*& context, int winHandler, short *options, short *p
|
||||
return retSize;
|
||||
}
|
||||
|
||||
extern map<string, int> keyValueFromGUI;
|
||||
extern map<string, int> distrStateFromGUI;
|
||||
int SPF_SetDistributionFlagToArray(void*& context, char *key, int flag)
|
||||
{
|
||||
MessageManager::clearCache();
|
||||
@@ -1589,7 +1597,7 @@ int SPF_SetDistributionFlagToArray(void*& context, char *key, int flag)
|
||||
}
|
||||
}
|
||||
else
|
||||
keyValueFromGUI[keyStr] = flag;
|
||||
distrStateFromGUI[keyStr] = flag;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -1654,7 +1662,7 @@ int SPF_SetDistributionFlagToArrays(void*& context, const char* keys, const char
|
||||
int flagI = -1;
|
||||
if (sscanf(flagsS[z].c_str(), "%d", &flagI) == -1)
|
||||
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
||||
keyValueFromGUI[keysS[z]] = flagI;
|
||||
distrStateFromGUI[keysS[z]] = flagI;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1887,6 +1895,22 @@ int SPF_SharedMemoryParallelization(void*& context, int winHandler, short* optio
|
||||
return simpleTransformPass(INSERT_PARALLEL_DIRS_NODIST, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
|
||||
}
|
||||
|
||||
int SPF_InsertPrivateFromGUI(void*& context, int winHandler, short* options, short* projName, short* folderName, short*& output,
|
||||
int*& outputSize, short*& outputMessage, int*& outputMessageSize)
|
||||
{
|
||||
MessageManager::clearCache();
|
||||
MessageManager::setWinHandler(winHandler);
|
||||
return simpleTransformPass(INSERT_NO_DISTR_FLAGS_FROM_GUI, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
|
||||
}
|
||||
|
||||
int SPF_RemoveDeadCode(void*& context, int winHandler, short* options, short* projName, short* folderName, short*& output,
|
||||
int*& outputSize, short*& outputMessage, int*& outputMessageSize)
|
||||
{
|
||||
MessageManager::clearCache();
|
||||
MessageManager::setWinHandler(winHandler);
|
||||
return simpleTransformPass(REMOVE_DEAD_CODE_AND_UNPARSE, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
|
||||
}
|
||||
|
||||
static inline void convertBackSlash(char *str, int strL)
|
||||
{
|
||||
for (int z = 0; z < strL; ++z)
|
||||
@@ -2597,6 +2621,10 @@ const wstring Sapfor_RunTransformation(const char* transformName_c, const char*
|
||||
retCode = SPF_ResolveCommonBlockConflicts(context, winHandler, optSh, projSh, fold, output, outputSize, outputMessage, outputMessageSize);
|
||||
else if (whichRun == "SPF_SharedMemoryParallelization")
|
||||
retCode = SPF_SharedMemoryParallelization(context, winHandler, optSh, projSh, fold, output, outputSize, outputMessage, outputMessageSize);
|
||||
else if (whichRun == "SPF_InsertPrivateFromGUI")
|
||||
retCode = SPF_InsertPrivateFromGUI(context, winHandler, optSh, projSh, fold, output, outputSize, outputMessage, outputMessageSize);
|
||||
else if (whichRun == "SPF_RemoveDeadCode")
|
||||
retCode = SPF_RemoveDeadCode(context, winHandler, optSh, projSh, fold, output, outputSize, outputMessage, outputMessageSize);
|
||||
else
|
||||
{
|
||||
if (showDebug)
|
||||
|
||||
Reference in New Issue
Block a user