Merge branch 'master' into CP_blocks_insert

This commit is contained in:
2024-04-16 14:36:19 +00:00
85 changed files with 6931 additions and 5459 deletions

View File

@@ -55,47 +55,47 @@ include_directories(${zlib_sources}/include)
include_directories(${pppa_sources})
set(PR_PARAM _src/ProjectParameters/projectParameters.cpp
_src/ProjectParameters/projectParameters.h)
_src/ProjectParameters/projectParameters.h)
set(GR_LAYOUT _src/VisualizerCalls/graphLayout/algebra.cpp
_src/VisualizerCalls/graphLayout/algebra.hpp
_src/VisualizerCalls/graphLayout/fruchterman_reingold.cpp
_src/VisualizerCalls/graphLayout/fruchterman_reingold.hpp
_src/VisualizerCalls/graphLayout/kamada_kawai.cpp
_src/VisualizerCalls/graphLayout/kamada_kawai.hpp
_src/VisualizerCalls/graphLayout/layout.cpp
_src/VisualizerCalls/graphLayout/layout.hpp
_src/VisualizerCalls/graphLayout/nodesoup.cpp
_src/VisualizerCalls/graphLayout/nodesoup.hpp)
_src/VisualizerCalls/graphLayout/algebra.hpp
_src/VisualizerCalls/graphLayout/fruchterman_reingold.cpp
_src/VisualizerCalls/graphLayout/fruchterman_reingold.hpp
_src/VisualizerCalls/graphLayout/kamada_kawai.cpp
_src/VisualizerCalls/graphLayout/kamada_kawai.hpp
_src/VisualizerCalls/graphLayout/layout.cpp
_src/VisualizerCalls/graphLayout/layout.hpp
_src/VisualizerCalls/graphLayout/nodesoup.cpp
_src/VisualizerCalls/graphLayout/nodesoup.hpp)
set(VS_CALLS _src/VisualizerCalls/get_information.cpp
_src/VisualizerCalls/get_information.h
_src/VisualizerCalls/SendMessage.cpp
_src/VisualizerCalls/SendMessage.h
_src/VisualizerCalls/BuildGraph.cpp
_src/VisualizerCalls/BuildGraph.h)
_src/VisualizerCalls/get_information.h
_src/VisualizerCalls/SendMessage.cpp
_src/VisualizerCalls/SendMessage.h
_src/VisualizerCalls/BuildGraph.cpp
_src/VisualizerCalls/BuildGraph.h)
set(VERIF _src/VerificationCode/CorrectVarDecl.cpp
_src/VerificationCode/IncludeChecker.cpp
_src/VerificationCode/StructureChecker.cpp
_src/VerificationCode/VerifySageStructures.cpp
_src/VerificationCode/verifications.h)
_src/VerificationCode/verifications.h)
set(UTILS _src/Utils/AstWrapper.h
_src/Utils/BoostStackTrace.cpp
_src/Utils/CommonBlock.h
_src/Utils/DefUseList.h
_src/Utils/errors.h
_src/Utils/leak_detector.h
_src/Utils/RationalNum.cpp
_src/Utils/RationalNum.h
_src/Utils/BoostStackTrace.cpp
_src/Utils/CommonBlock.h
_src/Utils/DefUseList.h
_src/Utils/errors.h
_src/Utils/leak_detector.h
_src/Utils/RationalNum.cpp
_src/Utils/RationalNum.h
_src/Utils/SgUtils.cpp
_src/Utils/SgUtils.h
_src/Utils/SgUtils.h
_src/Utils/types.h
_src/Utils/utils.cpp
_src/Utils/utils.h
_src/Utils/version.h)
_src/Utils/utils.h
_src/Utils/version.h)
set(OMEGA _src/SageAnalysisTool/OmegaForSage/add-assert.cpp
_src/SageAnalysisTool/OmegaForSage/affine.cpp
_src/SageAnalysisTool/OmegaForSage/cover.cpp
@@ -126,207 +126,212 @@ set(OMEGA _src/SageAnalysisTool/OmegaForSage/add-assert.cpp
_src/SageAnalysisTool/set.cpp)
set(PRIV _src/PrivateAnalyzer/private_analyzer.cpp
_src/PrivateAnalyzer/private_analyzer.h)
_src/PrivateAnalyzer/private_analyzer.h)
set(FDVM ${fdvm_sources}/acc.cpp
${fdvm_sources}/acc_across.cpp
${fdvm_sources}/acc_across_analyzer.cpp
${fdvm_sources}/acc_analyzer.cpp
${fdvm_sources}/acc_across.cpp
${fdvm_sources}/acc_across_analyzer.cpp
${fdvm_sources}/acc_analyzer.cpp
${fdvm_sources}/acc_data.cpp
${fdvm_sources}/acc_f2c.cpp
${fdvm_sources}/acc_f2c_handlers.cpp
${fdvm_sources}/acc_rtc.cpp
${fdvm_sources}/acc_rtc.cpp
${fdvm_sources}/acc_f2c.cpp
${fdvm_sources}/acc_f2c_handlers.cpp
${fdvm_sources}/acc_rtc.cpp
${fdvm_sources}/acc_rtc.cpp
${fdvm_sources}/acc_utilities.cpp
${fdvm_sources}/aks_analyzeLoops.cpp
${fdvm_sources}/aks_structs.cpp
${fdvm_sources}/checkpoint.cpp
${fdvm_sources}/debug.cpp
${fdvm_sources}/dvm.cpp
${fdvm_sources}/aks_analyzeLoops.cpp
${fdvm_sources}/aks_structs.cpp
${fdvm_sources}/checkpoint.cpp
${fdvm_sources}/debug.cpp
${fdvm_sources}/dvm.cpp
${fdvm_sources}/calls.cpp
${fdvm_sources}/funcall.cpp
${fdvm_sources}/help.cpp
${fdvm_sources}/hpf.cpp
${fdvm_sources}/io.cpp
${fdvm_sources}/omp.cpp
${fdvm_sources}/ompdebug.cpp
${fdvm_sources}/parloop.cpp
${fdvm_sources}/stmt.cpp)
${fdvm_sources}/funcall.cpp
${fdvm_sources}/help.cpp
${fdvm_sources}/hpf.cpp
${fdvm_sources}/io.cpp
${fdvm_sources}/omp.cpp
${fdvm_sources}/ompdebug.cpp
${fdvm_sources}/parloop.cpp
${fdvm_sources}/stmt.cpp)
set(PARALLEL_REG _src/ParallelizationRegions/ParRegions.cpp
_src/ParallelizationRegions/ParRegions.h
_src/ParallelizationRegions/ParRegions_func.h
_src/ParallelizationRegions/expand_extract_reg.cpp
_src/ParallelizationRegions/expand_extract_reg.h
_src/ParallelizationRegions/resolve_par_reg_conflicts.cpp
_src/ParallelizationRegions/resolve_par_reg_conflicts.h)
_src/ParallelizationRegions/ParRegions.h
_src/ParallelizationRegions/ParRegions_func.h
_src/ParallelizationRegions/expand_extract_reg.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)
_src/Transformations/dead_code.h)
set(TR_CP _src/Transformations/checkpoints.cpp
_src/Transformations/checkpoints.h)
_src/Transformations/checkpoints.h)
set(TR_VECTOR _src/Transformations/array_assign_to_loop.cpp
_src/Transformations/array_assign_to_loop.h)
_src/Transformations/array_assign_to_loop.h)
set(TR_ENDDO_LOOP _src/Transformations/enddo_loop_converter.cpp
_src/Transformations/enddo_loop_converter.h)
_src/Transformations/enddo_loop_converter.h)
set(TR_LOOP_NEST _src/Transformations/loop_transform.cpp
_src/Transformations/loop_transform.h)
_src/Transformations/loop_transform.h)
set(TR_LOOP_COMB _src/Transformations/loops_combiner.cpp
_src/Transformations/loops_combiner.h)
_src/Transformations/loops_combiner.h)
set(TR_LOOP_SPLIT _src/Transformations/loops_splitter.cpp
_src/Transformations/loops_splitter.h)
_src/Transformations/loops_splitter.h)
set(TR_LOOP_UNROLL _src/Transformations/loops_unrolling.cpp
_src/Transformations/loops_unrolling.h)
_src/Transformations/loops_unrolling.h)
set(TR_PRIV_BR _src/Transformations/private_arrays_resizing.cpp
_src/Transformations/private_arrays_resizing.h)
set(TR_PRIV_DEL _src/Transformations/private_removing.cpp
_src/Transformations/private_removing.h)
set(TR_SWAP_ARR_DIMS _src/Transformations/swap_array_dims.cpp
_src/Transformations/swap_array_dims.h)
_src/Transformations/swap_array_dims.h)
set(TR_FUNC_DUP _src/Transformations/uniq_call_chain_dup.cpp
_src/Transformations/uniq_call_chain_dup.h)
_src/Transformations/uniq_call_chain_dup.h)
set(TR_FUNC_PURE _src/Transformations/function_purifying.cpp
_src/Transformations/function_purifying.h)
_src/Transformations/function_purifying.h)
set(TR_GV _src/Transformations/fix_common_blocks.cpp
_src/Transformations/fix_common_blocks.h)
_src/Transformations/fix_common_blocks.h)
set(TR_CONV _src/Transformations/convert_to_c.cpp
_src/Transformations/convert_to_c.h)
_src/Transformations/convert_to_c.h)
set(TR_IMPLICIT_NONE _src/Transformations/set_implicit_none.cpp
_src/Transformations/set_implicit_none.h)
set(TRANSFORMS
${TR_DEAD_CODE}
${TR_DEAD_CODE}
${TR_CP}
${TR_VECTOR}
${TR_ENDDO_LOOP}
${TR_LOOP_NEST}
${TR_LOOP_COMB}
${TR_LOOP_SPLIT}
${TR_PRIV_BR}
${TR_SWAP_ARR_DIMS}
${TR_FUNC_DUP}
${TR_FUNC_PURE}
${TR_LOOP_UNROLL}
${TR_GV}
${TR_PRIV_DEL}
${TR_CONV})
${TR_VECTOR}
${TR_ENDDO_LOOP}
${TR_LOOP_NEST}
${TR_LOOP_COMB}
${TR_LOOP_SPLIT}
${TR_PRIV_BR}
${TR_SWAP_ARR_DIMS}
${TR_FUNC_DUP}
${TR_FUNC_PURE}
${TR_LOOP_UNROLL}
${TR_GV}
${TR_PRIV_DEL}
${TR_CONV}
${TR_PRIV_DEL}
${TR_IMPLICIT_NONE})
set(CFG _src/CFGraph/IR.cpp
_src/CFGraph/IR.h
_src/CFGraph/CFGraph.cpp
_src/CFGraph/CFGraph.h
_src/CFGraph/RD_subst.cpp
_src/CFGraph/RD_subst.h
_src/CFGraph/live_variable_analysis.cpp
_src/CFGraph/live_variable_analysis.h
_src/CFGraph/private_variables_analysis.cpp
_src/CFGraph/private_variables_analysis.h
)
_src/CFGraph/IR.h
_src/CFGraph/CFGraph.cpp
_src/CFGraph/CFGraph.h
_src/CFGraph/RD_subst.cpp
_src/CFGraph/RD_subst.h
_src/CFGraph/live_variable_analysis.cpp
_src/CFGraph/live_variable_analysis.h
_src/CFGraph/private_variables_analysis.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
)
_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)
set(CREATE_INTER_T _src/CreateInterTree/CreateInterTree.cpp
_src/CreateInterTree/CreateInterTree.h)
set(DIRA _src/DirectiveProcessing/DirectiveAnalyzer.cpp
_src/DirectiveProcessing/DirectiveAnalyzer.h
_src/DirectiveProcessing/directive_creator.cpp
_src/DirectiveProcessing/directive_creator_base.cpp
_src/DirectiveProcessing/directive_creator.h
_src/DirectiveProcessing/directive_creator_base_nodist.cpp
_src/DirectiveProcessing/directive_creator_nodist.h
_src/DirectiveProcessing/directive_creator_internal.h
_src/DirectiveProcessing/directive_parser.cpp
_src/DirectiveProcessing/directive_parser.h
set(DIRA _src/DirectiveProcessing/directive_analyzer.cpp
_src/DirectiveProcessing/directive_analyzer.h
_src/DirectiveProcessing/directive_creator.cpp
_src/DirectiveProcessing/directive_creator_base.cpp
_src/DirectiveProcessing/directive_creator.h
_src/DirectiveProcessing/directive_creator_base_nodist.cpp
_src/DirectiveProcessing/directive_creator_nodist.h
_src/DirectiveProcessing/directive_parser.cpp
_src/DirectiveProcessing/directive_parser.h
_src/DirectiveProcessing/directive_omp_parser.cpp
_src/DirectiveProcessing/directive_omp_parser.h
_src/DirectiveProcessing/insert_directive.cpp
_src/DirectiveProcessing/insert_directive.h
_src/DirectiveProcessing/remote_access.cpp
_src/DirectiveProcessing/remote_access_base.cpp
_src/DirectiveProcessing/remote_access.h
_src/DirectiveProcessing/shadow.cpp
_src/DirectiveProcessing/shadow.h
_src/DirectiveProcessing/spf_directive_preproc.cpp)
_src/DirectiveProcessing/insert_directive.h
_src/DirectiveProcessing/remote_access.cpp
_src/DirectiveProcessing/remote_access_base.cpp
_src/DirectiveProcessing/remote_access.h
_src/DirectiveProcessing/shadow.cpp
_src/DirectiveProcessing/shadow.h
_src/DirectiveProcessing/spf_directive_preproc.cpp)
set(DISTR _src/Distribution/Array.cpp
_src/Distribution/Array.h
_src/Distribution/Arrays.h
_src/Distribution/CreateDistributionDirs.cpp
_src/Distribution/CreateDistributionDirs.h
_src/Distribution/CreateDistributionDirs.h
_src/Distribution/Cycle.cpp
_src/Distribution/Cycle.h
_src/Distribution/Cycle.h
_src/Distribution/Distribution.cpp
_src/Distribution/Distribution.h
_src/Distribution/Distribution.h
_src/Distribution/DvmhDirective.cpp
_src/Distribution/DvmhDirective.h
_src/Distribution/DvmhDirective_nodist.cpp
_src/Distribution/DvmhDirective_internal.h
_src/Distribution/DvmhDirective_func.h
_src/Distribution/DvmhDirective.h
_src/Distribution/DvmhDirective_nodist.cpp
_src/Distribution/DvmhDirective_internal.h
_src/Distribution/DvmhDirective_func.h
_src/Distribution/DvmhDirectiveBase.cpp
_src/Distribution/DvmhDirectiveBase_nodist.cpp
_src/Distribution/DvmhDirectiveBase.h
_src/Distribution/DvmhDirectiveBase.h
_src/Distribution/GraphCSR.cpp
_src/Distribution/GraphCSR.h)
_src/Distribution/GraphCSR.h)
set(DVMH_REG _src/DvmhRegions/DvmhRegionInserter.cpp
_src/DvmhRegions/DvmhRegionInserter.h
_src/DvmhRegions/RegionsMerger.cpp
_src/DvmhRegions/RegionsMerger.h
_src/DvmhRegions/ReadWriteAnalyzer.cpp
_src/DvmhRegions/ReadWriteAnalyzer.h
_src/DvmhRegions/LoopChecker.cpp
_src/DvmhRegions/LoopChecker.h
_src/DvmhRegions/DvmhRegion.cpp
_src/DvmhRegions/DvmhRegion.h
_src/DvmhRegions/VarUsages.cpp
_src/DvmhRegions/VarUsages.h
_src/DvmhRegions/TypedSymbol.cpp
_src/DvmhRegions/TypedSymbol.h)
_src/DvmhRegions/DvmhRegionInserter.h
_src/DvmhRegions/RegionsMerger.cpp
_src/DvmhRegions/RegionsMerger.h
_src/DvmhRegions/ReadWriteAnalyzer.cpp
_src/DvmhRegions/ReadWriteAnalyzer.h
_src/DvmhRegions/LoopChecker.cpp
_src/DvmhRegions/LoopChecker.h
_src/DvmhRegions/DvmhRegion.cpp
_src/DvmhRegions/DvmhRegion.h
_src/DvmhRegions/VarUsages.cpp
_src/DvmhRegions/VarUsages.h
_src/DvmhRegions/TypedSymbol.cpp
_src/DvmhRegions/TypedSymbol.h)
set(DYNA _src/DynamicAnalysis/createParallelRegions.cpp
_src/DynamicAnalysis/createParallelRegions.h
_src/DynamicAnalysis/gcov_info.cpp
_src/DynamicAnalysis/gcov_info.h
_src/DynamicAnalysis/gCov_parser.cpp
_src/DynamicAnalysis/gCov_parser_func.h)
_src/DynamicAnalysis/createParallelRegions.h
_src/DynamicAnalysis/gcov_info.cpp
_src/DynamicAnalysis/gcov_info.h
_src/DynamicAnalysis/gCov_parser.cpp
_src/DynamicAnalysis/gCov_parser_func.h)
set(EXPR_TRANSFORM _src/ExpressionTransform/control_flow_graph_part.cpp
_src/ExpressionTransform/expr_transform.cpp
_src/ExpressionTransform/expr_transform.h)
_src/ExpressionTransform/expr_transform.cpp
_src/ExpressionTransform/expr_transform.h)
set(GR_CALL _src/GraphCall/graph_calls.cpp
_src/GraphCall/graph_calls.h
_src/GraphCall/graph_calls_base.cpp
_src/GraphCall/graph_calls_func.h
_src/GraphCall/select_array_conf.cpp
_src/GraphCall/select_array_conf.h)
_src/GraphCall/graph_calls.h
_src/GraphCall/graph_calls_base.cpp
_src/GraphCall/graph_calls_func.h
_src/GraphCall/select_array_conf.cpp
_src/GraphCall/select_array_conf.h)
set(GR_LOOP _src/GraphLoop/graph_loops_base.cpp
_src/GraphLoop/graph_loops.cpp
_src/GraphLoop/graph_loops.h
_src/GraphLoop/graph_loops_func.h)
_src/GraphLoop/graph_loops.h
_src/GraphLoop/graph_loops_func.h)
set(INLINER _src/Inliner/inliner.cpp
_src/Inliner/inliner.h)
_src/Inliner/inliner.h)
set(LOOP_ANALYZER _src/LoopAnalyzer/allocations_prepoc.cpp
_src/LoopAnalyzer/dep_analyzer.cpp
_src/LoopAnalyzer/loop_analyzer.cpp
_src/LoopAnalyzer/loop_analyzer_nodist.cpp
_src/LoopAnalyzer/loop_analyzer_nodist.h
_src/LoopAnalyzer/loop_analyzer_internal.h
_src/LoopAnalyzer/loop_analyzer.h)
_src/LoopAnalyzer/loop_analyzer_nodist.h
_src/LoopAnalyzer/loop_analyzer_internal.h
_src/LoopAnalyzer/loop_analyzer.h)
set(RENAME_SYMBOLS _src/RenameSymbols/rename_symbols.cpp
_src/RenameSymbols/rename_symbols.h)
_src/RenameSymbols/rename_symbols.h)
set(MAIN _src/Sapfor.cpp
_src/Sapfor.h
_src/SapforData.h
_src/Utils/PassManager.h)
_src/Sapfor.h
_src/SapforData.h
_src/Utils/PassManager.h)
set(PREDICTOR _src/Predictor/PredictScheme.cpp
_src/Predictor/PredictScheme.h)
@@ -342,88 +347,88 @@ set(PROJ_MAN _src/ProjectManipulation/ParseFiles.cpp
_src/ProjectManipulation/ConvertFiles.h)
set(PARSER ${parser_sources}/cftn.c
${parser_sources}/errors.c
${parser_sources}/gram1.tab.c
${parser_sources}/hash.c
${parser_sources}/init.c
${parser_sources}/lexfdvm.c
${parser_sources}/lists.c
${parser_sources}/low_hpf.c
${parser_sources}/misc.c
${parser_sources}/stat.c
${parser_sources}/sym.c
${parser_sources}/types.c
${parser_sources}/unparse_hpf.c)
${parser_sources}/errors.c
${parser_sources}/gram1.tab.c
${parser_sources}/hash.c
${parser_sources}/init.c
${parser_sources}/lexfdvm.c
${parser_sources}/lists.c
${parser_sources}/low_hpf.c
${parser_sources}/misc.c
${parser_sources}/stat.c
${parser_sources}/sym.c
${parser_sources}/types.c
${parser_sources}/unparse_hpf.c)
set(PPPA ${pppa_sources}/inter.cpp
${pppa_sources}/potensyn.cpp
${pppa_sources}/stat.cpp
${pppa_sources}/statfile.cpp
${pppa_sources}/statinter.cpp
${pppa_sources}/statlist.cpp
${pppa_sources}/statprintf.cpp
${pppa_sources}/statread.cpp
${pppa_sources}/treeinter.cpp
${pppa_sources}/bool.h
${pppa_sources}/dvmh_stat.h
${pppa_sources}/inter.h
${pppa_sources}/potensyn.h
${pppa_sources}/statist.h
${pppa_sources}/statlist.h
${pppa_sources}/statprintf.h
${pppa_sources}/statread.h
${pppa_sources}/strall.h
${pppa_sources}/sysstat.h
${pppa_sources}/treeinter.h
${pppa_sources}/ver.h
${pppa_sources}/statinter.h
${pppa_sources}/json.hpp)
${pppa_sources}/potensyn.cpp
${pppa_sources}/stat.cpp
${pppa_sources}/statfile.cpp
${pppa_sources}/statinter.cpp
${pppa_sources}/statlist.cpp
${pppa_sources}/statprintf.cpp
${pppa_sources}/statread.cpp
${pppa_sources}/treeinter.cpp
${pppa_sources}/bool.h
${pppa_sources}/dvmh_stat.h
${pppa_sources}/inter.h
${pppa_sources}/potensyn.h
${pppa_sources}/statist.h
${pppa_sources}/statlist.h
${pppa_sources}/statprintf.h
${pppa_sources}/statread.h
${pppa_sources}/strall.h
${pppa_sources}/sysstat.h
${pppa_sources}/treeinter.h
${pppa_sources}/ver.h
${pppa_sources}/statinter.h
${pppa_sources}/json.hpp)
set(ZLIB ${zlib_sources}/src/adler32.c
${zlib_sources}/src/compress.c
${zlib_sources}/src/crc32.c
${zlib_sources}/src/deflate.c
${zlib_sources}/src/gzio.c
${zlib_sources}/src/infblock.c
${zlib_sources}/src/infcodes.c
${zlib_sources}/src/inffast.c
${zlib_sources}/src/inflate.c
${zlib_sources}/src/inftrees.c
${zlib_sources}/src/infutil.c
${zlib_sources}/src/trees.c
${zlib_sources}/src/uncompr.c
${zlib_sources}/src/zutil.c)
${zlib_sources}/src/compress.c
${zlib_sources}/src/crc32.c
${zlib_sources}/src/deflate.c
${zlib_sources}/src/gzio.c
${zlib_sources}/src/infblock.c
${zlib_sources}/src/infcodes.c
${zlib_sources}/src/inffast.c
${zlib_sources}/src/inflate.c
${zlib_sources}/src/inftrees.c
${zlib_sources}/src/infutil.c
${zlib_sources}/src/trees.c
${zlib_sources}/src/uncompr.c
${zlib_sources}/src/zutil.c)
set(SOURCE_EXE
${CFG}
${DATA_FLOW}
${CREATE_INTER_T}
${DIRA}
${DISTR}
${DVMH_REG}
${DYNA}
${EXPR_TRANSFORM}
${GR_CALL}
${GR_LOOP}
${INLINER}
${LOOP_ANALYZER}
${RENAME_SYMBOLS}
${TRANSFORMS}
${PARALLEL_REG}
${PRIV}
${FDVM}
${OMEGA}
${UTILS}
${VERIF}
${VS_CALLS}
${MAIN}
${PREDICTOR}
${PARSER}
${PPPA}
${ZLIB}
${GR_LAYOUT}
${PR_PARAM}
set(SOURCE_EXE
${CFG}
${DATA_FLOW}
${CREATE_INTER_T}
${DIRA}
${DISTR}
${DVMH_REG}
${DYNA}
${EXPR_TRANSFORM}
${GR_CALL}
${GR_LOOP}
${INLINER}
${LOOP_ANALYZER}
${RENAME_SYMBOLS}
${TRANSFORMS}
${PARALLEL_REG}
${PRIV}
${FDVM}
${OMEGA}
${UTILS}
${VERIF}
${VS_CALLS}
${MAIN}
${PREDICTOR}
${PARSER}
${PPPA}
${ZLIB}
${GR_LAYOUT}
${PR_PARAM}
${PROJ_MAN})
add_executable(Sapfor_F ${SOURCE_EXE})
@@ -448,6 +453,7 @@ source_group (Transformations\\VectorAssignToLoop FILES ${TR_VECTOR})
source_group (Transformations\\RenameSymbols FILES ${RENAME_SYMBOLS})
source_group (Transformations\\GlobalVariables FILES ${TR_GV})
source_group (Transformations\\ConvertToC FILES ${TR_CONV})
source_group (Transformations\\SetImplicitNone FILES ${TR_IMPLICIT_NONE})
source_group (CreateIntervals FILES ${CREATE_INTER_T})
@@ -459,11 +465,11 @@ source_group (GraphCall FILES ${GR_CALL})
source_group (GraphLoop FILES ${GR_LOOP})
source_group (LoopAnalyzer FILES ${LOOP_ANALYZER})
source_group (ParallelizationRegions FILES ${PARALLEL_REG})
source_group (PrivateAnalyzer FILES ${PRIV})
source_group (PrivateAnalyzer FILES ${PRIV})
source_group (FDVM_Compiler FILES ${FDVM})
source_group (SageExtension FILES ${OMEGA})
source_group (Utils FILES ${UTILS})
source_group (VerificationCode FILES ${VERIF})
source_group (VerificationCode FILES ${VERIF})
source_group (ProjectParameters FILES ${PR_PARAM})
source_group (ProjectManipulation FILES ${PROJ_MAN})
@@ -503,15 +509,15 @@ add_definitions("-D __SPF_BUILT_IN_PARSER")
add_definitions("-D __SPF_BUILT_IN_PPPA")
if (WIN32)
target_link_libraries(Sapfor_F SageNewSrc SageLib SageOldSrc)
target_link_libraries(Sapfor_F SageNewSrc SageLib SageOldSrc)
elseif(UNIX)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0)
target_link_libraries(Sapfor_F SageNewSrc SageLib SageOldSrc pthread stdc++fs)
else()
target_link_libraries(Sapfor_F SageNewSrc SageLib SageOldSrc pthread)
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0)
target_link_libraries(Sapfor_F SageNewSrc SageLib SageOldSrc pthread stdc++fs)
else()
target_link_libraries(Sapfor_F SageNewSrc SageLib SageOldSrc pthread)
endif()
endif()
#install(TARGETS <name.exe/dll>
# LIBRARY DESTINATION <name_f>
# RUNTIME DESTINATION <name_f>)
# RUNTIME DESTINATION <name_f>)

View File

@@ -10,7 +10,8 @@
#include "../IR.h"
template <class NodeType>
class BackwardDataFlowAnalysis : public DataFlowAnalysis<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:

View File

@@ -29,6 +29,7 @@ public:
virtual bool addIn(const DataType& data) = 0;
virtual bool addOut(const DataType& data) = 0;
virtual bool updateState() { return false; }
virtual bool forwardData(const DataType& data) = 0;
bool newerThan(const DataFlowAnalysisNode<DataType>* block) const { return out_cnt > block->in_cnt; }

View File

