#pragma once #include #include #include #include "../Sapfor.h" using std::vector; using std::map; using std::set; #define list vector static map> *passDeps; static map> 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(); (*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(); (*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(); (*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(); 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(); 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> to_process, processed; to_process[name] = {}; while (!to_process.empty()) { map> 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 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 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> &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> &passDepsIn, set &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({ 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({ REVERT_SUBST_EXPR_RD, CONVERT_LOOP_TO_ASSIGN, FILL_PAR_REGIONS}) <= 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); 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); 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>& 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