Files
SAPFOR/src/Utils/PassManager.h
2025-07-09 14:46:37 +03:00

347 lines
15 KiB
C++

#pragma once
#include <map>
#include <set>
#include <vector>
#include "../Sapfor.h"
using std::vector;
using std::map;
using std::set;
#define list vector<Pass>
static map<passes, vector<passes>> *passDeps;
static map<passes, set<passes>> passRemovals;
class Pass
{
private:
passes name;
public:
const Pass& operator<=(const Pass &right) const
{
if ((*passDeps).find(right.name) == (*passDeps).end())
(*passDeps)[right.name] = vector<passes>();
(*passDeps)[right.name].push_back(this->name);
return right;
}
Pass& operator<=(Pass &right) const
{
if ((*passDeps).find(right.name) == (*passDeps).end())
(*passDeps)[right.name] = vector<passes>();
(*passDeps)[right.name].push_back(this->name);
return right;
}
const list& operator<=(const list &right_vec) const
{
for (int i = 0; i < right_vec.size(); ++i)
{
if ((*passDeps).find(right_vec[i].name) == (*passDeps).end())
(*passDeps)[right_vec[i].name] = vector<passes>();
(*passDeps)[right_vec[i].name].push_back(this->name);
}
return right_vec;
}
friend const Pass& operator<=(const list &left_vec, const Pass &right)
{
if ((*passDeps).find(right.name) == (*passDeps).end())
(*passDeps)[right.name] = vector<passes>();
for (int i = 0; i < left_vec.size(); ++i)
(*passDeps)[right.name].push_back(left_vec[i].name);
return right;
}
friend const list& operator<=(const list &left_vec, const list &right_vec)
{
for (int k = 0; k < right_vec.size(); ++k)
{
if ((*passDeps).find(right_vec[k].name) == (*passDeps).end())
(*passDeps)[right_vec[k].name] = vector<passes>();
for (int i = 0; i < left_vec.size(); ++i)
(*passDeps)[right_vec[k].name].push_back(left_vec[i].name);
}
return right_vec;
}
friend void operator-=(const list& left_vec, const list& right_vec)
{
/* erase each pass in right_vec from dependency tree for each pass in left_vec */
for(const auto& left : left_vec)
{
auto& eraseFrom = passRemovals[left.name];
for(const auto& right : right_vec)
eraseFrom.insert(right.name);
}
}
friend void operator-=(const list& left_vec, const Pass& right)
{
left_vec -= list({right});
}
void operator-=(const list& right_vec) const
{
list({ *this }) -= right_vec;
}
void operator-=(const Pass& right) const
{
list({ *this }) -= list({ right });
}
void applyRemovals()
{
map<passes, set<passes>> to_process, processed;
to_process[name] = {};
while (!to_process.empty())
{
map<passes, set<passes>> to_process_next;
for (const auto& pass : to_process)
{
auto processed_it = processed.find(pass.first);
auto& done_removals = processed_it != processed.end() ? processed_it->second : processed[pass.first];
set<passes> removals_to_do;
bool process_pass = false;
if (processed_it == processed.end())
{
removals_to_do = done_removals = pass.second;
process_pass = true;
}
else
{
const auto& needed_removals = pass.second;
set_difference(needed_removals.begin(), needed_removals.end(), done_removals.begin(), done_removals.end(),
inserter(removals_to_do, removals_to_do.begin()));
process_pass = needed_removals.size() != 0;
done_removals.insert(removals_to_do.begin(), removals_to_do.end());
}
if (process_pass)
{
processed[pass.first] = pass.second;
auto removals_it = passRemovals.find(pass.first);
if (removals_it != passRemovals.end())
{
auto& removals_saved = removals_it->second;
set<passes> add;
set_difference(removals_saved.begin(), removals_saved.end(), done_removals.begin(), done_removals.end(),
inserter(add, add.begin()));
done_removals.insert(add.begin(), add.end());
removals_to_do.insert(add.begin(), add.end());
}
auto deps_it = passDeps->find(pass.first);
if (deps_it != passDeps->end())
{
auto& deps = deps_it->second;
for (auto dep_it = deps.begin(); dep_it != deps.end();)
{
if (removals_to_do.find(*dep_it) == removals_to_do.end())
to_process_next[*(dep_it++)].insert(removals_to_do.begin(), removals_to_do.end());
else
dep_it = deps.erase(dep_it);
}
}
}
}
to_process = to_process_next;
}
}
Pass(passes name) : name(name) { }
};
static void depsToGraphViz(const map<passes, vector<passes>> &passDepsIn)
{
FILE *file = fopen("pass_tree.txt", "w");
if (!file)
printf("ERROR in creating 'pass_tree.txt' file\n");
else
{
fprintf(file, "digraph G {");
for (auto it = passDepsIn.begin(); it != passDepsIn.end(); ++it)
{
for (int k = 0; k < it->second.size(); ++k)
fprintf(file, "\"%s\" -> \"%s\";\n", passNames[it->first], passNames[it->second[k]]);
}
fprintf(file, "}\n");
fclose(file);
printf("write to 'pass_tree.txt' file complited\n");
}
}
void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes> &passesIgnoreStateDone, bool printTree = false)
{
passDepsIn.clear();
passDeps = &passDepsIn;
Pass(PREPROC_SPF) <= Pass(CREATE_INTER_TREE);
list({ CREATE_INTER_TREE, CORRECT_VAR_DECL }) <= list({ GCOV_PARSER, PREDICT_SCHEME, INSERT_INTER_TREE });
list({ FILE_LINE_INFO, BUILD_INCLUDE_DEPENDENCIES }) <= Pass(CORRECT_VAR_DECL);
Pass(DEF_USE_STAGE1) <= Pass(DEF_USE_STAGE2);
list({ VERIFY_DVM_DIRS, PRIVATE_CALL_GRAPH_STAGE1, PRIVATE_CALL_GRAPH_STAGE2, MACRO_EXPANSION, CONVERT_ASSIGN_TO_LOOP, DEF_USE_STAGE1, DEF_USE_STAGE2, FILL_PARALLEL_REG_IR, VERIFY_COMMON, FILL_COMMON_BLOCKS, CALL_GRAPH_IR }) <= list({ SUBST_EXPR, SUBST_EXPR_RD, BUILD_IR });
Pass(BUILD_IR) <= Pass(SUBST_EXPR) <= Pass(SUBST_EXPR_AND_UNPARSE);
Pass(BUILD_IR) <= Pass(SUBST_EXPR_RD) <= Pass(SUBST_EXPR_RD_AND_UNPARSE);
list({BUILD_IR, CALL_GRAPH2}) <= Pass(SWAP_OPERATORS);
list({ LOOP_ANALYZER_DATA_DIST_S1, SUBST_EXPR_RD } ) <= Pass(PRIVATE_REMOVING_ANALYSIS);
list({ PRIVATE_REMOVING_ANALYSIS, REVERT_SUBST_EXPR_RD }) <= Pass(PRIVATE_REMOVING);
Pass(RESTORE_LOOP_FROM_ASSIGN) <= list({ SUBST_EXPR_AND_UNPARSE, SUBST_EXPR_RD_AND_UNPARSE });
Pass(GET_ALL_ARRAY_DECL) <= list({ CALL_GRAPH_IR, INSERT_NO_DISTR_FLAGS_FROM_GUI });
Pass(LOOP_GRAPH) <= Pass(PRIVATE_CALL_GRAPH_STAGE3) <= list(FIND_FUNC_TO_INCLUDE, PRIVATE_ANALYSIS_IR) <= list({ LOOP_ANALYZER_DATA_DIST_S0, LOOP_ANALYZER_DATA_DIST_S1, ONLY_ARRAY_GRAPH, LOOP_ANALYZER_ALIGNS });
Pass(PRIVATE_ANALYSIS_IR) <= Pass(LOOP_ANALYZER_NODIST);
Pass(CORRECT_VAR_DECL) <= list({ VERIFY_DVM_DIRS, VERIFY_OPERATORS, VERIFY_FORMAT, VERIFY_ENDDO, PREPROC_SPF, VERIFY_INCLUDES, PREPROC_ALLOCATES, CHECK_FUNC_TO_INCLUDE, FILL_PAR_REGIONS_LINES, CONVERT_ASSIGN_TO_LOOP, VERIFY_COMMON, VERIFY_EQUIVALENCE, PRINT_PAR_REGIONS_ERRORS }) <= Pass(CODE_CHECKER_PASSES);
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_SPF, PREPROC_ALLOCATES, GET_ALL_ARRAY_DECL, GCOV_PARSER }) <= list({ CALL_GRAPH, MACRO_EXPANSION, DEF_USE_STAGE1 });
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_INCLUDES, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ GET_ALL_ARRAY_DECL, FILL_COMMON_BLOCKS, PARSE_OMP_DIRS }) <= Pass(PREPROC_SPF);
Pass(CHECK_PAR_REG_DIR) <= Pass(FILL_PARALLEL_REG_IR);
list({ CODE_CHECKER_PASSES, GET_ALL_ARRAY_DECL, CALL_GRAPH2, SUBST_EXPR_RD, ARRAY_ACCESS_ANALYSIS_FOR_CORNER }) <= list({ LOOP_ANALYZER_NODIST, LOOP_ANALYZER_DATA_DIST_S0, LOOP_ANALYZER_DATA_DIST_S1, ONLY_ARRAY_GRAPH });
list({ LOOP_ANALYZER_NODIST, REMOVE_OMP_DIRS }) <= Pass(INSERT_PARALLEL_DIRS_NODIST);
Pass(CHECK_ARGS_DECL) <= Pass(CREATE_TEMPLATE_LINKS);
Pass(LOOP_ANALYZER_DATA_DIST_S0) <= Pass(LOOP_ANALYZER_DATA_DIST_S1) <= Pass(LOOP_ANALYZER_DATA_DIST_S2) <= Pass(CREATE_TEMPLATE_LINKS) <= Pass(LOOP_ANALYZER_COMP_DIST);
list({ VERIFY_OPERATORS, VERIFY_ENDDO, VERIFY_FORMAT, SUBST_EXPR_RD, CONVERT_ASSIGN_TO_LOOP }) <= Pass(LOOP_GRAPH) <= Pass(CALL_GRAPH) <= Pass(CALL_GRAPH2);
Pass(MACRO_EXPANSION) <= Pass(CALL_GRAPH);
list({ PREPROC_SPF, PROCESS_IO, CALL_GRAPH2, CONVERT_SAVE_TO_MODULE, REVERT_SUBST_EXPR_RD }) <= Pass(CREATE_CHECKPOINTS);
Pass(FILL_PAR_REGIONS_LINES) <= Pass(VERIFY_EQUIVALENCE);
Pass(LOOP_ANALYZER_DATA_DIST_S2) <= Pass(CREATE_NESTED_LOOPS);
list({ CORRECT_VAR_DECL, PREPROC_SPF }) <= list({ LOOP_GRAPH, CALL_GRAPH, CALL_GRAPH2 });
list({ PREPROC_SPF, CALL_GRAPH2 }) <= Pass(FILL_PAR_REGIONS_LINES) <= list({ EXPAND_EXTRACT_PAR_REGION, CHECK_FUNC_TO_INCLUDE, FIND_FUNC_TO_INCLUDE, CHECK_ARGS_DECL });
list({ PREPROC_SPF, CALL_GRAPH2, FILL_PAR_REGIONS_LINES }) <= Pass(FILL_PAR_REGIONS) <= Pass(RESOLVE_PAR_REGIONS);
list({ REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN }) <= Pass(RESOLVE_PAR_REGIONS);
list({ FILL_PAR_REGIONS, REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN }) <= Pass(REMOVE_DIST_ARRAYS_FROM_IO);
Pass(REVERT_SUBST_EXPR_RD) <= Pass(EXPAND_EXTRACT_PAR_REGION);
Pass(FILL_PAR_REGIONS) <= Pass(PRINT_PAR_REGIONS_ERRORS);
list({ PREPROC_SPF, CORRECT_VAR_DECL }) <= Pass(FILL_PAR_REGIONS_LINES);
list({ LOOP_ANALYZER_COMP_DIST, REMOVE_OMP_DIRS }) <= list({ CREATE_DISTR_DIRS, CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS });
Pass(CALL_GRAPH2) <= list({ ONLY_ARRAY_GRAPH, CREATE_NESTED_LOOPS, FIND_FUNC_TO_INCLUDE, CHECK_FUNC_TO_INCLUDE, FIND_PARAMETERS, GET_STATS_FOR_PREDICTOR });
Pass(CALL_GRAPH2) <= list({ PURE_SAVE_TO_PARAMS, PURE_MODULE_TO_PARAMS, PURE_COMMON_TO_PARAMS, PURE_INTENT_INSERT });
Pass(REVERT_SUBST_EXPR_RD) <= list({ PURE_SAVE_TO_PARAMS, PURE_MODULE_TO_PARAMS, PURE_COMMON_TO_PARAMS, PURE_INTENT_INSERT });
list({ CORRECT_VAR_DECL, REVERT_SUBST_EXPR_RD, VERIFY_INCLUDES }) <= list({ CONVERT_TO_ENDDO, CORRECT_CODE_STYLE, REMOVE_DVM_DIRS, REMOVE_DVM_DIRS_TO_COMMENTS, REMOVE_SPF_DIRS, REMOVE_DVM_INTERVALS });
list({ CALL_GRAPH2, CONVERT_LOOP_TO_ASSIGN, REVERT_SUBST_EXPR_RD, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(INLINE_PROCEDURES);
list({ CONVERT_LOOP_TO_ASSIGN, CORRECT_FORMAT_PLACE }) <= list({ CONVERT_TO_ENDDO, CORRECT_CODE_STYLE, INSERT_INCLUDES, REMOVE_DVM_DIRS, REMOVE_DVM_DIRS_TO_COMMENTS, REMOVE_SPF_DIRS, REMOVE_DVM_INTERVALS });
list({ CORRECT_VAR_DECL, REVERT_SUBST_EXPR_RD }) <= list({ INSERT_INCLUDES, UNPARSE_FILE, SET_TO_ALL_DECL_INIT_ZERO });
Pass(CALL_GRAPH2) <= Pass(PRIVATE_ARRAYS_SHRINKING_ANALYSIS) <= Pass(PRIVATE_ARRAYS_SHRINKING);
list({ CALL_GRAPH2, LOOP_ANALYZER_ALIGNS, REVERT_SUBST_EXPR_RD }) <= list({ PRIVATE_ARRAYS_EXPANSION, PRIVATE_ARRAYS_SHRINKING });
list({ GCOV_PARSER, CREATE_INTER_TREE, CALL_GRAPH, CALL_GRAPH2 }) <= Pass(CREATE_PARALLEL_REGIONS);
list({ PRIVATE_CALL_GRAPH_STAGE1, PRIVATE_CALL_GRAPH_STAGE2, MACRO_EXPANSION, CONVERT_ASSIGN_TO_LOOP, DEF_USE_STAGE1, DEF_USE_STAGE2, LOOP_GRAPH, CALL_GRAPH, PRIVATE_ANALYSIS_IR, FIND_FUNC_TO_INCLUDE }) <= Pass(INSERT_REGIONS);
list({ LOOP_ANALYZER_DATA_DIST_S1, REVERT_SUBST_EXPR_RD }) <= list({ LOOPS_SPLITTER, LOOPS_COMBINER, UNROLL_LOOPS, INSERT_REGIONS });
list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= list({ DUPLICATE_FUNCTIONS, REMOVE_UNUSED_FUNCTIONS });
list({ CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= list({ LOOPS_SPLITTER, LOOPS_COMBINER, PRIVATE_ARRAYS_EXPANSION, PRIVATE_ARRAYS_SHRINKING, CREATE_PARALLEL_REGIONS, PURE_SAVE_TO_PARAMS, PURE_MODULE_TO_PARAMS, PURE_COMMON_TO_PARAMS, PURE_INTENT_INSERT, PRIVATE_REMOVING });
list({ GET_ALL_ARRAY_DECL, FILL_PARALLEL_REG_IR }) <= Pass(CONVERT_ASSIGN_TO_LOOP);
list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(RENAME_SYMBOLS);
list({ BUILD_IR, CALL_GRAPH }) <= Pass(LIVE_ANALYSIS_IR);
list({ BUILD_IR, LOOP_GRAPH, LIVE_ANALYSIS_IR }) <= Pass(PRIVATE_ANALYSIS_IR);
Pass(FILE_LINE_INFO) <= Pass(GET_MIN_MAX_BLOCK_DIST);
Pass(CALL_GRAPH2) <= Pass(FIX_COMMON_BLOCKS);
Pass(REMOVE_OMP_DIRS) <= Pass(REMOVE_OMP_DIRS_TRANSFORM);
Pass(VERIFY_INCLUDES) <= Pass(RENAME_INLCUDES);
list({ CALL_GRAPH2, REVERT_SUBST_EXPR_RD }) <= Pass(REMOVE_DEAD_CODE);
list({ REMOVE_DEAD_CODE, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);
list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE);
list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS);
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,
RESTORE_LOOP_FROM_ASSIGN, RESTORE_LOOP_FROM_ASSIGN_BACK, INSERT_REGIONS, REMOVE_COPIES, RESTORE_COPIES, SHADOW_GROUPING,
SWAP_LOOPS, RESTORE_SWAP_LOOPS, TEST_PASS, GROUP_ACTUAL_AND_REMOTE, GROUP_ACTUAL_AND_REMOTE_RESTORE, ADD_TEMPL_TO_USE_ONLY });
//only for print
if (printTree)
{
list({ CREATE_PARALLEL_DIRS, PRIVATE_ANALYSIS_IR, CREATE_REMOTES, REVERT_SUBST_EXPR_RD, UNPARSE_FILE, EXTRACT_PARALLEL_DIRS }) <= Pass(INSERT_PARALLEL_DIRS);
depsToGraphViz(passDepsIn);
exit(0);
}
}
void removalsFromPassesDependencies(map<passes, vector<passes>>& passDepsIn, const int curr_regime)
{
passDeps = &passDepsIn;
list({ INSERT_PARALLEL_DIRS_NODIST, LOOP_ANALYZER_NODIST }) -= list({ FIND_FUNC_TO_INCLUDE, CHECK_FUNC_TO_INCLUDE });
Pass(passes(curr_regime)).applyRemovals();
}
#undef list