Merge branch 'master' into CP_blocks_insert
This commit is contained in:
@@ -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>)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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__);
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -631,7 +631,7 @@ int printParalleRegions(const char *fileName, vector<ParallelRegion*> ®ions)
|
||||
|
||||
static int getIntVal(SgExpression *ex)
|
||||
{
|
||||
SgExpression* calc = CalculateInteger(ex);
|
||||
SgExpression* calc = CalculateInteger(ex->copyPtr());
|
||||
if (calc->variant() == INT_VAL)
|
||||
return calc->valueInteger();
|
||||
else
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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> ¤tVariant = 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:
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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))
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void implicitCheck(SgFile* 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,
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_SPF "2289"
|
||||
#define VERSION_SPF "2320"
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user