@@ -27,29 +27,29 @@ template <class DataType>
void DataFlowAnalysisNode<DataType>::doStep()
{
int in_max_cnt = CNT_NOTINIT, out_max_cnt = CNT_NOTINIT;
bool uniq_change = updateState();
for (auto next : prev_blocks)
{
if (in_cnt < next->out_cnt)
{
for (const auto& byOut : next->getOut())
const auto& byOut = next->getOut();
bool inserted = addIn( byOut);
if (inserted)
{
bool inserted = addIn({ byOut });
if (next->out_cnt > in_max_cnt)
in_max_cnt = next->out_cnt;
if (inserted)
{
if (next->out_cnt > in_max_cnt)
in_max_cnt = next->out_cnt;
inserted = forwardData(byOut);
inserted = forwardData({ byOut });
if (inserted && next->out_cnt > out_max_cnt)
out_max_cnt = next->out_cnt;
}
if (inserted && next->out_cnt > out_max_cnt)
out_max_cnt = next->out_cnt;
}
}
}
bool was_notinit = (out_cnt == CNT_NOTINIT);
uniq_change |= (out_cnt == CNT_NOTINIT);
if (out_max_cnt != CNT_NOTINIT)
out_cnt = out_max_cnt;
@@ -58,7 +58,7 @@ void DataFlowAnalysisNode<DataType>::doStep()
in_cnt = in_max_cnt;
// TODO: fix counter overflow
if (was_notinit)
if (uniq_change)
{
out_cnt++;
in_cnt++;
@@ -68,7 +68,8 @@ void DataFlowAnalysisNode<DataType>::doStep()
/* definitions for DataFlowAnalysis class */
template <class NodeType>
void DataFlowAnalysis<NodeType>::analyze() {
void DataFlowAnalysis<NodeType>::analyze()
{
auto curr = 0;
auto stop = nodes.size();

View File

@@ -195,7 +195,7 @@ static SAPFOR::Argument* createConstArg(SgExpression* exp)
else if (var == BOOL_VAL)
newName = value->boolValue() ? "TRUE" : "FALSE";
else if (var == KEYWORD_VAL)
newName = string("%") + isSgKeywordValExp(exp)->value();
newName = string("%") + "key_arg_" + isSgKeywordValExp(exp)->value();
else if (var == CONSTRUCTOR_REF)
{
type = CFG_ARG_TYPE::CONSTR_REF;
@@ -395,7 +395,7 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector<IR_Block*>&
if (ex)
{
const int var = ex->variant();
if ((var == VAR_REF || var == CONST_REF) && !ex->lhs() && !ex->rhs()) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ((var == VAR_REF || var == CONST_REF || var == LABEL_REF) && !ex->lhs() && !ex->rhs()) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
if (var == CONST_REF)
{
@@ -405,6 +405,14 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector<IR_Block*>&
else
return createArg(ex->symbol(), commonVars, func);
}
else if (var == LABEL_REF)
{
auto labRef = isSgLabelRefExp(ex);
if (labRef == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return createConstArg(labRef->label()->getLabNumber());
}
else
return createArg(ex->symbol(), commonVars, func);
}
@@ -609,13 +617,15 @@ static SAPFOR::Argument* processExpression(SgExpression* ex, vector<IR_Block*>&
}
else if (var == CONSTRUCTOR_REF)
return createConstArg(ex);
else if (var == SPEC_PAIR)
return processExpression(ex->rhs(), blocks, func, commonVars);
else
{
__spf_print(1, "unknown expression '%s'\n", tag[ex->variant()]);
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
return NULL;
}
@@ -1131,8 +1141,8 @@ static SgStatement* processStatement(SgStatement* st, vector<IR_Block*>& blocks,
else if (var == PRINT_STAT || var == WRITE_STAT || var == READ_STAT)
{
SgInputOutputStmt* io = isSgInputOutputStmt(st);
SgExpression* item = io->itemList();
vector<vector<SgExpression*>> items;
vector<SgExpression*> tmp;
@@ -1200,10 +1210,30 @@ static SgStatement* processStatement(SgStatement* st, vector<IR_Block*>& blocks,
}
else
{
SgExpression* spec = io->specList();
vector<SAPFOR::Argument*> specArgs;
if (spec->variant() == SPEC_PAIR)
specArgs.push_back(processExpression(spec, blocks, func, commonVars));
else
{
while (spec)
{
specArgs.push_back(processExpression(spec->lhs(), blocks, func, commonVars));
spec = spec->rhs();
}
}
vector<SAPFOR::Argument*> args;
for (auto& par : item)
args.push_back(processExpression(par, blocks, func, commonVars));
for (auto& arg : specArgs)
{
Instruction* instr = new Instruction(CFG_OP::IO_PARAM, arg);
blocks.push_back(new IR_Block(instr));
}
for (auto& arg : args)
{
Instruction* instr = new Instruction(CFG_OP::PARAM, arg);

View File

@@ -12,7 +12,7 @@ namespace SAPFOR
{
struct CFG_Settings;
enum class CFG_OP { NONE, ASSIGN, POINTER_ASS, LOAD, STORE, REC_REF_LOAD, REC_REF_STORE, REF, PARAM, RANGE, ENTRY, REC_REF,
enum class CFG_OP { NONE, ASSIGN, POINTER_ASS, LOAD, STORE, REC_REF_LOAD, REC_REF_STORE, REF, PARAM, IO_PARAM, RANGE, ENTRY, REC_REF,
ADD, MULT, DIV, SUBT, UN_ADD, UN_MINUS, POW, CONCAT, CAST,
JUMP, JUMP_IF,
GE, LE, GT, LT, EQ, NEQV, EQV, EMPTY, OR, AND, NOT,
@@ -22,7 +22,7 @@ namespace SAPFOR
enum class CFG_ARG_TYPE { NONE, REG, VAR, ARRAY, CONST, FUNC, LAB, INSTR, CONST_STR, RECORD, CONSTR_REF };
enum class CFG_MEM_TYPE { NONE_, COMMON_, SAVE_, LOCAL_, MODULE_, FUNC_RES_, FUNC_PARAM_, FILED_ };
static std::vector<std::string> CFG_OP_S = { "--", " = ", " => ", "LOAD ", "STORE ", "LOAD_REF ", "STORE_REF ", "REF ", "PARAM ", "RANGE ", "ENTRY ", "->",
static std::vector<std::string> CFG_OP_S = { "--", " = ", " => ", "LOAD ", "STORE ", "LOAD_REF ", "STORE_REF ", "REF ", "PARAM ", "IO_PARAM ", "RANGE ", "ENTRY ", "->",
" + ", " * ", " / ", " - ", " + ", "-", " ** ", " // ", "CAST ",
"GOTO ", "IF_FALSE ",
" >= ", " <= ", " > " , " < ", " == ", " != ", " eqv ", "CONTINUE", " || ", " && ", " ! ",
@@ -228,7 +228,8 @@ namespace SAPFOR
res = "LOAD " + resultVal + " " + arg1Val + CFG_OP_S[(int)operation] + arg2Val;
break;
case CFG_OP::REF:
case CFG_OP::PARAM:
case CFG_OP::PARAM:
case CFG_OP::IO_PARAM:
res = CFG_OP_S[(int)operation] + arg1Val;
break;
case CFG_OP::CAST:

View File

@@ -8,6 +8,7 @@
#include <set>
#include <list>
#include <unordered_map>
#include <algorithm>
using std::string;
using std::pair;
@@ -138,7 +139,11 @@ namespace SAPFOR
for (auto& by_pair : by_source)
{
auto& dest = res[by_pair.first];
dest.insert(dest.end(), by_pair.second.begin(), by_pair.second.end());
auto dest_copy = dest;
dest.resize(dest_copy.size() + by_pair.second.size());
set_union(dest_copy.begin(), dest_copy.end(), by_pair.second.begin(), by_pair.second.end(), dest.begin());
}
}
@@ -289,39 +294,46 @@ public:
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,
vector<SAPFOR::Argument*>& arg_stack, int& arg_stack_index, int& arg_stack_size,
bool& last_stack_op,
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;
last_stack_op = false;
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))
if (instr_operation == SAPFOR::CFG_OP::F_CALL ||
instr_operation == SAPFOR::CFG_OP::STORE ||
instr_operation == SAPFOR::CFG_OP::LOAD)
{
res_arg = (instr_operation == SAPFOR::CFG_OP::STORE ? instr->getArg1() : instr->getResult());
if(instr_operation != SAPFOR::CFG_OP::F_CALL)
use.insert(instr_operation != SAPFOR::CFG_OP::STORE ? instr->getArg1() : instr->getResult());
arg_stack_size = stoi(instr->getArg2()->getValue());
arg_stack.clear();
arg_stack.resize(arg_stack_size);
arg_stack_index = arg_stack_size - 1;
if(instr_operation == SAPFOR::CFG_OP::F_CALL)
fName = instr->getArg1()->getValue();
}
else 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)
else if (instr_operation == SAPFOR::CFG_OP::PARAM || instr_operation == SAPFOR::CFG_OP::REF)
{
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();
arg_stack[arg_stack_index--] = instr->getArg1();
}
else if (skip.find(instr_operation) == skip.end())
{
@@ -336,50 +348,60 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins
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 (arg_stack_index < 0) {
if(instr_operation == SAPFOR::CFG_OP::PARAM || instr_operation == SAPFOR::CFG_OP::F_CALL)
{
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++)
auto func_it = funcByName.find(fName);
if (interprocedural && func_it != funcByName.end())
{
if(func_it->second->funcParams.isArgOut(i))
def.insert(lastParamRef[i]);
fcalls.push_back(LiveDeadVarsForCall(func_it->second, block, arg_stack));
if (func_it->second->funcParams.isArgIn(i))
use.insert(lastParamRef[i]);
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(arg_stack.begin(), arg_stack.end());
else if (interprocedural && getLiveDead(arg_stack, 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 = arg_stack.size();
for (int i = 0; i < arg_num; i++)
{
if(func_it->second->funcParams.isArgOut(i))
def.insert(arg_stack[i]);
if (func_it->second->funcParams.isArgIn(i))
use.insert(arg_stack[i]);
}
}
else
use.insert(arg_stack.begin(), arg_stack.end());
fName = "";
}
else
{
use.insert(arg_stack.begin(), arg_stack.end());
}
else
use.insert(lastParamRef.begin(), lastParamRef.end());
last_param_ref_index = 0;
last_param_ref_size = 0;
arg_stack_index = 0;
arg_stack_size = 0;
lastParamRef.clear();
fName = "";
arg_stack.clear();
last_stack_op = true;
}
if (res_arg)
@@ -389,15 +411,16 @@ void getUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instruction* ins
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,
vector<SAPFOR::Argument*>& arg_stack, int& arg_stack_index, int& arg_stack_size,
string& fName, const map<string, FuncInfo*>& funcByName, bool interprocedural)
{
set<SAPFOR::Argument*> res, args;
bool last_stack_op;
getUseDefForInstruction(block, instr,
args, res,
formal_parameters, fcalls,
lastParamRef, last_param_ref_index, last_param_ref_size,
arg_stack, arg_stack_index, arg_stack_size,
last_stack_op,
fName, funcByName,
interprocedural
);
@@ -426,8 +449,8 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
vector<SAPFOR::Argument*>& formal_parameters, vector<LiveDeadVarsForCall>& fcalls,
const map<string, FuncInfo*>& funcByName, bool interprocedural)
{
vector<SAPFOR::Argument*> lastParamRef;
int last_param_ref_index = 0, last_param_ref_size = 0;
vector<SAPFOR::Argument*> arg_stack;
int arg_stack_index = 0, arg_stack_size = 0;
string fName;
const auto& instructions = block->getInstructions();
@@ -438,7 +461,7 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
updateUseDefForInstruction(block, (*ir_block_it)->getInstruction(),
use, def,
formal_parameters, fcalls,
lastParamRef, last_param_ref_index, last_param_ref_size,
arg_stack, arg_stack_index, arg_stack_size,
fName, funcByName,
interprocedural
);

View File

@@ -42,7 +42,8 @@ void insertIfVar(IT begin, IT end, DEST& to) {
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::vector<SAPFOR::Argument*>& arg_stack, int& arg_stack_index, int& arg_stack_size,
bool& last_stack_op,
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);

View File

@@ -17,7 +17,7 @@
#include "../Distribution/DvmhDirective.h"
#include "../GraphLoop/graph_loops.h"
#include "DirectiveAnalyzer.h"
#include "directive_analyzer.h"
#include "../Utils/utils.h"
using std::vector;

View File

@@ -45,6 +45,8 @@ using std::get;
using std::string;
using std::wstring;
extern int mpiProgram;
static vector<pair<string, vector<Expression*>>>
groupRealignsDirs(const vector<pair<string, vector<Expression*>>>& toRealign)
{
@@ -423,6 +425,66 @@ bool analyzeLoopBody(LoopGraph* loopV,
return true;
}
void createParallelDirs(File *file,
map<string, vector<Directive*>>& createdDirectives,
vector<Messages>& messages,
const vector<LoopGraph*>& loopsInFile,
const map<string, vector<FuncInfo*>>& allFuncInfo,
const vector<ParallelRegion*>& parallelRegions,
const map<LoopGraph*, void*>& depInfoForLoopGraph,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
const string file_name = file->filename();
map<int, LoopGraph*> mapLoopsInFile;
createMapLoopGraph(loopsInFile, mapLoopsInFile);
map<string, FuncInfo*> mapFuncInfo;
createMapOfFunc(allFuncInfo, mapFuncInfo);
for (int z = 0; z < parallelRegions.size(); ++z)
{
vector<Directive*> toInsert;
const DataDirective& dataDirectives = parallelRegions[z]->GetDataDir();
const vector<int>& currentVariant = parallelRegions[z]->GetCurrentVariant();
DIST::GraphCSR<int, double, attrType>& reducedG = parallelRegions[z]->GetReducedGraphToModify();
DIST::Arrays<int>& allArrays = parallelRegions[z]->GetAllArraysToModify();
auto& tmp = dataDirectives.distrRules;
vector<pair<DIST::Array*, const DistrVariant*>> currentVar;
if (mpiProgram == 0)
{
for (int z1 = 0; z1 < currentVariant.size(); ++z1)
currentVar.push_back(make_pair(tmp[z1].first, &tmp[z1].second[currentVariant[z1]]));
}
else
{
for (auto& loop : mapLoopsInFile)
{
auto& rules = loop.second->getDataDir().distrRules;
for (auto& rule : rules)
currentVar.push_back(make_pair(rule.first, &rule.second[0]));
}
}
selectParallelDirectiveForVariant(file, parallelRegions[z], reducedG, allArrays, loopsInFile,
mapLoopsInFile, mapFuncInfo, currentVar,
toInsert, parallelRegions[z]->GetId(), arrayLinksByFuncCalls,
depInfoForLoopGraph, messages);
if (toInsert.size() > 0)
{
auto it = createdDirectives.find(file_name);
if (it == createdDirectives.end())
createdDirectives.insert(it, make_pair(file_name, toInsert));
else
for (int m = 0; m < toInsert.size(); ++m)
it->second.push_back(toInsert[m]);
}
}
}
#undef PRINT_DIR_RESULT
#undef FIRST
#undef SECOND

View File

@@ -43,4 +43,21 @@ DIST::Array* getRealArrayRef(DIST::Array* in, const uint64_t regId, const std::m
void shiftAlignRulesForTemplates(const std::set<DIST::Array*>& arrays, const uint64_t regId, DataDirective& dataDirectives, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
void createShadowSpec(const std::map<std::string, std::vector<LoopGraph*>>& loopGraph, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, const std::set<DIST::Array*>& forArrays);
void createShadowSpec(const std::map<std::string, std::vector<LoopGraph*>>& loopGraph, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, const std::set<DIST::Array*>& forArrays);
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);
void createParallelDirs(File* file,
std::map<std::string, std::vector<Directive*>>& createdDirectives,
std::vector<Messages>& messages,
const std::vector<LoopGraph*>& loopsInFile,
const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo,
const std::vector<ParallelRegion*>& parallelRegions,
const std::map<LoopGraph*, void*>& depInfoForLoopGraph,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);

View File

@@ -15,7 +15,6 @@
#include "../Utils/errors.h"
#include "directive_parser.h"
#include "directive_creator.h"
#include "directive_creator_internal.h"
#define PRINT_PROF_INFO 1
#define PRINT_DIR_RESULT 0
@@ -1092,6 +1091,9 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
set<string> privates;
#if __SPF
tmpL = loop->parent;
while (tmpL)
{
@@ -1110,11 +1112,9 @@ static bool tryToResolveUnmatchedDims(const map<DIST::Array*, vector<bool>> &dim
tmpL = tmpL->parent;
}
set<string> privates;
#if __SPF
tryToFindPrivateInAttributes(loop->loop->GetOriginal(), privates);
#else
#error 'TODO - fill privates for this loop'
#error 'TODO - fill privates for this loop and check all inductive variables'
#endif
//try to resolve from write operations

View File

@@ -15,7 +15,6 @@
#include "../Utils/errors.h"
#include "directive_parser.h"
#include "directive_creator.h"
#include "directive_creator_internal.h"
#include "directive_creator_nodist.h"
#define PRINT_PROF_INFO 1
@@ -135,14 +134,7 @@ void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currPar
#if __SPF
//move label before loop
if (loop->hasRedistribute())
{
auto prev = loop->loop->lexPrev();
if (!prev)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
moveLabelBefore(prev, loop->loop);
}
else if(loop->lineNum > 0)
if(loop->lineNum > 0)
moveLabelBefore(loop->loop, NULL);
// check correctness
@@ -158,7 +150,7 @@ void selectParallelDirectiveForVariantNoDist(File* file, ParallelRegion* currPar
checkNull(local, convertFileName(__FILE__).c_str(), __LINE__);
}
#endif
toInsert.push_back(dirImpl);
toInsert.push_back(dirImpl);
}
}
else //TODO: add checker for indexing in this loop

View File

@@ -1,23 +0,0 @@
#pragma once
#include <vector>
#include <map>
#include <set>
#include <string>
#include "../Distribution/Distribution.h"
#include "../Utils/errors.h"
#include "../GraphLoop/graph_loops.h"
#include "../Utils/types.h"
#define FIRST(x) get<0>(x)
#define SECOND(x) get<1>(x)
#define THIRD(x) get<2>(x)
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);

View File

@@ -0,0 +1,524 @@
#include "../Utils/leak_detector.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include "dvm.h"
#include "directive_omp_parser.h"
#include "directive_parser.h"
#include "../Utils/SgUtils.h"
using std::vector;
using std::map;
using std::set;
using std::string;
void removeOmpDir(SgStatement* st)
{
char* lineS = st->comments();
if (!lineS)
return;
vector<string> split;
splitString(lineS, '\n', split);
int idx = 0;
for (auto& elem : split)
{
string line = elem;
convertToLower(line);
if (line.substr(0, 5) == "!$omp")
lineS[idx + 1] = '_';
else if (line.substr(0, 3) == "!$ ")
lineS[idx + 1] = '_';
idx += line.size() + 1; // with '\n'
}
}
static inline void addToAttribute(SgStatement* st, int var, vector<SgExpression*> list)
{
if (list.size())
{
SgExprListExp* ex = new SgExprListExp();
ex->setLhs(new SgExpression(var, makeExprList(list), NULL));
SgStatement* toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, ex, NULL, NULL);
toAdd->setlineNumber(st->lineNumber());
toAdd->setLocalLineNumber(SPF_OMP_DIR);
//filter
if (var == ACC_PRIVATE_OP)
{
vector<SgExpression*> list_new;
auto attributes = getAttributes<SgStatement*, SgStatement*>(st, set<int>{SPF_ANALYSIS_DIR});
set<string> privates;
for (auto& attr : attributes)
fillPrivatesFromComment(new Statement(attr), privates);
if (privates.size())
{
for (auto& elem : list)
if (privates.find(elem->unparse()) == privates.end())
list_new.push_back(elem);
list = list_new;
if (!list.size())
{
__spf_print(1, "-- skip privates on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
return;
}
}
}
else if (var == REDUCTION_OP)
{
auto attributes = getAttributes<SgStatement*, SgStatement*>(st, set<int>{SPF_ANALYSIS_DIR});
map<string, set<string>> reduction;
for (auto& attr : attributes)
fillReductionsFromComment(new Statement(attr), reduction);
map<string, set<string>> reductionToAdd;
fillReductionsFromComment(new Statement(toAdd), reductionToAdd);
vector<SgExpression*> list_new;
if (reduction.size())
{
if (reduction == reductionToAdd)
{
__spf_print(1, "-- skip reduction on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
return;
}
map<string, set<string>> reductionToAddNew;
for (auto& redPair : reductionToAdd)
{
auto it = reduction.find(redPair.first);
if (it == reduction.end())
reductionToAddNew[redPair.first] = redPair.second;
else
{
set<string> newVar;
for (auto& var : redPair.second)
{
auto itVar = it->second.find(var);
if (itVar == it->second.end())
reductionToAddNew[redPair.first].insert(var);
}
}
}
if (!reductionToAddNew.size())
{
__spf_print(1, "-- skip reduction on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
return;
}
if (reductionToAddNew != reductionToAdd)
{
list.clear();
for (auto& redPair : reductionToAddNew)
for (auto& var : redPair.second)
list.push_back(new SgExpression(ARRAY_OP,
new SgKeywordValExp(redPair.first.c_str()),
new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st)))));
}
}
}
ex = new SgExprListExp();
ex->setLhs(new SgExpression(var, makeExprList(list), NULL));
toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, ex, NULL, NULL);
st->addAttribute(SPF_ANALYSIS_DIR, toAdd, sizeof(SgStatement));
if (var == ACC_PRIVATE_OP)
__spf_print(1, "-- set private attribute to line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
else if (var == REDUCTION_OP)
__spf_print(1, "-- set reduction attribute to line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
}
}
static bool is_write_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;
}
else if (st->variant() == FOR_NODE)
{
if (var == isSgForStmt(st)->doName()->identifier())
return true;
}
}
return false;
}
vector<OmpDir> parseOmpInStatement(SgStatement* st, const set<string>& globalPriv, bool forDo)
{
vector<OmpDir> resultAll;
const char* lineS = st->comments();
if (!lineS)
return resultAll;
string comment(lineS);
convertToLower(comment);
vector<string> split;
splitString(comment, '\n', split);
for (int z = split.size() - 1; z >= 0; z--)
{
string line = split[z];
if (line.substr(0, 6) == "!$omp&")
{
if (z - 1 < 0)
break;
split[z - 1] += line.substr(6);
split[z] = "";
}
}
for (auto& line : split)
{
if (line.substr(0, 5) == "!$omp")
{
OmpDir result;
string line1 = "";
int space = 0;
int brake = 0;
for (int z = 0; z < line.size(); ++z)
{
if (brake < 0)
return vector<OmpDir>(); // error
if (brake == 0)
{
if (line[z] == ' ')
space++;
else
space = 0;
if ((line[z] == ' ' && space <= 1) || line[z] != ' ')
line1 += line[z];
}
else
{
if (line[z] != ' ')
line1 += line[z];
}
if (line[z] == '(')
{
while (line1.size() > 2 && line1[line1.size() - 2] == ' ')
line1 = line1.erase(line1.size() - 2, 1);
brake++;
space = 0;
}
else if (line[z] == ')')
brake--;
}
vector<string> lexems;
splitString(line1, ' ', lexems);
bool doLexem = false;
bool end = false;
bool parallel = false;
bool privat = false;
for (auto& lexem : lexems)
{
if (lexem == "do")
{
doLexem = true;
result.keys.insert(lexem);
}
if (lexem == "end")
{
end = true;
result.keys.insert(lexem);
}
if (lexem == "parallel")
{
parallel = true;
result.keys.insert(lexem);
}
if (lexem == "private")
{
privat = true;
result.keys.insert(lexem);
}
}
if (privat == false)
{
if (forDo && doLexem)
{
vector<SgExpression*> list;
for (auto& var : globalPriv)
if (is_write_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);
}
}
for (auto& lexem : lexems)
{
bool priv = lexem.substr(0, strlen("private(")) == "private(";
bool threadpriv = lexem.substr(0, strlen("threadprivate(")) == "threadprivate(";
bool red = lexem.substr(0, strlen("reduction(")) == "reduction(";
if (priv || threadpriv)
{
vector<string> sublex;
splitString(lexem, '(', sublex);
if (sublex.size() == 2 && lexem.back() == ')')
{
splitString(sublex[1].erase(sublex[1].size() - 1), ',', sublex);
vector<SgExpression*> list;
set<string> uniqList;
for (auto& varG : globalPriv)
uniqList.insert(varG);
for (auto& var : sublex)
uniqList.insert(var);
for (auto& var : uniqList)
{
if (priv)
{
result.privVars.insert(var);
list.push_back(new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st))));
}
else
result.threadPrivVars.insert(var);
}
if (forDo && doLexem && priv)
addToAttribute(st, ACC_PRIVATE_OP, list);
}
}
else if (red)
{
vector<string> sublex;
splitString(lexem, '(', sublex);
if (sublex.size() == 2 && lexem.back() == ')')
{
splitString(sublex[1].erase(sublex[1].size() - 1), ':', sublex);
vector<string> vars;
vector<SgExpression*> list;
splitString(sublex[1], ',', vars);
string op = "";
if (sublex[0] == "+")
op = "sum";
else if (sublex[0] == "*")
op = "prod";
else if (sublex[0] == "max")
op = "max";
else if (sublex[0] == "min")
op = "min";
else if (sublex[0] == ".or." || sublex[0] == "or")
op = "or";
else if (sublex[0] == ".and." || sublex[0] == "and")
op = "and";
else if (sublex[0] == ".eqv." || sublex[0] == "eqv")
op = "eqv";
else if (sublex[0] == ".neqv." || sublex[0] == "neqv")
op = "neqv";
if (op != "")
{
for (auto& var : vars)
{
result.redVars[sublex[0]].insert(var);
list.push_back(new SgExpression(ARRAY_OP, new SgKeywordValExp(op.c_str()), new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st)))));
}
}
if (forDo && doLexem && op != "")
addToAttribute(st, REDUCTION_OP, list);
}
}
}
resultAll.push_back(result);
}
}
return resultAll;
}
//TODO: need to use IR and RD for checking
static void filterPrivates(OmpDir& dir)
{
if (dir.privVars.size() == 0)
return;
for (auto st = dir.start; st != dir.end; st = st->lexNext())
{
vector<OmpDir> res;
if (st != dir.start)
{
set<string> dummy;
res = parseOmpInStatement(st, dummy);
}
bool hasParallelDo = false;
for (auto& dir : res)
{
if (dir.keys.find("parallel") != dir.keys.end() ||
dir.keys.find("do") != dir.keys.end())
{
hasParallelDo = true;
}
}
if (res.size() == 0 || !hasParallelDo)
{
if (st->variant() == ASSIGN_STAT)
{
if (st->expr(0))
{
string ref = st->expr(0)->symbol()->identifier();
dir.privVars.erase(ref);
}
}
}
}
}
static vector<OmpDir> findAllGlobalParallelRegions(SgStatement* stFunc)
{
vector<OmpDir> sections;
SgStatement* lastNode = stFunc->lastNodeOfStmt();
for (auto st = stFunc; st != lastNode; st = st->lexNext())
{
if (st == NULL)
{
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
break;
}
if (st->variant() == CONTAINS_STMT)
break;
set<string> dummy;
auto res = parseOmpInStatement(st, dummy);
for (auto& dir : res)
{
auto end = dir.keys.end();
if (dir.keys.find("parallel") != end
&& dir.keys.find("do") == end
&& dir.keys.find("end") == end)
{
if (sections.size() && sections.back().end == NULL) // has open parallel region
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
sections.push_back(dir);
sections.back().start = st;
}
else if (dir.keys.find("parallel") != end
&& dir.keys.find("do") == end
&& dir.keys.find("end") != end)
{
sections.back().end = st;
}
}
}
for (auto& dir : sections)
filterPrivates(dir);
return sections;
}
static set<string> getGlobalPrivate(SgStatement* st, const vector<OmpDir>& globalParallelRegions)
{
set<string> globalPrivates;
const int line = st->lineNumber();
if (line > 0)
{
for (auto& reg : globalParallelRegions)
{
if (reg.start->lineNumber() <= line && line < reg.end->lineNumber())
{
if (reg.privVars.size())
return reg.privVars;
else
return globalPrivates;
}
}
}
else
{
for (auto& reg : globalParallelRegions)
{
for (auto stF = reg.start; stF != reg.end; stF = stF->lexNext())
{
if (st == stF)
{
if (reg.privVars.size())
return reg.privVars;
else
return globalPrivates;
}
}
}
}
return globalPrivates;
}
void parseOmpDirectives(SgFile* file, vector<Messages>& currMessages)
{
int funcNum = file->numberOfFunctions();
for (int i = 0; i < funcNum; ++i)
{
SgStatement* st = file->functions(i);
SgStatement* lastNode = st->lastNodeOfStmt();
vector<OmpDir> globalParallelRegions = findAllGlobalParallelRegions(st);
while (st != lastNode)
{
if (st == NULL)
{
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
break;
}
if (st->variant() == CONTAINS_STMT)
break;
if (st->variant() == FOR_NODE)
{
SgForStmt* currSt = (SgForStmt*)st;
if (currSt->isEnddoLoop() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
else
parseOmpInStatement(st, getGlobalPrivate(st, globalParallelRegions), true);
}
st = st->lexNext();
}
}
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include <string>
#include <set>
#include <map>
#include <vector>
#include "../Utils/errors.h"
#define SPF_USER_DIR 777
#define SPF_USER_DIR_COPY 999
#define SPF_OMP_DIR 888
struct OmpDir
{
std::set<std::string> privVars;
std::set<std::string> threadPrivVars;
std::map<std::string, std::set<std::string>> redVars;
std::set<std::string> keys;
SgStatement* start = NULL;
SgStatement* end = NULL;
};
void removeOmpDir(SgStatement* st);
std::vector<OmpDir> parseOmpInStatement(SgStatement* st, const std::set<std::string>& globalPriv, bool forDo = false);
void parseOmpDirectives(SgFile* file, std::vector<Messages>& currMessages);

View File

@@ -84,7 +84,7 @@ static inline Symbol* getData(SgExpression *symb, Symbol**, bool moduleNameAdd =
}
template<typename fillType>
void fillPrivatesFromComment(Statement *stIn, set<fillType> &privates)
void fillPrivatesFromComment(Statement *stIn, set<fillType> &privates, int type)
{
if (stIn)
{
@@ -94,7 +94,10 @@ void fillPrivatesFromComment(Statement *stIn, set<fillType> &privates)
SgExpression *exprList = st->expr(0);
while (exprList)
{
if (exprList->lhs()->variant() == ACC_PRIVATE_OP)
const int var = exprList->lhs()->variant();
if ( ((var == ACC_PRIVATE_OP || var == SPF_PROCESS_PRIVATE_OP) && type == -1) ||
(var == ACC_PRIVATE_OP && var == type) ||
(var == SPF_PROCESS_PRIVATE_OP && var == type) )
{
SgExpression *list = exprList->lhs()->lhs();
while (list)
@@ -111,8 +114,8 @@ void fillPrivatesFromComment(Statement *stIn, set<fillType> &privates)
}
}
template void fillPrivatesFromComment(Statement *st, set<string> &privates);
template void fillPrivatesFromComment(Statement *st, set<Symbol*> &privates);
template void fillPrivatesFromComment(Statement *st, set<string> &privates, int type);
template void fillPrivatesFromComment(Statement *st, set<Symbol*> &privates, int type);
//XXX: need to remove message and to add implementation
extern map<string, vector<Messages>> SPF_messages;
@@ -595,349 +598,27 @@ void fillInfoFromDirectives(const LoopGraph *loopInfo, ParallelDirective *direct
}
}
void removeOmpDir(void* stIn)
int getCoverPropertyFromComment(Statement* stIn)
{
SgStatement* st = (SgStatement*)stIn;
char* lineS = st->comments();
if (!lineS)
return;
vector<string> split;
splitString(lineS, '\n', split);
int idx = 0;
for (auto& elem : split)
if (stIn)
{
string line = elem;
convertToLower(line);
if (line.substr(0, 5) == "!$omp")
lineS[idx + 1] = '_';
else if (line.substr(0, 3) == "!$ ")
lineS[idx + 1] = '_';
idx += line.size() + 1; // with '\n'
}
}
static inline void addToAttribute(SgStatement* st, int var, vector<SgExpression*> list)
{
if (list.size())
{
SgExprListExp* ex = new SgExprListExp();
ex->setLhs(new SgExpression(var, makeExprList(list), NULL));
SgStatement* toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, ex, NULL, NULL);
toAdd->setlineNumber(st->lineNumber());
toAdd->setLocalLineNumber(888);
//filter
if (var == ACC_PRIVATE_OP)
SgStatement* st = stIn->GetOriginal();
if (st->variant() == SPF_ANALYSIS_DIR)
{
vector<SgExpression*> list_new;
auto attributes = getAttributes<SgStatement*, SgStatement*>(st, set<int>{SPF_ANALYSIS_DIR});
set<string> privates;
for (auto& attr : attributes)
fillPrivatesFromComment(new Statement(attr), privates);
if (privates.size())
SgExpression* exprList = st->expr(0);
while (exprList)
{
for (auto& elem : list)
if (privates.find(elem->unparse()) == privates.end())
list_new.push_back(elem);
list = list_new;
if (!list.size())
if (exprList->lhs() && exprList->lhs()->variant() == SPF_COVER_OP)
{
__spf_print(1, "-- skip privates on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
return;
}
}
}
else if (var == REDUCTION_OP)
{
auto attributes = getAttributes<SgStatement*, SgStatement*>(st, set<int>{SPF_ANALYSIS_DIR});
map<string, set<string>> reduction;
for (auto& attr : attributes)
fillReductionsFromComment(new Statement(attr), reduction);
map<string, set<string>> reductionToAdd;
fillReductionsFromComment(new Statement(st), reductionToAdd);
vector<SgExpression*> list_new;
if (reduction.size())
{
if (reduction == reductionToAdd)
{
__spf_print(1, "-- skip reduction on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
return;
}
map<string, set<string>> reductionToAddNew;
for (auto& redPair : reductionToAdd)
{
auto it = reduction.find(redPair.first);
if (it == reduction.end())
reductionToAddNew[redPair.first] = redPair.second;
auto value = exprList->lhs()->lhs();
if (value->isInteger())
return value->valueInteger();
else
{
set<string> newVar;
for (auto& var : redPair.second)
{
auto itVar = it->second.find(var);
if (itVar == it->second.end())
reductionToAddNew[redPair.first].insert(var);
}
}
}
if (!reductionToAddNew.size())
{
__spf_print(1, "-- skip reduction on line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
return;
}
if (reductionToAddNew != reductionToAdd)
{
list.clear();
for (auto& redPair : reductionToAddNew)
for (auto& var : redPair.second)
list.push_back(new SgExpression(ARRAY_OP,
new SgKeywordValExp(redPair.first.c_str()),
new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st)))));
return -1;
}
exprList = exprList->rhs();
}
}
ex = new SgExprListExp();
ex->setLhs(new SgExpression(var, makeExprList(list), NULL));
toAdd = new SgStatement(SPF_ANALYSIS_DIR, NULL, NULL, ex, NULL, NULL);
st->addAttribute(SPF_ANALYSIS_DIR, toAdd, sizeof(SgStatement));
if (var == ACC_PRIVATE_OP)
__spf_print(1, "-- set private attribute to line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
else if (var == REDUCTION_OP)
__spf_print(1, "-- set reduction attribute to line %d from OMP dir\n%s", st->lineNumber(), toAdd->unparse());
}
return 0;
}
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;
vector<OmpDir> resultAll;
const char* lineS = st->comments();
if (!lineS)
return resultAll;
string comment(lineS);
convertToLower(comment);
vector<string> split;
splitString(comment, '\n', split);
for (int z = split.size() - 1; z >= 0; z--)
{
string line = split[z];
if (line.substr(0, 6) == "!$omp&")
{
if (z - 1 < 0)
break;
split[z - 1] += line.substr(6);
split[z] = "";
}
}
for (auto& line : split)
{
if (line.substr(0, 5) == "!$omp")
{
OmpDir result;
string line1 = "";
int space = 0;
int brake = 0;
for (int z = 0; z < line.size(); ++z)
{
if (brake < 0)
return vector<OmpDir>(); // error
if (brake == 0)
{
if (line[z] == ' ')
space++;
else
space = 0;
if ((line[z] == ' ' && space <= 1) || line[z] != ' ')
line1 += line[z];
}
else
{
if (line[z] != ' ')
line1 += line[z];
}
if (line[z] == '(')
{
while (line1.size() > 2 && line1[line1.size() - 2] == ' ')
line1 = line1.erase(line1.size() - 2, 1);
brake++;
space = 0;
}
else if (line[z] == ')')
brake--;
}
vector<string> lexems;
splitString(line1, ' ', lexems);
bool doLexem = false;
bool end = false;
bool parallel = false;
bool privat = false;
for (auto& lexem : lexems)
{
if (lexem == "do")
{
doLexem = true;
result.keys.insert(lexem);
}
if (lexem == "end")
{
end = true;
result.keys.insert(lexem);
}
if (lexem == "parallel")
{
parallel = true;
result.keys.insert(lexem);
}
if (lexem == "private")
{
privat = true;
result.keys.insert(lexem);
}
}
if (privat == false)
{
if (forDo && doLexem)
{
vector<SgExpression*> list;
for (auto& var : globalPriv)
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);
}
}
for (auto& lexem : lexems)
{
bool priv = lexem.substr(0, strlen("private(")) == "private(";
bool threadpriv = lexem.substr(0, strlen("threadprivate(")) == "threadprivate(";
bool red = lexem.substr(0, strlen("reduction(")) == "reduction(";
if (priv || threadpriv)
{
vector<string> sublex;
splitString(lexem, '(', sublex);
if (sublex.size() == 2 && lexem.back() == ')')
{
splitString(sublex[1].erase(sublex[1].size() - 1), ',', sublex);
vector<SgExpression*> list;
set<string> uniqList;
for (auto& varG : globalPriv)
uniqList.insert(varG);
for (auto& var : sublex)
uniqList.insert(var);
for (auto& var : uniqList)
{
if (priv)
{
result.privVars.insert(var);
list.push_back(new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st))));
}
else
result.threadPrivVars.insert(var);
}
if (forDo && doLexem && priv)
addToAttribute(st, ACC_PRIVATE_OP, list);
}
}
else if (red)
{
vector<string> sublex;
splitString(lexem, '(', sublex);
if (sublex.size() == 2 && lexem.back() == ')')
{
splitString(sublex[1].erase(sublex[1].size() - 1), ':', sublex);
vector<string> vars;
vector<SgExpression*> list;
splitString(sublex[1], ',', vars);
string op = "";
if (sublex[0] == "+")
op = "sum";
else if (sublex[0] == "*")
op = "prod";
else if (sublex[0] == "max")
op = "max";
else if (sublex[0] == "min")
op = "min";
else if (sublex[0] == ".or." || sublex[0] == "or")
op = "or";
else if (sublex[0] == ".and." || sublex[0] == "and")
op = "and";
else if (sublex[0] == ".eqv." || sublex[0] == "eqv")
op = "eqv";
else if (sublex[0] == ".neqv." || sublex[0] == "neqv")
op = "neqv";
if (op != "")
{
for (auto& var : vars)
{
result.redVars[sublex[0]].insert(var);
list.push_back(new SgExpression(ARRAY_OP, new SgKeywordValExp(op.c_str()), new SgVarRefExp(findSymbolOrCreate(current_file, var, NULL, getFuncStat(st)))));
}
}
if (forDo && doLexem && op != "")
addToAttribute(st, REDUCTION_OP, list);
}
}
}
resultAll.push_back(result);
}
}
return resultAll;
}

View File

@@ -11,7 +11,7 @@
bool isSPF_NoInline(Statement *stPrev);
template<typename fillType>
void fillPrivatesFromComment(Statement *st, std::set<fillType> &privates);
void fillPrivatesFromComment(Statement *st, std::set<fillType> &privates, int type = -1);
template<typename fillType>
void fillReductionsFromComment(Statement *st, std::map<std::string, std::set<fillType>> &reduction, bool moduleNameAdd = false);
@@ -41,13 +41,4 @@ void fillShrinkFromComment(Statement *stIn, std::vector<std::pair<fillType, std:
template<typename fillType>
void fillCheckpointFromComment(Statement *stIn, std::map<int, Expression*> &clauses, std::set<fillType> &vars, std::set<fillType> &expt);
struct OmpDir
{
std::set<std::string> privVars;
std::set<std::string> threadPrivVars;
std::map<std::string, std::set<std::string>> redVars;
std::set<std::string> keys;
};
void removeOmpDir(void* stIn);
std::vector<OmpDir> parseOmpDirs(void* st, const std::set<std::string>& globalPriv, bool forDo = false);
int getCoverPropertyFromComment(Statement* stIn);

View File

@@ -39,6 +39,8 @@ using std::make_tuple;
static const string dvmhModuleName = "dvmh_template_mod";
extern int mpiProgram;
//the size of vector indiceates type of DVM_DIR
SgStatement* createStatFromExprs(const vector<Expression*> &exprs)
{
@@ -2364,4 +2366,65 @@ void insertDistributeDirsToParallelRegions(const vector<ParallelRegionLines> *cu
}
}
}
}
void insertParallelDirs(SgFile *file, bool extract,
vector<Directive*>& createdDirectives,
vector<Messages>& messages,
map<string, string>& templateDeclInIncludes,
map<string, map<int, set<string>>>& commentsToInclude,
const vector<FuncInfo*>& callGraph,
const vector<ParallelRegion*>& parallelRegions,
const map<string, vector<LoopGraph*>>& loopGraph,
const set<string>& allFileNames,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<DIST::Array*, tuple<int, string, string>>& tableOfUniqNamesByArray)
{
const char* file_name = file->filename();
insertDirectiveToFile(file, file_name, createdDirectives, extract, messages);
if (mpiProgram == 0)
{
map<string, FuncInfo*> mapFuncInfo;
createMapOfFunc(callGraph, mapFuncInfo);
for (int z = 0; z < parallelRegions.size(); ++z)
{
ParallelRegion* currReg = parallelRegions[z];
const DataDirective& dataDirectives = currReg->GetDataDir();
const vector<int>& currentVariant = currReg->GetCurrentVariant();
const DIST::Arrays<int>& allArrays = currReg->GetAllArrays();
DIST::GraphCSR<int, double, attrType>& reducedG = currReg->GetReducedGraphToModify();
const set<string> distrArrays = fillDistributedArrays(dataDirectives, tableOfUniqNamesByArray, arrayLinksByFuncCalls);
const vector<string> distrRules = dataDirectives.GenRule(currentVariant);
const vector<vector<dist>> distrRulesSt = dataDirectives.GenRule(currentVariant, 0);
const vector<string> alignRules = dataDirectives.GenAlignsRules();
insertDistributionToFile(file, file_name, dataDirectives, distrArrays, distrRules, distrRulesSt, alignRules, loopGraph,
allArrays, reducedG, commentsToInclude, templateDeclInIncludes, extract, messages,
arrayLinksByFuncCalls, mapFuncInfo, currReg->GetId(), allFileNames);
insertLoopTempalteDeclaration(file, dataDirectives, distrRules, distrRulesSt, allArrays, extract, currReg->GetId());
}
}
if (extract)
{
createdDirectives.clear();
//clear shadow specs
for (auto& array : declaredArrays)
array.second.first->ClearShadowSpecs();
}
else if (mpiProgram == 0)
{
set<uint64_t> regNum;
for (int z = 0; z < parallelRegions.size(); ++z)
regNum.insert(parallelRegions[z]->GetId());
insertTemplateModuleUse(file, regNum, arrayLinksByFuncCalls);
}
}

View File

@@ -47,4 +47,17 @@ void insertDistributeDirsToParallelRegions(const std::vector<ParallelRegionLines
void insertTemplateModuleUse(SgFile* file, const std::set<uint64_t>& regNum, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
void removeStatementsFromAllproject(const std::set<int>& variants);
void correctTemplateModuleDeclaration(const std::string& folderName);
void correctTemplateModuleDeclaration(const std::string& folderName);
void insertParallelDirs(SgFile* file, bool extract,
std::vector<Directive*>& createdDirectives,
std::vector<Messages>& messages,
std::map<std::string, std::string>& templateDeclInIncludes,
std::map<std::string, std::map<int, std::set<std::string>>>& commentsToInclude,
const std::vector<FuncInfo*>& callGraph,
const std::vector<ParallelRegion*>& parallelRegions,
const std::map<std::string, std::vector<LoopGraph*>>& loopGraph,
const std::set<std::string>& allFileNames,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls,
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const std::map<DIST::Array*, std::tuple<int, std::string, std::string>>& tableOfUniqNamesByArray);

View File

@@ -20,6 +20,7 @@
#include "directive_parser.h"
#include "../ExpressionTransform/expr_transform.h"
#include "../LoopAnalyzer/loop_analyzer.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
using std::string;
using std::wstring;
@@ -34,7 +35,7 @@ static void addToattribute(SgStatement *toAttr, SgStatement *curr, const int var
// move SgStatement to attribute
SgStatement *toAdd = new SgStatement(toAttr->variant(), NULL, toAttr->symbol(), toAttr->expr(0), toAttr->expr(1), toAttr->expr(2));
toAdd->setlineNumber(toAttr->lineNumber());
toAdd->setLocalLineNumber(777);
toAdd->setLocalLineNumber(SPF_USER_DIR);
curr->addAttribute(variant, toAdd, sizeof(SgStatement));
//copy comments to st
@@ -106,7 +107,7 @@ static bool isPrivateVar(SgStatement *st, SgSymbol *symbol)
return retVal;
}
#define BAD_POSITION_FULL(NEED_PRINT, ERR_TYPE, PLACE_E, PLACE_R, BEFORE_VAR_E, BEFORE_VAR_R, BEFORE_DO_E, BEFORE_DO_R, LINE) do { \
#define BAD_POSITION_FULL(ERR_TYPE, PLACE_E, PLACE_R, BEFORE_VAR_E, BEFORE_VAR_R, BEFORE_DO_E, BEFORE_DO_R, LINE) do { \
__spf_print(1, "bad directive position on line %d, it can be placed only %s %s %s\n", LINE, PLACE_E, BEFORE_VAR_E, BEFORE_DO_E); \
wstring messageE, messageR;\
__spf_printToLongBuf(messageE, L"bad directive position, it can be placed only %s %s %s", to_wstring(PLACE_E).c_str(), to_wstring(BEFORE_VAR_E).c_str(), to_wstring(BEFORE_DO_E).c_str()); \
@@ -156,6 +157,76 @@ static void fillVarsSets(SgStatement *iterator, SgStatement *end, set<string> &v
}
}
static bool checkCover(SgStatement* st,
SgStatement* attributeStatement,
const int coverLoops,
vector<Messages>& messagesForFile)
{
// COVER(VALUE)
const int var = st->variant();
bool retVal = true;
SgForStmt* forSt = (SgForStmt*)st;
const int nestedCount = countPerfectLoopNest(forSt);
if (coverLoops > nestedCount || coverLoops == 0)
{
__spf_print(1, "bad directive expression: expected %d nested loops on line %d but got %d on line %d\n",
coverLoops, attributeStatement->lineNumber(), nestedCount, st->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"bad directive expression: expected %d nested loops on line %d but got %d",
coverLoops, attributeStatement->lineNumber(), nestedCount);
__spf_printToLongBuf(messageR, R77, coverLoops, attributeStatement->lineNumber(), nestedCount);
messagesForFile.push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1043));
retVal = false;
}
return retVal;
}
static bool checkProcessPrivate(SgStatement* st,
SgStatement* attributeStatement,
const set<Symbol*>& privates,
vector<Messages>& messagesForFile)
{
// PROCESS_PRIVATE(VAR)
const int var = st->variant();
bool retVal = true;
if (!isSgExecutableStatement(st))
{
st = skipDvmDirs(st);
SgStatement* iterator = st;
SgStatement* end = st->lexNext();
set<string> varDef, varUse;
fillVarsSets(iterator, end, varDef, varUse);
for (auto& privElemS : privates)
{
const string privElem = privElemS->GetOriginal()->identifier();
bool defCond = true;
if (varDef.find(privElem) == varDef.end())
defCond = false;
if (!defCond)
{
BAD_POSITION_FULL(ERROR, "before", RR1_1, "variable declaration", RR1_2, "", L" ", attributeStatement->lineNumber());
retVal = false;
}
}
}
else
{
BAD_POSITION_FULL(ERROR, "before", RR1_1, "variable declaration", RR1_2, "", L" ", attributeStatement->lineNumber());
retVal = false;
}
return retVal;
}
static bool checkPrivate(SgStatement *st,
SgStatement *attributeStatement,
const set<Symbol*> &privates,
@@ -165,19 +236,16 @@ static bool checkPrivate(SgStatement *st,
const int var = st->variant();
bool retVal = true;
if (!isSgExecutableStatement(st) || var == FOR_NODE)
if (var == FOR_NODE)
{
st = skipDvmDirs(st);
SgStatement *iterator = st;
SgStatement *end = (var == FOR_NODE) ? st->lastNodeOfStmt() : st->lexNext();
set<string> varDef;
set<string> varUse;
fillVarsSets(iterator, end, varDef, varUse);
SgStatement *end = st->lastNodeOfStmt();
set<string> varDef, varUse;
set<string> wrongPrivFromOmpParallel;
for (auto &privElemS : privates)
fillVarsSets(iterator, end, varDef, varUse);
for (auto& privElemS : privates)
{
const string privElem = privElemS->GetOriginal()->identifier();
bool defCond = true;
@@ -188,51 +256,40 @@ static bool checkPrivate(SgStatement *st,
if (varUse.find(privElem) == varUse.end())
useCond = false;
if (var == FOR_NODE)
if (!defCond && !useCond)
{
if (!defCond && !useCond)
if (attributeStatement->localLineNumber() != SPF_OMP_DIR)
{
if (attributeStatement->localLineNumber() != 888)
{
__spf_print(1, "variable '%s' is not used in loop on line %d\n", privElem.c_str(), attributeStatement->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"variable '%s' is not used in loop", to_wstring(privElem.c_str()).c_str());
__spf_print(1, "variable '%s' is not used in loop on line %d\n", privElem.c_str(), attributeStatement->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"variable '%s' is not used in loop", to_wstring(privElem.c_str()).c_str());
__spf_printToLongBuf(messageR, R21, to_wstring(privElem.c_str()).c_str());
__spf_printToLongBuf(messageR, R21, to_wstring(privElem.c_str()).c_str());
messagesForFile.push_back(Messages(WARR, attributeStatement->lineNumber(), messageR, messageE, 1002));
}
else
wrongPrivFromOmpParallel.insert(privElem);
}
else if (!defCond && useCond)
{
if (attributeStatement->localLineNumber() != 888)
{
__spf_print(1, "variable '%s' is not changed in loop on line %d\n", privElem.c_str(), attributeStatement->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"variable '%s' is not changed in loop", to_wstring(privElem.c_str()).c_str());
__spf_printToLongBuf(messageR, R23, to_wstring(privElem.c_str()).c_str());
messagesForFile.push_back(Messages(ERROR, attributeStatement->lineNumber(), messageR, messageE, 1003));
retVal = false;
}
else
wrongPrivFromOmpParallel.insert(privElem);
messagesForFile.push_back(Messages(WARR, attributeStatement->lineNumber(), messageR, messageE, 1002));
}
else
wrongPrivFromOmpParallel.insert(privElem);
}
else
else if (!defCond && useCond)
{
if (!defCond)
if (attributeStatement->localLineNumber() != SPF_OMP_DIR)
{
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "variable declaration or", RR1_2, "DO statement", RR1_3, attributeStatement->lineNumber());
__spf_print(1, "variable '%s' is not changed in loop on line %d\n", privElem.c_str(), attributeStatement->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"variable '%s' is not changed in loop", to_wstring(privElem.c_str()).c_str());
__spf_printToLongBuf(messageR, R23, to_wstring(privElem.c_str()).c_str());
messagesForFile.push_back(Messages(ERROR, attributeStatement->lineNumber(), messageR, messageE, 1003));
retVal = false;
}
else
wrongPrivFromOmpParallel.insert(privElem);
}
}
if (var == FOR_NODE && wrongPrivFromOmpParallel.size()) // remove unnecessary
if (wrongPrivFromOmpParallel.size()) // remove unnecessary
{
if (wrongPrivFromOmpParallel.size() == privates.size()) // remove all
attributeStatement->expr(0)->lhs()->setLhs(NULL);
@@ -252,7 +309,7 @@ static bool checkPrivate(SgStatement *st,
}
else
{
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "variable declaration or", RR1_2, "DO statement", RR1_3, attributeStatement->lineNumber());
BAD_POSITION_FULL(ERROR, "before", RR1_1, "", L"", "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
@@ -316,7 +373,7 @@ static bool checkReduction(SgStatement *st,
}
else
{
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "", L"", "DO statement", RR1_3, attributeStatement->lineNumber());
BAD_POSITION_FULL(ERROR, "before", RR1_1, "", L"", "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
@@ -713,7 +770,7 @@ static bool checkShadowAcross(SgStatement *st,
}
else
{
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "", L"", "DO statement", RR1_3, attributeStatement->lineNumber());
BAD_POSITION_FULL(ERROR, "before", RR1_1, "", L"", "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
@@ -937,7 +994,7 @@ static bool checkRemote(SgStatement *st,
}
else
{
BAD_POSITION_FULL(1, ERROR, "before", RR1_1, "", L"", "DO statement", RR1_3, attributeStatement->lineNumber());
BAD_POSITION_FULL(ERROR, "before", RR1_1, "", L"", "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
@@ -1169,7 +1226,7 @@ static bool checkParallelRegions(SgStatement *st,
}
else
{
BAD_POSITION_FULL(1, ERROR, "after", RR1_4, "", L"", "all declaration statements", RR1_5, st->lineNumber());
BAD_POSITION_FULL(ERROR, "after", RR1_4, "", L"", "all declaration statements", RR1_5, st->lineNumber());
retVal = false;
}
@@ -1246,17 +1303,17 @@ static bool checkFissionPrivatesExpansion(SgStatement *st,
addSPFtoAttr(s, currFile, usersDirectives);
SgForStmt *forSt = (SgForStmt*)st;
if (vars.size() > countPerfectLoopNest(forSt))
const int nestedCount = countPerfectLoopNest(forSt);
if (vars.size() > nestedCount)
{
__spf_print(1, "bad directive expression: expected %d nested loops on line %d but got %d on line %d\n",
(int)vars.size(), attributeStatement->lineNumber(), countPerfectLoopNest(forSt), st->lineNumber());
(int)vars.size(), attributeStatement->lineNumber(), nestedCount, st->lineNumber());
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"bad directive expression: expected %d nested loops on line %d but got %d",
(int)vars.size(), attributeStatement->lineNumber(), countPerfectLoopNest(forSt));
(int)vars.size(), attributeStatement->lineNumber(), nestedCount);
__spf_printToLongBuf(messageR, R77,
(int)vars.size(), attributeStatement->lineNumber(), countPerfectLoopNest(forSt));
__spf_printToLongBuf(messageR, R77, (int)vars.size(), attributeStatement->lineNumber(), nestedCount);
messagesForFile.push_back(Messages(ERROR, st->lineNumber(), messageR, messageE, 1043));
@@ -1708,18 +1765,29 @@ static inline bool processStat(SgStatement *st, const string &currFile,
SgAttribute *attr = st->getAttribute(i);
SgStatement *attributeStatement = (SgStatement *)(attr->getAttributeData());
int type = st->attributeType(i);
int count;
if (type == SPF_ANALYSIS_DIR)
{
// !$SPF ANALYSIS
// PRIVATE(VAR)
set<Symbol*> privates;
fillPrivatesFromComment(new Statement(attributeStatement), privates);
fillPrivatesFromComment(new Statement(attributeStatement), privates, ACC_PRIVATE_OP);
if (privates.size())
{
bool result = checkPrivate(st, attributeStatement, privates, messagesForFile);
retVal = retVal && result;
}
// PROCESS_PRIVATE(VAR)
privates.clear();
fillPrivatesFromComment(new Statement(attributeStatement), privates, SPF_PROCESS_PRIVATE_OP);
if (privates.size())
{
bool result = checkProcessPrivate(st, attributeStatement, privates, messagesForFile);
retVal = retVal && result;
}
// REDUCTION(OP(VAR), MIN/MAXLOC(VAR, ARRAY, CONST))
map<string, set<Symbol*>> reduction;
map<string, set<tuple<Symbol*, Symbol*, int>>> reductionLoc;
@@ -1740,10 +1808,27 @@ static inline bool processStat(SgStatement *st, const string &currFile,
bool result = checkParameter(st, attributeStatement, assigns, messagesForFile);
retVal = retVal && result;
}
// COVER
if (isSPF_OP(attributeStatement, SPF_COVER_OP) && (count = countSPF_OP(st, SPF_ANALYSIS_DIR, SPF_COVER_OP)))
{
attributeStatement->setLocalLineNumber(-1);
if (count > 1 || st->variant() != FOR_NODE)
{
BAD_POSITION_FULL(ERROR, "once", RR1_7, "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
else
{
bool result = checkCover(st, attributeStatement, getCoverPropertyFromComment(new Statement(attributeStatement)), messagesForFile);
retVal = retVal && result;
}
}
}
else if (type == SPF_PARALLEL_DIR)
{
// !$SPF PARALLEL
// SHADOW (VAR(list of shadows)) / ACROSS (VAR(list of shadows))
vector<pair<pair<Symbol*, string>, vector<pair<int, int>>>> data;
fillShadowAcrossFromComment(SHADOW_OP, new Statement(attributeStatement), data);
@@ -1766,7 +1851,6 @@ static inline bool processStat(SgStatement *st, const string &currFile,
else if (type == SPF_TRANSFORM_DIR)
{
// !$SPF TRANSFORM
int count;
// NOINLINE
if (isSPF_NoInline(new Statement(st)))
@@ -1775,7 +1859,7 @@ static inline bool processStat(SgStatement *st, const string &currFile,
const int prevVar = prev->variant();
if (prevVar != PROC_HEDR && prevVar != FUNC_HEDR)
{
BAD_POSITION_FULL(1, ERROR, "after", RR1_4, "", L"", "function statements", RR1_6, attributeStatement->lineNumber());
BAD_POSITION_FULL(ERROR, "after", RR1_4, "", L"", "function statements", RR1_6, attributeStatement->lineNumber());
retVal = false;
}
}
@@ -1786,7 +1870,7 @@ static inline bool processStat(SgStatement *st, const string &currFile,
attributeStatement->setLocalLineNumber(-1);
if (count > 1 || st->variant() != FOR_NODE)
{
BAD_POSITION_FULL(1, ERROR, "once", RR1_7, "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
BAD_POSITION_FULL(ERROR, "once", RR1_7, "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
else
@@ -1802,7 +1886,7 @@ static inline bool processStat(SgStatement *st, const string &currFile,
attributeStatement->setLocalLineNumber(-1);
if (count > 1 || st->variant() != FOR_NODE)
{
BAD_POSITION_FULL(1, ERROR, "once", RR1_7, "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
BAD_POSITION_FULL(ERROR, "once", RR1_7, "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
else
@@ -1815,10 +1899,10 @@ static inline bool processStat(SgStatement *st, const string &currFile,
// SHRINK
if (isSPF_OP(attributeStatement, SPF_SHRINK_OP))
{
attributeStatement->setLocalLineNumber(-1); // is it needed?
attributeStatement->setLocalLineNumber(-1);
if (st->variant() != FOR_NODE)
{
BAD_POSITION_FULL(1, ERROR, "", "", "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
BAD_POSITION_FULL(ERROR, "", "", "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
else
@@ -1834,7 +1918,18 @@ static inline bool processStat(SgStatement *st, const string &currFile,
attributeStatement->setLocalLineNumber(-1);
if (st->variant() != FOR_NODE)
{
BAD_POSITION_FULL(1, ERROR, "", "", "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
BAD_POSITION_FULL(ERROR, "", "", "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
}
// MERGE
if (isSPF_OP(attributeStatement, SPF_MERGE_OP))
{
attributeStatement->setLocalLineNumber(-1);
if (st->variant() != FOR_NODE)
{
BAD_POSITION_FULL(ERROR, "", "", "before", RR1_1, "DO statement", RR1_3, attributeStatement->lineNumber());
retVal = false;
}
}
@@ -1948,6 +2043,69 @@ bool check_par_reg_dirs(SgFile *file, vector<Messages> &messagesForFile)
return noError;
}
static void distributeAnalysisWithCover(SgFile* file)
{
int funcNum = file->numberOfFunctions();
const string currFile = file->filename();
for (int i = 0; i < funcNum; ++i)
{
SgStatement* st = file->functions(i);
SgStatement* lastNode = st->lastNodeOfStmt();
map<SgStatement*, pair<set<SgStatement*>, int>> spfAnalysis;
do
{
st = st->lexNext();
if (st == NULL)
{
__spf_print(1, "internal error in analysis, parallel directives will not be generated for this file!\n");
break;
}
if (st->variant() == CONTAINS_STMT)
break;
if (st->variant() == FOR_NODE)
{
pair<set<SgStatement*>, int> newData = { set<SgStatement*>(), 0 };
for (auto& data : getAttributes<SgStatement*, SgStatement*>(st, set<int>{ SPF_ANALYSIS_DIR }))
{
newData.first.insert(data);
int cover = getCoverPropertyFromComment(new Statement(data));
if (cover != 0)
newData.second = cover;
}
if (newData.first.size())
spfAnalysis[st] = newData;
}
} while (st != lastNode);
for (auto& data : spfAnalysis)
{
SgForStmt* st = isSgForStmt(data.first);
checkNull(st, convertFileName(__FILE__).c_str(), __LINE__);
int level = st->isPerfectLoopNest();
if (data.second.second < level && data.second.second != 0)
level = data.second.second;
for (int z = 0; z < level - 1; ++z)
{
st = isSgForStmt(st->lexNext());
checkNull(st, convertFileName(__FILE__).c_str(), __LINE__);
for (auto& dirs : data.second.first)
{
auto copy = dirs->copyPtr();
copy->setLocalLineNumber(SPF_USER_DIR_COPY);
st->addAttribute(copy->variant(), copy, sizeof(SgStatement));
}
}
}
}
}
bool preprocess_spf_dirs(SgFile *file, const map<string, CommonBlock*> &commonBlocks, vector<Messages> &messagesForFile, const set<string>& allFileNames,
map<pair<string, int>, set<SgStatement*>>& usersDirectives)
{
@@ -1990,6 +2148,10 @@ bool preprocess_spf_dirs(SgFile *file, const map<string, CommonBlock*> &commonBl
findModulesInFile(file, modules);
bool result = processModules(modules, currFile, &commonBlocks, messagesForFile, allFileNames, usersDirectives);
noError = noError && result;
if (noError)
distributeAnalysisWithCover(file);
return noError;
}
@@ -2090,7 +2252,7 @@ vector<SgStatement*> filterUserSpf(const vector<SgStatement*> &toFilter, bool wi
{
vector<SgStatement*> ret;
for (auto &elem : toFilter)
if (elem->localLineNumber() == 777 || (elem->localLineNumber() == 888 && with_omp)) // user and omp
if (elem->localLineNumber() == SPF_USER_DIR || (elem->localLineNumber() == SPF_OMP_DIR && with_omp)) // user and omp
ret.push_back(elem);
return ret;
@@ -2121,6 +2283,23 @@ static bool moveSpfParameterForImplicitLoops(SgStatement* st, SgStatement* toAdd
return moveNext;
}
static void insertBefore(SgStatement* st, SgStatement* toAdd)
{
if (toAdd == NULL)
return;
st->insertStmtBefore(*toAdd, *st->controlParent());
if (st->variant() == FOR_NODE)
{
auto com = st->comments();
if (com)
{
st->lexPrev()->addComment(com);
st->delComments();
}
}
}
void revertion_spf_dirs(SgFile *file,
map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>> declaredArrays,
map<SgStatement*, set<tuple<int, string, string>>> declaratedArraysSt)
@@ -2163,7 +2342,7 @@ void revertion_spf_dirs(SgFile *file,
toAdd = UniteAttributes(sameAtt);
if (toAdd)
if (!moveSpfParameterForImplicitLoops(st, toAdd))
st->insertStmtBefore(*toAdd, *st->controlParent());
insertBefore(st, toAdd);
}
//check previosly directives SPF_PARALLEL
@@ -2174,7 +2353,7 @@ void revertion_spf_dirs(SgFile *file,
{
if (toAdd)
toAdd = UniteAttributes(sameAtt);
st->insertStmtBefore(*toAdd, *st->controlParent());
insertBefore(st, toAdd);
}
}
@@ -2188,7 +2367,7 @@ void revertion_spf_dirs(SgFile *file,
SgStatement *toAdd = &(data->copy());
if (toAdd)
st->insertStmtBefore(*toAdd, *st->controlParent());
insertBefore(st, toAdd);
}
}
}

View File

@@ -29,11 +29,12 @@ using std::map;
using std::make_pair;
static vector<SgExpression*>
compliteTieListNoDist(const LoopGraph* currLoop, const vector<LoopGraph*>& loops,
compliteTieListNoDist(const LoopGraph* currLoop,
const set<string>& privates,
const vector<LoopGraph*>& loops,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const map<string, set<SgSymbol*>>& byUseInFunc,
File* file, const pair<int, int>& lineRange,
const set<DIST::Array*>& onlyFor)
File* file, const pair<int, int>& lineRange)
{
vector<SgExpression*> tieList;
@@ -44,6 +45,9 @@ compliteTieListNoDist(const LoopGraph* currLoop, const vector<LoopGraph*>& loops
for (auto& elem : currLoop->usedArraysAll)
{
if (privates.find(elem->GetShortName()) != privates.end())
continue;
auto type = elem->GetDeclSymbol(currLoop->fileName, lineRange, getAllFilesInProject())->GetOriginal()->type();
SgSymbol* arrayS = getFromModule(byUseInFunc, findSymbolOrCreate(file, elem->GetShortName(), type));
SgArrayRefExp* array = new SgArrayRefExp(*arrayS);
@@ -233,11 +237,8 @@ ParallelDirective::genDirectiveNoDist(File* file, LoopGraph* currLoop, DIST::Arr
if (parallel[i] != "*")
loopsTie.push_back(loops[i]);
set<DIST::Array*> onlyFor;
vector<SgExpression*> tieList;
tieList = compliteTieListNoDist(currLoop, loopsTie, arrayLinksByFuncCalls, byUseInFunc, file, lineRange, onlyFor);
tieList = compliteTieListNoDist(currLoop, uniqNamesOfPrivates, loopsTie, arrayLinksByFuncCalls, byUseInFunc, file, lineRange);
if (tieList.size())
{

View File

@@ -328,7 +328,7 @@ static void processActualParams(SgExpression *parList, const map<string, vector<
currParams.parametersT[num] = parf;
if (parf == SCALAR_INT_T)
{
SgExpression* result = CalculateInteger(ex->lhs());
SgExpression* result = CalculateInteger(ex->lhs()->copyPtr());
if (result != ex->lhs())
{
currParams.parameters[num] = new int[1];

View File

@@ -65,26 +65,13 @@ static void findUsedArraysInParallelLoops(LoopGraph* loop, set<DIST::Array*>& re
}
static void preventLoopsFromParallelizations(LoopGraph* loop, const set<DIST::Array*>& prevent,
vector<Directive*>& createdDirectives,vector<Messages>& messagesForFile)
vector<Messages>& messagesForFile)
{
if (loop->directive)
{
if (IsSetsIntersect(prevent, loop->usedArraysAll))
{
// prevent this loop
int loopLine = loop->lineNum;
for (auto dir_it = createdDirectives.begin(); dir_it != createdDirectives.end(); dir_it++)
{
if ((*dir_it)->line == loopLine)
{
delete *dir_it;
dir_it = createdDirectives.erase(dir_it);
break;
}
}
delete loop->directive;
loop->directive = NULL;
@@ -118,14 +105,13 @@ static void preventLoopsFromParallelizations(LoopGraph* loop, const set<DIST::Ar
__spf_printToLongBuf(bufR, R202, to_wstring(array_ref).c_str());
messagesForFile.push_back(Messages(WARR, loop->lineNum, bufR, bufE, 3023));
loop->hasAccessToSubArray = true;
}
}
}
else
{
for (LoopGraph* child : loop->children)
preventLoopsFromParallelizations(child, prevent, createdDirectives, messagesForFile);
}
for (LoopGraph* child : loop->children)
preventLoopsFromParallelizations(child, prevent, messagesForFile);
}
struct DimConf
@@ -171,9 +157,9 @@ pickBest(const map<DimConf, map<FuncInfo*, set<DIST::Array*>>>& arrs)
}
void SelectArrayConfForParallelization(SgProject* proj, map<string, vector<FuncInfo*>>& funcByFile,
const map<string, vector<LoopGraph*>>& loopGraph, map<std::string, vector<Directive*>>& createdDirectives,
map<string, vector<Messages>>& allMessages, const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
const vector<ParallelRegion*>& regions)
const map<string, vector<LoopGraph*>>& loopGraph,
map<string, vector<Messages>>& allMessages,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
map<string, FuncInfo*> funcByName;
for (const auto& byFile : funcByFile)
@@ -267,121 +253,43 @@ void SelectArrayConfForParallelization(SgProject* proj, map<string, vector<FuncI
for (const auto& byFile : loopGraph)
{
vector<Messages>& fileM = getObjectForFileFromMap(byFile.first.c_str(), allMessages);
auto dirs_it = createdDirectives.find(byFile.first);
if (dirs_it != createdDirectives.end())
SgFile::switchToFile(byFile.first);
auto& loops = byFile.second;
auto file_funcs_it = funcByFile.find(byFile.first);
if (file_funcs_it == funcByFile.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); // no such file in funcByFile
map<FuncInfo*, set<DIST::Array*>> usedInLoops;
for (const auto& loop : loops)
{
SgFile::switchToFile(byFile.first);
SgStatement* search_func = loop->loop->GetOriginal();
auto& loops = byFile.second;
while (search_func && (!isSgProgHedrStmt(search_func)))
search_func = search_func->controlParent();
auto file_funcs_it = funcByFile.find(byFile.first);
if (!search_func)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //loop statement outside any function statement
if (file_funcs_it == funcByFile.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); // no such file in funcByFile
map<FuncInfo*, set<DIST::Array*>> usedInLoops;
for (const auto& loop : loops)
bool loop_analyzed = false;
for (const auto& byFunc : file_funcs_it->second)
{
SgStatement* search_func = loop->loop->GetOriginal();
while (search_func && (!isSgProgHedrStmt(search_func)))
search_func = search_func->controlParent();
if (!search_func)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //loop statement outside any function statement
bool loop_analyzed = false;
for (const auto& byFunc : file_funcs_it->second)
if (byFunc->funcPointer->GetOriginal() == search_func)
{
if (byFunc->funcPointer->GetOriginal() == search_func)
{
auto prevent_it = preventFromParallelization.find(byFunc);
if (prevent_it != preventFromParallelization.end())
preventLoopsFromParallelizations(loop, prevent_it->second, dirs_it->second, fileM);
auto prevent_it = preventFromParallelization.find(byFunc);
if (prevent_it != preventFromParallelization.end())
preventLoopsFromParallelizations(loop, prevent_it->second, fileM);
loop_analyzed = true;
break;
}
}
if (!loop_analyzed)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //no func found for loop
}
}
}
}
void removeRegionsWithoutDirs(const map<string, vector<Directive*>>& createdDirectives,
vector<ParallelRegion*>& parallelRegions,
const map<string, vector<FuncInfo*>>& allFuncInfo,
map<string, vector<Messages>>& SPF_messages)
{
set<ParallelRegion*> empty_regs(parallelRegions.begin(), parallelRegions.end());
for (const auto& byFile : createdDirectives)
for (const auto& dir : byFile.second)
empty_regs.erase(getRegionByLine(parallelRegions, byFile.first, dir->line));
set<int> idxToDel;
for (int z = 0; z < parallelRegions.size(); ++z)
{
if (empty_regs.find(parallelRegions[z]) != empty_regs.end())
{
__spf_print(1, " no parallel directives for parallel region '%s'\n", parallelRegions[z]->GetName().c_str());
if (parallelRegions[z]->GetId() == 0) // DEFAULT
{
wstring bufE, bufR;
__spf_printToLongBuf(bufE, L"Can not find arrays or free loops for distribution in this project");
__spf_printToLongBuf(bufR, R130);
for (auto& funcByFile : allFuncInfo)
{
vector<Messages>& fileM = getObjectForFileFromMap(funcByFile.first.c_str(), SPF_messages);
for (auto& func : funcByFile.second)
{
auto stat = func->funcPointer->GetOriginal();
if (stat->variant() == PROG_HEDR)
fileM.push_back(Messages(ERROR, stat->lineNumber(), bufR, bufE, 3010));
}
loop_analyzed = true;
break;
}
}
else
{
wstring bufE, bufR;
__spf_printToLongBuf(bufE, L"Can not find arrays or free loops for distribution in this region");
__spf_printToLongBuf(bufR, R131);
for (auto& linesByFile : parallelRegions[z]->GetAllLines())
{
vector<Messages>& fileM = getObjectForFileFromMap(linesByFile.first.c_str(), SPF_messages);
for (auto& lines : linesByFile.second)
if (!lines.isImplicit())
fileM.push_back(Messages(ERROR, lines.lines.first, bufR, bufE, 3010));
}
}
idxToDel.insert(z);
if (!loop_analyzed)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__); //no func found for loop
}
}
vector<ParallelRegion*> newParReg;
for (int z = 0; z < parallelRegions.size(); ++z)
{
if (idxToDel.find(z) != idxToDel.end())
{
ParallelRegion* regToDel = parallelRegions[z];
#ifdef _WIN32
removeFromCollection(parallelRegions[z]);
#endif
delete parallelRegions[z];
}
else
newParReg.push_back(parallelRegions[z]);
}
parallelRegions.clear();
parallelRegions = newParReg;
if (parallelRegions.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}

View File

@@ -11,12 +11,6 @@
void SelectArrayConfForParallelization(SgProject* proj, std::map<std::string, std::vector<FuncInfo*>>& funcByFile,
const std::map<std::string, std::vector<LoopGraph*>>& loopGraph,
std::map<std::string, std::vector<Directive*>>& createdDirectives,
const std::map<std::string, std::vector<LoopGraph*>>& loopGraph,
std::map<std::string, std::vector<Messages>>& allMessages,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, const std::vector<ParallelRegion*>& regions);
void removeRegionsWithoutDirs(const std::map<std::string, std::vector<Directive*>>& createdDirectives,
std::vector<ParallelRegion*>& parallelRegions,
const std::map<std::string, std::vector<FuncInfo*>>& allFuncInfo,
std::map<std::string, std::vector<Messages>>& SPF_messages);
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);

View File

@@ -207,6 +207,12 @@ static inline bool hasGoto(SgStatement *begin, SgStatement *end,
has = true;
}
if (curr->variant() == RETURN_STAT)
{
linesOfIntGoTo.push_back(curr->lineNumber());
has = true;
}
if (curr->variant() == CYCLE_STMT)
cycleStmts.push_back(curr->lineNumber());
curr = curr->lexNext();
@@ -866,6 +872,13 @@ static void printToBuffer(const LoopGraph *currLoop, const int childSize, char b
else
loopState = 1;
}
else if (PASSES_DONE[SELECT_ARRAY_DIM_CONF])
{
if (currLoop->hasLimitsToParallel())
loopState = 2;
else
loopState = 1;
}
else
{
if (currLoop->hasLimitsToParallel())

View File

@@ -72,6 +72,7 @@ public:
inDvmhRegion = 0;
isFor = false;
inCanonicalFrom = false;
hasAccessToSubArray = false;
}
~LoopGraph()
@@ -111,7 +112,7 @@ public:
{
return hasUnknownArrayDep || hasUnknownScalarDep || hasGoto || hasPrints || (hasConflicts.size() != 0) || hasStops || hasNonPureProcedures ||
hasUnknownArrayAssigns || hasNonRectangularBounds || hasIndirectAccess || hasWritesToNonDistribute || hasDifferentAlignRules || hasDvmIntervals ||
!isFor || lastprivateScalars.size();
!isFor || lastprivateScalars.size() || hasAccessToSubArray;
}
bool hasLimitsToSplit() const
@@ -171,6 +172,9 @@ public:
if (lastprivateScalars.size())
messages->push_back(Messages(NOTE, line, R199, L"lastprivate scalar dependency prevents parallelization of this loop", 3006));
if(hasAccessToSubArray)
messages->push_back(Messages(NOTE, line, R204, L"Array's memory intersections prevents this loop from parallelization", 3024));
}
void setNewRedistributeRules(const std::vector<std::pair<DIST::Array*, DistrVariant*>> &newRedistributeRules)
@@ -211,7 +215,7 @@ public:
}
ParallelDirective *parDirective = baseDirs[0];
for (int z = 1; z < baseDirs.size(); ++z)
for (int z = 1; z < baseDirs.size() && baseDirs[z]; ++z)
{
ParallelDirective *old = parDirective;
parDirective = *parDirective + *baseDirs[z];
@@ -443,6 +447,8 @@ public:
bool isFor;
bool inCanonicalFrom;
// make sense only for NODIST regime
bool hasAccessToSubArray;
std::vector<LoopGraph*> children;
std::vector<LoopGraph*> funcChildren;

View File

@@ -2320,20 +2320,20 @@ static void createDeclarations(const map<SgStatement*, set<SgSymbol*>>& newSymbs
if (t->selector())
{
if (t->selector()->variant() == CONST_REF)
t->setSelector(CalculateInteger(t->selector()));
t->setSelector(CalculateInteger(t->selector()->copyPtr()));
}
if (t->length())
{
if (t->length()->variant() == CONST_REF)
{
auto result = CalculateInteger(t->length());
auto result = CalculateInteger(t->length()->copyPtr());
if (result->variant() == INT_VAL)
t->setLength(result);
}
}
}
auto result = CalculateInteger(list->lhs());
auto result = CalculateInteger(list->lhs()->copyPtr());
list->setLhs(result);
}
list = list->rhs();

View File

@@ -16,6 +16,7 @@
#include "loop_analyzer_internal.h"
#include "loop_analyzer.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
using std::vector;
using std::pair;
@@ -125,9 +126,8 @@ static void addInfoToMap(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, S
__spf_print(DEB, "RemoteAccess[%d]: true for dim %d and array %s, loop line %d\n", __LINE__, dimNum, symb->identifier(), position->lineNumber());
}
enum { READ_OP, WRITE_OP, UNREC_OP };
static void addInfoToVectors(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, SgForStmt *position, SgSymbol *symb,
const int dimNum, const pair<int, int> newCoef, int type, const int maxDimSize, const double currentW)
void addInfoToVectors(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, SgForStmt *position, SgSymbol *symb,
const int dimNum, const pair<int, int> newCoef, int type, const int maxDimSize, const double currentW)
{
auto itLoop = loopInfo.find(position);
if (itLoop == loopInfo.end())
@@ -159,10 +159,10 @@ static void addInfoToVectors(map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInf
}
static vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, SgExpression *subscr,
SgArrayRefExp *arrayRefIn, const int side, const int dimNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo,
const int currLine, const int numOfSubscriptions, const double currentW)
vector<int> matchSubscriptToLoopSymbols(const vector<SgForStmt*> &parentLoops, SgExpression *subscr,
SgArrayRefExp *arrayRefIn, const int side, const int dimNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo,
const int currLine, const int numOfSubscriptions, const double currentW)
{
SgExpression *origSubscr = subscr;
ArrayRefExp *arrayRef = new ArrayRefExp(arrayRefIn);
@@ -557,7 +557,7 @@ static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp,
__spf_print(PRINT_ARRAY_ARCS, "\n");
}
void findArrayRef(const vector<SgForStmt*> &parentLoops, SgExpression *currExp, const int lineNum, const int side,
static void findArrayRef(const vector<SgForStmt*> &parentLoops, SgExpression *currExp, const int lineNum, const int side,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, const set<string> &privatesVars,
vector<set<string>>& privatesVarsForLoop, map<int, LoopGraph*> &sortedLoopGraph,
const map<string, vector<SgExpression*>> &commonBlocks,
@@ -2559,9 +2559,9 @@ SgExpression* getTypeLengthExpr(SgType *t)
if (!len && !selector) //the number of bytes is not specified in type declaration statement
return (new SgValueExp(getIntrinsicTypeSize(t)));
else if (len && !selector) //INTEGER*2,REAL*8,CHARACTER*(N+1)
return CalculateInteger(len);
return CalculateInteger(len->copyPtr());
else
return CalculateInteger(getLengthOfKindExpr(t, selector, len)); //specified kind or/and len
return CalculateInteger(getLengthOfKindExpr(t, selector, len)->copyPtr()); //specified kind or/and len
}
int getSizeOfType(SgType *t)
@@ -2599,7 +2599,7 @@ static bool findOmpThreadPrivDecl(SgStatement* st, map<SgStatement*, set<string>
{
st = st->lexNext();
auto res = parseOmpDirs(st, dummy);
auto res = parseOmpInStatement(st, dummy);
for (auto& dir : res)
for (auto& var : dir.threadPrivVars)
it->second.insert(var);

View File

@@ -58,13 +58,13 @@ void changeLoopWeight(double& currentWeight, const std::map<int, LoopGraph*>& so
SgStatement* takeOutConditions(std::stack<SgExpression*>& conditions, std::stack<SgStatement*>& ifBlocks, SgStatement* st);
void findArrayRef(const std::vector<SgForStmt*>& parentLoops, SgExpression* currExp, const int lineNum, const int side,
std::map<SgForStmt*, std::map<SgSymbol*, ArrayInfo>>& loopInfo, const std::set<std::string>& privatesVars,
std::vector<std::set<std::string>>& privatesVarsForLoop, std::map<int, LoopGraph*>& sortedLoopGraph,
const std::map<std::string, std::vector<SgExpression*>>& commonBlocks,
const std::map<std::tuple<int, std::string, std::string>, std::pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
bool wasDistributedArrayRef, std::map<std::string, std::pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays,
std::set<std::string>& mappedDistrbutedArrays, SgStatement* currentSt, const ParallelRegion* reg, const double currentW,
const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls);
enum { READ_OP, WRITE_OP, UNREC_OP };
void addInfoToVectors(std::map<SgForStmt*, std::map<SgSymbol*, ArrayInfo>>& loopInfo, SgForStmt* position, SgSymbol* symb,
const int dimNum, const std::pair<int, int> newCoef, int type, const int maxDimSize, const double currentW);
std::vector<int> matchSubscriptToLoopSymbols(const std::vector<SgForStmt*>& parentLoops, SgExpression* subscr,
SgArrayRefExp* arrayRefIn, const int side, const int dimNum,
std::map<SgForStmt*, std::map<SgSymbol*, ArrayInfo>>& loopInfo,
const int currLine, const int numOfSubscriptions, const double currentW);
bool hasNonPureFunctions(SgExpression* ex, LoopGraph* loopRef, std::vector<Messages>& messagesForFile, const int line, const std::map<std::string, FuncInfo*>& funcByName);

View File

@@ -1,4 +1,4 @@
#include <cstdio>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
@@ -36,7 +36,6 @@ extern void createMapLoopGraph(map<int, LoopGraph*>& sortedLoopGraph, const vect
extern map<DIST::Array*, std::tuple<int, string, string>> tableOfUniqNamesByArray;
static void convertOneLoopNoDist(LoopGraph* currLoop, map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>& outInfo,
const map<SgSymbol*, ArrayInfo>& toConvert,
const set<string>& privateArrays,
const map<string, vector<SgExpression*>>& commonBlocks,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
@@ -109,7 +108,6 @@ static void convertOneLoopNoDist(LoopGraph* currLoop, map<LoopGraph*, map<DIST::
static map<LoopGraph*, map<DIST::Array*, ArrayInfo*>>
convertLoopInfoNoDist(const map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
const map<int, LoopGraph*>& sortedLoopGraph,
const set<string>& privateArrays,
const map<string, vector<SgExpression*>>& commonBlocks,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
@@ -123,12 +121,188 @@ convertLoopInfoNoDist(const map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo
if (itGraph == sortedLoopGraph.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
convertOneLoopNoDist(itGraph->second, outInfo, it->second, privateArrays, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
convertOneLoopNoDist(itGraph->second, outInfo, it->second, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
}
return outInfo;
}
static vector<int> matchArrayToLoopSymbols(const vector<SgForStmt*> &parentLoops, vector<set<string>>& privatesVarsForLoop,
SgExpression *currExp, const int side,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> &loopInfo, const int currLine,
map<int, LoopGraph*> &sortedLoopGraph, const ParallelRegion *reg, const double currentW,
const map<DIST::Array*, set<DIST::Array*>> &arrayLinksByFuncCalls)
{
SgArrayRefExp *arrayRef = (SgArrayRefExp*)currExp;
int numOfSubs = arrayRef->numberOfSubscripts();
currExp = currExp->lhs();
vector<int> wasFoundForLoop(parentLoops.size());
vector<int> matched(numOfSubs);
vector<int> matchedToDim(parentLoops.size());
std::fill(wasFoundForLoop.begin(), wasFoundForLoop.end(), 0);
std::fill(matched.begin(), matched.end(), -1);
std::fill(matchedToDim.begin(), matchedToDim.end(), -1);
int maxMatched = 0;
int sumMatched = 0;
for (int i = 0; i < numOfSubs; ++i)
{
vector<int> matchToLoops = matchSubscriptToLoopSymbols(parentLoops, currExp->lhs(), arrayRef, side, i, loopInfo, currLine, numOfSubs, currentW);
for (int k = 0; k < matchToLoops.size(); ++k)
{
wasFoundForLoop[matchToLoops[k]]++;
matchedToDim[matchToLoops[k]] = i;
}
matched[i] = matchToLoops.size();
sumMatched += matchToLoops.size();
maxMatched = std::max(maxMatched, (int)matchToLoops.size());
currExp = currExp->rhs();
}
//full array is used, add unknown operations to all loops
if (numOfSubs == 0)
{
SgSymbol *currOrigArrayS = OriginalSymbol(arrayRef->symbol());
auto arrType = isSgArrayType(currOrigArrayS->type());
if (arrType != NULL)
{
for (int d = 0; d < arrType->dimension(); ++d)
for (int i = 0; i < parentLoops.size(); ++i)
addInfoToVectors(loopInfo, parentLoops[i], currOrigArrayS, d, make_pair(0, 0), UNREC_OP, arrType->dimension(), currentW);
}
}
bool ifUnknownArrayAssignFound = false;
vector<int> canNotMapToLoop;
for (int i = 0; i < wasFoundForLoop.size(); ++i)
{
if (wasFoundForLoop[i] != 1 &&
privatesVarsForLoop[i].find(string(arrayRef->symbol()->identifier())) == privatesVarsForLoop[i].end())
{
auto itLoop = sortedLoopGraph.find(parentLoops[i]->lineNumber());
if (itLoop == sortedLoopGraph.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
ifUnknownArrayAssignFound = true;
if (side == LEFT)
itLoop->second->hasUnknownArrayAssigns = true;
itLoop->second->hasUnknownDistributedMap = true;
canNotMapToLoop.push_back(parentLoops[i]->lineNumber());
}
}
if (side == LEFT)
{
if (ifUnknownArrayAssignFound)
{
const string arrayRefS = arrayRef->unparse();
for (auto &line : canNotMapToLoop)
{
__spf_print(1, "WARN: can not map write to array '%s' to loop on line %d\n", arrayRefS.c_str(), line);
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"can not map write to array '%s' to this loop", to_wstring(arrayRefS).c_str());
__spf_printToLongBuf(messageR, R59, to_wstring(arrayRefS).c_str());
if (line > 0)
currMessages->push_back(Messages(WARR, line, messageR, messageE, 1025));
}
}
}
return wasFoundForLoop;
}
static void mapArrayRef(SgStatement* currentSt, SgExpression* currExp,
const vector<SgForStmt*>& parentLoops, const int side, const int lineNum,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
vector<set<string>>& privatesVarsForLoop,
map<int, LoopGraph*>& sortedLoopGraph, map<string, pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays,
set<string>& mappedDistrbutedArrays,
const ParallelRegion* reg, const double currentW, const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
const char* printSide = NULL;
if (PRINT_ARRAY_ARCS)
printBlanks(2, (int)parentLoops.size());
if (side == LEFT)
printSide = "W_OP";
else
printSide = "R_OP";
__spf_print(PRINT_ARRAY_ARCS, "%s to array <%s> on line %d: ", printSide, OriginalSymbol(currExp->symbol())->identifier(), lineNum);
bool wasMapped = false;
vector<int> matched = matchArrayToLoopSymbols(parentLoops, privatesVarsForLoop, currExp, side, loopInfo, lineNum, sortedLoopGraph, reg, currentW, arrayLinksByFuncCalls);
for (int z = 0; z < matched.size(); ++z)
wasMapped |= (matched[z] != 0);
if (parentLoops.size() == 0)
{
SgSymbol* symb = currExp->symbol();
if (symb->type()->variant() == T_ARRAY)
notMappedDistributedArrays[symb->identifier()] = make_pair(symb, currentSt);
}
else
{
if (wasMapped)
mappedDistrbutedArrays.insert(currExp->symbol()->identifier());
else
{
SgSymbol* symb = currExp->symbol();
if (symb->type()->variant() == T_ARRAY)
notMappedDistributedArrays[symb->identifier()] = make_pair(symb, currentSt);
}
}
__spf_print(PRINT_ARRAY_ARCS, "\n");
}
static void findArrayRef(const vector<SgForStmt*>& parentLoops, SgExpression* currExp, const int lineNum, const int side,
map<SgForStmt*, map<SgSymbol*, ArrayInfo>>& loopInfo,
vector<set<string>>& privatesVarsForLoop, map<int, LoopGraph*>& sortedLoopGraph,
map<string, pair<SgSymbol*, SgStatement*>>& notMappedDistributedArrays,
set<string>& mappedDistrbutedArrays, SgStatement* currentSt, const ParallelRegion* reg, const double currentW,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls)
{
int nextSide = side;
if (isArrayRef(currExp))
{
mapArrayRef(currentSt, currExp, parentLoops, side, lineNum, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, reg, currentW, arrayLinksByFuncCalls);
nextSide = (side == LEFT) ? RIGHT : side;
}
bool needToContinue = true;
if (currExp->variant() == FUNC_CALL)
{
SgFunctionCallExp* funcExp = (SgFunctionCallExp*)currExp;
auto currFunc = isUserFunctionInProject(funcExp->funName()->identifier());
if (currFunc)
{
for (int z = 0; z < funcExp->numberOfArgs(); ++z)
{
if ((currFunc->funcParams.inout_types[z] & OUT_BIT) != 0)
nextSide = LEFT;
else
nextSide = RIGHT;
findArrayRef(parentLoops, funcExp->arg(z), lineNum, nextSide, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, currentSt, reg, currentW, arrayLinksByFuncCalls);
}
needToContinue = false;
}
}
if (needToContinue)
{
if (currExp->lhs())
findArrayRef(parentLoops, currExp->lhs(), lineNum, nextSide, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, currentSt, reg, currentW, arrayLinksByFuncCalls);
if (currExp->rhs())
findArrayRef(parentLoops, currExp->rhs(), lineNum, nextSide, loopInfo, privatesVarsForLoop, sortedLoopGraph,
notMappedDistributedArrays, mappedDistrbutedArrays, currentSt, reg, currentW, arrayLinksByFuncCalls);
}
}
void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tuple<int, string, string>, DIST::Array*>& createdArrays,
vector<Messages>& messagesForFile, const map<string, vector<FuncInfo*>>& AllfuncInfo,
const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
@@ -187,8 +361,6 @@ void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tupl
map<SgForStmt*, map<SgSymbol*, ArrayInfo>> loopInfo;
set<int> loopWithOutArrays;
set<string> privatesVars;
SgStatement* st = file->functions(i);
string funcName = "";
if (st->variant() == PROG_HEDR)
@@ -269,7 +441,7 @@ void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tupl
const int currV = st->variant();
if (currV == FOR_NODE)
{
tryToFindPrivateInAttributes(st, privatesVars);
//tryToFindPrivateInAttributes(st, privatesVars);
set<string> toAdd;
tryToFindPrivateInAttributes(st, toAdd);
@@ -312,12 +484,12 @@ void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tupl
else if (currV == ASSIGN_STAT)
{
if (st->expr(0))
findArrayRef(parentLoops, st->expr(0), st->lineNumber(), LEFT, loopInfo, privatesVars, privatesVarsForLoop,
sortedLoopGraph, commonBlocks, declaredArrays, false, notMappedDistributedArrays,
findArrayRef(parentLoops, st->expr(0), st->lineNumber(), LEFT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
if (st->expr(1))
findArrayRef(parentLoops, st->expr(1), st->lineNumber(), RIGHT, loopInfo, privatesVars, privatesVarsForLoop,
sortedLoopGraph, commonBlocks, declaredArrays, false, notMappedDistributedArrays,
findArrayRef(parentLoops, st->expr(1), st->lineNumber(), RIGHT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
else if (currV == IF_NODE || currV == ELSEIF_NODE || currV == LOGIF_NODE || currV == SWITCH_NODE)
@@ -325,8 +497,8 @@ void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tupl
SgStatement* before = NULL;
if (st->expr(0))
{
findArrayRef(parentLoops, st->expr(0), st->lineNumber(), RIGHT, loopInfo, privatesVars, privatesVarsForLoop,
sortedLoopGraph, commonBlocks, declaredArrays, false, notMappedDistributedArrays,
findArrayRef(parentLoops, st->expr(0), st->lineNumber(), RIGHT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
}
@@ -344,12 +516,12 @@ void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tupl
{
SgExpression* par = list->elem(z);
if ((func->funcParams.inout_types[z] & OUT_BIT) != 0)
findArrayRef(parentLoops, par, st->lineNumber(), LEFT, loopInfo, privatesVars, privatesVarsForLoop,
sortedLoopGraph, commonBlocks, declaredArrays, false, notMappedDistributedArrays,
findArrayRef(parentLoops, par, st->lineNumber(), LEFT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
else
findArrayRef(parentLoops, par, st->lineNumber(), RIGHT, loopInfo, privatesVars, privatesVarsForLoop,
sortedLoopGraph, commonBlocks, declaredArrays, false, notMappedDistributedArrays,
findArrayRef(parentLoops, par, st->lineNumber(), RIGHT, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
@@ -385,8 +557,8 @@ void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tupl
for (int z = 0; z < 3; ++z)
if (st->expr(z))
findArrayRef(parentLoops, st->expr(z), st->lineNumber(), side, loopInfo, privatesVars, privatesVarsForLoop,
sortedLoopGraph, commonBlocks, declaredArrays, false, notMappedDistributedArrays,
findArrayRef(parentLoops, st->expr(z), st->lineNumber(), side, loopInfo, privatesVarsForLoop,
sortedLoopGraph, notMappedDistributedArrays,
mappedDistrbutedArrays, st, currReg, currentWeight, arrayLinksByFuncCalls);
}
@@ -395,7 +567,7 @@ void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tupl
st = st->lexNext();
}
auto convertedLoopInfo = convertLoopInfoNoDist(loopInfo, sortedLoopGraph, privatesVars, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
auto convertedLoopInfo = convertLoopInfoNoDist(loopInfo, sortedLoopGraph, commonBlocks, declaredArrays, arrayLinksByFuncCalls, createdArrays);
processLoopInformationForFunction(convertedLoopInfo);
@@ -469,8 +641,26 @@ void loopAnalyzerNoDist(SgFile* file, vector<ParallelRegion*>& regions, map<tupl
sendMessage_2lvl(L"");
createParallelDirectivesNoDist(convertedLoopInfo, regions, arrayLinksByFuncCalls, messagesForFile);
if (parallizeFreeLoops)
selectFreeLoopsForParallelization(loopsForFunction, funcName, false, regions, messagesForFile);
for (auto& loopLine : loopWithOutArrays)
{
auto loopRef = sortedLoopGraph[loopLine];
if (loopRef->withoutDistributedArrays && loopRef->region && !loopRef->hasLimitsToParallel() && loopRef->lineNum > 0)
{
int nesting = 0;
LoopGraph* it = loopRef;
for (int z = 0; z < loopRef->perfectLoop; ++z, it->children.size() ? it = it->children[0] : it)
if (it->withoutDistributedArrays && it->region && !it->hasLimitsToParallel() && it->lineNum > 0)
++nesting;
map<LoopGraph*, map<DIST::Array*, ArrayInfo*>> convertedLoopInfo;
it = loopRef;
for (int z = 0; z < nesting; ++z, it->children.size() ? it = it->children[0] : it)
convertedLoopInfo.insert(make_pair(it, map<DIST::Array*, ArrayInfo*>()));
createParallelDirectivesNoDist(convertedLoopInfo, regions, map<DIST::Array*, set<DIST::Array*>>(), messagesForFile);
}
}
__spf_print(PRINT_PROF_INFO, "Function ended\n");
}

View File

@@ -631,7 +631,7 @@ int printParalleRegions(const char *fileName, vector<ParallelRegion*> &regions)
static int getIntVal(SgExpression *ex)
{
SgExpression* calc = CalculateInteger(ex);
SgExpression* calc = CalculateInteger(ex->copyPtr());
if (calc->variant() == INT_VAL)
return calc->valueInteger();
else

View File

@@ -114,7 +114,7 @@ static string getStringDeclaration(SgSymbol *symb)
if (SgFile::switchToFile(symb->getFile()->filename()) != -1)
{
auto stat = symb->makeVarDeclStmt();
auto res = CalculateInteger(stat->expr(0));
auto res = CalculateInteger(stat->expr(0)->copyPtr());
stat->setExpression(0, res);
decl = stat->unparse();
}

View File

@@ -31,7 +31,6 @@ 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;
extern "C" PTR_SYMB FileLastSymbol(...);
static int convertFile(int argc, char* argv[], const set<string>& filesInProj, const set<string>& moduleDeclsInFiles)
{
@@ -353,7 +352,6 @@ static int convertFile(int argc, char* argv[], const set<string>& filesInProj, c
fout_name_info_C = ChangeFto_info_C(fout_name); /*ACC*/
//set the last symbol of file
last_file_symbol = FileLastSymbol(file->filename());
initLibNames(); //for every file
InitDVM(file); //for every file
current_file = file; // global variable (used in SgTypeComplex)

View File

@@ -46,10 +46,11 @@
#include "DynamicAnalysis/gCov_parser_func.h"
#include "DynamicAnalysis/createParallelRegions.h"
#include "DirectiveProcessing/DirectiveAnalyzer.h"
#include "DirectiveProcessing/directive_analyzer.h"
#include "DirectiveProcessing/directive_creator.h"
#include "DirectiveProcessing/directive_creator_nodist.h"
#include "DirectiveProcessing/insert_directive.h"
#include "DirectiveProcessing/directive_omp_parser.h"
#include "VerificationCode/verifications.h"
#include "Distribution/CreateDistributionDirs.h"
#include "PrivateAnalyzer/private_analyzer.h"
@@ -83,6 +84,7 @@
#include "Transformations/private_removing.h"
#include "Transformations/fix_common_blocks.h"
#include "Transformations/convert_to_c.h"
#include "Transformations/set_implicit_none.h"
#include "Transformations/dead_code.h"
#include "RenameSymbols/rename_symbols.h"
@@ -377,68 +379,6 @@ string unparseProjectToString(SgFile *file, const int curr_regime)
return unparseProjectIfNeed(file, curr_regime, true, "", NULL, allIncludeFiles, true);
}
static bool isNotNullIntersection(const set<DIST::Array*> &first, const set<DIST::Array*> &second)
{
for (auto &elem1 : first)
if (second.find(elem1) != second.end())
return true;
return false;
}
static set<DIST::Array*> fillDistributedArraysD(const DataDirective& dataDirectives, bool onlyCommon = false)
{
set<DIST::Array*> distrArrays;
set<DIST::Array*> distrArraysD;
set<DIST::Array*> distrArraysAdded;
for (int z = 0; z < dataDirectives.distrRules.size(); ++z)
distrArraysD.insert(dataDirectives.distrRules[z].first);
for (int z = 0; z < dataDirectives.alignRules.size(); ++z)
distrArraysD.insert(dataDirectives.alignRules[z].alignArray);
for (auto& elem : tableOfUniqNamesByArray)
{
set<DIST::Array*> realRefs;
getRealArrayRefs(elem.first, elem.first, realRefs, arrayLinksByFuncCalls);
if (isNotNullIntersection(realRefs, distrArraysD))
distrArraysAdded.insert(elem.first);
}
for (auto& elem : distrArraysD)
{
if (onlyCommon)
{
if (elem->GetLocation().first == DIST::l_COMMON)
distrArrays.insert(elem);
}
else
distrArrays.insert(elem);
}
for (auto& elem : distrArraysAdded)
{
if (onlyCommon)
{
if (elem->GetLocation().first == DIST::l_COMMON)
distrArrays.insert(elem);
}
else
distrArrays.insert(elem);
}
return distrArrays;
}
static set<string> fillDistributedArrays(const DataDirective &dataDirectives, bool onlyCommon = false, bool shortName = false)
{
set<string> distrArrays;
set<DIST::Array*> ret = fillDistributedArraysD(dataDirectives, onlyCommon);
for (auto& elem : ret)
distrArrays.insert(shortName ? elem->GetShortName() : elem->GetName());
return distrArrays;
}
static bool runAnalysis(SgProject &project, const int curr_regime, const bool need_to_unparse, const char *newVer = NULL, const char *folderName = NULL)
{
if (PASSES_DONE_INIT == false)
@@ -496,6 +436,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
}
auto rw_analyzer = ReadWriteAnalyzer(allFuncInfo); // doesn't analyze anything until first query
int global_err = 0;
for (int i = n - 1; i >= 0; --i)
{
@@ -525,7 +466,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{
vector<Messages> tmp;
loopAnalyzer(file, parallelRegions, createdArrays, tmp, DATA_DISTR,
allFuncInfo, declaredArrays, declaratedArraysSt, arrayLinksByFuncCalls, createDefUseMapByPlace(), true, &(loopGraph.find(file_name)->second));
allFuncInfo, declaredArrays, declaratedArraysSt, arrayLinksByFuncCalls, createDefUseMapByPlace(),
true, &(loopGraph.find(file_name)->second));
}
else if (curr_regime == LOOP_ANALYZER_DATA_DIST_S1 || curr_regime == ONLY_ARRAY_GRAPH)
{
@@ -595,113 +537,24 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
verifyOK &= res;
}
else if (curr_regime == CORRECT_FORMAT_PLACE)
checkAndMoveFormatOperators(file, getObjectForFileFromMap(file_name, SPF_messages), false);
checkAndMoveFormatOperators(file, getObjectForFileFromMap(file_name, SPF_messages), false);
else if (curr_regime == CREATE_PARALLEL_DIRS)
{
auto &loopsInFile = getObjectForFileFromMap(file_name, loopGraph);
map<int, LoopGraph*> mapLoopsInFile;
createMapLoopGraph(loopsInFile, mapLoopsInFile);
map<LoopGraph*, void*> depInfoForLoopGraphV;
for (auto& elem : depInfoForLoopGraph)
depInfoForLoopGraphV[elem.first] = elem.second;
map<string, FuncInfo*> mapFuncInfo;
createMapOfFunc(allFuncInfo, mapFuncInfo);
for (int z = 0; z < parallelRegions.size(); ++z)
{
vector<Directive*> toInsert;
const DataDirective &dataDirectives = parallelRegions[z]->GetDataDir();
const vector<int> &currentVariant = parallelRegions[z]->GetCurrentVariant();
DIST::GraphCSR<int, double, attrType> &reducedG = parallelRegions[z]->GetReducedGraphToModify();
DIST::Arrays<int> &allArrays = parallelRegions[z]->GetAllArraysToModify();
auto& tmp = dataDirectives.distrRules;
vector<pair<DIST::Array*, const DistrVariant*>> currentVar;
if (mpiProgram == 0)
{
for (int z1 = 0; z1 < currentVariant.size(); ++z1)
currentVar.push_back(make_pair(tmp[z1].first, &tmp[z1].second[currentVariant[z1]]));
}
else
{
for (auto& loop : mapLoopsInFile)
{
auto& rules = loop.second->getDataDir().distrRules;
for (auto& rule : rules)
currentVar.push_back(make_pair(rule.first, &rule.second[0]));
}
}
map<LoopGraph*, void*> depInfoForLoopGraphV;
for (auto& elem : depInfoForLoopGraph)
depInfoForLoopGraphV[elem.first] = elem.second;
selectParallelDirectiveForVariant(new File(file), parallelRegions[z], reducedG, allArrays, loopsInFile, mapLoopsInFile, mapFuncInfo, currentVar,
toInsert, parallelRegions[z]->GetId(), arrayLinksByFuncCalls,
depInfoForLoopGraphV, getObjectForFileFromMap(file_name, SPF_messages));
if (toInsert.size() > 0)
{
auto it = createdDirectives.find(file_name);
if (it == createdDirectives.end())
createdDirectives.insert(it, make_pair(file_name, toInsert));
else
for (int m = 0; m < toInsert.size(); ++m)
it->second.push_back(toInsert[m]);
}
}
createParallelDirs(new File(file), createdDirectives, getObjectForFileFromMap(file_name, SPF_messages),
loopsInFile, allFuncInfo, parallelRegions, depInfoForLoopGraphV, arrayLinksByFuncCalls);
}
else if (curr_regime == INSERT_PARALLEL_DIRS || curr_regime == EXTRACT_PARALLEL_DIRS)
{
const bool extract = (curr_regime == EXTRACT_PARALLEL_DIRS);
insertDirectiveToFile(file, file_name, createdDirectives[file_name], extract, getObjectForFileFromMap(file_name, SPF_messages));
if (mpiProgram == 0)
{
auto callGraph = getObjectForFileFromMap(file_name, allFuncInfo);
map<string, FuncInfo*> mapFuncInfo;
createMapOfFunc(callGraph, mapFuncInfo);
for (int z = 0; z < parallelRegions.size(); ++z)
{
ParallelRegion* currReg = parallelRegions[z];
const DataDirective& dataDirectives = currReg->GetDataDir();
const vector<int>& currentVariant = currReg->GetCurrentVariant();
const DIST::Arrays<int>& allArrays = currReg->GetAllArrays();
DIST::GraphCSR<int, double, attrType>& reducedG = currReg->GetReducedGraphToModify();
const set<string> distrArrays = fillDistributedArrays(dataDirectives);
const vector<string> distrRules = dataDirectives.GenRule(currentVariant);
const vector<vector<dist>> distrRulesSt = dataDirectives.GenRule(currentVariant, 0);
const vector<string> alignRules = dataDirectives.GenAlignsRules();
insertDistributionToFile(file, file_name, dataDirectives, distrArrays, distrRules, distrRulesSt, alignRules, loopGraph,
allArrays, reducedG, commentsToInclude, templateDeclInIncludes, extract, getObjectForFileFromMap(file_name, SPF_messages),
arrayLinksByFuncCalls, mapFuncInfo, currReg->GetId(), allFileNames);
insertLoopTempalteDeclaration(file, dataDirectives, distrRules, distrRulesSt, allArrays, extract, currReg->GetId());
}
}
if (extract)
{
createdDirectives[file_name].clear();
//clear shadow specs
for (auto& array : declaredArrays)
array.second.first->ClearShadowSpecs();
}
else if (mpiProgram == 0)
{
set<uint64_t> regNum;
for (int z = 0; z < parallelRegions.size(); ++z)
regNum.insert(parallelRegions[z]->GetId());
insertTemplateModuleUse(file, regNum, arrayLinksByFuncCalls);
}
insertParallelDirs(file, extract, createdDirectives[file_name], getObjectForFileFromMap(file_name, SPF_messages),
templateDeclInIncludes, commentsToInclude, getObjectForFileFromMap(file_name, allFuncInfo),
parallelRegions, loopGraph, allFileNames, arrayLinksByFuncCalls, declaredArrays, tableOfUniqNamesByArray);
}
else if (curr_regime == LOOP_ANALYZER_NODIST)
{
@@ -733,7 +586,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, arrayLinksByFuncCalls, depInfoForLoopGraphV, getObjectForFileFromMap(file_name, SPF_messages));
toInsert, arrayLinksByFuncCalls, depInfoForLoopGraphV, getObjectForFileFromMap(file_name, SPF_messages));
if (toInsert.size() > 0)
{
@@ -757,7 +610,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
DataDirective &dataDirectives = currReg->GetDataDirToModify();
DIST::GraphCSR<int, double, attrType> &reducedG = parallelRegions[z]->GetReducedGraphToModify();
set<string> distrArraysF = fillDistributedArrays(dataDirectives);
set<string> distrArraysF = fillDistributedArrays(dataDirectives, tableOfUniqNamesByArray, arrayLinksByFuncCalls);
set<string> distrArrays;
for (auto& elem : distrArraysF)
@@ -774,7 +627,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{
ParallelRegion* currReg = parallelRegions[z];
DataDirective& dataDirectives = currReg->GetDataDirToModify();
const set<DIST::Array*> distrCommonArrays = fillDistributedArraysD(dataDirectives, true);
const set<DIST::Array*> distrCommonArrays = fillDistributedArraysD(dataDirectives, tableOfUniqNamesByArray, arrayLinksByFuncCalls, true);
insertRealignsBeforeFragments(currReg, file, distrCommonArrays, arrayLinksByFuncCalls);
}
}
@@ -1060,11 +913,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{
auto founded = loopGraph.find(file->filename());
if (founded != loopGraph.end())
{
int err = privateArraysResizing(file, founded->second, getObjectForFileFromMap(file_name, SPF_messages), usersDirectives, true);
if (err != 0)
internalExit = -1;
}
privateArraysResizing(file, founded->second, getObjectForFileFromMap(file_name, SPF_messages), countOfTransform, usersDirectives, true);
}
else if (curr_regime == PRIVATE_ARRAYS_SHRINKING_ANALYSIS)
{
@@ -1076,11 +925,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
{
auto founded = loopGraph.find(file->filename());
if (founded != loopGraph.end())
{
int err = privateArraysResizing(file, founded->second, getObjectForFileFromMap(file_name, SPF_messages), usersDirectives, false);
if (err != 0)
internalExit = -1;
}
privateArraysResizing(file, founded->second, getObjectForFileFromMap(file_name, SPF_messages), countOfTransform, usersDirectives, false);
}
else if(curr_regime == LOOPS_SPLITTER)
{
@@ -1163,6 +1008,8 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
removeOmpDir(st);
}
else if (curr_regime == PARSE_OMP_DIRS)
parseOmpDirectives(file, getObjectForFileFromMap(file_name, SPF_messages));
else if (curr_regime == REMOVE_COMMENTS)
{
for (SgStatement* st = file->firstStatement(); st; st = st->lexNext())
@@ -1173,13 +1020,16 @@ 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);
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);
if(func->funcPointer->variant() != ENTRY_STAT)
countOfTransform += removeDeadCode(func->funcPointer, allFuncInfo, commonBlocks);
}
else if (curr_regime == TEST_PASS)
{
@@ -1188,12 +1038,18 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
unparseProjectIfNeed(file, curr_regime, need_to_unparse, newVer, folderName, allIncludeFiles);
} // end of FOR by files
if (internalExit < 0)
throw -1;
bool applyFor = (curr_regime == LOOPS_SPLITTER || curr_regime == LOOPS_COMBINER || curr_regime == PRIVATE_REMOVING);
if ((countOfTransform == 0 || internalExit > 0) && applyFor)
set<int> applyFor = { LOOPS_SPLITTER,
LOOPS_COMBINER,
PRIVATE_REMOVING,
PRIVATE_ARRAYS_EXPANSION,
PRIVATE_ARRAYS_SHRINKING,
REMOVE_DEAD_CODE };
if ((countOfTransform == 0 || internalExit > 0) && applyFor.find(curr_regime) != applyFor.end())
{
SgStatement* mainUnit = findMainUnit(&project, SPF_messages);
checkNull(mainUnit, convertFileName(__FILE__).c_str(), __LINE__);
@@ -2077,8 +1933,7 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne
else if (curr_regime == FIX_COMMON_BLOCKS)
fixCommonBlocks(allFuncInfo, commonBlocks, &project);
else if (curr_regime == SELECT_ARRAY_DIM_CONF) {
SelectArrayConfForParallelization(&project, allFuncInfo, loopGraph, createdDirectives, SPF_messages, arrayLinksByFuncCalls, parallelRegions);
removeRegionsWithoutDirs(createdDirectives, parallelRegions, allFuncInfo, SPF_messages);
SelectArrayConfForParallelization(&project, allFuncInfo, loopGraph, SPF_messages, arrayLinksByFuncCalls);
}
else if (curr_regime == GET_MIN_MAX_BLOCK_DIST)
{
@@ -2307,8 +2162,6 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
runPass(REVERT_SUBST_EXPR_RD, proj_name, folderName);
runPass(CONVERT_LOOP_TO_ASSIGN, proj_name, folderName);
runPass(SELECT_ARRAY_DIM_CONF, proj_name, folderName);
runPass(REVERT_SUBST_EXPR_RD, proj_name, folderName);
@@ -2534,6 +2387,7 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam
case LOOPS_COMBINER:
case FIX_COMMON_BLOCKS:
case TEST_PASS:
case SET_IMPLICIT_NONE:
runAnalysis(*project, curr_regime, false);
case SUBST_EXPR_RD_AND_UNPARSE:
case SUBST_EXPR_AND_UNPARSE:

View File

@@ -169,6 +169,7 @@ enum passes {
REMOVE_DEAD_CODE_AND_UNPARSE,
FIX_COMMON_BLOCKS,
PARSE_OMP_DIRS,
REMOVE_OMP_DIRS,
REMOVE_OMP_DIRS_TRANSFORM,
REMOVE_COMMENTS,
@@ -176,6 +177,8 @@ enum passes {
CONVERT_TO_C,
INSERT_NO_DISTR_FLAGS_FROM_GUI,
SET_IMPLICIT_NONE,
TEST_PASS,
EMPTY_PASS
};
@@ -349,11 +352,13 @@ static void setPassValues()
passNames[REMOVE_DEAD_CODE_AND_UNPARSE] = "REMOVE_DEAD_CODE_AND_UNPARSE";
passNames[FIX_COMMON_BLOCKS] = "FIX_COMMON_BLOCKS";
passNames[PARSE_OMP_DIRS] = "PARSE_OMP_DIRS";
passNames[REMOVE_OMP_DIRS] = "REMOVE_OMP_DIRS";
passNames[REMOVE_OMP_DIRS_TRANSFORM] = "REMOVE_OMP_DIRS_TRANSFORM";
passNames[REMOVE_COMMENTS] = "REMOVE_COMMENTS";
passNames[GET_MIN_MAX_BLOCK_DIST] = "GET_MIN_MAX_BLOCK_DIST";
passNames[CONVERT_TO_C] = "CONVERT_TO_C";
passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE";
passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI";
passNames[TEST_PASS] = "TEST_PASS";

View File

@@ -13,33 +13,40 @@ using std::set;
using std::remove_if;
#define PRINT_USELESS_STATEMENTS 0
#define PRINT_USELESS_STATEMENTS 1
#define DEBUG_IR 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,
vector<SAPFOR::Argument*>& arg_stack, int& arg_stack_index, int& arg_stack_size,
string& fName, const map<string, FuncInfo*>& funcByName,
bool& useful, bool& last_fcall_useful,
bool& useful, bool& last_stack_op_useful,
set<SAPFOR::Argument*>& usedByThisBlock)
{
set<SAPFOR::Argument*> res, args;
bool last_stack_op;
vector<LIVE_VARIABLES::LiveDeadVarsForCall> fcalls;
getUseDefForInstruction(block, instr,
args, res,
formal_parameters, fcalls,
lastParamRef, last_param_ref_index, last_param_ref_size,
arg_stack, arg_stack_index, arg_stack_size,
last_stack_op,
fName, funcByName,
false
);
const auto instr_operation = instr->getOperation();
if (!useful)
{
for (SAPFOR::Argument* r : res)
{
if (use.find(r) != use.end() || r->getMemType() != SAPFOR::CFG_MEM_TYPE::LOCAL_)
if (use.find(r) != use.end() ||
r->getMemType() != SAPFOR::CFG_MEM_TYPE::LOCAL_ ||
!(r->getType() == SAPFOR::CFG_ARG_TYPE::VAR || r->getType() == SAPFOR::CFG_ARG_TYPE::REG))
{
useful = true;
break;
@@ -49,7 +56,7 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
if (!useful)
{
set<SAPFOR::CFG_OP> always_useful =
static const set<SAPFOR::CFG_OP> always_useful =
{
SAPFOR::CFG_OP::POINTER_ASS,
SAPFOR::CFG_OP::STORE,
@@ -58,24 +65,28 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
SAPFOR::CFG_OP::ENTRY,
SAPFOR::CFG_OP::EXIT,
SAPFOR::CFG_OP::DVM_DIR,
SAPFOR::CFG_OP::SPF_DIR
SAPFOR::CFG_OP::SPF_DIR,
SAPFOR::CFG_OP::IO_PARAM
};
if (always_useful.find(instr->getOperation()) != always_useful.end())
if (always_useful.find(instr_operation) != always_useful.end())
useful = true;
else if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
else if (instr_operation == 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;
else if (instr_operation == SAPFOR::CFG_OP::PARAM ||
instr_operation == SAPFOR::CFG_OP::REF)
useful |= last_stack_op_useful;
}
if (useful)
{
if (instr->getOperation() == SAPFOR::CFG_OP::F_CALL)
last_fcall_useful = true;
if (instr_operation == SAPFOR::CFG_OP::F_CALL ||
instr_operation == SAPFOR::CFG_OP::LOAD ||
instr_operation == SAPFOR::CFG_OP::STORE)
last_stack_op_useful = true;
for (auto e : res)
{
@@ -88,12 +99,12 @@ static void updateUseDefForInstruction(SAPFOR::BasicBlock* block, SAPFOR::Instru
use.insert(e);
def.erase(e);
}
insertIfVar(args.begin(), args.end(), usedByThisBlock);
usedByThisBlock.insert(args.begin(), args.end());
}
if ((instr->getOperation() == SAPFOR::CFG_OP::F_CALL || instr->getOperation() == SAPFOR::CFG_OP::PARAM) && fName == "")
last_fcall_useful = false;
if (last_stack_op)
last_stack_op_useful = false;
}
@@ -104,8 +115,8 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
{
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;
vector<SAPFOR::Argument*> arg_stack;
int arg_stack_index = 0, arg_stack_size = 0;
string fName = "";
bool last_fcall_useful = false;
@@ -119,7 +130,7 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
updateUseDefForInstruction(block, instructions[i]->getInstruction(),
use_with_regs, def_with_regs,
formal_parameters,
lastParamRef, last_param_ref_index, last_param_ref_size,
arg_stack, arg_stack_index, arg_stack_size,
fName, funcByName,
u, last_fcall_useful,
usedByThisBlock
@@ -128,12 +139,13 @@ static void buildUseDef(SAPFOR::BasicBlock* block, set<SAPFOR::Argument*>& use,
useful[i] = u;
}
insertIfVar(use_with_regs.begin(), use_with_regs.end(), use);
insertIfVar(def_with_regs.begin(), def_with_regs.end(), def);
use.insert(use_with_regs.begin(), use_with_regs.end());
def.insert(def_with_regs.begin(), def_with_regs.end());
}
class DeadCodeAnalysisNode : public DataFlowAnalysisNode<map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>> {
class DeadCodeAnalysisNode : public DataFlowAnalysisNode<map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>>
{
private:
vector<bool> useful;
bool useful_block = false;
@@ -196,32 +208,45 @@ public:
return updated;
}
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getIn() {
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getIn()
{
return getBlock()->getLiveOut();
}
map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>> getOut() {
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 addIn(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
{
return getBlock()->addLiveOut(data);
}
bool addOut(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& 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 updateState()
{
bool updated = false;
if (!useful_block)
updated |= updateNextNotEmpty();
updated |= updateJumpStatus();
if(updated)
this->forwardData({ });
return updated;
}
bool forwardData(const map<SAPFOR::Argument*, vector<SAPFOR::BasicBlock*>>& data)
{
bool inserted = false;
SAPFOR::BasicBlock* bb= getBlock();
SAPFOR::BasicBlock* bb = getBlock();
set<SAPFOR::Argument*> use, def;
@@ -235,30 +260,33 @@ public:
for (SAPFOR::Argument* arg : use)
{
bool this_block = usedByThisBlock.find(arg) != usedByThisBlock.end();
if (!this_block)
if(arg && (arg->getType() == SAPFOR::CFG_ARG_TYPE::VAR || arg->getType() == SAPFOR::CFG_ARG_TYPE::REG))
{
auto data_it = data.find(arg);
bool this_block = usedByThisBlock.find(arg) != usedByThisBlock.end();
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 (!this_block)
{
if (in_it->second.size() == 1 && *(in_it->second.begin()) == bb)
skip = true; // nothing to do, inserted = false
else
bb->removeLiveIn(arg);
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(!skip)
inserted |= bb->addLiveIn({ { arg, { bb } } });
}
}
@@ -298,41 +326,73 @@ public:
{
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() } } });
this->forwardData({ });
}
const vector<bool>& getResult() { return useful; }
};
class DeadCodeAnalysis : public BackwardDataFlowAnalysis<DeadCodeAnalysisNode> {
class DeadCodeAnalysis : public BackwardDataFlowAnalysis<DeadCodeAnalysisNode>
{
protected:
vector<SAPFOR::Argument*>& formal_parameters;
const map<string, FuncInfo*>& funcByName;
DeadCodeAnalysisNode* createNode(SAPFOR::BasicBlock* block) override {
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)
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)
static bool hasCalls(SgExpression* ex)
{
if (ex)
{
if (ex->variant() == FUNC_CALL)
return true;
return hasCalls(ex->lhs()) || hasCalls(ex->rhs());
}
return false;
}
//TODO: add check for side effects for function calls
static bool hasCalls(SgStatement* stat)
{
if (stat->variant() == FOR_NODE)
{
auto forSt = isSgForStmt(stat);
return hasCalls(forSt->start()) || hasCalls(forSt->end()) || hasCalls(forSt->step());
}
else
return hasCalls(stat->expr(0)) || hasCalls(stat->expr(1)) || hasCalls(stat->expr(2));
}
int removeDeadCode(SgStatement* func,
const map<string, vector<FuncInfo*>>& allFuncs,
const map<string, CommonBlock*>& commonBlocks,
SgStatement* intervalDelStart, SgStatement* intervalDelEnd)
{
int countOfTransform = 0;
if (intervalDelStart && !intervalDelEnd || !intervalDelStart && intervalDelEnd)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgProgHedrStmt* prog = isSgProgHedrStmt(func);
if (intervalDelStart)
if (intervalDelStart->lineNumber() < prog->lineNumber() || intervalDelStart->lineNumber() > prog->lastNodeOfStmt()->lineNumber())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (intervalDelEnd)
if (intervalDelEnd->lineNumber() < prog->lineNumber() || intervalDelEnd->lineNumber() > prog->lastNodeOfStmt()->lineNumber())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
auto cfg = buildCFGforCurrentFunc(func, SAPFOR::CFG_Settings(true, false, false, false, false, false, false), commonBlocks, allFuncs);
if(cfg.size() != 1)
@@ -345,7 +405,8 @@ void removeDeadCode(SgStatement* func,
set<SAPFOR::BasicBlock*> reachable;
for (auto b : cfg_pair.second)
if(b->getInstructions().front()->isHeader())
if(b->getInstructions().front()->isHeader() ||
b->getInstructions().front()->getInstruction()->getOperation() == SAPFOR::CFG_OP::ENTRY)
reachable.insert(b);
set<SAPFOR::BasicBlock*> worklist = reachable;
@@ -382,8 +443,10 @@ void removeDeadCode(SgStatement* func,
cfg_pair.second.erase(remove_unreachable_it, cfg_pair.second.end());
#if DEBUG_IR
dumpCFG({ cfg_pair }, false);
#endif
// detect useless code
vector<SAPFOR::Argument*> func_parameters(cfg_pair.first->funcParams.countOfPars, NULL);
map<string, FuncInfo*> funcByName;
@@ -424,10 +487,7 @@ void removeDeadCode(SgStatement* func,
}
// remove dead statements
SgStatement* end = func->lastNodeOfStmt(), *st = func;
set<int> removable =
static const set<int> removable =
{
ASSIGN_STAT,
PROC_STAT,
@@ -435,50 +495,98 @@ void removeDeadCode(SgStatement* func,
READ_STAT
};
while (st != end)
vector<SgStatement*> remove;
SgStatement* start = intervalDelStart ? intervalDelStart : func;
SgStatement* end = intervalDelEnd ? intervalDelEnd : func->lastNodeOfStmt();
for (auto st = start; st != end; st = st->lexNext())
{
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();
}
}
const int var = st->variant();
if (removable.find(var) != removable.end() && useful.find(st) == useful.end())
{
remove.push_back(st);
st = st->lastNodeOfStmt();
}
st = next;
if (var == CONTAINS_STMT)
break;
}
for (auto& rem : remove)
{
__spf_print(PRINT_USELESS_STATEMENTS, "[Useless statement on line %d and file %s]\n", rem->lineNumber(), rem->fileName());
auto cp = rem->controlParent();
if (cp->variant() == LOGIF_NODE)
{
if (hasCalls(cp))
{
((SgLogIfStmt*)cp)->convertLogicIf();
rem->deleteStmt();
}
else
cp->deleteStmt();
}
else
rem->deleteStmt();
}
countOfTransform += remove.size();
//remove empty blocks
do
{
remove.clear();
for (auto st = start; st != end; st = st->lexNext())
{
const int var = st->variant();
if ((var == FOR_NODE || var == WHILE_NODE || var == SWITCH_NODE) &&
st->lexNext()->variant() == CONTROL_END)
{
if (!hasCalls(st))
remove.push_back(st);
}
else if (var == IF_NODE)
{
if (!hasCalls(st))
{
bool hasCalls_ = false;
SgStatement* ifS = st;
while (ifS->lexNext()->variant() == ELSEIF_NODE)
{
hasCalls_ |= hasCalls(ifS->lexNext());
ifS = ifS->lexNext();
}
SgStatement* lastNode = ifS->lastNodeOfStmt();
ifS = ifS->lexNext();
while (ifS->variant() == CONTROL_END && ifS != lastNode)
ifS = ifS->lexNext();
if (ifS == lastNode && !hasCalls_)
remove.push_back(st);
}
}
//TODO: other block statements
if (var == CONTAINS_STMT)
break;
}
bool mainRemoved = false;
for (auto& rem : remove)
{
__spf_print(PRINT_USELESS_STATEMENTS, "[Useless block statement on line %d and file %s]\n", rem->lineNumber(), rem->fileName());
rem->deleteStmt();
if (rem == start)
mainRemoved = true;
}
countOfTransform += remove.size();
if (mainRemoved)
break;
} while (remove.size());
deleteCFG(cfg);
return countOfTransform;
}

View File

@@ -9,6 +9,7 @@
#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);
int removeDeadCode(SgStatement* func,
const std::map<std::string, std::vector<FuncInfo*>>&allFuncs,
const std::map<std::string, CommonBlock*>& commonBlocks,
SgStatement* intervalDelStart = NULL, SgStatement* intervalDelEnd = NULL);

View File

@@ -131,13 +131,13 @@ static bool isEqExpressions(SgExpression* exp1, SgExpression* exp2)
if (exp1 != NULL)
{
exp1 = CalculateInteger(exp1);
exp1 = CalculateInteger(exp1->copyPtr());
str1 = exp1->unparse();
}
if (exp2 != NULL)
{
exp2 = CalculateInteger(exp2);
exp2 = CalculateInteger(exp2->copyPtr());
str2 = exp2->unparse();
}
@@ -150,8 +150,8 @@ static bool isOppositeExpressions(SgExpression* exp1, SgExpression* exp2)
if (exp1 == NULL || exp2 == NULL)
return false;
exp1 = CalculateInteger(exp1);
exp2 = CalculateInteger(exp2);
exp1 = CalculateInteger(exp1->copyPtr());
exp2 = CalculateInteger(exp2->copyPtr());
if (exp1->variant() == MINUS_OP)
return isEqExpressions(exp1->lhs(), exp2);

View File

@@ -9,6 +9,7 @@
#include "../CFGraph/CFGraph.h"
#include "../SageAnalysisTool/OmegaForSage/include/lang-interf.h"
#include "../DirectiveProcessing/directive_parser.h"
#include "../DirectiveProcessing/directive_omp_parser.h"
using std::string;
using std::vector;
@@ -766,7 +767,7 @@ static void filterSpfAttributes(SgStatement* stat)
if (attr->getAttributeType() == SPF_ANALYSIS_DIR)
{
SgStatement* data = (SgStatement*)attr->getAttributeData();
if (data->localLineNumber() != 777)
if (data->localLineNumber() != SPF_USER_DIR)
continue;
//__spf_print(1, "%s", data->unparse());

View File

@@ -89,19 +89,24 @@ static void fillIterationVariables(const LoopGraph* loop, set<string>& vars, int
}
}
static SgExpression* findSymbolInExprList(SgSymbol* symbol, SgExpression* list)
static SgExpression* findSymbol(SgSymbol* symbol, SgExpression* list)
{
while (list)
if (list)
{
if (list->variant() != EXPR_LIST || list->lhs()->symbol() == NULL)
return NULL;
if (list->variant() == VAR_REF || list->variant() == ARRAY_REF)
{
if (isEqSymbols(list->symbol(), symbol))
return list;
}
if (isEqSymbols(list->lhs()->symbol(), symbol))
return list->lhs();
auto left = findSymbol(symbol, list->lhs());
if (left)
return left;
list = list->rhs();
auto right = findSymbol(symbol, list->rhs());
if (right)
return right;
}
return NULL;
}
@@ -135,13 +140,17 @@ static const string constructNewBoundName(const char *oldName, int loopLineNumbe
return newName;
}
static SgSymbol* createNewArrayNameSymbol(SgExpression* declaration, bool isExpansion)
static SgSymbol* createNewArrayNameSymbol(SgExpression* declaration, bool isExpansion, bool canBeStatic)
{
SgType* type = new SgType(T_ARRAY);
char* newNameStr = constructNewArrayName(declaration->symbol()->identifier(), isExpansion);
SgSymbol* newName = new SgSymbol(VARIABLE_NAME, newNameStr, type, NULL);
newName->setAttribute(declaration->symbol()->attributes());
SgSymbol* newName = new SgSymbol(VARIABLE_NAME, newNameStr, type, NULL);
auto attrs = declaration->symbol()->attributes();
if (!canBeStatic)
attrs |= ALLOCATABLE_BIT;
newName->setAttribute(attrs);
return newName;
}
@@ -155,7 +164,17 @@ static void fillLoopBoundExprs(const LoopGraph* forLoop, int depthOfResize, cons
{
if (indexes[j] && isEqSymbols(loopStmt->doName(), indexes[j]))
{
bounds[j] = new SgExpression(DDOT, loopStmt->start()->copyPtr(), loopStmt->end()->copyPtr(), NULL);
//TODO: add MIN and MAX call for bounds
if (curLoop->stepVal == 0)
{
__spf_print(1, "unknown step sign of loop on line %d\n", curLoop->lineNum);
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
if (curLoop->stepVal > 0)
bounds[j] = new SgExpression(DDOT, loopStmt->start()->copyPtr(), loopStmt->end()->copyPtr(), NULL);
else
bounds[j] = new SgExpression(DDOT, loopStmt->end()->copyPtr(), loopStmt->start()->copyPtr(), NULL);
break;
}
}
@@ -257,11 +276,10 @@ static SgExpression* constructExtendedArrayRefTail(SgExpression* oldTail, const
return newTail;
}
static SgExpression* extendArrayRef(const vector<SgSymbol*>& indexes, SgExpression* expressionToExtend,
SgSymbol* newSymbol, const vector<SgExpression*>& lowBounds)
static void extendArrayRef(const vector<SgSymbol*>& indexes, SgExpression*& expressionToExtend,
SgSymbol* newSymbol, const vector<SgExpression*>& lowBounds)
{
SgExpression* newTail = constructExtendedArrayRefTail(expressionToExtend->lhs(), indexes);
SgExpression* oldTail = expressionToExtend->lhs();
if (oldTail == NULL)
{
@@ -286,8 +304,6 @@ static SgExpression* extendArrayRef(const vector<SgSymbol*>& indexes, SgExpressi
expressionToExtend->setLhs(newTail);
expressionToExtend->setSymbol(newSymbol);
}
return expressionToExtend;
}
static bool isAllocatable(SgSymbol* symbol)
@@ -328,14 +344,50 @@ static void setAllocatable(SgStatement *newDecl, SgSymbol *origSymbol)
}
}
static SgExpression* checkArrayDecl(SgExpression* array, SgSymbol* arraySymbol, SgStatement* checkedDecl)
{
if (array->lhs() == NULL)
{
vector<SgStatement*> allDecls;
auto mainDecl = declaratedInStmt(arraySymbol, &allDecls);
if (allDecls.size() == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
if (allDecls.size() == 1)
{
array = findSymbol(arraySymbol, mainDecl->expr(0));
checkNull(array, convertFileName(__FILE__).c_str(), __LINE__);
return array;
}
for (auto& decl : allDecls)
{
if (decl == mainDecl)
continue;
if (decl == checkedDecl)
continue;
array = findSymbol(arraySymbol, decl->expr(0));
if (array->lhs())
break;
array = NULL;
}
checkNull(array, convertFileName(__FILE__).c_str(), __LINE__);
}
return array;
}
static SgSymbol* alterExtendArrayDeclaration(const LoopGraph* forLoop, SgStatement* declarationStmt, SgSymbol* arraySymbol,
bool canBeStatic, const vector<SgSymbol*>& indexes)
{
SgSymbol* newArraySymbol = NULL;
SgExpression* array = findSymbolInExprList(arraySymbol, declarationStmt->expr(0));
SgExpression* array = findSymbol(arraySymbol, declarationStmt->expr(0));
array = checkArrayDecl(array, arraySymbol, declarationStmt);
SgExpression* newArray = array->copyPtr();
newArraySymbol = createNewArrayNameSymbol(newArray, true);
newArraySymbol = createNewArrayNameSymbol(newArray, true, canBeStatic);
if (newArraySymbol == NULL)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -350,13 +402,14 @@ static SgSymbol* alterExtendArrayDeclaration(const LoopGraph* forLoop, SgStateme
return newArraySymbol;
}
static SgSymbol* alterShrinkArrayDeclaration(SgStatement *declarationStatement, SgSymbol *arraySymbol, vector<int> &dimensions)
static SgSymbol* alterShrinkArrayDeclaration(SgStatement *declarationStatement, SgSymbol *arraySymbol,
vector<int> &dimensions, bool canBeStatic)
{
SgSymbol *newArraySymbol = NULL;
SgExpression *array = findSymbolInExprList(arraySymbol, declarationStatement->expr(0));
SgExpression *array = findSymbol(arraySymbol, declarationStatement->expr(0));
SgExpression *newArray = array->copyPtr();
newArraySymbol = createNewArrayNameSymbol(newArray, false);
newArraySymbol = createNewArrayNameSymbol(newArray, false, canBeStatic);
reduceArray(dimensions, newArray, newArraySymbol);
@@ -369,35 +422,40 @@ static SgSymbol* alterShrinkArrayDeclaration(SgStatement *declarationStatement,
return newArraySymbol;
}
static void extendArrayRefsInExpr(const vector<SgSymbol*>& indexes, SgExpression* expr, SgSymbol* arraySymbol,
SgSymbol* newArraySymbol, const vector<SgExpression*>& lowBounds)
static void extendArrayRefsInExpr(const vector<SgSymbol*>& indexes, SgExpression*& expr,
SgSymbol* arraySymbol, SgSymbol* newArraySymbol,
const vector<SgExpression*>& lowBounds, int line)
{
SgExpression *lhs = expr->lhs(), *rhs = expr->rhs();
if (lhs)
if (expr)
{
if (isArrayRef(lhs) && isEqSymbols(arraySymbol, lhs->symbol()))
extendArrayRef(indexes, lhs, newArraySymbol, lowBounds);
else if (lhs->variant() == VAR_REF && isEqSymbols(arraySymbol, lhs->symbol()))
if (expr->variant() == FUNC_CALL)
{
SgExpression* extended = extendArrayRef(indexes, lhs, newArraySymbol, lowBounds);
expr->setLhs(extended);
SgFunctionCallExp* call = isSgFunctionCallExp(expr);
for (int arg = 0; arg < call->numberOfArgs(); ++arg)
{
auto argRef = call->arg(arg);
if ((isArrayRef(argRef) || argRef->variant() == VAR_REF) && isEqSymbols(argRef->symbol(), arraySymbol))
{
__spf_print(1, "unsupported private array extension under call on line %d\n", line);
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
}
else
extendArrayRefsInExpr(indexes, lhs, arraySymbol, newArraySymbol, lowBounds);
}
if (rhs)
{
if (isArrayRef(rhs) && isEqSymbols(arraySymbol, rhs->symbol()))
extendArrayRef(indexes, rhs, newArraySymbol, lowBounds);
else if (rhs->variant() == VAR_REF && isEqSymbols(arraySymbol, rhs->symbol()))
{
SgExpression* extended = extendArrayRef(indexes, rhs, newArraySymbol, lowBounds);
expr->setRhs(extended);
}
else
extendArrayRefsInExpr(indexes, rhs, arraySymbol, newArraySymbol, lowBounds);
SgExpression* left = expr->lhs();
extendArrayRefsInExpr(indexes, left, arraySymbol, newArraySymbol, lowBounds, line);
if (left != expr->lhs())
expr->setLhs(left);
SgExpression* right = expr->rhs();
extendArrayRefsInExpr(indexes, right, arraySymbol, newArraySymbol, lowBounds, line);
if (right != expr->rhs())
expr->setRhs(right);
if (isArrayRef(expr) && isEqSymbols(arraySymbol, expr->symbol()))
extendArrayRef(indexes, expr, newArraySymbol, lowBounds);
else if (expr->variant() == VAR_REF && isEqSymbols(arraySymbol, expr->symbol()))
extendArrayRef(indexes, expr, newArraySymbol, lowBounds);
}
}
@@ -406,17 +464,26 @@ static void extendArrayRefs(const vector<SgSymbol*> &indexes, SgStatement *st, S
{
for (int i = 0; i < 3; ++i)
{
if (st->variant() == PROC_STAT)
{
SgCallStmt* call = isSgCallStmt(st);
for (int arg = 0; arg < call->numberOfArgs(); ++arg)
{
auto argRef = call->arg(arg);
if ((isArrayRef(argRef) || argRef->variant() == VAR_REF) && isEqSymbols(argRef->symbol(), arraySymbol))
{
__spf_print(1, "unsupported private array extension under call on line %d\n", st->lineNumber());
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
}
}
}
if (st->expr(i))
{
if (isArrayRef(st->expr(i)) && isEqSymbols(arraySymbol, st->expr(i)->symbol()))
extendArrayRef(indexes, st->expr(i), newArraySymbol, lowBounds);
else if (st->expr(i)->variant() == VAR_REF && isEqSymbols(arraySymbol, st->expr(i)->symbol()))
{
SgExpression* extended = extendArrayRef(indexes, st->expr(i), newArraySymbol, lowBounds);
st->setExpression(i, *extended);
}
else
extendArrayRefsInExpr(indexes, st->expr(i), arraySymbol, newArraySymbol, lowBounds);
SgExpression* ex = st->expr(i);
extendArrayRefsInExpr(indexes, ex, arraySymbol, newArraySymbol, lowBounds, st->lineNumber());
if (ex != st->expr(i))
st->setExpression(i, ex);
}
}
}
@@ -428,6 +495,8 @@ static SgStatement* createNewDeclarationStatemnet(SgStatement *loop, SgStatement
{
if (isSgExecutableStatement(lastDecl))
break;
if (lastDecl->variant() == CONTAINS_STMT)
break;
lastDecl = lastDecl->lexNext();
}
@@ -435,7 +504,9 @@ static SgStatement* createNewDeclarationStatemnet(SgStatement *loop, SgStatement
while (!isEqSymbols(exprList->lhs()->symbol(), arraySymbol))
exprList = exprList->rhs();
SgExpression newExprList(EXPR_LIST, exprList->lhs(), NULL, NULL);
checkNull(exprList, convertFileName(__FILE__).c_str(), __LINE__);
SgExpression newExprList(EXPR_LIST, exprList->lhs()->copyPtr(), NULL, NULL);
SgStatement *newDeclaration = originalDeclaration->copyPtr();
newDeclaration->setExpression(0, newExprList);
@@ -479,7 +550,7 @@ static SgStatement* getAllocationStmt(const LoopGraph* loop, SgSymbol* symbol)
if (alloc->variant() != ALLOCATE_STMT)
continue;
if (NULL == findSymbolInExprList(symbol, alloc->expr(0)))
if (findSymbol(symbol, alloc->expr(0)) == NULL)
continue;
if (allocationStmt == NULL)
@@ -502,10 +573,10 @@ static void fillLowBounds(const LoopGraph* forLoop, SgSymbol* origArraySymbol, S
if (isAllocatable(origArraySymbol))
{
SgStatement* allocationStmt = getAllocationStmt(forLoop, origArraySymbol);
origArray = findSymbolInExprList(origArraySymbol, allocationStmt->expr(0));
origArray = findSymbol(origArraySymbol, allocationStmt->expr(0));
}
else
origArray = findSymbolInExprList(origArraySymbol, originalDecl->expr(0));
origArray = findSymbol(origArraySymbol, originalDecl->expr(0));
SgExpression* arrayRef = origArray->copyPtr();
SgExpression* oldTail = arrayRef->lhs();
@@ -559,7 +630,7 @@ static SgExpression* constructArrayAllocationExp(const LoopGraph* forLoop, SgExp
return new SgExpression(EXPR_LIST, arrayRef, (SgExpression*)NULL, (SgSymbol*)NULL);
}
static void insertAllocDealloc(const LoopGraph* forLoop, SgSymbol* origArraySymbol, SgSymbol* arraySymbol,
static void insertAllocDealloc(const LoopGraph* forLoop, SgSymbol* origArraySymbol, SgSymbol* arraySymbol, SgSymbol* allocDone,
bool isExpansion, const vector<SgSymbol*>* indexes = NULL, const vector<int>* shrinkIndexes = NULL)
{
SgForStmt *loopStmt = (SgForStmt*)(forLoop->loop->GetOriginal());
@@ -571,10 +642,13 @@ static void insertAllocDealloc(const LoopGraph* forLoop, SgSymbol* origArraySymb
if (isAllocatable(origArraySymbol))
{
SgStatement *allocationStmt = getAllocationStmt(forLoop, origArraySymbol);
origArray = findSymbolInExprList(origArraySymbol, allocationStmt->expr(0));
origArray = findSymbol(origArraySymbol, allocationStmt->expr(0));
}
else
origArray = findSymbolInExprList(origArraySymbol, originalDeclaration->expr(0));
{
origArray = findSymbol(origArraySymbol, originalDeclaration->expr(0));
origArray = checkArrayDecl(origArray, origArraySymbol, originalDeclaration);
}
int depthOfResize = 0;
if (isExpansion)
@@ -589,11 +663,17 @@ static void insertAllocDealloc(const LoopGraph* forLoop, SgSymbol* origArraySymb
new SgExpression(ARRAY_REF, (SgExpression*)NULL, (SgExpression*)NULL, arraySymbol),
(SgExpression*)NULL, (SgSymbol*)NULL);
SgStatement *allocate = new SgStatement(ALLOCATE_STMT, (SgLabel*)NULL, (SgSymbol*)NULL, arrayAllocation, (SgExpression*)NULL, (SgExpression*)NULL);
SgStatement *deallocate = new SgStatement(DEALLOCATE_STMT, (SgLabel*)NULL, (SgSymbol*)NULL, arrayDeallocation, (SgExpression*)NULL, (SgExpression*)NULL);
loopStmt->insertStmtBefore(*allocate, *loopStmt->controlParent());
loopStmt->lastNodeOfStmt()->insertStmtAfter(*deallocate, *loopStmt->controlParent());
SgStatement *allocate = new SgStatement(ALLOCATE_STMT, (SgLabel*)NULL, (SgSymbol*)NULL, arrayAllocation, (SgExpression*)NULL, (SgExpression*)NULL);
SgIfStmt* ifSt = new SgIfStmt(SgEqOp(*new SgVarRefExp(allocDone), *new SgValueExp(0)), *allocate);
loopStmt->insertStmtBefore(*ifSt, *loopStmt->controlParent());
// insert allocates as save
//SgStatement* deallocate = new SgStatement(DEALLOCATE_STMT, (SgLabel*)NULL, (SgSymbol*)NULL, arrayDeallocation, (SgExpression*)NULL, (SgExpression*)NULL);
//loopStmt->lastNodeOfStmt()->insertStmtAfter(*deallocate, *loopStmt->controlParent());
}
static bool containsFunctionCall(SgExpression* exp)
@@ -734,7 +814,7 @@ static void reduceArrayRefs(SgStatement *st, SgSymbol *arraySymbol, SgSymbol *ne
static void fillIndexesToShrink(SgSymbol* arr, SgExprListExp* listExp, vector<int>& indexes)
{
SgExpression* sym = findSymbolInExprList(arr, listExp);
SgExpression* sym = findSymbol(arr, listExp);
if (sym)
{
SgExpression* expr = sym->lhs();
@@ -781,6 +861,61 @@ static void renamePrivateVarsInAttributes(const vector<SgStatement*>& attrs, con
}
}
static void removePrivateVarsInAttributes(const vector<SgStatement*>& attrs, const map<SgSymbol*, SgSymbol*>& symbols)
{
for (SgStatement* st : attrs)
{
if (st->variant() != SPF_ANALYSIS_DIR)
return;
SgExpression* exprList = st->expr(0);
vector<SgExpression*> newL;
bool remList = false;
while (exprList)
{
if (exprList->lhs()->variant() == ACC_PRIVATE_OP)
{
vector<SgExpression*> newL;
bool removed = false;
SgExpression* list = exprList->lhs()->lhs();
while (list)
{
bool found = false;
for (auto& pair : symbols)
{
if (isEqSymbols(pair.first, list->lhs()->symbol()))
found = true;
if (found)
break;
}
if (!found)
newL.push_back(list->lhs());
else
removed = true;
list = list->rhs();
}
if (removed)
{
if (newL.size() == 0)
remList = true;
else
{
exprList->lhs()->setLhs(makeExprList(newL));
newL.push_back(exprList->lhs());
}
}
}
else
newL.push_back(exprList->lhs());
exprList = exprList->rhs();
}
if (remList)
st->setExpression(0, makeExprList(newL));
}
}
static int getArrayDimensionality(SgSymbol* array)
{
if (array->type()->variant() != T_ARRAY)
@@ -975,7 +1110,7 @@ static int fillIndexesToExtend(const LoopGraph* loop, int origDim, int depthOfRe
return 0;
}
static SgSymbol* shrinkArray(const LoopGraph *forLoop, SgSymbol *arraySymbol, vector<int> &indexes)
static SgSymbol* shrinkArray(const LoopGraph *forLoop, SgSymbol *arraySymbol, vector<int> &indexes, SgSymbol *allocDone)
{
int maxDepth = forLoop->perfectLoop;
const LoopGraph *curLoop = forLoop;
@@ -1005,16 +1140,17 @@ static SgSymbol* shrinkArray(const LoopGraph *forLoop, SgSymbol *arraySymbol, ve
SgStatement *originalDeclaration = declaratedInStmt(arraySymbol);
SgStatement *copiedDeclaration = createNewDeclarationStatemnet(forLoop->loop->GetOriginal(), originalDeclaration, arraySymbol);
bool canBeStatic = !(!reduceToVariable && isAllocatable(arraySymbol));
SgSymbol *newSymbol = reduceToVariable
? createReducedToVariableArray(copiedDeclaration, forLoop->lineNum, arraySymbol)
: alterShrinkArrayDeclaration(copiedDeclaration, arraySymbol, indexes);
: alterShrinkArrayDeclaration(copiedDeclaration, arraySymbol, indexes, canBeStatic);
if (newSymbol)
{
SgForStmt *loopStmt = (SgForStmt*)(forLoop->loop->GetOriginal());
if (!reduceToVariable && isAllocatable(arraySymbol))
insertAllocDealloc(forLoop, arraySymbol, newSymbol, false, NULL, &indexes);
insertAllocDealloc(forLoop, arraySymbol, newSymbol, allocDone, false, NULL, &indexes);
for (SgStatement *st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt()->lexNext(); st = st->lexNext())
if (st->variant() != ALLOCATE_STMT && st->variant() != DEALLOCATE_STMT)
@@ -1026,7 +1162,7 @@ static SgSymbol* shrinkArray(const LoopGraph *forLoop, SgSymbol *arraySymbol, ve
return NULL;
}
static SgSymbol* resizeArray(const LoopGraph *forLoop, SgSymbol *arraySymbol, int depthOfResize)
static SgSymbol* resizeArray(const LoopGraph *forLoop, SgSymbol *arraySymbol, int depthOfResize, SgSymbol *allocDone)
{
if (depthOfResize < 0 || depthOfResize > forLoop->perfectLoop)
depthOfResize = forLoop->perfectLoop;
@@ -1043,7 +1179,8 @@ static SgSymbol* resizeArray(const LoopGraph *forLoop, SgSymbol *arraySymbol, in
for (int i = 0; i < depthOfResize; ++i)
{
if (curLoop->calculatedCountOfIters == 0)
//TODO: add checking for PARAMETER
//if (curLoop->calculatedCountOfIters == 0)
canBeStatic = false;
if (areIndexesFilled != 0)
@@ -1074,7 +1211,8 @@ static SgSymbol* resizeArray(const LoopGraph *forLoop, SgSymbol *arraySymbol, in
{
SgForStmt *loopStmt = (SgForStmt*)(forLoop->loop->GetOriginal());
if (!canBeStatic || isAllocatable(newArraySymbol))
insertAllocDealloc(forLoop, arraySymbol, newArraySymbol, true, &indexes, NULL);
insertAllocDealloc(forLoop, arraySymbol, newArraySymbol, allocDone, true, &indexes, NULL);
for (SgStatement *st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt()->lexNext(); st = st->lexNext())
if (st->variant() != ALLOCATE_STMT && st->variant() != DEALLOCATE_STMT)
extendArrayRefs(indexes, st, arraySymbol, newArraySymbol, lowBounds);
@@ -1257,13 +1395,27 @@ void analyzeShrinking(SgFile* file, const vector<LoopGraph*>& loopGraphs, vector
}
}
static void createAllocDoneSymbol(map<SgStatement*, SgSymbol*>& allocDoneByFunc, SgStatement* func)
{
if (allocDoneByFunc.find(func) == allocDoneByFunc.end())
{
auto newName = (string("spf_") + string(func->symbol()->identifier()) + "_alloc_");
allocDoneByFunc[func] = new SgSymbol(VARIABLE_NAME, newName.c_str(), SgTypeInt(), func);
}
}
//Вычислять размер массива с учётом шага цикла - //TODO
int privateArraysResizing(SgFile *file, const vector<LoopGraph*> &loopGraphs, vector<Messages> &messages,
const map<pair<string, int>, set<SgStatement*>>& usersDirectives, bool isExpand)
void privateArraysResizing(SgFile *file, const vector<LoopGraph*> &loopGraphs, vector<Messages> &messages, int& countOfTransform,
const map<pair<string, int>, set<SgStatement*>>& usersDirectives, bool isExpand)
{
map<int, LoopGraph*> mapLoopGraph;
createMapLoopGraph(loopGraphs, mapLoopGraph);
map<SgStatement*, SgSymbol*> allocDoneByFunc;
map<SgStatement*, SgSymbol*> usedAllocDoneByFunc;
map<SgStatement*, vector<SgExpression*>> saveDecls;
for (auto &loopPair : mapLoopGraph)
{
LoopGraph *loop = loopPair.second;
@@ -1275,6 +1427,9 @@ int privateArraysResizing(SgFile *file, const vector<LoopGraph*> &loopGraphs, ve
auto attrPrivInCode = getAttributes<SgStatement*, SgStatement*>(loopSt, set<int>{ SPF_ANALYSIS_DIR });
auto arrayPrivates = fillPrivates(usersDirectives, loop);
auto func = getFuncStat(loopSt);
set<SgSymbol*> symbolsToDecl;
if (arrayPrivates.size() == 0)
{
@@ -1284,9 +1439,7 @@ int privateArraysResizing(SgFile *file, const vector<LoopGraph*> &loopGraphs, ve
else
__spf_printToBuf(str, "Can not do PRIVATE SHRINK for this loop - privates not found");
//TODO:
//messages.push_back(Messages(NOTE, loop->lineNum, str, 2008));
__spf_print(1, "%s on line %d\n", str.c_str(), loop->lineNum);
__spf_print(0, "%s on line %d\n", str.c_str(), loop->lineNum);
}
else
{
@@ -1301,7 +1454,9 @@ int privateArraysResizing(SgFile *file, const vector<LoopGraph*> &loopGraphs, ve
symbols.clear();
if (list->lhs()->variant() == SPF_EXPAND_OP && isExpand)
{
{
createAllocDoneSymbol(allocDoneByFunc, func);
int deep = -1;
if (list->lhs()->lhs() != NULL)
{
@@ -1311,15 +1466,25 @@ int privateArraysResizing(SgFile *file, const vector<LoopGraph*> &loopGraphs, ve
}
for (SgSymbol* privArr : arrayPrivates)
{
SgSymbol* newSymbol = resizeArray(loop, privArr, deep);
{
SgSymbol* newSymbol = resizeArray(loop, privArr, deep, allocDoneByFunc[func]);
if (newSymbol)
{
symbols.insert(std::make_pair(privArr, newSymbol));
usedAllocDoneByFunc[func] = allocDoneByFunc[func];
countOfTransform++;
if (isAllocatable(newSymbol))
symbolsToDecl.insert(newSymbol);
}
}
renamePrivateVarsInAttributes(attrPrivInCode, symbols);
removePrivateVarsInAttributes(attrPrivInCode, symbols);
}
else if (list->lhs()->variant() == SPF_SHRINK_OP && !isExpand)
{
createAllocDoneSymbol(allocDoneByFunc, func);
SgExprListExp* listExp = isSgExprListExp(list->lhs()->lhs());
checkNull(listExp, convertFileName(__FILE__).c_str(), __LINE__);
@@ -1335,9 +1500,17 @@ int privateArraysResizing(SgFile *file, const vector<LoopGraph*> &loopGraphs, ve
if (!indexes.empty() && !skip)
{
SgSymbol* newSymbol = shrinkArray(loop, privArr, indexes);
SgSymbol* newSymbol = shrinkArray(loop, privArr, indexes, allocDoneByFunc[func]);
if (newSymbol)
{
symbols.insert(std::make_pair(privArr, newSymbol));
usedAllocDoneByFunc[func] = allocDoneByFunc[func];
countOfTransform++;
if (isAllocatable(newSymbol))
symbolsToDecl.insert(newSymbol);
}
}
}
renamePrivateVarsInAttributes(attrPrivInCode, symbols);
@@ -1348,23 +1521,39 @@ int privateArraysResizing(SgFile *file, const vector<LoopGraph*> &loopGraphs, ve
list = list->rhs();
}
SgExpression *ex = NULL;
SgExpression *p = NULL;
for (int z = 0; z < newL.size(); ++z)
{
if (z == 0)
p = ex = newL[z];
else
{
ex->setRhs(newL[z]);
ex = ex->rhs();
}
}
attr->setExpression(0, p);
attr->setExpression(0, makeExprList(newL, false));
//__spf_print(1, "set new %d attributes to line %d\n", newL.size(), loop->lineNum);
}
}
for (auto& elem : symbolsToDecl)
saveDecls[func].push_back(new SgVarRefExp(elem));
}
return 0;
for (auto& funcPair : saveDecls)
{
auto func = funcPair.first;
if (usedAllocDoneByFunc.find(func) == usedAllocDoneByFunc.end())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgSymbol* allocVar = usedAllocDoneByFunc[func];
auto list = makeExprList(funcPair.second);
SgStatement* save = new SgStatement(SAVE_DECL, NULL, NULL, list);
SgStatement* st = func->lexNext();
while (!isSgExecutableStatement(st))
{
if (st->variant() == CONTAINS_STMT)
break;
st = st->lexNext();
}
vector<SgExpression*> init = { new SgValueExp(-1) };
makeDeclaration(func, { allocVar }, &init);
st->insertStmtBefore(*save, *func);
SgAssignStmt* assign = new SgAssignStmt(*new SgVarRefExp(allocVar), *new SgVarRefExp(allocVar) + *new SgValueExp(1));
st->insertStmtBefore(*assign, *func);
}
}

View File

@@ -5,5 +5,5 @@
#include <set>
int privateArraysResizing(SgFile *file, const std::vector<LoopGraph*> &loopGraphs, std::vector<Messages> &messages, const std::map<std::pair<std::string, int>, std::set<SgStatement*>>& usersDirectives, bool isExpand);
void privateArraysResizing(SgFile *file, const std::vector<LoopGraph*> &loopGraphs, std::vector<Messages> &messages, int& countOfTransform, const std::map<std::pair<std::string, int>, std::set<SgStatement*>>& usersDirectives, bool isExpand);
void analyzeShrinking(SgFile* file, const std::vector<LoopGraph*>& loopGraphs, std::vector<Messages>& messages, const std::map<std::pair<std::string, int>, std::set<SgStatement*>>& usersDirectives);

View File

@@ -44,7 +44,7 @@ static bool operator<(const RegularExpr& left, const RegularExpr& right)
}
// FixedSubscript represents subscript of array. Subscript is fixed if it is INT_VAL value
struct FixedSubscript {
struct ArraySubscript {
bool isFixed;
int value;
@@ -52,7 +52,7 @@ struct FixedSubscript {
RegularExpr regExprStart;
RegularExpr regExprEnd;
FixedSubscript() {
ArraySubscript() {
isFixed = false;
value = 0;
isRegIndex = false;
@@ -240,6 +240,7 @@ static vector<int> getShortFixedSubscriptsVector(SgArrayRefExp* arrayRef, const
if (vars != varToRemove.arrayRefToIterationVarsMap.end())
iterationVars = vars->second;
}
return getShortFixedSubscriptsVector(arrayRef, varToRemove.fixedDimensions,
varToRemove.regime, iterationVars);
}
@@ -278,27 +279,28 @@ static bool isSymbolInExpression(SgSymbol* symbol, SgExpression* exp)
if (exp == nullptr)
return false;
if (exp->symbol() != nullptr && isEqSymbols(exp->symbol(), symbol))
if (exp->symbol() != nullptr &&
(exp->variant() == VAR_REF || exp->variant() == ARRAY_REF) &&
isEqSymbols(exp->symbol(), symbol))
{
return true;
}
return isSymbolInExpression(symbol, exp->lhs()) ||
isSymbolInExpression(symbol, exp->rhs());
}
static FuncInfo* findFunc(string fileName, string funcName, const map<string, vector<FuncInfo*>>& allFuncInfo)
static FuncInfo* findFuncByName(string funcName, const map<string, vector<FuncInfo*>>& allFuncInfo)
{
auto fileInfo = allFuncInfo.find(fileName);
if (fileInfo == allFuncInfo.end())
return nullptr;
for (auto funcInfo : fileInfo->second)
if (funcInfo->funcName == funcName)
return funcInfo;
for (const auto& fileFuncs : allFuncInfo)
for (auto funcInfo : fileFuncs.second)
if (funcInfo->funcName == funcName)
return funcInfo;
return nullptr;
}
static FuncInfo* getCurrectFunc(SgStatement* stmt, const map<string, vector<FuncInfo*>>& allFuncInfo)
static FuncInfo* getCurrentFunc(SgStatement* stmt, const map<string, vector<FuncInfo*>>& allFuncInfo)
{
auto fileInfo = allFuncInfo.find(stmt->fileName());
if (fileInfo == allFuncInfo.end())
@@ -312,6 +314,20 @@ static FuncInfo* getCurrectFunc(SgStatement* stmt, const map<string, vector<Func
return nullptr;
}
// fillIterationVariables fill vars set with iteration variables of all loops
// from stmt to outerLoopStmt
static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, vector<SgSymbol*>& vars)
{
if (stmt == nullptr)
return;
if (stmt->variant() == FOR_NODE)
vars.push_back(((SgForStmt*)stmt)->doName());
if (stmt->id() != outerLoopStmt->id())
fillIterationVars(stmt->controlParent(), outerLoopStmt, vars);
}
/* ************************************** *
* End of block of common used functions: *
* ************************************** */
@@ -369,18 +385,19 @@ static void addMessageCannotFindRD(vector<Messages>& messages, string varName, i
messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2021));
}
static void addMessageMoreThanOneRD(vector<Messages>& messages, string varName, int loopLineNum)
{
__spf_print(1, "WARR: cannot remove private var '%s' - more than one definition reaches the statement in line %d\n",
varName.c_str(), loopLineNum);
wstring messageE, messageR;
__spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - more than one definition reaches the statement",
to_wstring(varName).c_str());
__spf_printToLongBuf(messageR, R193, to_wstring(varName).c_str());
messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2020));
}
// TODO: unused:
//static void addMessageMoreThanOneRD(vector<Messages>& messages, string varName, int loopLineNum)
//{
// __spf_print(1, "WARR: cannot remove private var '%s' - more than one definition reaches the statement in line %d\n",
// varName.c_str(), loopLineNum);
//
// wstring messageE, messageR;
// __spf_printToLongBuf(messageE, L"Cannot remove private var '%s' - more than one definition reaches the statement",
// to_wstring(varName).c_str());
// __spf_printToLongBuf(messageR, R193, to_wstring(varName).c_str());
//
// messages.push_back(Messages(typeMessage::WARR, loopLineNum, messageR, messageE, 2020));
//}
static void addMessageRecursiveDependency(vector<Messages>& messages, string varName, int lineNum)
{
@@ -499,7 +516,7 @@ static string getDimensionVarName(SgSymbol* var, const vector<int>& subscripts,
}
// getDimensionVarName returns var name in style A(1, 2, *)
static string getDimensionVarName(SgSymbol* var, const vector<FixedSubscript>& fixedSubscripts)
static string getDimensionVarName(SgSymbol* var, const vector<ArraySubscript>& fixedSubscripts)
{
string result = var->identifier();
@@ -599,40 +616,6 @@ static bool isVarChangedBetween(string var, SgStatement* first, SgStatement* sec
return false;
}
// TODO: remove if needless
// removeDeadCodeFromLoop removes assign statements to private scalar vars which are not read in loop
//static void removeDeadCodeFromLoop(LoopGraph* loop)
//{
// SgForStmt* loopStmt = (SgForStmt*) loop->loop->GetOriginal();
// set<Symbol*> privateVars;
// for (auto data : getAttributes<SgStatement*, SgStatement*>(loopStmt, set<int>{ SPF_ANALYSIS_DIR }))
// fillPrivatesFromComment(new Statement(data), privateVars);
//
// set<string> privates;
// for (Symbol* symbol : privateVars)
// privates.insert(OriginalSymbol((SgSymbol*)symbol)->identifier());
//
// vector<SgStatement*> stmtsToDelete;
// for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
// {
// if (st->variant() != ASSIGN_STAT)
// continue;
//
// SgSymbol* var = st->expr(0)->symbol();
// if (var == nullptr || var->variant() != VARIABLE_NAME)
// continue;
//
// if (privates.find(var->identifier()) != privates.end() && !isVarReadInLoop(var, loopStmt))
// stmtsToDelete.push_back(st);
// }
//
// for (auto stmt : stmtsToDelete)
// stmt->deleteStmt();
//
// for (auto childLoop : loop->children)
// removeDeadCodeFromLoop(childLoop);
//}
// fillReadShortFixedSumscripts fills all short fixed subscripts vectors of array var,
// which are used for reading from array var in exp
static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemove& var,
@@ -641,14 +624,13 @@ static void fillReadShortFixedSubscripts(SgExpression* exp, const PrivateToRemov
if (exp == nullptr)
return;
if (exp->symbol() != nullptr)
if (exp->symbol() != nullptr &&
(exp->symbol()->variant() == ARRAY_REF || exp->symbol()->variant() == VARIABLE_NAME) &&
isEqSymbols(exp->symbol(), var.varSymbol))
{
if (isEqSymbols(exp->symbol(), var.varSymbol))
{
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var);
fixedSubscripts.insert(subscripts);
return;
}
auto subscripts = getShortFixedSubscriptsVector((SgArrayRefExp*)exp, var);
fixedSubscripts.insert(subscripts);
return;
}
fillReadShortFixedSubscripts(exp->lhs(), var, fixedSubscripts);
@@ -698,32 +680,6 @@ static void removeExcessiveDefs(const PrivateToRemove& var)
st->deleteStmt();
}
// TODO: remove is needless
// removeEmptyLoops removes loops with empty body and create messages
//static void removeEmptyLoops(LoopGraph* loop, vector<Messages>& messages)
//{
// vector<LoopGraph*> loopsToDelete;
// vector<LoopGraph*> newChildrenVector;
// for (auto childLoop : loop->children)
// {
// SgStatement* loopStmt = childLoop->loop->GetOriginal();
// if (loopStmt->lastNodeOfStmt() == loopStmt->lexNext())
// loopsToDelete.push_back(childLoop);
// else
// newChildrenVector.push_back(childLoop);
// }
//
// for (auto loopToDelete : loopsToDelete)
// {
// addMessageRemoveLoop(messages, loopToDelete->lineNum);
// loopToDelete->loop->extractStmt();
// }
//
// loop->children.swap(newChildrenVector);
// for (auto childLoop : loop->children)
// removeEmptyLoops(childLoop, messages);
//}
// removeVarFromPrivateAttributes removes var from SPF ANALYSIS PRIVATE attributes of loop
static void removeVarFromPrivateAttributes(SgSymbol* var, LoopGraph* loop)
{
@@ -778,10 +734,23 @@ static map<SgSymbol*, SgExpression*> getVarToExpMap(SgArrayRefExp* defRef, SgArr
// removeArray removes array by substituting it in DEF-USE pairs.
// Returns set of removed fixed subscripts
static set<vector<int>> removeArray(string filename, const PrivateToRemove& arrayToRemove)
static set<vector<int>> removeArray(string filename, PrivateToRemove& arrayToRemove)
{
set<vector<int>> removedFixedSubscripts;
// again fill itaration vars:
arrayToRemove.arrayRefToIterationVarsMap.clear();
SgStatement* loopStmt = arrayToRemove.loop->loop->GetOriginal();
for (SgStatement* st = loopStmt->lexNext(); st != loopStmt->lastNodeOfStmt(); st = st->lexNext())
{
vector<SgSymbol*> iterationVars;
fillIterationVars(st, loopStmt, iterationVars);
vector<SgArrayRefExp*> arrayRefs = getDirectArrayRefsFromSingleStmt(st, arrayToRemove.varSymbol);
for (SgArrayRefExp* arrayRef : arrayRefs)
arrayToRemove.arrayRefToIterationVarsMap.insert(make_pair(arrayRef, iterationVars));
}
auto& fixedDimensions = arrayToRemove.fixedDimensions;
for (auto& defUsePair : arrayToRemove.defUseStmtsPairs)
{
@@ -833,6 +802,7 @@ void removePrivates(string filename, vector<Messages>& messages,
const map<string, vector<FuncInfo*>>& allFuncInfo,
int& countOfTransform)
{
set<LoopGraph*> removeDC;
for (auto& varToRemove : privatesToRemoveGlobal)
{
if (filename != varToRemove.loop->fileName)
@@ -841,18 +811,10 @@ void removePrivates(string filename, vector<Messages>& messages,
auto removedDimensions = removeArray(filename, varToRemove);
countOfTransform++;
//removeDeadCodeFromLoop(varToRemove.loop);
removeExcessiveDefs(varToRemove);
//removeEmptyLoops(varToRemove.loop, messages);
removeDC.insert(varToRemove.loop);
SgForStmt* loopStmt = (SgForStmt*)varToRemove.loop->loop->GetOriginal();
FuncInfo* currFunc = getCurrectFunc(loopStmt, allFuncInfo);
if (currFunc == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
removeDeadCode(currFunc->funcPointer, allFuncInfo, commonBlocks);
vector<SgArrayRefExp*> varRefs = getDirectArrayRefs(loopStmt, varToRemove.varSymbol);
vector<SgArrayRefExp*> varRefs = getDirectArrayRefs(varToRemove.loop->loop, varToRemove.varSymbol);
int loopLineNum = varToRemove.loop->lineNum;
string varName = varToRemove.varSymbol->identifier();
auto& fixedDimensions = varToRemove.fixedDimensions;
@@ -863,7 +825,7 @@ void removePrivates(string filename, vector<Messages>& messages,
}
else
{
varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime,
varRefs = removeDuplicateArrayRefs(varRefs, fixedDimensions, varToRemove.regime,
varToRemove.arrayRefToIterationVarsMap);
for (auto& varRef : varRefs)
{
@@ -886,6 +848,18 @@ void removePrivates(string filename, vector<Messages>& messages,
}
}
}
for (auto& dcLoopRem : removeDC)
{
auto loopStmt = dcLoopRem->loop->GetOriginal();
FuncInfo* currFunc = getCurrentFunc(loopStmt, allFuncInfo);
if (currFunc == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
removeDeadCode(currFunc->funcPointer, allFuncInfo, commonBlocks,
loopStmt, loopStmt->lastNodeOfStmt());
}
}
/* ****************************************** *
@@ -989,19 +963,6 @@ static vector<int> getShortFixedSubscriptsVector(Context* ctx, SgArrayRefExp* ar
return getShortFixedSubscriptsVector(arrayRef, ctx->fixedDimensionsMask, ctx->regime, iterationVars);
}
// fillIterationVariables fill vars set with iteration variables of all loops
// from stmt to outerLoopStmt
static void fillIterationVars(SgStatement* stmt, SgStatement* outerLoopStmt, vector<SgSymbol*>& vars)
{
if (stmt == nullptr)
return;
if (stmt->variant() == FOR_NODE)
vars.push_back(((SgForStmt*)stmt)->doName());
if (stmt->id() != outerLoopStmt->id())
fillIterationVars(stmt->controlParent(), outerLoopStmt, vars);
}
// matchesFixedDimensionsMask checks if all array references have INT_VAL value in fixed dimension
static bool checkFixedDimensionsMaskMatching(Context* ctx)
@@ -1113,6 +1074,7 @@ static bool checkRegularIndexRefs(Context* ctx)
return false;
}
// TODO: possibly can be removed:
if (st->variant() == ASSIGN_STAT && isEqSymbols(st->expr(0)->symbol(), ctx->arraySymbol))
for (auto iterationVar : iterationVars)
if (isSymbolInExpression(iterationVar, st->expr(1)))
@@ -1172,17 +1134,17 @@ static SgForStmt* getLoopStmtForVar(SgStatement* stmt, string loopVar)
// getFixedSubscriptsVector returns vector of fixed INT_VAL subscripts of arrayRef
// true - subscript is fixed, false - it isn't
static vector<FixedSubscript> getFixedSubscriptsVector(SgArrayRefExp* arrayRef, int dimensionsNum = 0,
static vector<ArraySubscript> getFixedSubscriptsVector(SgArrayRefExp* arrayRef, int dimensionsNum = 0,
SgStatement* stmt = nullptr)
{
if (arrayRef->numberOfSubscripts() == 0)
return vector<FixedSubscript>(dimensionsNum);
if (arrayRef == nullptr || arrayRef->numberOfSubscripts() == 0)
return vector<ArraySubscript>(dimensionsNum);
vector<FixedSubscript> subscriptsVector;
vector<ArraySubscript> subscriptsVector;
for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i)
{
SgExpression* subscriptExpr = arrayRef->subscript(i);
FixedSubscript sub;
ArraySubscript sub;
if (subscriptExpr->variant() == INT_VAL)
{
@@ -1228,7 +1190,7 @@ static vector<FixedSubscript> getFixedSubscriptsVector(SgArrayRefExp* arrayRef,
// checkImplicitDirectUsage returns masks of array implicit usage (as out argument)
// in any function call in exp and writes message about each usage
static void checkImplicitDirectUsage(Context* ctx, SgExpression* exp, int stmtLineNum,
vector<vector<FixedSubscript>>& fixedSubscripts)
vector<vector<ArraySubscript>>& fixedSubscripts)
{
if (exp == nullptr)
return;
@@ -1237,15 +1199,16 @@ static void checkImplicitDirectUsage(Context* ctx, SgExpression* exp, int stmtLi
{
SgFunctionCallExp* funcCallExp = (SgFunctionCallExp*)exp;
string funcName = funcCallExp->funName()->identifier();
FuncInfo* funcInfo = findFunc(ctx->loopStmt->fileName(), funcName, ctx->allFuncInfo);
FuncInfo* funcInfo = findFuncByName(funcName, ctx->allFuncInfo);
if (funcInfo != nullptr)
{
for (int i = 0; i < funcCallExp->numberOfArgs(); ++i)
{
SgExpression* funcArg = funcCallExp->arg(i);
if (funcInfo->funcParams.isArgOut(i)
&& funcArg->symbol() != nullptr
&& isEqSymbols(funcArg->symbol(), ctx->arraySymbol))
if (funcArg->symbol() == nullptr || !isEqSymbols(funcArg->symbol(), ctx->arraySymbol))
continue;
if (funcInfo->funcParams.isArgOut(i) || funcArg->lhs() == nullptr)
{
auto fixedVec = getFixedSubscriptsVector((SgArrayRefExp*)funcArg, ctx->dimensionsNum);
fixedSubscripts.push_back(fixedVec);
@@ -1263,9 +1226,9 @@ static void checkImplicitDirectUsage(Context* ctx, SgExpression* exp, int stmtLi
// checkImplicitDirectUsage returns masks of array implicit usage (as out argument)
// and reference to whole array (like fcall(A, 1)) in any function call in loop
// and writes message about each usage
static vector<vector<FixedSubscript>> checkImplicitDirectUsage(Context* ctx)
static vector<vector<ArraySubscript>> checkImplicitDirectUsage(Context* ctx)
{
vector<vector<FixedSubscript>> fixedSubscripts;
vector<vector<ArraySubscript>> fixedSubscripts;
for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext())
{
if (st->variant() != PROC_STAT)
@@ -1279,8 +1242,8 @@ static vector<vector<FixedSubscript>> checkImplicitDirectUsage(Context* ctx)
// st->variant() == PROC_STAT:
SgCallStmt* callStmt = (SgCallStmt*)st;
string procName = callStmt->name()->identifier();
FuncInfo* funcInfo = findFunc(callStmt->fileName(), procName, ctx->allFuncInfo);
FuncInfo* funcInfo = findFuncByName(procName, ctx->allFuncInfo);
for (int i = 0; i < callStmt->numberOfArgs(); ++i)
{
SgExpression* callArg = callStmt->arg(i);
@@ -1330,42 +1293,69 @@ static vector<Variable*> getCommonBlockGroupedVar(FuncInfo* curFunc, SgSymbol* v
// checkIndirectUsage returns masks of array indirect usage in function
// (indirect usage is usage through common blocks) and writes messages about it
static void checkIndirectUsage(Context* ctx, FuncInfo* curFunc, vector<Variable*> commonBlockGroupedVar,
set<string>& visitedFuncs, vector<vector<FixedSubscript>>& indirectUsageMasks)
static void checkIndirectUsage(Context* ctx, FuncInfo* calledFunc, vector<Variable*> commonBlockGroupedVar,
set<string>& visitedFuncs, vector<vector<ArraySubscript>>& indirectUsageMasks)
{
if (visitedFuncs.find(curFunc->funcName) != visitedFuncs.end())
if (calledFunc == nullptr)
return;
visitedFuncs.insert(curFunc->funcName);
if (visitedFuncs.find(calledFunc->funcName) != visitedFuncs.end())
return;
visitedFuncs.insert(calledFunc->funcName);
for (Variable* commonBlockVar : commonBlockGroupedVar)
{
for (const CommonVariableUse& varUse : commonBlockVar->getAllUse())
{
if (varUse.getFileName() != curFunc->fileName || varUse.getFunctionName() != curFunc->funcName)
if (varUse.getFileName() != calledFunc->fileName || varUse.getFunctionName() != calledFunc->funcName)
continue;
vector<SgArrayRefExp*> directArrayRefs = getDirectArrayRefs(varUse.getFunction(), varUse.getUseS());
SgStatement* calledFuncStmt = varUse.getFunction();
calledFuncStmt->switchToFile();
vector<SgArrayRefExp*> directArrayRefs = getDirectArrayRefs(calledFuncStmt, varUse.getUseS());
for (auto arrayRef : directArrayRefs)
{
auto mask = getFixedSubscriptsVector(arrayRef, ctx->dimensionsNum);
indirectUsageMasks.push_back(mask);
addMessageUsageInFunctionCall(ctx->messages, getDimensionVarName(ctx->arraySymbol, mask),
curFunc->funcName, ctx->loop->lineNum, ctx->loop->lineNum);
calledFunc->funcName, ctx->loop->lineNum, ctx->loop->lineNum);
}
ctx->loopStmt->switchToFile();
}
}
for (FuncInfo* calledFunc : curFunc->callsFromV)
checkIndirectUsage(ctx, calledFunc, commonBlockGroupedVar, visitedFuncs, indirectUsageMasks);
for (FuncInfo* subCalledFunc : calledFunc->callsFromV)
checkIndirectUsage(ctx, subCalledFunc, commonBlockGroupedVar, visitedFuncs, indirectUsageMasks);
}
// checkIndirectUsage returns masks of array indirect usage in any function call in exp
// (indirect usage is usage through common blocks) and writes messages about it
static void checkIndirectUsage(Context* ctx, SgExpression* exp, vector<Variable*> commonBlockGroupedVar,
set<string>& visitedFuncs, vector<vector<ArraySubscript>>& indirectUsageMasks)
{
if (exp == nullptr)
return;
if (exp->variant() == FUNC_CALL)
{
SgFunctionCallExp* funcCallExp = (SgFunctionCallExp*)exp;
string funcName = funcCallExp->funName()->identifier();
FuncInfo* funcInfo = findFuncByName(funcName, ctx->allFuncInfo);
if (funcInfo != nullptr)
checkIndirectUsage(ctx, funcInfo, commonBlockGroupedVar, visitedFuncs, indirectUsageMasks);
}
checkIndirectUsage(ctx, exp->lhs(), commonBlockGroupedVar, visitedFuncs, indirectUsageMasks);
checkIndirectUsage(ctx, exp->rhs(), commonBlockGroupedVar, visitedFuncs, indirectUsageMasks);
}
// checkIndirectUsage returns masks of array indirect usage in any function call in loop
// (indirect usage is usage through common blocks) and writes messages about it
static vector<vector<FixedSubscript>> checkIndirectUsage(Context* ctx)
static vector<vector<ArraySubscript>> checkIndirectUsage(Context* ctx)
{
vector<vector<FixedSubscript>> indirectUsageMasks;
FuncInfo* currentFunc = getCurrectFunc(ctx->loopStmt, ctx->allFuncInfo);
vector<vector<ArraySubscript>> indirectUsageMasks;
FuncInfo* currentFunc = getCurrentFunc(ctx->loopStmt, ctx->allFuncInfo);
if (currentFunc == nullptr)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1373,19 +1363,29 @@ static vector<vector<FixedSubscript>> checkIndirectUsage(Context* ctx)
if (commonBlockGroupedVar.empty())
return indirectUsageMasks;
set<string> visitedFunctions = { currentFunc->funcName };
for (FuncInfo* calledFunc : currentFunc->callsFromV)
checkIndirectUsage(ctx, calledFunc, commonBlockGroupedVar, visitedFunctions, indirectUsageMasks);
for (SgStatement* st = ctx->loopStmt->lexNext(); st != ctx->loopStmt->lastNodeOfStmt(); st = st->lexNext())
{
if (st->variant() == PROC_STAT)
{
SgCallStmt* callStmt = (SgCallStmt*)st;
string procName = callStmt->name()->identifier();
FuncInfo* calledFunc = findFuncByName(procName, ctx->allFuncInfo);
checkIndirectUsage(ctx, calledFunc, commonBlockGroupedVar, visitedFunctions, indirectUsageMasks);
}
for (int i = 0; i < 3; ++i)
checkIndirectUsage(ctx, st->expr(i), commonBlockGroupedVar, visitedFunctions, indirectUsageMasks);
}
return indirectUsageMasks;
}
// checkImplicitAndIndirectUsage returns masks of implicit or indirect array usage in loop
static vector<vector<FixedSubscript>> checkImplicitAndIndirectUsage(Context* ctx)
static vector<vector<ArraySubscript>> checkImplicitAndIndirectUsage(Context* ctx)
{
vector<vector<FixedSubscript>> implicitMasks = checkImplicitDirectUsage(ctx);
vector<vector<FixedSubscript>> indirectMasks = checkIndirectUsage(ctx);
vector<vector<ArraySubscript>> implicitMasks = checkImplicitDirectUsage(ctx);
vector<vector<ArraySubscript>> indirectMasks = checkIndirectUsage(ctx);
implicitMasks.insert(implicitMasks.end(), indirectMasks.begin(), indirectMasks.end());
return implicitMasks;
@@ -1393,7 +1393,7 @@ static vector<vector<FixedSubscript>> checkImplicitAndIndirectUsage(Context* ctx
// filterArrayRefs removes from arrayRefs all refs that are not different from fixedVectors
static void filterArrayRefs(Context* ctx, vector<SgArrayRefExp*>& arrayRefs,
const vector<vector<FixedSubscript>>& masks)
const vector<vector<ArraySubscript>>& masks)
{
if (masks.empty())
return;
@@ -1401,7 +1401,7 @@ static void filterArrayRefs(Context* ctx, vector<SgArrayRefExp*>& arrayRefs,
vector<SgArrayRefExp*> filteredArrayRefs;
for (auto arrayRef : arrayRefs)
{
vector<FixedSubscript> arrayRefVec = getFixedSubscriptsVector(arrayRef, ctx->dimensionsNum);
vector<ArraySubscript> arrayRefVec = getFixedSubscriptsVector(arrayRef, ctx->dimensionsNum);
bool isDifferent = false;
for (auto& mask : masks)
@@ -1664,17 +1664,21 @@ static vector<DefUseStmtsPair> buildDefUsePairs(Context* ctx, const CFG_Type& CF
if (!defIsFound)
{
// try to find definition not from RD_defArgs:
// try to find definition not from RD_defArgs, by search in the block instructions:
string defVarName = useInsertedStmt.insertedStmt->expr(1)->symbol()->identifier();
SgStatement* blockStart = useInsAndBlock.second->getInstructions().front()->getInstruction()->getOperator();
SgStatement* blockEnd = useInsAndBlock.second->getInstructions().back()->getInstruction()->getOperator();
for (SgStatement* st = blockStart; st != blockEnd; st = st->lexNext())
const auto& blockInstructionsVector = useInsAndBlock.second->getInstructions();
for (auto& instruction : blockInstructionsVector)
{
if (st->variant() == ASSIGN_STAT && st->expr(0)->symbol()->identifier() == defVarName &&
!isVarChangedBetween(defVarName, st, useInsertedStmt.insertedStmt))
SgStatement* stmt = instruction->getInstruction()->getOperator();
if (stmt == useInsertedStmt.insertedStmt)
break;
if (stmt->variant() == ASSIGN_STAT
&& stmt->expr(0)->symbol()->identifier() == defVarName
&& !isVarChangedBetween(defVarName, stmt, useInsertedStmt.insertedStmt))
{
defIsFound = true;
defStmt = st;
defStmt = stmt;
break;
}
}
@@ -1790,7 +1794,7 @@ static LoopGraph* leastCommonAncestor(LoopGraph* a, LoopGraph* b, LoopGraph* par
// fillFullFixedSubscriptsVectorsOfAllVars return vector of pairs (name of var, its fixed subscripts vector)
// of all VAR_REF and ARRAY_REF vars in exp
static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp,
vector<pair<string, vector<FixedSubscript>>>& vec,
vector<pair<string, vector<ArraySubscript>>>& vec,
SgStatement* stmt = nullptr)
{
if (exp == nullptr)
@@ -1804,7 +1808,7 @@ static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp,
if (elem.first == exp->symbol()->identifier())
return;
vec.push_back(make_pair(exp->symbol()->identifier(), vector<FixedSubscript>{}));
vec.push_back(make_pair(exp->symbol()->identifier(), vector<ArraySubscript>{}));
}
else if (exp->variant() == ARRAY_REF)
{
@@ -1823,7 +1827,7 @@ static void fillFixedSubscriptsVectorsOfAllVars(SgExpression* exp,
}
// fixedSubscriptLess checks if left FixedSubscript is less than right
static bool fixedSubscriptLess(const FixedSubscript& left, const FixedSubscript& right)
static bool fixedSubscriptLess(const ArraySubscript& left, const ArraySubscript& right)
{
if (left.isFixed && right.isFixed && left.value < right.value)
return true;
@@ -1844,7 +1848,7 @@ static bool fixedSubscriptLess(const FixedSubscript& left, const FixedSubscript&
// fixedSubscriptLess checks if left and right FixedSubscripts are different,
// using empirical methods
static bool possibleDifferent(FixedSubscript left, FixedSubscript right)
static bool possibleDifferent(ArraySubscript left, ArraySubscript right)
{
// TODO: add warning?
if (left.isFixed && right.isRegIndex && right.regExprStart == right.regExprEnd) {
@@ -1856,7 +1860,7 @@ static bool possibleDifferent(FixedSubscript left, FixedSubscript right)
// isDifferentRefs checks if exp (var reference) is different from var. Refs are different
// if they has at least one different fixed subscript: arr(i, 1) is different from arr(j, 2)
static bool isDifferentRefs(SgExpression* exp, const pair<string, vector<FixedSubscript>>& var, SgStatement* stmt)
static bool isDifferentRefs(SgExpression* exp, const pair<string, vector<ArraySubscript>>& var, SgStatement* stmt)
{
if (exp->symbol()->identifier() != var.first)
return true;
@@ -1864,7 +1868,7 @@ static bool isDifferentRefs(SgExpression* exp, const pair<string, vector<FixedSu
if (exp->variant() == VAR_REF)
return false;
vector<FixedSubscript> leftVec = getFixedSubscriptsVector((SgArrayRefExp*)exp, 0, stmt);
vector<ArraySubscript> leftVec = getFixedSubscriptsVector((SgArrayRefExp*)exp, 0, stmt);
if (leftVec.size() != var.second.size())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
@@ -1907,7 +1911,7 @@ static bool checkDefUsePair(Context* ctx, const DefUseStmtsPair& defUse, const C
string arrayName = ctx->arraySymbol->identifier();
vector<pair<string, vector<FixedSubscript>>> dependOnVars;
vector<pair<string, vector<ArraySubscript>>> dependOnVars;
SgArrayRefExp* defRef = (SgArrayRefExp*)defUse.first->expr(0);
vector<SgArrayRefExp*> arrayUseRefs = getDirectArrayRefsFromSingleStmt(defUse.second, ctx->arraySymbol);
for (auto useRef : arrayUseRefs)
@@ -2170,13 +2174,13 @@ void removePrivatesAnalysis(string filename,
auto filterMasks = checkImplicitAndIndirectUsage(&context);
filterArrayRefs(&context, arrayRefs, filterMasks);
context.explicitArrayRefs.swap(arrayRefs);
context.explicitArrayRefs.swap(arrayRefs);
if (context.explicitArrayRefs.empty())
continue;
context.fixedDimensionsMask = getFixedDimensionsMask(&context);
if (!context.fixedDimensionsMask.empty() &&
checkFixedDimensionsMaskMatching(&context) &&
checkDefStmtRefsMatchesMask(&context))

View File

@@ -0,0 +1,193 @@
#include "../Utils/leak_detector.h"
#include <string>
#include <map>
#include "Utils/SgUtils.h"
#include "set_implicit_none.h"
using std::vector;
using std::map;
using std::set;
using std::string;
static const char commonIntLetters[6] = { 'i', 'j', 'k', 'm', 'n', 'l' };
static void InitTypes(map<char, SgType*>& types)
{
for (char letter = 'a'; letter <= 'z'; letter++)
types[letter] = 0;
}
static void FillCommonTypes(map<char, SgType*>& types)
{
for (char letter : commonIntLetters)
if (types[letter] == 0)
types[letter] = new SgType(T_INT);
for (auto letter : types)
if (letter.second == NULL)
types[letter.first] = new SgType(T_FLOAT);
}
static void FindAllVars(SgExpression* expr, set<SgSymbol*>& allVars)
{
if (expr == NULL)
return;
if (expr->variant() == VAR_REF || expr->variant() == ARRAY_REF)
allVars.insert(expr->symbol());
FindAllVars(expr->lhs(), allVars);
FindAllVars(expr->rhs(), allVars);
}
static char getValue(SgExpression* ex)
{
char charVal = 0;
if (ex && ex->variant() == CHAR_VAL)
charVal = isSgValueExp(ex)->charValue();
return charVal;
}
static void AddLettersToMap(SgExpression* expr, SgType* type, map<char, SgType*>& types)
{
while (expr)
{
if (expr->variant() != EXPR_LIST)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
SgExpression* val = expr->lhs();
if (val->variant() == DDOT)
{
char leftVal = getValue(val->lhs());
char rightVal = getValue(val->rhs());
if (leftVal == 0 || rightVal == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
for (char letter = leftVal; letter <= rightVal; letter++)
types[letter] = type;
}
else
{
char charVal = getValue(val);
if (charVal == 0)
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
types[charVal] = type;
}
expr = expr->rhs();
}
}
static map<char, SgType*> FunctionImplicitCheck(SgStatement* function, const map<SgStatement*, map<char, SgType*>>& typesByFunctions)
{
set<SgSymbol*> allVars;
map<char, SgType*> types;
vector<SgSymbol*> varsWithoutDecl;
InitTypes(types);
FillCommonTypes(types);
auto cp = function->controlParent();
if (isSgProgHedrStmt(cp))
if (typesByFunctions.find(cp) != typesByFunctions.end())
for (auto& parentType : typesByFunctions.at(cp))
types[parentType.first] = parentType.second;
auto hasImplicitNone = false;
auto endOfFunc = function->lastNodeOfStmt();
for (auto st = function; st != endOfFunc; st = st->lexNext())
{
if (st->variant() == IMPL_DECL)
{
SgImplicitStmt* implicitStatement = isSgImplicitStmt(st);
if (implicitStatement != NULL)
{
const int numberOfTypes = implicitStatement->numberOfImplicitTypes();
if (numberOfTypes > 0)
{
for (int j = 0; j < numberOfTypes; ++j)
{
SgType* type = implicitStatement->implicitType(j);
SgExpression* lettersExpression = implicitStatement->implicitRangeList(j);
AddLettersToMap(lettersExpression, type, types);
}
}
else
hasImplicitNone = true;
}
}
else if (st->variant() == CONTAINS_STMT || isSgExecutableStatement(st) != NULL)
break;
}
for (auto st = function; st != endOfFunc && st->variant() != CONTAINS_STMT; st = st->lexNext())
for (int i = 0; i < 3; ++i)
FindAllVars(st->expr(i), allVars);
for (auto& var : allVars)
{
if (string(var->identifier()) == function->symbol()->identifier())
continue;
vector<SgStatement*> _;
SgStatement* declaredInStatement = declaratedInStmt(var, &_, false);
if (declaredInStatement == NULL)
{
const char c = var->identifier()[0];
if (types.find(c) != types.end())
var->setType(types[c]);
varsWithoutDecl.push_back(var);
}
}
makeDeclaration(varsWithoutDecl, function, NULL);
if (!hasImplicitNone)
{
for (auto st = function->lexNext();
st != endOfFunc && st->variant() != CONTAINS_STMT && isSgExecutableStatement(st) == NULL;
)
{
if (st->variant() == IMPL_DECL)
{
auto tmpStatement = st;
st = st->lexNext();
tmpStatement->deleteStmt();
}
else
st = st->lexNext();
}
auto implNone = new SgStatement(IMPL_DECL);
implNone->setlineNumber(function->lineNumber());
implNone->setFileName(function->fileName());
function->insertStmtAfter(*implNone, *function);
}
allVars.clear();
varsWithoutDecl.clear();
return types;
}
void implicitCheck(SgFile* file)
{
map<SgStatement*, map<char, SgType*>> typesByFunctions;
for (int func = 0; func < file->numberOfFunctions(); ++func)
{
SgStatement* function = file->functions(func);
typesByFunctions[function] = FunctionImplicitCheck(function, typesByFunctions);
}
typesByFunctions.clear();
}

View File

@@ -0,0 +1,3 @@
#pragma once
void implicitCheck(SgFile* file);

View File

@@ -227,13 +227,13 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
list({ VERIFY_ENDDO, VERIFY_INCLUDE, PREPROC_SPF, PREPROC_ALLOCATES, GET_ALL_ARRAY_DECL, GCOV_PARSER }) <= list({ CALL_GRAPH, MACRO_EXPANSION, DEF_USE_STAGE1 });
list({ VERIFY_ENDDO, VERIFY_INCLUDE, PREPROC_ALLOCATES, FILL_PARALLEL_REG_IR }) <= list({ GET_ALL_ARRAY_DECL, FILL_COMMON_BLOCKS }) <= Pass(PREPROC_SPF);
list({ VERIFY_ENDDO, VERIFY_INCLUDE, 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({ GET_ALL_ARRAY_DECL, CALL_GRAPH2, CODE_CHECKER_PASSES, 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);
list({ LOOP_ANALYZER_NODIST, REMOVE_OMP_DIRS }) <= Pass(SELECT_ARRAY_DIM_CONF) <= Pass(INSERT_PARALLEL_DIRS_NODIST);
Pass(CHECK_ARGS_DECL) <= Pass(CREATE_TEMPLATE_LINKS);
@@ -251,7 +251,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
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, SELECT_ARRAY_DIM_CONF});
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);
@@ -291,7 +291,7 @@ void InitPassesDependencies(map<passes, vector<passes>> &passDepsIn, set<passes>
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 });
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);
@@ -307,8 +307,8 @@ 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_RD, CONVERT_LOOP_TO_ASSIGN, RESTORE_LOOP_FROM_ASSIGN }) <= Pass(REMOVE_DEAD_CODE_AND_UNPARSE);
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);
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,

View File

@@ -1153,7 +1153,7 @@ bool isSPF_stat(SgStatement *st)
const int var = st->variant();
//for details see dvm_tag.h
if (var >= SPF_ANALYSIS_DIR && var <= SPF_UNROLL_OP)
if (var >= SPF_ANALYSIS_DIR && var <= SPF_PROCESS_PRIVATE_OP)
ret = true;
return ret;
}
@@ -3543,10 +3543,11 @@ void getMaxMinBlockDistribution(SgFile* file, pair<int, int>& min_max)
}
}
//TODO: need to add to includes
void addPrivatesToArraysFromGUI(SgFile* file, const map<tuple<int, string, string>, pair<DIST::Array*, DIST::ArrayAccessInfo*>>& declaredArrays,
const map<string, int>& distrStateFromGUI)
{
map<SgStatement*, set<string>> added;
map<SgStatement*, set<SgSymbol*>> added;
for (auto& arrayPair : declaredArrays)
{
@@ -3570,12 +3571,19 @@ void addPrivatesToArraysFromGUI(SgFile* file, const map<tuple<int, string, strin
SgStatement* declSt = SgStatement::getStatementByFileAndLine(place.first, place.second);
checkNull(declSt, convertFileName(__FILE__).c_str(), __LINE__);
string toAdd = "!$SPF ANALYSIS(PRIVATE(" + string(symb->identifier()) + "))\n";
added[declSt].insert(toAdd);
added[declSt].insert(symb);
}
}
for (auto& toInsert : added)
{
vector<SgExpression*> list;
for (auto& elem : toInsert.second)
toInsert.first->addComment(elem.c_str());
list.push_back(new SgVarRefExp(elem));
SgStatement* op = new SgStatement(SPF_ANALYSIS_DIR);
op->setExpression(0, new SgExpression(SPF_PROCESS_PRIVATE_OP, makeExprList(list)));
toInsert.first->insertStmtBefore(*op, *toInsert.first->controlParent());
}
}

View File

@@ -127,6 +127,7 @@ enum typeMessage { WARR, ERROR, NOTE };
// 21 "empty parallel regions is forbidden"
// 22 "Can not find align rules"
// 23 "Array reference '%s' has a different size from the original array"
// 24 "Array's memory intersections prevents this loop from parallelization"
// 40xx LOW LEVEL WARNINGS
// 01
@@ -275,7 +276,7 @@ static void printStackTrace() { };
} \
} while (0)
// Свободный - R204
// Свободный - R205
// Гайд по русификации сообщений: При добавлении нового сообщения, меняется последний сводобный идентификатор.
// В этом файле остаются только спецификаторы, для которых будет заполнен текст. Полный текст пишется в файле
// russian_errors_text.txt. Спецификаторы там тоже сохраняются, по ним в визуализаторе будет восстановлен
@@ -603,6 +604,8 @@ static const wchar_t *R151 = L"R151:";
static const wchar_t *R171 = L"R171:%s";
//3023
static const wchar_t *R202 = L"R202:%s";
//3024
static const wchar_t* R204 = L"R204:";
//4001
//---TODO ошибки из SAGE

View File

@@ -1,7 +1,7 @@
//1001
R1 = "Неверное расположение директивы: можно располагать только %s %s %s"
RR1_1 = "перед"
RR1_2 = "объявлением переменных или"
RR1_2 = "объявлением переменных"
RR1_3 = "циклом"
RR1_4 = "после"
RR1_5 = "всех операторов объявления"
@@ -314,6 +314,8 @@ R151 = "Пустые области распараллеливания недо
R171 = "Невозможно определить правила выравнивания для массива '%s'."
//3023
R202 = "Ссылка '%s' имеет отличный от оригинального массива размер"
//3024
R204 = "Пересечение памяти массивов препятствует распараллеливанию цикла"
//4001
//---TODO ошибки из SAGE

View File

@@ -19,6 +19,7 @@
#include <locale>
#include <algorithm>
#include <thread>
#include <cstdint>
#include "utils.h"
#include "errors.h"
@@ -184,6 +185,7 @@ extern int staticShadowAnalysis;
extern int keepDvmDirectives;
extern int ignoreIO;
extern int keepSpfDirs;
extern int maxShadowWidth;
const string printVersionAsFortranComm()
{
@@ -199,13 +201,14 @@ const string printVersionAsFortranComm()
ret += "! *** shadow optimization\n";
if (keepDvmDirectives)
ret += "! *** consider DVMH directives\n";
if (keepSpfDirs)
ret += "! *** save SPF directives\n";
if (mpiProgram)
ret += "! *** MPI program regime (shared memory parallelization)\n";
if (ignoreIO)
ret += "! *** ignore I/O checker for arrays (DVM I/O limitations)\n";
if (keepSpfDirs)
ret += "! *** save SPF directives\n";
if (maxShadowWidth > 0)
ret += "! *** maximum shadow width is " + std::to_string(maxShadowWidth) + " percent\n";
ret += "! *** generated by SAPFOR\n";
return ret;
@@ -1159,7 +1162,9 @@ template vector<LoopGraph*>& getObjectForFileFromMap(const char *fileName, map<s
template vector<FuncInfo*>& getObjectForFileFromMap(const char *fileName, map<string, vector<FuncInfo*>>&);
template map<int, Gcov_info>& getObjectForFileFromMap(const char *fileName, map<string, map<int, Gcov_info>>&);
template map<int, double>& getObjectForFileFromMap(const char *fileName, map<string, map<int, double>>&);
#if __SPF
template map<SgStatement*, vector<SgStatement*>>& getObjectForFileFromMap(const char* fileName, map<string, map<SgStatement*, vector<SgStatement*>>>&);
#endif
static set<string> mpiFunctions;
bool isMpiFunction(const string& func)
@@ -1573,3 +1578,71 @@ vector<string> splitAndArgvCreate(const string& options)
}
return optSplited1;
}
static bool isNotNullIntersection(const set<DIST::Array*>& first, const set<DIST::Array*>& second)
{
for (auto& elem1 : first)
if (second.find(elem1) != second.end())
return true;
return false;
}
set<DIST::Array*> fillDistributedArraysD(const DataDirective& dataDirectives,
const map<DIST::Array*, tuple<int, string, string>>& tableOfUniqNamesByArray,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
bool onlyCommon)
{
set<DIST::Array*> distrArrays;
set<DIST::Array*> distrArraysD;
set<DIST::Array*> distrArraysAdded;
for (int z = 0; z < dataDirectives.distrRules.size(); ++z)
distrArraysD.insert(dataDirectives.distrRules[z].first);
for (int z = 0; z < dataDirectives.alignRules.size(); ++z)
distrArraysD.insert(dataDirectives.alignRules[z].alignArray);
for (auto& elem : tableOfUniqNamesByArray)
{
set<DIST::Array*> realRefs;
getRealArrayRefs(elem.first, elem.first, realRefs, arrayLinksByFuncCalls);
if (isNotNullIntersection(realRefs, distrArraysD))
distrArraysAdded.insert(elem.first);
}
for (auto& elem : distrArraysD)
{
if (onlyCommon)
{
if (elem->GetLocation().first == DIST::l_COMMON)
distrArrays.insert(elem);
}
else
distrArrays.insert(elem);
}
for (auto& elem : distrArraysAdded)
{
if (onlyCommon)
{
if (elem->GetLocation().first == DIST::l_COMMON)
distrArrays.insert(elem);
}
else
distrArrays.insert(elem);
}
return distrArrays;
}
set<string> fillDistributedArrays(const DataDirective& dataDirectives,
const map<DIST::Array*, tuple<int, string, string>>& tableOfUniqNamesByArray,
const map<DIST::Array*, set<DIST::Array*>>& arrayLinksByFuncCalls,
bool onlyCommon, bool shortName)
{
set<string> distrArrays;
set<DIST::Array*> ret = fillDistributedArraysD(dataDirectives, tableOfUniqNamesByArray, arrayLinksByFuncCalls, onlyCommon);
for (auto& elem : ret)
distrArrays.insert(shortName ? elem->GetShortName() : elem->GetName());
return distrArrays;
}

View File

@@ -3,11 +3,13 @@
#include <vector>
#include <set>
#include <string>
#include <cstdint>
struct DataDirective;
namespace Distribution
{
class Array;
class ArrayAccessInfo;
class ArrayAccessInfo;
template<typename vType> class Arrays;
}
namespace DIST = Distribution;
@@ -90,3 +92,6 @@ std::wstring fixedLongFormat(const wchar_t* old);
std::map<std::string, DIST::Array*> sortArraysByName(const std::set<DIST::Array*>& toSort);
bool createDirectory(const std::string& name);
std::vector<std::string> splitAndArgvCreate(const std::string& options);
std::set<DIST::Array*> fillDistributedArraysD(const DataDirective& dataDirectives, const std::map<DIST::Array*, std::tuple<int, std::string, std::string>>& tableOfUniqNamesByArray, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, bool onlyCommon = false);
std::set<std::string> fillDistributedArrays(const DataDirective& dataDirectives, const std::map<DIST::Array*, std::tuple<int, std::string, std::string>>& tableOfUniqNamesByArray, const std::map<DIST::Array*, std::set<DIST::Array*>>& arrayLinksByFuncCalls, bool onlyCommon = false, bool shortName = false);

View File

@@ -1,3 +1,3 @@
#pragma once
#define VERSION_SPF "2289"
#define VERSION_SPF "2320"

View File

@@ -12,7 +12,6 @@
#include "../Utils/utils.h"
#include "../Utils/SgUtils.h"
#include "../Utils/errors.h"
#include "../DirectiveProcessing/directive_parser.h"
using std::vector;
using std::map;
@@ -32,7 +31,6 @@ bool EndDoLoopChecker(SgFile *file, vector<Messages> &currMessages)
SgStatement *st = file->functions(i);
SgStatement *lastNode = st->lastNodeOfStmt();
OmpDir globalParallelSection;
while (st != lastNode)
{
if (st == NULL)
@@ -44,31 +42,6 @@ bool EndDoLoopChecker(SgFile *file, vector<Messages> &currMessages)
if (st->variant() == CONTAINS_STMT)
break;
{
set<string> globalPriv;
auto res = parseOmpDirs(st, globalPriv);
for (auto& dir : res)
{
auto end = dir.keys.end();
if (dir.keys.find("parallel") != end
&& dir.keys.find("do") == end
&& dir.privVars.size()
&& dir.keys.find("end") == end)
{
if (globalParallelSection.keys.size())
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
globalParallelSection = dir;
}
else if (dir.keys.find("parallel") != end
&& dir.keys.find("do") == end
&& dir.keys.find("end") != end)
{
globalParallelSection = OmpDir();
}
}
}
if (st->variant() == FOR_NODE)
{
SgForStmt *currSt = (SgForStmt*)st;
@@ -78,13 +51,6 @@ bool EndDoLoopChecker(SgFile *file, vector<Messages> &currMessages)
currMessages.push_back(Messages(ERROR, st->lineNumber(), R51, L"This loop does not have END DO format", 1018));
checkOK = false;
}
else
{
set<string> globalPriv;
if (globalParallelSection.privVars.size())
globalPriv = globalParallelSection.privVars;
auto res = parseOmpDirs(st, globalPriv, true);
}
}
if (st->variant() == FORALL_NODE || st->variant() == FORALL_STAT ||

View File

@@ -820,7 +820,7 @@ int SPF_GetArrayDistribution(void*& context, int winHandler, short *options, sho
else if (regime == 1)
{
if (mpiProgram)
runPassesForVisualizer(projName, { LOOP_ANALYZER_NODIST });
runPassesForVisualizer(projName, { SELECT_ARRAY_DIM_CONF });
else
runPassesForVisualizer(projName, { LOOP_ANALYZER_DATA_DIST_S1 });
}
@@ -1674,10 +1674,11 @@ int SPF_SetDistributionFlagToArrays(void*& context, const char* keys, const char
}
static int simpleTransformPass(const passes PASS_NAME, short *options, short *projName, short *folderName,
short *&output, int *&outputSize, short *&outputMessage, int *&outputMessageSize)
short *&output, int *&outputSize, short *&outputMessage, int *&outputMessageSize,
bool isBuildParallel = false)
{
clearGlobalMessagesBuffer();
setOptions(options);
setOptions(options, isBuildParallel);
int retCode = 0;
try
@@ -1892,7 +1893,7 @@ int SPF_SharedMemoryParallelization(void*& context, int winHandler, short* optio
MessageManager::setWinHandler(winHandler);
ignoreArrayDistributeState = true;
mpiProgram = 1;
return simpleTransformPass(INSERT_PARALLEL_DIRS_NODIST, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
return simpleTransformPass(INSERT_PARALLEL_DIRS_NODIST, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize, true);
}
int SPF_InsertPrivateFromGUI(void*& context, int winHandler, short* options, short* projName, short* folderName, short*& output,
@@ -1904,13 +1905,21 @@ int SPF_InsertPrivateFromGUI(void*& context, int winHandler, short* options, sho
}
int SPF_RemoveDeadCode(void*& context, int winHandler, short* options, short* projName, short* folderName, short*& output,
int*& outputSize, short*& outputMessage, int*& outputMessageSize)
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);
}
int SPF_InsertImplicitNone(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(SET_IMPLICIT_NONE, options, projName, folderName, output, outputSize, outputMessage, outputMessageSize);
}
static inline void convertBackSlash(char *str, int strL)
{
for (int z = 0; z < strL; ++z)
@@ -2625,6 +2634,8 @@ const wstring Sapfor_RunTransformation(const char* transformName_c, const char*
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 (whichRun == "SPF_InsertImplicitNone")
retCode = SPF_InsertImplicitNone(context, winHandler, optSh, projSh, fold, output, outputSize, outputMessage, outputMessageSize);
else
{
if (showDebug)